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