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