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