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