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