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