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