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