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