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