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