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