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