added r_transparent_sortsurfacesbynearest cvar (default 1), this
[xonotic/darkplaces.git] / gl_rmain.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20 // r_main.c
21
22 #include "quakedef.h"
23 #include "cl_dyntexture.h"
24 #include "r_shadow.h"
25 #include "polygon.h"
26 #include "image.h"
27 #include "ft2.h"
28 #include "csprogs.h"
29 #include "cl_video.h"
30 #include "dpsoftrast.h"
31
32 #ifdef SUPPORTD3D
33 #include <d3d9.h>
34 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
35 #endif
36
37 mempool_t *r_main_mempool;
38 rtexturepool_t *r_main_texturepool;
39
40 static int r_textureframe = 0; ///< used only by R_GetCurrentTexture
41
42 static qboolean r_loadnormalmap;
43 static qboolean r_loadgloss;
44 qboolean r_loadfog;
45 static qboolean r_loaddds;
46 static qboolean r_savedds;
47
48 //
49 // screen size info
50 //
51 r_refdef_t r_refdef;
52
53 cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "screen motionblur - value represents intensity, somewhere around 0.5 recommended"};
54 cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "screen motionblur based on damage - value represents intensity, somewhere around 0.5 recommended"};
55 cvar_t r_motionblur_averaging = {CVAR_SAVE, "r_motionblur_averaging", "0.1", "sliding average reaction time for velocity (higher = slower adaption to change)"};
56 cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"};
57 cvar_t r_motionblur_minblur = {CVAR_SAVE, "r_motionblur_minblur", "0.5", "factor of blur to apply at all times (always have this amount of blur no matter what the other factors are)"};
58 cvar_t r_motionblur_maxblur = {CVAR_SAVE, "r_motionblur_maxblur", "0.9", "maxmimum amount of blur"};
59 cvar_t r_motionblur_velocityfactor = {CVAR_SAVE, "r_motionblur_velocityfactor", "1", "factoring in of player velocity to the blur equation - the faster the player moves around the map, the more blur they get"};
60 cvar_t r_motionblur_velocityfactor_minspeed = {CVAR_SAVE, "r_motionblur_velocityfactor_minspeed", "400", "lower value of velocity when it starts to factor into blur equation"};
61 cvar_t r_motionblur_velocityfactor_maxspeed = {CVAR_SAVE, "r_motionblur_velocityfactor_maxspeed", "800", "upper value of velocity when it reaches the peak factor into blur equation"};
62 cvar_t r_motionblur_mousefactor = {CVAR_SAVE, "r_motionblur_mousefactor", "2", "factoring in of mouse acceleration to the blur equation - the faster the player turns their mouse, the more blur they get"};
63 cvar_t r_motionblur_mousefactor_minspeed = {CVAR_SAVE, "r_motionblur_mousefactor_minspeed", "0", "lower value of mouse acceleration when it starts to factor into blur equation"};
64 cvar_t r_motionblur_mousefactor_maxspeed = {CVAR_SAVE, "r_motionblur_mousefactor_maxspeed", "50", "upper value of mouse acceleration when it reaches the peak factor into blur equation"};
65
66 // TODO do we want a r_equalize_entities cvar that works on all ents, or would that be a cheat?
67 cvar_t r_equalize_entities_fullbright = {CVAR_SAVE, "r_equalize_entities_fullbright", "0", "render fullbright entities by equalizing their lightness, not by not rendering light"};
68 cvar_t r_equalize_entities_minambient = {CVAR_SAVE, "r_equalize_entities_minambient", "0.5", "light equalizing: ensure at least this ambient/diffuse ratio"};
69 cvar_t r_equalize_entities_by = {CVAR_SAVE, "r_equalize_entities_by", "0.7", "light equalizing: exponent of dynamics compression (0 = no compression, 1 = full compression)"};
70 cvar_t r_equalize_entities_to = {CVAR_SAVE, "r_equalize_entities_to", "0.8", "light equalizing: target light level"};
71
72 cvar_t r_depthfirst = {CVAR_SAVE, "r_depthfirst", "0", "renders a depth-only version of the scene before normal rendering begins to eliminate overdraw, values: 0 = off, 1 = world depth, 2 = world and model depth"};
73 cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"};
74 cvar_t r_farclip_base = {0, "r_farclip_base", "65536", "farclip (furthest visible distance) for rendering when r_useinfinitefarclip is 0"};
75 cvar_t r_farclip_world = {0, "r_farclip_world", "2", "adds map size to farclip multiplied by this value"};
76 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
77 cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"};
78 cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"};
79 cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "1", "enables GL_ALPHA_TO_COVERAGE antialiasing technique on alphablend and alphatest surfaces when using vid_samples 2 or higher"};
80 cvar_t r_transparent_sortsurfacesbynearest = {0, "r_transparent_sortsurfacesbynearest", "1", "sort entity and world surfaces by nearest point on bounding box instead of using the center of the bounding box, usually reduces sorting artifacts"};
81 cvar_t r_transparent_useplanardistance = {0, "r_transparent_useplanardistance", "0", "sort transparent meshes by distance from view plane rather than spherical distance to the chosen point"};
82 cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"};
83 cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%,  10 = 100%)"};
84 cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"};
85 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
86 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
87 cvar_t r_showlighting = {0, "r_showlighting", "0", "shows areas lit by lights, useful for finding out why some areas of a map render slowly (bright orange = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
88 cvar_t r_showshadowvolumes = {0, "r_showshadowvolumes", "0", "shows areas shadowed by lights, useful for finding out why some areas of a map render slowly (bright blue = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
89 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
90 cvar_t r_showcollisionbrushes_polygonfactor = {0, "r_showcollisionbrushes_polygonfactor", "-1", "expands outward the brush polygons a little bit, used to make collision brushes appear infront of walls"};
91 cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygonoffset", "0", "nudges brush polygon depth in hardware depth units, used to make collision brushes appear infront of walls"};
92 cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"};
93 cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
94 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
95 cvar_t r_draw2d = {0, "r_draw2d","1", "draw 2D stuff (dangerous to turn off)"};
96 cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"};
97 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
98 cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
99 cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
100 cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "number of samples to test for entity culling (in addition to center sample)"};
101 cvar_t r_cullentities_trace_tempentitysamples = {0, "r_cullentities_trace_tempentitysamples", "-1", "number of samples to test for entity culling of temp entities (including all CSQC entities), -1 disables trace culling on these entities to prevent flicker (pvs still applies)"};
102 cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
103 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
104 cvar_t r_sortentities = {0, "r_sortentities", "0", "sort entities before drawing (might be faster)"};
105 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
106 cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
107
108 cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps"};
109 cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier"};
110 #define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit))
111
112 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
113 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
114 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
115 cvar_t r_shadows = {CVAR_SAVE, "r_shadows", "0", "casts fake stencil shadows from models onto the world (rtlights are unaffected by this); when set to 2, always cast the shadows in the direction set by r_shadows_throwdirection, otherwise use the model lighting."};
116 cvar_t r_shadows_darken = {CVAR_SAVE, "r_shadows_darken", "0.5", "how much shadowed areas will be darkened"};
117 cvar_t r_shadows_throwdistance = {CVAR_SAVE, "r_shadows_throwdistance", "500", "how far to cast shadows from models"};
118 cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"};
119 cvar_t r_shadows_drawafterrtlighting = {CVAR_SAVE, "r_shadows_drawafterrtlighting", "0", "draw fake shadows AFTER realtime lightning is drawn. May be useful for simulating fast sunlight on large outdoor maps with only one noshadow rtlight. The price is less realistic appearance of dynamic light shadows."};
120 cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
121 cvar_t r_shadows_focus = {CVAR_SAVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"};
122 cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "1", "increases shadowmap quality (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
123 cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
124 cvar_t r_polygonoffset_submodel_factor = {0, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
125 cvar_t r_polygonoffset_submodel_offset = {0, "r_polygonoffset_submodel_offset", "14", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
126 cvar_t r_polygonoffset_decals_factor = {0, "r_polygonoffset_decals_factor", "0", "biases depth values of decals to prevent z-fighting artifacts"};
127 cvar_t r_polygonoffset_decals_offset = {0, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"};
128 cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
129 cvar_t r_fog_clear = {0, "r_fog_clear", "1", "clears renderbuffer with fog color before render starts"};
130 cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
131 cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0", "enables depth writes on transparent meshes whose materially is normally opaque, this prevents seeing the inside of a transparent mesh"};
132 cvar_t r_transparent_sortmindist = {CVAR_SAVE, "r_transparent_sortmindist", "0", "lower distance limit for transparent sorting"};
133 cvar_t r_transparent_sortmaxdist = {CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
134 cvar_t r_transparent_sortarraysize = {CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
135
136 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
137 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
138 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
139 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
140 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
141 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
142 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
143 cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"};
144
145 cvar_t r_texture_dds_load = {CVAR_SAVE, "r_texture_dds_load", "0", "load compressed dds/filename.dds texture instead of filename.tga, if the file exists (requires driver support)"};
146 cvar_t r_texture_dds_save = {CVAR_SAVE, "r_texture_dds_save", "0", "save compressed dds/filename.dds texture when filename.tga is loaded, so that it can be loaded instead next time"};
147
148 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"};
149 static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"};
150 static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"};
151
152 cvar_t r_usedepthtextures = {CVAR_SAVE, "r_usedepthtextures", "1", "use depth texture instead of depth renderbuffer where possible, uses less video memory but may render slower (or faster) depending on hardware"};
153 cvar_t r_viewfbo = {CVAR_SAVE, "r_viewfbo", "0", "enables use of an 8bit (1) or 16bit (2) or 32bit (3) per component float framebuffer render, which may be at a different resolution than the video mode"};
154 cvar_t r_viewscale = {CVAR_SAVE, "r_viewscale", "1", "scaling factor for resolution of the fbo rendering method, must be > 0, can be above 1 for a costly antialiasing behavior, typical values are 0.5 for 1/4th as many pixels rendered, or 1 for normal rendering"};
155 cvar_t r_viewscale_fpsscaling = {CVAR_SAVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"};
156 cvar_t r_viewscale_fpsscaling_min = {CVAR_SAVE, "r_viewscale_fpsscaling_min", "0.0625", "worst acceptable quality"};
157 cvar_t r_viewscale_fpsscaling_multiply = {CVAR_SAVE, "r_viewscale_fpsscaling_multiply", "5", "adjust quality up or down by the frametime difference from 1.0/target, multiplied by this factor"};
158 cvar_t r_viewscale_fpsscaling_stepsize = {CVAR_SAVE, "r_viewscale_fpsscaling_stepsize", "0.01", "smallest adjustment to hit the target framerate (this value prevents minute oscillations)"};
159 cvar_t r_viewscale_fpsscaling_stepmax = {CVAR_SAVE, "r_viewscale_fpsscaling_stepmax", "1.00", "largest adjustment to hit the target framerate (this value prevents wild overshooting of the estimate)"};
160 cvar_t r_viewscale_fpsscaling_target = {CVAR_SAVE, "r_viewscale_fpsscaling_target", "70", "desired framerate"};
161
162 cvar_t r_glsl_deluxemapping = {CVAR_SAVE, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"};
163 cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
164 cvar_t r_glsl_offsetmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_steps", "2", "offset mapping steps (note: too high values may be not supported by your GPU)"};
165 cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
166 cvar_t r_glsl_offsetmapping_reliefmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_steps", "10", "relief mapping steps (note: too high values may be not supported by your GPU)"};
167 cvar_t r_glsl_offsetmapping_reliefmapping_refinesteps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_refinesteps", "5", "relief mapping refine steps (these are a binary search executed as the last step as given by r_glsl_offsetmapping_reliefmapping_steps)"};
168 cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
169 cvar_t r_glsl_offsetmapping_lod = {CVAR_SAVE, "r_glsl_offsetmapping_lod", "0", "apply distance-based level-of-detail correction to number of offsetmappig steps, effectively making it render faster on large open-area maps"};
170 cvar_t r_glsl_offsetmapping_lod_distance = {CVAR_SAVE, "r_glsl_offsetmapping_lod_distance", "32", "first LOD level distance, second level (-50% steps) is 2x of this, third (33%) - 3x etc."};
171 cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
172 cvar_t r_glsl_postprocess_uservec1 = {CVAR_SAVE, "r_glsl_postprocess_uservec1", "0 0 0 0", "a 4-component vector to pass as uservec1 to the postprocessing shader (only useful if default.glsl has been customized)"};
173 cvar_t r_glsl_postprocess_uservec2 = {CVAR_SAVE, "r_glsl_postprocess_uservec2", "0 0 0 0", "a 4-component vector to pass as uservec2 to the postprocessing shader (only useful if default.glsl has been customized)"};
174 cvar_t r_glsl_postprocess_uservec3 = {CVAR_SAVE, "r_glsl_postprocess_uservec3", "0 0 0 0", "a 4-component vector to pass as uservec3 to the postprocessing shader (only useful if default.glsl has been customized)"};
175 cvar_t r_glsl_postprocess_uservec4 = {CVAR_SAVE, "r_glsl_postprocess_uservec4", "0 0 0 0", "a 4-component vector to pass as uservec4 to the postprocessing shader (only useful if default.glsl has been customized)"};
176 cvar_t r_glsl_postprocess_uservec1_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec1_enable", "1", "enables postprocessing uservec1 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
177 cvar_t r_glsl_postprocess_uservec2_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec2_enable", "1", "enables postprocessing uservec2 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
178 cvar_t r_glsl_postprocess_uservec3_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec3_enable", "1", "enables postprocessing uservec3 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
179 cvar_t r_glsl_postprocess_uservec4_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec4_enable", "1", "enables postprocessing uservec4 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
180
181 cvar_t r_water = {CVAR_SAVE, "r_water", "0", "whether to use reflections and refraction on water surfaces (note: r_wateralpha must be set below 1)"};
182 cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
183 cvar_t r_water_resolutionmultiplier = {CVAR_SAVE, "r_water_resolutionmultiplier", "0.5", "multiplier for screen resolution when rendering refracted/reflected scenes, 1 is full quality, lower values are faster"};
184 cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
185 cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
186 cvar_t r_water_scissormode = {0, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
187 cvar_t r_water_lowquality = {0, "r_water_lowquality", "0", "special option to accelerate water rendering, 1 disables shadows and particles, 2 disables all dynamic lights"};
188 cvar_t r_water_hideplayer = {CVAR_SAVE, "r_water_hideplayer", "0", "if set to 1 then player will be hidden in refraction views, if set to 2 then player will also be hidden in reflection views, player is always visible in camera views"};
189 cvar_t r_water_fbo = {CVAR_SAVE, "r_water_fbo", "1", "enables use of render to texture for water effects, otherwise copy to texture is used (slower)"};
190
191 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
192 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
193 cvar_t r_lerplightstyles = {CVAR_SAVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"};
194 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
195
196 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
197 cvar_t r_bloom_colorscale = {CVAR_SAVE, "r_bloom_colorscale", "1", "how bright the glow is"};
198
199 cvar_t r_bloom_brighten = {CVAR_SAVE, "r_bloom_brighten", "2", "how bright the glow is, after subtract/power"};
200 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
201 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
202 cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exaggerated the glow is"};
203 cvar_t r_bloom_colorsubtract = {CVAR_SAVE, "r_bloom_colorsubtract", "0.125", "reduces bloom colors by a certain amount"};
204
205 cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
206 cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
207 cvar_t r_hdr_irisadaptation = {CVAR_SAVE, "r_hdr_irisadaptation", "0", "adjust scene brightness according to light intensity at player location"};
208 cvar_t r_hdr_irisadaptation_multiplier = {CVAR_SAVE, "r_hdr_irisadaptation_multiplier", "2", "brightness at which value will be 1.0"};
209 cvar_t r_hdr_irisadaptation_minvalue = {CVAR_SAVE, "r_hdr_irisadaptation_minvalue", "0.5", "minimum value that can result from multiplier / brightness"};
210 cvar_t r_hdr_irisadaptation_maxvalue = {CVAR_SAVE, "r_hdr_irisadaptation_maxvalue", "4", "maximum value that can result from multiplier / brightness"};
211 cvar_t r_hdr_irisadaptation_value = {0, "r_hdr_irisadaptation_value", "1", "current value as scenebrightness multiplier, changes continuously when irisadaptation is active"};
212 cvar_t r_hdr_irisadaptation_fade_up = {CVAR_SAVE, "r_hdr_irisadaptation_fade_up", "0.1", "fade rate at which value adjusts to darkness"};
213 cvar_t r_hdr_irisadaptation_fade_down = {CVAR_SAVE, "r_hdr_irisadaptation_fade_down", "0.5", "fade rate at which value adjusts to brightness"};
214 cvar_t r_hdr_irisadaptation_radius = {CVAR_SAVE, "r_hdr_irisadaptation_radius", "15", "lighting within this many units of the eye is averaged"};
215
216 cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1", "uses significantly faster (and supposedly higher quality) area-weighted vertex normals and tangent vectors rather than summing normalized triangle normals and tangents"};
217
218 cvar_t developer_texturelogging = {0, "developer_texturelogging", "0", "produces a textures.log file containing names of skins and map textures the engine tried to load"};
219
220 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
221
222 cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
223
224 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
225 cvar_t r_glsl_saturation_redcompensate = {CVAR_SAVE, "r_glsl_saturation_redcompensate", "0", "a 'vampire sight' addition to desaturation effect, does compensation for red color, r_glsl_restart is required"};
226
227 cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer."};
228
229 cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "0.5", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
230
231 extern cvar_t v_glslgamma;
232 extern cvar_t v_glslgamma_2d;
233
234 extern qboolean v_flipped_state;
235
236 r_framebufferstate_t r_fb;
237
238 /// shadow volume bsp struct with automatically growing nodes buffer
239 svbsp_t r_svbsp;
240
241 rtexture_t *r_texture_blanknormalmap;
242 rtexture_t *r_texture_white;
243 rtexture_t *r_texture_grey128;
244 rtexture_t *r_texture_black;
245 rtexture_t *r_texture_notexture;
246 rtexture_t *r_texture_whitecube;
247 rtexture_t *r_texture_normalizationcube;
248 rtexture_t *r_texture_fogattenuation;
249 rtexture_t *r_texture_fogheighttexture;
250 rtexture_t *r_texture_gammaramps;
251 unsigned int r_texture_gammaramps_serial;
252 //rtexture_t *r_texture_fogintensity;
253 rtexture_t *r_texture_reflectcube;
254
255 // TODO: hash lookups?
256 typedef struct cubemapinfo_s
257 {
258         char basename[64];
259         rtexture_t *texture;
260 }
261 cubemapinfo_t;
262
263 int r_texture_numcubemaps;
264 cubemapinfo_t *r_texture_cubemaps[MAX_CUBEMAPS];
265
266 unsigned int r_queries[MAX_OCCLUSION_QUERIES];
267 unsigned int r_numqueries;
268 unsigned int r_maxqueries;
269
270 typedef struct r_qwskincache_s
271 {
272         char name[MAX_QPATH];
273         skinframe_t *skinframe;
274 }
275 r_qwskincache_t;
276
277 static r_qwskincache_t *r_qwskincache;
278 static int r_qwskincache_size;
279
280 /// vertex coordinates for a quad that covers the screen exactly
281 extern const float r_screenvertex3f[12];
282 extern const float r_d3dscreenvertex3f[12];
283 const float r_screenvertex3f[12] =
284 {
285         0, 0, 0,
286         1, 0, 0,
287         1, 1, 0,
288         0, 1, 0
289 };
290 const float r_d3dscreenvertex3f[12] =
291 {
292         0, 1, 0,
293         1, 1, 0,
294         1, 0, 0,
295         0, 0, 0
296 };
297
298 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
299 {
300         int i;
301         for (i = 0;i < verts;i++)
302         {
303                 out[0] = in[0] * r;
304                 out[1] = in[1] * g;
305                 out[2] = in[2] * b;
306                 out[3] = in[3];
307                 in += 4;
308                 out += 4;
309         }
310 }
311
312 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
313 {
314         int i;
315         for (i = 0;i < verts;i++)
316         {
317                 out[0] = r;
318                 out[1] = g;
319                 out[2] = b;
320                 out[3] = a;
321                 out += 4;
322         }
323 }
324
325 // FIXME: move this to client?
326 void FOG_clear(void)
327 {
328         if (gamemode == GAME_NEHAHRA)
329         {
330                 Cvar_Set("gl_fogenable", "0");
331                 Cvar_Set("gl_fogdensity", "0.2");
332                 Cvar_Set("gl_fogred", "0.3");
333                 Cvar_Set("gl_foggreen", "0.3");
334                 Cvar_Set("gl_fogblue", "0.3");
335         }
336         r_refdef.fog_density = 0;
337         r_refdef.fog_red = 0;
338         r_refdef.fog_green = 0;
339         r_refdef.fog_blue = 0;
340         r_refdef.fog_alpha = 1;
341         r_refdef.fog_start = 0;
342         r_refdef.fog_end = 16384;
343         r_refdef.fog_height = 1<<30;
344         r_refdef.fog_fadedepth = 128;
345         memset(r_refdef.fog_height_texturename, 0, sizeof(r_refdef.fog_height_texturename));
346 }
347
348 static void R_BuildBlankTextures(void)
349 {
350         unsigned char data[4];
351         data[2] = 128; // normal X
352         data[1] = 128; // normal Y
353         data[0] = 255; // normal Z
354         data[3] = 255; // height
355         r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
356         data[0] = 255;
357         data[1] = 255;
358         data[2] = 255;
359         data[3] = 255;
360         r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
361         data[0] = 128;
362         data[1] = 128;
363         data[2] = 128;
364         data[3] = 255;
365         r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
366         data[0] = 0;
367         data[1] = 0;
368         data[2] = 0;
369         data[3] = 255;
370         r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
371 }
372
373 static void R_BuildNoTexture(void)
374 {
375         int x, y;
376         unsigned char pix[16][16][4];
377         // this makes a light grey/dark grey checkerboard texture
378         for (y = 0;y < 16;y++)
379         {
380                 for (x = 0;x < 16;x++)
381                 {
382                         if ((y < 8) ^ (x < 8))
383                         {
384                                 pix[y][x][0] = 128;
385                                 pix[y][x][1] = 128;
386                                 pix[y][x][2] = 128;
387                                 pix[y][x][3] = 255;
388                         }
389                         else
390                         {
391                                 pix[y][x][0] = 64;
392                                 pix[y][x][1] = 64;
393                                 pix[y][x][2] = 64;
394                                 pix[y][x][3] = 255;
395                         }
396                 }
397         }
398         r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, -1, NULL);
399 }
400
401 static void R_BuildWhiteCube(void)
402 {
403         unsigned char data[6*1*1*4];
404         memset(data, 255, sizeof(data));
405         r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
406 }
407
408 static void R_BuildNormalizationCube(void)
409 {
410         int x, y, side;
411         vec3_t v;
412         vec_t s, t, intensity;
413 #define NORMSIZE 64
414         unsigned char *data;
415         data = (unsigned char *)Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
416         for (side = 0;side < 6;side++)
417         {
418                 for (y = 0;y < NORMSIZE;y++)
419                 {
420                         for (x = 0;x < NORMSIZE;x++)
421                         {
422                                 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
423                                 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
424                                 switch(side)
425                                 {
426                                 default:
427                                 case 0:
428                                         v[0] = 1;
429                                         v[1] = -t;
430                                         v[2] = -s;
431                                         break;
432                                 case 1:
433                                         v[0] = -1;
434                                         v[1] = -t;
435                                         v[2] = s;
436                                         break;
437                                 case 2:
438                                         v[0] = s;
439                                         v[1] = 1;
440                                         v[2] = t;
441                                         break;
442                                 case 3:
443                                         v[0] = s;
444                                         v[1] = -1;
445                                         v[2] = -t;
446                                         break;
447                                 case 4:
448                                         v[0] = s;
449                                         v[1] = -t;
450                                         v[2] = 1;
451                                         break;
452                                 case 5:
453                                         v[0] = -s;
454                                         v[1] = -t;
455                                         v[2] = -1;
456                                         break;
457                                 }
458                                 intensity = 127.0f / sqrt(DotProduct(v, v));
459                                 data[((side*64+y)*64+x)*4+2] = (unsigned char)(128.0f + intensity * v[0]);
460                                 data[((side*64+y)*64+x)*4+1] = (unsigned char)(128.0f + intensity * v[1]);
461                                 data[((side*64+y)*64+x)*4+0] = (unsigned char)(128.0f + intensity * v[2]);
462                                 data[((side*64+y)*64+x)*4+3] = 255;
463                         }
464                 }
465         }
466         r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
467         Mem_Free(data);
468 }
469
470 static void R_BuildFogTexture(void)
471 {
472         int x, b;
473 #define FOGWIDTH 256
474         unsigned char data1[FOGWIDTH][4];
475         //unsigned char data2[FOGWIDTH][4];
476         double d, r, alpha;
477
478         r_refdef.fogmasktable_start = r_refdef.fog_start;
479         r_refdef.fogmasktable_alpha = r_refdef.fog_alpha;
480         r_refdef.fogmasktable_range = r_refdef.fogrange;
481         r_refdef.fogmasktable_density = r_refdef.fog_density;
482
483         r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH;
484         for (x = 0;x < FOGMASKTABLEWIDTH;x++)
485         {
486                 d = (x * r - r_refdef.fogmasktable_start);
487                 if(developer_extra.integer)
488                         Con_DPrintf("%f ", d);
489                 d = max(0, d);
490                 if (r_fog_exp2.integer)
491                         alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d);
492                 else
493                         alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d);
494                 if(developer_extra.integer)
495                         Con_DPrintf(" : %f ", alpha);
496                 alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha;
497                 if(developer_extra.integer)
498                         Con_DPrintf(" = %f\n", alpha);
499                 r_refdef.fogmasktable[x] = bound(0, alpha, 1);
500         }
501
502         for (x = 0;x < FOGWIDTH;x++)
503         {
504                 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
505                 data1[x][0] = b;
506                 data1[x][1] = b;
507                 data1[x][2] = b;
508                 data1[x][3] = 255;
509                 //data2[x][0] = 255 - b;
510                 //data2[x][1] = 255 - b;
511                 //data2[x][2] = 255 - b;
512                 //data2[x][3] = 255;
513         }
514         if (r_texture_fogattenuation)
515         {
516                 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
517                 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
518         }
519         else
520         {
521                 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
522                 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
523         }
524 }
525
526 static void R_BuildFogHeightTexture(void)
527 {
528         unsigned char *inpixels;
529         int size;
530         int x;
531         int y;
532         int j;
533         float c[4];
534         float f;
535         inpixels = NULL;
536         strlcpy(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename, sizeof(r_refdef.fogheighttexturename));
537         if (r_refdef.fogheighttexturename[0])
538                 inpixels = loadimagepixelsbgra(r_refdef.fogheighttexturename, true, false, false, NULL);
539         if (!inpixels)
540         {
541                 r_refdef.fog_height_tablesize = 0;
542                 if (r_texture_fogheighttexture)
543                         R_FreeTexture(r_texture_fogheighttexture);
544                 r_texture_fogheighttexture = NULL;
545                 if (r_refdef.fog_height_table2d)
546                         Mem_Free(r_refdef.fog_height_table2d);
547                 r_refdef.fog_height_table2d = NULL;
548                 if (r_refdef.fog_height_table1d)
549                         Mem_Free(r_refdef.fog_height_table1d);
550                 r_refdef.fog_height_table1d = NULL;
551                 return;
552         }
553         size = image_width;
554         r_refdef.fog_height_tablesize = size;
555         r_refdef.fog_height_table1d = (unsigned char *)Mem_Alloc(r_main_mempool, size * 4);
556         r_refdef.fog_height_table2d = (unsigned char *)Mem_Alloc(r_main_mempool, size * size * 4);
557         memcpy(r_refdef.fog_height_table1d, inpixels, size * 4);
558         Mem_Free(inpixels);
559         // LordHavoc: now the magic - what is that table2d for?  it is a cooked
560         // average fog color table accounting for every fog layer between a point
561         // and the camera.  (Note: attenuation is handled separately!)
562         for (y = 0;y < size;y++)
563         {
564                 for (x = 0;x < size;x++)
565                 {
566                         Vector4Clear(c);
567                         f = 0;
568                         if (x < y)
569                         {
570                                 for (j = x;j <= y;j++)
571                                 {
572                                         Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
573                                         f++;
574                                 }
575                         }
576                         else
577                         {
578                                 for (j = x;j >= y;j--)
579                                 {
580                                         Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
581                                         f++;
582                                 }
583                         }
584                         f = 1.0f / f;
585                         r_refdef.fog_height_table2d[(y*size+x)*4+0] = (unsigned char)(c[0] * f);
586                         r_refdef.fog_height_table2d[(y*size+x)*4+1] = (unsigned char)(c[1] * f);
587                         r_refdef.fog_height_table2d[(y*size+x)*4+2] = (unsigned char)(c[2] * f);
588                         r_refdef.fog_height_table2d[(y*size+x)*4+3] = (unsigned char)(c[3] * f);
589                 }
590         }
591         r_texture_fogheighttexture = R_LoadTexture2D(r_main_texturepool, "fogheighttable", size, size, r_refdef.fog_height_table2d, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_CLAMP, -1, NULL);
592 }
593
594 //=======================================================================================================================================================
595
596 static const char *builtinshaderstring =
597 #include "shader_glsl.h"
598 ;
599
600 const char *builtinhlslshaderstring =
601 #include "shader_hlsl.h"
602 ;
603
604 char *glslshaderstring = NULL;
605 char *hlslshaderstring = NULL;
606
607 //=======================================================================================================================================================
608
609 typedef struct shaderpermutationinfo_s
610 {
611         const char *pretext;
612         const char *name;
613 }
614 shaderpermutationinfo_t;
615
616 typedef struct shadermodeinfo_s
617 {
618         const char *vertexfilename;
619         const char *geometryfilename;
620         const char *fragmentfilename;
621         const char *pretext;
622         const char *name;
623 }
624 shadermodeinfo_t;
625
626 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
627 shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
628 {
629         {"#define USEDIFFUSE\n", " diffuse"},
630         {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
631         {"#define USEVIEWTINT\n", " viewtint"},
632         {"#define USECOLORMAPPING\n", " colormapping"},
633         {"#define USESATURATION\n", " saturation"},
634         {"#define USEFOGINSIDE\n", " foginside"},
635         {"#define USEFOGOUTSIDE\n", " fogoutside"},
636         {"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"},
637         {"#define USEFOGALPHAHACK\n", " fogalphahack"},
638         {"#define USEGAMMARAMPS\n", " gammaramps"},
639         {"#define USECUBEFILTER\n", " cubefilter"},
640         {"#define USEGLOW\n", " glow"},
641         {"#define USEBLOOM\n", " bloom"},
642         {"#define USESPECULAR\n", " specular"},
643         {"#define USEPOSTPROCESSING\n", " postprocessing"},
644         {"#define USEREFLECTION\n", " reflection"},
645         {"#define USEOFFSETMAPPING\n", " offsetmapping"},
646         {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
647         {"#define USESHADOWMAP2D\n", " shadowmap2d"},
648         {"#define USESHADOWMAPPCF 1\n", " shadowmappcf"}, // TODO make this a static parm
649         {"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"}, // TODO make this a static parm
650         {"#define USESHADOWSAMPLER\n", " shadowsampler"}, // TODO make this a static parm
651         {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, // TODO make this a static parm
652         {"#define USESHADOWMAPORTHO\n", " shadowmaportho"},
653         {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
654         {"#define USEALPHAKILL\n", " alphakill"},
655         {"#define USEREFLECTCUBE\n", " reflectcube"},
656         {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
657         {"#define USEBOUNCEGRID\n", " bouncegrid"},
658         {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, // TODO make this a static parm
659         {"#define USETRIPPY\n", " trippy"},
660         {"#define USEDEPTHRGB\n", " depthrgb"},
661 };
662
663 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
664 shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
665 {
666         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
667         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
668         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
669         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
670         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
671         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
672         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
673         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
674         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
675         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
676         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
677         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
678         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
679         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
680         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_WATER\n", " water"},
681         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
682         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
683         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
684 };
685
686 shadermodeinfo_t hlslshadermodeinfo[SHADERMODE_COUNT] =
687 {
688         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_GENERIC\n", " generic"},
689         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_POSTPROCESS\n", " postprocess"},
690         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
691         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
692         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
693         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTMAP\n", " lightmap"},
694         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"},
695         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
696         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
697         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
698         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
699         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
700         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
701         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"},
702         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_WATER\n", " water"},
703         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
704         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
705         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
706 };
707
708 struct r_glsl_permutation_s;
709 typedef struct r_glsl_permutation_s
710 {
711         /// hash lookup data
712         struct r_glsl_permutation_s *hashnext;
713         unsigned int mode;
714         unsigned int permutation;
715
716         /// indicates if we have tried compiling this permutation already
717         qboolean compiled;
718         /// 0 if compilation failed
719         int program;
720         // texture units assigned to each detected uniform
721         int tex_Texture_First;
722         int tex_Texture_Second;
723         int tex_Texture_GammaRamps;
724         int tex_Texture_Normal;
725         int tex_Texture_Color;
726         int tex_Texture_Gloss;
727         int tex_Texture_Glow;
728         int tex_Texture_SecondaryNormal;
729         int tex_Texture_SecondaryColor;
730         int tex_Texture_SecondaryGloss;
731         int tex_Texture_SecondaryGlow;
732         int tex_Texture_Pants;
733         int tex_Texture_Shirt;
734         int tex_Texture_FogHeightTexture;
735         int tex_Texture_FogMask;
736         int tex_Texture_Lightmap;
737         int tex_Texture_Deluxemap;
738         int tex_Texture_Attenuation;
739         int tex_Texture_Cube;
740         int tex_Texture_Refraction;
741         int tex_Texture_Reflection;
742         int tex_Texture_ShadowMap2D;
743         int tex_Texture_CubeProjection;
744         int tex_Texture_ScreenNormalMap;
745         int tex_Texture_ScreenDiffuse;
746         int tex_Texture_ScreenSpecular;
747         int tex_Texture_ReflectMask;
748         int tex_Texture_ReflectCube;
749         int tex_Texture_BounceGrid;
750         /// locations of detected uniforms in program object, or -1 if not found
751         int loc_Texture_First;
752         int loc_Texture_Second;
753         int loc_Texture_GammaRamps;
754         int loc_Texture_Normal;
755         int loc_Texture_Color;
756         int loc_Texture_Gloss;
757         int loc_Texture_Glow;
758         int loc_Texture_SecondaryNormal;
759         int loc_Texture_SecondaryColor;
760         int loc_Texture_SecondaryGloss;
761         int loc_Texture_SecondaryGlow;
762         int loc_Texture_Pants;
763         int loc_Texture_Shirt;
764         int loc_Texture_FogHeightTexture;
765         int loc_Texture_FogMask;
766         int loc_Texture_Lightmap;
767         int loc_Texture_Deluxemap;
768         int loc_Texture_Attenuation;
769         int loc_Texture_Cube;
770         int loc_Texture_Refraction;
771         int loc_Texture_Reflection;
772         int loc_Texture_ShadowMap2D;
773         int loc_Texture_CubeProjection;
774         int loc_Texture_ScreenNormalMap;
775         int loc_Texture_ScreenDiffuse;
776         int loc_Texture_ScreenSpecular;
777         int loc_Texture_ReflectMask;
778         int loc_Texture_ReflectCube;
779         int loc_Texture_BounceGrid;
780         int loc_Alpha;
781         int loc_BloomBlur_Parameters;
782         int loc_ClientTime;
783         int loc_Color_Ambient;
784         int loc_Color_Diffuse;
785         int loc_Color_Specular;
786         int loc_Color_Glow;
787         int loc_Color_Pants;
788         int loc_Color_Shirt;
789         int loc_DeferredColor_Ambient;
790         int loc_DeferredColor_Diffuse;
791         int loc_DeferredColor_Specular;
792         int loc_DeferredMod_Diffuse;
793         int loc_DeferredMod_Specular;
794         int loc_DistortScaleRefractReflect;
795         int loc_EyePosition;
796         int loc_FogColor;
797         int loc_FogHeightFade;
798         int loc_FogPlane;
799         int loc_FogPlaneViewDist;
800         int loc_FogRangeRecip;
801         int loc_LightColor;
802         int loc_LightDir;
803         int loc_LightPosition;
804         int loc_OffsetMapping_ScaleSteps;
805         int loc_OffsetMapping_LodDistance;
806         int loc_OffsetMapping_Bias;
807         int loc_PixelSize;
808         int loc_ReflectColor;
809         int loc_ReflectFactor;
810         int loc_ReflectOffset;
811         int loc_RefractColor;
812         int loc_Saturation;
813         int loc_ScreenCenterRefractReflect;
814         int loc_ScreenScaleRefractReflect;
815         int loc_ScreenToDepth;
816         int loc_ShadowMap_Parameters;
817         int loc_ShadowMap_TextureScale;
818         int loc_SpecularPower;
819         int loc_UserVec1;
820         int loc_UserVec2;
821         int loc_UserVec3;
822         int loc_UserVec4;
823         int loc_ViewTintColor;
824         int loc_ViewToLight;
825         int loc_ModelToLight;
826         int loc_TexMatrix;
827         int loc_BackgroundTexMatrix;
828         int loc_ModelViewProjectionMatrix;
829         int loc_ModelViewMatrix;
830         int loc_PixelToScreenTexCoord;
831         int loc_ModelToReflectCube;
832         int loc_ShadowMapMatrix;
833         int loc_BloomColorSubtract;
834         int loc_NormalmapScrollBlend;
835         int loc_BounceGridMatrix;
836         int loc_BounceGridIntensity;
837 }
838 r_glsl_permutation_t;
839
840 #define SHADERPERMUTATION_HASHSIZE 256
841
842
843 // non-degradable "lightweight" shader parameters to keep the permutations simpler
844 // these can NOT degrade! only use for simple stuff
845 enum
846 {
847         SHADERSTATICPARM_SATURATION_REDCOMPENSATE = 0, ///< red compensation filter for saturation
848         SHADERSTATICPARM_EXACTSPECULARMATH = 1, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
849         SHADERSTATICPARM_POSTPROCESS_USERVEC1 = 2, ///< postprocess uservec1 is enabled
850         SHADERSTATICPARM_POSTPROCESS_USERVEC2 = 3, ///< postprocess uservec2 is enabled
851         SHADERSTATICPARM_POSTPROCESS_USERVEC3 = 4, ///< postprocess uservec3 is enabled
852         SHADERSTATICPARM_POSTPROCESS_USERVEC4 = 5,  ///< postprocess uservec4 is enabled
853         SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6, // use both alpha layers while blending materials, allows more advanced microblending
854         SHADERSTATICPARM_OFFSETMAPPING_USELOD = 7,  ///< LOD for offsetmapping
855 };
856 #define SHADERSTATICPARMS_COUNT 8
857
858 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
859 static int shaderstaticparms_count = 0;
860
861 static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
862 #define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
863 static qboolean R_CompileShader_CheckStaticParms(void)
864 {
865         static int r_compileshader_staticparms_save[1];
866         memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
867         memset(r_compileshader_staticparms, 0, sizeof(r_compileshader_staticparms));
868
869         // detect all
870         if (r_glsl_saturation_redcompensate.integer)
871                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SATURATION_REDCOMPENSATE);
872         if (r_glsl_vertextextureblend_usebothalphas.integer)
873                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS);
874         if (r_shadow_glossexact.integer)
875                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_EXACTSPECULARMATH);
876         if (r_glsl_postprocess.integer)
877         {
878                 if (r_glsl_postprocess_uservec1_enable.integer)
879                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC1);
880                 if (r_glsl_postprocess_uservec2_enable.integer)
881                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC2);
882                 if (r_glsl_postprocess_uservec3_enable.integer)
883                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC3);
884                 if (r_glsl_postprocess_uservec4_enable.integer)
885                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4);
886         }
887         if (r_glsl_offsetmapping_lod.integer && r_glsl_offsetmapping_lod_distance.integer > 0)
888                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_OFFSETMAPPING_USELOD);
889         return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
890 }
891
892 #define R_COMPILESHADER_STATICPARM_EMIT(p, n) \
893         if(r_compileshader_staticparms[(p) >> 5] & (1 << ((p) & 0x1F))) \
894                 shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
895         else \
896                 shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
897 static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation)
898 {
899         shaderstaticparms_count = 0;
900
901         // emit all
902         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SATURATION_REDCOMPENSATE, "SATURATION_REDCOMPENSATE");
903         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_EXACTSPECULARMATH, "USEEXACTSPECULARMATH");
904         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC1, "USERVEC1");
905         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC2, "USERVEC2");
906         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC3, "USERVEC3");
907         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC4, "USERVEC4");
908         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS, "USEBOTHALPHAS");
909         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_OFFSETMAPPING_USELOD, "USEOFFSETMAPPING_LOD");
910 }
911
912 /// information about each possible shader permutation
913 r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
914 /// currently selected permutation
915 r_glsl_permutation_t *r_glsl_permutation;
916 /// storage for permutations linked in the hash table
917 memexpandablearray_t r_glsl_permutationarray;
918
919 static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, unsigned int permutation)
920 {
921         //unsigned int hashdepth = 0;
922         unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
923         r_glsl_permutation_t *p;
924         for (p = r_glsl_permutationhash[mode][hashindex];p;p = p->hashnext)
925         {
926                 if (p->mode == mode && p->permutation == permutation)
927                 {
928                         //if (hashdepth > 10)
929                         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
930                         return p;
931                 }
932                 //hashdepth++;
933         }
934         p = (r_glsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_glsl_permutationarray);
935         p->mode = mode;
936         p->permutation = permutation;
937         p->hashnext = r_glsl_permutationhash[mode][hashindex];
938         r_glsl_permutationhash[mode][hashindex] = p;
939         //if (hashdepth > 10)
940         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
941         return p;
942 }
943
944 static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice)
945 {
946         char *shaderstring;
947         if (!filename || !filename[0])
948                 return NULL;
949         if (!strcmp(filename, "glsl/default.glsl"))
950         {
951                 if (!glslshaderstring)
952                 {
953                         glslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
954                         if (glslshaderstring)
955                                 Con_DPrintf("Loading shaders from file %s...\n", filename);
956                         else
957                                 glslshaderstring = (char *)builtinshaderstring;
958                 }
959                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(glslshaderstring) + 1);
960                 memcpy(shaderstring, glslshaderstring, strlen(glslshaderstring) + 1);
961                 return shaderstring;
962         }
963         shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
964         if (shaderstring)
965         {
966                 if (printfromdisknotice)
967                         Con_DPrintf("from disk %s... ", filename);
968                 return shaderstring;
969         }
970         return shaderstring;
971 }
972
973 static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation)
974 {
975         int i;
976         int sampler;
977         shadermodeinfo_t *modeinfo = glslshadermodeinfo + mode;
978         char *vertexstring, *geometrystring, *fragmentstring;
979         char permutationname[256];
980         int vertstrings_count = 0;
981         int geomstrings_count = 0;
982         int fragstrings_count = 0;
983         const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
984         const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
985         const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
986
987         if (p->compiled)
988                 return;
989         p->compiled = true;
990         p->program = 0;
991
992         permutationname[0] = 0;
993         vertexstring   = R_GLSL_GetText(modeinfo->vertexfilename, true);
994         geometrystring = R_GLSL_GetText(modeinfo->geometryfilename, false);
995         fragmentstring = R_GLSL_GetText(modeinfo->fragmentfilename, false);
996
997         strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
998
999         // if we can do #version 130, we should (this improves quality of offset/reliefmapping thanks to textureGrad)
1000         if(vid.support.gl20shaders130)
1001         {
1002                 vertstrings_list[vertstrings_count++] = "#version 130\n";
1003                 geomstrings_list[geomstrings_count++] = "#version 130\n";
1004                 fragstrings_list[fragstrings_count++] = "#version 130\n";
1005                 vertstrings_list[vertstrings_count++] = "#define GLSL130\n";
1006                 geomstrings_list[geomstrings_count++] = "#define GLSL130\n";
1007                 fragstrings_list[fragstrings_count++] = "#define GLSL130\n";
1008         }
1009
1010         // the first pretext is which type of shader to compile as
1011         // (later these will all be bound together as a program object)
1012         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1013         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1014         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1015
1016         // the second pretext is the mode (for example a light source)
1017         vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1018         geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1019         fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1020         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1021
1022         // now add all the permutation pretexts
1023         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1024         {
1025                 if (permutation & (1<<i))
1026                 {
1027                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1028                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1029                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1030                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1031                 }
1032                 else
1033                 {
1034                         // keep line numbers correct
1035                         vertstrings_list[vertstrings_count++] = "\n";
1036                         geomstrings_list[geomstrings_count++] = "\n";
1037                         fragstrings_list[fragstrings_count++] = "\n";
1038                 }
1039         }
1040
1041         // add static parms
1042         R_CompileShader_AddStaticParms(mode, permutation);
1043         memcpy((char *)(vertstrings_list + vertstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1044         vertstrings_count += shaderstaticparms_count;
1045         memcpy((char *)(geomstrings_list + geomstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1046         geomstrings_count += shaderstaticparms_count;
1047         memcpy((char *)(fragstrings_list + fragstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1048         fragstrings_count += shaderstaticparms_count;
1049
1050         // now append the shader text itself
1051         vertstrings_list[vertstrings_count++] = vertexstring;
1052         geomstrings_list[geomstrings_count++] = geometrystring;
1053         fragstrings_list[fragstrings_count++] = fragmentstring;
1054
1055         // if any sources were NULL, clear the respective list
1056         if (!vertexstring)
1057                 vertstrings_count = 0;
1058         if (!geometrystring)
1059                 geomstrings_count = 0;
1060         if (!fragmentstring)
1061                 fragstrings_count = 0;
1062
1063         // compile the shader program
1064         if (vertstrings_count + geomstrings_count + fragstrings_count)
1065                 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
1066         if (p->program)
1067         {
1068                 CHECKGLERROR
1069                 qglUseProgram(p->program);CHECKGLERROR
1070                 // look up all the uniform variable names we care about, so we don't
1071                 // have to look them up every time we set them
1072
1073                 p->loc_Texture_First              = qglGetUniformLocation(p->program, "Texture_First");
1074                 p->loc_Texture_Second             = qglGetUniformLocation(p->program, "Texture_Second");
1075                 p->loc_Texture_GammaRamps         = qglGetUniformLocation(p->program, "Texture_GammaRamps");
1076                 p->loc_Texture_Normal             = qglGetUniformLocation(p->program, "Texture_Normal");
1077                 p->loc_Texture_Color              = qglGetUniformLocation(p->program, "Texture_Color");
1078                 p->loc_Texture_Gloss              = qglGetUniformLocation(p->program, "Texture_Gloss");
1079                 p->loc_Texture_Glow               = qglGetUniformLocation(p->program, "Texture_Glow");
1080                 p->loc_Texture_SecondaryNormal    = qglGetUniformLocation(p->program, "Texture_SecondaryNormal");
1081                 p->loc_Texture_SecondaryColor     = qglGetUniformLocation(p->program, "Texture_SecondaryColor");
1082                 p->loc_Texture_SecondaryGloss     = qglGetUniformLocation(p->program, "Texture_SecondaryGloss");
1083                 p->loc_Texture_SecondaryGlow      = qglGetUniformLocation(p->program, "Texture_SecondaryGlow");
1084                 p->loc_Texture_Pants              = qglGetUniformLocation(p->program, "Texture_Pants");
1085                 p->loc_Texture_Shirt              = qglGetUniformLocation(p->program, "Texture_Shirt");
1086                 p->loc_Texture_FogHeightTexture   = qglGetUniformLocation(p->program, "Texture_FogHeightTexture");
1087                 p->loc_Texture_FogMask            = qglGetUniformLocation(p->program, "Texture_FogMask");
1088                 p->loc_Texture_Lightmap           = qglGetUniformLocation(p->program, "Texture_Lightmap");
1089                 p->loc_Texture_Deluxemap          = qglGetUniformLocation(p->program, "Texture_Deluxemap");
1090                 p->loc_Texture_Attenuation        = qglGetUniformLocation(p->program, "Texture_Attenuation");
1091                 p->loc_Texture_Cube               = qglGetUniformLocation(p->program, "Texture_Cube");
1092                 p->loc_Texture_Refraction         = qglGetUniformLocation(p->program, "Texture_Refraction");
1093                 p->loc_Texture_Reflection         = qglGetUniformLocation(p->program, "Texture_Reflection");
1094                 p->loc_Texture_ShadowMap2D        = qglGetUniformLocation(p->program, "Texture_ShadowMap2D");
1095                 p->loc_Texture_CubeProjection     = qglGetUniformLocation(p->program, "Texture_CubeProjection");
1096                 p->loc_Texture_ScreenNormalMap    = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap");
1097                 p->loc_Texture_ScreenDiffuse      = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse");
1098                 p->loc_Texture_ScreenSpecular     = qglGetUniformLocation(p->program, "Texture_ScreenSpecular");
1099                 p->loc_Texture_ReflectMask        = qglGetUniformLocation(p->program, "Texture_ReflectMask");
1100                 p->loc_Texture_ReflectCube        = qglGetUniformLocation(p->program, "Texture_ReflectCube");
1101                 p->loc_Texture_BounceGrid         = qglGetUniformLocation(p->program, "Texture_BounceGrid");
1102                 p->loc_Alpha                      = qglGetUniformLocation(p->program, "Alpha");
1103                 p->loc_BloomBlur_Parameters       = qglGetUniformLocation(p->program, "BloomBlur_Parameters");
1104                 p->loc_ClientTime                 = qglGetUniformLocation(p->program, "ClientTime");
1105                 p->loc_Color_Ambient              = qglGetUniformLocation(p->program, "Color_Ambient");
1106                 p->loc_Color_Diffuse              = qglGetUniformLocation(p->program, "Color_Diffuse");
1107                 p->loc_Color_Specular             = qglGetUniformLocation(p->program, "Color_Specular");
1108                 p->loc_Color_Glow                 = qglGetUniformLocation(p->program, "Color_Glow");
1109                 p->loc_Color_Pants                = qglGetUniformLocation(p->program, "Color_Pants");
1110                 p->loc_Color_Shirt                = qglGetUniformLocation(p->program, "Color_Shirt");
1111                 p->loc_DeferredColor_Ambient      = qglGetUniformLocation(p->program, "DeferredColor_Ambient");
1112                 p->loc_DeferredColor_Diffuse      = qglGetUniformLocation(p->program, "DeferredColor_Diffuse");
1113                 p->loc_DeferredColor_Specular     = qglGetUniformLocation(p->program, "DeferredColor_Specular");
1114                 p->loc_DeferredMod_Diffuse        = qglGetUniformLocation(p->program, "DeferredMod_Diffuse");
1115                 p->loc_DeferredMod_Specular       = qglGetUniformLocation(p->program, "DeferredMod_Specular");
1116                 p->loc_DistortScaleRefractReflect = qglGetUniformLocation(p->program, "DistortScaleRefractReflect");
1117                 p->loc_EyePosition                = qglGetUniformLocation(p->program, "EyePosition");
1118                 p->loc_FogColor                   = qglGetUniformLocation(p->program, "FogColor");
1119                 p->loc_FogHeightFade              = qglGetUniformLocation(p->program, "FogHeightFade");
1120                 p->loc_FogPlane                   = qglGetUniformLocation(p->program, "FogPlane");
1121                 p->loc_FogPlaneViewDist           = qglGetUniformLocation(p->program, "FogPlaneViewDist");
1122                 p->loc_FogRangeRecip              = qglGetUniformLocation(p->program, "FogRangeRecip");
1123                 p->loc_LightColor                 = qglGetUniformLocation(p->program, "LightColor");
1124                 p->loc_LightDir                   = qglGetUniformLocation(p->program, "LightDir");
1125                 p->loc_LightPosition              = qglGetUniformLocation(p->program, "LightPosition");
1126                 p->loc_OffsetMapping_ScaleSteps   = qglGetUniformLocation(p->program, "OffsetMapping_ScaleSteps");
1127                 p->loc_OffsetMapping_LodDistance  = qglGetUniformLocation(p->program, "OffsetMapping_LodDistance");
1128                 p->loc_OffsetMapping_Bias         = qglGetUniformLocation(p->program, "OffsetMapping_Bias");
1129                 p->loc_PixelSize                  = qglGetUniformLocation(p->program, "PixelSize");
1130                 p->loc_ReflectColor               = qglGetUniformLocation(p->program, "ReflectColor");
1131                 p->loc_ReflectFactor              = qglGetUniformLocation(p->program, "ReflectFactor");
1132                 p->loc_ReflectOffset              = qglGetUniformLocation(p->program, "ReflectOffset");
1133                 p->loc_RefractColor               = qglGetUniformLocation(p->program, "RefractColor");
1134                 p->loc_Saturation                 = qglGetUniformLocation(p->program, "Saturation");
1135                 p->loc_ScreenCenterRefractReflect = qglGetUniformLocation(p->program, "ScreenCenterRefractReflect");
1136                 p->loc_ScreenScaleRefractReflect  = qglGetUniformLocation(p->program, "ScreenScaleRefractReflect");
1137                 p->loc_ScreenToDepth              = qglGetUniformLocation(p->program, "ScreenToDepth");
1138                 p->loc_ShadowMap_Parameters       = qglGetUniformLocation(p->program, "ShadowMap_Parameters");
1139                 p->loc_ShadowMap_TextureScale     = qglGetUniformLocation(p->program, "ShadowMap_TextureScale");
1140                 p->loc_SpecularPower              = qglGetUniformLocation(p->program, "SpecularPower");
1141                 p->loc_UserVec1                   = qglGetUniformLocation(p->program, "UserVec1");
1142                 p->loc_UserVec2                   = qglGetUniformLocation(p->program, "UserVec2");
1143                 p->loc_UserVec3                   = qglGetUniformLocation(p->program, "UserVec3");
1144                 p->loc_UserVec4                   = qglGetUniformLocation(p->program, "UserVec4");
1145                 p->loc_ViewTintColor              = qglGetUniformLocation(p->program, "ViewTintColor");
1146                 p->loc_ViewToLight                = qglGetUniformLocation(p->program, "ViewToLight");
1147                 p->loc_ModelToLight               = qglGetUniformLocation(p->program, "ModelToLight");
1148                 p->loc_TexMatrix                  = qglGetUniformLocation(p->program, "TexMatrix");
1149                 p->loc_BackgroundTexMatrix        = qglGetUniformLocation(p->program, "BackgroundTexMatrix");
1150                 p->loc_ModelViewMatrix            = qglGetUniformLocation(p->program, "ModelViewMatrix");
1151                 p->loc_ModelViewProjectionMatrix  = qglGetUniformLocation(p->program, "ModelViewProjectionMatrix");
1152                 p->loc_PixelToScreenTexCoord      = qglGetUniformLocation(p->program, "PixelToScreenTexCoord");
1153                 p->loc_ModelToReflectCube         = qglGetUniformLocation(p->program, "ModelToReflectCube");
1154                 p->loc_ShadowMapMatrix            = qglGetUniformLocation(p->program, "ShadowMapMatrix");
1155                 p->loc_BloomColorSubtract         = qglGetUniformLocation(p->program, "BloomColorSubtract");
1156                 p->loc_NormalmapScrollBlend       = qglGetUniformLocation(p->program, "NormalmapScrollBlend");
1157                 p->loc_BounceGridMatrix           = qglGetUniformLocation(p->program, "BounceGridMatrix");
1158                 p->loc_BounceGridIntensity        = qglGetUniformLocation(p->program, "BounceGridIntensity");
1159                 // initialize the samplers to refer to the texture units we use
1160                 p->tex_Texture_First = -1;
1161                 p->tex_Texture_Second = -1;
1162                 p->tex_Texture_GammaRamps = -1;
1163                 p->tex_Texture_Normal = -1;
1164                 p->tex_Texture_Color = -1;
1165                 p->tex_Texture_Gloss = -1;
1166                 p->tex_Texture_Glow = -1;
1167                 p->tex_Texture_SecondaryNormal = -1;
1168                 p->tex_Texture_SecondaryColor = -1;
1169                 p->tex_Texture_SecondaryGloss = -1;
1170                 p->tex_Texture_SecondaryGlow = -1;
1171                 p->tex_Texture_Pants = -1;
1172                 p->tex_Texture_Shirt = -1;
1173                 p->tex_Texture_FogHeightTexture = -1;
1174                 p->tex_Texture_FogMask = -1;
1175                 p->tex_Texture_Lightmap = -1;
1176                 p->tex_Texture_Deluxemap = -1;
1177                 p->tex_Texture_Attenuation = -1;
1178                 p->tex_Texture_Cube = -1;
1179                 p->tex_Texture_Refraction = -1;
1180                 p->tex_Texture_Reflection = -1;
1181                 p->tex_Texture_ShadowMap2D = -1;
1182                 p->tex_Texture_CubeProjection = -1;
1183                 p->tex_Texture_ScreenNormalMap = -1;
1184                 p->tex_Texture_ScreenDiffuse = -1;
1185                 p->tex_Texture_ScreenSpecular = -1;
1186                 p->tex_Texture_ReflectMask = -1;
1187                 p->tex_Texture_ReflectCube = -1;
1188                 p->tex_Texture_BounceGrid = -1;
1189                 sampler = 0;
1190                 if (p->loc_Texture_First           >= 0) {p->tex_Texture_First            = sampler;qglUniform1i(p->loc_Texture_First           , sampler);sampler++;}
1191                 if (p->loc_Texture_Second          >= 0) {p->tex_Texture_Second           = sampler;qglUniform1i(p->loc_Texture_Second          , sampler);sampler++;}
1192                 if (p->loc_Texture_GammaRamps      >= 0) {p->tex_Texture_GammaRamps       = sampler;qglUniform1i(p->loc_Texture_GammaRamps      , sampler);sampler++;}
1193                 if (p->loc_Texture_Normal          >= 0) {p->tex_Texture_Normal           = sampler;qglUniform1i(p->loc_Texture_Normal          , sampler);sampler++;}
1194                 if (p->loc_Texture_Color           >= 0) {p->tex_Texture_Color            = sampler;qglUniform1i(p->loc_Texture_Color           , sampler);sampler++;}
1195                 if (p->loc_Texture_Gloss           >= 0) {p->tex_Texture_Gloss            = sampler;qglUniform1i(p->loc_Texture_Gloss           , sampler);sampler++;}
1196                 if (p->loc_Texture_Glow            >= 0) {p->tex_Texture_Glow             = sampler;qglUniform1i(p->loc_Texture_Glow            , sampler);sampler++;}
1197                 if (p->loc_Texture_SecondaryNormal >= 0) {p->tex_Texture_SecondaryNormal  = sampler;qglUniform1i(p->loc_Texture_SecondaryNormal , sampler);sampler++;}
1198                 if (p->loc_Texture_SecondaryColor  >= 0) {p->tex_Texture_SecondaryColor   = sampler;qglUniform1i(p->loc_Texture_SecondaryColor  , sampler);sampler++;}
1199                 if (p->loc_Texture_SecondaryGloss  >= 0) {p->tex_Texture_SecondaryGloss   = sampler;qglUniform1i(p->loc_Texture_SecondaryGloss  , sampler);sampler++;}
1200                 if (p->loc_Texture_SecondaryGlow   >= 0) {p->tex_Texture_SecondaryGlow    = sampler;qglUniform1i(p->loc_Texture_SecondaryGlow   , sampler);sampler++;}
1201                 if (p->loc_Texture_Pants           >= 0) {p->tex_Texture_Pants            = sampler;qglUniform1i(p->loc_Texture_Pants           , sampler);sampler++;}
1202                 if (p->loc_Texture_Shirt           >= 0) {p->tex_Texture_Shirt            = sampler;qglUniform1i(p->loc_Texture_Shirt           , sampler);sampler++;}
1203                 if (p->loc_Texture_FogHeightTexture>= 0) {p->tex_Texture_FogHeightTexture = sampler;qglUniform1i(p->loc_Texture_FogHeightTexture, sampler);sampler++;}
1204                 if (p->loc_Texture_FogMask         >= 0) {p->tex_Texture_FogMask          = sampler;qglUniform1i(p->loc_Texture_FogMask         , sampler);sampler++;}
1205                 if (p->loc_Texture_Lightmap        >= 0) {p->tex_Texture_Lightmap         = sampler;qglUniform1i(p->loc_Texture_Lightmap        , sampler);sampler++;}
1206                 if (p->loc_Texture_Deluxemap       >= 0) {p->tex_Texture_Deluxemap        = sampler;qglUniform1i(p->loc_Texture_Deluxemap       , sampler);sampler++;}
1207                 if (p->loc_Texture_Attenuation     >= 0) {p->tex_Texture_Attenuation      = sampler;qglUniform1i(p->loc_Texture_Attenuation     , sampler);sampler++;}
1208                 if (p->loc_Texture_Cube            >= 0) {p->tex_Texture_Cube             = sampler;qglUniform1i(p->loc_Texture_Cube            , sampler);sampler++;}
1209                 if (p->loc_Texture_Refraction      >= 0) {p->tex_Texture_Refraction       = sampler;qglUniform1i(p->loc_Texture_Refraction      , sampler);sampler++;}
1210                 if (p->loc_Texture_Reflection      >= 0) {p->tex_Texture_Reflection       = sampler;qglUniform1i(p->loc_Texture_Reflection      , sampler);sampler++;}
1211                 if (p->loc_Texture_ShadowMap2D     >= 0) {p->tex_Texture_ShadowMap2D      = sampler;qglUniform1i(p->loc_Texture_ShadowMap2D     , sampler);sampler++;}
1212                 if (p->loc_Texture_CubeProjection  >= 0) {p->tex_Texture_CubeProjection   = sampler;qglUniform1i(p->loc_Texture_CubeProjection  , sampler);sampler++;}
1213                 if (p->loc_Texture_ScreenNormalMap >= 0) {p->tex_Texture_ScreenNormalMap  = sampler;qglUniform1i(p->loc_Texture_ScreenNormalMap , sampler);sampler++;}
1214                 if (p->loc_Texture_ScreenDiffuse   >= 0) {p->tex_Texture_ScreenDiffuse    = sampler;qglUniform1i(p->loc_Texture_ScreenDiffuse   , sampler);sampler++;}
1215                 if (p->loc_Texture_ScreenSpecular  >= 0) {p->tex_Texture_ScreenSpecular   = sampler;qglUniform1i(p->loc_Texture_ScreenSpecular  , sampler);sampler++;}
1216                 if (p->loc_Texture_ReflectMask     >= 0) {p->tex_Texture_ReflectMask      = sampler;qglUniform1i(p->loc_Texture_ReflectMask     , sampler);sampler++;}
1217                 if (p->loc_Texture_ReflectCube     >= 0) {p->tex_Texture_ReflectCube      = sampler;qglUniform1i(p->loc_Texture_ReflectCube     , sampler);sampler++;}
1218                 if (p->loc_Texture_BounceGrid      >= 0) {p->tex_Texture_BounceGrid       = sampler;qglUniform1i(p->loc_Texture_BounceGrid      , sampler);sampler++;}
1219                 CHECKGLERROR
1220                 Con_DPrintf("^5GLSL shader %s compiled (%i textures).\n", permutationname, sampler);
1221         }
1222         else
1223                 Con_Printf("^1GLSL shader %s failed!  some features may not work properly.\n", permutationname);
1224
1225         // free the strings
1226         if (vertexstring)
1227                 Mem_Free(vertexstring);
1228         if (geometrystring)
1229                 Mem_Free(geometrystring);
1230         if (fragmentstring)
1231                 Mem_Free(fragmentstring);
1232 }
1233
1234 static void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutation)
1235 {
1236         r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
1237         if (r_glsl_permutation != perm)
1238         {
1239                 r_glsl_permutation = perm;
1240                 if (!r_glsl_permutation->program)
1241                 {
1242                         if (!r_glsl_permutation->compiled)
1243                                 R_GLSL_CompilePermutation(perm, mode, permutation);
1244                         if (!r_glsl_permutation->program)
1245                         {
1246                                 // remove features until we find a valid permutation
1247                                 int i;
1248                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1249                                 {
1250                                         // reduce i more quickly whenever it would not remove any bits
1251                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
1252                                         if (!(permutation & j))
1253                                                 continue;
1254                                         permutation -= j;
1255                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1256                                         if (!r_glsl_permutation->compiled)
1257                                                 R_GLSL_CompilePermutation(perm, mode, permutation);
1258                                         if (r_glsl_permutation->program)
1259                                                 break;
1260                                 }
1261                                 if (i >= SHADERPERMUTATION_COUNT)
1262                                 {
1263                                         //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
1264                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1265                                         qglUseProgram(0);CHECKGLERROR
1266                                         return; // no bit left to clear, entire mode is broken
1267                                 }
1268                         }
1269                 }
1270                 CHECKGLERROR
1271                 qglUseProgram(r_glsl_permutation->program);CHECKGLERROR
1272         }
1273         if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
1274         if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
1275         if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1f(r_glsl_permutation->loc_ClientTime, cl.time);
1276 }
1277
1278 #ifdef SUPPORTD3D
1279
1280 #ifdef SUPPORTD3D
1281 #include <d3d9.h>
1282 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
1283 extern D3DCAPS9 vid_d3d9caps;
1284 #endif
1285
1286 struct r_hlsl_permutation_s;
1287 typedef struct r_hlsl_permutation_s
1288 {
1289         /// hash lookup data
1290         struct r_hlsl_permutation_s *hashnext;
1291         unsigned int mode;
1292         unsigned int permutation;
1293
1294         /// indicates if we have tried compiling this permutation already
1295         qboolean compiled;
1296         /// NULL if compilation failed
1297         IDirect3DVertexShader9 *vertexshader;
1298         IDirect3DPixelShader9 *pixelshader;
1299 }
1300 r_hlsl_permutation_t;
1301
1302 typedef enum D3DVSREGISTER_e
1303 {
1304         D3DVSREGISTER_TexMatrix = 0, // float4x4
1305         D3DVSREGISTER_BackgroundTexMatrix = 4, // float4x4
1306         D3DVSREGISTER_ModelViewProjectionMatrix = 8, // float4x4
1307         D3DVSREGISTER_ModelViewMatrix = 12, // float4x4
1308         D3DVSREGISTER_ShadowMapMatrix = 16, // float4x4
1309         D3DVSREGISTER_ModelToLight = 20, // float4x4
1310         D3DVSREGISTER_EyePosition = 24,
1311         D3DVSREGISTER_FogPlane = 25,
1312         D3DVSREGISTER_LightDir = 26,
1313         D3DVSREGISTER_LightPosition = 27,
1314 }
1315 D3DVSREGISTER_t;
1316
1317 typedef enum D3DPSREGISTER_e
1318 {
1319         D3DPSREGISTER_Alpha = 0,
1320         D3DPSREGISTER_BloomBlur_Parameters = 1,
1321         D3DPSREGISTER_ClientTime = 2,
1322         D3DPSREGISTER_Color_Ambient = 3,
1323         D3DPSREGISTER_Color_Diffuse = 4,
1324         D3DPSREGISTER_Color_Specular = 5,
1325         D3DPSREGISTER_Color_Glow = 6,
1326         D3DPSREGISTER_Color_Pants = 7,
1327         D3DPSREGISTER_Color_Shirt = 8,
1328         D3DPSREGISTER_DeferredColor_Ambient = 9,
1329         D3DPSREGISTER_DeferredColor_Diffuse = 10,
1330         D3DPSREGISTER_DeferredColor_Specular = 11,
1331         D3DPSREGISTER_DeferredMod_Diffuse = 12,
1332         D3DPSREGISTER_DeferredMod_Specular = 13,
1333         D3DPSREGISTER_DistortScaleRefractReflect = 14,
1334         D3DPSREGISTER_EyePosition = 15, // unused
1335         D3DPSREGISTER_FogColor = 16,
1336         D3DPSREGISTER_FogHeightFade = 17,
1337         D3DPSREGISTER_FogPlane = 18,
1338         D3DPSREGISTER_FogPlaneViewDist = 19,
1339         D3DPSREGISTER_FogRangeRecip = 20,
1340         D3DPSREGISTER_LightColor = 21,
1341         D3DPSREGISTER_LightDir = 22, // unused
1342         D3DPSREGISTER_LightPosition = 23,
1343         D3DPSREGISTER_OffsetMapping_ScaleSteps = 24,
1344         D3DPSREGISTER_PixelSize = 25,
1345         D3DPSREGISTER_ReflectColor = 26,
1346         D3DPSREGISTER_ReflectFactor = 27,
1347         D3DPSREGISTER_ReflectOffset = 28,
1348         D3DPSREGISTER_RefractColor = 29,
1349         D3DPSREGISTER_Saturation = 30,
1350         D3DPSREGISTER_ScreenCenterRefractReflect = 31,
1351         D3DPSREGISTER_ScreenScaleRefractReflect = 32,
1352         D3DPSREGISTER_ScreenToDepth = 33,
1353         D3DPSREGISTER_ShadowMap_Parameters = 34,
1354         D3DPSREGISTER_ShadowMap_TextureScale = 35,
1355         D3DPSREGISTER_SpecularPower = 36,
1356         D3DPSREGISTER_UserVec1 = 37,
1357         D3DPSREGISTER_UserVec2 = 38,
1358         D3DPSREGISTER_UserVec3 = 39,
1359         D3DPSREGISTER_UserVec4 = 40,
1360         D3DPSREGISTER_ViewTintColor = 41,
1361         D3DPSREGISTER_PixelToScreenTexCoord = 42,
1362         D3DPSREGISTER_BloomColorSubtract = 43,
1363         D3DPSREGISTER_ViewToLight = 44, // float4x4
1364         D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
1365         D3DPSREGISTER_NormalmapScrollBlend = 52,
1366         D3DPSREGISTER_OffsetMapping_LodDistance = 53,
1367         D3DPSREGISTER_OffsetMapping_Bias = 54,
1368         // next at 54
1369 }
1370 D3DPSREGISTER_t;
1371
1372 /// information about each possible shader permutation
1373 r_hlsl_permutation_t *r_hlsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
1374 /// currently selected permutation
1375 r_hlsl_permutation_t *r_hlsl_permutation;
1376 /// storage for permutations linked in the hash table
1377 memexpandablearray_t r_hlsl_permutationarray;
1378
1379 static r_hlsl_permutation_t *R_HLSL_FindPermutation(unsigned int mode, unsigned int permutation)
1380 {
1381         //unsigned int hashdepth = 0;
1382         unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
1383         r_hlsl_permutation_t *p;
1384         for (p = r_hlsl_permutationhash[mode][hashindex];p;p = p->hashnext)
1385         {
1386                 if (p->mode == mode && p->permutation == permutation)
1387                 {
1388                         //if (hashdepth > 10)
1389                         //      Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1390                         return p;
1391                 }
1392                 //hashdepth++;
1393         }
1394         p = (r_hlsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_hlsl_permutationarray);
1395         p->mode = mode;
1396         p->permutation = permutation;
1397         p->hashnext = r_hlsl_permutationhash[mode][hashindex];
1398         r_hlsl_permutationhash[mode][hashindex] = p;
1399         //if (hashdepth > 10)
1400         //      Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1401         return p;
1402 }
1403
1404 static char *R_HLSL_GetText(const char *filename, qboolean printfromdisknotice)
1405 {
1406         char *shaderstring;
1407         if (!filename || !filename[0])
1408                 return NULL;
1409         if (!strcmp(filename, "hlsl/default.hlsl"))
1410         {
1411                 if (!hlslshaderstring)
1412                 {
1413                         hlslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1414                         if (hlslshaderstring)
1415                                 Con_DPrintf("Loading shaders from file %s...\n", filename);
1416                         else
1417                                 hlslshaderstring = (char *)builtinhlslshaderstring;
1418                 }
1419                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(hlslshaderstring) + 1);
1420                 memcpy(shaderstring, hlslshaderstring, strlen(hlslshaderstring) + 1);
1421                 return shaderstring;
1422         }
1423         shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1424         if (shaderstring)
1425         {
1426                 if (printfromdisknotice)
1427                         Con_DPrintf("from disk %s... ", filename);
1428                 return shaderstring;
1429         }
1430         return shaderstring;
1431 }
1432
1433 #include <d3dx9.h>
1434 //#include <d3dx9shader.h>
1435 //#include <d3dx9mesh.h>
1436
1437 static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
1438 {
1439         DWORD *vsbin = NULL;
1440         DWORD *psbin = NULL;
1441         fs_offset_t vsbinsize;
1442         fs_offset_t psbinsize;
1443 //      IDirect3DVertexShader9 *vs = NULL;
1444 //      IDirect3DPixelShader9 *ps = NULL;
1445         ID3DXBuffer *vslog = NULL;
1446         ID3DXBuffer *vsbuffer = NULL;
1447         ID3DXConstantTable *vsconstanttable = NULL;
1448         ID3DXBuffer *pslog = NULL;
1449         ID3DXBuffer *psbuffer = NULL;
1450         ID3DXConstantTable *psconstanttable = NULL;
1451         int vsresult = 0;
1452         int psresult = 0;
1453         char temp[MAX_INPUTLINE];
1454         const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
1455         char vabuf[1024];
1456         qboolean debugshader = gl_paranoid.integer != 0;
1457         if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1458         if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1459         if (!debugshader)
1460         {
1461                 vsbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
1462                 psbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.psbin", cachename), r_main_mempool, true, &psbinsize);
1463         }
1464         if ((!vsbin && vertstring) || (!psbin && fragstring))
1465         {
1466                 const char* dllnames_d3dx9 [] =
1467                 {
1468                         "d3dx9_43.dll",
1469                         "d3dx9_42.dll",
1470                         "d3dx9_41.dll",
1471                         "d3dx9_40.dll",
1472                         "d3dx9_39.dll",
1473                         "d3dx9_38.dll",
1474                         "d3dx9_37.dll",
1475                         "d3dx9_36.dll",
1476                         "d3dx9_35.dll",
1477                         "d3dx9_34.dll",
1478                         "d3dx9_33.dll",
1479                         "d3dx9_32.dll",
1480                         "d3dx9_31.dll",
1481                         "d3dx9_30.dll",
1482                         "d3dx9_29.dll",
1483                         "d3dx9_28.dll",
1484                         "d3dx9_27.dll",
1485                         "d3dx9_26.dll",
1486                         "d3dx9_25.dll",
1487                         "d3dx9_24.dll",
1488                         NULL
1489                 };
1490                 dllhandle_t d3dx9_dll = NULL;
1491                 HRESULT (WINAPI *qD3DXCompileShaderFromFileA)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1492                 HRESULT (WINAPI *qD3DXPreprocessShader)(LPCSTR pSrcData, UINT SrcDataSize, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs);
1493                 HRESULT (WINAPI *qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1494                 dllfunction_t d3dx9_dllfuncs[] =
1495                 {
1496                         {"D3DXCompileShaderFromFileA",  (void **) &qD3DXCompileShaderFromFileA},
1497                         {"D3DXPreprocessShader",                (void **) &qD3DXPreprocessShader},
1498                         {"D3DXCompileShader",                   (void **) &qD3DXCompileShader},
1499                         {NULL, NULL}
1500                 };
1501                 if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
1502                 {
1503                         DWORD shaderflags = 0;
1504                         if (debugshader)
1505                                 shaderflags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
1506                         vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1507                         psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1508                         if (vertstring && vertstring[0])
1509                         {
1510                                 if (debugshader)
1511                                 {
1512 //                                      vsresult = qD3DXPreprocessShader(vertstring, strlen(vertstring), NULL, NULL, &vsbuffer, &vslog);
1513 //                                      FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_vs.fx", cachename), vsbuffer->GetBufferPointer(), vsbuffer->GetBufferSize());
1514                                         FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_vs.fx", cachename), vertstring, strlen(vertstring));
1515                                         vsresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1516                                 }
1517                                 else
1518                                         vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1519                                 if (vsbuffer)
1520                                 {
1521                                         vsbinsize = vsbuffer->GetBufferSize();
1522                                         vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
1523                                         memcpy(vsbin, vsbuffer->GetBufferPointer(), vsbinsize);
1524                                         vsbuffer->Release();
1525                                 }
1526                                 if (vslog)
1527                                 {
1528                                         strlcpy(temp, (const char *)vslog->GetBufferPointer(), min(sizeof(temp), vslog->GetBufferSize()));
1529                                         Con_DPrintf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
1530                                         vslog->Release();
1531                                 }
1532                         }
1533                         if (fragstring && fragstring[0])
1534                         {
1535                                 if (debugshader)
1536                                 {
1537 //                                      psresult = qD3DXPreprocessShader(fragstring, strlen(fragstring), NULL, NULL, &psbuffer, &pslog);
1538 //                                      FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_ps.fx", cachename), psbuffer->GetBufferPointer(), psbuffer->GetBufferSize());
1539                                         FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_ps.fx", cachename), fragstring, strlen(fragstring));
1540                                         psresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1541                                 }
1542                                 else
1543                                         psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1544                                 if (psbuffer)
1545                                 {
1546                                         psbinsize = psbuffer->GetBufferSize();
1547                                         psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
1548                                         memcpy(psbin, psbuffer->GetBufferPointer(), psbinsize);
1549                                         psbuffer->Release();
1550                                 }
1551                                 if (pslog)
1552                                 {
1553                                         strlcpy(temp, (const char *)pslog->GetBufferPointer(), min(sizeof(temp), pslog->GetBufferSize()));
1554                                         Con_DPrintf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
1555                                         pslog->Release();
1556                                 }
1557                         }
1558                         Sys_UnloadLibrary(&d3dx9_dll);
1559                 }
1560                 else
1561                         Con_DPrintf("Unable to compile shader - D3DXCompileShader function not found\n");
1562         }
1563         if (vsbin && psbin)
1564         {
1565                 vsresult = IDirect3DDevice9_CreateVertexShader(vid_d3d9dev, vsbin, &p->vertexshader);
1566                 if (FAILED(vsresult))
1567                         Con_DPrintf("HLSL CreateVertexShader failed for %s (hresult = %8x)\n", cachename, vsresult);
1568                 psresult = IDirect3DDevice9_CreatePixelShader(vid_d3d9dev, psbin, &p->pixelshader);
1569                 if (FAILED(psresult))
1570                         Con_DPrintf("HLSL CreatePixelShader failed for %s (hresult = %8x)\n", cachename, psresult);
1571         }
1572         // free the shader data
1573         vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1574         psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1575 }
1576
1577 static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode, unsigned int permutation)
1578 {
1579         int i;
1580         shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
1581         int vertstring_length = 0;
1582         int geomstring_length = 0;
1583         int fragstring_length = 0;
1584         char *t;
1585         char *vertexstring, *geometrystring, *fragmentstring;
1586         char *vertstring, *geomstring, *fragstring;
1587         char permutationname[256];
1588         char cachename[256];
1589         int vertstrings_count = 0;
1590         int geomstrings_count = 0;
1591         int fragstrings_count = 0;
1592         const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1593         const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1594         const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1595
1596         if (p->compiled)
1597                 return;
1598         p->compiled = true;
1599         p->vertexshader = NULL;
1600         p->pixelshader = NULL;
1601
1602         permutationname[0] = 0;
1603         cachename[0] = 0;
1604         vertexstring   = R_HLSL_GetText(modeinfo->vertexfilename, true);
1605         geometrystring = R_HLSL_GetText(modeinfo->geometryfilename, false);
1606         fragmentstring = R_HLSL_GetText(modeinfo->fragmentfilename, false);
1607
1608         strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
1609         strlcat(cachename, "hlsl/", sizeof(cachename));
1610
1611         // define HLSL so that the shader can tell apart the HLSL compiler and the Cg compiler
1612         vertstrings_count = 0;
1613         geomstrings_count = 0;
1614         fragstrings_count = 0;
1615         vertstrings_list[vertstrings_count++] = "#define HLSL\n";
1616         geomstrings_list[geomstrings_count++] = "#define HLSL\n";
1617         fragstrings_list[fragstrings_count++] = "#define HLSL\n";
1618
1619         // the first pretext is which type of shader to compile as
1620         // (later these will all be bound together as a program object)
1621         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1622         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1623         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1624
1625         // the second pretext is the mode (for example a light source)
1626         vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1627         geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1628         fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1629         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1630         strlcat(cachename, modeinfo->name, sizeof(cachename));
1631
1632         // now add all the permutation pretexts
1633         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1634         {
1635                 if (permutation & (1<<i))
1636                 {
1637                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1638                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1639                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1640                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1641                         strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename));
1642                 }
1643                 else
1644                 {
1645                         // keep line numbers correct
1646                         vertstrings_list[vertstrings_count++] = "\n";
1647                         geomstrings_list[geomstrings_count++] = "\n";
1648                         fragstrings_list[fragstrings_count++] = "\n";
1649                 }
1650         }
1651
1652         // add static parms
1653         R_CompileShader_AddStaticParms(mode, permutation);
1654         memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1655         vertstrings_count += shaderstaticparms_count;
1656         memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1657         geomstrings_count += shaderstaticparms_count;
1658         memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1659         fragstrings_count += shaderstaticparms_count;
1660
1661         // replace spaces in the cachename with _ characters
1662         for (i = 0;cachename[i];i++)
1663                 if (cachename[i] == ' ')
1664                         cachename[i] = '_';
1665
1666         // now append the shader text itself
1667         vertstrings_list[vertstrings_count++] = vertexstring;
1668         geomstrings_list[geomstrings_count++] = geometrystring;
1669         fragstrings_list[fragstrings_count++] = fragmentstring;
1670
1671         // if any sources were NULL, clear the respective list
1672         if (!vertexstring)
1673                 vertstrings_count = 0;
1674         if (!geometrystring)
1675                 geomstrings_count = 0;
1676         if (!fragmentstring)
1677                 fragstrings_count = 0;
1678
1679         vertstring_length = 0;
1680         for (i = 0;i < vertstrings_count;i++)
1681                 vertstring_length += strlen(vertstrings_list[i]);
1682         vertstring = t = (char *)Mem_Alloc(tempmempool, vertstring_length + 1);
1683         for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
1684                 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
1685
1686         geomstring_length = 0;
1687         for (i = 0;i < geomstrings_count;i++)
1688                 geomstring_length += strlen(geomstrings_list[i]);
1689         geomstring = t = (char *)Mem_Alloc(tempmempool, geomstring_length + 1);
1690         for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
1691                 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
1692
1693         fragstring_length = 0;
1694         for (i = 0;i < fragstrings_count;i++)
1695                 fragstring_length += strlen(fragstrings_list[i]);
1696         fragstring = t = (char *)Mem_Alloc(tempmempool, fragstring_length + 1);
1697         for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
1698                 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
1699
1700         // try to load the cached shader, or generate one
1701         R_HLSL_CacheShader(p, cachename, vertstring, fragstring);
1702
1703         if ((p->vertexshader || !vertstring[0]) && (p->pixelshader || !fragstring[0]))
1704                 Con_DPrintf("^5HLSL shader %s compiled.\n", permutationname);
1705         else
1706                 Con_Printf("^1HLSL shader %s failed!  some features may not work properly.\n", permutationname);
1707
1708         // free the strings
1709         if (vertstring)
1710                 Mem_Free(vertstring);
1711         if (geomstring)
1712                 Mem_Free(geomstring);
1713         if (fragstring)
1714                 Mem_Free(fragstring);
1715         if (vertexstring)
1716                 Mem_Free(vertexstring);
1717         if (geometrystring)
1718                 Mem_Free(geometrystring);
1719         if (fragmentstring)
1720                 Mem_Free(fragmentstring);
1721 }
1722
1723 static inline void hlslVSSetParameter16f(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 4);}
1724 static inline void hlslVSSetParameter4fv(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 1);}
1725 static inline void hlslVSSetParameter4f(D3DVSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1726 static inline void hlslVSSetParameter3f(D3DVSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1727 static inline void hlslVSSetParameter2f(D3DVSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1728 static inline void hlslVSSetParameter1f(D3DVSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1729
1730 static inline void hlslPSSetParameter16f(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 4);}
1731 static inline void hlslPSSetParameter4fv(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 1);}
1732 static inline void hlslPSSetParameter4f(D3DPSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1733 static inline void hlslPSSetParameter3f(D3DPSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1734 static inline void hlslPSSetParameter2f(D3DPSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1735 static inline void hlslPSSetParameter1f(D3DPSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1736
1737 void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutation)
1738 {
1739         r_hlsl_permutation_t *perm = R_HLSL_FindPermutation(mode, permutation);
1740         if (r_hlsl_permutation != perm)
1741         {
1742                 r_hlsl_permutation = perm;
1743                 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1744                 {
1745                         if (!r_hlsl_permutation->compiled)
1746                                 R_HLSL_CompilePermutation(perm, mode, permutation);
1747                         if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1748                         {
1749                                 // remove features until we find a valid permutation
1750                                 int i;
1751                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1752                                 {
1753                                         // reduce i more quickly whenever it would not remove any bits
1754                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
1755                                         if (!(permutation & j))
1756                                                 continue;
1757                                         permutation -= j;
1758                                         r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1759                                         if (!r_hlsl_permutation->compiled)
1760                                                 R_HLSL_CompilePermutation(perm, mode, permutation);
1761                                         if (r_hlsl_permutation->vertexshader || r_hlsl_permutation->pixelshader)
1762                                                 break;
1763                                 }
1764                                 if (i >= SHADERPERMUTATION_COUNT)
1765                                 {
1766                                         //Con_Printf("Could not find a working HLSL shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
1767                                         r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1768                                         return; // no bit left to clear, entire mode is broken
1769                                 }
1770                         }
1771                 }
1772                 IDirect3DDevice9_SetVertexShader(vid_d3d9dev, r_hlsl_permutation->vertexshader);
1773                 IDirect3DDevice9_SetPixelShader(vid_d3d9dev, r_hlsl_permutation->pixelshader);
1774         }
1775         hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
1776         hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
1777         hlslPSSetParameter1f(D3DPSREGISTER_ClientTime, cl.time);
1778 }
1779 #endif
1780
1781 static void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
1782 {
1783         DPSOFTRAST_SetShader(mode, permutation, r_shadow_glossexact.integer);
1784         DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
1785         DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
1786         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
1787 }
1788
1789 static void R_GLSL_Restart_f(void)
1790 {
1791         unsigned int i, limit;
1792         if (glslshaderstring && glslshaderstring != builtinshaderstring)
1793                 Mem_Free(glslshaderstring);
1794         glslshaderstring = NULL;
1795         if (hlslshaderstring && hlslshaderstring != builtinhlslshaderstring)
1796                 Mem_Free(hlslshaderstring);
1797         hlslshaderstring = NULL;
1798         switch(vid.renderpath)
1799         {
1800         case RENDERPATH_D3D9:
1801 #ifdef SUPPORTD3D
1802                 {
1803                         r_hlsl_permutation_t *p;
1804                         r_hlsl_permutation = NULL;
1805                         limit = Mem_ExpandableArray_IndexRange(&r_hlsl_permutationarray);
1806                         for (i = 0;i < limit;i++)
1807                         {
1808                                 if ((p = (r_hlsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_hlsl_permutationarray, i)))
1809                                 {
1810                                         if (p->vertexshader)
1811                                                 IDirect3DVertexShader9_Release(p->vertexshader);
1812                                         if (p->pixelshader)
1813                                                 IDirect3DPixelShader9_Release(p->pixelshader);
1814                                         Mem_ExpandableArray_FreeRecord(&r_hlsl_permutationarray, (void*)p);
1815                                 }
1816                         }
1817                         memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
1818                 }
1819 #endif
1820                 break;
1821         case RENDERPATH_D3D10:
1822                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1823                 break;
1824         case RENDERPATH_D3D11:
1825                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1826                 break;
1827         case RENDERPATH_GL20:
1828         case RENDERPATH_GLES2:
1829                 {
1830                         r_glsl_permutation_t *p;
1831                         r_glsl_permutation = NULL;
1832                         limit = Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
1833                         for (i = 0;i < limit;i++)
1834                         {
1835                                 if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
1836                                 {
1837                                         GL_Backend_FreeProgram(p->program);
1838                                         Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
1839                                 }
1840                         }
1841                         memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
1842                 }
1843                 break;
1844         case RENDERPATH_GL11:
1845         case RENDERPATH_GL13:
1846         case RENDERPATH_GLES1:
1847                 break;
1848         case RENDERPATH_SOFT:
1849                 break;
1850         }
1851 }
1852
1853 static void R_GLSL_DumpShader_f(void)
1854 {
1855         int i;
1856         qfile_t *file;
1857
1858         file = FS_OpenRealFile("glsl/default.glsl", "w", false);
1859         if (file)
1860         {
1861                 FS_Print(file, "/* The engine may define the following macros:\n");
1862                 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
1863                 for (i = 0;i < SHADERMODE_COUNT;i++)
1864                         FS_Print(file, glslshadermodeinfo[i].pretext);
1865                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1866                         FS_Print(file, shaderpermutationinfo[i].pretext);
1867                 FS_Print(file, "*/\n");
1868                 FS_Print(file, builtinshaderstring);
1869                 FS_Close(file);
1870                 Con_Printf("glsl/default.glsl written\n");
1871         }
1872         else
1873                 Con_Printf("failed to write to glsl/default.glsl\n");
1874
1875         file = FS_OpenRealFile("hlsl/default.hlsl", "w", false);
1876         if (file)
1877         {
1878                 FS_Print(file, "/* The engine may define the following macros:\n");
1879                 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
1880                 for (i = 0;i < SHADERMODE_COUNT;i++)
1881                         FS_Print(file, hlslshadermodeinfo[i].pretext);
1882                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1883                         FS_Print(file, shaderpermutationinfo[i].pretext);
1884                 FS_Print(file, "*/\n");
1885                 FS_Print(file, builtinhlslshaderstring);
1886                 FS_Close(file);
1887                 Con_Printf("hlsl/default.hlsl written\n");
1888         }
1889         else
1890                 Con_Printf("failed to write to hlsl/default.hlsl\n");
1891 }
1892
1893 void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale, qboolean usegamma, qboolean notrippy, qboolean suppresstexalpha)
1894 {
1895         unsigned int permutation = 0;
1896         if (r_trippy.integer && !notrippy)
1897                 permutation |= SHADERPERMUTATION_TRIPPY;
1898         permutation |= SHADERPERMUTATION_VIEWTINT;
1899         if (first)
1900                 permutation |= SHADERPERMUTATION_DIFFUSE;
1901         if (second)
1902                 permutation |= SHADERPERMUTATION_SPECULAR;
1903         if (texturemode == GL_MODULATE)
1904                 permutation |= SHADERPERMUTATION_COLORMAPPING;
1905         else if (texturemode == GL_ADD)
1906                 permutation |= SHADERPERMUTATION_GLOW;
1907         else if (texturemode == GL_DECAL)
1908                 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
1909         if (usegamma && v_glslgamma.integer && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
1910                 permutation |= SHADERPERMUTATION_GAMMARAMPS;
1911         if (suppresstexalpha)
1912                 permutation |= SHADERPERMUTATION_REFLECTCUBE;
1913         if (!second)
1914                 texturemode = GL_MODULATE;
1915         if (vid.allowalphatocoverage)
1916                 GL_AlphaToCoverage(false);
1917         switch (vid.renderpath)
1918         {
1919         case RENDERPATH_D3D9:
1920 #ifdef SUPPORTD3D
1921                 R_SetupShader_SetPermutationHLSL(SHADERMODE_GENERIC, permutation);
1922                 R_Mesh_TexBind(GL20TU_FIRST , first );
1923                 R_Mesh_TexBind(GL20TU_SECOND, second);
1924                 if (permutation & SHADERPERMUTATION_GAMMARAMPS)
1925                         R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
1926 #endif
1927                 break;
1928         case RENDERPATH_D3D10:
1929                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1930                 break;
1931         case RENDERPATH_D3D11:
1932                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1933                 break;
1934         case RENDERPATH_GL20:
1935         case RENDERPATH_GLES2:
1936                 R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, permutation);
1937                 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , first );
1938                 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second);
1939                 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0)
1940                         R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
1941                 break;
1942         case RENDERPATH_GL13:
1943         case RENDERPATH_GLES1:
1944                 R_Mesh_TexBind(0, first );
1945                 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
1946                 R_Mesh_TexBind(1, second);
1947                 if (second)
1948                         R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
1949                 break;
1950         case RENDERPATH_GL11:
1951                 R_Mesh_TexBind(0, first );
1952                 break;
1953         case RENDERPATH_SOFT:
1954                 R_SetupShader_SetPermutationSoft(SHADERMODE_GENERIC, permutation);
1955                 R_Mesh_TexBind(GL20TU_FIRST , first );
1956                 R_Mesh_TexBind(GL20TU_SECOND, second);
1957                 break;
1958         }
1959 }
1960
1961 void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy)
1962 {
1963         R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, usegamma, notrippy, false);
1964 }
1965
1966 void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb)
1967 {
1968         unsigned int permutation = 0;
1969         if (r_trippy.integer && !notrippy)
1970                 permutation |= SHADERPERMUTATION_TRIPPY;
1971         if (depthrgb)
1972                 permutation |= SHADERPERMUTATION_DEPTHRGB;
1973         if (vid.allowalphatocoverage)
1974                 GL_AlphaToCoverage(false);
1975         switch (vid.renderpath)
1976         {
1977         case RENDERPATH_D3D9:
1978 #ifdef SUPPORTD3D
1979                 R_SetupShader_SetPermutationHLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
1980 #endif
1981                 break;
1982         case RENDERPATH_D3D10:
1983                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1984                 break;
1985         case RENDERPATH_D3D11:
1986                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1987                 break;
1988         case RENDERPATH_GL20:
1989         case RENDERPATH_GLES2:
1990                 R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
1991                 break;
1992         case RENDERPATH_GL13:
1993         case RENDERPATH_GLES1:
1994                 R_Mesh_TexBind(0, 0);
1995                 R_Mesh_TexBind(1, 0);
1996                 break;
1997         case RENDERPATH_GL11:
1998                 R_Mesh_TexBind(0, 0);
1999                 break;
2000         case RENDERPATH_SOFT:
2001                 R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2002                 break;
2003         }
2004 }
2005
2006 void R_SetupShader_ShowDepth(qboolean notrippy)
2007 {
2008         int permutation = 0;
2009         if (r_trippy.integer && !notrippy)
2010                 permutation |= SHADERPERMUTATION_TRIPPY;
2011         if (vid.allowalphatocoverage)
2012                 GL_AlphaToCoverage(false);
2013         switch (vid.renderpath)
2014         {
2015         case RENDERPATH_D3D9:
2016 #ifdef SUPPORTHLSL
2017                 R_SetupShader_SetPermutationHLSL(SHADERMODE_SHOWDEPTH, permutation);
2018 #endif
2019                 break;
2020         case RENDERPATH_D3D10:
2021                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2022                 break;
2023         case RENDERPATH_D3D11:
2024                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2025                 break;
2026         case RENDERPATH_GL20:
2027         case RENDERPATH_GLES2:
2028                 R_SetupShader_SetPermutationGLSL(SHADERMODE_SHOWDEPTH, permutation);
2029                 break;
2030         case RENDERPATH_GL13:
2031         case RENDERPATH_GLES1:
2032                 break;
2033         case RENDERPATH_GL11:
2034                 break;
2035         case RENDERPATH_SOFT:
2036                 R_SetupShader_SetPermutationSoft(SHADERMODE_SHOWDEPTH, permutation);
2037                 break;
2038         }
2039 }
2040
2041 extern qboolean r_shadow_usingdeferredprepass;
2042 extern rtexture_t *r_shadow_attenuationgradienttexture;
2043 extern rtexture_t *r_shadow_attenuation2dtexture;
2044 extern rtexture_t *r_shadow_attenuation3dtexture;
2045 extern qboolean r_shadow_usingshadowmap2d;
2046 extern qboolean r_shadow_usingshadowmaportho;
2047 extern float r_shadow_shadowmap_texturescale[2];
2048 extern float r_shadow_shadowmap_parameters[4];
2049 extern qboolean r_shadow_shadowmapvsdct;
2050 extern qboolean r_shadow_shadowmapsampler;
2051 extern int r_shadow_shadowmappcf;
2052 extern rtexture_t *r_shadow_shadowmap2ddepthbuffer;
2053 extern rtexture_t *r_shadow_shadowmap2ddepthtexture;
2054 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
2055 extern matrix4x4_t r_shadow_shadowmapmatrix;
2056 extern int r_shadow_shadowmaplod; // changes for each light based on distance
2057 extern int r_shadow_prepass_width;
2058 extern int r_shadow_prepass_height;
2059 extern rtexture_t *r_shadow_prepassgeometrydepthbuffer;
2060 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
2061 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
2062 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
2063
2064 #define BLENDFUNC_ALLOWS_COLORMOD      1
2065 #define BLENDFUNC_ALLOWS_FOG           2
2066 #define BLENDFUNC_ALLOWS_FOG_HACK0     4
2067 #define BLENDFUNC_ALLOWS_FOG_HACKALPHA 8
2068 #define BLENDFUNC_ALLOWS_ANYFOG        (BLENDFUNC_ALLOWS_FOG | BLENDFUNC_ALLOWS_FOG_HACK0 | BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2069 static int R_BlendFuncFlags(int src, int dst)
2070 {
2071         int r = 0;
2072
2073         // a blendfunc allows colormod if:
2074         // a) it can never keep the destination pixel invariant, or
2075         // b) it can keep the destination pixel invariant, and still can do so if colormodded
2076         // this is to prevent unintended side effects from colormod
2077
2078         // a blendfunc allows fog if:
2079         // blend(fog(src), fog(dst)) == fog(blend(src, dst))
2080         // this is to prevent unintended side effects from fog
2081
2082         // these checks are the output of fogeval.pl
2083
2084         r |= BLENDFUNC_ALLOWS_COLORMOD;
2085         if(src == GL_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2086         if(src == GL_DST_ALPHA && dst == GL_ONE_MINUS_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2087         if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2088         if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2089         if(src == GL_DST_COLOR && dst == GL_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2090         if(src == GL_DST_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2091         if(src == GL_DST_COLOR && dst == GL_ZERO) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2092         if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2093         if(src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG_HACKALPHA;
2094         if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
2095         if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2096         if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2097         if(src == GL_ONE_MINUS_DST_COLOR && dst == GL_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2098         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2099         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2100         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2101         if(src == GL_ONE_MINUS_SRC_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2102         if(src == GL_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2103         if(src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2104         if(src == GL_ZERO && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG;
2105         if(src == GL_ZERO && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2106
2107         return r;
2108 }
2109
2110 void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qboolean notrippy)
2111 {
2112         // select a permutation of the lighting shader appropriate to this
2113         // combination of texture, entity, light source, and fogging, only use the
2114         // minimum features necessary to avoid wasting rendering time in the
2115         // fragment shader on features that are not being used
2116         unsigned int permutation = 0;
2117         unsigned int mode = 0;
2118         int blendfuncflags;
2119         static float dummy_colormod[3] = {1, 1, 1};
2120         float *colormod = rsurface.colormod;
2121         float m16f[16];
2122         matrix4x4_t tempmatrix;
2123         r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
2124         if (r_trippy.integer && !notrippy)
2125                 permutation |= SHADERPERMUTATION_TRIPPY;
2126         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
2127                 permutation |= SHADERPERMUTATION_ALPHAKILL;
2128         if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
2129                 permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
2130         if (rsurfacepass == RSURFPASS_BACKGROUND)
2131         {
2132                 // distorted background
2133                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
2134                 {
2135                         mode = SHADERMODE_WATER;
2136                         if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
2137                         {
2138                                 // this is the right thing to do for wateralpha
2139                                 GL_BlendFunc(GL_ONE, GL_ZERO);
2140                                 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2141                         }
2142                         else
2143                         {
2144                                 // this is the right thing to do for entity alpha
2145                                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2146                                 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2147                         }
2148                 }
2149                 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
2150                 {
2151                         mode = SHADERMODE_REFRACTION;
2152                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2153                         blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2154                 }
2155                 else
2156                 {
2157                         mode = SHADERMODE_GENERIC;
2158                         permutation |= SHADERPERMUTATION_DIFFUSE;
2159                         GL_BlendFunc(GL_ONE, GL_ZERO);
2160                         blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2161                 }
2162                 if (vid.allowalphatocoverage)
2163                         GL_AlphaToCoverage(false);
2164         }
2165         else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
2166         {
2167                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2168                 {
2169                         switch(rsurface.texture->offsetmapping)
2170                         {
2171                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2172                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2173                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2174                         case OFFSETMAPPING_OFF: break;
2175                         }
2176                 }
2177                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2178                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2179                 // normalmap (deferred prepass), may use alpha test on diffuse
2180                 mode = SHADERMODE_DEFERREDGEOMETRY;
2181                 GL_BlendFunc(GL_ONE, GL_ZERO);
2182                 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2183                 if (vid.allowalphatocoverage)
2184                         GL_AlphaToCoverage(false);
2185         }
2186         else if (rsurfacepass == RSURFPASS_RTLIGHT)
2187         {
2188                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2189                 {
2190                         switch(rsurface.texture->offsetmapping)
2191                         {
2192                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2193                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2194                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2195                         case OFFSETMAPPING_OFF: break;
2196                         }
2197                 }
2198                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2199                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2200                 // light source
2201                 mode = SHADERMODE_LIGHTSOURCE;
2202                 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
2203                         permutation |= SHADERPERMUTATION_CUBEFILTER;
2204                 if (diffusescale > 0)
2205                         permutation |= SHADERPERMUTATION_DIFFUSE;
2206                 if (specularscale > 0)
2207                         permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2208                 if (r_refdef.fogenabled)
2209                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2210                 if (rsurface.texture->colormapping)
2211                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2212                 if (r_shadow_usingshadowmap2d)
2213                 {
2214                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2215                         if(r_shadow_shadowmapvsdct)
2216                                 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2217
2218                         if (r_shadow_shadowmapsampler)
2219                                 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
2220                         if (r_shadow_shadowmappcf > 1)
2221                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
2222                         else if (r_shadow_shadowmappcf)
2223                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
2224                         if (r_shadow_shadowmap2ddepthbuffer)
2225                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2226                 }
2227                 if (rsurface.texture->reflectmasktexture)
2228                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2229                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2230                 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE);
2231                 if (vid.allowalphatocoverage)
2232                         GL_AlphaToCoverage(false);
2233         }
2234         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2235         {
2236                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2237                 {
2238                         switch(rsurface.texture->offsetmapping)
2239                         {
2240                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2241                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2242                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2243                         case OFFSETMAPPING_OFF: break;
2244                         }
2245                 }
2246                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2247                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2248                 // unshaded geometry (fullbright or ambient model lighting)
2249                 mode = SHADERMODE_FLATCOLOR;
2250                 ambientscale = diffusescale = specularscale = 0;
2251                 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2252                         permutation |= SHADERPERMUTATION_GLOW;
2253                 if (r_refdef.fogenabled)
2254                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2255                 if (rsurface.texture->colormapping)
2256                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2257                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2258                 {
2259                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2260                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2261
2262                         if (r_shadow_shadowmapsampler)
2263                                 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
2264                         if (r_shadow_shadowmappcf > 1)
2265                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
2266                         else if (r_shadow_shadowmappcf)
2267                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
2268                         if (r_shadow_shadowmap2ddepthbuffer)
2269                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2270                 }
2271                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2272                         permutation |= SHADERPERMUTATION_REFLECTION;
2273                 if (rsurface.texture->reflectmasktexture)
2274                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2275                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2276                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2277                 // when using alphatocoverage, we don't need alphakill
2278                 if (vid.allowalphatocoverage)
2279                 {
2280                         if (r_transparent_alphatocoverage.integer)
2281                         {
2282                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2283                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2284                         }
2285                         else
2286                                 GL_AlphaToCoverage(false);
2287                 }
2288         }
2289         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
2290         {
2291                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2292                 {
2293                         switch(rsurface.texture->offsetmapping)
2294                         {
2295                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2296                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2297                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2298                         case OFFSETMAPPING_OFF: break;
2299                         }
2300                 }
2301                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2302                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2303                 // directional model lighting
2304                 mode = SHADERMODE_LIGHTDIRECTION;
2305                 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2306                         permutation |= SHADERPERMUTATION_GLOW;
2307                 permutation |= SHADERPERMUTATION_DIFFUSE;
2308                 if (specularscale > 0)
2309                         permutation |= SHADERPERMUTATION_SPECULAR;
2310                 if (r_refdef.fogenabled)
2311                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2312                 if (rsurface.texture->colormapping)
2313                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2314                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2315                 {
2316                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2317                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2318
2319                         if (r_shadow_shadowmapsampler)
2320                                 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
2321                         if (r_shadow_shadowmappcf > 1)
2322                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
2323                         else if (r_shadow_shadowmappcf)
2324                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
2325                         if (r_shadow_shadowmap2ddepthbuffer)
2326                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2327                 }
2328                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2329                         permutation |= SHADERPERMUTATION_REFLECTION;
2330                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2331                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2332                 if (rsurface.texture->reflectmasktexture)
2333                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2334                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2335                 {
2336                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2337                         if (r_shadow_bouncegriddirectional)
2338                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2339                 }
2340                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2341                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2342                 // when using alphatocoverage, we don't need alphakill
2343                 if (vid.allowalphatocoverage)
2344                 {
2345                         if (r_transparent_alphatocoverage.integer)
2346                         {
2347                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2348                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2349                         }
2350                         else
2351                                 GL_AlphaToCoverage(false);
2352                 }
2353         }
2354         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
2355         {
2356                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2357                 {
2358                         switch(rsurface.texture->offsetmapping)
2359                         {
2360                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2361                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2362                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2363                         case OFFSETMAPPING_OFF: break;
2364                         }
2365                 }
2366                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2367                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2368                 // ambient model lighting
2369                 mode = SHADERMODE_LIGHTDIRECTION;
2370                 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2371                         permutation |= SHADERPERMUTATION_GLOW;
2372                 if (r_refdef.fogenabled)
2373                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2374                 if (rsurface.texture->colormapping)
2375                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2376                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2377                 {
2378                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2379                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2380
2381                         if (r_shadow_shadowmapsampler)
2382                                 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
2383                         if (r_shadow_shadowmappcf > 1)
2384                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
2385                         else if (r_shadow_shadowmappcf)
2386                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
2387                         if (r_shadow_shadowmap2ddepthbuffer)
2388                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2389                 }
2390                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2391                         permutation |= SHADERPERMUTATION_REFLECTION;
2392                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2393                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2394                 if (rsurface.texture->reflectmasktexture)
2395                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2396                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2397                 {
2398                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2399                         if (r_shadow_bouncegriddirectional)
2400                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2401                 }
2402                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2403                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2404                 // when using alphatocoverage, we don't need alphakill
2405                 if (vid.allowalphatocoverage)
2406                 {
2407                         if (r_transparent_alphatocoverage.integer)
2408                         {
2409                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2410                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2411                         }
2412                         else
2413                                 GL_AlphaToCoverage(false);
2414                 }
2415         }
2416         else
2417         {
2418                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2419                 {
2420                         switch(rsurface.texture->offsetmapping)
2421                         {
2422                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2423                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2424                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2425                         case OFFSETMAPPING_OFF: break;
2426                         }
2427                 }
2428                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2429                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2430                 // lightmapped wall
2431                 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2432                         permutation |= SHADERPERMUTATION_GLOW;
2433                 if (r_refdef.fogenabled)
2434                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2435                 if (rsurface.texture->colormapping)
2436                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2437                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2438                 {
2439                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2440                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2441
2442                         if (r_shadow_shadowmapsampler)
2443                                 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
2444                         if (r_shadow_shadowmappcf > 1)
2445                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
2446                         else if (r_shadow_shadowmappcf)
2447                                 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
2448                         if (r_shadow_shadowmap2ddepthbuffer)
2449                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2450                 }
2451                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2452                         permutation |= SHADERPERMUTATION_REFLECTION;
2453                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2454                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2455                 if (rsurface.texture->reflectmasktexture)
2456                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2457                 if (FAKELIGHT_ENABLED)
2458                 {
2459                         // fake lightmapping (q1bsp, q3bsp, fullbright map)
2460                         mode = SHADERMODE_FAKELIGHT;
2461                         permutation |= SHADERPERMUTATION_DIFFUSE;
2462                         if (specularscale > 0)
2463                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2464                 }
2465                 else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
2466                 {
2467                         // deluxemapping (light direction texture)
2468                         if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
2469                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
2470                         else
2471                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2472                         permutation |= SHADERPERMUTATION_DIFFUSE;
2473                         if (specularscale > 0)
2474                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2475                 }
2476                 else if (r_glsl_deluxemapping.integer >= 2)
2477                 {
2478                         // fake deluxemapping (uniform light direction in tangentspace)
2479                         if (rsurface.uselightmaptexture)
2480                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP;
2481                         else
2482                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR;
2483                         permutation |= SHADERPERMUTATION_DIFFUSE;
2484                         if (specularscale > 0)
2485                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2486                 }
2487                 else if (rsurface.uselightmaptexture)
2488                 {
2489                         // ordinary lightmapping (q1bsp, q3bsp)
2490                         mode = SHADERMODE_LIGHTMAP;
2491                 }
2492                 else
2493                 {
2494                         // ordinary vertex coloring (q3bsp)
2495                         mode = SHADERMODE_VERTEXCOLOR;
2496                 }
2497                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2498                 {
2499                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2500                         if (r_shadow_bouncegriddirectional)
2501                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2502                 }
2503                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2504                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2505                 // when using alphatocoverage, we don't need alphakill
2506                 if (vid.allowalphatocoverage)
2507                 {
2508                         if (r_transparent_alphatocoverage.integer)
2509                         {
2510                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2511                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2512                         }
2513                         else
2514                                 GL_AlphaToCoverage(false);
2515                 }
2516         }
2517         if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD))
2518                 colormod = dummy_colormod;
2519         if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
2520                 permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
2521         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2522                 permutation |= SHADERPERMUTATION_FOGALPHAHACK;
2523         switch(vid.renderpath)
2524         {
2525         case RENDERPATH_D3D9:
2526 #ifdef SUPPORTD3D
2527                 RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
2528                 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
2529                 R_SetupShader_SetPermutationHLSL(mode, permutation);
2530                 Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);hlslPSSetParameter16f(D3DPSREGISTER_ModelToReflectCube, m16f);
2531                 if (mode == SHADERMODE_LIGHTSOURCE)
2532                 {
2533                         Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ModelToLight, m16f);
2534                         hlslVSSetParameter3f(D3DVSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2535                 }
2536                 else
2537                 {
2538                         if (mode == SHADERMODE_LIGHTDIRECTION)
2539                         {
2540                                 hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2541                         }
2542                 }
2543                 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
2544                 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
2545                 Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
2546                 hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2547                 hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2548
2549                 if (mode == SHADERMODE_LIGHTSOURCE)
2550                 {
2551                         hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2552                         hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2553                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2554                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2555                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2556
2557                         // additive passes are only darkened by fog, not tinted
2558                         hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2559                         hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2560                 }
2561                 else
2562                 {
2563                         if (mode == SHADERMODE_FLATCOLOR)
2564                         {
2565                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2566                         }
2567                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2568                         {
2569                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]);
2570                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2571                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2572                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2573                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2574                                 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
2575                                 hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2576                         }
2577                         else
2578                         {
2579                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2580                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2581                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2582                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2583                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2584                         }
2585                         // additive passes are only darkened by fog, not tinted
2586                         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2587                                 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2588                         else
2589                                 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2590                         hlslPSSetParameter4f(D3DPSREGISTER_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
2591                         hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
2592                         hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
2593                         hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2594                         hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2595                         hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2596                         hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
2597                         hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
2598                         if (mode == SHADERMODE_WATER)
2599                                 hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2600                 }
2601                 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2602                 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
2603                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2604                 hlslPSSetParameter1f(D3DPSREGISTER_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
2605                 hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2606                 if (rsurface.texture->pantstexture)
2607                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2608                 else
2609                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
2610                 if (rsurface.texture->shirttexture)
2611                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2612                 else
2613                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
2614                 hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2615                 hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist);
2616                 hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
2617                 hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
2618                 hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps,
2619                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2620                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2621                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2622                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2623                         );
2624                 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer);
2625                 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias);
2626                 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2627                 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
2628
2629                 R_Mesh_TexBind(GL20TU_NORMAL            , rsurface.texture->nmaptexture                       );
2630                 R_Mesh_TexBind(GL20TU_COLOR             , rsurface.texture->basetexture                       );
2631                 R_Mesh_TexBind(GL20TU_GLOSS             , rsurface.texture->glosstexture                      );
2632                 R_Mesh_TexBind(GL20TU_GLOW              , rsurface.texture->glowtexture                       );
2633                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL  , rsurface.texture->backgroundnmaptexture             );
2634                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR   , rsurface.texture->backgroundbasetexture             );
2635                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS   , rsurface.texture->backgroundglosstexture            );
2636                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW    , rsurface.texture->backgroundglowtexture             );
2637                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS             , rsurface.texture->pantstexture                      );
2638                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT             , rsurface.texture->shirttexture                      );
2639                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK       , rsurface.texture->reflectmasktexture                );
2640                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE       , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2641                 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE  , r_texture_fogheighttexture                          );
2642                 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK           , r_texture_fogattenuation                            );
2643                 R_Mesh_TexBind(GL20TU_LIGHTMAP          , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2644                 R_Mesh_TexBind(GL20TU_DELUXEMAP         , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2645                 if (rsurface.rtlight                                  ) R_Mesh_TexBind(GL20TU_ATTENUATION       , r_shadow_attenuationgradienttexture                 );
2646                 if (rsurfacepass == RSURFPASS_BACKGROUND)
2647                 {
2648                         R_Mesh_TexBind(GL20TU_REFRACTION        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2649                         if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2650                         R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2651                 }
2652                 else
2653                 {
2654                         if (permutation & SHADERPERMUTATION_REFLECTION        ) R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2655                 }
2656 //              if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP   , r_shadow_prepassgeometrynormalmaptexture            );
2657                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE     , r_shadow_prepasslightingdiffusetexture              );
2658                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
2659                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2660                 {
2661                         R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
2662                         if (rsurface.rtlight)
2663                         {
2664                                 if (permutation & SHADERPERMUTATION_CUBEFILTER        ) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
2665                                 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT    ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION    , r_shadow_shadowmapvsdcttexture                      );
2666                         }
2667                 }
2668 #endif
2669                 break;
2670         case RENDERPATH_D3D10:
2671                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2672                 break;
2673         case RENDERPATH_D3D11:
2674                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2675                 break;
2676         case RENDERPATH_GL20:
2677         case RENDERPATH_GLES2:
2678                 if (!vid.useinterleavedarrays)
2679                 {
2680                         RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
2681                         R_Mesh_VertexPointer(     3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
2682                         R_Mesh_ColorPointer(      4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
2683                         R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
2684                         R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
2685                         R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
2686                         R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
2687                         R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
2688                 }
2689                 else
2690                 {
2691                         RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
2692                         R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
2693                 }
2694                 R_SetupShader_SetPermutationGLSL(mode, permutation);
2695                 if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
2696                 if (mode == SHADERMODE_LIGHTSOURCE)
2697                 {
2698                         if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
2699                         if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2700                         if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2701                         if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2702                         if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2703                         if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2704         
2705                         // additive passes are only darkened by fog, not tinted
2706                         if (r_glsl_permutation->loc_FogColor >= 0)
2707                                 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2708                         if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2709                 }
2710                 else
2711                 {
2712                         if (mode == SHADERMODE_FLATCOLOR)
2713                         {
2714                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2715                         }
2716                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2717                         {
2718                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
2719                                 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2720                                 if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2721                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2722                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2723                                 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
2724                                 if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2725                         }
2726                         else
2727                         {
2728                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2729                                 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2730                                 if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
2731                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2732                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2733                         }
2734                         // additive passes are only darkened by fog, not tinted
2735                         if (r_glsl_permutation->loc_FogColor >= 0)
2736                         {
2737                                 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2738                                         qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2739                                 else
2740                                         qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2741                         }
2742                         if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
2743                         if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
2744                         if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
2745                         if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4f(r_glsl_permutation->loc_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2746                         if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2747                         if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2748                         if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
2749                         if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2750                         if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2751                 }
2752                 if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
2753                 if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
2754                 if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
2755                 if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2756                 if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
2757
2758                 if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2759                 if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
2760                 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2761                 if (r_glsl_permutation->loc_Color_Pants >= 0)
2762                 {
2763                         if (rsurface.texture->pantstexture)
2764                                 qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2765                         else
2766                                 qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
2767                 }
2768                 if (r_glsl_permutation->loc_Color_Shirt >= 0)
2769                 {
2770                         if (rsurface.texture->shirttexture)
2771                                 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2772                         else
2773                                 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
2774                 }
2775                 if (r_glsl_permutation->loc_FogPlane >= 0) qglUniform4f(r_glsl_permutation->loc_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2776                 if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1f(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
2777                 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
2778                 if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
2779                 if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps,
2780                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2781                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2782                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2783                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2784                         );
2785                 if (r_glsl_permutation->loc_OffsetMapping_LodDistance >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer);
2786                 if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias);
2787                 if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2788                 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
2789                 if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegridmatrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);}
2790                 if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegridintensity*r_refdef.view.colorscale);
2791
2792                 if (r_glsl_permutation->tex_Texture_First           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First            , r_texture_white                                     );
2793                 if (r_glsl_permutation->tex_Texture_Second          >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second           , r_texture_white                                     );
2794                 if (r_glsl_permutation->tex_Texture_GammaRamps      >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps       , r_texture_gammaramps                                );
2795                 if (r_glsl_permutation->tex_Texture_Normal          >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal           , rsurface.texture->nmaptexture                       );
2796                 if (r_glsl_permutation->tex_Texture_Color           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color            , rsurface.texture->basetexture                       );
2797                 if (r_glsl_permutation->tex_Texture_Gloss           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss            , rsurface.texture->glosstexture                      );
2798                 if (r_glsl_permutation->tex_Texture_Glow            >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow             , rsurface.texture->glowtexture                       );
2799                 if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal  , rsurface.texture->backgroundnmaptexture             );
2800                 if (r_glsl_permutation->tex_Texture_SecondaryColor  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor   , rsurface.texture->backgroundbasetexture             );
2801                 if (r_glsl_permutation->tex_Texture_SecondaryGloss  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss   , rsurface.texture->backgroundglosstexture            );
2802                 if (r_glsl_permutation->tex_Texture_SecondaryGlow   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow    , rsurface.texture->backgroundglowtexture             );
2803                 if (r_glsl_permutation->tex_Texture_Pants           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants            , rsurface.texture->pantstexture                      );
2804                 if (r_glsl_permutation->tex_Texture_Shirt           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt            , rsurface.texture->shirttexture                      );
2805                 if (r_glsl_permutation->tex_Texture_ReflectMask     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask      , rsurface.texture->reflectmasktexture                );
2806                 if (r_glsl_permutation->tex_Texture_ReflectCube     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube      , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2807                 if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture                          );
2808                 if (r_glsl_permutation->tex_Texture_FogMask         >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask          , r_texture_fogattenuation                            );
2809                 if (r_glsl_permutation->tex_Texture_Lightmap        >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap         , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2810                 if (r_glsl_permutation->tex_Texture_Deluxemap       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Deluxemap        , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2811                 if (r_glsl_permutation->tex_Texture_Attenuation     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation      , r_shadow_attenuationgradienttexture                 );
2812                 if (rsurfacepass == RSURFPASS_BACKGROUND)
2813                 {
2814                         if (r_glsl_permutation->tex_Texture_Refraction  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Refraction        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2815                         if (r_glsl_permutation->tex_Texture_First       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2816                         if (r_glsl_permutation->tex_Texture_Reflection  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2817                 }
2818                 else
2819                 {
2820                         if (r_glsl_permutation->tex_Texture_Reflection >= 0 && waterplane) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2821                 }
2822                 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap   , r_shadow_prepassgeometrynormalmaptexture            );
2823                 if (r_glsl_permutation->tex_Texture_ScreenDiffuse   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse     , r_shadow_prepasslightingdiffusetexture              );
2824                 if (r_glsl_permutation->tex_Texture_ScreenSpecular  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular    , r_shadow_prepasslightingspeculartexture             );
2825                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2826                 {
2827                         if (r_glsl_permutation->tex_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2ddepthtexture                           );
2828                         if (rsurface.rtlight)
2829                         {
2830                                 if (r_glsl_permutation->tex_Texture_Cube            >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube              , rsurface.rtlight->currentcubemap                    );
2831                                 if (r_glsl_permutation->tex_Texture_CubeProjection  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection    , r_shadow_shadowmapvsdcttexture                      );
2832                         }
2833                 }
2834                 if (r_glsl_permutation->tex_Texture_BounceGrid  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegridtexture);
2835                 CHECKGLERROR
2836                 break;
2837         case RENDERPATH_GL11:
2838         case RENDERPATH_GL13:
2839         case RENDERPATH_GLES1:
2840                 break;
2841         case RENDERPATH_SOFT:
2842                 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
2843                 R_Mesh_PrepareVertices_Mesh_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchsvector3f, rsurface.batchtvector3f, rsurface.batchnormal3f, rsurface.batchlightmapcolor4f, rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordlightmap2f);
2844                 R_SetupShader_SetPermutationSoft(mode, permutation);
2845                 {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToReflectCubeM1, 1, false, m16f);}
2846                 if (mode == SHADERMODE_LIGHTSOURCE)
2847                 {