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