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