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