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