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