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