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