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