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