added entity caching stats in graph
[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                 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , first );
1970                 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second);
1971                 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0)
1972                         R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
1973                 break;
1974         case RENDERPATH_GL13:
1975         case RENDERPATH_GLES1:
1976                 R_Mesh_TexBind(0, first );
1977                 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
1978                 R_Mesh_TexBind(1, second);
1979                 if (second)
1980                         R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
1981                 break;
1982         case RENDERPATH_GL11:
1983                 R_Mesh_TexBind(0, first );
1984                 break;
1985         case RENDERPATH_SOFT:
1986                 R_SetupShader_SetPermutationSoft(SHADERMODE_GENERIC, permutation);
1987                 R_Mesh_TexBind(GL20TU_FIRST , first );
1988                 R_Mesh_TexBind(GL20TU_SECOND, second);
1989                 break;
1990         }
1991 }
1992
1993 void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy)
1994 {
1995         R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, usegamma, notrippy, false);
1996 }
1997
1998 void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb, qboolean skeletal)
1999 {
2000         unsigned int permutation = 0;
2001         if (r_trippy.integer && !notrippy)
2002                 permutation |= SHADERPERMUTATION_TRIPPY;
2003         if (depthrgb)
2004                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2005         if (skeletal)
2006                 permutation |= SHADERPERMUTATION_SKELETAL;
2007
2008         if (vid.allowalphatocoverage)
2009                 GL_AlphaToCoverage(false);
2010         switch (vid.renderpath)
2011         {
2012         case RENDERPATH_D3D9:
2013 #ifdef SUPPORTD3D
2014                 R_SetupShader_SetPermutationHLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2015 #endif
2016                 break;
2017         case RENDERPATH_D3D10:
2018                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2019                 break;
2020         case RENDERPATH_D3D11:
2021                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2022                 break;
2023         case RENDERPATH_GL20:
2024         case RENDERPATH_GLES2:
2025                 R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2026                 break;
2027         case RENDERPATH_GL13:
2028         case RENDERPATH_GLES1:
2029                 R_Mesh_TexBind(0, 0);
2030                 R_Mesh_TexBind(1, 0);
2031                 break;
2032         case RENDERPATH_GL11:
2033                 R_Mesh_TexBind(0, 0);
2034                 break;
2035         case RENDERPATH_SOFT:
2036                 R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2037                 break;
2038         }
2039 }
2040
2041 extern qboolean r_shadow_usingdeferredprepass;
2042 extern rtexture_t *r_shadow_attenuationgradienttexture;
2043 extern rtexture_t *r_shadow_attenuation2dtexture;
2044 extern rtexture_t *r_shadow_attenuation3dtexture;
2045 extern qboolean r_shadow_usingshadowmap2d;
2046 extern qboolean r_shadow_usingshadowmaportho;
2047 extern float r_shadow_shadowmap_texturescale[2];
2048 extern float r_shadow_shadowmap_parameters[4];
2049 extern qboolean r_shadow_shadowmapvsdct;
2050 extern rtexture_t *r_shadow_shadowmap2ddepthbuffer;
2051 extern rtexture_t *r_shadow_shadowmap2ddepthtexture;
2052 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
2053 extern matrix4x4_t r_shadow_shadowmapmatrix;
2054 extern int r_shadow_shadowmaplod; // changes for each light based on distance
2055 extern int r_shadow_prepass_width;
2056 extern int r_shadow_prepass_height;
2057 extern rtexture_t *r_shadow_prepassgeometrydepthbuffer;
2058 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
2059 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
2060 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
2061
2062 #define BLENDFUNC_ALLOWS_COLORMOD      1
2063 #define BLENDFUNC_ALLOWS_FOG           2
2064 #define BLENDFUNC_ALLOWS_FOG_HACK0     4
2065 #define BLENDFUNC_ALLOWS_FOG_HACKALPHA 8
2066 #define BLENDFUNC_ALLOWS_ANYFOG        (BLENDFUNC_ALLOWS_FOG | BLENDFUNC_ALLOWS_FOG_HACK0 | BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2067 static int R_BlendFuncFlags(int src, int dst)
2068 {
2069         int r = 0;
2070
2071         // a blendfunc allows colormod if:
2072         // a) it can never keep the destination pixel invariant, or
2073         // b) it can keep the destination pixel invariant, and still can do so if colormodded
2074         // this is to prevent unintended side effects from colormod
2075
2076         // a blendfunc allows fog if:
2077         // blend(fog(src), fog(dst)) == fog(blend(src, dst))
2078         // this is to prevent unintended side effects from fog
2079
2080         // these checks are the output of fogeval.pl
2081
2082         r |= BLENDFUNC_ALLOWS_COLORMOD;
2083         if(src == GL_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2084         if(src == GL_DST_ALPHA && dst == GL_ONE_MINUS_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2085         if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2086         if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2087         if(src == GL_DST_COLOR && dst == GL_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2088         if(src == GL_DST_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2089         if(src == GL_DST_COLOR && dst == GL_ZERO) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2090         if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2091         if(src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG_HACKALPHA;
2092         if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
2093         if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2094         if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2095         if(src == GL_ONE_MINUS_DST_COLOR && dst == GL_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2096         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2097         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2098         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2099         if(src == GL_ONE_MINUS_SRC_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2100         if(src == GL_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2101         if(src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2102         if(src == GL_ZERO && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG;
2103         if(src == GL_ZERO && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2104
2105         return r;
2106 }
2107
2108 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)
2109 {
2110         // select a permutation of the lighting shader appropriate to this
2111         // combination of texture, entity, light source, and fogging, only use the
2112         // minimum features necessary to avoid wasting rendering time in the
2113         // fragment shader on features that are not being used
2114         unsigned int permutation = 0;
2115         unsigned int mode = 0;
2116         int blendfuncflags;
2117         static float dummy_colormod[3] = {1, 1, 1};
2118         float *colormod = rsurface.colormod;
2119         float m16f[16];
2120         matrix4x4_t tempmatrix;
2121         r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
2122         if (r_trippy.integer && !notrippy)
2123                 permutation |= SHADERPERMUTATION_TRIPPY;
2124         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
2125                 permutation |= SHADERPERMUTATION_ALPHAKILL;
2126         if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
2127                 permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
2128         if (rsurfacepass == RSURFPASS_BACKGROUND)
2129         {
2130                 // distorted background
2131                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
2132                 {
2133                         mode = SHADERMODE_WATER;
2134                         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2135                                 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2136                         if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
2137                         {
2138                                 // this is the right thing to do for wateralpha
2139                                 GL_BlendFunc(GL_ONE, GL_ZERO);
2140                                 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2141                         }
2142                         else
2143                         {
2144                                 // this is the right thing to do for entity alpha
2145                                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2146                                 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2147                         }
2148                 }
2149                 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
2150                 {
2151                         mode = SHADERMODE_REFRACTION;
2152                         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2153                                 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2154                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2155                         blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2156                 }
2157                 else
2158                 {
2159                         mode = SHADERMODE_GENERIC;
2160                         permutation |= SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_ALPHAKILL;
2161                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2162                         blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2163                 }
2164                 if (vid.allowalphatocoverage)
2165                         GL_AlphaToCoverage(false);
2166         }
2167         else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
2168         {
2169                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2170                 {
2171                         switch(rsurface.texture->offsetmapping)
2172                         {
2173                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2174                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2175                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2176                         case OFFSETMAPPING_OFF: break;
2177                         }
2178                 }
2179                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2180                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2181                 // normalmap (deferred prepass), may use alpha test on diffuse
2182                 mode = SHADERMODE_DEFERREDGEOMETRY;
2183                 GL_BlendFunc(GL_ONE, GL_ZERO);
2184                 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2185                 if (vid.allowalphatocoverage)
2186                         GL_AlphaToCoverage(false);
2187         }
2188         else if (rsurfacepass == RSURFPASS_RTLIGHT)
2189         {
2190                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2191                 {
2192                         switch(rsurface.texture->offsetmapping)
2193                         {
2194                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2195                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2196                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2197                         case OFFSETMAPPING_OFF: break;
2198                         }
2199                 }
2200                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2201                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2202                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2203                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2204                 // light source
2205                 mode = SHADERMODE_LIGHTSOURCE;
2206                 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
2207                         permutation |= SHADERPERMUTATION_CUBEFILTER;
2208                 if (diffusescale > 0)
2209                         permutation |= SHADERPERMUTATION_DIFFUSE;
2210                 if (specularscale > 0)
2211                         permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2212                 if (r_refdef.fogenabled)
2213                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2214                 if (rsurface.texture->colormapping)
2215                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2216                 if (r_shadow_usingshadowmap2d)
2217                 {
2218                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2219                         if(r_shadow_shadowmapvsdct)
2220                                 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2221
2222                         if (r_shadow_shadowmap2ddepthbuffer)
2223                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2224                 }
2225                 if (rsurface.texture->reflectmasktexture)
2226                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2227                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2228                 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE);
2229                 if (vid.allowalphatocoverage)
2230                         GL_AlphaToCoverage(false);
2231         }
2232         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2233         {
2234                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2235                 {
2236                         switch(rsurface.texture->offsetmapping)
2237                         {
2238                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2239                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2240                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2241                         case OFFSETMAPPING_OFF: break;
2242                         }
2243                 }
2244                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2245                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2246                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2247                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2248                 // unshaded geometry (fullbright or ambient model lighting)
2249                 mode = SHADERMODE_FLATCOLOR;
2250                 ambientscale = diffusescale = specularscale = 0;
2251                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2252                         permutation |= SHADERPERMUTATION_GLOW;
2253                 if (r_refdef.fogenabled)
2254                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2255                 if (rsurface.texture->colormapping)
2256                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2257                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2258                 {
2259                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2260                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2261
2262                         if (r_shadow_shadowmap2ddepthbuffer)
2263                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2264                 }
2265                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2266                         permutation |= SHADERPERMUTATION_REFLECTION;
2267                 if (rsurface.texture->reflectmasktexture)
2268                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2269                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2270                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2271                 // when using alphatocoverage, we don't need alphakill
2272                 if (vid.allowalphatocoverage)
2273                 {
2274                         if (r_transparent_alphatocoverage.integer)
2275                         {
2276                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2277                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2278                         }
2279                         else
2280                                 GL_AlphaToCoverage(false);
2281                 }
2282         }
2283         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
2284         {
2285                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2286                 {
2287                         switch(rsurface.texture->offsetmapping)
2288                         {
2289                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2290                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2291                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2292                         case OFFSETMAPPING_OFF: break;
2293                         }
2294                 }
2295                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2296                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2297                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2298                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2299                 // directional model lighting
2300                 mode = SHADERMODE_LIGHTDIRECTION;
2301                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2302                         permutation |= SHADERPERMUTATION_GLOW;
2303                 permutation |= SHADERPERMUTATION_DIFFUSE;
2304                 if (specularscale > 0)
2305                         permutation |= SHADERPERMUTATION_SPECULAR;
2306                 if (r_refdef.fogenabled)
2307                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2308                 if (rsurface.texture->colormapping)
2309                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2310                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2311                 {
2312                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2313                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2314
2315                         if (r_shadow_shadowmap2ddepthbuffer)
2316                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2317                 }
2318                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2319                         permutation |= SHADERPERMUTATION_REFLECTION;
2320                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2321                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2322                 if (rsurface.texture->reflectmasktexture)
2323                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2324                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2325                 {
2326                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2327                         if (r_shadow_bouncegriddirectional)
2328                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2329                 }
2330                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2331                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2332                 // when using alphatocoverage, we don't need alphakill
2333                 if (vid.allowalphatocoverage)
2334                 {
2335                         if (r_transparent_alphatocoverage.integer)
2336                         {
2337                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2338                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2339                         }
2340                         else
2341                                 GL_AlphaToCoverage(false);
2342                 }
2343         }
2344         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
2345         {
2346                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2347                 {
2348                         switch(rsurface.texture->offsetmapping)
2349                         {
2350                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2351                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2352                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2353                         case OFFSETMAPPING_OFF: break;
2354                         }
2355                 }
2356                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2357                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2358                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2359                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2360                 // ambient model lighting
2361                 mode = SHADERMODE_LIGHTDIRECTION;
2362                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2363                         permutation |= SHADERPERMUTATION_GLOW;
2364                 if (r_refdef.fogenabled)
2365                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2366                 if (rsurface.texture->colormapping)
2367                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2368                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2369                 {
2370                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2371                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2372
2373                         if (r_shadow_shadowmap2ddepthbuffer)
2374                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2375                 }
2376                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2377                         permutation |= SHADERPERMUTATION_REFLECTION;
2378                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2379                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2380                 if (rsurface.texture->reflectmasktexture)
2381                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2382                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2383                 {
2384                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2385                         if (r_shadow_bouncegriddirectional)
2386                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2387                 }
2388                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2389                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2390                 // when using alphatocoverage, we don't need alphakill
2391                 if (vid.allowalphatocoverage)
2392                 {
2393                         if (r_transparent_alphatocoverage.integer)
2394                         {
2395                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2396                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2397                         }
2398                         else
2399                                 GL_AlphaToCoverage(false);
2400                 }
2401         }
2402         else
2403         {
2404                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2405                 {
2406                         switch(rsurface.texture->offsetmapping)
2407                         {
2408                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2409                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2410                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2411                         case OFFSETMAPPING_OFF: break;
2412                         }
2413                 }
2414                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2415                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2416                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2417                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2418                 // lightmapped wall
2419                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2420                         permutation |= SHADERPERMUTATION_GLOW;
2421                 if (r_refdef.fogenabled)
2422                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2423                 if (rsurface.texture->colormapping)
2424                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2425                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2426                 {
2427                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2428                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2429
2430                         if (r_shadow_shadowmap2ddepthbuffer)
2431                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2432                 }
2433                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2434                         permutation |= SHADERPERMUTATION_REFLECTION;
2435                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2436                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2437                 if (rsurface.texture->reflectmasktexture)
2438                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2439                 if (FAKELIGHT_ENABLED)
2440                 {
2441                         // fake lightmapping (q1bsp, q3bsp, fullbright map)
2442                         mode = SHADERMODE_FAKELIGHT;
2443                         permutation |= SHADERPERMUTATION_DIFFUSE;
2444                         if (specularscale > 0)
2445                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2446                 }
2447                 else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
2448                 {
2449                         // deluxemapping (light direction texture)
2450                         if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
2451                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
2452                         else
2453                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2454                         permutation |= SHADERPERMUTATION_DIFFUSE;
2455                         if (specularscale > 0)
2456                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2457                 }
2458                 else if (r_glsl_deluxemapping.integer >= 2)
2459                 {
2460                         // fake deluxemapping (uniform light direction in tangentspace)
2461                         if (rsurface.uselightmaptexture)
2462                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP;
2463                         else
2464                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR;
2465                         permutation |= SHADERPERMUTATION_DIFFUSE;
2466                         if (specularscale > 0)
2467                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2468                 }
2469                 else if (rsurface.uselightmaptexture)
2470                 {
2471                         // ordinary lightmapping (q1bsp, q3bsp)
2472                         mode = SHADERMODE_LIGHTMAP;
2473                 }
2474                 else
2475                 {
2476                         // ordinary vertex coloring (q3bsp)
2477                         mode = SHADERMODE_VERTEXCOLOR;
2478                 }
2479                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2480                 {
2481                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2482                         if (r_shadow_bouncegriddirectional)
2483                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2484                 }
2485                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2486                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2487                 // when using alphatocoverage, we don't need alphakill
2488                 if (vid.allowalphatocoverage)
2489                 {
2490                         if (r_transparent_alphatocoverage.integer)
2491                         {
2492                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2493                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2494                         }
2495                         else
2496                                 GL_AlphaToCoverage(false);
2497                 }
2498         }
2499         if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD))
2500                 colormod = dummy_colormod;
2501         if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
2502                 permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
2503         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2504                 permutation |= SHADERPERMUTATION_FOGALPHAHACK;
2505         switch(vid.renderpath)
2506         {
2507         case RENDERPATH_D3D9:
2508 #ifdef SUPPORTD3D
2509                 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);
2510                 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
2511                 R_SetupShader_SetPermutationHLSL(mode, permutation);
2512                 Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);hlslPSSetParameter16f(D3DPSREGISTER_ModelToReflectCube, m16f);
2513                 if (mode == SHADERMODE_LIGHTSOURCE)
2514                 {
2515                         Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ModelToLight, m16f);
2516                         hlslVSSetParameter3f(D3DVSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2517                 }
2518                 else
2519                 {
2520                         if (mode == SHADERMODE_LIGHTDIRECTION)
2521                         {
2522                                 hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2523                         }
2524                 }
2525                 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
2526                 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
2527                 Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
2528                 hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2529                 hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2530
2531                 if (mode == SHADERMODE_LIGHTSOURCE)
2532                 {
2533                         hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2534                         hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2535                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2536                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2537                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2538
2539                         // additive passes are only darkened by fog, not tinted
2540                         hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2541                         hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2542                 }
2543                 else
2544                 {
2545                         if (mode == SHADERMODE_FLATCOLOR)
2546                         {
2547                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2548                         }
2549                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2550                         {
2551                                 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]);
2552                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2553                                 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);
2554                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2555                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2556                                 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
2557                                 hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2558                         }
2559                         else
2560                         {
2561                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2562                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2563                                 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);
2564                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2565                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2566                         }
2567                         // additive passes are only darkened by fog, not tinted
2568                         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2569                                 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2570                         else
2571                                 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2572                         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);
2573                         hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
2574                         hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
2575                         hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2576                         hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2577                         hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2578                         hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
2579                         hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
2580                         if (mode == SHADERMODE_WATER)
2581                                 hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2582                 }
2583                 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2584                 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
2585                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2586                 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));
2587                 hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2588                 if (rsurface.texture->pantstexture)
2589                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2590                 else
2591                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
2592                 if (rsurface.texture->shirttexture)
2593                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2594                 else
2595                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
2596                 hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2597                 hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist);
2598                 hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
2599                 hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
2600                 hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps,
2601                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2602                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2603                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2604                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2605                         );
2606                 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
2607                 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias);
2608                 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2609                 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
2610
2611                 R_Mesh_TexBind(GL20TU_NORMAL            , rsurface.texture->nmaptexture                       );
2612                 R_Mesh_TexBind(GL20TU_COLOR             , rsurface.texture->basetexture                       );
2613                 R_Mesh_TexBind(GL20TU_GLOSS             , rsurface.texture->glosstexture                      );
2614                 R_Mesh_TexBind(GL20TU_GLOW              , rsurface.texture->glowtexture                       );
2615                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL  , rsurface.texture->backgroundnmaptexture             );
2616                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR   , rsurface.texture->backgroundbasetexture             );
2617                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS   , rsurface.texture->backgroundglosstexture            );
2618                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW    , rsurface.texture->backgroundglowtexture             );
2619                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS             , rsurface.texture->pantstexture                      );
2620                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT             , rsurface.texture->shirttexture                      );
2621                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK       , rsurface.texture->reflectmasktexture                );
2622                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE       , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2623                 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE  , r_texture_fogheighttexture                          );
2624                 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK           , r_texture_fogattenuation                            );
2625                 R_Mesh_TexBind(GL20TU_LIGHTMAP          , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2626                 R_Mesh_TexBind(GL20TU_DELUXEMAP         , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2627                 if (rsurface.rtlight                                  ) R_Mesh_TexBind(GL20TU_ATTENUATION       , r_shadow_attenuationgradienttexture                 );
2628                 if (rsurfacepass == RSURFPASS_BACKGROUND)
2629                 {
2630                         R_Mesh_TexBind(GL20TU_REFRACTION        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2631                         if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2632                         R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2633                 }
2634                 else
2635                 {
2636                         if (permutation & SHADERPERMUTATION_REFLECTION        ) R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2637                 }
2638 //              if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP   , r_shadow_prepassgeometrynormalmaptexture            );
2639                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE     , r_shadow_prepasslightingdiffusetexture              );
2640                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
2641                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2642                 {
2643                         R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
2644                         if (rsurface.rtlight)
2645                         {
2646                                 if (permutation & SHADERPERMUTATION_CUBEFILTER        ) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
2647                                 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT    ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION    , r_shadow_shadowmapvsdcttexture                      );
2648                         }
2649                 }
2650 #endif
2651                 break;
2652         case RENDERPATH_D3D10:
2653                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2654                 break;
2655         case RENDERPATH_D3D11:
2656                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2657                 break;
2658         case RENDERPATH_GL20:
2659         case RENDERPATH_GLES2:
2660                 if (!vid.useinterleavedarrays)
2661                 {
2662                         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);
2663                         R_Mesh_VertexPointer(     3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
2664                         R_Mesh_ColorPointer(      4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
2665                         R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
2666                         R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
2667                         R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
2668                         R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
2669                         R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
2670                         R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
2671                         R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE | 0x80000000, sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, rsurface.batchskeletalindex4ub_vertexbuffer, rsurface.batchskeletalindex4ub_bufferoffset);
2672                         R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, rsurface.batchskeletalweight4ub_vertexbuffer, rsurface.batchskeletalweight4ub_bufferoffset);
2673                 }
2674                 else
2675                 {
2676                         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);
2677                         R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
2678                 }
2679                 // this has to be after RSurf_PrepareVerticesForBatch
2680                 if (rsurface.batchskeletaltransform3x4)
2681                         permutation |= SHADERPERMUTATION_SKELETAL;
2682                 R_SetupShader_SetPermutationGLSL(mode, permutation);
2683                 if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
2684                 if (mode == SHADERMODE_LIGHTSOURCE)
2685                 {
2686                         if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
2687                         if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2688                         if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2689                         if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2690                         if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2691                         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);
2692         
2693                         // additive passes are only darkened by fog, not tinted
2694                         if (r_glsl_permutation->loc_FogColor >= 0)
2695                                 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2696                         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);
2697                 }
2698                 else
2699                 {
2700                         if (mode == SHADERMODE_FLATCOLOR)
2701                         {
2702                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2703                         }
2704                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2705                         {
2706                                 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]);
2707                                 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]);
2708                                 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);
2709                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2710                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2711                                 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]);
2712                                 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]);
2713                         }
2714                         else
2715                         {
2716                                 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]);
2717                                 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]);
2718                                 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);
2719                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2720                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2721                         }
2722                         // additive passes are only darkened by fog, not tinted
2723                         if (r_glsl_permutation->loc_FogColor >= 0)
2724                         {
2725                                 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2726                                         qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2727                                 else
2728                                         qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2729                         }
2730                         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);
2731                         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]);
2732                         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]);
2733                         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]);
2734                         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]);
2735                         if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2736                         if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
2737                         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);
2738                         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]);
2739                 }
2740                 if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
2741                 if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
2742                 if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
2743                 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]);
2744                 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]);
2745
2746                 if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2747                 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));
2748                 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2749                 if (r_glsl_permutation->loc_Color_Pants >= 0)
2750                 {
2751                         if (rsurface.texture->pantstexture)
2752                                 qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2753                         else
2754                                 qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
2755                 }
2756                 if (r_glsl_permutation->loc_Color_Shirt >= 0)
2757                 {
2758                         if (rsurface.texture->shirttexture)
2759                                 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2760                         else
2761                                 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
2762                 }
2763                 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]);
2764                 if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1f(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
2765                 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
2766                 if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
2767                 if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps,
2768                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2769                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2770                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2771                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2772                         );
2773                 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);
2774                 if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias);
2775                 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]);
2776                 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
2777                 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);}
2778                 if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegridintensity*r_refdef.view.colorscale);
2779
2780                 if (r_glsl_permutation->tex_Texture_First           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First            , r_texture_white                                     );
2781                 if (r_glsl_permutation->tex_Texture_Second          >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second           , r_texture_white                                     );
2782                 if (r_glsl_permutation->tex_Texture_GammaRamps      >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps       , r_texture_gammaramps                                );
2783                 if (r_glsl_permutation->tex_Texture_Normal          >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal           , rsurface.texture->nmaptexture                       );
2784                 if (r_glsl_permutation->tex_Texture_Color           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color            , rsurface.texture->basetexture                       );
2785                 if (r_glsl_permutation->tex_Texture_Gloss           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss            , rsurface.texture->glosstexture                      );
2786                 if (r_glsl_permutation->tex_Texture_Glow            >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow             , rsurface.texture->glowtexture                       );
2787                 if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal  , rsurface.texture->backgroundnmaptexture             );
2788                 if (r_glsl_permutation->tex_Texture_SecondaryColor  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor   , rsurface.texture->backgroundbasetexture             );
2789                 if (r_glsl_permutation->tex_Texture_SecondaryGloss  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss   , rsurface.texture->backgroundglosstexture            );
2790                 if (r_glsl_permutation->tex_Texture_SecondaryGlow   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow    , rsurface.texture->backgroundglowtexture             );
2791                 if (r_glsl_permutation->tex_Texture_Pants           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants            , rsurface.texture->pantstexture                      );
2792                 if (r_glsl_permutation->tex_Texture_Shirt           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt            , rsurface.texture->shirttexture                      );
2793                 if (r_glsl_permutation->tex_Texture_ReflectMask     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask      , rsurface.texture->reflectmasktexture                );
2794                 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);
2795                 if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture                          );
2796                 if (r_glsl_permutation->tex_Texture_FogMask         >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask          , r_texture_fogattenuation                            );
2797                 if (r_glsl_permutation->tex_Texture_Lightmap        >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap         , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2798                 if (r_glsl_permutation->tex_Texture_Deluxemap       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Deluxemap        , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2799                 if (r_glsl_permutation->tex_Texture_Attenuation     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation      , r_shadow_attenuationgradienttexture                 );
2800                 if (rsurfacepass == RSURFPASS_BACKGROUND)
2801                 {
2802                         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);
2803                         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);
2804                         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);
2805                 }
2806                 else
2807                 {
2808                         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);
2809                 }
2810                 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap   , r_shadow_prepassgeometrynormalmaptexture            );
2811                 if (r_glsl_permutation->tex_Texture_ScreenDiffuse   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse     , r_shadow_prepasslightingdiffusetexture              );
2812                 if (r_glsl_permutation->tex_Texture_ScreenSpecular  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular    , r_shadow_prepasslightingspeculartexture             );
2813                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2814                 {
2815                         if (r_glsl_permutation->tex_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2ddepthtexture                           );
2816                         if (rsurface.rtlight)
2817                         {
2818                                 if (r_glsl_permutation->tex_Texture_Cube            >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube              , rsurface.rtlight->currentcubemap                    );
2819                                 if (r_glsl_permutation->tex_Texture_CubeProjection  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection    , r_shadow_shadowmapvsdcttexture                      );
2820                         }
2821                 }
2822                 if (r_glsl_permutation->tex_Texture_BounceGrid  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegridtexture);
2823                 if (r_glsl_permutation->loc_Skeletal_Transform12 >= 0 && rsurface.batchskeletalnumtransforms > 0)
2824                         qglUniform4fv(r_glsl_permutation->loc_Skeletal_Transform12, rsurface.batchskeletalnumtransforms*3, rsurface.batchskeletaltransform3x4);
2825                 CHECKGLERROR
2826                 break;
2827         case RENDERPATH_GL11:
2828         case RENDERPATH_GL13:
2829         case RENDERPATH_GLES1:
2830                 break;
2831         case RENDERPATH_SOFT:
2832                 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);
2833                 R_Mesh_PrepareVertices_Mesh_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchsvector3f, rsurface.batchtvector3f, rsurface.batchnormal3f, rsurface.batchlightmapcolor4f, rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordlightmap2f);
2834                 R_SetupShader_SetPermutationSoft(mode, permutation);
2835                 {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToReflectCubeM1, 1, false, m16f);}
2836                 if (mode == SHADERMODE_LIGHTSOURCE)
2837                 {
2838                         {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);}
2839                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2840                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2841                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2842                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2843                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2844         
2845                         // additive passes are only darkened by fog, not tinted
2846                         DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
2847                         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2848                 }
2849                 else
2850                 {
2851                         if (mode == SHADERMODE_FLATCOLOR)
2852                         {
2853                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2854                         }
2855                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2856                         {
2857                                 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]);
2858                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2859                                 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);
2860                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2861                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
2862                                 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]);
2863                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2864                         }
2865                         else
2866                         {
2867                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2868                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2869                                 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);
2870                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2871                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
2872                         }
2873                         // additive passes are only darkened by fog, not tinted
2874                         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2875                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
2876                         else
2877                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2878                         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);
2879                         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]);
2880                         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]);
2881                         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]);
2882                         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]);
2883                         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2884                         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
2885                         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2886                         DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2887                 }
2888                 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
2889                 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);}
2890                 {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);}
2891                 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2892                 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]);
2893
2894                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2895                 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));
2896                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2897                 if (DPSOFTRAST_UNIFORM_Color_Pants >= 0)
2898                 {
2899                         if (rsurface.texture->pantstexture)
2900                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2901                         else
2902                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0);
2903                 }
2904                 if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0)
2905                 {
2906                         if (rsurface.texture->shirttexture)
2907                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2908                         else
2909                                 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0);
2910                 }
2911                 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2912                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogPlaneViewDist, rsurface.fogplaneviewdist);
2913                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip);
2914                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade);
2915                 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps,
2916                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2917                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2918                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2919                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2920                         );
2921                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
2922                 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, rsurface.texture->offsetbias);
2923                 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2924                 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
2925
2926                 R_Mesh_TexBind(GL20TU_NORMAL            , rsurface.texture->nmaptexture                       );
2927                 R_Mesh_TexBind(GL20TU_COLOR             , rsurface.texture->basetexture                       );
2928                 R_Mesh_TexBind(GL20TU_GLOSS             , rsurface.texture->glosstexture                      );
2929                 R_Mesh_TexBind(GL20TU_GLOW              , rsurface.texture->glowtexture                       );
2930                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL  , rsurface.texture->backgroundnmaptexture             );
2931                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR   , rsurface.texture->backgroundbasetexture             );
2932                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS   , rsurface.texture->backgroundglosstexture            );
2933                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW    , rsurface.texture->backgroundglowtexture             );
2934                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS             , rsurface.texture->pantstexture                      );
2935                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT             , rsurface.texture->shirttexture                      );
2936                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK       , rsurface.texture->reflectmasktexture                );
2937                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE       , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2938                 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE  , r_texture_fogheighttexture                          );
2939                 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK           , r_texture_fogattenuation                            );
2940                 R_Mesh_TexBind(GL20TU_LIGHTMAP          , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2941                 R_Mesh_TexBind(GL20TU_DELUXEMAP         , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2942                 if (rsurface.rtlight                                  ) R_Mesh_TexBind(GL20TU_ATTENUATION       , r_shadow_attenuationgradienttexture                 );
2943                 if (rsurfacepass == RSURFPASS_BACKGROUND)
2944                 {
2945                         R_Mesh_TexBind(GL20TU_REFRACTION        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2946                         if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2947                         R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2948                 }
2949                 else
2950                 {
2951                         if (permutation & SHADERPERMUTATION_REFLECTION        ) R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2952                 }
2953 //              if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP   , r_shadow_prepassgeometrynormalmaptexture            );
2954                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE     , r_shadow_prepasslightingdiffusetexture              );
2955                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
2956                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2957                 {
2958                         R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
2959                         if (rsurface.rtlight)
2960                         {
2961                                 if (permutation & SHADERPERMUTATION_CUBEFILTER        ) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
2962                                 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT    ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION    , r_shadow_shadowmapvsdcttexture                      );
2963                         }
2964                 }
2965                 break;
2966         }
2967 }
2968
2969 void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
2970 {
2971         // select a permutation of the lighting shader appropriate to this
2972         // combination of texture, entity, light source, and fogging, only use the
2973         // minimum features necessary to avoid wasting rendering time in the
2974         // fragment shader on features that are not being used
2975         unsigned int permutation = 0;
2976         unsigned int mode = 0;
2977         const float *lightcolorbase = rtlight->currentcolor;
2978         float ambientscale = rtlight->ambientscale;
2979         float diffusescale = rtlight->diffusescale;
2980         float specularscale = rtlight->specularscale;
2981         // this is the location of the light in view space
2982         vec3_t viewlightorigin;
2983         // this transforms from view space (camera) to light space (cubemap)
2984         matrix4x4_t viewtolight;
2985         matrix4x4_t lighttoview;
2986         float viewtolight16f[16];
2987         // light source
2988         mode = SHADERMODE_DEFERREDLIGHTSOURCE;
2989         if (rtlight->currentcubemap != r_texture_whitecube)
2990                 permutation |= SHADERPERMUTATION_CUBEFILTER;
2991         if (diffusescale > 0)
2992                 permutation |= SHADERPERMUTATION_DIFFUSE;
2993         if (specularscale > 0 && r_shadow_gloss.integer > 0)
2994                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2995         if (r_shadow_usingshadowmap2d)
2996         {
2997                 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2998                 if (r_shadow_shadowmapvsdct)
2999                         permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
3000
3001                 if (r_shadow_shadowmap2ddepthbuffer)
3002                         permutation |= SHADERPERMUTATION_DEPTHRGB;
3003         }
3004         if (vid.allowalphatocoverage)
3005                 GL_AlphaToCoverage(false);
3006         Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin);
3007         Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld);
3008         Matrix4x4_Invert_Simple(&viewtolight, &lighttoview);
3009         Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f);
3010         switch(vid.renderpath)
3011         {
3012         case RENDERPATH_D3D9:
3013 #ifdef SUPPORTD3D
3014                 R_SetupShader_SetPermutationHLSL(mode, permutation);
3015                 hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3016                 hlslPSSetParameter16f(D3DPSREGISTER_ViewToLight, viewtolight16f);
3017                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
3018                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
3019                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
3020                 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3021                 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
3022                 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);
3023                 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3024                 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
3025
3026                 R_Mesh_TexBind(GL20TU_ATTENUATION        , r_shadow_attenuationgradienttexture                 );
3027                 R_Mesh_TexBind(GL20TU_SCREENNORMALMAP    , r_shadow_prepassgeometrynormalmaptexture            );
3028                 R_Mesh_TexBind(GL20TU_CUBE               , rsurface.rtlight->currentcubemap                    );
3029                 R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2ddepthtexture                    );
3030                 R_Mesh_TexBind(GL20TU_CUBEPROJECTION     , r_shadow_shadowmapvsdcttexture                      );
3031 #endif
3032                 break;
3033         case RENDERPATH_D3D10:
3034                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3035                 break;
3036         case RENDERPATH_D3D11:
3037                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3038                 break;
3039         case RENDERPATH_GL20:
3040         case RENDERPATH_GLES2:
3041                 R_SetupShader_SetPermutationGLSL(mode, permutation);
3042                 if (r_glsl_permutation->loc_LightPosition             >= 0) qglUniform3f(       r_glsl_permutation->loc_LightPosition            , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3043                 if (r_glsl_permutation->loc_ViewToLight               >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ViewToLight              , 1, false, viewtolight16f);
3044                 if (r_glsl_permutation->loc_DeferredColor_Ambient     >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Ambient    , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
3045                 if (r_glsl_permutation->loc_DeferredColor_Diffuse     >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Diffuse    , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
3046                 if (r_glsl_permutation->loc_DeferredColor_Specular    >= 0) qglUniform3f(       r_glsl_permutation->loc_DeferredColor_Specular   , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
3047                 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]);
3048                 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]);
3049                 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);
3050                 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]);
3051                 if (r_glsl_permutation->loc_PixelToScreenTexCoord     >= 0) qglUniform2f(       r_glsl_permutation->loc_PixelToScreenTexCoord    , 1.0f/vid.width, 1.0f/vid.height);
3052
3053                 if (r_glsl_permutation->tex_Texture_Attenuation       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation        , r_shadow_attenuationgradienttexture                 );
3054                 if (r_glsl_permutation->tex_Texture_ScreenNormalMap   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap    , r_shadow_prepassgeometrynormalmaptexture            );
3055                 if (r_glsl_permutation->tex_Texture_Cube              >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube               , rsurface.rtlight->currentcubemap                    );
3056                 if (r_glsl_permutation->tex_Texture_ShadowMap2D       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D        , r_shadow_shadowmap2ddepthtexture                    );
3057                 if (r_glsl_permutation->tex_Texture_CubeProjection    >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection     , r_shadow_shadowmapvsdcttexture                      );
3058                 break;
3059         case RENDERPATH_GL11:
3060         case RENDERPATH_GL13:
3061         case RENDERPATH_GLES1:
3062                 break;
3063         case RENDERPATH_SOFT:
3064                 R_SetupShader_SetPermutationGLSL(mode, permutation);
3065                 DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_LightPosition            , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3066                 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ViewToLightM1            , 1, false, viewtolight16f);
3067                 DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Ambient    , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
3068                 DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Diffuse    , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
3069                 DPSOFTRAST_Uniform3f(       DPSOFTRAST_UNIFORM_DeferredColor_Specular   , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
3070                 DPSOFTRAST_Uniform2f(       DPSOFTRAST_UNIFORM_ShadowMap_TextureScale   , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3071                 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]);
3072                 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);
3073                 DPSOFTRAST_Uniform2f(       DPSOFTRAST_UNIFORM_ScreenToDepth            , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3074                 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
3075
3076                 R_Mesh_TexBind(GL20TU_ATTENUATION        , r_shadow_attenuationgradienttexture                 );
3077                 R_Mesh_TexBind(GL20TU_SCREENNORMALMAP    , r_shadow_prepassgeometrynormalmaptexture            );
3078                 R_Mesh_TexBind(GL20TU_CUBE               , rsurface.rtlight->currentcubemap                    );
3079                 R_Mesh_TexBind(GL20TU_SHADOWMAP2D        , r_shadow_shadowmap2ddepthtexture                    );
3080                 R_Mesh_TexBind(GL20TU_CUBEPROJECTION     , r_shadow_shadowmapvsdcttexture                      );
3081                 break;
3082         }
3083 }
3084
3085 #define SKINFRAME_HASH 1024
3086
3087 typedef struct
3088 {
3089         int loadsequence; // incremented each level change
3090         memexpandablearray_t array;
3091         skinframe_t *hash[SKINFRAME_HASH];
3092 }
3093 r_skinframe_t;
3094 r_skinframe_t r_skinframe;
3095
3096 void R_SkinFrame_PrepareForPurge(void)
3097 {
3098         r_skinframe.loadsequence++;
3099         // wrap it without hitting zero
3100         if (r_skinframe.loadsequence >= 200)
3101                 r_skinframe.loadsequence = 1;
3102 }
3103
3104 void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
3105 {
3106         if (!skinframe)
3107                 return;
3108         // mark the skinframe as used for the purging code
3109         skinframe->loadsequence = r_skinframe.loadsequence;
3110 }
3111
3112 void R_SkinFrame_Purge(void)
3113 {
3114         int i;
3115         skinframe_t *s;
3116         for (i = 0;i < SKINFRAME_HASH;i++)
3117         {
3118                 for (s = r_skinframe.hash[i];s;s = s->next)
3119                 {
3120                         if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
3121                         {
3122                                 if (s->merged == s->base)
3123                                         s->merged = NULL;
3124                                 // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
3125                                 R_PurgeTexture(s->stain );s->stain  = NULL;
3126                                 R_PurgeTexture(s->merged);s->merged = NULL;
3127                                 R_PurgeTexture(s->base  );s->base   = NULL;
3128                                 R_PurgeTexture(s->pants );s->pants  = NULL;
3129                                 R_PurgeTexture(s->shirt );s->shirt  = NULL;
3130                                 R_PurgeTexture(s->nmap  );s->nmap   = NULL;
3131                                 R_PurgeTexture(s->gloss );s->gloss  = NULL;
3132                                 R_PurgeTexture(s->glow  );s->glow   = NULL;
3133                                 R_PurgeTexture(s->fog   );s->fog    = NULL;
3134                                 R_PurgeTexture(s->reflect);s->reflect = NULL;
3135                                 s->loadsequence = 0;
3136                         }
3137                 }
3138         }
3139 }
3140
3141 skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name ) {
3142         skinframe_t *item;
3143         char basename[MAX_QPATH];
3144
3145         Image_StripImageExtension(name, basename, sizeof(basename));
3146
3147         if( last == NULL ) {
3148                 int hashindex;
3149                 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
3150                 item = r_skinframe.hash[hashindex];
3151         } else {
3152                 item = last->next;
3153         }
3154
3155         // linearly search through the hash bucket
3156         for( ; item ; item = item->next ) {
3157                 if( !strcmp( item->basename, basename ) ) {
3158                         return item;
3159                 }
3160         }
3161         return NULL;
3162 }
3163
3164 skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add)
3165 {
3166         skinframe_t *item;
3167         int hashindex;
3168         char basename[MAX_QPATH];
3169
3170         Image_StripImageExtension(name, basename, sizeof(basename));
3171
3172         hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
3173         for (item = r_skinframe.hash[hashindex];item;item = item->next)
3174         &nb