implemented gpu-skinning (vertex shader skeletal animation), can be
[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
232 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
233 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"};
234
235 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."};
236
237 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)"};
238
239 extern cvar_t v_glslgamma;
240 extern cvar_t v_glslgamma_2d;
241
242 extern qboolean v_flipped_state;
243
244 r_framebufferstate_t r_fb;
245
246 /// shadow volume bsp struct with automatically growing nodes buffer
247 svbsp_t r_svbsp;
248
249 rtexture_t *r_texture_blanknormalmap;
250 rtexture_t *r_texture_white;
251 rtexture_t *r_texture_grey128;
252 rtexture_t *r_texture_black;
253 rtexture_t *r_texture_notexture;
254 rtexture_t *r_texture_whitecube;
255 rtexture_t *r_texture_normalizationcube;
256 rtexture_t *r_texture_fogattenuation;
257 rtexture_t *r_texture_fogheighttexture;
258 rtexture_t *r_texture_gammaramps;
259 unsigned int r_texture_gammaramps_serial;
260 //rtexture_t *r_texture_fogintensity;
261 rtexture_t *r_texture_reflectcube;
262
263 // TODO: hash lookups?
264 typedef struct cubemapinfo_s
265 {
266         char basename[64];
267         rtexture_t *texture;
268 }
269 cubemapinfo_t;
270
271 int r_texture_numcubemaps;
272 cubemapinfo_t *r_texture_cubemaps[MAX_CUBEMAPS];
273
274 unsigned int r_queries[MAX_OCCLUSION_QUERIES];
275 unsigned int r_numqueries;
276 unsigned int r_maxqueries;
277
278 typedef struct r_qwskincache_s
279 {
280         char name[MAX_QPATH];
281         skinframe_t *skinframe;
282 }
283 r_qwskincache_t;
284
285 static r_qwskincache_t *r_qwskincache;
286 static int r_qwskincache_size;
287
288 /// vertex coordinates for a quad that covers the screen exactly
289 extern const float r_screenvertex3f[12];
290 extern const float r_d3dscreenvertex3f[12];
291 const float r_screenvertex3f[12] =
292 {
293         0, 0, 0,
294         1, 0, 0,
295         1, 1, 0,
296         0, 1, 0
297 };
298 const float r_d3dscreenvertex3f[12] =
299 {
300         0, 1, 0,
301         1, 1, 0,
302         1, 0, 0,
303         0, 0, 0
304 };
305
306 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
307 {
308         int i;
309         for (i = 0;i < verts;i++)
310         {
311                 out[0] = in[0] * r;
312                 out[1] = in[1] * g;
313                 out[2] = in[2] * b;
314                 out[3] = in[3];
315                 in += 4;
316                 out += 4;
317         }
318 }
319
320 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
321 {
322         int i;
323         for (i = 0;i < verts;i++)
324         {
325                 out[0] = r;
326                 out[1] = g;
327                 out[2] = b;
328                 out[3] = a;
329                 out += 4;
330         }
331 }
332
333 // FIXME: move this to client?
334 void FOG_clear(void)
335 {
336         if (gamemode == GAME_NEHAHRA)
337         {
338                 Cvar_Set("gl_fogenable", "0");
339                 Cvar_Set("gl_fogdensity", "0.2");
340                 Cvar_Set("gl_fogred", "0.3");
341                 Cvar_Set("gl_foggreen", "0.3");
342                 Cvar_Set("gl_fogblue", "0.3");
343         }
344         r_refdef.fog_density = 0;
345         r_refdef.fog_red = 0;
346         r_refdef.fog_green = 0;
347         r_refdef.fog_blue = 0;
348         r_refdef.fog_alpha = 1;
349         r_refdef.fog_start = 0;
350         r_refdef.fog_end = 16384;
351         r_refdef.fog_height = 1<<30;
352         r_refdef.fog_fadedepth = 128;
353         memset(r_refdef.fog_height_texturename, 0, sizeof(r_refdef.fog_height_texturename));
354 }
355
356 static void R_BuildBlankTextures(void)
357 {
358         unsigned char data[4];
359         data[2] = 128; // normal X
360         data[1] = 128; // normal Y
361         data[0] = 255; // normal Z
362         data[3] = 255; // height
363         r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
364         data[0] = 255;
365         data[1] = 255;
366         data[2] = 255;
367         data[3] = 255;
368         r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
369         data[0] = 128;
370         data[1] = 128;
371         data[2] = 128;
372         data[3] = 255;
373         r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
374         data[0] = 0;
375         data[1] = 0;
376         data[2] = 0;
377         data[3] = 255;
378         r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
379 }
380
381 static void R_BuildNoTexture(void)
382 {
383         int x, y;
384         unsigned char pix[16][16][4];
385         // this makes a light grey/dark grey checkerboard texture
386         for (y = 0;y < 16;y++)
387         {
388                 for (x = 0;x < 16;x++)
389                 {
390                         if ((y < 8) ^ (x < 8))
391                         {
392                                 pix[y][x][0] = 128;
393                                 pix[y][x][1] = 128;
394                                 pix[y][x][2] = 128;
395                                 pix[y][x][3] = 255;
396                         }
397                         else
398                         {
399                                 pix[y][x][0] = 64;
400                                 pix[y][x][1] = 64;
401                                 pix[y][x][2] = 64;
402                                 pix[y][x][3] = 255;
403                         }
404                 }
405         }
406         r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, -1, NULL);
407 }
408
409 static void R_BuildWhiteCube(void)
410 {
411         unsigned char data[6*1*1*4];
412         memset(data, 255, sizeof(data));
413         r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
414 }
415
416 static void R_BuildNormalizationCube(void)
417 {
418         int x, y, side;
419         vec3_t v;
420         vec_t s, t, intensity;
421 #define NORMSIZE 64
422         unsigned char *data;
423         data = (unsigned char *)Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
424         for (side = 0;side < 6;side++)
425         {
426                 for (y = 0;y < NORMSIZE;y++)
427                 {
428                         for (x = 0;x < NORMSIZE;x++)
429                         {
430                                 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
431                                 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
432                                 switch(side)
433                                 {
434                                 default:
435                                 case 0:
436                                         v[0] = 1;
437                                         v[1] = -t;
438                                         v[2] = -s;
439                                         break;
440                                 case 1:
441                                         v[0] = -1;
442                                         v[1] = -t;
443                                         v[2] = s;
444                                         break;
445                                 case 2:
446                                         v[0] = s;
447                                         v[1] = 1;
448                                         v[2] = t;
449                                         break;
450                                 case 3:
451                                         v[0] = s;
452                                         v[1] = -1;
453                                         v[2] = -t;
454                                         break;
455                                 case 4:
456                                         v[0] = s;
457                                         v[1] = -t;
458                                         v[2] = 1;
459                                         break;
460                                 case 5:
461                                         v[0] = -s;
462                                         v[1] = -t;
463                                         v[2] = -1;
464                                         break;
465                                 }
466                                 intensity = 127.0f / sqrt(DotProduct(v, v));
467                                 data[((side*64+y)*64+x)*4+2] = (unsigned char)(128.0f + intensity * v[0]);
468                                 data[((side*64+y)*64+x)*4+1] = (unsigned char)(128.0f + intensity * v[1]);
469                                 data[((side*64+y)*64+x)*4+0] = (unsigned char)(128.0f + intensity * v[2]);
470                                 data[((side*64+y)*64+x)*4+3] = 255;
471                         }
472                 }
473         }
474         r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
475         Mem_Free(data);
476 }
477
478 static void R_BuildFogTexture(void)
479 {
480         int x, b;
481 #define FOGWIDTH 256
482         unsigned char data1[FOGWIDTH][4];
483         //unsigned char data2[FOGWIDTH][4];
484         double d, r, alpha;
485
486         r_refdef.fogmasktable_start = r_refdef.fog_start;
487         r_refdef.fogmasktable_alpha = r_refdef.fog_alpha;
488         r_refdef.fogmasktable_range = r_refdef.fogrange;
489         r_refdef.fogmasktable_density = r_refdef.fog_density;
490
491         r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH;
492         for (x = 0;x < FOGMASKTABLEWIDTH;x++)
493         {
494                 d = (x * r - r_refdef.fogmasktable_start);
495                 if(developer_extra.integer)
496                         Con_DPrintf("%f ", d);
497                 d = max(0, d);
498                 if (r_fog_exp2.integer)
499                         alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d);
500                 else
501                         alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d);
502                 if(developer_extra.integer)
503                         Con_DPrintf(" : %f ", alpha);
504                 alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha;
505                 if(developer_extra.integer)
506                         Con_DPrintf(" = %f\n", alpha);
507                 r_refdef.fogmasktable[x] = bound(0, alpha, 1);
508         }
509
510         for (x = 0;x < FOGWIDTH;x++)
511         {
512                 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
513                 data1[x][0] = b;
514                 data1[x][1] = b;
515                 data1[x][2] = b;
516                 data1[x][3] = 255;
517                 //data2[x][0] = 255 - b;
518                 //data2[x][1] = 255 - b;
519                 //data2[x][2] = 255 - b;
520                 //data2[x][3] = 255;
521         }
522         if (r_texture_fogattenuation)
523         {
524                 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
525                 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
526         }
527         else
528         {
529                 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
530                 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
531         }
532 }
533
534 static void R_BuildFogHeightTexture(void)
535 {
536         unsigned char *inpixels;
537         int size;
538         int x;
539         int y;
540         int j;
541         float c[4];
542         float f;
543         inpixels = NULL;
544         strlcpy(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename, sizeof(r_refdef.fogheighttexturename));
545         if (r_refdef.fogheighttexturename[0])
546                 inpixels = loadimagepixelsbgra(r_refdef.fogheighttexturename, true, false, false, NULL);
547         if (!inpixels)
548         {
549                 r_refdef.fog_height_tablesize = 0;
550                 if (r_texture_fogheighttexture)
551                         R_FreeTexture(r_texture_fogheighttexture);
552                 r_texture_fogheighttexture = NULL;
553                 if (r_refdef.fog_height_table2d)
554                         Mem_Free(r_refdef.fog_height_table2d);
555                 r_refdef.fog_height_table2d = NULL;
556                 if (r_refdef.fog_height_table1d)
557                         Mem_Free(r_refdef.fog_height_table1d);
558                 r_refdef.fog_height_table1d = NULL;
559                 return;
560         }
561         size = image_width;
562         r_refdef.fog_height_tablesize = size;
563         r_refdef.fog_height_table1d = (unsigned char *)Mem_Alloc(r_main_mempool, size * 4);
564         r_refdef.fog_height_table2d = (unsigned char *)Mem_Alloc(r_main_mempool, size * size * 4);
565         memcpy(r_refdef.fog_height_table1d, inpixels, size * 4);
566         Mem_Free(inpixels);
567         // LordHavoc: now the magic - what is that table2d for?  it is a cooked
568         // average fog color table accounting for every fog layer between a point
569         // and the camera.  (Note: attenuation is handled separately!)
570         for (y = 0;y < size;y++)
571         {
572                 for (x = 0;x < size;x++)
573                 {
574                         Vector4Clear(c);
575                         f = 0;
576                         if (x < y)
577                         {
578                                 for (j = x;j <= y;j++)
579                                 {
580                                         Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
581                                         f++;
582                                 }
583                         }
584                         else
585                         {
586                                 for (j = x;j >= y;j--)
587                                 {
588                                         Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
589                                         f++;
590                                 }
591                         }
592                         f = 1.0f / f;
593                         r_refdef.fog_height_table2d[(y*size+x)*4+0] = (unsigned char)(c[0] * f);
594                         r_refdef.fog_height_table2d[(y*size+x)*4+1] = (unsigned char)(c[1] * f);
595                         r_refdef.fog_height_table2d[(y*size+x)*4+2] = (unsigned char)(c[2] * f);
596                         r_refdef.fog_height_table2d[(y*size+x)*4+3] = (unsigned char)(c[3] * f);
597                 }
598         }
599         r_texture_fogheighttexture = R_LoadTexture2D(r_main_texturepool, "fogheighttable", size, size, r_refdef.fog_height_table2d, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_CLAMP, -1, NULL);
600 }
601
602 //=======================================================================================================================================================
603
604 static const char *builtinshaderstring =
605 #include "shader_glsl.h"
606 ;
607
608 const char *builtinhlslshaderstring =
609 #include "shader_hlsl.h"
610 ;
611
612 char *glslshaderstring = NULL;
613 char *hlslshaderstring = NULL;
614
615 //=======================================================================================================================================================
616
617 typedef struct shaderpermutationinfo_s
618 {
619         const char *pretext;
620         const char *name;
621 }
622 shaderpermutationinfo_t;
623
624 typedef struct shadermodeinfo_s
625 {
626         const char *vertexfilename;
627         const char *geometryfilename;
628         const char *fragmentfilename;
629         const char *pretext;
630         const char *name;
631 }
632 shadermodeinfo_t;
633
634 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
635 shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
636 {
637         {"#define USEDIFFUSE\n", " diffuse"},
638         {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
639         {"#define USEVIEWTINT\n", " viewtint"},
640         {"#define USECOLORMAPPING\n", " colormapping"},
641         {"#define USESATURATION\n", " saturation"},
642         {"#define USEFOGINSIDE\n", " foginside"},
643         {"#define USEFOGOUTSIDE\n", " fogoutside"},
644         {"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"},
645         {"#define USEFOGALPHAHACK\n", " fogalphahack"},
646         {"#define USEGAMMARAMPS\n", " gammaramps"},
647         {"#define USECUBEFILTER\n", " cubefilter"},
648         {"#define USEGLOW\n", " glow"},
649         {"#define USEBLOOM\n", " bloom"},
650         {"#define USESPECULAR\n", " specular"},
651         {"#define USEPOSTPROCESSING\n", " postprocessing"},
652         {"#define USEREFLECTION\n", " reflection"},
653         {"#define USEOFFSETMAPPING\n", " offsetmapping"},
654         {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
655         {"#define USESHADOWMAP2D\n", " shadowmap2d"},
656         {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, // TODO make this a static parm
657         {"#define USESHADOWMAPORTHO\n", " shadowmaportho"},
658         {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
659         {"#define USEALPHAKILL\n", " alphakill"},
660         {"#define USEREFLECTCUBE\n", " reflectcube"},
661         {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
662         {"#define USEBOUNCEGRID\n", " bouncegrid"},
663         {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, // TODO make this a static parm
664         {"#define USETRIPPY\n", " trippy"},
665         {"#define USEDEPTHRGB\n", " depthrgb"},
666         {"#define USEALPHAGENVERTEX\n", " alphagenvertex"},
667         {"#define USESKELETAL\n", " skeletal"}
668 };
669
670 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
671 shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
672 {
673         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
674         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
675         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
676         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
677         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
678         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
679         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
680         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
681         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
682         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
683         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
684         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
685         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
686         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
687         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_WATER\n", " water"},
688         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
689         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
690         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
691 };
692
693 shadermodeinfo_t hlslshadermodeinfo[SHADERMODE_COUNT] =
694 {
695         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_GENERIC\n", " generic"},
696         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_POSTPROCESS\n", " postprocess"},
697         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
698         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
699         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
700         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTMAP\n", " lightmap"},
701         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"},
702         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
703         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
704         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
705         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
706         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
707         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
708         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"},
709         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_WATER\n", " water"},
710         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
711         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
712         {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
713 };
714
715 struct r_glsl_permutation_s;
716 typedef struct r_glsl_permutation_s
717 {
718         /// hash lookup data
719         struct r_glsl_permutation_s *hashnext;
720         unsigned int mode;
721         unsigned int permutation;
722
723         /// indicates if we have tried compiling this permutation already
724         qboolean compiled;
725         /// 0 if compilation failed
726         int program;
727         // texture units assigned to each detected uniform
728         int tex_Texture_First;
729         int tex_Texture_Second;
730         int tex_Texture_GammaRamps;
731         int tex_Texture_Normal;
732         int tex_Texture_Color;
733         int tex_Texture_Gloss;
734         int tex_Texture_Glow;
735         int tex_Texture_SecondaryNormal;
736         int tex_Texture_SecondaryColor;
737         int tex_Texture_SecondaryGloss;
738         int tex_Texture_SecondaryGlow;
739         int tex_Texture_Pants;
740         int tex_Texture_Shirt;
741         int tex_Texture_FogHeightTexture;
742         int tex_Texture_FogMask;
743         int tex_Texture_Lightmap;
744         int tex_Texture_Deluxemap;
745         int tex_Texture_Attenuation;
746         int tex_Texture_Cube;
747         int tex_Texture_Refraction;
748         int tex_Texture_Reflection;
749         int tex_Texture_ShadowMap2D;
750         int tex_Texture_CubeProjection;
751         int tex_Texture_ScreenNormalMap;
752         int tex_Texture_ScreenDiffuse;
753         int tex_Texture_ScreenSpecular;
754         int tex_Texture_ReflectMask;
755         int tex_Texture_ReflectCube;
756         int tex_Texture_BounceGrid;
757         /// locations of detected uniforms in program object, or -1 if not found
758         int loc_Texture_First;
759         int loc_Texture_Second;
760         int loc_Texture_GammaRamps;
761         int loc_Texture_Normal;
762         int loc_Texture_Color;
763         int loc_Texture_Gloss;
764         int loc_Texture_Glow;
765         int loc_Texture_SecondaryNormal;
766         int loc_Texture_SecondaryColor;
767         int loc_Texture_SecondaryGloss;
768         int loc_Texture_SecondaryGlow;
769         int loc_Texture_Pants;
770         int loc_Texture_Shirt;
771         int loc_Texture_FogHeightTexture;
772         int loc_Texture_FogMask;
773         int loc_Texture_Lightmap;
774         int loc_Texture_Deluxemap;
775         int loc_Texture_Attenuation;
776         int loc_Texture_Cube;
777         int loc_Texture_Refraction;
778         int loc_Texture_Reflection;
779         int loc_Texture_ShadowMap2D;
780         int loc_Texture_CubeProjection;
781         int loc_Texture_ScreenNormalMap;
782         int loc_Texture_ScreenDiffuse;
783         int loc_Texture_ScreenSpecular;
784         int loc_Texture_ReflectMask;
785         int loc_Texture_ReflectCube;
786         int loc_Texture_BounceGrid;
787         int loc_Alpha;
788         int loc_BloomBlur_Parameters;
789         int loc_ClientTime;
790         int loc_Color_Ambient;
791         int loc_Color_Diffuse;
792         int loc_Color_Specular;
793         int loc_Color_Glow;
794         int loc_Color_Pants;
795         int loc_Color_Shirt;
796         int loc_DeferredColor_Ambient;
797         int loc_DeferredColor_Diffuse;
798         int loc_DeferredColor_Specular;
799         int loc_DeferredMod_Diffuse;
800         int loc_DeferredMod_Specular;
801         int loc_DistortScaleRefractReflect;
802         int loc_EyePosition;
803         int loc_FogColor;
804         int loc_FogHeightFade;
805         int loc_FogPlane;
806         int loc_FogPlaneViewDist;
807         int loc_FogRangeRecip;
808         int loc_LightColor;
809         int loc_LightDir;
810         int loc_LightPosition;
811         int loc_OffsetMapping_ScaleSteps;
812         int loc_OffsetMapping_LodDistance;
813         int loc_OffsetMapping_Bias;
814         int loc_PixelSize;
815         int loc_ReflectColor;
816         int loc_ReflectFactor;
817         int loc_ReflectOffset;
818         int loc_RefractColor;
819         int loc_Saturation;
820         int loc_ScreenCenterRefractReflect;
821         int loc_ScreenScaleRefractReflect;
822         int loc_ScreenToDepth;
823         int loc_ShadowMap_Parameters;
824         int loc_ShadowMap_TextureScale;
825         int loc_SpecularPower;
826         int loc_Skeletal_Transform12;
827         int loc_UserVec1;
828         int loc_UserVec2;
829         int loc_UserVec3;
830         int loc_UserVec4;
831         int loc_ViewTintColor;
832         int loc_ViewToLight;
833         int loc_ModelToLight;
834         int loc_TexMatrix;
835         int loc_BackgroundTexMatrix;
836         int loc_ModelViewProjectionMatrix;
837         int loc_ModelViewMatrix;
838         int loc_PixelToScreenTexCoord;
839         int loc_ModelToReflectCube;
840         int loc_ShadowMapMatrix;
841         int loc_BloomColorSubtract;
842         int loc_NormalmapScrollBlend;
843         int loc_BounceGridMatrix;
844         int loc_BounceGridIntensity;
845 }
846 r_glsl_permutation_t;
847
848 #define SHADERPERMUTATION_HASHSIZE 256
849
850
851 // non-degradable "lightweight" shader parameters to keep the permutations simpler
852 // these can NOT degrade! only use for simple stuff
853 enum
854 {
855         SHADERSTATICPARM_SATURATION_REDCOMPENSATE = 0, ///< red compensation filter for saturation
856         SHADERSTATICPARM_EXACTSPECULARMATH = 1, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
857         SHADERSTATICPARM_POSTPROCESS_USERVEC1 = 2, ///< postprocess uservec1 is enabled
858         SHADERSTATICPARM_POSTPROCESS_USERVEC2 = 3, ///< postprocess uservec2 is enabled
859         SHADERSTATICPARM_POSTPROCESS_USERVEC3 = 4, ///< postprocess uservec3 is enabled
860         SHADERSTATICPARM_POSTPROCESS_USERVEC4 = 5,  ///< postprocess uservec4 is enabled
861         SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6, // use both alpha layers while blending materials, allows more advanced microblending
862         SHADERSTATICPARM_OFFSETMAPPING_USELOD = 7,  ///< LOD for offsetmapping
863         SHADERSTATICPARM_SHADOWMAPPCF_1 = 8, ///< PCF 1
864         SHADERSTATICPARM_SHADOWMAPPCF_2 = 9, ///< PCF 2
865         SHADERSTATICPARM_SHADOWSAMPLER = 10, ///< sampler
866         SHADERSTATICPARM_CELSHADING = 11, ///< celshading (alternative diffuse and specular math)
867         SHADERSTATICPARM_CELOUTLINES = 12, ///< celoutline (depth buffer analysis to produce outlines)
868 };
869 #define SHADERSTATICPARMS_COUNT 13
870
871 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
872 static int shaderstaticparms_count = 0;
873
874 static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
875 #define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
876
877 extern qboolean r_shadow_shadowmapsampler;
878 extern int r_shadow_shadowmappcf;
879 qboolean R_CompileShader_CheckStaticParms(void)
880 {
881         static int r_compileshader_staticparms_save[1];
882         memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
883         memset(r_compileshader_staticparms, 0, sizeof(r_compileshader_staticparms));
884
885         // detect all
886         if (r_glsl_saturation_redcompensate.integer)
887                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SATURATION_REDCOMPENSATE);
888         if (r_glsl_vertextextureblend_usebothalphas.integer)
889                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS);
890         if (r_shadow_glossexact.integer)
891                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_EXACTSPECULARMATH);
892         if (r_glsl_postprocess.integer)
893         {
894                 if (r_glsl_postprocess_uservec1_enable.integer)
895                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC1);
896                 if (r_glsl_postprocess_uservec2_enable.integer)
897                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC2);
898                 if (r_glsl_postprocess_uservec3_enable.integer)
899                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC3);
900                 if (r_glsl_postprocess_uservec4_enable.integer)
901                         R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4);
902         }
903         if (r_glsl_offsetmapping_lod.integer && r_glsl_offsetmapping_lod_distance.integer > 0)
904                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_OFFSETMAPPING_USELOD);
905
906         if (r_shadow_shadowmapsampler)
907                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWSAMPLER);
908         if (r_shadow_shadowmappcf > 1)
909                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_2);
910         else if (r_shadow_shadowmappcf)
911                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_1);
912         if (r_celshading.integer)
913                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELSHADING);
914         if (r_celoutlines.integer)
915                 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELOUTLINES);
916
917         return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
918 }
919
920 #define R_COMPILESHADER_STATICPARM_EMIT(p, n) \
921         if(r_compileshader_staticparms[(p) >> 5] & (1 << ((p) & 0x1F))) \
922                 shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
923         else \
924                 shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
925 static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation)
926 {
927         shaderstaticparms_count = 0;
928
929         // emit all
930         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SATURATION_REDCOMPENSATE, "SATURATION_REDCOMPENSATE");
931         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_EXACTSPECULARMATH, "USEEXACTSPECULARMATH");
932         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC1, "USERVEC1");
933         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC2, "USERVEC2");
934         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC3, "USERVEC3");
935         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC4, "USERVEC4");
936         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS, "USEBOTHALPHAS");
937         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_OFFSETMAPPING_USELOD, "USEOFFSETMAPPING_LOD");
938         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_1, "USESHADOWMAPPCF 1");
939         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_2, "USESHADOWMAPPCF 2");
940         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWSAMPLER, "USESHADOWSAMPLER");
941         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELSHADING, "USECELSHADING");
942         R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELOUTLINES, "USECELOUTLINES");
943 }
944
945 /// information about each possible shader permutation
946 r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
947 /// currently selected permutation
948 r_glsl_permutation_t *r_glsl_permutation;
949 /// storage for permutations linked in the hash table
950 memexpandablearray_t r_glsl_permutationarray;
951
952 static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, unsigned int permutation)
953 {
954         //unsigned int hashdepth = 0;
955         unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
956         r_glsl_permutation_t *p;
957         for (p = r_glsl_permutationhash[mode][hashindex];p;p = p->hashnext)
958         {
959                 if (p->mode == mode && p->permutation == permutation)
960                 {
961                         //if (hashdepth > 10)
962                         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
963                         return p;
964                 }
965                 //hashdepth++;
966         }
967         p = (r_glsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_glsl_permutationarray);
968         p->mode = mode;
969         p->permutation = permutation;
970         p->hashnext = r_glsl_permutationhash[mode][hashindex];
971         r_glsl_permutationhash[mode][hashindex] = p;
972         //if (hashdepth > 10)
973         //      Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
974         return p;
975 }
976
977 static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice)
978 {
979         char *shaderstring;
980         if (!filename || !filename[0])
981                 return NULL;
982         if (!strcmp(filename, "glsl/default.glsl"))
983         {
984                 if (!glslshaderstring)
985                 {
986                         glslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
987                         if (glslshaderstring)
988                                 Con_DPrintf("Loading shaders from file %s...\n", filename);
989                         else
990                                 glslshaderstring = (char *)builtinshaderstring;
991                 }
992                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(glslshaderstring) + 1);
993                 memcpy(shaderstring, glslshaderstring, strlen(glslshaderstring) + 1);
994                 return shaderstring;
995         }
996         shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
997         if (shaderstring)
998         {
999                 if (printfromdisknotice)
1000                         Con_DPrintf("from disk %s... ", filename);
1001                 return shaderstring;
1002         }
1003         return shaderstring;
1004 }
1005
1006 static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation)
1007 {
1008         int i;
1009         int sampler;
1010         shadermodeinfo_t *modeinfo = glslshadermodeinfo + mode;
1011         char *vertexstring, *geometrystring, *fragmentstring;
1012         char permutationname[256];
1013         int vertstrings_count = 0;
1014         int geomstrings_count = 0;
1015         int fragstrings_count = 0;
1016         const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1017         const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1018         const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1019
1020         if (p->compiled)
1021                 return;
1022         p->compiled = true;
1023         p->program = 0;
1024
1025         permutationname[0] = 0;
1026         vertexstring   = R_GLSL_GetText(modeinfo->vertexfilename, true);
1027         geometrystring = R_GLSL_GetText(modeinfo->geometryfilename, false);
1028         fragmentstring = R_GLSL_GetText(modeinfo->fragmentfilename, false);
1029
1030         strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
1031
1032         // if we can do #version 130, we should (this improves quality of offset/reliefmapping thanks to textureGrad)
1033         if(vid.support.gl20shaders130)
1034         {
1035                 vertstrings_list[vertstrings_count++] = "#version 130\n";
1036                 geomstrings_list[geomstrings_count++] = "#version 130\n";
1037                 fragstrings_list[fragstrings_count++] = "#version 130\n";
1038                 vertstrings_list[vertstrings_count++] = "#define GLSL130\n";
1039                 geomstrings_list[geomstrings_count++] = "#define GLSL130\n";
1040                 fragstrings_list[fragstrings_count++] = "#define GLSL130\n";
1041         }
1042
1043         // the first pretext is which type of shader to compile as
1044         // (later these will all be bound together as a program object)
1045         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1046         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1047         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1048
1049         // the second pretext is the mode (for example a light source)
1050         vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1051         geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1052         fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1053         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1054
1055         // now add all the permutation pretexts
1056         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1057         {
1058                 if (permutation & (1<<i))
1059                 {
1060                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1061                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1062                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1063                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1064                 }
1065                 else
1066                 {
1067                         // keep line numbers correct
1068                         vertstrings_list[vertstrings_count++] = "\n";
1069                         geomstrings_list[geomstrings_count++] = "\n";
1070                         fragstrings_list[fragstrings_count++] = "\n";
1071                 }
1072         }
1073
1074         // add static parms
1075         R_CompileShader_AddStaticParms(mode, permutation);
1076         memcpy((char *)(vertstrings_list + vertstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1077         vertstrings_count += shaderstaticparms_count;
1078         memcpy((char *)(geomstrings_list + geomstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1079         geomstrings_count += shaderstaticparms_count;
1080         memcpy((char *)(fragstrings_list + fragstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1081         fragstrings_count += shaderstaticparms_count;
1082
1083         // now append the shader text itself
1084         vertstrings_list[vertstrings_count++] = vertexstring;
1085         geomstrings_list[geomstrings_count++] = geometrystring;
1086         fragstrings_list[fragstrings_count++] = fragmentstring;
1087
1088         // if any sources were NULL, clear the respective list
1089         if (!vertexstring)
1090                 vertstrings_count = 0;
1091         if (!geometrystring)
1092                 geomstrings_count = 0;
1093         if (!fragmentstring)
1094                 fragstrings_count = 0;
1095
1096         // compile the shader program
1097         if (vertstrings_count + geomstrings_count + fragstrings_count)
1098                 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
1099         if (p->program)
1100         {
1101                 CHECKGLERROR
1102                 qglUseProgram(p->program);CHECKGLERROR
1103                 // look up all the uniform variable names we care about, so we don't
1104                 // have to look them up every time we set them
1105
1106                 p->loc_Texture_First              = qglGetUniformLocation(p->program, "Texture_First");
1107                 p->loc_Texture_Second             = qglGetUniformLocation(p->program, "Texture_Second");
1108                 p->loc_Texture_GammaRamps         = qglGetUniformLocation(p->program, "Texture_GammaRamps");
1109                 p->loc_Texture_Normal             = qglGetUniformLocation(p->program, "Texture_Normal");
1110                 p->loc_Texture_Color              = qglGetUniformLocation(p->program, "Texture_Color");
1111                 p->loc_Texture_Gloss              = qglGetUniformLocation(p->program, "Texture_Gloss");
1112                 p->loc_Texture_Glow               = qglGetUniformLocation(p->program, "Texture_Glow");
1113                 p->loc_Texture_SecondaryNormal    = qglGetUniformLocation(p->program, "Texture_SecondaryNormal");
1114                 p->loc_Texture_SecondaryColor     = qglGetUniformLocation(p->program, "Texture_SecondaryColor");
1115                 p->loc_Texture_SecondaryGloss     = qglGetUniformLocation(p->program, "Texture_SecondaryGloss");
1116                 p->loc_Texture_SecondaryGlow      = qglGetUniformLocation(p->program, "Texture_SecondaryGlow");
1117                 p->loc_Texture_Pants              = qglGetUniformLocation(p->program, "Texture_Pants");
1118                 p->loc_Texture_Shirt              = qglGetUniformLocation(p->program, "Texture_Shirt");
1119                 p->loc_Texture_FogHeightTexture   = qglGetUniformLocation(p->program, "Texture_FogHeightTexture");
1120                 p->loc_Texture_FogMask            = qglGetUniformLocation(p->program, "Texture_FogMask");
1121                 p->loc_Texture_Lightmap           = qglGetUniformLocation(p->program, "Texture_Lightmap");
1122                 p->loc_Texture_Deluxemap          = qglGetUniformLocation(p->program, "Texture_Deluxemap");
1123                 p->loc_Texture_Attenuation        = qglGetUniformLocation(p->program, "Texture_Attenuation");
1124                 p->loc_Texture_Cube               = qglGetUniformLocation(p->program, "Texture_Cube");
1125                 p->loc_Texture_Refraction         = qglGetUniformLocation(p->program, "Texture_Refraction");
1126                 p->loc_Texture_Reflection         = qglGetUniformLocation(p->program, "Texture_Reflection");
1127                 p->loc_Texture_ShadowMap2D        = qglGetUniformLocation(p->program, "Texture_ShadowMap2D");
1128                 p->loc_Texture_CubeProjection     = qglGetUniformLocation(p->program, "Texture_CubeProjection");
1129                 p->loc_Texture_ScreenNormalMap    = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap");
1130                 p->loc_Texture_ScreenDiffuse      = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse");
1131                 p->loc_Texture_ScreenSpecular     = qglGetUniformLocation(p->program, "Texture_ScreenSpecular");
1132                 p->loc_Texture_ReflectMask        = qglGetUniformLocation(p->program, "Texture_ReflectMask");
1133                 p->loc_Texture_ReflectCube        = qglGetUniformLocation(p->program, "Texture_ReflectCube");
1134                 p->loc_Texture_BounceGrid         = qglGetUniformLocation(p->program, "Texture_BounceGrid");
1135                 p->loc_Alpha                      = qglGetUniformLocation(p->program, "Alpha");
1136                 p->loc_BloomBlur_Parameters       = qglGetUniformLocation(p->program, "BloomBlur_Parameters");
1137                 p->loc_ClientTime                 = qglGetUniformLocation(p->program, "ClientTime");
1138                 p->loc_Color_Ambient              = qglGetUniformLocation(p->program, "Color_Ambient");
1139                 p->loc_Color_Diffuse              = qglGetUniformLocation(p->program, "Color_Diffuse");
1140                 p->loc_Color_Specular             = qglGetUniformLocation(p->program, "Color_Specular");
1141                 p->loc_Color_Glow                 = qglGetUniformLocation(p->program, "Color_Glow");
1142                 p->loc_Color_Pants                = qglGetUniformLocation(p->program, "Color_Pants");
1143                 p->loc_Color_Shirt                = qglGetUniformLocation(p->program, "Color_Shirt");
1144                 p->loc_DeferredColor_Ambient      = qglGetUniformLocation(p->program, "DeferredColor_Ambient");
1145                 p->loc_DeferredColor_Diffuse      = qglGetUniformLocation(p->program, "DeferredColor_Diffuse");
1146                 p->loc_DeferredColor_Specular     = qglGetUniformLocation(p->program, "DeferredColor_Specular");
1147                 p->loc_DeferredMod_Diffuse        = qglGetUniformLocation(p->program, "DeferredMod_Diffuse");
1148                 p->loc_DeferredMod_Specular       = qglGetUniformLocation(p->program, "DeferredMod_Specular");
1149                 p->loc_DistortScaleRefractReflect = qglGetUniformLocation(p->program, "DistortScaleRefractReflect");
1150                 p->loc_EyePosition                = qglGetUniformLocation(p->program, "EyePosition");
1151                 p->loc_FogColor                   = qglGetUniformLocation(p->program, "FogColor");
1152                 p->loc_FogHeightFade              = qglGetUniformLocation(p->program, "FogHeightFade");
1153                 p->loc_FogPlane                   = qglGetUniformLocation(p->program, "FogPlane");
1154                 p->loc_FogPlaneViewDist           = qglGetUniformLocation(p->program, "FogPlaneViewDist");
1155                 p->loc_FogRangeRecip              = qglGetUniformLocation(p->program, "FogRangeRecip");
1156                 p->loc_LightColor                 = qglGetUniformLocation(p->program, "LightColor");
1157                 p->loc_LightDir                   = qglGetUniformLocation(p->program, "LightDir");
1158                 p->loc_LightPosition              = qglGetUniformLocation(p->program, "LightPosition");
1159                 p->loc_OffsetMapping_ScaleSteps   = qglGetUniformLocation(p->program, "OffsetMapping_ScaleSteps");
1160                 p->loc_OffsetMapping_LodDistance  = qglGetUniformLocation(p->program, "OffsetMapping_LodDistance");
1161                 p->loc_OffsetMapping_Bias         = qglGetUniformLocation(p->program, "OffsetMapping_Bias");
1162                 p->loc_PixelSize                  = qglGetUniformLocation(p->program, "PixelSize");
1163                 p->loc_ReflectColor               = qglGetUniformLocation(p->program, "ReflectColor");
1164                 p->loc_ReflectFactor              = qglGetUniformLocation(p->program, "ReflectFactor");
1165                 p->loc_ReflectOffset              = qglGetUniformLocation(p->program, "ReflectOffset");
1166                 p->loc_RefractColor               = qglGetUniformLocation(p->program, "RefractColor");
1167                 p->loc_Saturation                 = qglGetUniformLocation(p->program, "Saturation");
1168                 p->loc_ScreenCenterRefractReflect = qglGetUniformLocation(p->program, "ScreenCenterRefractReflect");
1169                 p->loc_ScreenScaleRefractReflect  = qglGetUniformLocation(p->program, "ScreenScaleRefractReflect");
1170                 p->loc_ScreenToDepth              = qglGetUniformLocation(p->program, "ScreenToDepth");
1171                 p->loc_ShadowMap_Parameters       = qglGetUniformLocation(p->program, "ShadowMap_Parameters");
1172                 p->loc_ShadowMap_TextureScale     = qglGetUniformLocation(p->program, "ShadowMap_TextureScale");
1173                 p->loc_SpecularPower              = qglGetUniformLocation(p->program, "SpecularPower");
1174                 p->loc_Skeletal_Transform12       = qglGetUniformLocation(p->program, "Skeletal_Transform12");
1175                 p->loc_UserVec1                   = qglGetUniformLocation(p->program, "UserVec1");
1176                 p->loc_UserVec2                   = qglGetUniformLocation(p->program, "UserVec2");
1177                 p->loc_UserVec3                   = qglGetUniformLocation(p->program, "UserVec3");
1178                 p->loc_UserVec4                   = qglGetUniformLocation(p->program, "UserVec4");
1179                 p->loc_ViewTintColor              = qglGetUniformLocation(p->program, "ViewTintColor");
1180                 p->loc_ViewToLight                = qglGetUniformLocation(p->program, "ViewToLight");
1181                 p->loc_ModelToLight               = qglGetUniformLocation(p->program, "ModelToLight");
1182                 p->loc_TexMatrix                  = qglGetUniformLocation(p->program, "TexMatrix");
1183                 p->loc_BackgroundTexMatrix        = qglGetUniformLocation(p->program, "BackgroundTexMatrix");
1184                 p->loc_ModelViewMatrix            = qglGetUniformLocation(p->program, "ModelViewMatrix");
1185                 p->loc_ModelViewProjectionMatrix  = qglGetUniformLocation(p->program, "ModelViewProjectionMatrix");
1186                 p->loc_PixelToScreenTexCoord      = qglGetUniformLocation(p->program, "PixelToScreenTexCoord");
1187                 p->loc_ModelToReflectCube         = qglGetUniformLocation(p->program, "ModelToReflectCube");
1188                 p->loc_ShadowMapMatrix            = qglGetUniformLocation(p->program, "ShadowMapMatrix");
1189                 p->loc_BloomColorSubtract         = qglGetUniformLocation(p->program, "BloomColorSubtract");
1190                 p->loc_NormalmapScrollBlend       = qglGetUniformLocation(p->program, "NormalmapScrollBlend");
1191                 p->loc_BounceGridMatrix           = qglGetUniformLocation(p->program, "BounceGridMatrix");
1192                 p->loc_BounceGridIntensity        = qglGetUniformLocation(p->program, "BounceGridIntensity");
1193                 // initialize the samplers to refer to the texture units we use
1194                 p->tex_Texture_First = -1;
1195                 p->tex_Texture_Second = -1;
1196                 p->tex_Texture_GammaRamps = -1;
1197                 p->tex_Texture_Normal = -1;
1198                 p->tex_Texture_Color = -1;
1199                 p->tex_Texture_Gloss = -1;
1200                 p->tex_Texture_Glow = -1;
1201                 p->tex_Texture_SecondaryNormal = -1;
1202                 p->tex_Texture_SecondaryColor = -1;
1203                 p->tex_Texture_SecondaryGloss = -1;
1204                 p->tex_Texture_SecondaryGlow = -1;
1205                 p->tex_Texture_Pants = -1;
1206                 p->tex_Texture_Shirt = -1;
1207                 p->tex_Texture_FogHeightTexture = -1;
1208                 p->tex_Texture_FogMask = -1;
1209                 p->tex_Texture_Lightmap = -1;
1210                 p->tex_Texture_Deluxemap = -1;
1211                 p->tex_Texture_Attenuation = -1;
1212                 p->tex_Texture_Cube = -1;
1213                 p->tex_Texture_Refraction = -1;
1214                 p->tex_Texture_Reflection = -1;
1215                 p->tex_Texture_ShadowMap2D = -1;
1216                 p->tex_Texture_CubeProjection = -1;
1217                 p->tex_Texture_ScreenNormalMap = -1;
1218                 p->tex_Texture_ScreenDiffuse = -1;
1219                 p->tex_Texture_ScreenSpecular = -1;
1220                 p->tex_Texture_ReflectMask = -1;
1221                 p->tex_Texture_ReflectCube = -1;
1222                 p->tex_Texture_BounceGrid = -1;
1223                 sampler = 0;
1224                 if (p->loc_Texture_First           >= 0) {p->tex_Texture_First            = sampler;qglUniform1i(p->loc_Texture_First           , sampler);sampler++;}
1225                 if (p->loc_Texture_Second          >= 0) {p->tex_Texture_Second           = sampler;qglUniform1i(p->loc_Texture_Second          , sampler);sampler++;}
1226                 if (p->loc_Texture_GammaRamps      >= 0) {p->tex_Texture_GammaRamps       = sampler;qglUniform1i(p->loc_Texture_GammaRamps      , sampler);sampler++;}
1227                 if (p->loc_Texture_Normal          >= 0) {p->tex_Texture_Normal           = sampler;qglUniform1i(p->loc_Texture_Normal          , sampler);sampler++;}
1228                 if (p->loc_Texture_Color           >= 0) {p->tex_Texture_Color            = sampler;qglUniform1i(p->loc_Texture_Color           , sampler);sampler++;}
1229                 if (p->loc_Texture_Gloss           >= 0) {p->tex_Texture_Gloss            = sampler;qglUniform1i(p->loc_Texture_Gloss           , sampler);sampler++;}
1230                 if (p->loc_Texture_Glow            >= 0) {p->tex_Texture_Glow             = sampler;qglUniform1i(p->loc_Texture_Glow            , sampler);sampler++;}
1231                 if (p->loc_Texture_SecondaryNormal >= 0) {p->tex_Texture_SecondaryNormal  = sampler;qglUniform1i(p->loc_Texture_SecondaryNormal , sampler);sampler++;}
1232                 if (p->loc_Texture_SecondaryColor  >= 0) {p->tex_Texture_SecondaryColor   = sampler;qglUniform1i(p->loc_Texture_SecondaryColor  , sampler);sampler++;}
1233                 if (p->loc_Texture_SecondaryGloss  >= 0) {p->tex_Texture_SecondaryGloss   = sampler;qglUniform1i(p->loc_Texture_SecondaryGloss  , sampler);sampler++;}
1234                 if (p->loc_Texture_SecondaryGlow   >= 0) {p->tex_Texture_SecondaryGlow    = sampler;qglUniform1i(p->loc_Texture_SecondaryGlow   , sampler);sampler++;}
1235                 if (p->loc_Texture_Pants           >= 0) {p->tex_Texture_Pants            = sampler;qglUniform1i(p->loc_Texture_Pants           , sampler);sampler++;}
1236                 if (p->loc_Texture_Shirt           >= 0) {p->tex_Texture_Shirt            = sampler;qglUniform1i(p->loc_Texture_Shirt           , sampler);sampler++;}
1237                 if (p->loc_Texture_FogHeightTexture>= 0) {p->tex_Texture_FogHeightTexture = sampler;qglUniform1i(p->loc_Texture_FogHeightTexture, sampler);sampler++;}
1238                 if (p->loc_Texture_FogMask         >= 0) {p->tex_Texture_FogMask          = sampler;qglUniform1i(p->loc_Texture_FogMask         , sampler);sampler++;}
1239                 if (p->loc_Texture_Lightmap        >= 0) {p->tex_Texture_Lightmap         = sampler;qglUniform1i(p->loc_Texture_Lightmap        , sampler);sampler++;}
1240                 if (p->loc_Texture_Deluxemap       >= 0) {p->tex_Texture_Deluxemap        = sampler;qglUniform1i(p->loc_Texture_Deluxemap       , sampler);sampler++;}
1241                 if (p->loc_Texture_Attenuation     >= 0) {p->tex_Texture_Attenuation      = sampler;qglUniform1i(p->loc_Texture_Attenuation     , sampler);sampler++;}
1242                 if (p->loc_Texture_Cube            >= 0) {p->tex_Texture_Cube             = sampler;qglUniform1i(p->loc_Texture_Cube            , sampler);sampler++;}
1243                 if (p->loc_Texture_Refraction      >= 0) {p->tex_Texture_Refraction       = sampler;qglUniform1i(p->loc_Texture_Refraction      , sampler);sampler++;}
1244                 if (p->loc_Texture_Reflection      >= 0) {p->tex_Texture_Reflection       = sampler;qglUniform1i(p->loc_Texture_Reflection      , sampler);sampler++;}
1245                 if (p->loc_Texture_ShadowMap2D     >= 0) {p->tex_Texture_ShadowMap2D      = sampler;qglUniform1i(p->loc_Texture_ShadowMap2D     , sampler);sampler++;}
1246                 if (p->loc_Texture_CubeProjection  >= 0) {p->tex_Texture_CubeProjection   = sampler;qglUniform1i(p->loc_Texture_CubeProjection  , sampler);sampler++;}
1247                 if (p->loc_Texture_ScreenNormalMap >= 0) {p->tex_Texture_ScreenNormalMap  = sampler;qglUniform1i(p->loc_Texture_ScreenNormalMap , sampler);sampler++;}
1248                 if (p->loc_Texture_ScreenDiffuse   >= 0) {p->tex_Texture_ScreenDiffuse    = sampler;qglUniform1i(p->loc_Texture_ScreenDiffuse   , sampler);sampler++;}
1249                 if (p->loc_Texture_ScreenSpecular  >= 0) {p->tex_Texture_ScreenSpecular   = sampler;qglUniform1i(p->loc_Texture_ScreenSpecular  , sampler);sampler++;}
1250                 if (p->loc_Texture_ReflectMask     >= 0) {p->tex_Texture_ReflectMask      = sampler;qglUniform1i(p->loc_Texture_ReflectMask     , sampler);sampler++;}
1251                 if (p->loc_Texture_ReflectCube     >= 0) {p->tex_Texture_ReflectCube      = sampler;qglUniform1i(p->loc_Texture_ReflectCube     , sampler);sampler++;}
1252                 if (p->loc_Texture_BounceGrid      >= 0) {p->tex_Texture_BounceGrid       = sampler;qglUniform1i(p->loc_Texture_BounceGrid      , sampler);sampler++;}
1253                 CHECKGLERROR
1254                 Con_DPrintf("^5GLSL shader %s compiled (%i textures).\n", permutationname, sampler);
1255         }
1256         else
1257                 Con_Printf("^1GLSL shader %s failed!  some features may not work properly.\n", permutationname);
1258
1259         // free the strings
1260         if (vertexstring)
1261                 Mem_Free(vertexstring);
1262         if (geometrystring)
1263                 Mem_Free(geometrystring);
1264         if (fragmentstring)
1265                 Mem_Free(fragmentstring);
1266 }
1267
1268 static void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutation)
1269 {
1270         r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
1271         if (r_glsl_permutation != perm)
1272         {
1273                 r_glsl_permutation = perm;
1274                 if (!r_glsl_permutation->program)
1275                 {
1276                         if (!r_glsl_permutation->compiled)
1277                                 R_GLSL_CompilePermutation(perm, mode, permutation);
1278                         if (!r_glsl_permutation->program)
1279                         {
1280                                 // remove features until we find a valid permutation
1281                                 int i;
1282                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1283                                 {
1284                                         // reduce i more quickly whenever it would not remove any bits
1285                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
1286                                         if (!(permutation & j))
1287                                                 continue;
1288                                         permutation -= j;
1289                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1290                                         if (!r_glsl_permutation->compiled)
1291                                                 R_GLSL_CompilePermutation(perm, mode, permutation);
1292                                         if (r_glsl_permutation->program)
1293                                                 break;
1294                                 }
1295                                 if (i >= SHADERPERMUTATION_COUNT)
1296                                 {
1297                                         //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
1298                                         r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1299                                         qglUseProgram(0);CHECKGLERROR
1300                                         return; // no bit left to clear, entire mode is broken
1301                                 }
1302                         }
1303                 }
1304                 CHECKGLERROR
1305                 qglUseProgram(r_glsl_permutation->program);CHECKGLERROR
1306         }
1307         if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
1308         if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
1309         if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1f(r_glsl_permutation->loc_ClientTime, cl.time);
1310 }
1311
1312 #ifdef SUPPORTD3D
1313
1314 #ifdef SUPPORTD3D
1315 #include <d3d9.h>
1316 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
1317 extern D3DCAPS9 vid_d3d9caps;
1318 #endif
1319
1320 struct r_hlsl_permutation_s;
1321 typedef struct r_hlsl_permutation_s
1322 {
1323         /// hash lookup data
1324         struct r_hlsl_permutation_s *hashnext;
1325         unsigned int mode;
1326         unsigned int permutation;
1327
1328         /// indicates if we have tried compiling this permutation already
1329         qboolean compiled;
1330         /// NULL if compilation failed
1331         IDirect3DVertexShader9 *vertexshader;
1332         IDirect3DPixelShader9 *pixelshader;
1333 }
1334 r_hlsl_permutation_t;
1335
1336 typedef enum D3DVSREGISTER_e
1337 {
1338         D3DVSREGISTER_TexMatrix = 0, // float4x4
1339         D3DVSREGISTER_BackgroundTexMatrix = 4, // float4x4
1340         D3DVSREGISTER_ModelViewProjectionMatrix = 8, // float4x4
1341         D3DVSREGISTER_ModelViewMatrix = 12, // float4x4
1342         D3DVSREGISTER_ShadowMapMatrix = 16, // float4x4
1343         D3DVSREGISTER_ModelToLight = 20, // float4x4
1344         D3DVSREGISTER_EyePosition = 24,
1345         D3DVSREGISTER_FogPlane = 25,
1346         D3DVSREGISTER_LightDir = 26,
1347         D3DVSREGISTER_LightPosition = 27,
1348 }
1349 D3DVSREGISTER_t;
1350
1351 typedef enum D3DPSREGISTER_e
1352 {
1353         D3DPSREGISTER_Alpha = 0,
1354         D3DPSREGISTER_BloomBlur_Parameters = 1,
1355         D3DPSREGISTER_ClientTime = 2,
1356         D3DPSREGISTER_Color_Ambient = 3,
1357         D3DPSREGISTER_Color_Diffuse = 4,
1358         D3DPSREGISTER_Color_Specular = 5,
1359         D3DPSREGISTER_Color_Glow = 6,
1360         D3DPSREGISTER_Color_Pants = 7,
1361         D3DPSREGISTER_Color_Shirt = 8,
1362         D3DPSREGISTER_DeferredColor_Ambient = 9,
1363         D3DPSREGISTER_DeferredColor_Diffuse = 10,
1364         D3DPSREGISTER_DeferredColor_Specular = 11,
1365         D3DPSREGISTER_DeferredMod_Diffuse = 12,
1366         D3DPSREGISTER_DeferredMod_Specular = 13,
1367         D3DPSREGISTER_DistortScaleRefractReflect = 14,
1368         D3DPSREGISTER_EyePosition = 15, // unused
1369         D3DPSREGISTER_FogColor = 16,
1370         D3DPSREGISTER_FogHeightFade = 17,
1371         D3DPSREGISTER_FogPlane = 18,
1372         D3DPSREGISTER_FogPlaneViewDist = 19,
1373         D3DPSREGISTER_FogRangeRecip = 20,
1374         D3DPSREGISTER_LightColor = 21,
1375         D3DPSREGISTER_LightDir = 22, // unused
1376         D3DPSREGISTER_LightPosition = 23,
1377         D3DPSREGISTER_OffsetMapping_ScaleSteps = 24,
1378         D3DPSREGISTER_PixelSize = 25,
1379         D3DPSREGISTER_ReflectColor = 26,
1380         D3DPSREGISTER_ReflectFactor = 27,
1381         D3DPSREGISTER_ReflectOffset = 28,
1382         D3DPSREGISTER_RefractColor = 29,
1383         D3DPSREGISTER_Saturation = 30,
1384         D3DPSREGISTER_ScreenCenterRefractReflect = 31,
1385         D3DPSREGISTER_ScreenScaleRefractReflect = 32,
1386         D3DPSREGISTER_ScreenToDepth = 33,
1387         D3DPSREGISTER_ShadowMap_Parameters = 34,
1388         D3DPSREGISTER_ShadowMap_TextureScale = 35,
1389         D3DPSREGISTER_SpecularPower = 36,
1390         D3DPSREGISTER_UserVec1 = 37,
1391         D3DPSREGISTER_UserVec2 = 38,
1392         D3DPSREGISTER_UserVec3 = 39,
1393         D3DPSREGISTER_UserVec4 = 40,
1394         D3DPSREGISTER_ViewTintColor = 41,
1395         D3DPSREGISTER_PixelToScreenTexCoord = 42,
1396         D3DPSREGISTER_BloomColorSubtract = 43,
1397         D3DPSREGISTER_ViewToLight = 44, // float4x4
1398         D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
1399         D3DPSREGISTER_NormalmapScrollBlend = 52,
1400         D3DPSREGISTER_OffsetMapping_LodDistance = 53,
1401         D3DPSREGISTER_OffsetMapping_Bias = 54,
1402         // next at 54
1403 }
1404 D3DPSREGISTER_t;
1405
1406 /// information about each possible shader permutation
1407 r_hlsl_permutation_t *r_hlsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
1408 /// currently selected permutation
1409 r_hlsl_permutation_t *r_hlsl_permutation;
1410 /// storage for permutations linked in the hash table
1411 memexpandablearray_t r_hlsl_permutationarray;
1412
1413 static r_hlsl_permutation_t *R_HLSL_FindPermutation(unsigned int mode, unsigned int permutation)
1414 {
1415         //unsigned int hashdepth = 0;
1416         unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
1417         r_hlsl_permutation_t *p;
1418         for (p = r_hlsl_permutationhash[mode][hashindex];p;p = p->hashnext)
1419         {
1420                 if (p->mode == mode && p->permutation == permutation)
1421                 {
1422                         //if (hashdepth > 10)
1423                         //      Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1424                         return p;
1425                 }
1426                 //hashdepth++;
1427         }
1428         p = (r_hlsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_hlsl_permutationarray);
1429         p->mode = mode;
1430         p->permutation = permutation;
1431         p->hashnext = r_hlsl_permutationhash[mode][hashindex];
1432         r_hlsl_permutationhash[mode][hashindex] = p;
1433         //if (hashdepth > 10)
1434         //      Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1435         return p;
1436 }
1437
1438 static char *R_HLSL_GetText(const char *filename, qboolean printfromdisknotice)
1439 {
1440         char *shaderstring;
1441         if (!filename || !filename[0])
1442                 return NULL;
1443         if (!strcmp(filename, "hlsl/default.hlsl"))
1444         {
1445                 if (!hlslshaderstring)
1446                 {
1447                         hlslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1448                         if (hlslshaderstring)
1449                                 Con_DPrintf("Loading shaders from file %s...\n", filename);
1450                         else
1451                                 hlslshaderstring = (char *)builtinhlslshaderstring;
1452                 }
1453                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(hlslshaderstring) + 1);
1454                 memcpy(shaderstring, hlslshaderstring, strlen(hlslshaderstring) + 1);
1455                 return shaderstring;
1456         }
1457         shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1458         if (shaderstring)
1459         {
1460                 if (printfromdisknotice)
1461                         Con_DPrintf("from disk %s... ", filename);
1462                 return shaderstring;
1463         }
1464         return shaderstring;
1465 }
1466
1467 #include <d3dx9.h>
1468 //#include <d3dx9shader.h>
1469 //#include <d3dx9mesh.h>
1470
1471 static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
1472 {
1473         DWORD *vsbin = NULL;
1474         DWORD *psbin = NULL;
1475         fs_offset_t vsbinsize;
1476         fs_offset_t psbinsize;
1477 //      IDirect3DVertexShader9 *vs = NULL;
1478 //      IDirect3DPixelShader9 *ps = NULL;
1479         ID3DXBuffer *vslog = NULL;
1480         ID3DXBuffer *vsbuffer = NULL;
1481         ID3DXConstantTable *vsconstanttable = NULL;
1482         ID3DXBuffer *pslog = NULL;
1483         ID3DXBuffer *psbuffer = NULL;
1484         ID3DXConstantTable *psconstanttable = NULL;
1485         int vsresult = 0;
1486         int psresult = 0;
1487         char temp[MAX_INPUTLINE];
1488         const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
1489         char vabuf[1024];
1490         qboolean debugshader = gl_paranoid.integer != 0;
1491         if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1492         if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1493         if (!debugshader)
1494         {
1495                 vsbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
1496                 psbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.psbin", cachename), r_main_mempool, true, &psbinsize);
1497         }
1498         if ((!vsbin && vertstring) || (!psbin && fragstring))
1499         {
1500                 const char* dllnames_d3dx9 [] =
1501                 {
1502                         "d3dx9_43.dll",
1503                         "d3dx9_42.dll",
1504                         "d3dx9_41.dll",
1505                         "d3dx9_40.dll",
1506                         "d3dx9_39.dll",
1507                         "d3dx9_38.dll",
1508                         "d3dx9_37.dll",
1509                         "d3dx9_36.dll",
1510                         "d3dx9_35.dll",
1511                         "d3dx9_34.dll",
1512                         "d3dx9_33.dll",
1513                         "d3dx9_32.dll",
1514                         "d3dx9_31.dll",
1515                         "d3dx9_30.dll",
1516                         "d3dx9_29.dll",
1517                         "d3dx9_28.dll",
1518                         "d3dx9_27.dll",
1519                         "d3dx9_26.dll",
1520                         "d3dx9_25.dll",
1521                         "d3dx9_24.dll",
1522                         NULL
1523                 };
1524                 dllhandle_t d3dx9_dll = NULL;
1525                 HRESULT (WINAPI *qD3DXCompileShaderFromFileA)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1526                 HRESULT (WINAPI *qD3DXPreprocessShader)(LPCSTR pSrcData, UINT SrcDataSize, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs);
1527                 HRESULT (WINAPI *qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1528                 dllfunction_t d3dx9_dllfuncs[] =
1529                 {
1530                         {"D3DXCompileShaderFromFileA",  (void **) &qD3DXCompileShaderFromFileA},
1531                         {"D3DXPreprocessShader",                (void **) &qD3DXPreprocessShader},
1532                         {"D3DXCompileShader",                   (void **) &qD3DXCompileShader},
1533                         {NULL, NULL}
1534                 };
1535                 if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
1536                 {
1537                         DWORD shaderflags = 0;
1538                         if (debugshader)
1539                                 shaderflags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
1540                         vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1541                         psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1542                         if (vertstring && vertstring[0])
1543                         {
1544                                 if (debugshader)
1545                                 {
1546                                         FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_vs.fx", cachename), vertstring, strlen(vertstring));
1547                                         vsresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1548                                 }
1549                                 else
1550                                         vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1551                                 if (vsbuffer)
1552                                 {
1553                                         vsbinsize = ID3DXBuffer_GetBufferSize(vsbuffer);
1554                                         vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
1555                                         memcpy(vsbin, ID3DXBuffer_GetBufferPointer(vsbuffer), vsbinsize);
1556                                         ID3DXBuffer_Release(vsbuffer);
1557                                 }
1558                                 if (vslog)
1559                                 {
1560                                         strlcpy(temp, (const char *)ID3DXBuffer_GetBufferPointer(vslog), min(sizeof(temp), ID3DXBuffer_GetBufferSize(vslog)));
1561                                         Con_DPrintf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
1562                                         ID3DXBuffer_Release(vslog);
1563                                 }
1564                         }
1565                         if (fragstring && fragstring[0])
1566                         {
1567                                 if (debugshader)
1568                                 {
1569                                         FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_ps.fx", cachename), fragstring, strlen(fragstring));
1570                                         psresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1571                                 }
1572                                 else
1573                                         psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1574                                 if (psbuffer)
1575                                 {
1576                                         psbinsize = ID3DXBuffer_GetBufferSize(psbuffer);
1577                                         psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
1578                                         memcpy(psbin, ID3DXBuffer_GetBufferPointer(psbuffer), psbinsize);
1579                                         ID3DXBuffer_Release(psbuffer);
1580                                 }
1581                                 if (pslog)
1582                                 {
1583                                         strlcpy(temp, (const char *)ID3DXBuffer_GetBufferPointer(pslog), min(sizeof(temp), ID3DXBuffer_GetBufferSize(pslog)));
1584                                         Con_DPrintf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
1585                                         ID3DXBuffer_Release(pslog);
1586                                 }
1587                         }
1588                         Sys_UnloadLibrary(&d3dx9_dll);
1589                 }
1590                 else
1591                         Con_DPrintf("Unable to compile shader - D3DXCompileShader function not found\n");
1592         }
1593         if (vsbin && psbin)
1594         {
1595                 vsresult = IDirect3DDevice9_CreateVertexShader(vid_d3d9dev, vsbin, &p->vertexshader);
1596                 if (FAILED(vsresult))
1597                         Con_DPrintf("HLSL CreateVertexShader failed for %s (hresult = %8x)\n", cachename, vsresult);
1598                 psresult = IDirect3DDevice9_CreatePixelShader(vid_d3d9dev, psbin, &p->pixelshader);
1599                 if (FAILED(psresult))
1600                         Con_DPrintf("HLSL CreatePixelShader failed for %s (hresult = %8x)\n", cachename, psresult);
1601         }
1602         // free the shader data
1603         vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1604         psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1605 }
1606
1607 static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode, unsigned int permutation)
1608 {
1609         int i;
1610         shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
1611         int vertstring_length = 0;
1612         int geomstring_length = 0;
1613         int fragstring_length = 0;
1614         char *t;
1615         char *vertexstring, *geometrystring, *fragmentstring;
1616         char *vertstring, *geomstring, *fragstring;
1617         char permutationname[256];
1618         char cachename[256];
1619         int vertstrings_count = 0;
1620         int geomstrings_count = 0;
1621         int fragstrings_count = 0;
1622         const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1623         const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1624         const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1625
1626         if (p->compiled)
1627                 return;
1628         p->compiled = true;
1629         p->vertexshader = NULL;
1630         p->pixelshader = NULL;
1631
1632         permutationname[0] = 0;
1633         cachename[0] = 0;
1634         vertexstring   = R_HLSL_GetText(modeinfo->vertexfilename, true);
1635         geometrystring = R_HLSL_GetText(modeinfo->geometryfilename, false);
1636         fragmentstring = R_HLSL_GetText(modeinfo->fragmentfilename, false);
1637
1638         strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
1639         strlcat(cachename, "hlsl/", sizeof(cachename));
1640
1641         // define HLSL so that the shader can tell apart the HLSL compiler and the Cg compiler
1642         vertstrings_count = 0;
1643         geomstrings_count = 0;
1644         fragstrings_count = 0;
1645         vertstrings_list[vertstrings_count++] = "#define HLSL\n";
1646         geomstrings_list[geomstrings_count++] = "#define HLSL\n";
1647         fragstrings_list[fragstrings_count++] = "#define HLSL\n";
1648
1649         // the first pretext is which type of shader to compile as
1650         // (later these will all be bound together as a program object)
1651         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1652         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1653         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1654
1655         // the second pretext is the mode (for example a light source)
1656         vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1657         geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1658         fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1659         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1660         strlcat(cachename, modeinfo->name, sizeof(cachename));
1661
1662         // now add all the permutation pretexts
1663         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1664         {
1665                 if (permutation & (1<<i))
1666                 {
1667                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1668                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1669                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1670                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1671                         strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename));
1672                 }
1673                 else
1674                 {
1675                         // keep line numbers correct
1676                         vertstrings_list[vertstrings_count++] = "\n";
1677                         geomstrings_list[geomstrings_count++] = "\n";
1678                         fragstrings_list[fragstrings_count++] = "\n";
1679                 }
1680         }
1681
1682         // add static parms
1683         R_CompileShader_AddStaticParms(mode, permutation);
1684         memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1685         vertstrings_count += shaderstaticparms_count;
1686         memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1687         geomstrings_count += shaderstaticparms_count;
1688         memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1689         fragstrings_count += shaderstaticparms_count;
1690
1691         // replace spaces in the cachename with _ characters
1692         for (i = 0;cachename[i];i++)
1693                 if (cachename[i] == ' ')
1694                         cachename[i] = '_';
1695
1696         // now append the shader text itself
1697         vertstrings_list[vertstrings_count++] = vertexstring;
1698         geomstrings_list[geomstrings_count++] = geometrystring;
1699         fragstrings_list[fragstrings_count++] = fragmentstring;
1700
1701         // if any sources were NULL, clear the respective list
1702         if (!vertexstring)
1703                 vertstrings_count = 0;
1704         if (!geometrystring)
1705                 geomstrings_count = 0;
1706         if (!fragmentstring)
1707                 fragstrings_count = 0;
1708
1709         vertstring_length = 0;
1710         for (i = 0;i < vertstrings_count;i++)
1711                 vertstring_length += strlen(vertstrings_list[i]);
1712         vertstring = t = (char *)Mem_Alloc(tempmempool, vertstring_length + 1);
1713         for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
1714                 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
1715
1716         geomstring_length = 0;
1717         for (i = 0;i < geomstrings_count;i++)
1718                 geomstring_length += strlen(geomstrings_list[i]);
1719         geomstring = t = (char *)Mem_Alloc(tempmempool, geomstring_length + 1);
1720         for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
1721                 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
1722
1723         fragstring_length = 0;
1724         for (i = 0;i < fragstrings_count;i++)
1725                 fragstring_length += strlen(fragstrings_list[i]);
1726         fragstring = t = (char *)Mem_Alloc(tempmempool, fragstring_length + 1);
1727         for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
1728                 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
1729
1730         // try to load the cached shader, or generate one
1731         R_HLSL_CacheShader(p, cachename, vertstring, fragstring);
1732
1733         if ((p->vertexshader || !vertstring[0]) && (p->pixelshader || !fragstring[0]))
1734                 Con_DPrintf("^5HLSL shader %s compiled.\n", permutationname);
1735         else
1736                 Con_Printf("^1HLSL shader %s failed!  some features may not work properly.\n", permutationname);
1737
1738         // free the strings
1739         if (vertstring)
1740                 Mem_Free(vertstring);
1741         if (geomstring)
1742                 Mem_Free(geomstring);
1743         if (fragstring)
1744                 Mem_Free(fragstring);
1745         if (vertexstring)
1746                 Mem_Free(vertexstring);
1747         if (geometrystring)
1748                 Mem_Free(geometrystring);
1749         if (fragmentstring)
1750                 Mem_Free(fragmentstring);
1751 }
1752
1753 static inline void hlslVSSetParameter16f(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 4);}
1754 static inline void hlslVSSetParameter4fv(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 1);}
1755 static inline void hlslVSSetParameter4f(D3DVSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1756 static inline void hlslVSSetParameter3f(D3DVSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1757 static inline void hlslVSSetParameter2f(D3DVSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1758 static inline void hlslVSSetParameter1f(D3DVSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1759
1760 static inline void hlslPSSetParameter16f(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 4);}
1761 static inline void hlslPSSetParameter4fv(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 1);}
1762 static inline void hlslPSSetParameter4f(D3DPSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1763 static inline void hlslPSSetParameter3f(D3DPSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1764 static inline void hlslPSSetParameter2f(D3DPSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1765 static inline void hlslPSSetParameter1f(D3DPSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1766
1767 void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutation)
1768 {
1769         r_hlsl_permutation_t *perm = R_HLSL_FindPermutation(mode, permutation);
1770         if (r_hlsl_permutation != perm)
1771         {
1772                 r_hlsl_permutation = perm;
1773                 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1774                 {
1775                         if (!r_hlsl_permutation->compiled)
1776                                 R_HLSL_CompilePermutation(perm, mode, permutation);
1777                         if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1778                         {
1779                                 // remove features until we find a valid permutation
1780                                 int i;
1781                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1782                                 {
1783                                         // reduce i more quickly whenever it would not remove any bits
1784                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
1785                                         if (!(permutation & j))
1786                                                 continue;
1787                                         permutation -= j;
1788                                         r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1789                                         if (!r_hlsl_permutation->compiled)
1790                                                 R_HLSL_CompilePermutation(perm, mode, permutation);
1791                                         if (r_hlsl_permutation->vertexshader || r_hlsl_permutation->pixelshader)
1792                                                 break;
1793                                 }
1794                                 if (i >= SHADERPERMUTATION_COUNT)
1795                                 {
1796                                         //Con_Printf("Could not find a working HLSL shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
1797                                         r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1798                                         return; // no bit left to clear, entire mode is broken
1799                                 }
1800                         }
1801                 }
1802                 IDirect3DDevice9_SetVertexShader(vid_d3d9dev, r_hlsl_permutation->vertexshader);
1803                 IDirect3DDevice9_SetPixelShader(vid_d3d9dev, r_hlsl_permutation->pixelshader);
1804         }
1805         hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
1806         hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
1807         hlslPSSetParameter1f(D3DPSREGISTER_ClientTime, cl.time);
1808 }
1809 #endif
1810
1811 static void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
1812 {
1813         DPSOFTRAST_SetShader(mode, permutation, r_shadow_glossexact.integer);
1814         DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
1815         DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
1816         DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
1817 }
1818
1819 void R_GLSL_Restart_f(void)
1820 {
1821         unsigned int i, limit;
1822         if (glslshaderstring && glslshaderstring != builtinshaderstring)
1823                 Mem_Free(glslshaderstring);
1824         glslshaderstring = NULL;
1825         if (hlslshaderstring && hlslshaderstring != builtinhlslshaderstring)
1826                 Mem_Free(hlslshaderstring);
1827         hlslshaderstring = NULL;
1828         switch(vid.renderpath)
1829         {
1830         case RENDERPATH_D3D9:
1831 #ifdef SUPPORTD3D
1832                 {
1833                         r_hlsl_permutation_t *p;
1834                         r_hlsl_permutation = NULL;
1835                         limit = Mem_ExpandableArray_IndexRange(&r_hlsl_permutationarray);
1836                         for (i = 0;i < limit;i++)
1837                         {
1838                                 if ((p = (r_hlsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_hlsl_permutationarray, i)))
1839                                 {
1840                                         if (p->vertexshader)
1841                                                 IDirect3DVertexShader9_Release(p->vertexshader);
1842                                         if (p->pixelshader)
1843                                                 IDirect3DPixelShader9_Release(p->pixelshader);
1844                                         Mem_ExpandableArray_FreeRecord(&r_hlsl_permutationarray, (void*)p);
1845                                 }
1846                         }
1847                         memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
1848                 }
1849 #endif
1850                 break;
1851         case RENDERPATH_D3D10:
1852                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1853                 break;
1854         case RENDERPATH_D3D11:
1855                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1856                 break;
1857         case RENDERPATH_GL20:
1858         case RENDERPATH_GLES2:
1859                 {
1860                         r_glsl_permutation_t *p;
1861                         r_glsl_permutation = NULL;
1862                         limit = Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
1863                         for (i = 0;i < limit;i++)
1864                         {
1865                                 if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
1866                                 {
1867                                         GL_Backend_FreeProgram(p->program);
1868                                         Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
1869                                 }
1870                         }
1871                         memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
1872                 }
1873                 break;
1874         case RENDERPATH_GL11:
1875         case RENDERPATH_GL13:
1876         case RENDERPATH_GLES1:
1877                 break;
1878         case RENDERPATH_SOFT:
1879                 break;
1880         }
1881 }
1882
1883 static void R_GLSL_DumpShader_f(void)
1884 {
1885         int i;
1886         qfile_t *file;
1887
1888         file = FS_OpenRealFile("glsl/default.glsl", "w", false);
1889         if (file)
1890         {
1891                 FS_Print(file, "/* The engine may define the following macros:\n");
1892                 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
1893                 for (i = 0;i < SHADERMODE_COUNT;i++)
1894                         FS_Print(file, glslshadermodeinfo[i].pretext);
1895                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1896                         FS_Print(file, shaderpermutationinfo[i].pretext);
1897                 FS_Print(file, "*/\n");
1898                 FS_Print(file, builtinshaderstring);
1899                 FS_Close(file);
1900                 Con_Printf("glsl/default.glsl written\n");
1901         }
1902         else
1903                 Con_Printf("failed to write to glsl/default.glsl\n");
1904
1905         file = FS_OpenRealFile("hlsl/default.hlsl", "w", false);
1906         if (file)
1907         {
1908                 FS_Print(file, "/* The engine may define the following macros:\n");
1909                 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
1910                 for (i = 0;i < SHADERMODE_COUNT;i++)
1911                         FS_Print(file, hlslshadermodeinfo[i].pretext);
1912                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1913                         FS_Print(file, shaderpermutationinfo[i].pretext);
1914                 FS_Print(file, "*/\n");
1915                 FS_Print(file, builtinhlslshaderstring);
1916                 FS_Close(file);
1917                 Con_Printf("hlsl/default.hlsl written\n");
1918         }
1919         else
1920                 Con_Printf("failed to write to hlsl/default.hlsl\n");
1921 }
1922
1923 void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale, qboolean usegamma, qboolean notrippy, qboolean suppresstexalpha)
1924 {
1925         unsigned int permutation = 0;
1926         if (r_trippy.integer && !notrippy)
1927                 permutation |= SHADERPERMUTATION_TRIPPY;
1928         permutation |= SHADERPERMUTATION_VIEWTINT;
1929         if (first)
1930                 permutation |= SHADERPERMUTATION_DIFFUSE;
1931         if (second)
1932                 permutation |= SHADERPERMUTATION_SPECULAR;
1933         if (texturemode == GL_MODULATE)
1934                 permutation |= SHADERPERMUTATION_COLORMAPPING;
1935         else if (texturemode == GL_ADD)
1936                 permutation |= SHADERPERMUTATION_GLOW;
1937         else if (texturemode == GL_DECAL)
1938                 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
1939         if (usegamma && v_glslgamma.integer && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
1940                 permutation |= SHADERPERMUTATION_GAMMARAMPS;
1941         if (suppresstexalpha)
1942                 permutation |= SHADERPERMUTATION_REFLECTCUBE;
1943         if (!second)
1944                 texturemode = GL_MODULATE;
1945         if (vid.allowalphatocoverage)
1946                 GL_AlphaToCoverage(false);
1947         switch (vid.renderpath)
1948         {
1949         case RENDERPATH_D3D9:
1950 #ifdef SUPPORTD3D
1951                 R_SetupShader_SetPermutationHLSL(SHADERMODE_GENERIC, permutation);
1952                 R_Mesh_TexBind(GL20TU_FIRST , first );
1953                 R_Mesh_TexBind(GL20TU_SECOND, second);
1954                 if (permutation & SHADERPERMUTATION_GAMMARAMPS)
1955                         R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
1956 #endif
1957                 break;
1958         case RENDERPATH_D3D10:
1959                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1960                 break;
1961         case RENDERPATH_D3D11:
1962                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1963                 break;
1964         case RENDERPATH_GL20:
1965         case RENDERPATH_GLES2:
1966                 R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, permutation);
1967                 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , first );
1968                 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second);
1969                 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0)
1970                         R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
1971                 break;
1972         case RENDERPATH_GL13:
1973         case RENDERPATH_GLES1:
1974                 R_Mesh_TexBind(0, first );
1975                 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
1976                 R_Mesh_TexBind(1, second);
1977                 if (second)
1978                         R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
1979                 break;
1980         case RENDERPATH_GL11:
1981                 R_Mesh_TexBind(0, first );
1982                 break;
1983         case RENDERPATH_SOFT:
1984                 R_SetupShader_SetPermutationSoft(SHADERMODE_GENERIC, permutation);
1985                 R_Mesh_TexBind(GL20TU_FIRST , first );
1986                 R_Mesh_TexBind(GL20TU_SECOND, second);
1987                 break;
1988         }
1989 }
1990
1991 void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy)
1992 {
1993         R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, usegamma, notrippy, false);
1994 }
1995
1996 void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb)
1997 {
1998         unsigned int permutation = 0;
1999         if (r_trippy.integer && !notrippy)
2000                 permutation |= SHADERPERMUTATION_TRIPPY;
2001         if (depthrgb)
2002                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2003         if (vid.allowalphatocoverage)
2004                 GL_AlphaToCoverage(false);
2005         switch (vid.renderpath)
2006         {
2007         case RENDERPATH_D3D9:
2008 #ifdef SUPPORTD3D
2009                 R_SetupShader_SetPermutationHLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2010 #endif
2011                 break;
2012         case RENDERPATH_D3D10:
2013                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2014                 break;
2015         case RENDERPATH_D3D11:
2016                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2017                 break;
2018         case RENDERPATH_GL20:
2019         case RENDERPATH_GLES2:
2020                 R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2021                 break;
2022         case RENDERPATH_GL13:
2023         case RENDERPATH_GLES1:
2024                 R_Mesh_TexBind(0, 0);
2025                 R_Mesh_TexBind(1, 0);
2026                 break;
2027         case RENDERPATH_GL11:
2028                 R_Mesh_TexBind(0, 0);
2029                 break;
2030         case RENDERPATH_SOFT:
2031                 R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2032                 break;
2033         }
2034 }
2035
2036 void R_SetupShader_ShowDepth(qboolean notrippy)
2037 {
2038         int permutation = 0;
2039         if (r_trippy.integer && !notrippy)
2040                 permutation |= SHADERPERMUTATION_TRIPPY;
2041         if (vid.allowalphatocoverage)
2042                 GL_AlphaToCoverage(false);
2043         switch (vid.renderpath)
2044         {
2045         case RENDERPATH_D3D9:
2046 #ifdef SUPPORTHLSL
2047                 R_SetupShader_SetPermutationHLSL(SHADERMODE_SHOWDEPTH, permutation);
2048 #endif
2049                 break;
2050         case RENDERPATH_D3D10:
2051                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2052                 break;
2053         case RENDERPATH_D3D11:
2054                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2055                 break;
2056         case RENDERPATH_GL20:
2057         case RENDERPATH_GLES2:
2058                 R_SetupShader_SetPermutationGLSL(SHADERMODE_SHOWDEPTH, permutation);
2059                 break;
2060         case RENDERPATH_GL13:
2061         case RENDERPATH_GLES1:
2062                 break;
2063         case RENDERPATH_GL11:
2064                 break;
2065         case RENDERPATH_SOFT:
2066                 R_SetupShader_SetPermutationSoft(SHADERMODE_SHOWDEPTH, permutation);
2067                 break;
2068         }
2069 }
2070
2071 extern qboolean r_shadow_usingdeferredprepass;
2072 extern rtexture_t *r_shadow_attenuationgradienttexture;
2073 extern rtexture_t *r_shadow_attenuation2dtexture;
2074 extern rtexture_t *r_shadow_attenuation3dtexture;
2075 extern qboolean r_shadow_usingshadowmap2d;
2076 extern qboolean r_shadow_usingshadowmaportho;
2077 extern float r_shadow_shadowmap_texturescale[2];
2078 extern float r_shadow_shadowmap_parameters[4];
2079 extern qboolean r_shadow_shadowmapvsdct;
2080 extern rtexture_t *r_shadow_shadowmap2ddepthbuffer;
2081 extern rtexture_t *r_shadow_shadowmap2ddepthtexture;
2082 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
2083 extern matrix4x4_t r_shadow_shadowmapmatrix;
2084 extern int r_shadow_shadowmaplod; // changes for each light based on distance
2085 extern int r_shadow_prepass_width;
2086 extern int r_shadow_prepass_height;
2087 extern rtexture_t *r_shadow_prepassgeometrydepthbuffer;
2088 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
2089 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
2090 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
2091
2092 #define BLENDFUNC_ALLOWS_COLORMOD      1
2093 #define BLENDFUNC_ALLOWS_FOG           2
2094 #define BLENDFUNC_ALLOWS_FOG_HACK0     4
2095 #define BLENDFUNC_ALLOWS_FOG_HACKALPHA 8
2096 #define BLENDFUNC_ALLOWS_ANYFOG        (BLENDFUNC_ALLOWS_FOG | BLENDFUNC_ALLOWS_FOG_HACK0 | BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2097 static int R_BlendFuncFlags(int src, int dst)
2098 {
2099         int r = 0;
2100
2101         // a blendfunc allows colormod if:
2102         // a) it can never keep the destination pixel invariant, or
2103         // b) it can keep the destination pixel invariant, and still can do so if colormodded
2104         // this is to prevent unintended side effects from colormod
2105
2106         // a blendfunc allows fog if:
2107         // blend(fog(src), fog(dst)) == fog(blend(src, dst))
2108         // this is to prevent unintended side effects from fog
2109
2110         // these checks are the output of fogeval.pl
2111
2112         r |= BLENDFUNC_ALLOWS_COLORMOD;
2113         if(src == GL_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2114         if(src == GL_DST_ALPHA && dst == GL_ONE_MINUS_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2115         if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2116         if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2117         if(src == GL_DST_COLOR && dst == GL_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2118         if(src == GL_DST_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2119         if(src == GL_DST_COLOR && dst == GL_ZERO) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2120         if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2121         if(src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG_HACKALPHA;
2122         if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
2123         if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2124         if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2125         if(src == GL_ONE_MINUS_DST_COLOR && dst == GL_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2126         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2127         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2128         if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2129         if(src == GL_ONE_MINUS_SRC_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2130         if(src == GL_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2131         if(src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2132         if(src == GL_ZERO && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG;
2133         if(src == GL_ZERO && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2134
2135         return r;
2136 }
2137
2138 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)
2139 {
2140         // select a permutation of the lighting shader appropriate to this
2141         // combination of texture, entity, light source, and fogging, only use the
2142         // minimum features necessary to avoid wasting rendering time in the
2143         // fragment shader on features that are not being used
2144         unsigned int permutation = 0;
2145         unsigned int mode = 0;
2146         int blendfuncflags;
2147         static float dummy_colormod[3] = {1, 1, 1};
2148         float *colormod = rsurface.colormod;
2149         float m16f[16];
2150         matrix4x4_t tempmatrix;
2151         r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
2152         if (rsurface.entityskeletaltransform3x4)
2153                 permutation |= SHADERPERMUTATION_SKELETAL;
2154         if (r_trippy.integer && !notrippy)
2155                 permutation |= SHADERPERMUTATION_TRIPPY;
2156         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
2157                 permutation |= SHADERPERMUTATION_ALPHAKILL;
2158         if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
2159                 permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
2160         if (rsurfacepass == RSURFPASS_BACKGROUND)
2161         {
2162                 // distorted background
2163                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
2164                 {
2165                         mode = SHADERMODE_WATER;
2166                         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2167                                 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2168                         if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
2169                         {
2170                                 // this is the right thing to do for wateralpha
2171                                 GL_BlendFunc(GL_ONE, GL_ZERO);
2172                                 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2173                         }
2174                         else
2175                         {
2176                                 // this is the right thing to do for entity alpha
2177                                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2178                                 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2179                         }
2180                 }
2181                 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
2182                 {
2183                         mode = SHADERMODE_REFRACTION;
2184                         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2185                                 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2186                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2187                         blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2188                 }
2189                 else
2190                 {
2191                         mode = SHADERMODE_GENERIC;
2192                         permutation |= SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_ALPHAKILL;
2193                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2194                         blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2195                 }
2196                 if (vid.allowalphatocoverage)
2197                         GL_AlphaToCoverage(false);
2198         }
2199         else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
2200         {
2201                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2202                 {
2203                         switch(rsurface.texture->offsetmapping)
2204                         {
2205                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2206                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2207                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2208                         case OFFSETMAPPING_OFF: break;
2209                         }
2210                 }
2211                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2212                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2213                 // normalmap (deferred prepass), may use alpha test on diffuse
2214                 mode = SHADERMODE_DEFERREDGEOMETRY;
2215                 GL_BlendFunc(GL_ONE, GL_ZERO);
2216                 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2217                 if (vid.allowalphatocoverage)
2218                         GL_AlphaToCoverage(false);
2219         }
2220         else if (rsurfacepass == RSURFPASS_RTLIGHT)
2221         {
2222                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2223                 {
2224                         switch(rsurface.texture->offsetmapping)
2225                         {
2226                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2227                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2228                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2229                         case OFFSETMAPPING_OFF: break;
2230                         }
2231                 }
2232                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2233                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2234                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2235                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2236                 // light source
2237                 mode = SHADERMODE_LIGHTSOURCE;
2238                 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
2239                         permutation |= SHADERPERMUTATION_CUBEFILTER;
2240                 if (diffusescale > 0)
2241                         permutation |= SHADERPERMUTATION_DIFFUSE;
2242                 if (specularscale > 0)
2243                         permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2244                 if (r_refdef.fogenabled)
2245                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2246                 if (rsurface.texture->colormapping)
2247                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2248                 if (r_shadow_usingshadowmap2d)
2249                 {
2250                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2251                         if(r_shadow_shadowmapvsdct)
2252                                 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2253
2254                         if (r_shadow_shadowmap2ddepthbuffer)
2255                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2256                 }
2257                 if (rsurface.texture->reflectmasktexture)
2258                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2259                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2260                 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE);
2261                 if (vid.allowalphatocoverage)
2262                         GL_AlphaToCoverage(false);
2263         }
2264         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2265         {
2266                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2267                 {
2268                         switch(rsurface.texture->offsetmapping)
2269                         {
2270                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2271                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2272                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2273                         case OFFSETMAPPING_OFF: break;
2274                         }
2275                 }
2276                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2277                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2278                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2279                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2280                 // unshaded geometry (fullbright or ambient model lighting)
2281                 mode = SHADERMODE_FLATCOLOR;
2282                 ambientscale = diffusescale = specularscale = 0;
2283                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2284                         permutation |= SHADERPERMUTATION_GLOW;
2285                 if (r_refdef.fogenabled)
2286                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2287                 if (rsurface.texture->colormapping)
2288                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2289                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2290                 {
2291                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2292                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2293
2294                         if (r_shadow_shadowmap2ddepthbuffer)
2295                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2296                 }
2297                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2298                         permutation |= SHADERPERMUTATION_REFLECTION;
2299                 if (rsurface.texture->reflectmasktexture)
2300                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2301                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2302                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2303                 // when using alphatocoverage, we don't need alphakill
2304                 if (vid.allowalphatocoverage)
2305                 {
2306                         if (r_transparent_alphatocoverage.integer)
2307                         {
2308                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2309                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2310                         }
2311                         else
2312                                 GL_AlphaToCoverage(false);
2313                 }
2314         }
2315         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
2316         {
2317                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2318                 {
2319                         switch(rsurface.texture->offsetmapping)
2320                         {
2321                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2322                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2323                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2324                         case OFFSETMAPPING_OFF: break;
2325                         }
2326                 }
2327                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2328                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2329                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2330                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2331                 // directional model lighting
2332                 mode = SHADERMODE_LIGHTDIRECTION;
2333                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2334                         permutation |= SHADERPERMUTATION_GLOW;
2335                 permutation |= SHADERPERMUTATION_DIFFUSE;
2336                 if (specularscale > 0)
2337                         permutation |= SHADERPERMUTATION_SPECULAR;
2338                 if (r_refdef.fogenabled)
2339                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2340                 if (rsurface.texture->colormapping)
2341                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2342                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2343                 {
2344                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2345                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2346
2347                         if (r_shadow_shadowmap2ddepthbuffer)
2348                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2349                 }
2350                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2351                         permutation |= SHADERPERMUTATION_REFLECTION;
2352                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2353                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2354                 if (rsurface.texture->reflectmasktexture)
2355                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2356                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2357                 {
2358                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2359                         if (r_shadow_bouncegriddirectional)
2360                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2361                 }
2362                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2363                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2364                 // when using alphatocoverage, we don't need alphakill
2365                 if (vid.allowalphatocoverage)
2366                 {
2367                         if (r_transparent_alphatocoverage.integer)
2368                         {
2369                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2370                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2371                         }
2372                         else
2373                                 GL_AlphaToCoverage(false);
2374                 }
2375         }
2376         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
2377         {
2378                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2379                 {
2380                         switch(rsurface.texture->offsetmapping)
2381                         {
2382                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2383                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2384                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2385                         case OFFSETMAPPING_OFF: break;
2386                         }
2387                 }
2388                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2389                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2390                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2391                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2392                 // ambient model lighting
2393                 mode = SHADERMODE_LIGHTDIRECTION;
2394                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2395                         permutation |= SHADERPERMUTATION_GLOW;
2396                 if (r_refdef.fogenabled)
2397                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2398                 if (rsurface.texture->colormapping)
2399                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2400                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2401                 {
2402                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2403                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2404
2405                         if (r_shadow_shadowmap2ddepthbuffer)
2406                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2407                 }
2408                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2409                         permutation |= SHADERPERMUTATION_REFLECTION;
2410                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2411                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2412                 if (rsurface.texture->reflectmasktexture)
2413                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2414                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2415                 {
2416                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2417                         if (r_shadow_bouncegriddirectional)
2418                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2419                 }
2420                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2421                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2422                 // when using alphatocoverage, we don't need alphakill
2423                 if (vid.allowalphatocoverage)
2424                 {
2425                         if (r_transparent_alphatocoverage.integer)
2426                         {
2427                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2428                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2429                         }
2430                         else
2431                                 GL_AlphaToCoverage(false);
2432                 }
2433         }
2434         else
2435         {
2436                 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2437                 {
2438                         switch(rsurface.texture->offsetmapping)
2439                         {
2440                         case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2441                         case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2442                         case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2443                         case OFFSETMAPPING_OFF: break;
2444                         }
2445                 }
2446                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2447                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2448                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2449                         permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2450                 // lightmapped wall
2451                 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2452                         permutation |= SHADERPERMUTATION_GLOW;
2453                 if (r_refdef.fogenabled)
2454                         permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2455                 if (rsurface.texture->colormapping)
2456                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2457                 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2458                 {
2459                         permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2460                         permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2461
2462                         if (r_shadow_shadowmap2ddepthbuffer)
2463                                 permutation |= SHADERPERMUTATION_DEPTHRGB;
2464                 }
2465                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2466                         permutation |= SHADERPERMUTATION_REFLECTION;
2467                 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2468                         permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2469                 if (rsurface.texture->reflectmasktexture)
2470                         permutation |= SHADERPERMUTATION_REFLECTCUBE;
2471                 if (FAKELIGHT_ENABLED)
2472                 {
2473                         // fake lightmapping (q1bsp, q3bsp, fullbright map)
2474                         mode = SHADERMODE_FAKELIGHT;
2475                         permutation |= SHADERPERMUTATION_DIFFUSE;
2476                         if (specularscale > 0)
2477                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2478                 }
2479                 else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
2480                 {
2481                         // deluxemapping (light direction texture)
2482                         if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
2483                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
2484                         else
2485                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2486                         permutation |= SHADERPERMUTATION_DIFFUSE;
2487                         if (specularscale > 0)
2488                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2489                 }
2490                 else if (r_glsl_deluxemapping.integer >= 2)
2491                 {
2492                         // fake deluxemapping (uniform light direction in tangentspace)
2493                         if (rsurface.uselightmaptexture)
2494                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP;
2495                         else
2496                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR;
2497                         permutation |= SHADERPERMUTATION_DIFFUSE;
2498                         if (specularscale > 0)
2499                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2500                 }
2501                 else if (rsurface.uselightmaptexture)
2502                 {
2503                         // ordinary lightmapping (q1bsp, q3bsp)
2504                         mode = SHADERMODE_LIGHTMAP;
2505                 }
2506                 else
2507                 {
2508                         // ordinary vertex coloring (q3bsp)
2509                         mode = SHADERMODE_VERTEXCOLOR;
2510                 }
2511                 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2512                 {
2513                         permutation |= SHADERPERMUTATION_BOUNCEGRID;
2514                         if (r_shadow_bouncegriddirectional)
2515                                 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2516                 }
2517                 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2518                 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2519                 // when using alphatocoverage, we don't need alphakill
2520                 if (vid.allowalphatocoverage)
2521                 {
2522                         if (r_transparent_alphatocoverage.integer)
2523                         {
2524                                 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2525                                 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2526                         }
2527                         else
2528                                 GL_AlphaToCoverage(false);
2529                 }
2530         }
2531         if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD))
2532                 colormod = dummy_colormod;
2533         if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
2534                 permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
2535         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2536                 permutation |= SHADERPERMUTATION_FOGALPHAHACK;
2537         switch(vid.renderpath)
2538         {
2539         case RENDERPATH_D3D9:
2540 #ifdef SUPPORTD3D
2541                 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);
2542                 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
2543                 R_SetupShader_SetPermutationHLSL(mode, permutation);
2544                 Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);hlslPSSetParameter16f(D3DPSREGISTER_ModelToReflectCube, m16f);
2545                 if (mode == SHADERMODE_LIGHTSOURCE)
2546                 {
2547                         Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ModelToLight, m16f);
2548                         hlslVSSetParameter3f(D3DVSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2549                 }
2550                 else
2551                 {
2552                         if (mode == SHADERMODE_LIGHTDIRECTION)
2553                         {
2554                                 hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2555                         }
2556                 }
2557                 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
2558                 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
2559                 Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
2560                 hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2561                 hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2562
2563                 if (mode == SHADERMODE_LIGHTSOURCE)
2564                 {
2565                         hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2566                         hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2567                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2568                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2569                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2570
2571                         // additive passes are only darkened by fog, not tinted
2572                         hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2573                         hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2574                 }
2575                 else
2576                 {
2577                         if (mode == SHADERMODE_FLATCOLOR)
2578                         {
2579                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2580                         }
2581                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2582                         {
2583                                 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]);
2584                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2585                                 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);
2586                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2587                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2588                                 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
2589                                 hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2590                         }
2591                         else
2592                         {
2593                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2594                                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2595                                 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);
2596                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2597                                 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2598                         }
2599                         // additive passes are only darkened by fog, not tinted
2600                         if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2601                                 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2602                         else
2603                                 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2604                         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);
2605                         hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
2606                         hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
2607                         hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2608                         hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2609                         hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2610                         hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
2611                         hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
2612                         if (mode == SHADERMODE_WATER)
2613                                 hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2614                 }
2615                 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2616                 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
2617                 hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2618                 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));
2619                 hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2620                 if (rsurface.texture->pantstexture)
2621                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2622                 else
2623                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
2624                 if (rsurface.texture->shirttexture)
2625                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2626                 else
2627                         hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
2628                 hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2629                 hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist);
2630                 hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
2631                 hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
2632                 hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps,
2633                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2634                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2635                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2636                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2637                         );
2638                 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
2639                 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias);
2640                 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2641                 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
2642
2643                 R_Mesh_TexBind(GL20TU_NORMAL            , rsurface.texture->nmaptexture                       );
2644                 R_Mesh_TexBind(GL20TU_COLOR             , rsurface.texture->basetexture                       );
2645                 R_Mesh_TexBind(GL20TU_GLOSS             , rsurface.texture->glosstexture                      );
2646                 R_Mesh_TexBind(GL20TU_GLOW              , rsurface.texture->glowtexture                       );
2647                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL  , rsurface.texture->backgroundnmaptexture             );
2648                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR   , rsurface.texture->backgroundbasetexture             );
2649                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS   , rsurface.texture->backgroundglosstexture            );
2650                 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW    , rsurface.texture->backgroundglowtexture             );
2651                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS             , rsurface.texture->pantstexture                      );
2652                 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT             , rsurface.texture->shirttexture                      );
2653                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK       , rsurface.texture->reflectmasktexture                );
2654                 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE       , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2655                 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE  , r_texture_fogheighttexture                          );
2656                 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK           , r_texture_fogattenuation                            );
2657                 R_Mesh_TexBind(GL20TU_LIGHTMAP          , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2658                 R_Mesh_TexBind(GL20TU_DELUXEMAP         , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2659                 if (rsurface.rtlight                                  ) R_Mesh_TexBind(GL20TU_ATTENUATION       , r_shadow_attenuationgradienttexture                 );
2660                 if (rsurfacepass == RSURFPASS_BACKGROUND)
2661                 {
2662                         R_Mesh_TexBind(GL20TU_REFRACTION        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2663                         if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2664                         R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2665                 }
2666                 else
2667                 {
2668                         if (permutation & SHADERPERMUTATION_REFLECTION        ) R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2669                 }
2670 //              if (rsurfacepass == RSURFPASS_DEFERREDLIGHT           ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP   , r_shadow_prepassgeometrynormalmaptexture            );
2671                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE     , r_shadow_prepasslightingdiffusetexture              );
2672                 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP  ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR    , r_shadow_prepasslightingspeculartexture             );
2673                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2674                 {
2675                         R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
2676                         if (rsurface.rtlight)
2677                         {
2678                                 if (permutation & SHADERPERMUTATION_CUBEFILTER        ) R_Mesh_TexBind(GL20TU_CUBE              , rsurface.rtlight->currentcubemap                    );
2679                                 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT    ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION    , r_shadow_shadowmapvsdcttexture                      );
2680                         }
2681                 }
2682 #endif
2683                 break;
2684         case RENDERPATH_D3D10:
2685                 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2686                 break;
2687         case RENDERPATH_D3D11:
2688                 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2689                 break;
2690         case RENDERPATH_GL20:
2691         case RENDERPATH_GLES2:
2692                 if (!vid.useinterleavedarrays)
2693                 {
2694                         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);
2695                         R_Mesh_VertexPointer(     3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
2696                         R_Mesh_ColorPointer(      4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
2697                         R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
2698                         R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
2699                         R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
2700                         R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
2701                         R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
2702                         R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
2703                         R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE | 0x80000000, sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, rsurface.batchskeletalindex4ub_vertexbuffer, rsurface.batchskeletalindex4ub_bufferoffset);
2704                         R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, rsurface.batchskeletalweight4ub_vertexbuffer, rsurface.batchskeletalweight4ub_bufferoffset);
2705                 }
2706                 else
2707                 {
2708                         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);
2709                         R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
2710                 }
2711                 R_SetupShader_SetPermutationGLSL(mode, permutation);
2712                 if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
2713                 if (mode == SHADERMODE_LIGHTSOURCE)
2714                 {
2715                         if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
2716                         if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2717                         if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2718                         if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2719                         if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2720                         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);
2721         
2722                         // additive passes are only darkened by fog, not tinted
2723                         if (r_glsl_permutation->loc_FogColor >= 0)
2724                                 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2725                         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);
2726                 }
2727                 else
2728                 {
2729                         if (mode == SHADERMODE_FLATCOLOR)
2730                         {
2731                                 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2732                         }
2733                         else if (mode == SHADERMODE_LIGHTDIRECTION)
2734                         {
2735                                 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]);
2736                                 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]);
2737                                 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);
2738                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2739                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2740                                 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]);
2741                                 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]);
2742                         }
2743                         else
2744                         {
2745                                 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]);
2746                                 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]);
2747                                 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);
2748                                 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2749                                 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2750                         }
2751                         // additive passes are only darkened by fog, not tinted
2752                         if (r_glsl_permutation->loc_FogColor >= 0)
2753                         {
2754                                 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2755                                         qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2756                                 else
2757                                         qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2758                         }
2759                         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);
2760                         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]);
2761                         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]);
2762                         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]);
2763                         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]);
2764                         if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2765                         if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
2766                         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);
2767                         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]);
2768                 }
2769                 if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
2770                 if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
2771                 if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
2772                 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]);
2773                 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]);
2774
2775                 if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2776                 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));
2777                 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2778                 if (r_glsl_permutation->loc_Color_Pants >= 0)
2779                 {
2780                         if (rsurface.texture->pantstexture)
2781                                 qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2782                         else
2783                                 qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
2784                 }
2785                 if (r_glsl_permutation->loc_Color_Shirt >= 0)
2786                 {
2787                         if (rsurface.texture->shirttexture)
2788                                 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2789                         else
2790                                 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
2791                 }
2792                 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]);
2793                 if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1f(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
2794                 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
2795                 if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
2796                 if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps,
2797                                 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2798                                 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2799                                 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2800                                 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2801                         );
2802                 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);
2803                 if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias);
2804                 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]);
2805                 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
2806                 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);}
2807                 if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegridintensity*r_refdef.view.colorscale);
2808
2809                 if (r_glsl_permutation->tex_Texture_First           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First            , r_texture_white                                     );
2810                 if (r_glsl_permutation->tex_Texture_Second          >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second           , r_texture_white                                     );
2811                 if (r_glsl_permutation->tex_Texture_GammaRamps      >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps       , r_texture_gammaramps                                );
2812                 if (r_glsl_permutation->tex_Texture_Normal          >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal           , rsurface.texture->nmaptexture                       );
2813                 if (r_glsl_permutation->tex_Texture_Color           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color            , rsurface.texture->basetexture                       );
2814                 if (r_glsl_permutation->tex_Texture_Gloss           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss            , rsurface.texture->glosstexture                      );
2815                 if (r_glsl_permutation->tex_Texture_Glow            >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow             , rsurface.texture->glowtexture                       );
2816                 if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal  , rsurface.texture->backgroundnmaptexture             );
2817                 if (r_glsl_permutation->tex_Texture_SecondaryColor  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor   , rsurface.texture->backgroundbasetexture             );
2818                 if (r_glsl_permutation->tex_Texture_SecondaryGloss  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss   , rsurface.texture->backgroundglosstexture            );
2819                 if (r_glsl_permutation->tex_Texture_SecondaryGlow   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow    , rsurface.texture->backgroundglowtexture             );
2820                 if (r_glsl_permutation->tex_Texture_Pants           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants            , rsurface.texture->pantstexture                      );
2821                 if (r_glsl_permutation->tex_Texture_Shirt           >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt            , rsurface.texture->shirttexture                      );
2822                 if (r_glsl_permutation->tex_Texture_ReflectMask     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask      , rsurface.texture->reflectmasktexture                );
2823                 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);
2824                 if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture                          );
2825                 if (r_glsl_permutation->tex_Texture_FogMask         >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask          , r_texture_fogattenuation                            );
2826                 if (r_glsl_permutation->tex_Texture_Lightmap        >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap         , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2827                 if (r_glsl_permutation->tex_Texture_Deluxemap       >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Deluxemap        , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2828                 if (r_glsl_permutation->tex_Texture_Attenuation     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation      , r_shadow_attenuationgradienttexture                 );
2829                 if (rsurfacepass == RSURFPASS_BACKGROUND)
2830                 {
2831                         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);
2832                         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);
2833                         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);
2834                 }
2835                 else
2836                 {
2837                         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);
2838                 }
2839                 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap   , r_shadow_prepassgeometrynormalmaptexture            );
2840                 if (r_glsl_permutation->tex_Texture_ScreenDiffuse   >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse     , r_shadow_prepasslightingdiffusetexture              );
2841                 if (r_glsl_permutation->tex_Texture_ScreenSpecular  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular    , r_shadow_prepasslightingspeculartexture             );
2842                 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2843                 {
2844                         if (r_glsl_permutation->tex_Texture_ShadowMap2D     >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2ddepthtexture                           );
2845                         if (rsurface.rtlight)
2846                         {
2847                                 if (r_glsl_permutation->tex_Texture_Cube            >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube              , rsurface.rtlight->currentcubemap                    );
2848                                 if (r_glsl_permutation->tex_Texture_CubeProjection  >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection    , r_shadow_shadowmapvsdcttexture                      );
2849                         }