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