added indirection cube map for shadowmapping and revised filtering modes
[xonotic/darkplaces.git] / gl_rmain.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20 // r_main.c
21
22 #include "quakedef.h"
23 #include "cl_dyntexture.h"
24 #include "r_shadow.h"
25 #include "polygon.h"
26 #include "image.h"
27
28 mempool_t *r_main_mempool;
29 rtexturepool_t *r_main_texturepool;
30
31 static int r_frame = 0; ///< used only by R_GetCurrentTexture
32
33 //
34 // screen size info
35 //
36 r_refdef_t r_refdef;
37
38 cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "motionblur value scale - 0.5 recommended"};
39 cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "motionblur based on damage"};
40 cvar_t r_motionblur_vmin = {CVAR_SAVE, "r_motionblur_vmin", "300", "minimum influence from velocity"};
41 cvar_t r_motionblur_vmax = {CVAR_SAVE, "r_motionblur_vmax", "600", "maximum influence from velocity"};
42 cvar_t r_motionblur_bmin = {CVAR_SAVE, "r_motionblur_bmin", "0.5", "velocity at which there is no blur yet (may be negative to always have some blur)"};
43 cvar_t r_motionblur_vcoeff = {CVAR_SAVE, "r_motionblur_vcoeff", "0.05", "sliding average reaction time for velocity"};
44 cvar_t r_motionblur_maxblur = {CVAR_SAVE, "r_motionblur_maxblur", "0.88", "cap for motionblur alpha value"};
45 cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"};
46
47 cvar_t r_animcache = {CVAR_SAVE, "r_animcache", "1", "cache animation frames to save CPU usage, primarily optimizes shadows and reflections"};
48
49 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"};
50 cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"};
51 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
52 cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%,  10 = 100%)"};
53 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)"};
54 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
55 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
56 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"};
57 cvar_t r_showshadowvolumes = {0, "r_showshadowvolumes", "0", "shows areas shadowed by lights, useful for finding out why some areas of a map render slowly (bright blue = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
58 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
59 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"};
60 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"};
61 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"};
62 cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
63 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
64 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
65 cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
66 cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "number of samples to test for entity culling"};
67 cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
68 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
69 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
70 cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
71 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
72 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
73 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
74 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."};
75 cvar_t r_shadows_darken = {CVAR_SAVE, "r_shadows_darken", "0.5", "how much shadowed areas will be darkened"};
76 cvar_t r_shadows_throwdistance = {CVAR_SAVE, "r_shadows_throwdistance", "500", "how far to cast shadows from models"};
77 cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"};
78 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."};
79 cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
80 cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
81 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"};
82 cvar_t r_polygonoffset_submodel_offset = {0, "r_polygonoffset_submodel_offset", "2", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
83 cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
84 cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
85
86 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
87 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
88 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
89 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
90 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
91 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
92 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
93 cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"};
94
95 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of hardware texture units reported by driver (note: setting this to 1 turns off gl_combine)"};
96
97 cvar_t r_glsl = {CVAR_SAVE, "r_glsl", "1", "enables use of OpenGL 2.0 pixel shaders for lighting"};
98 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)"};
99 cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
100 cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
101 cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
102 cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
103 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)"};
104 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)"};
105 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)"};
106 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)"};
107 cvar_t r_glsl_usegeneric = {CVAR_SAVE, "r_glsl_usegeneric", "1", "use shaders for rendering simple geometry (rather than conventional fixed-function rendering for this purpose)"};
108
109 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)"};
110 cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
111 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"};
112 cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
113 cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
114
115 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1", "enables animation smoothing on sprites"};
116 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
117 cvar_t r_lerplightstyles = {CVAR_SAVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"};
118 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
119
120 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
121 cvar_t r_bloom_colorscale = {CVAR_SAVE, "r_bloom_colorscale", "1", "how bright the glow is"};
122 cvar_t r_bloom_brighten = {CVAR_SAVE, "r_bloom_brighten", "2", "how bright the glow is, after subtract/power"};
123 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
124 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
125 cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exagerated the glow is"};
126 cvar_t r_bloom_colorsubtract = {CVAR_SAVE, "r_bloom_colorsubtract", "0.125", "reduces bloom colors by a certain amount"};
127
128 cvar_t r_hdr = {CVAR_SAVE, "r_hdr", "0", "enables High Dynamic Range bloom effect (higher quality version of r_bloom)"};
129 cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
130 cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
131 cvar_t r_hdr_range = {CVAR_SAVE, "r_hdr_range", "4", "how much dynamic range to render bloom with (equivilant to multiplying r_bloom_brighten by this value and dividing r_bloom_colorscale by this value)"};
132
133 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"};
134
135 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"};
136
137 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
138
139 cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
140 cvar_t r_batchmode = {0, "r_batchmode", "1", "selects method of rendering multiple surfaces with one driver call (values are 0, 1, 2, etc...)"};
141 cvar_t r_track_sprites = {CVAR_SAVE, "r_track_sprites", "1", "track SPR_LABEL* sprites by putting them as indicator at the screen border to rotate to"};
142 cvar_t r_track_sprites_flags = {CVAR_SAVE, "r_track_sprites_flags", "1", "1: Rotate sprites accodringly, 2: Make it a continuous rotation"};
143 cvar_t r_track_sprites_scalew = {CVAR_SAVE, "r_track_sprites_scalew", "1", "width scaling of tracked sprites"};
144 cvar_t r_track_sprites_scaleh = {CVAR_SAVE, "r_track_sprites_scaleh", "1", "height scaling of tracked sprites"};
145 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
146
147 extern cvar_t v_glslgamma;
148
149 extern qboolean v_flipped_state;
150
151 static struct r_bloomstate_s
152 {
153         qboolean enabled;
154         qboolean hdr;
155
156         int bloomwidth, bloomheight;
157
158         int screentexturewidth, screentextureheight;
159         rtexture_t *texture_screen; /// \note also used for motion blur if enabled!
160
161         int bloomtexturewidth, bloomtextureheight;
162         rtexture_t *texture_bloom;
163
164         // arrays for rendering the screen passes
165         float screentexcoord2f[8];
166         float bloomtexcoord2f[8];
167         float offsettexcoord2f[8];
168
169         r_viewport_t viewport;
170 }
171 r_bloomstate;
172
173 r_waterstate_t r_waterstate;
174
175 /// shadow volume bsp struct with automatically growing nodes buffer
176 svbsp_t r_svbsp;
177
178 rtexture_t *r_texture_blanknormalmap;
179 rtexture_t *r_texture_white;
180 rtexture_t *r_texture_grey128;
181 rtexture_t *r_texture_black;
182 rtexture_t *r_texture_notexture;
183 rtexture_t *r_texture_whitecube;
184 rtexture_t *r_texture_normalizationcube;
185 rtexture_t *r_texture_fogattenuation;
186 rtexture_t *r_texture_gammaramps;
187 unsigned int r_texture_gammaramps_serial;
188 //rtexture_t *r_texture_fogintensity;
189
190 unsigned int r_queries[R_MAX_OCCLUSION_QUERIES];
191 unsigned int r_numqueries;
192 unsigned int r_maxqueries;
193
194 char r_qwskincache[MAX_SCOREBOARD][MAX_QPATH];
195 skinframe_t *r_qwskincache_skinframe[MAX_SCOREBOARD];
196
197 /// vertex coordinates for a quad that covers the screen exactly
198 const float r_screenvertex3f[12] =
199 {
200         0, 0, 0,
201         1, 0, 0,
202         1, 1, 0,
203         0, 1, 0
204 };
205
206 extern void R_DrawModelShadows(void);
207
208 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
209 {
210         int i;
211         for (i = 0;i < verts;i++)
212         {
213                 out[0] = in[0] * r;
214                 out[1] = in[1] * g;
215                 out[2] = in[2] * b;
216                 out[3] = in[3];
217                 in += 4;
218                 out += 4;
219         }
220 }
221
222 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
223 {
224         int i;
225         for (i = 0;i < verts;i++)
226         {
227                 out[0] = r;
228                 out[1] = g;
229                 out[2] = b;
230                 out[3] = a;
231                 out += 4;
232         }
233 }
234
235 // FIXME: move this to client?
236 void FOG_clear(void)
237 {
238         if (gamemode == GAME_NEHAHRA)
239         {
240                 Cvar_Set("gl_fogenable", "0");
241                 Cvar_Set("gl_fogdensity", "0.2");
242                 Cvar_Set("gl_fogred", "0.3");
243                 Cvar_Set("gl_foggreen", "0.3");
244                 Cvar_Set("gl_fogblue", "0.3");
245         }
246         r_refdef.fog_density = 0;
247         r_refdef.fog_red = 0;
248         r_refdef.fog_green = 0;
249         r_refdef.fog_blue = 0;
250         r_refdef.fog_alpha = 1;
251         r_refdef.fog_start = 0;
252         r_refdef.fog_end = 0;
253 }
254
255 float FogForDistance(vec_t dist)
256 {
257         unsigned int fogmasktableindex = (unsigned int)(dist * r_refdef.fogmasktabledistmultiplier);
258         return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
259 }
260
261 float FogPoint_World(const vec3_t p)
262 {
263         return FogForDistance(VectorDistance((p), r_refdef.view.origin));
264 }
265
266 float FogPoint_Model(const vec3_t p)
267 {
268         return FogForDistance(VectorDistance((p), rsurface.modelorg) * Matrix4x4_ScaleFromMatrix(&rsurface.matrix));
269 }
270
271 static void R_BuildBlankTextures(void)
272 {
273         unsigned char data[4];
274         data[2] = 128; // normal X
275         data[1] = 128; // normal Y
276         data[0] = 255; // normal Z
277         data[3] = 128; // height
278         r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_PERSISTENT, NULL);
279         data[0] = 255;
280         data[1] = 255;
281         data[2] = 255;
282         data[3] = 255;
283         r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_PERSISTENT, NULL);
284         data[0] = 128;
285         data[1] = 128;
286         data[2] = 128;
287         data[3] = 255;
288         r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_PERSISTENT, NULL);
289         data[0] = 0;
290         data[1] = 0;
291         data[2] = 0;
292         data[3] = 255;
293         r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_PERSISTENT, NULL);
294 }
295
296 static void R_BuildNoTexture(void)
297 {
298         int x, y;
299         unsigned char pix[16][16][4];
300         // this makes a light grey/dark grey checkerboard texture
301         for (y = 0;y < 16;y++)
302         {
303                 for (x = 0;x < 16;x++)
304                 {
305                         if ((y < 8) ^ (x < 8))
306                         {
307                                 pix[y][x][0] = 128;
308                                 pix[y][x][1] = 128;
309                                 pix[y][x][2] = 128;
310                                 pix[y][x][3] = 255;
311                         }
312                         else
313                         {
314                                 pix[y][x][0] = 64;
315                                 pix[y][x][1] = 64;
316                                 pix[y][x][2] = 64;
317                                 pix[y][x][3] = 255;
318                         }
319                 }
320         }
321         r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, NULL);
322 }
323
324 static void R_BuildWhiteCube(void)
325 {
326         unsigned char data[6*1*1*4];
327         memset(data, 255, sizeof(data));
328         r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
329 }
330
331 static void R_BuildNormalizationCube(void)
332 {
333         int x, y, side;
334         vec3_t v;
335         vec_t s, t, intensity;
336 #define NORMSIZE 64
337         unsigned char data[6][NORMSIZE][NORMSIZE][4];
338         for (side = 0;side < 6;side++)
339         {
340                 for (y = 0;y < NORMSIZE;y++)
341                 {
342                         for (x = 0;x < NORMSIZE;x++)
343                         {
344                                 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
345                                 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
346                                 switch(side)
347                                 {
348                                 default:
349                                 case 0:
350                                         v[0] = 1;
351                                         v[1] = -t;
352                                         v[2] = -s;
353                                         break;
354                                 case 1:
355                                         v[0] = -1;
356                                         v[1] = -t;
357                                         v[2] = s;
358                                         break;
359                                 case 2:
360                                         v[0] = s;
361                                         v[1] = 1;
362                                         v[2] = t;
363                                         break;
364                                 case 3:
365                                         v[0] = s;
366                                         v[1] = -1;
367                                         v[2] = -t;
368                                         break;
369                                 case 4:
370                                         v[0] = s;
371                                         v[1] = -t;
372                                         v[2] = 1;
373                                         break;
374                                 case 5:
375                                         v[0] = -s;
376                                         v[1] = -t;
377                                         v[2] = -1;
378                                         break;
379                                 }
380                                 intensity = 127.0f / sqrt(DotProduct(v, v));
381                                 data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[0]);
382                                 data[side][y][x][1] = (unsigned char)(128.0f + intensity * v[1]);
383                                 data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[2]);
384                                 data[side][y][x][3] = 255;
385                         }
386                 }
387         }
388         r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
389 }
390
391 static void R_BuildFogTexture(void)
392 {
393         int x, b;
394 #define FOGWIDTH 256
395         unsigned char data1[FOGWIDTH][4];
396         //unsigned char data2[FOGWIDTH][4];
397         double d, r, alpha;
398
399         r_refdef.fogmasktable_start = r_refdef.fog_start;
400         r_refdef.fogmasktable_alpha = r_refdef.fog_alpha;
401         r_refdef.fogmasktable_range = r_refdef.fogrange;
402         r_refdef.fogmasktable_density = r_refdef.fog_density;
403
404         r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH;
405         for (x = 0;x < FOGMASKTABLEWIDTH;x++)
406         {
407                 d = (x * r - r_refdef.fogmasktable_start);
408                 if(developer.integer >= 100)
409                         Con_Printf("%f ", d);
410                 d = max(0, d);
411                 if (r_fog_exp2.integer)
412                         alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d);
413                 else
414                         alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d);
415                 if(developer.integer >= 100)
416                         Con_Printf(" : %f ", alpha);
417                 alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha;
418                 if(developer.integer >= 100)
419                         Con_Printf(" = %f\n", alpha);
420                 r_refdef.fogmasktable[x] = bound(0, alpha, 1);
421         }
422
423         for (x = 0;x < FOGWIDTH;x++)
424         {
425                 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
426                 data1[x][0] = b;
427                 data1[x][1] = b;
428                 data1[x][2] = b;
429                 data1[x][3] = 255;
430                 //data2[x][0] = 255 - b;
431                 //data2[x][1] = 255 - b;
432                 //data2[x][2] = 255 - b;
433                 //data2[x][3] = 255;
434         }
435         if (r_texture_fogattenuation)
436         {
437                 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, FOGWIDTH, 1);
438                 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, FOGWIDTH, 1);
439         }
440         else
441         {
442                 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
443                 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
444         }
445 }
446
447 static const char *builtinshaderstring =
448 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
449 "// written by Forest 'LordHavoc' Hale\n"
450 "#ifdef USESHADOWMAPRECT\n"
451 "#extension GL_ARB_texture_rectangle : enable\n"
452 "# ifdef HASTEXTUREGATHER\n"
453 "#   extension GL_ARB_texture_gather : enable\n"
454 "# else\n"
455 "#   ifdef HASTEXTURE4\n"
456 "#     extension GL_AMD_texture_texture4 : enable\n"
457 "#     define textureGather texture4\n"
458 "#   endif\n"
459 "# endif\n"
460 "#endif\n"
461 "\n"
462 "// common definitions between vertex shader and fragment shader:\n"
463 "\n"
464 "//#ifdef __GLSL_CG_DATA_TYPES\n"
465 "//# define myhalf half\n"
466 "//# define myhalf2 half2\n"
467 "//# define myhalf3half3\n"
468 "//# define myhalf4 half4\n"
469 "//#else\n"
470 "# define myhalf float\n"
471 "# define myhalf2 vec2\n"
472 "# define myhalf3 vec3\n"
473 "# define myhalf4 vec4\n"
474 "//#endif\n"
475 "\n"
476 "#ifdef MODE_DEPTH_OR_SHADOW\n"
477 "\n"
478 "# ifdef VERTEX_SHADER\n"
479 "void main(void)\n"
480 "{\n"
481 "       gl_Position = ftransform();\n"
482 "}\n"
483 "# endif\n"
484 "\n"
485 "#else\n"
486 "#ifdef MODE_SHOWDEPTH\n"
487 "# ifdef VERTEX_SHADER\n"
488 "void main(void)\n"
489 "{\n"
490 "       gl_Position = ftransform();\n"
491 "       gl_FrontColor = vec4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
492 "}\n"
493 "# endif\n"
494 "# ifdef FRAGMENT_SHADER\n"
495 "void main(void)\n"
496 "{\n"
497 "       gl_FragColor = gl_Color;\n"
498 "}\n"
499 "# endif\n"
500 "\n"
501 "#else // !MODE_SHOWDEPTH\n"
502 "\n"
503 "#ifdef MODE_POSTPROCESS\n"
504 "# ifdef VERTEX_SHADER\n"
505 "void main(void)\n"
506 "{\n"
507 "       gl_FrontColor = gl_Color;\n"
508 "       gl_Position = ftransform();\n"
509 "       gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;\n"
510 "#ifdef USEBLOOM\n"
511 "       gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;\n"
512 "#endif\n"
513 "}\n"
514 "# endif\n"
515 "# ifdef FRAGMENT_SHADER\n"
516 "\n"
517 "uniform sampler2D Texture_First;\n"
518 "#ifdef USEBLOOM\n"
519 "uniform sampler2D Texture_Second;\n"
520 "#endif\n"
521 "#ifdef USEGAMMARAMPS\n"
522 "uniform sampler2D Texture_GammaRamps;\n"
523 "#endif\n"
524 "#ifdef USESATURATION\n"
525 "uniform float Saturation;\n"
526 "#endif\n"
527 "#ifdef USEVIEWTINT\n"
528 "uniform vec4 TintColor;\n"
529 "#endif\n"
530 "//uncomment these if you want to use them:\n"
531 "uniform vec4 UserVec1;\n"
532 "// uniform vec4 UserVec2;\n"
533 "// uniform vec4 UserVec3;\n"
534 "// uniform vec4 UserVec4;\n"
535 "// uniform float ClientTime;\n"
536 "uniform vec2 PixelSize;\n"
537 "void main(void)\n"
538 "{\n"
539 "       gl_FragColor = texture2D(Texture_First, gl_TexCoord[0].xy);\n"
540 "#ifdef USEBLOOM\n"
541 "       gl_FragColor += texture2D(Texture_Second, gl_TexCoord[1].xy);\n"
542 "#endif\n"
543 "#ifdef USEVIEWTINT\n"
544 "       gl_FragColor = mix(gl_FragColor, TintColor, TintColor.a);\n"
545 "#endif\n"
546 "\n"
547 "#ifdef USEPOSTPROCESSING\n"
548 "// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
549 "// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n"
550 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n"
551 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n"
552 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n"
553 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2( 0.707107,  0.707107)) * UserVec1.y;\n"
554 "       gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.453990,  0.891007)) * UserVec1.y;\n"
555 "       gl_FragColor /= (1 + 5 * UserVec1.y);\n"
556 "#endif\n"
557 "\n"
558 "#ifdef USESATURATION\n"
559 "       //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
560 "       myhalf y = dot(gl_FragColor.rgb, vec3(0.299, 0.587, 0.114));\n"
561 "       //gl_FragColor = vec3(y) + (gl_FragColor.rgb - vec3(y)) * Saturation;\n"
562 "       gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
563 "#endif\n"
564 "\n"
565 "#ifdef USEGAMMARAMPS\n"
566 "       gl_FragColor.r = texture2D(Texture_GammaRamps, vec2(gl_FragColor.r, 0)).r;\n"
567 "       gl_FragColor.g = texture2D(Texture_GammaRamps, vec2(gl_FragColor.g, 0)).g;\n"
568 "       gl_FragColor.b = texture2D(Texture_GammaRamps, vec2(gl_FragColor.b, 0)).b;\n"
569 "#endif\n"
570 "}\n"
571 "# endif\n"
572 "\n"
573 "\n"
574 "#else\n"
575 "#ifdef MODE_GENERIC\n"
576 "# ifdef VERTEX_SHADER\n"
577 "void main(void)\n"
578 "{\n"
579 "       gl_FrontColor = gl_Color;\n"
580 "#  ifdef USEDIFFUSE\n"
581 "       gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;\n"
582 "#  endif\n"
583 "#  ifdef USESPECULAR\n"
584 "       gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;\n"
585 "#  endif\n"
586 "       gl_Position = ftransform();\n"
587 "}\n"
588 "# endif\n"
589 "# ifdef FRAGMENT_SHADER\n"
590 "\n"
591 "#  ifdef USEDIFFUSE\n"
592 "uniform sampler2D Texture_First;\n"
593 "#  endif\n"
594 "#  ifdef USESPECULAR\n"
595 "uniform sampler2D Texture_Second;\n"
596 "#  endif\n"
597 "\n"
598 "void main(void)\n"
599 "{\n"
600 "       gl_FragColor = gl_Color;\n"
601 "#  ifdef USEDIFFUSE\n"
602 "       gl_FragColor *= texture2D(Texture_First, gl_TexCoord[0].xy);\n"
603 "#  endif\n"
604 "\n"
605 "#  ifdef USESPECULAR\n"
606 "       vec4 tex2 = texture2D(Texture_Second, gl_TexCoord[1].xy);\n"
607 "#  endif\n"
608 "#  ifdef USECOLORMAPPING\n"
609 "       gl_FragColor *= tex2;\n"
610 "#  endif\n"
611 "#  ifdef USEGLOW\n"
612 "       gl_FragColor += tex2;\n"
613 "#  endif\n"
614 "#  ifdef USEVERTEXTEXTUREBLEND\n"
615 "       gl_FragColor = mix(gl_FragColor, tex2, tex2.a);\n"
616 "#  endif\n"
617 "}\n"
618 "# endif\n"
619 "\n"
620 "#else // !MODE_GENERIC\n"
621 "\n"
622 "varying vec2 TexCoord;\n"
623 "#ifdef USEVERTEXTEXTUREBLEND\n"
624 "varying vec2 TexCoord2;\n"
625 "#endif\n"
626 "varying vec2 TexCoordLightmap;\n"
627 "\n"
628 "#ifdef MODE_LIGHTSOURCE\n"
629 "varying vec3 CubeVector;\n"
630 "#endif\n"
631 "\n"
632 "#ifdef MODE_LIGHTSOURCE\n"
633 "varying vec3 LightVector;\n"
634 "#endif\n"
635 "#ifdef MODE_LIGHTDIRECTION\n"
636 "varying vec3 LightVector;\n"
637 "#endif\n"
638 "\n"
639 "varying vec3 EyeVector;\n"
640 "#ifdef USEFOG\n"
641 "varying vec3 EyeVectorModelSpace;\n"
642 "#endif\n"
643 "\n"
644 "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
645 "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
646 "varying vec3 VectorR; // direction of R texcoord (surface normal)\n"
647 "\n"
648 "#ifdef MODE_WATER\n"
649 "varying vec4 ModelViewProjectionPosition;\n"
650 "#endif\n"
651 "#ifdef MODE_REFRACTION\n"
652 "varying vec4 ModelViewProjectionPosition;\n"
653 "#endif\n"
654 "#ifdef USEREFLECTION\n"
655 "varying vec4 ModelViewProjectionPosition;\n"
656 "#endif\n"
657 "\n"
658 "\n"
659 "\n"
660 "\n"
661 "\n"
662 "// vertex shader specific:\n"
663 "#ifdef VERTEX_SHADER\n"
664 "\n"
665 "uniform vec3 LightPosition;\n"
666 "uniform vec3 EyePosition;\n"
667 "uniform vec3 LightDir;\n"
668 "\n"
669 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
670 "\n"
671 "void main(void)\n"
672 "{\n"
673 "       gl_FrontColor = gl_Color;\n"
674 "       // copy the surface texcoord\n"
675 "       TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n"
676 "#ifdef USEVERTEXTEXTUREBLEND\n"
677 "       TexCoord2 = vec2(gl_TextureMatrix[1] * gl_MultiTexCoord0);\n"
678 "#endif\n"
679 "#ifndef MODE_LIGHTSOURCE\n"
680 "# ifndef MODE_LIGHTDIRECTION\n"
681 "       TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
682 "# endif\n"
683 "#endif\n"
684 "\n"
685 "#ifdef MODE_LIGHTSOURCE\n"
686 "       // transform vertex position into light attenuation/cubemap space\n"
687 "       // (-1 to +1 across the light box)\n"
688 "       CubeVector = vec3(gl_TextureMatrix[3] * gl_Vertex);\n"
689 "\n"
690 "       // transform unnormalized light direction into tangent space\n"
691 "       // (we use unnormalized to ensure that it interpolates correctly and then\n"
692 "       //  normalize it per pixel)\n"
693 "       vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
694 "       LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
695 "       LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
696 "       LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
697 "#endif\n"
698 "\n"
699 "#ifdef MODE_LIGHTDIRECTION\n"
700 "       LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
701 "       LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
702 "       LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
703 "#endif\n"
704 "\n"
705 "       // transform unnormalized eye direction into tangent space\n"
706 "#ifndef USEFOG\n"
707 "       vec3 EyeVectorModelSpace;\n"
708 "#endif\n"
709 "       EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
710 "       EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
711 "       EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
712 "       EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
713 "\n"
714 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
715 "       VectorS = gl_MultiTexCoord1.xyz;\n"
716 "       VectorT = gl_MultiTexCoord2.xyz;\n"
717 "       VectorR = gl_MultiTexCoord3.xyz;\n"
718 "#endif\n"
719 "\n"
720 "//#if defined(MODE_WATER) || defined(MODE_REFRACTION) || defined(USEREFLECTION)\n"
721 "//     ModelViewProjectionPosition = gl_Vertex * gl_ModelViewProjectionMatrix;\n"
722 "//     //ModelViewProjectionPosition_svector = (gl_Vertex + vec4(gl_MultiTexCoord1.xyz, 0)) * gl_ModelViewProjectionMatrix - ModelViewProjectionPosition;\n"
723 "//     //ModelViewProjectionPosition_tvector = (gl_Vertex + vec4(gl_MultiTexCoord2.xyz, 0)) * gl_ModelViewProjectionMatrix - ModelViewProjectionPosition;\n"
724 "//#endif\n"
725 "\n"
726 "// transform vertex to camera space, using ftransform to match non-VS\n"
727 "       // rendering\n"
728 "       gl_Position = ftransform();\n"
729 "\n"
730 "#ifdef MODE_WATER\n"
731 "       ModelViewProjectionPosition = gl_Position;\n"
732 "#endif\n"
733 "#ifdef MODE_REFRACTION\n"
734 "       ModelViewProjectionPosition = gl_Position;\n"
735 "#endif\n"
736 "#ifdef USEREFLECTION\n"
737 "       ModelViewProjectionPosition = gl_Position;\n"
738 "#endif\n"
739 "}\n"
740 "\n"
741 "#endif // VERTEX_SHADER\n"
742 "\n"
743 "\n"
744 "\n"
745 "\n"
746 "// fragment shader specific:\n"
747 "#ifdef FRAGMENT_SHADER\n"
748 "\n"
749 "// 13 textures, we can only use up to 16 on DX9-class hardware\n"
750 "uniform sampler2D Texture_Normal;\n"
751 "uniform sampler2D Texture_Color;\n"
752 "uniform sampler2D Texture_Gloss;\n"
753 "uniform sampler2D Texture_Glow;\n"
754 "uniform sampler2D Texture_SecondaryNormal;\n"
755 "uniform sampler2D Texture_SecondaryColor;\n"
756 "uniform sampler2D Texture_SecondaryGloss;\n"
757 "uniform sampler2D Texture_SecondaryGlow;\n"
758 "uniform sampler2D Texture_Pants;\n"
759 "uniform sampler2D Texture_Shirt;\n"
760 "uniform sampler2D Texture_FogMask;\n"
761 "uniform sampler2D Texture_Lightmap;\n"
762 "uniform sampler2D Texture_Deluxemap;\n"
763 "uniform sampler2D Texture_Refraction;\n"
764 "uniform sampler2D Texture_Reflection;\n"
765 "uniform sampler2D Texture_Attenuation;\n"
766 "uniform samplerCube Texture_Cube;\n"
767 "\n"
768 "#define showshadowmap 0\n"
769 "\n"
770 "#ifdef USESHADOWMAPRECT\n"
771 "# ifdef USESHADOWSAMPLER\n"
772 "uniform sampler2DRectShadow Texture_ShadowMapRect;\n"
773 "# else\n"
774 "uniform sampler2DRect Texture_ShadowMapRect;\n"
775 "# endif\n"
776 "\n"
777 "uniform samplerCube Texture_CubeProjection;\n"
778 "#endif\n"
779 "\n"
780 "uniform myhalf3 LightColor;\n"
781 "uniform myhalf3 AmbientColor;\n"
782 "uniform myhalf3 DiffuseColor;\n"
783 "uniform myhalf3 SpecularColor;\n"
784 "uniform myhalf3 Color_Pants;\n"
785 "uniform myhalf3 Color_Shirt;\n"
786 "uniform myhalf3 FogColor;\n"
787 "\n"
788 "uniform myhalf4 TintColor;\n"
789 "\n"
790 "\n"
791 "//#ifdef MODE_WATER\n"
792 "uniform vec4 DistortScaleRefractReflect;\n"
793 "uniform vec4 ScreenScaleRefractReflect;\n"
794 "uniform vec4 ScreenCenterRefractReflect;\n"
795 "uniform myhalf4 RefractColor;\n"
796 "uniform myhalf4 ReflectColor;\n"
797 "uniform myhalf ReflectFactor;\n"
798 "uniform myhalf ReflectOffset;\n"
799 "//#else\n"
800 "//# ifdef MODE_REFRACTION\n"
801 "//uniform vec4 DistortScaleRefractReflect;\n"
802 "//uniform vec4 ScreenScaleRefractReflect;\n"
803 "//uniform vec4 ScreenCenterRefractReflect;\n"
804 "//uniform myhalf4 RefractColor;\n"
805 "//#  ifdef USEREFLECTION\n"
806 "//uniform myhalf4 ReflectColor;\n"
807 "//#  endif\n"
808 "//# else\n"
809 "//#  ifdef USEREFLECTION\n"
810 "//uniform vec4 DistortScaleRefractReflect;\n"
811 "//uniform vec4 ScreenScaleRefractReflect;\n"
812 "//uniform vec4 ScreenCenterRefractReflect;\n"
813 "//uniform myhalf4 ReflectColor;\n"
814 "//#  endif\n"
815 "//# endif\n"
816 "//#endif\n"
817 "\n"
818 "uniform myhalf GlowScale;\n"
819 "uniform myhalf SceneBrightness;\n"
820 "\n"
821 "uniform float OffsetMapping_Scale;\n"
822 "uniform float OffsetMapping_Bias;\n"
823 "uniform float FogRangeRecip;\n"
824 "\n"
825 "uniform myhalf AmbientScale;\n"
826 "uniform myhalf DiffuseScale;\n"
827 "uniform myhalf SpecularScale;\n"
828 "uniform myhalf SpecularPower;\n"
829 "\n"
830 "#ifdef USEOFFSETMAPPING\n"
831 "vec2 OffsetMapping(vec2 TexCoord)\n"
832 "{\n"
833 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
834 "       // 14 sample relief mapping: linear search and then binary search\n"
835 "       // this basically steps forward a small amount repeatedly until it finds\n"
836 "       // itself inside solid, then jitters forward and back using decreasing\n"
837 "       // amounts to find the impact\n"
838 "       //vec3 OffsetVector = vec3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1), -1);\n"
839 "       //vec3 OffsetVector = vec3(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
840 "       vec3 OffsetVector = vec3(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
841 "       vec3 RT = vec3(TexCoord, 1);\n"
842 "       OffsetVector *= 0.1;\n"
843 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
844 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
845 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
846 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
847 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
848 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
849 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
850 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
851 "       RT += OffsetVector *  step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
852 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z)          - 0.5);\n"
853 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.5    - 0.25);\n"
854 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.25   - 0.125);\n"
855 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.125  - 0.0625);\n"
856 "       RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
857 "       return RT.xy;\n"
858 "#else\n"
859 "       // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
860 "       // this basically moves forward the full distance, and then backs up based\n"
861 "       // on height of samples\n"
862 "       //vec2 OffsetVector = vec2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1));\n"
863 "       //vec2 OffsetVector = vec2(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1));\n"
864 "       vec2 OffsetVector = vec2(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1));\n"
865 "       TexCoord += OffsetVector;\n"
866 "       OffsetVector *= 0.333;\n"
867 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
868 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
869 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
870 "       return TexCoord;\n"
871 "#endif\n"
872 "}\n"
873 "#endif // USEOFFSETMAPPING\n"
874 "\n"
875 "#ifdef USESHADOWMAPRECT \n"
876 "uniform vec4 ShadowMap_TextureScale;\n"
877 "#if 0\n"
878 "uniform vec4 ShadowMap_Parameters;\n"
879 "#endif\n"
880 "\n"
881 "vec3 GetShadowMapTC2D(vec3 dir)\n"
882 "{\n"
883 "       vec3 adir = abs(dir);\n"
884 "# if 0\n"
885 "       vec2 tc;\n"
886 "       vec2 offset;\n"
887 "       float ma;\n"
888 "       if (adir.x > adir.y)\n"
889 "       {\n"
890 "               if (adir.x > adir.z)\n"
891 "               {\n"
892 "                       ma = adir.x;\n"
893 "                       if (dir.x >= 0.0)\n"
894 "                       {\n"
895 "                               // +X\n"
896 "                               tc = vec2(-dir.z, -dir.y);\n"
897 "                               offset = vec2(0.5, 0.5);\n"
898 "                       }\n"
899 "                       else\n"
900 "                       {\n"
901 "                               // -X\n"
902 "                               tc = vec2( dir.z, -dir.y);\n"
903 "                               offset = vec2(1.5, 0.5);\n"
904 "                       }\n"
905 "               }\n"
906 "               else\n"
907 "               {\n"
908 "            ma = adir.z;\n"
909 "                       if (dir.z >= 0.0)\n"
910 "                       {\n"
911 "                               // +Z\n"
912 "                               tc = vec2( dir.x, -dir.y);\n"
913 "                               offset = vec2(0.5, 2.5);\n"
914 "                       }\n"
915 "                       else\n"
916 "                       {\n"
917 "                               // -Z\n"
918 "                               tc = vec2(-dir.x, -dir.y);\n"
919 "                               offset = vec2(1.5, 2.5);\n"
920 "                       }\n"
921 "               }\n"
922 "       }\n"
923 "       else\n"
924 "       {\n"
925 "               if (adir.y > adir.z)\n"
926 "               {\n"
927 "            ma = adir.y;\n"
928 "                       if (dir.y >= 0.0)\n"
929 "                       {\n"
930 "                               // +Y\n"
931 "                               tc = vec2( dir.x,  dir.z);\n"
932 "                               offset = vec2(0.5, 1.5);\n"
933 "                       }\n"
934 "                       else\n"
935 "                       {\n"
936 "                               // -Y\n"
937 "                               tc = vec2( dir.x, -dir.z);\n"
938 "                               offset = vec2(1.5, 1.5);\n"
939 "                       }\n"
940 "               }\n"
941 "               else\n"
942 "               {\n"
943 "            ma = adir.z;\n"
944 "                       if (dir.z >= 0.0)\n"
945 "                       {\n"
946 "                               // +Z\n"
947 "                               tc = vec2(dir.x, -dir.y);\n"
948 "                               offset = vec2(0.5, 2.5);\n"
949 "                       }\n"
950 "                       else\n"
951 "                       {\n"
952 "                               // -Z\n"
953 "                               tc = vec2(-dir.x, -dir.y);\n"
954 "                               offset = vec2(1.5, 2.5);\n"
955 "                       }\n"
956 "               }\n"
957 "       }\n"
958 "\n"
959 "       return vec3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma + vec3(offset * ShadowMap_Parameters.y, ShadowMap_Parameters.z);\n"
960 "# else\n"
961 "    return vec3(textureCube(Texture_CubeProjection, dir.xyz).ra * ShadowMap_TextureScale.xy, ShadowMap_TextureScale.z + ShadowMap_TextureScale.w / max(max(adir.x, adir.y), adir.z));\n"
962 "# endif\n"
963 "}\n"
964 "\n"
965 "#endif // USESHADOWMAPRECT\n"
966 "\n"
967 "#if !showshadowmap\n"
968 "# ifdef USESHADOWMAPRECT\n"
969 "float ShadowMapCompare(vec3 dir)\n"
970 "{\n"
971 "       vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
972 "       float f;\n"
973 "#  ifdef USESHADOWSAMPLER\n"
974 "\n"
975 "#    ifdef USESHADOWMAPPCF\n"
976 "       f = dot(vec4(0.25),\n"
977 "                       vec4(shadow2DRect(Texture_ShadowMapRect, shadowmaptc.xyz + vec3(-0.4,  1.0, 0.0)).r,\n"
978 "                                shadow2DRect(Texture_ShadowMapRect, shadowmaptc.xyz + vec3(-1.0, -0.4, 0.0)).r,\n"
979 "                                shadow2DRect(Texture_ShadowMapRect, shadowmaptc.xyz + vec3( 0.4, -1.0, 0.0)).r,\n"
980 "                                shadow2DRect(Texture_ShadowMapRect, shadowmaptc.xyz + vec3( 1.0,  0.4, 0.0)).r));\n"
981 "#    else\n"
982 "    f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
983 "#    endif\n"
984 "\n"
985 "#  else\n"
986 "\n"
987 "#    ifdef USESHADOWMAPPCF\n"
988 "#      if defined(HASTEXTUREGATHER) || defined(HASTEXTURE4)\n"
989 "    vec2 offset = fract(shadowmaptc.xy - 0.5);\n"
990 "    vec4 group1 = step(shadowmaptc.z, textureGather(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0, -1.0))),\n"
991 "         group2 = step(shadowmaptc.z, textureGather(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0, -1.0))),\n"
992 "         group3 = step(shadowmaptc.z, textureGather(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0,  1.0))),\n"
993 "         group4 = step(shadowmaptc.z, textureGather(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0,  1.0))),\n"
994 "         cols = vec4(group1.ab, group2.ab) + vec4(group3.rg, group4.rg) +\n"
995 "                mix(vec4(group1.rg, group2.rg), vec4(group3.ab, group4.ab), offset.y);\n"
996 "    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
997 "#      elif 1\n"
998 "    vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
999 "    vec4 row1 = step(shadowmaptc.z,\n"
1000 "                    vec4(texture2DRect(Texture_ShadowMapRect, center + vec2(-1.0, -1.0)).r,\n"
1001 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 0.0, -1.0)).r,\n"
1002 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 1.0, -1.0)).r,\n"
1003 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 2.0, -1.0)).r)),\n"
1004 "         row2 = step(shadowmaptc.z,\n"
1005 "                    vec4(texture2DRect(Texture_ShadowMapRect, center + vec2(-1.0,  0.0)).r,\n"
1006 "                         texture2DRect(Texture_ShadowMapRect, center).r,\n"
1007 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 1.0,  0.0)).r,\n"
1008 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 2.0,  0.0)).r)),\n"
1009 "         row3 = step(shadowmaptc.z,\n"
1010 "                    vec4(texture2DRect(Texture_ShadowMapRect, center + vec2(-1.0,  1.0)).r,\n"
1011 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 0.0,  1.0)).r,\n"
1012 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 1.0,  1.0)).r,\n"
1013 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 2.0,  1.0)).r)),\n"
1014 "         row4 = step(shadowmaptc.z,\n"
1015 "                    vec4(texture2DRect(Texture_ShadowMapRect, center + vec2(-1.0,  2.0)).r,\n"
1016 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 0.0,  2.0)).r,\n"
1017 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 1.0,  2.0)).r,\n"
1018 "                         texture2DRect(Texture_ShadowMapRect, center + vec2( 2.0,  2.0)).r)),\n"
1019 "         cols = row2 + row3 + mix(row1, row4, offset.y);\n"
1020 "    f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
1021 "#      else\n"
1022 "    vec2 offset = fract(shadowmaptc.xy);\n"
1023 "    vec3 row1 = step(shadowmaptc.z,\n"
1024 "                    vec3(texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0, -1.0)).r,\n"
1025 "                         texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 0.0, -1.0)).r,\n"
1026 "                         texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0, -1.0)).r)),\n"
1027 "         row2 = step(shadowmaptc.z,\n"
1028 "                    vec3(texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0,  0.0)).r,\n"
1029 "                         texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r,\n"
1030 "                         texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0,  0.0)).r)),\n"
1031 "         row3 = step(shadowmaptc.z,\n"
1032 "                    vec3(texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(-1.0,  1.0)).r,\n"
1033 "                         texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 0.0,  1.0)).r,\n"
1034 "                         texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2( 1.0,  1.0)).r)),\n"
1035 "         cols = row2 + mix(row1, row3, offset.y);\n"
1036 "    f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
1037 "#      endif\n"
1038 "#    else\n"
1039 "    f = step(shadowmaptc.z, texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
1040 "#    endif\n"
1041 "\n"
1042 "#  endif\n"
1043 "       return f;\n"
1044 "}\n"
1045 "# endif\n"
1046 "\n"
1047 "#endif\n"
1048 "\n"
1049 "\n"
1050 "#ifdef MODE_WATER\n"
1051 "\n"
1052 "// water pass\n"
1053 "void main(void)\n"
1054 "{\n"
1055 "#ifdef USEOFFSETMAPPING\n"
1056 "       // apply offsetmapping\n"
1057 "       vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
1058 "#define TexCoord TexCoordOffset\n"
1059 "#endif\n"
1060 "\n"
1061 "       vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
1062 "       //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
1063 "       vec4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
1064 "       vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xyxy * DistortScaleRefractReflect;\n"
1065 "       // FIXME temporary hack to detect the case that the reflection\n"
1066 "       // gets blackened at edges due to leaving the area that contains actual\n"
1067 "       // content.\n"
1068 "       // Remove this 'ack once we have a better way to stop this thing from\n"
1069 "       // 'appening.\n"
1070 "       float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.01, 0.01)).rgb) / 0.05);\n"
1071 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.01, -0.01)).rgb) / 0.05);\n"
1072 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
1073 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
1074 "       ScreenTexCoord.xy = mix(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
1075 "       f       = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.01, 0.01)).rgb) / 0.05);\n"
1076 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.01, -0.01)).rgb) / 0.05);\n"
1077 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
1078 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
1079 "       ScreenTexCoord.zw = mix(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
1080 "       float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
1081 "       gl_FragColor = mix(texture2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, texture2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
1082 "}\n"
1083 "\n"
1084 "#else // !MODE_WATER\n"
1085 "#ifdef MODE_REFRACTION\n"
1086 "\n"
1087 "// refraction pass\n"
1088 "void main(void)\n"
1089 "{\n"
1090 "#ifdef USEOFFSETMAPPING\n"
1091 "       // apply offsetmapping\n"
1092 "       vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
1093 "#define TexCoord TexCoordOffset\n"
1094 "#endif\n"
1095 "\n"
1096 "       vec2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
1097 "       //vec2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
1098 "       vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
1099 "       vec2 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
1100 "       // FIXME temporary hack to detect the case that the reflection\n"
1101 "       // gets blackened at edges due to leaving the area that contains actual\n"
1102 "       // content.\n"
1103 "       // Remove this 'ack once we have a better way to stop this thing from\n"
1104 "       // 'appening.\n"
1105 "       float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
1106 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
1107 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
1108 "       f      *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
1109 "       ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
1110 "       gl_FragColor = texture2D(Texture_Refraction, ScreenTexCoord) * RefractColor;\n"
1111 "}\n"
1112 "\n"
1113 "#else // !MODE_REFRACTION\n"
1114 "void main(void)\n"
1115 "{\n"
1116 "#ifdef USEOFFSETMAPPING\n"
1117 "       // apply offsetmapping\n"
1118 "       vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
1119 "#define TexCoord TexCoordOffset\n"
1120 "#endif\n"
1121 "\n"
1122 "       // combine the diffuse textures (base, pants, shirt)\n"
1123 "       myhalf4 color = myhalf4(texture2D(Texture_Color, TexCoord));\n"
1124 "#ifdef USECOLORMAPPING\n"
1125 "       color.rgb += myhalf3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhalf3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
1126 "#endif\n"
1127 "#ifdef USEVERTEXTEXTUREBLEND\n"
1128 "       myhalf terrainblend = clamp(myhalf(gl_Color.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n"
1129 "       //myhalf terrainblend = min(myhalf(gl_Color.a) * color.a * 2.0, myhalf(1.0));\n"
1130 "       //myhalf terrainblend = myhalf(gl_Color.a) * color.a > 0.5;\n"
1131 "       color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord2)), color.rgb, terrainblend);\n"
1132 "       color.a = 1.0;\n"
1133 "       //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n"
1134 "#endif\n"
1135 "\n"
1136 "#ifdef USEDIFFUSE\n"
1137 "       // get the surface normal and the gloss color\n"
1138 "# ifdef USEVERTEXTEXTUREBLEND\n"
1139 "       myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord2)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n"
1140 "#  ifdef USESPECULAR\n"
1141 "       myhalf3 glosscolor = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n"
1142 "#  endif\n"
1143 "# else\n"
1144 "       myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n"
1145 "#  ifdef USESPECULAR\n"
1146 "       myhalf3 glosscolor = myhalf3(texture2D(Texture_Gloss, TexCoord));\n"
1147 "#  endif\n"
1148 "# endif\n"
1149 "#endif\n"
1150 "\n"
1151 "\n"
1152 "\n"
1153 "#ifdef MODE_LIGHTSOURCE\n"
1154 "       // light source\n"
1155 "\n"
1156 "       // calculate surface normal, light normal, and specular normal\n"
1157 "       // compute color intensity for the two textures (colormap and glossmap)\n"
1158 "       // scale by light color and attenuation as efficiently as possible\n"
1159 "       // (do as much scalar math as possible rather than vector math)\n"
1160 "# ifdef USEDIFFUSE\n"
1161 "       // get the light normal\n"
1162 "       myhalf3 diffusenormal = myhalf3(normalize(LightVector));\n"
1163 "# endif\n"
1164 "# ifdef USESPECULAR\n"
1165 "#  ifndef USEEXACTSPECULARMATH\n"
1166 "       myhalf3 specularnormal = normalize(diffusenormal + myhalf3(normalize(EyeVector)));\n"
1167 "\n"
1168 "#  endif\n"
1169 "       // calculate directional shading\n"
1170 "#  ifdef USEEXACTSPECULARMATH\n"
1171 "       color.rgb = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower)) * glosscolor);\n"
1172 "#  else\n"
1173 "       color.rgb = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower)) * glosscolor);\n"
1174 "#  endif\n"
1175 "# else\n"
1176 "#  ifdef USEDIFFUSE\n"
1177 "       // calculate directional shading\n"
1178 "       color.rgb = color.rgb * (myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))));\n"
1179 "#  else\n"
1180 "       // calculate directionless shading\n"
1181 "       color.rgb = color.rgb * myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
1182 "#  endif\n"
1183 "# endif\n"
1184 "\n"
1185 "#ifdef USESHADOWMAPRECT\n"
1186 "#if !showshadowmap\n"
1187 "       color.rgb *= ShadowMapCompare(CubeVector);\n"
1188 "#endif\n"
1189 "#endif\n"
1190 "\n"
1191 "# ifdef USECUBEFILTER\n"
1192 "       // apply light cubemap filter\n"
1193 "       //color.rgb *= normalize(CubeVector) * 0.5 + 0.5;//vec3(textureCube(Texture_Cube, CubeVector));\n"
1194 "       color.rgb *= myhalf3(textureCube(Texture_Cube, CubeVector));\n"
1195 "# endif\n"
1196 "#endif // MODE_LIGHTSOURCE\n"
1197 "\n"
1198 "\n"
1199 "\n"
1200 "\n"
1201 "#ifdef MODE_LIGHTDIRECTION\n"
1202 "       // directional model lighting\n"
1203 "# ifdef USEDIFFUSE\n"
1204 "       // get the light normal\n"
1205 "       myhalf3 diffusenormal = myhalf3(normalize(LightVector));\n"
1206 "# endif\n"
1207 "# ifdef USESPECULAR\n"
1208 "       // calculate directional shading\n"
1209 "       color.rgb *= AmbientColor + DiffuseColor * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0));\n"
1210 "#  ifdef USEEXACTSPECULARMATH\n"
1211 "       color.rgb += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
1212 "#  else\n"
1213 "       myhalf3 specularnormal = normalize(diffusenormal + myhalf3(normalize(EyeVector)));\n"
1214 "       color.rgb += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
1215 "#  endif\n"
1216 "# else\n"
1217 "#  ifdef USEDIFFUSE\n"
1218 "\n"
1219 "       // calculate directional shading\n"
1220 "       color.rgb *= AmbientColor + DiffuseColor * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0));\n"
1221 "#  else\n"
1222 "       color.rgb *= AmbientColor;\n"
1223 "#  endif\n"
1224 "# endif\n"
1225 "#endif // MODE_LIGHTDIRECTION\n"
1226 "\n"
1227 "\n"
1228 "\n"
1229 "\n"
1230 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
1231 "       // deluxemap lightmapping using light vectors in modelspace (evil q3map2)\n"
1232 "\n"
1233 "       // get the light normal\n"
1234 "       myhalf3 diffusenormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
1235 "       myhalf3 diffusenormal;\n"
1236 "       diffusenormal.x = dot(diffusenormal_modelspace, myhalf3(VectorS));\n"
1237 "       diffusenormal.y = dot(diffusenormal_modelspace, myhalf3(VectorT));\n"
1238 "       diffusenormal.z = dot(diffusenormal_modelspace, myhalf3(VectorR));\n"
1239 "       // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
1240 "       // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
1241 "       // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
1242 "       // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
1243 "       // to map the luxels to coordinates on the draw surfaces), which also causes\n"
1244 "       // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
1245 "       // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
1246 "       // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
1247 "       // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
1248 "       myhalf3 tempcolor = color.rgb * (DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal) / max(0.25, diffusenormal.z)), 0.0)));\n"
1249 "               // 0.25 supports up to 75.5 degrees normal/deluxe angle\n"
1250 "# ifdef USESPECULAR\n"
1251 "#  ifdef USEEXACTSPECULARMATH\n"
1252 "       tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(reflect(normalize(diffusenormal), surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
1253 "#  else\n"
1254 "       myhalf3 specularnormal = myhalf3(normalize(diffusenormal + myhalf3(normalize(EyeVector))));\n"
1255 "       tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
1256 "#  endif\n"
1257 "# endif\n"
1258 "\n"
1259 "       // apply lightmap color\n"
1260 "       color.rgb = color.rgb * AmbientScale + tempcolor * myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
1261 "#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
1262 "\n"
1263 "\n"
1264 "\n"
1265 "\n"
1266 "#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
1267 "       // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
1268 "\n"
1269 "       // get the light normal\n"
1270 "       myhalf3 diffusenormal = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
1271 "       // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
1272 "       myhalf3 tempcolor = color.rgb * (DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal) / diffusenormal.z), 0.0)));\n"
1273 "# ifdef USESPECULAR\n"
1274 "#  ifdef USEEXACTSPECULARMATH\n"
1275 "       tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
1276 "#  else\n"
1277 "       myhalf3 specularnormal = myhalf3(normalize(diffusenormal + myhalf3(normalize(EyeVector))));\n"
1278 "       tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
1279 "#  endif\n"
1280 "# endif\n"
1281 "\n"
1282 "       // apply lightmap color\n"
1283 "       color.rgb = color.rgb * AmbientScale + tempcolor * myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
1284 "#endif // MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
1285 "\n"
1286 "\n"
1287 "\n"
1288 "\n"
1289 "#ifdef MODE_LIGHTMAP\n"
1290 "       // apply lightmap color\n"
1291 "       color.rgb = color.rgb * myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + color.rgb * AmbientScale;\n"
1292 "#endif // MODE_LIGHTMAP\n"
1293 "\n"
1294 "\n"
1295 "\n"
1296 "\n"
1297 "#ifdef MODE_VERTEXCOLOR\n"
1298 "       // apply lightmap color\n"
1299 "       color.rgb = color.rgb * myhalf3(gl_Color.rgb) * DiffuseScale + color.rgb * AmbientScale;\n"
1300 "#endif // MODE_VERTEXCOLOR\n"
1301 "\n"
1302 "\n"
1303 "\n"
1304 "\n"
1305 "#ifdef MODE_FLATCOLOR\n"
1306 "#endif // MODE_FLATCOLOR\n"
1307 "\n"
1308 "\n"
1309 "\n"
1310 "\n"
1311 "\n"
1312 "\n"
1313 "\n"
1314 "       color *= TintColor;\n"
1315 "\n"
1316 "#ifdef USEGLOW\n"
1317 "#ifdef USEVERTEXTEXTUREBLEND\n"
1318 "       color.rgb += mix(myhalf3(texture2D(Texture_SecondaryGlow, TexCoord2)), myhalf3(texture2D(Texture_Glow, TexCoord)), terrainblend);\n"
1319 "#else\n"
1320 "       color.rgb += myhalf3(texture2D(Texture_Glow, TexCoord)) * GlowScale;\n"
1321 "#endif\n"
1322 "#endif\n"
1323 "\n"
1324 "       color.rgb *= SceneBrightness;\n"
1325 "\n"
1326 "       // apply fog after Contrastboost/SceneBrightness because its color is already modified appropriately\n"
1327 "#ifdef USEFOG\n"
1328 "       color.rgb = mix(FogColor, color.rgb, myhalf(texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0))));\n"
1329 "#endif\n"
1330 "\n"
1331 "       // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
1332 "#ifdef USEREFLECTION\n"
1333 "       vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
1334 "       //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
1335 "       vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
1336 "       vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xy * DistortScaleRefractReflect.zw;\n"
1337 "       // FIXME temporary hack to detect the case that the reflection\n"
1338 "       // gets blackened at edges due to leaving the area that contains actual\n"
1339 "       // content.\n"
1340 "       // Remove this 'ack once we have a better way to stop this thing from\n"
1341 "       // 'appening.\n"
1342 "       float f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
1343 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
1344 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
1345 "       f      *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
1346 "       ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
1347 "       color.rgb = mix(color.rgb, myhalf3(texture2D(Texture_Reflection, ScreenTexCoord)) * ReflectColor.rgb, ReflectColor.a);\n"
1348 "#endif\n"
1349 "\n"
1350 "       gl_FragColor = vec4(color);\n"
1351 "\n"
1352 "#if showshadowmap\n"
1353 "# ifdef USESHADOWMAPRECT\n"
1354 "#  ifdef USESHADOWSAMPLER\n"
1355 "       gl_FragColor = shadow2DRect(Texture_ShadowMapRect, GetShadowMapTC2D(CubeVector).xyz);\n"
1356 "#  else\n"
1357 "       gl_FragColor = texture2DRect(Texture_ShadowMapRect, GetShadowMapTC2D(CubeVector).xy);\n"
1358 "#  endif\n"
1359 "# endif\n"
1360 "#endif\n"
1361 "}\n"
1362 "#endif // !MODE_REFRACTION\n"
1363 "#endif // !MODE_WATER\n"
1364 "\n"
1365 "#endif // FRAGMENT_SHADER\n"
1366 "\n"
1367 "#endif // !MODE_GENERIC\n"
1368 "#endif // !MODE_POSTPROCESS\n"
1369 "#endif // !MODE_SHOWDEPTH\n"
1370 "#endif // !MODE_DEPTH_OR_SHADOW\n"
1371 ;
1372
1373 typedef struct shaderpermutationinfo_s
1374 {
1375         const char *pretext;
1376         const char *name;
1377 }
1378 shaderpermutationinfo_t;
1379
1380 typedef struct shadermodeinfo_s
1381 {
1382         const char *vertexfilename;
1383         const char *geometryfilename;
1384         const char *fragmentfilename;
1385         const char *pretext;
1386         const char *name;
1387 }
1388 shadermodeinfo_t;
1389
1390 typedef enum shaderpermutation_e
1391 {
1392         SHADERPERMUTATION_DIFFUSE = 1<<0, ///< (lightsource) whether to use directional shading
1393         SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<1, ///< indicates this is a two-layer material blend based on vertex alpha (q3bsp)
1394         SHADERPERMUTATION_VIEWTINT = 1<<1, ///< view tint (postprocessing only)
1395         SHADERPERMUTATION_COLORMAPPING = 1<<2, ///< indicates this is a colormapped skin
1396         SHADERPERMUTATION_SATURATION = 1<<2, ///< saturation (postprocessing only)
1397         SHADERPERMUTATION_FOG = 1<<3, ///< tint the color by fog color or black if using additive blend mode
1398         SHADERPERMUTATION_GAMMARAMPS = 1<<3, ///< gamma (postprocessing only)
1399         SHADERPERMUTATION_CUBEFILTER = 1<<4, ///< (lightsource) use cubemap light filter
1400         SHADERPERMUTATION_GLOW = 1<<5, ///< (lightmap) blend in an additive glow texture
1401         SHADERPERMUTATION_BLOOM = 1<<5, ///< bloom (postprocessing only)
1402         SHADERPERMUTATION_SPECULAR = 1<<6, ///< (lightsource or deluxemapping) render specular effects
1403         SHADERPERMUTATION_POSTPROCESSING = 1<<6, ///< user defined postprocessing (postprocessing only)
1404         SHADERPERMUTATION_EXACTSPECULARMATH = 1<<7, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
1405         SHADERPERMUTATION_REFLECTION = 1<<8, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
1406         SHADERPERMUTATION_OFFSETMAPPING = 1<<9, ///< adjust texcoords to roughly simulate a displacement mapped surface
1407         SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<10, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
1408         SHADERPERMUTATION_SHADOWMAPRECT = 1<<11, ///< (lightsource) use shadowmap rectangle texture as light filter
1409         SHADERPERMUTATION_SHADOWMAPPCF = 1<<12, //< (lightsource) use percentage closer filtering on shadowmap test results
1410         SHADERPERMUTATION_SHADOWSAMPLER = 1<<13, //< (lightsource) use hardware shadowmap test
1411         SHADERPERMUTATION_LIMIT = 1<<14, ///< size of permutations array
1412         SHADERPERMUTATION_COUNT = 14 ///< size of shaderpermutationinfo array
1413 }
1414 shaderpermutation_t;
1415
1416 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
1417 shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
1418 {
1419         {"#define USEDIFFUSE\n", " diffuse"},
1420         {"#define USEVERTEXTEXTUREBLEND\n#define USEVIEWTINT\n", " vertextextureblend/tint"},
1421         {"#define USECOLORMAPPING\n#define USESATURATION\n", " colormapping/saturation"},
1422         {"#define USEFOG\n#define USEGAMMARAMPS\n", " fog/gammaramps"},
1423         {"#define USECUBEFILTER\n", " cubefilter"},
1424         {"#define USEGLOW\n#define USEBLOOM\n", " glow/bloom"},
1425         {"#define USESPECULAR\n#define USEPOSTPROCESSING", " specular/postprocessing"},
1426         {"#define USEEXACTSPECULARMATH\n", " exactspecularmath"},
1427         {"#define USEREFLECTION\n", " reflection"},
1428         {"#define USEOFFSETMAPPING\n", " offsetmapping"},
1429         {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
1430         {"#define USESHADOWMAPRECT\n", " shadowmaprect"},
1431         {"#define USESHADOWMAPPCF\n", " shadowmappcf"},
1432         {"#define USESHADOWSAMPLER\n", " shadowsampler"},
1433 };
1434
1435 /// this enum is multiplied by SHADERPERMUTATION_MODEBASE
1436 typedef enum shadermode_e
1437 {
1438         SHADERMODE_GENERIC, ///< (particles/HUD/etc) vertex color, optionally multiplied by one texture
1439         SHADERMODE_POSTPROCESS, ///< postprocessing shader (r_glsl_postprocess)
1440         SHADERMODE_DEPTH_OR_SHADOW, ///< (depthfirst/shadows) vertex shader only
1441         SHADERMODE_FLATCOLOR, ///< (lightmap) modulate texture by uniform color (q1bsp, q3bsp)
1442         SHADERMODE_VERTEXCOLOR, ///< (lightmap) modulate texture by vertex colors (q3bsp)
1443         SHADERMODE_LIGHTMAP, ///< (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp)
1444         SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, ///< (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap)
1445         SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, ///< (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap)
1446         SHADERMODE_LIGHTDIRECTION, ///< (lightmap) use directional pixel shading from fixed light direction (q3bsp)
1447         SHADERMODE_LIGHTSOURCE, ///< (lightsource) use directional pixel shading from light source (rtlight)
1448         SHADERMODE_REFRACTION, ///< refract background (the material is rendered normally after this pass)
1449         SHADERMODE_WATER, ///< refract background and reflection (the material is rendered normally after this pass)
1450         SHADERMODE_SHOWDEPTH, ///< (debugging) renders depth as color
1451         SHADERMODE_COUNT
1452 }
1453 shadermode_t;
1454
1455 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
1456 shadermodeinfo_t shadermodeinfo[SHADERMODE_COUNT] =
1457 {
1458         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
1459         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
1460         {"glsl/default.glsl", NULL, NULL               , "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
1461         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
1462         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
1463         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
1464         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
1465         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
1466         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
1467         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
1468         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
1469         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_WATER\n", " water"},
1470         {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
1471 };
1472
1473 typedef struct r_glsl_permutation_s
1474 {
1475         /// indicates if we have tried compiling this permutation already
1476         qboolean compiled;
1477         /// 0 if compilation failed
1478         int program;
1479         /// locations of detected uniforms in program object, or -1 if not found
1480         int loc_Texture_First;
1481         int loc_Texture_Second;
1482         int loc_Texture_GammaRamps;
1483         int loc_Texture_Normal;
1484         int loc_Texture_Color;
1485         int loc_Texture_Gloss;
1486         int loc_Texture_Glow;
1487         int loc_Texture_SecondaryNormal;
1488         int loc_Texture_SecondaryColor;
1489         int loc_Texture_SecondaryGloss;
1490         int loc_Texture_SecondaryGlow;
1491         int loc_Texture_Pants;
1492         int loc_Texture_Shirt;
1493         int loc_Texture_FogMask;
1494         int loc_Texture_Lightmap;
1495         int loc_Texture_Deluxemap;
1496         int loc_Texture_Attenuation;
1497         int loc_Texture_Cube;
1498         int loc_Texture_Refraction;
1499         int loc_Texture_Reflection;
1500         int loc_Texture_ShadowMapRect;
1501         int loc_Texture_CubeProjection;
1502         int loc_FogColor;
1503         int loc_LightPosition;
1504         int loc_EyePosition;
1505         int loc_Color_Pants;
1506         int loc_Color_Shirt;
1507         int loc_FogRangeRecip;
1508         int loc_AmbientScale;
1509         int loc_DiffuseScale;
1510         int loc_SpecularScale;
1511         int loc_SpecularPower;
1512         int loc_GlowScale;
1513         int loc_SceneBrightness; // or: Scenebrightness * ContrastBoost
1514         int loc_OffsetMapping_Scale;
1515         int loc_TintColor;
1516         int loc_AmbientColor;
1517         int loc_DiffuseColor;
1518         int loc_SpecularColor;
1519         int loc_LightDir;
1520         int loc_ContrastBoostCoeff; ///< 1 - 1/ContrastBoost
1521         int loc_GammaCoeff; ///< 1 / gamma
1522         int loc_DistortScaleRefractReflect;
1523         int loc_ScreenScaleRefractReflect;
1524         int loc_ScreenCenterRefractReflect;
1525         int loc_RefractColor;
1526         int loc_ReflectColor;
1527         int loc_ReflectFactor;
1528         int loc_ReflectOffset;
1529         int loc_UserVec1;
1530         int loc_UserVec2;
1531         int loc_UserVec3;
1532         int loc_UserVec4;
1533         int loc_ClientTime;
1534         int loc_PixelSize;
1535         int loc_Saturation;
1536         int loc_ShadowMap_TextureScale;
1537         int loc_ShadowMap_Parameters;
1538 }
1539 r_glsl_permutation_t;
1540
1541 /// information about each possible shader permutation
1542 r_glsl_permutation_t r_glsl_permutations[SHADERMODE_COUNT][SHADERPERMUTATION_LIMIT];
1543 /// currently selected permutation
1544 r_glsl_permutation_t *r_glsl_permutation;
1545
1546 static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice)
1547 {
1548         char *shaderstring;
1549         if (!filename || !filename[0])
1550                 return NULL;
1551         shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1552         if (shaderstring)
1553         {
1554                 if (printfromdisknotice)
1555                         Con_DPrint("from disk... ");
1556                 return shaderstring;
1557         }
1558         else if (!strcmp(filename, "glsl/default.glsl"))
1559         {
1560                 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(builtinshaderstring) + 1);
1561                 memcpy(shaderstring, builtinshaderstring, strlen(builtinshaderstring) + 1);
1562         }
1563         return shaderstring;
1564 }
1565
1566 static void R_GLSL_CompilePermutation(unsigned int mode, unsigned int permutation)
1567 {
1568         int i;
1569         shadermodeinfo_t *modeinfo = shadermodeinfo + mode;
1570         r_glsl_permutation_t *p = &r_glsl_permutations[mode][permutation];
1571         int vertstrings_count = 0;
1572         int geomstrings_count = 0;
1573         int fragstrings_count = 0;
1574         char *vertexstring, *geometrystring, *fragmentstring;
1575         const char *vertstrings_list[32+3];
1576         const char *geomstrings_list[32+3];
1577         const char *fragstrings_list[32+3];
1578         char permutationname[256];
1579
1580         if (p->compiled)
1581                 return;
1582         p->compiled = true;
1583         p->program = 0;
1584
1585         permutationname[0] = 0;
1586         vertexstring   = R_GLSL_GetText(modeinfo->vertexfilename, true);
1587         geometrystring = R_GLSL_GetText(modeinfo->geometryfilename, false);
1588         fragmentstring = R_GLSL_GetText(modeinfo->fragmentfilename, false);
1589
1590         strlcat(permutationname, shadermodeinfo[mode].vertexfilename, sizeof(permutationname));
1591
1592         // the first pretext is which type of shader to compile as
1593         // (later these will all be bound together as a program object)
1594         vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1595         geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1596         fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1597
1598         // the second pretext is the mode (for example a light source)
1599         vertstrings_list[vertstrings_count++] = shadermodeinfo[mode].pretext;
1600         geomstrings_list[geomstrings_count++] = shadermodeinfo[mode].pretext;
1601         fragstrings_list[fragstrings_count++] = shadermodeinfo[mode].pretext;
1602         strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1603
1604         // now add all the permutation pretexts
1605         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1606         {
1607                 if (permutation & (1<<i))
1608                 {
1609                         vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1610                         geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1611                         fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1612                         strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1613                 }
1614                 else
1615                 {
1616                         // keep line numbers correct
1617                         vertstrings_list[vertstrings_count++] = "\n";
1618                         geomstrings_list[geomstrings_count++] = "\n";
1619                         fragstrings_list[fragstrings_count++] = "\n";
1620                 }
1621         }
1622
1623         // now append the shader text itself
1624         vertstrings_list[vertstrings_count++] = vertexstring;
1625         geomstrings_list[geomstrings_count++] = geometrystring;
1626         fragstrings_list[fragstrings_count++] = fragmentstring;
1627
1628         // if any sources were NULL, clear the respective list
1629         if (!vertexstring)
1630                 vertstrings_count = 0;
1631         if (!geometrystring)
1632                 geomstrings_count = 0;
1633         if (!fragmentstring)
1634                 fragstrings_count = 0;
1635
1636         // compile the shader program
1637         if (vertstrings_count + geomstrings_count + fragstrings_count)
1638                 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
1639         if (p->program)
1640         {
1641                 CHECKGLERROR
1642                 qglUseProgramObjectARB(p->program);CHECKGLERROR
1643                 // look up all the uniform variable names we care about, so we don't
1644                 // have to look them up every time we set them
1645                 p->loc_Texture_First              = qglGetUniformLocationARB(p->program, "Texture_First");
1646                 p->loc_Texture_Second             = qglGetUniformLocationARB(p->program, "Texture_Second");
1647                 p->loc_Texture_GammaRamps         = qglGetUniformLocationARB(p->program, "Texture_GammaRamps");
1648                 p->loc_Texture_Normal             = qglGetUniformLocationARB(p->program, "Texture_Normal");
1649                 p->loc_Texture_Color              = qglGetUniformLocationARB(p->program, "Texture_Color");
1650                 p->loc_Texture_Gloss              = qglGetUniformLocationARB(p->program, "Texture_Gloss");
1651                 p->loc_Texture_Glow               = qglGetUniformLocationARB(p->program, "Texture_Glow");
1652                 p->loc_Texture_SecondaryNormal    = qglGetUniformLocationARB(p->program, "Texture_SecondaryNormal");
1653                 p->loc_Texture_SecondaryColor     = qglGetUniformLocationARB(p->program, "Texture_SecondaryColor");
1654                 p->loc_Texture_SecondaryGloss     = qglGetUniformLocationARB(p->program, "Texture_SecondaryGloss");
1655                 p->loc_Texture_SecondaryGlow      = qglGetUniformLocationARB(p->program, "Texture_SecondaryGlow");
1656                 p->loc_Texture_FogMask            = qglGetUniformLocationARB(p->program, "Texture_FogMask");
1657                 p->loc_Texture_Pants              = qglGetUniformLocationARB(p->program, "Texture_Pants");
1658                 p->loc_Texture_Shirt              = qglGetUniformLocationARB(p->program, "Texture_Shirt");
1659                 p->loc_Texture_Lightmap           = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
1660                 p->loc_Texture_Deluxemap          = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
1661                 p->loc_Texture_Refraction         = qglGetUniformLocationARB(p->program, "Texture_Refraction");
1662                 p->loc_Texture_Reflection         = qglGetUniformLocationARB(p->program, "Texture_Reflection");
1663                 p->loc_Texture_Attenuation        = qglGetUniformLocationARB(p->program, "Texture_Attenuation");
1664                 p->loc_Texture_Cube               = qglGetUniformLocationARB(p->program, "Texture_Cube");
1665                 p->loc_Texture_ShadowMapRect      = qglGetUniformLocationARB(p->program, "Texture_ShadowMapRect");
1666                 p->loc_Texture_CubeProjection     = qglGetUniformLocationARB(p->program, "Texture_CubeProjection");  
1667                 p->loc_FogColor                   = qglGetUniformLocationARB(p->program, "FogColor");
1668                 p->loc_LightPosition              = qglGetUniformLocationARB(p->program, "LightPosition");
1669                 p->loc_EyePosition                = qglGetUniformLocationARB(p->program, "EyePosition");
1670                 p->loc_Color_Pants                = qglGetUniformLocationARB(p->program, "Color_Pants");
1671                 p->loc_Color_Shirt                = qglGetUniformLocationARB(p->program, "Color_Shirt");
1672                 p->loc_FogRangeRecip              = qglGetUniformLocationARB(p->program, "FogRangeRecip");
1673                 p->loc_AmbientScale               = qglGetUniformLocationARB(p->program, "AmbientScale");
1674                 p->loc_DiffuseScale               = qglGetUniformLocationARB(p->program, "DiffuseScale");
1675                 p->loc_SpecularPower              = qglGetUniformLocationARB(p->program, "SpecularPower");
1676                 p->loc_SpecularScale              = qglGetUniformLocationARB(p->program, "SpecularScale");
1677                 p->loc_GlowScale                  = qglGetUniformLocationARB(p->program, "GlowScale");
1678                 p->loc_SceneBrightness            = qglGetUniformLocationARB(p->program, "SceneBrightness");
1679                 p->loc_OffsetMapping_Scale        = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
1680                 p->loc_TintColor                  = qglGetUniformLocationARB(p->program, "TintColor");
1681                 p->loc_AmbientColor               = qglGetUniformLocationARB(p->program, "AmbientColor");
1682                 p->loc_DiffuseColor               = qglGetUniformLocationARB(p->program, "DiffuseColor");
1683                 p->loc_SpecularColor              = qglGetUniformLocationARB(p->program, "SpecularColor");
1684                 p->loc_LightDir                   = qglGetUniformLocationARB(p->program, "LightDir");
1685                 p->loc_ContrastBoostCoeff         = qglGetUniformLocationARB(p->program, "ContrastBoostCoeff");
1686                 p->loc_DistortScaleRefractReflect = qglGetUniformLocationARB(p->program, "DistortScaleRefractReflect");
1687                 p->loc_ScreenScaleRefractReflect  = qglGetUniformLocationARB(p->program, "ScreenScaleRefractReflect");
1688                 p->loc_ScreenCenterRefractReflect = qglGetUniformLocationARB(p->program, "ScreenCenterRefractReflect");
1689                 p->loc_RefractColor               = qglGetUniformLocationARB(p->program, "RefractColor");
1690                 p->loc_ReflectColor               = qglGetUniformLocationARB(p->program, "ReflectColor");
1691                 p->loc_ReflectFactor              = qglGetUniformLocationARB(p->program, "ReflectFactor");
1692                 p->loc_ReflectOffset              = qglGetUniformLocationARB(p->program, "ReflectOffset");
1693                 p->loc_GammaCoeff                 = qglGetUniformLocationARB(p->program, "GammaCoeff");
1694                 p->loc_UserVec1                   = qglGetUniformLocationARB(p->program, "UserVec1");
1695                 p->loc_UserVec2                   = qglGetUniformLocationARB(p->program, "UserVec2");
1696                 p->loc_UserVec3                   = qglGetUniformLocationARB(p->program, "UserVec3");
1697                 p->loc_UserVec4                   = qglGetUniformLocationARB(p->program, "UserVec4");
1698                 p->loc_ClientTime                 = qglGetUniformLocationARB(p->program, "ClientTime");
1699                 p->loc_PixelSize                  = qglGetUniformLocationARB(p->program, "PixelSize");
1700                 p->loc_Saturation                 = qglGetUniformLocationARB(p->program, "Saturation");
1701                 p->loc_ShadowMap_TextureScale     = qglGetUniformLocationARB(p->program, "ShadowMap_TextureScale");
1702                 p->loc_ShadowMap_Parameters       = qglGetUniformLocationARB(p->program, "ShadowMap_Parameters");
1703                 // initialize the samplers to refer to the texture units we use
1704                 if (p->loc_Texture_First           >= 0) qglUniform1iARB(p->loc_Texture_First          , GL20TU_FIRST);
1705                 if (p->loc_Texture_Second          >= 0) qglUniform1iARB(p->loc_Texture_Second         , GL20TU_SECOND);
1706                 if (p->loc_Texture_GammaRamps      >= 0) qglUniform1iARB(p->loc_Texture_GammaRamps     , GL20TU_GAMMARAMPS);
1707                 if (p->loc_Texture_Normal          >= 0) qglUniform1iARB(p->loc_Texture_Normal         , GL20TU_NORMAL);
1708                 if (p->loc_Texture_Color           >= 0) qglUniform1iARB(p->loc_Texture_Color          , GL20TU_COLOR);
1709                 if (p->loc_Texture_Gloss           >= 0) qglUniform1iARB(p->loc_Texture_Gloss          , GL20TU_GLOSS);
1710                 if (p->loc_Texture_Glow            >= 0) qglUniform1iARB(p->loc_Texture_Glow           , GL20TU_GLOW);
1711                 if (p->loc_Texture_SecondaryNormal >= 0) qglUniform1iARB(p->loc_Texture_SecondaryNormal, GL20TU_SECONDARY_NORMAL);
1712                 if (p->loc_Texture_SecondaryColor  >= 0) qglUniform1iARB(p->loc_Texture_SecondaryColor , GL20TU_SECONDARY_COLOR);
1713                 if (p->loc_Texture_SecondaryGloss  >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGloss , GL20TU_SECONDARY_GLOSS);
1714                 if (p->loc_Texture_SecondaryGlow   >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGlow  , GL20TU_SECONDARY_GLOW);
1715                 if (p->loc_Texture_Pants           >= 0) qglUniform1iARB(p->loc_Texture_Pants          , GL20TU_PANTS);
1716                 if (p->loc_Texture_Shirt           >= 0) qglUniform1iARB(p->loc_Texture_Shirt          , GL20TU_SHIRT);
1717                 if (p->loc_Texture_FogMask         >= 0) qglUniform1iARB(p->loc_Texture_FogMask        , GL20TU_FOGMASK);
1718                 if (p->loc_Texture_Lightmap        >= 0) qglUniform1iARB(p->loc_Texture_Lightmap       , GL20TU_LIGHTMAP);
1719                 if (p->loc_Texture_Deluxemap       >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap      , GL20TU_DELUXEMAP);
1720                 if (p->loc_Texture_Attenuation     >= 0) qglUniform1iARB(p->loc_Texture_Attenuation    , GL20TU_ATTENUATION);
1721                 if (p->loc_Texture_Cube            >= 0) qglUniform1iARB(p->loc_Texture_Cube           , GL20TU_CUBE);
1722                 if (p->loc_Texture_Refraction      >= 0) qglUniform1iARB(p->loc_Texture_Refraction     , GL20TU_REFRACTION);
1723                 if (p->loc_Texture_Reflection      >= 0) qglUniform1iARB(p->loc_Texture_Reflection     , GL20TU_REFLECTION);
1724                 if (p->loc_Texture_ShadowMapRect   >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapRect  , GL20TU_SHADOWMAPRECT);
1725                 if (p->loc_Texture_CubeProjection  >= 0) qglUniform1iARB(p->loc_Texture_CubeProjection , GL20TU_CUBEPROJECTION);
1726                 CHECKGLERROR
1727                 if (developer.integer)
1728                         Con_Printf("GLSL shader %s compiled.\n", permutationname);
1729         }
1730         else
1731                 Con_Printf("GLSL shader %s failed!  some features may not work properly.\n", permutationname);
1732
1733         // free the strings
1734         if (vertexstring)
1735                 Mem_Free(vertexstring);
1736         if (geometrystring)
1737                 Mem_Free(geometrystring);
1738         if (fragmentstring)
1739                 Mem_Free(fragmentstring);
1740 }
1741
1742 void R_GLSL_Restart_f(void)
1743 {
1744         unsigned int mode;
1745         unsigned int permutation;
1746         for (mode = 0;mode < SHADERMODE_COUNT;mode++)
1747                 for (permutation = 0;permutation < SHADERPERMUTATION_LIMIT;permutation++)
1748                         if (r_glsl_permutations[mode][permutation].program)
1749                                 GL_Backend_FreeProgram(r_glsl_permutations[mode][permutation].program);
1750         memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
1751 }
1752
1753 void R_GLSL_DumpShader_f(void)
1754 {
1755         int i;
1756
1757         qfile_t *file = FS_OpenRealFile("glsl/default.glsl", "w", false);
1758         if(!file)
1759         {
1760                 Con_Printf("failed to write to glsl/default.glsl\n");
1761                 return;
1762         }
1763
1764         FS_Print(file, "/* The engine may define the following macros:\n");
1765         FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
1766         for (i = 0;i < SHADERMODE_COUNT;i++)
1767                 FS_Print(file, shadermodeinfo[i].pretext);
1768         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1769                 FS_Print(file, shaderpermutationinfo[i].pretext);
1770         FS_Print(file, "*/\n");
1771         FS_Print(file, builtinshaderstring);
1772         FS_Close(file);
1773
1774         Con_Printf("glsl/default.glsl written\n");
1775 }
1776
1777 void R_SetupShader_SetPermutation(unsigned int mode, unsigned int permutation)
1778 {
1779         r_glsl_permutation_t *perm = &r_glsl_permutations[mode][permutation];
1780         if (r_glsl_permutation != perm)
1781         {
1782                 r_glsl_permutation = perm;
1783                 if (!r_glsl_permutation->program)
1784                 {
1785                         if (!r_glsl_permutation->compiled)
1786                                 R_GLSL_CompilePermutation(mode, permutation);
1787                         if (!r_glsl_permutation->program)
1788                         {
1789                                 // remove features until we find a valid permutation
1790                                 int i;
1791                                 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1792                                 {
1793                                         // reduce i more quickly whenever it would not remove any bits
1794                                         int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
1795                                         if (!(permutation & j))
1796                                                 continue;
1797                                         permutation -= j;
1798                                         r_glsl_permutation = &r_glsl_permutations[mode][permutation];
1799                                         if (!r_glsl_permutation->compiled)
1800                                                 R_GLSL_CompilePermutation(mode, permutation);
1801                                         if (r_glsl_permutation->program)
1802                                                 break;
1803                                 }
1804                                 if (i >= SHADERPERMUTATION_COUNT)
1805                                 {
1806                                         Con_Printf("OpenGL 2.0 shaders disabled - unable to find a working shader permutation fallback on this driver (set r_glsl 1 if you want to try again)\n");
1807                                         Cvar_SetValueQuick(&r_glsl, 0);
1808                                         R_GLSL_Restart_f(); // unload shaders
1809                                         return; // no bit left to clear
1810                                 }
1811                         }
1812                 }
1813                 CHECKGLERROR
1814                 qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
1815         }
1816 }
1817
1818 void R_SetupGenericShader(qboolean usetexture)
1819 {
1820         if (gl_support_fragment_shader)
1821         {
1822                 if (r_glsl.integer && r_glsl_usegeneric.integer)
1823                         R_SetupShader_SetPermutation(SHADERMODE_GENERIC, usetexture ? SHADERPERMUTATION_DIFFUSE : 0);
1824                 else if (r_glsl_permutation)
1825                 {
1826                         r_glsl_permutation = NULL;
1827                         qglUseProgramObjectARB(0);CHECKGLERROR
1828                 }
1829         }
1830 }
1831
1832 void R_SetupGenericTwoTextureShader(int texturemode)
1833 {
1834         if (gl_support_fragment_shader)
1835         {
1836                 if (r_glsl.integer && r_glsl_usegeneric.integer)
1837                         R_SetupShader_SetPermutation(SHADERMODE_GENERIC, SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
1838                 else if (r_glsl_permutation)
1839                 {
1840                         r_glsl_permutation = NULL;
1841                         qglUseProgramObjectARB(0);CHECKGLERROR
1842                 }
1843         }
1844         if (!r_glsl_permutation)
1845         {
1846                 if (texturemode == GL_DECAL && gl_combine.integer)
1847                         texturemode = GL_INTERPOLATE_ARB;
1848                 R_Mesh_TexCombine(1, texturemode, texturemode, 1, 1);
1849         }
1850 }
1851
1852 void R_SetupDepthOrShadowShader(void)
1853 {
1854         if (gl_support_fragment_shader)
1855         {
1856                 if (r_glsl.integer && r_glsl_usegeneric.integer)
1857                         R_SetupShader_SetPermutation(SHADERMODE_DEPTH_OR_SHADOW, 0);
1858                 else if (r_glsl_permutation)
1859                 {
1860                         r_glsl_permutation = NULL;
1861                         qglUseProgramObjectARB(0);CHECKGLERROR
1862                 }
1863         }
1864 }
1865
1866 void R_SetupShowDepthShader(void)
1867 {
1868         if (gl_support_fragment_shader)
1869         {
1870                 if (r_glsl.integer && r_glsl_usegeneric.integer)
1871                         R_SetupShader_SetPermutation(SHADERMODE_SHOWDEPTH, 0);
1872                 else if (r_glsl_permutation)
1873                 {
1874                         r_glsl_permutation = NULL;
1875                         qglUseProgramObjectARB(0);CHECKGLERROR
1876                 }
1877         }
1878 }
1879
1880 extern rtexture_t *r_shadow_attenuationgradienttexture;
1881 extern rtexture_t *r_shadow_attenuation2dtexture;
1882 extern rtexture_t *r_shadow_attenuation3dtexture;
1883 extern float r_shadow_shadowmap_bias;
1884 extern float r_shadow_shadowmap_texturescale[4];
1885 extern float r_shadow_shadowmap_parameters[4];
1886 extern int r_shadow_shadowmode;
1887 extern int r_shadow_shadowmapfilter;
1888 void R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass)
1889 {
1890         // select a permutation of the lighting shader appropriate to this
1891         // combination of texture, entity, light source, and fogging, only use the
1892         // minimum features necessary to avoid wasting rendering time in the
1893         // fragment shader on features that are not being used
1894         unsigned int permutation = 0;
1895         unsigned int mode = 0;
1896         // TODO: implement geometry-shader based shadow volumes someday
1897         if (r_glsl_offsetmapping.integer)
1898         {
1899                 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
1900                 if (r_glsl_offsetmapping_reliefmapping.integer)
1901                         permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
1902         }
1903         if (rsurfacepass == RSURFPASS_BACKGROUND)
1904         {
1905                 // distorted background
1906                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
1907                         mode = SHADERMODE_WATER;
1908                 else
1909                         mode = SHADERMODE_REFRACTION;
1910         }
1911         else if (rsurfacepass == RSURFPASS_RTLIGHT)
1912         {
1913                 // light source
1914                 mode = SHADERMODE_LIGHTSOURCE;
1915                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
1916                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
1917                 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
1918                         permutation |= SHADERPERMUTATION_CUBEFILTER;
1919                 if (diffusescale > 0)
1920                         permutation |= SHADERPERMUTATION_DIFFUSE;
1921                 if (specularscale > 0)
1922                         permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
1923                 if (r_refdef.fogenabled)
1924                         permutation |= SHADERPERMUTATION_FOG;
1925                 if (rsurface.texture->colormapping)
1926                         permutation |= SHADERPERMUTATION_COLORMAPPING;
1927                 if (r_shadow_shadowmode)
1928                         permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
1929                 if (r_shadow_shadowmapfilter == 3)
1930                         permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
1931                 else if (r_shadow_shadowmapfilter == 2)
1932                         permutation |= SHADERPERMUTATION_SHADOWMAPPCF | SHADERPERMUTATION_SHADOWSAMPLER;
1933                 else if (r_shadow_shadowmapfilter == 1)
1934                         permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
1935         }
1936         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
1937         {
1938                 // unshaded geometry (fullbright or ambient model lighting)
1939                 mode = SHADERMODE_FLATCOLOR;
1940                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
1941                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
1942                 if (rsurface.texture->currentskinframe->glow && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
1943                         permutation |= SHADERPERMUTATION_GLOW;
1944                 if (r_refdef.fogenabled)
1945                         permutation |= SHADERPERMUTATION_FOG;
1946                 if (rsurface.texture->colormapping)
1947                         permutation |= SHADERPERMUTATION_COLORMAPPING;
1948                 if (r_glsl_offsetmapping.integer)
1949                 {
1950                         permutation |= SHADERPERMUTATION_OFFSETMAPPING;
1951                         if (r_glsl_offsetmapping_reliefmapping.integer)
1952                                 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
1953                 }
1954                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
1955                         permutation |= SHADERPERMUTATION_REFLECTION;
1956         }
1957         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
1958         {
1959                 // directional model lighting
1960                 mode = SHADERMODE_LIGHTDIRECTION;
1961                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
1962                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
1963                 if (rsurface.texture->currentskinframe->glow && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
1964                         permutation |= SHADERPERMUTATION_GLOW;
1965                 permutation |= SHADERPERMUTATION_DIFFUSE;
1966                 if (specularscale > 0)
1967                         permutation |= SHADERPERMUTATION_SPECULAR;
1968                 if (r_refdef.fogenabled)
1969                         permutation |= SHADERPERMUTATION_FOG;
1970                 if (rsurface.texture->colormapping)
1971                         permutation |= SHADERPERMUTATION_COLORMAPPING;
1972                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
1973                         permutation |= SHADERPERMUTATION_REFLECTION;
1974         }
1975         else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
1976         {
1977                 // ambient model lighting
1978                 mode = SHADERMODE_LIGHTDIRECTION;
1979                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
1980                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
1981                 if (rsurface.texture->currentskinframe->glow && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
1982                         permutation |= SHADERPERMUTATION_GLOW;
1983                 if (r_refdef.fogenabled)
1984                         permutation |= SHADERPERMUTATION_FOG;
1985                 if (rsurface.texture->colormapping)
1986                         permutation |= SHADERPERMUTATION_COLORMAPPING;
1987                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
1988                         permutation |= SHADERPERMUTATION_REFLECTION;
1989         }
1990         else
1991         {
1992                 // lightmapped wall
1993                 if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
1994                 {
1995                         // deluxemapping (light direction texture)
1996                         if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
1997                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
1998                         else
1999                                 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2000                         permutation |= SHADERPERMUTATION_DIFFUSE;
2001                         if (specularscale > 0)
2002                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2003                 }
2004                 else if (r_glsl_deluxemapping.integer >= 2)
2005                 {
2006                         // fake deluxemapping (uniform light direction in tangentspace)
2007                         mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2008                         permutation |= SHADERPERMUTATION_DIFFUSE;
2009                         if (specularscale > 0)
2010                                 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2011                 }
2012                 else if (rsurface.uselightmaptexture)
2013                 {
2014                         // ordinary lightmapping (q1bsp, q3bsp)
2015                         mode = SHADERMODE_LIGHTMAP;
2016                 }
2017                 else
2018                 {
2019                         // ordinary vertex coloring (q3bsp)
2020                         mode = SHADERMODE_VERTEXCOLOR;
2021                 }
2022                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2023                         permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2024                 if (rsurface.texture->currentskinframe->glow && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2025                         permutation |= SHADERPERMUTATION_GLOW;
2026                 if (r_refdef.fogenabled)
2027                         permutation |= SHADERPERMUTATION_FOG;
2028                 if (rsurface.texture->colormapping)
2029                         permutation |= SHADERPERMUTATION_COLORMAPPING;
2030                 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2031                         permutation |= SHADERPERMUTATION_REFLECTION;
2032         }
2033         if(permutation & SHADERPERMUTATION_SPECULAR)
2034                 if(r_shadow_glossexact.integer)
2035                         permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
2036         R_SetupShader_SetPermutation(mode, permutation);
2037         if (mode == SHADERMODE_LIGHTSOURCE)
2038         {
2039                 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2040                 if (permutation & SHADERPERMUTATION_DIFFUSE)
2041                 {
2042                         if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2], rsurface.texture->lightmapcolor[3]);
2043                         if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, ambientscale);
2044                         if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, diffusescale);
2045                         if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale);
2046                 }
2047                 else
2048                 {
2049                         // ambient only is simpler
2050                         if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, lightcolorbase[0] * ambientscale, lightcolorbase[1] * ambientscale, lightcolorbase[2] * ambientscale, rsurface.texture->lightmapcolor[3]);
2051                         if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, 1);
2052                         if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, 0);
2053                         if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, 0);
2054                 }
2055                 // additive passes are only darkened by fog, not tinted
2056                 if (r_glsl_permutation->loc_FogColor >= 0)
2057                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2058                 if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform4fARB(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1], r_shadow_shadowmap_texturescale[2], r_shadow_shadowmap_texturescale[3]);
2059                 if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4fARB(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
2060         }
2061         else
2062         {
2063                 if (mode == SHADERMODE_LIGHTDIRECTION)
2064                 {
2065                         if (r_glsl_permutation->loc_AmbientColor  >= 0) qglUniform3fARB(r_glsl_permutation->loc_AmbientColor , rsurface.modellight_ambient[0] * ambientscale  * 0.5f, rsurface.modellight_ambient[1] * ambientscale  * 0.5f, rsurface.modellight_ambient[2] * ambientscale  * 0.5f);
2066                         if (r_glsl_permutation->loc_DiffuseColor  >= 0) qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor , rsurface.modellight_diffuse[0] * diffusescale  * 0.5f, rsurface.modellight_diffuse[1] * diffusescale  * 0.5f, rsurface.modellight_diffuse[2] * diffusescale  * 0.5f);
2067                         if (r_glsl_permutation->loc_SpecularColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, rsurface.modellight_diffuse[0] * specularscale * 0.5f, rsurface.modellight_diffuse[1] * specularscale * 0.5f, rsurface.modellight_diffuse[2] * specularscale * 0.5f);
2068                         if (r_glsl_permutation->loc_LightDir      >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2069                 }
2070                 else
2071                 {
2072                         if (r_glsl_permutation->loc_AmbientScale  >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_refdef.scene.ambient * 1.0f / 128.0f);
2073                         if (r_glsl_permutation->loc_DiffuseScale  >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_refdef.lightmapintensity);
2074                         if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_refdef.lightmapintensity * specularscale);
2075                 }
2076                 if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2], rsurface.texture->lightmapcolor[3]);
2077                 if (r_glsl_permutation->loc_GlowScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_GlowScale, r_hdr_glowintensity.value);
2078                 // additive passes are only darkened by fog, not tinted
2079                 if (r_glsl_permutation->loc_FogColor >= 0)
2080                 {
2081                         if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
2082                                 qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2083                         else
2084                                 qglUniform3fARB(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2085                 }
2086                 if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
2087                 if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
2088                 if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
2089                 if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor4f);
2090                 if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor4f);
2091                 if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2092                 if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
2093         }
2094         if (r_glsl_permutation->loc_SceneBrightness >= 0) qglUniform1fARB(r_glsl_permutation->loc_SceneBrightness, r_refdef.view.colorscale);
2095         if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.modelorg[0], rsurface.modelorg[1], rsurface.modelorg[2]);
2096         if (r_glsl_permutation->loc_Color_Pants >= 0)
2097         {
2098                 if (rsurface.texture->currentskinframe->pants)
2099                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2100                 else
2101                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
2102         }
2103         if (r_glsl_permutation->loc_Color_Shirt >= 0)
2104         {
2105                 if (rsurface.texture->currentskinframe->shirt)
2106                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2107                 else
2108                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
2109         }
2110         if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip * Matrix4x4_ScaleFromMatrix(&rsurface.matrix));
2111         if(permutation & SHADERPERMUTATION_EXACTSPECULARMATH)
2112         {
2113                 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * 0.25);
2114         }
2115         else
2116         {
2117                 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower);
2118         }
2119         if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
2120         CHECKGLERROR
2121 }
2122
2123 #define SKINFRAME_HASH 1024
2124
2125 typedef struct
2126 {
2127         int loadsequence; // incremented each level change
2128         memexpandablearray_t array;
2129         skinframe_t *hash[SKINFRAME_HASH];
2130 }
2131 r_skinframe_t;
2132 r_skinframe_t r_skinframe;
2133
2134 void R_SkinFrame_PrepareForPurge(void)
2135 {
2136         r_skinframe.loadsequence++;
2137         // wrap it without hitting zero
2138         if (r_skinframe.loadsequence >= 200)
2139                 r_skinframe.loadsequence = 1;
2140 }
2141
2142 void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
2143 {
2144         if (!skinframe)
2145                 return;
2146         // mark the skinframe as used for the purging code
2147         skinframe->loadsequence = r_skinframe.loadsequence;
2148 }
2149
2150 void R_SkinFrame_Purge(void)
2151 {
2152         int i;
2153         skinframe_t *s;
2154         for (i = 0;i < SKINFRAME_HASH;i++)
2155         {
2156                 for (s = r_skinframe.hash[i];s;s = s->next)
2157                 {
2158                         if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
2159                         {
2160                                 if (s->merged == s->base)
2161                                         s->merged = NULL;
2162                                 // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
2163                                 R_PurgeTexture(s->stain );s->stain  = NULL;
2164                                 R_PurgeTexture(s->merged);s->merged = NULL;
2165                                 R_PurgeTexture(s->base  );s->base   = NULL;
2166                                 R_PurgeTexture(s->pants );s->pants  = NULL;
2167                                 R_PurgeTexture(s->shirt );s->shirt  = NULL;
2168                                 R_PurgeTexture(s->nmap  );s->nmap   = NULL;
2169                                 R_PurgeTexture(s->gloss );s->gloss  = NULL;
2170                                 R_PurgeTexture(s->glow  );s->glow   = NULL;
2171                                 R_PurgeTexture(s->fog   );s->fog    = NULL;
2172                                 s->loadsequence = 0;
2173                         }
2174                 }
2175         }
2176 }
2177
2178 skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name ) {
2179         skinframe_t *item;
2180         char basename[MAX_QPATH];
2181
2182         Image_StripImageExtension(name, basename, sizeof(basename));
2183
2184         if( last == NULL ) {
2185                 int hashindex;
2186                 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
2187                 item = r_skinframe.hash[hashindex];
2188         } else {
2189                 item = last->next;
2190         }
2191
2192         // linearly search through the hash bucket
2193         for( ; item ; item = item->next ) {
2194                 if( !strcmp( item->basename, basename ) ) {
2195                         return item;
2196                 }
2197         }
2198         return NULL;
2199 }
2200
2201 skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add)
2202 {
2203         skinframe_t *item;
2204         int hashindex;
2205         char basename[MAX_QPATH];
2206
2207         Image_StripImageExtension(name, basename, sizeof(basename));
2208
2209         hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
2210         for (item = r_skinframe.hash[hashindex];item;item = item->next)
2211                 if (!strcmp(item->basename, basename) && item->textureflags == textureflags && item->comparewidth == comparewidth && item->compareheight == compareheight && item->comparecrc == comparecrc)
2212                         break;
2213
2214         if (!item) {
2215                 rtexture_t *dyntexture;
2216                 // check whether its a dynamic texture
2217                 dyntexture = CL_GetDynTexture( basename );
2218                 if (!add && !dyntexture)
2219                         return NULL;
2220                 item = (skinframe_t *)Mem_ExpandableArray_AllocRecord(&r_skinframe.array);
2221                 memset(item, 0, sizeof(*item));
2222                 strlcpy(item->basename, basename, sizeof(item->basename));
2223                 item->base = dyntexture; // either NULL or dyntexture handle
2224                 item->textureflags = textureflags;
2225                 item->comparewidth = comparewidth;
2226                 item->compareheight = compareheight;
2227                 item->comparecrc = comparecrc;
2228                 item->next = r_skinframe.hash[hashindex];
2229                 r_skinframe.hash[hashindex] = item;
2230         }
2231         else if( item->base == NULL )
2232         {
2233                 rtexture_t *dyntexture;
2234                 // check whether its a dynamic texture
2235                 // this only needs to be done because Purge doesnt delete skinframes - only sets the texture pointers to NULL and we need to restore it before returing.. [11/29/2007 Black]
2236                 dyntexture = CL_GetDynTexture( basename );
2237                 item->base = dyntexture; // either NULL or dyntexture handle
2238         }
2239
2240         R_SkinFrame_MarkUsed(item);
2241         return item;
2242 }
2243
2244 #define R_SKINFRAME_LOAD_AVERAGE_COLORS(cnt, getpixel) \
2245         { \
2246                 unsigned long long avgcolor[5], wsum; \
2247                 int pix, comp, w; \
2248                 avgcolor[0] = 0; \
2249                 avgcolor[1] = 0; \
2250                 avgcolor[2] = 0; \
2251                 avgcolor[3] = 0; \
2252                 avgcolor[4] = 0; \
2253                 wsum = 0; \
2254                 for(pix = 0; pix < cnt; ++pix) \
2255                 { \
2256                         w = 0; \
2257                         for(comp = 0; comp < 3; ++comp) \
2258                                 w += getpixel; \
2259                         if(w) /* ignore perfectly black pixels because that is better for model skins */ \
2260                         { \
2261                                 ++wsum; \
2262                                 /* comp = 3; -- not needed, comp is always 3 when we get here */ \
2263                                 w = getpixel; \
2264                                 for(comp = 0; comp < 3; ++comp) \
2265                                         avgcolor[comp] += getpixel * w; \
2266                                 avgcolor[3] += w; \
2267                         } \
2268                         /* comp = 3; -- not needed, comp is always 3 when we get here */ \
2269                         avgcolor[4] += getpixel; \
2270                 } \
2271                 if(avgcolor[3] == 0) /* no pixels seen? even worse */ \
2272                         avgcolor[3] = 1; \
2273                 skinframe->avgcolor[0] = avgcolor[2] / (255.0 * avgcolor[3]); \
2274                 skinframe->avgcolor[1] = avgcolor[1] / (255.0 * avgcolor[3]); \
2275                 skinframe->avgcolor[2] = avgcolor[0] / (255.0 * avgcolor[3]); \
2276                 skinframe->avgcolor[3] = avgcolor[4] / (255.0 * cnt); \
2277         }
2278
2279 skinframe_t *R_SkinFrame_LoadExternal_CheckAlpha(const char *name, int textureflags, qboolean complain, qboolean *has_alpha)
2280 {
2281         // FIXME: it should be possible to disable loading various layers using
2282         // cvars, to prevent wasted loading time and memory usage if the user does
2283         // not want them
2284         qboolean loadnormalmap = true;
2285         qboolean loadgloss = true;
2286         qboolean loadpantsandshirt = true;
2287         qboolean loadglow = true;
2288         int j;
2289         unsigned char *pixels;
2290         unsigned char *bumppixels;
2291         unsigned char *basepixels = NULL;
2292         int basepixels_width;
2293         int basepixels_height;
2294         skinframe_t *skinframe;
2295
2296         *has_alpha = false;
2297
2298         if (cls.state == ca_dedicated)
2299                 return NULL;
2300
2301         // return an existing skinframe if already loaded
2302         // if loading of the first image fails, don't make a new skinframe as it
2303         // would cause all future lookups of this to be missing
2304         skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
2305         if (skinframe && skinframe->base)
2306                 return skinframe;
2307
2308         basepixels = loadimagepixelsbgra(name, complain, true);
2309         if (basepixels == NULL)
2310                 return NULL;
2311
2312         if (developer_loading.integer)
2313                 Con_Printf("loading skin \"%s\"\n", name);
2314
2315         // we've got some pixels to store, so really allocate this new texture now
2316         if (!skinframe)
2317                 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, true);
2318         skinframe->stain = NULL;
2319         skinframe->merged = NULL;
2320         skinframe->base = r_texture_notexture;
2321         skinframe->pants = NULL;
2322         skinframe->shirt = NULL;
2323         skinframe->nmap = r_texture_blanknormalmap;
2324         skinframe->gloss = NULL;
2325         skinframe->glow = NULL;
2326         skinframe->fog = NULL;
2327
2328         basepixels_width = image_width;
2329         basepixels_height = image_height;
2330         skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2331
2332         if (textureflags & TEXF_ALPHA)
2333         {
2334                 for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4)
2335                         if (basepixels[j] < 255)
2336                                 break;
2337                 if (j < basepixels_width * basepixels_height * 4)
2338                 {
2339                         // has transparent pixels
2340                         *has_alpha = true;
2341                         pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
2342                         for (j = 0;j < image_width * image_height * 4;j += 4)
2343                         {
2344                                 pixels[j+0] = 255;
2345                                 pixels[j+1] = 255;
2346                                 pixels[j+2] = 255;
2347                                 pixels[j+3] = basepixels[j+3];
2348                         }
2349                         skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2350                         Mem_Free(pixels);
2351                 }
2352         }
2353
2354         R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]);
2355         //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]);
2356
2357         // _norm is the name used by tenebrae and has been adopted as standard
2358         if (loadnormalmap)
2359         {
2360                 if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false)) != NULL)
2361                 {
2362                         skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2363                         Mem_Free(pixels);
2364                         pixels = NULL;
2365                 }
2366                 else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false)) != NULL)
2367                 {
2368                         pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
2369                         Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value);
2370                         skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2371                         Mem_Free(pixels);
2372                         Mem_Free(bumppixels);
2373                 }
2374                 else if (r_shadow_bumpscale_basetexture.value > 0)
2375                 {
2376                         pixels = (unsigned char *)Mem_Alloc(tempmempool, basepixels_width * basepixels_height * 4);
2377                         Image_HeightmapToNormalmap_BGRA(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value);
2378                         skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL);
2379                         Mem_Free(pixels);
2380                 }
2381         }
2382         // _luma is supported for tenebrae compatibility
2383         // (I think it's a very stupid name, but oh well)
2384         // _glow is the preferred name
2385         if (loadglow          && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false)) != NULL || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false)) != NULL)) {skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;}
2386         if (loadgloss         && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false)) != NULL) {skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;}
2387         if (loadpantsandshirt && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false)) != NULL) {skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;}
2388         if (loadpantsandshirt && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false)) != NULL) {skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;}
2389
2390         if (basepixels)
2391                 Mem_Free(basepixels);
2392
2393         return skinframe;
2394 }
2395
2396 skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain)
2397 {
2398         qboolean has_alpha;
2399         return R_SkinFrame_LoadExternal_CheckAlpha(name, textureflags, complain, &has_alpha);
2400 }
2401
2402 static rtexture_t *R_SkinFrame_TextureForSkinLayer(const unsigned char *in, int width, int height, const char *name, const unsigned int *palette, int textureflags, qboolean force)
2403 {
2404         int i;
2405         if (!force)
2406         {
2407                 for (i = 0;i < width*height;i++)
2408                         if (((unsigned char *)&palette[in[i]])[3] > 0)
2409                                 break;
2410                 if (i == width*height)
2411                         return NULL;
2412         }
2413         return R_LoadTexture2D (r_main_texturepool, name, width, height, in, TEXTYPE_PALETTE, textureflags, palette);
2414 }
2415
2416 // this is only used by .spr32 sprites, HL .spr files, HL .bsp files
2417 skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height)
2418 {
2419         int i;
2420         unsigned char *temp1, *temp2;
2421         skinframe_t *skinframe;
2422
2423         if (cls.state == ca_dedicated)
2424                 return NULL;
2425
2426         // if already loaded just return it, otherwise make a new skinframe
2427         skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height*4) : 0, true);
2428         if (skinframe && skinframe->base)
2429                 return skinframe;
2430
2431         skinframe->stain = NULL;
2432         skinframe->merged = NULL;
2433         skinframe->base = r_texture_notexture;
2434         skinframe->pants = NULL;
2435         skinframe->shirt = NULL;
2436         skinframe->nmap = r_texture_blanknormalmap;
2437         skinframe->gloss = NULL;
2438         skinframe->glow = NULL;
2439         skinframe->fog = NULL;
2440
2441         // if no data was provided, then clearly the caller wanted to get a blank skinframe
2442         if (!skindata)
2443                 return NULL;
2444
2445         if (developer_loading.integer)
2446                 Con_Printf("loading 32bit skin \"%s\"\n", name);
2447
2448         if (r_shadow_bumpscale_basetexture.value > 0)
2449         {
2450                 temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
2451                 temp2 = temp1 + width * height * 4;
2452                 Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
2453                 skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, NULL);
2454                 Mem_Free(temp1);
2455         }
2456         skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_BGRA, skinframe->textureflags, NULL);
2457         if (textureflags & TEXF_ALPHA)
2458         {
2459                 for (i = 3;i < width * height * 4;i += 4)
2460                         if (skindata[i] < 255)
2461                                 break;
2462                 if (i < width * height * 4)
2463                 {
2464                         unsigned char *fogpixels = (unsigned char *)Mem_Alloc(tempmempool, width * height * 4);
2465                         memcpy(fogpixels, skindata, width * height * 4);
2466                         for (i = 0;i < width * height * 4;i += 4)
2467                                 fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
2468                         skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, skinframe->textureflags, NULL);
2469                         Mem_Free(fogpixels);
2470                 }
2471         }
2472
2473         R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, skindata[4 * pix + comp]);
2474         //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]);
2475
2476         return skinframe;
2477 }
2478
2479 skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height)
2480 {
2481         int i;
2482         unsigned char *temp1, *temp2;
2483         unsigned int *palette;
2484         skinframe_t *skinframe;
2485
2486         if (cls.state == ca_dedicated)
2487                 return NULL;
2488
2489         // if already loaded just return it, otherwise make a new skinframe
2490         skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
2491         if (skinframe && skinframe->base)
2492                 return skinframe;
2493
2494         palette = (loadglowtexture ? palette_bgra_nofullbrights : ((skinframe->textureflags & TEXF_ALPHA) ? palette_bgra_transparent : palette_bgra_complete));
2495
2496         skinframe->stain = NULL;
2497         skinframe->merged = NULL;
2498         skinframe->base = r_texture_notexture;
2499         skinframe->pants = NULL;
2500         skinframe->shirt = NULL;
2501         skinframe->nmap = r_texture_blanknormalmap;
2502         skinframe->gloss = NULL;
2503         skinframe->glow = NULL;
2504         skinframe->fog = NULL;
2505
2506         // if no data was provided, then clearly the caller wanted to get a blank skinframe
2507         if (!skindata)
2508                 return NULL;
2509
2510         if (developer_loading.integer)
2511                 Con_Printf("loading quake skin \"%s\"\n", name);
2512
2513         if (r_shadow_bumpscale_basetexture.value > 0)
2514         {
2515                 temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
2516                 temp2 = temp1 + width * height * 4;
2517                 // use either a custom palette or the quake palette
2518                 Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete);
2519                 Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
2520                 skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, NULL);
2521                 Mem_Free(temp1);
2522         }
2523         // use either a custom palette, or the quake palette
2524         skinframe->base = skinframe->merged = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_merged", skinframe->basename), palette, skinframe->textureflags, true); // all
2525         if (loadglowtexture)
2526                 skinframe->glow = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_glow", skinframe->basename), palette_bgra_onlyfullbrights, skinframe->textureflags, false); // glow
2527         if (loadpantsandshirt)
2528         {
2529                 skinframe->pants = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_pants", skinframe->basename), palette_bgra_pantsaswhite, skinframe->textureflags, false); // pants
2530                 skinframe->shirt = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_shirt", skinframe->basename), palette_bgra_shirtaswhite, skinframe->textureflags, false); // shirt
2531         }
2532         if (skinframe->pants || skinframe->shirt)
2533                 skinframe->base = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_nospecial", skinframe->basename), loadglowtexture ? palette_bgra_nocolormapnofullbrights : palette_bgra_nocolormap, skinframe->textureflags, false); // no special colors
2534         if (textureflags & TEXF_ALPHA)
2535         {
2536                 for (i = 0;i < width * height;i++)
2537                         if (((unsigned char *)palette_bgra_alpha)[skindata[i]*4+3] < 255)
2538                                 break;
2539                 if (i < width * height)
2540                         skinframe->fog = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_fog", skinframe->basename), palette_bgra_alpha, skinframe->textureflags, true); // fog mask
2541         }
2542
2543         R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette)[skindata[pix]*4 + comp]);
2544         //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]);
2545
2546         return skinframe;
2547 }
2548
2549 skinframe_t *R_SkinFrame_LoadMissing(void)
2550 {
2551         skinframe_t *skinframe;
2552
2553         if (cls.state == ca_dedicated)
2554                 return NULL;
2555
2556         skinframe = R_SkinFrame_Find("missing", TEXF_PRECACHE | TEXF_FORCENEAREST, 0, 0, 0, true);
2557         skinframe->stain = NULL;
2558         skinframe->merged = NULL;
2559         skinframe->base = r_texture_notexture;
2560         skinframe->pants = NULL;
2561         skinframe->shirt = NULL;
2562         skinframe->nmap = r_texture_blanknormalmap;
2563         skinframe->gloss = NULL;
2564         skinframe->glow = NULL;
2565         skinframe->fog = NULL;
2566
2567         skinframe->avgcolor[0] = rand() / RAND_MAX;
2568         skinframe->avgcolor[1] = rand() / RAND_MAX;
2569         skinframe->avgcolor[2] = rand() / RAND_MAX;
2570         skinframe->avgcolor[3] = 1;
2571
2572         return skinframe;
2573 }
2574
2575 void gl_main_start(void)
2576 {
2577         r_numqueries = 0;
2578         r_maxqueries = 0;
2579         memset(r_queries, 0, sizeof(r_queries));
2580
2581         memset(r_qwskincache, 0, sizeof(r_qwskincache));
2582         memset(r_qwskincache_skinframe, 0, sizeof(r_qwskincache_skinframe));
2583
2584         // set up r_skinframe loading system for textures
2585         memset(&r_skinframe, 0, sizeof(r_skinframe));
2586         r_skinframe.loadsequence = 1;
2587         Mem_ExpandableArray_NewArray(&r_skinframe.array, r_main_mempool, sizeof(skinframe_t), 256);
2588
2589         r_main_texturepool = R_AllocTexturePool();
2590         R_BuildBlankTextures();
2591         R_BuildNoTexture();
2592         if (gl_texturecubemap)
2593         {
2594                 R_BuildWhiteCube();
2595                 R_BuildNormalizationCube();
2596         }
2597         r_texture_fogattenuation = NULL;
2598         r_texture_gammaramps = NULL;
2599         //r_texture_fogintensity = NULL;
2600         memset(&r_bloomstate, 0, sizeof(r_bloomstate));
2601         memset(&r_waterstate, 0, sizeof(r_waterstate));
2602         memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
2603         memset(&r_svbsp, 0, sizeof (r_svbsp));
2604
2605         r_refdef.fogmasktable_density = 0;
2606 }
2607
2608 extern rtexture_t *loadingscreentexture;
2609 void gl_main_shutdown(void)
2610 {
2611         if (r_maxqueries)
2612                 qglDeleteQueriesARB(r_maxqueries, r_queries);
2613
2614         r_numqueries = 0;
2615         r_maxqueries = 0;
2616         memset(r_queries, 0, sizeof(r_queries));
2617
2618         memset(r_qwskincache, 0, sizeof(r_qwskincache));
2619         memset(r_qwskincache_skinframe, 0, sizeof(r_qwskincache_skinframe));
2620
2621         // clear out the r_skinframe state
2622         Mem_ExpandableArray_FreeArray(&r_skinframe.array);
2623         memset(&r_skinframe, 0, sizeof(r_skinframe));
2624
2625         if (r_svbsp.nodes)
2626                 Mem_Free(r_svbsp.nodes);
2627         memset(&r_svbsp, 0, sizeof (r_svbsp));
2628         R_FreeTexturePool(&r_main_texturepool);
2629         loadingscreentexture = NULL;
2630         r_texture_blanknormalmap = NULL;
2631         r_texture_white = NULL;
2632         r_texture_grey128 = NULL;
2633         r_texture_black = NULL;
2634         r_texture_whitecube = NULL;
2635         r_texture_normalizationcube = NULL;
2636         r_texture_fogattenuation = NULL;
2637         r_texture_gammaramps = NULL;
2638         //r_texture_fogintensity = NULL;
2639         memset(&r_bloomstate, 0, sizeof(r_bloomstate));
2640         memset(&r_waterstate, 0, sizeof(r_waterstate));
2641         R_GLSL_Restart_f();
2642 }
2643
2644 extern void CL_ParseEntityLump(char *entitystring);
2645 void gl_main_newmap(void)
2646 {
2647         // FIXME: move this code to client
2648         int l;
2649         char *entities, entname[MAX_QPATH];
2650         if (cl.worldmodel)
2651         {
2652                 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
2653                 l = (int)strlen(entname) - 4;
2654                 if (l >= 0 && !strcmp(entname + l, ".bsp"))
2655                 {
2656                         memcpy(entname + l, ".ent", 5);
2657                         if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
2658                         {
2659                                 CL_ParseEntityLump(entities);
2660                                 Mem_Free(entities);
2661                                 return;
2662                         }
2663                 }
2664                 if (cl.worldmodel->brush.entities)
2665                         CL_ParseEntityLump(cl.worldmodel->brush.entities);
2666         }
2667 }
2668
2669 void GL_Main_Init(void)
2670 {
2671         r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
2672
2673         Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed");
2674         Cmd_AddCommand("r_glsl_dumpshader", R_GLSL_DumpShader_f, "dumps the engine internal default.glsl shader into glsl/default.glsl");
2675         // FIXME: the client should set up r_refdef.fog stuff including the fogmasktable
2676         if (gamemode == GAME_NEHAHRA)
2677         {
2678                 Cvar_RegisterVariable (&gl_fogenable);
2679                 Cvar_RegisterVariable (&gl_fogdensity);
2680                 Cvar_RegisterVariable (&gl_fogred);
2681                 Cvar_RegisterVariable (&gl_foggreen);
2682                 Cvar_RegisterVariable (&gl_fogblue);
2683                 Cvar_RegisterVariable (&gl_fogstart);
2684                 Cvar_RegisterVariable (&gl_fogend);
2685                 Cvar_RegisterVariable (&gl_skyclip);
2686         }
2687         Cvar_RegisterVariable(&r_motionblur);
2688         Cvar_RegisterVariable(&r_motionblur_maxblur);
2689         Cvar_RegisterVariable(&r_motionblur_bmin);
2690         Cvar_RegisterVariable(&r_motionblur_vmin);
2691         Cvar_RegisterVariable(&r_motionblur_vmax);
2692         Cvar_RegisterVariable(&r_motionblur_vcoeff);
2693         Cvar_RegisterVariable(&r_motionblur_randomize);
2694         Cvar_RegisterVariable(&r_damageblur);
2695         Cvar_RegisterVariable(&r_animcache);
2696         Cvar_RegisterVariable(&r_depthfirst);
2697         Cvar_RegisterVariable(&r_useinfinitefarclip);
2698         Cvar_RegisterVariable(&r_nearclip);
2699         Cvar_RegisterVariable(&r_showbboxes);
2700         Cvar_RegisterVariable(&r_showsurfaces);
2701         Cvar_RegisterVariable(&r_showtris);
2702         Cvar_RegisterVariable(&r_shownormals);
2703         Cvar_RegisterVariable(&r_showlighting);
2704         Cvar_RegisterVariable(&r_showshadowvolumes);
2705         Cvar_RegisterVariable(&r_showcollisionbrushes);
2706         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor);
2707         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset);
2708         Cvar_RegisterVariable(&r_showdisabledepthtest);
2709         Cvar_RegisterVariable(&r_drawportals);
2710         Cvar_RegisterVariable(&r_drawentities);
2711         Cvar_RegisterVariable(&r_cullentities_trace);
2712         Cvar_RegisterVariable(&r_cullentities_trace_samples);
2713         Cvar_RegisterVariable(&r_cullentities_trace_enlarge);
2714         Cvar_RegisterVariable(&r_cullentities_trace_delay);
2715         Cvar_RegisterVariable(&r_drawviewmodel);
2716         Cvar_RegisterVariable(&r_speeds);
2717         Cvar_RegisterVariable(&r_fullbrights);
2718         Cvar_RegisterVariable(&r_wateralpha);
2719         Cvar_RegisterVariable(&r_dynamic);
2720         Cvar_RegisterVariable(&r_fullbright);
2721         Cvar_RegisterVariable(&r_shadows);
2722         Cvar_RegisterVariable(&r_shadows_darken);
2723         Cvar_RegisterVariable(&r_shadows_drawafterrtlighting);
2724         Cvar_RegisterVariable(&r_shadows_castfrombmodels);
2725         Cvar_RegisterVariable(&r_shadows_throwdistance);
2726         Cvar_RegisterVariable(&r_shadows_throwdirection);
2727         Cvar_RegisterVariable(&r_q1bsp_skymasking);
2728         Cvar_RegisterVariable(&r_polygonoffset_submodel_factor);
2729         Cvar_RegisterVariable(&r_polygonoffset_submodel_offset);
2730         Cvar_RegisterVariable(&r_fog_exp2);
2731         Cvar_RegisterVariable(&r_drawfog);
2732         Cvar_RegisterVariable(&r_textureunits);
2733         Cvar_RegisterVariable(&r_glsl);
2734         Cvar_RegisterVariable(&r_glsl_deluxemapping);
2735         Cvar_RegisterVariable(&r_glsl_offsetmapping);
2736         Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
2737         Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
2738         Cvar_RegisterVariable(&r_glsl_postprocess);
2739         Cvar_RegisterVariable(&r_glsl_postprocess_uservec1);
2740         Cvar_RegisterVariable(&r_glsl_postprocess_uservec2);
2741         Cvar_RegisterVariable(&r_glsl_postprocess_uservec3);
2742         Cvar_RegisterVariable(&r_glsl_postprocess_uservec4);
2743         Cvar_RegisterVariable(&r_glsl_usegeneric);
2744         Cvar_RegisterVariable(&r_water);
2745         Cvar_RegisterVariable(&r_water_resolutionmultiplier);
2746         Cvar_RegisterVariable(&r_water_clippingplanebias);
2747         Cvar_RegisterVariable(&r_water_refractdistort);
2748         Cvar_RegisterVariable(&r_water_reflectdistort);
2749         Cvar_RegisterVariable(&r_lerpsprites);
2750         Cvar_RegisterVariable(&r_lerpmodels);
2751         Cvar_RegisterVariable(&r_lerplightstyles);
2752         Cvar_RegisterVariable(&r_waterscroll);
2753         Cvar_RegisterVariable(&r_bloom);
2754         Cvar_RegisterVariable(&r_bloom_colorscale);
2755         Cvar_RegisterVariable(&r_bloom_brighten);
2756         Cvar_RegisterVariable(&r_bloom_blur);
2757         Cvar_RegisterVariable(&r_bloom_resolution);
2758         Cvar_RegisterVariable(&r_bloom_colorexponent);
2759         Cvar_RegisterVariable(&r_bloom_colorsubtract);
2760         Cvar_RegisterVariable(&r_hdr);
2761         Cvar_RegisterVariable(&r_hdr_scenebrightness);
2762         Cvar_RegisterVariable(&r_hdr_glowintensity);
2763         Cvar_RegisterVariable(&r_hdr_range);
2764         Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
2765         Cvar_RegisterVariable(&developer_texturelogging);
2766         Cvar_RegisterVariable(&gl_lightmaps);
2767         Cvar_RegisterVariable(&r_test);
2768         Cvar_RegisterVariable(&r_batchmode);
2769         Cvar_RegisterVariable(&r_glsl_saturation);
2770         if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
2771                 Cvar_SetValue("r_fullbrights", 0);
2772         R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
2773
2774         Cvar_RegisterVariable(&r_track_sprites);
2775         Cvar_RegisterVariable(&r_track_sprites_flags);
2776         Cvar_RegisterVariable(&r_track_sprites_scalew);
2777         Cvar_RegisterVariable(&r_track_sprites_scaleh);
2778 }
2779
2780 extern void R_Textures_Init(void);
2781 extern void GL_Draw_Init(void);
2782 extern void GL_Main_Init(void);
2783 extern void R_Shadow_Init(void);
2784 extern void R_Sky_Init(void);
2785 extern void GL_Surf_Init(void);
2786 extern void R_Particles_Init(void);
2787 extern void R_Explosion_Init(void);
2788 extern void gl_backend_init(void);
2789 extern void Sbar_Init(void);
2790 extern void R_LightningBeams_Init(void);
2791 extern void Mod_RenderInit(void);
2792
2793 void Render_Init(void)
2794 {
2795         gl_backend_init();
2796         R_Textures_Init();
2797         GL_Main_Init();
2798         GL_Draw_Init();
2799         R_Shadow_Init();
2800         R_Sky_Init();
2801         GL_Surf_Init();
2802         Sbar_Init();
2803         R_Particles_Init();
2804         R_Explosion_Init();
2805         R_LightningBeams_Init();
2806         Mod_RenderInit();
2807 }
2808
2809 /*
2810 ===============
2811 GL_Init
2812 ===============
2813 */
2814 extern char *ENGINE_EXTENSIONS;
2815 void GL_Init (void)
2816 {
2817         gl_renderer = (const char *)qglGetString(GL_RENDERER);
2818         gl_vendor = (const char *)qglGetString(GL_VENDOR);
2819         gl_version = (const char *)qglGetString(GL_VERSION);
2820         gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
2821
2822         if (!gl_extensions)
2823                 gl_extensions = "";
2824         if (!gl_platformextensions)
2825                 gl_platformextensions = "";
2826
2827         Con_Printf("GL_VENDOR: %s\n", gl_vendor);
2828         Con_Printf("GL_RENDERER: %s\n", gl_renderer);
2829         Con_Printf("GL_VERSION: %s\n", gl_version);
2830         Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
2831         Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
2832
2833         VID_CheckExtensions();
2834
2835         // LordHavoc: report supported extensions
2836         Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
2837
2838         // clear to black (loading plaque will be seen over this)
2839         CHECKGLERROR
2840         qglClearColor(0,0,0,1);CHECKGLERROR
2841         qglClear(GL_COLOR_BUFFER_BIT);CHECKGLERROR
2842 }
2843
2844 int R_CullBox(const vec3_t mins, const vec3_t maxs)
2845 {
2846         int i;
2847         mplane_t *p;
2848         for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
2849         {
2850                 // skip nearclip plane, it often culls portals when you are very close, and is almost never useful
2851                 if (i == 4)
2852                         continue;
2853                 p = r_refdef.view.frustum + i;
2854                 switch(p->signbits)
2855                 {
2856                 default:
2857                 case 0:
2858                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
2859                                 return true;
2860                         break;
2861                 case 1:
2862                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
2863                                 return true;
2864                         break;
2865                 case 2:
2866                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
2867                                 return true;
2868                         break;
2869                 case 3:
2870                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
2871                                 return true;
2872                         break;
2873                 case 4:
2874                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
2875                                 return true;
2876                         break;
2877                 case 5:
2878                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
2879                                 return true;
2880                         break;
2881                 case 6:
2882                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
2883                                 return true;
2884                         break;
2885                 case 7:
2886                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
2887                                 return true;
2888                         break;
2889                 }
2890         }
2891         return false;
2892 }
2893
2894 int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
2895 {
2896         int i;
2897         const mplane_t *p;
2898         for (i = 0;i < numplanes;i++)
2899         {
2900                 p = planes + i;
2901                 switch(p->signbits)
2902                 {
2903                 default:
2904                 case 0:
2905                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
2906                                 return true;
2907                         break;
2908                 case 1:
2909                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
2910                                 return true;
2911                         break;
2912                 case 2:
2913                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
2914                                 return true;
2915                         break;
2916                 case 3:
2917                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
2918                                 return true;
2919                         break;
2920                 case 4:
2921                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
2922                                 return true;
2923                         break;
2924                 case 5:
2925                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
2926                                 return true;
2927                         break;
2928                 case 6:
2929                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
2930                                 return true;
2931                         break;
2932                 case 7:
2933                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
2934                                 return true;
2935                         break;
2936                 }
2937         }
2938         return false;
2939 }
2940
2941 //==================================================================================
2942
2943 // LordHavoc: animcache written by Echon, refactored and reformatted by me
2944
2945 /**
2946  * Animation cache helps save re-animating a player mesh if it's re-rendered again in a given frame
2947  * (reflections, lighting, etc). All animation cache becomes invalid on the next frame and is flushed
2948  * (well, over-wrote). The memory for each cache is kept around to save on allocation thrashing.
2949  */
2950
2951 typedef struct r_animcache_entity_s
2952 {
2953         float *vertex3f;
2954         float *normal3f;
2955         float *svector3f;
2956         float *tvector3f;
2957         int maxvertices;
2958         qboolean wantnormals;
2959         qboolean wanttangents;
2960 }
2961 r_animcache_entity_t;
2962
2963 typedef struct r_animcache_s
2964 {
2965         r_animcache_entity_t entity[MAX_EDICTS*2];
2966         int maxindex;
2967         int currentindex;
2968 }
2969 r_animcache_t;
2970
2971 static r_animcache_t r_animcachestate;
2972
2973 void R_AnimCache_Free(void)
2974 {
2975         int idx;
2976         for (idx=0 ; idx<r_animcachestate.maxindex ; idx++)
2977         {
2978                 r_animcachestate.entity[idx].maxvertices = 0;
2979                 Mem_Free(r_animcachestate.entity[idx].vertex3f);
2980                 r_animcachestate.entity[idx].vertex3f = NULL;
2981                 r_animcachestate.entity[idx].normal3f = NULL;
2982                 r_animcachestate.entity[idx].svector3f = NULL;
2983                 r_animcachestate.entity[idx].tvector3f = NULL;
2984         }
2985         r_animcachestate.currentindex = 0;
2986         r_animcachestate.maxindex = 0;
2987 }
2988
2989 void R_AnimCache_ResizeEntityCache(const int cacheIdx, const int numvertices)
2990 {
2991         int arraySize;
2992         float *base;
2993         r_animcache_entity_t *cache = &r_animcachestate.entity[cacheIdx];
2994
2995         if (cache->maxvertices >= numvertices)
2996                 return;
2997
2998         // Release existing memory
2999         if (cache->vertex3f)
3000                 Mem_Free(cache->vertex3f);
3001
3002         // Pad by 1024 verts
3003         cache->maxvertices = (numvertices + 1023) & ~1023;
3004         arraySize = cache->maxvertices * 3;
3005
3006         // Allocate, even if we don't need this memory in this instance it will get ignored and potentially used later
3007         base = (float *)Mem_Alloc(r_main_mempool, arraySize * sizeof(float) * 4);
3008         r_animcachestate.entity[cacheIdx].vertex3f = base;
3009         r_animcachestate.entity[cacheIdx].normal3f = base + arraySize;
3010         r_animcachestate.entity[cacheIdx].svector3f = base + arraySize*2;
3011         r_animcachestate.entity[cacheIdx].tvector3f = base + arraySize*3;
3012
3013 //      Con_Printf("allocated cache for %i (%f KB)\n", cacheIdx, (arraySize*sizeof(float)*4)/1024.0f);
3014 }
3015
3016 void R_AnimCache_NewFrame(void)
3017 {
3018         int i;
3019
3020         if (r_animcache.integer && r_drawentities.integer)
3021                 r_animcachestate.maxindex = sizeof(r_animcachestate.entity) / sizeof(r_animcachestate.entity[0]);
3022         else if (r_animcachestate.maxindex)
3023                 R_AnimCache_Free();
3024
3025         r_animcachestate.currentindex = 0;
3026
3027         for (i = 0;i < r_refdef.scene.numentities;i++)
3028                 r_refdef.scene.entities[i]->animcacheindex = -1;
3029 }
3030
3031 qboolean R_AnimCache_GetEntity(entity_render_t *ent, qboolean wantnormals, qboolean wanttangents)
3032 {
3033         dp_model_t *model = ent->model;
3034         r_animcache_entity_t *c;
3035         // see if it's already cached this frame
3036         if (ent->animcacheindex >= 0)
3037         {
3038                 // add normals/tangents if needed
3039                 c = r_animcachestate.entity + ent->animcacheindex;
3040                 if (c->wantnormals)
3041                         wantnormals = false;
3042                 if (c->wanttangents)
3043                         wanttangents = false;
3044                 if (wantnormals || wanttangents)
3045                         model->AnimateVertices(model, ent->frameblend, NULL, wantnormals ? c->normal3f : NULL, wanttangents ? c->svector3f : NULL, wanttangents ? c->tvector3f : NULL);
3046         }
3047         else
3048         {
3049                 // see if this ent is worth caching
3050                 if (r_animcachestate.maxindex <= r_animcachestate.currentindex)
3051                         return false;
3052                 if (!model || !model->Draw || !model->surfmesh.isanimated || !model->AnimateVertices || (ent->frameblend[0].lerp == 1 && ent->frameblend[0].subframe == 0))
3053                         return false;
3054                 // assign it a cache entry and make sure the arrays are big enough
3055                 R_AnimCache_ResizeEntityCache(r_animcachestate.currentindex, model->surfmesh.num_vertices);
3056                 ent->animcacheindex = r_animcachestate.currentindex++;
3057                 c = r_animcachestate.entity + ent->animcacheindex;
3058                 c->wantnormals = wantnormals;
3059                 c->wanttangents = wanttangents;
3060                 model->AnimateVertices(model, ent->frameblend, c->vertex3f, wantnormals ? c->normal3f : NULL, wanttangents ? c->svector3f : NULL, wanttangents ? c->tvector3f : NULL);
3061         }
3062         return true;
3063 }
3064
3065 void R_AnimCache_CacheVisibleEntities(void)
3066 {
3067         int i;
3068         qboolean wantnormals;
3069         qboolean wanttangents;
3070
3071         if (!r_animcachestate.maxindex)
3072                 return;
3073
3074         wantnormals = !r_showsurfaces.integer;
3075         wanttangents = !r_showsurfaces.integer && (r_glsl.integer || r_refdef.scene.rtworld || r_refdef.scene.rtdlight);
3076
3077         // TODO: thread this?
3078
3079         for (i = 0;i < r_refdef.scene.numentities;i++)
3080         {
3081                 if (!r_refdef.viewcache.entityvisible[i])
3082                         continue;
3083                 R_AnimCache_GetEntity(r_refdef.scene.entities[i], wantnormals, wanttangents);
3084         }
3085 }
3086
3087 //==================================================================================
3088
3089 static void R_View_UpdateEntityLighting (void)
3090 {
3091         int i;
3092         entity_render_t *ent;
3093         vec3_t tempdiffusenormal;
3094
3095         for (i = 0;i < r_refdef.scene.numentities;i++)
3096         {
3097                 ent = r_refdef.scene.entities[i];
3098
3099                 // skip unseen models
3100                 if (!r_refdef.viewcache.entityvisible[i] && r_shadows.integer != 1)
3101                         continue;
3102
3103                 // skip bsp models
3104                 if (ent->model && ent->model->brush.num_leafs)
3105                 {
3106                         // TODO: use modellight for r_ambient settings on world?
3107                         VectorSet(ent->modellight_ambient, 0, 0, 0);
3108                         VectorSet(ent->modellight_diffuse, 0, 0, 0);
3109                         VectorSet(ent->modellight_lightdir, 0, 0, 1);
3110                         continue;
3111                 }
3112
3113                 // fetch the lighting from the worldmodel data
3114                 VectorSet(ent->modellight_ambient, r_refdef.scene.ambient * (2.0f / 128.0f), r_refdef.scene.ambient * (2.0f / 128.0f), r_refdef.scene.ambient * (2.0f / 128.0f));
3115                 VectorClear(ent->modellight_diffuse);
3116                 VectorClear(tempdiffusenormal);
3117                 if ((ent->flags & RENDER_LIGHT) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint)
3118                 {
3119                         vec3_t org;
3120                         Matrix4x4_OriginFromMatrix(&ent->matrix, org);
3121                         r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, org, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
3122                 }
3123                 else // highly rare
3124                         VectorSet(ent->modellight_ambient, 1, 1, 1);
3125
3126                 // move the light direction into modelspace coordinates for lighting code
3127                 Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
3128                 if(VectorLength2(ent->modellight_lightdir) == 0)
3129                         VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here
3130                 VectorNormalize(ent->modellight_lightdir);
3131         }
3132 }
3133
3134 static void R_View_UpdateEntityVisible (void)
3135 {
3136         int i, renderimask;
3137         entity_render_t *ent;
3138
3139         if (!r_drawentities.integer)
3140                 return;
3141
3142         renderimask = r_refdef.envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : ((chase_active.integer || r_waterstate.renderingscene) ? RENDER_VIEWMODEL : RENDER_EXTERIORMODEL);
3143         if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs)
3144         {
3145                 // worldmodel can check visibility
3146                 memset(r_refdef.viewcache.entityvisible, 0, r_refdef.scene.numentities);
3147                 for (i = 0;i < r_refdef.scene.numentities;i++)
3148                 {
3149                         ent = r_refdef.scene.entities[i];
3150                         if (!(ent->flags & renderimask))
3151                         if (!R_CullBox(ent->mins, ent->maxs) || (ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
3152                         if ((ent->effects & EF_NODEPTHTEST) || (ent->flags & RENDER_VIEWMODEL) || r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, ent->mins, ent->maxs))
3153                                 r_refdef.viewcache.entityvisible[i] = true;
3154                 }
3155                 if(r_cullentities_trace.integer && r_refdef.scene.worldmodel->brush.TraceLineOfSight)
3156                 {
3157                         for (i = 0;i < r_refdef.scene.numentities;i++)
3158                         {
3159                                 ent = r_refdef.scene.entities[i];
3160                                 if(r_refdef.viewcache.entityvisible[i] && !(ent->effects & EF_NODEPTHTEST) && !(ent->flags & RENDER_VIEWMODEL) && !(ent->model && (ent->model->name[0] == '*')))
3161                                 {
3162                                         if(Mod_CanSeeBox_Trace(r_cullentities_trace_samples.integer, r_cullentities_trace_enlarge.value, r_refdef.scene.worldmodel, r_refdef.view.origin, ent->mins, ent->maxs))
3163                                                 ent->last_trace_visibility = realtime;
3164                                         if(ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value)
3165                                                 r_refdef.viewcache.entityvisible[i] = 0;
3166                                 }
3167                         }
3168                 }
3169         }
3170         else
3171         {
3172                 // no worldmodel or it can't check visibility
3173                 for (i = 0;i < r_refdef.scene.numentities;i++)
3174                 {
3175                         ent = r_refdef.scene.entities[i];
3176                         r_refdef.viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs));
3177                 }
3178         }
3179 }
3180
3181 /// only used if skyrendermasked, and normally returns false
3182 int R_DrawBrushModelsSky (void)
3183 {
3184         int i, sky;
3185         entity_render_t *ent;
3186
3187         if (!r_drawentities.integer)
3188                 return false;
3189
3190         sky = false;
3191         for (i = 0;i < r_refdef.scene.numentities;i++)
3192         {
3193                 if (!r_refdef.viewcache.entityvisible[i])
3194                         continue;
3195                 ent = r_refdef.scene.entities[i];
3196                 if (!ent->model || !ent->model->DrawSky)
3197                         continue;