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