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