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