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