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