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