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