replaced rainsplash animation with just a single particle which expands over time...
[divverent/darkplaces.git] / gl_rmain.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20 // r_main.c
21
22 #include "quakedef.h"
23 #include "r_shadow.h"
24 #include "polygon.h"
25
26 mempool_t *r_main_mempool;
27 rtexturepool_t *r_main_texturepool;
28
29 // used for dlight push checking and other things
30 int r_framecount;
31
32 mplane_t frustum[5];
33
34 renderstats_t renderstats;
35
36 // true during envmap command capture
37 qboolean envmap;
38
39 // maximum visible distance (recalculated from world box each frame)
40 float r_farclip;
41 // brightness of world lightmaps and related lighting
42 // (often reduced when world rtlights are enabled)
43 float r_lightmapintensity;
44 // whether to draw world lights realtime, dlights realtime, and their shadows
45 qboolean r_rtworld;
46 qboolean r_rtworldshadows;
47 qboolean r_rtdlight;
48 qboolean r_rtdlightshadows;
49
50
51 // view origin
52 vec3_t r_vieworigin;
53 vec3_t r_viewforward;
54 vec3_t r_viewleft;
55 vec3_t r_viewright;
56 vec3_t r_viewup;
57 int r_view_x;
58 int r_view_y;
59 int r_view_z;
60 int r_view_width;
61 int r_view_height;
62 int r_view_depth;
63 matrix4x4_t r_view_matrix;
64 float r_polygonfactor;
65 float r_polygonoffset;
66 float r_shadowpolygonfactor;
67 float r_shadowpolygonoffset;
68 //
69 // screen size info
70 //
71 refdef_t r_refdef;
72
73 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
74 cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "shows surfaces as different colors"};
75 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
76 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
77 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"};
78 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"};
79 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
80 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"};
81 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"};
82 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\n"};
83 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
84 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
85 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
86 cvar_t r_fullbright = {0, "r_fullbright","0", "make everything bright cheat (not allowed in multiplayer)"};
87 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
88 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
89 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
90 cvar_t r_q1bsp_skymasking = {0, "r_qb1sp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
91
92 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
93 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
94 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
95 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
96 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
97 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
98 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
99
100 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of hardware texture units reported by driver (note: setting this to 1 turns off gl_combine)"};
101
102 cvar_t r_glsl = {0, "r_glsl", "1", "enables use of OpenGL 2.0 pixel shaders for lighting"};
103 cvar_t r_glsl_offsetmapping = {0, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
104 cvar_t r_glsl_offsetmapping_reliefmapping = {0, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
105 cvar_t r_glsl_offsetmapping_scale = {0, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
106 cvar_t r_glsl_deluxemapping = {0, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"};
107
108 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1", "enables animation smoothing on sprites (requires r_lerpmodels 1)"};
109 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
110 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
111
112 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
113 cvar_t r_bloom_intensity = {CVAR_SAVE, "r_bloom_intensity", "1.5", "how bright the glow is"};
114 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
115 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
116 cvar_t r_bloom_power = {CVAR_SAVE, "r_bloom_power", "2", "how much to darken the image before blurring to make the bloom effect"};
117
118 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"};
119
120 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"};
121
122 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
123
124 cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"}; // used for testing renderer code changes, otherwise does nothing
125
126 rtexture_t *r_bloom_texture_screen;
127 rtexture_t *r_bloom_texture_bloom;
128 rtexture_t *r_texture_blanknormalmap;
129 rtexture_t *r_texture_white;
130 rtexture_t *r_texture_black;
131 rtexture_t *r_texture_notexture;
132 rtexture_t *r_texture_whitecube;
133 rtexture_t *r_texture_normalizationcube;
134 rtexture_t *r_texture_fogattenuation;
135 //rtexture_t *r_texture_fogintensity;
136
137 // information about each possible shader permutation
138 r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_COUNT];
139 // currently selected permutation
140 r_glsl_permutation_t *r_glsl_permutation;
141
142 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
143 {
144         int i;
145         for (i = 0;i < verts;i++)
146         {
147                 out[0] = in[0] * r;
148                 out[1] = in[1] * g;
149                 out[2] = in[2] * b;
150                 out[3] = in[3];
151                 in += 4;
152                 out += 4;
153         }
154 }
155
156 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
157 {
158         int i;
159         for (i = 0;i < verts;i++)
160         {
161                 out[0] = r;
162                 out[1] = g;
163                 out[2] = b;
164                 out[3] = a;
165                 out += 4;
166         }
167 }
168
169 vec3_t fogcolor;
170 vec_t fogdensity;
171 vec_t fogrange;
172 vec_t fograngerecip;
173 int fogtableindex;
174 vec_t fogtabledistmultiplier;
175 float fogtable[FOGTABLEWIDTH];
176 float fog_density, fog_red, fog_green, fog_blue;
177 qboolean fogenabled;
178 qboolean oldgl_fogenable;
179 void R_UpdateFog(void)
180 {
181         if (gamemode == GAME_NEHAHRA)
182         {
183                 if (gl_fogenable.integer)
184                 {
185                         oldgl_fogenable = true;
186                         fog_density = gl_fogdensity.value;
187                         fog_red = gl_fogred.value;
188                         fog_green = gl_foggreen.value;
189                         fog_blue = gl_fogblue.value;
190                 }
191                 else if (oldgl_fogenable)
192                 {
193                         oldgl_fogenable = false;
194                         fog_density = 0;
195                         fog_red = 0;
196                         fog_green = 0;
197                         fog_blue = 0;
198                 }
199         }
200         if (fog_density)
201         {
202                 fogcolor[0] = fog_red   = bound(0.0f, fog_red  , 1.0f);
203                 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
204                 fogcolor[2] = fog_blue  = bound(0.0f, fog_blue , 1.0f);
205         }
206         if (fog_density)
207         {
208                 fogenabled = true;
209                 fogdensity = -4000.0f / (fog_density * fog_density);
210                 // this is the point where the fog reaches 0.9986 alpha, which we
211                 // consider a good enough cutoff point for the texture
212                 // (0.9986 * 256 == 255.6)
213                 fogrange = 400 / fog_density;
214                 fograngerecip = 1.0f / fogrange;
215                 fogtabledistmultiplier = FOGTABLEWIDTH * fograngerecip;
216                 // fog color was already set
217         }
218         else
219                 fogenabled = false;
220 }
221
222 // FIXME: move this to client?
223 void FOG_clear(void)
224 {
225         if (gamemode == GAME_NEHAHRA)
226         {
227                 Cvar_Set("gl_fogenable", "0");
228                 Cvar_Set("gl_fogdensity", "0.2");
229                 Cvar_Set("gl_fogred", "0.3");
230                 Cvar_Set("gl_foggreen", "0.3");
231                 Cvar_Set("gl_fogblue", "0.3");
232         }
233         fog_density = fog_red = fog_green = fog_blue = 0.0f;
234 }
235
236 // FIXME: move this to client?
237 void FOG_registercvars(void)
238 {
239         int x;
240         double r, alpha;
241
242         if (gamemode == GAME_NEHAHRA)
243         {
244                 Cvar_RegisterVariable (&gl_fogenable);
245                 Cvar_RegisterVariable (&gl_fogdensity);
246                 Cvar_RegisterVariable (&gl_fogred);
247                 Cvar_RegisterVariable (&gl_foggreen);
248                 Cvar_RegisterVariable (&gl_fogblue);
249                 Cvar_RegisterVariable (&gl_fogstart);
250                 Cvar_RegisterVariable (&gl_fogend);
251         }
252
253         r = (-1.0/256.0) * (FOGTABLEWIDTH * FOGTABLEWIDTH);
254         for (x = 0;x < FOGTABLEWIDTH;x++)
255         {
256                 alpha = exp(r / ((double)x*(double)x));
257                 if (x == FOGTABLEWIDTH - 1)
258                         alpha = 1;
259                 fogtable[x] = bound(0, alpha, 1);
260         }
261 }
262
263 static void R_BuildBlankTextures(void)
264 {
265         unsigned char data[4];
266         data[0] = 128; // normal X
267         data[1] = 128; // normal Y
268         data[2] = 255; // normal Z
269         data[3] = 128; // height
270         r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
271         data[0] = 255;
272         data[1] = 255;
273         data[2] = 255;
274         data[3] = 255;
275         r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
276         data[0] = 0;
277         data[1] = 0;
278         data[2] = 0;
279         data[3] = 255;
280         r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
281 }
282
283 static void R_BuildNoTexture(void)
284 {
285         int x, y;
286         unsigned char pix[16][16][4];
287         // this makes a light grey/dark grey checkerboard texture
288         for (y = 0;y < 16;y++)
289         {
290                 for (x = 0;x < 16;x++)
291                 {
292                         if ((y < 8) ^ (x < 8))
293                         {
294                                 pix[y][x][0] = 128;
295                                 pix[y][x][1] = 128;
296                                 pix[y][x][2] = 128;
297                                 pix[y][x][3] = 255;
298                         }
299                         else
300                         {
301                                 pix[y][x][0] = 64;
302                                 pix[y][x][1] = 64;
303                                 pix[y][x][2] = 64;
304                                 pix[y][x][3] = 255;
305                         }
306                 }
307         }
308         r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL);
309 }
310
311 static void R_BuildWhiteCube(void)
312 {
313         unsigned char data[6*1*1*4];
314         data[ 0] = 255;data[ 1] = 255;data[ 2] = 255;data[ 3] = 255;
315         data[ 4] = 255;data[ 5] = 255;data[ 6] = 255;data[ 7] = 255;
316         data[ 8] = 255;data[ 9] = 255;data[10] = 255;data[11] = 255;
317         data[12] = 255;data[13] = 255;data[14] = 255;data[15] = 255;
318         data[16] = 255;data[17] = 255;data[18] = 255;data[19] = 255;
319         data[20] = 255;data[21] = 255;data[22] = 255;data[23] = 255;
320         r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
321 }
322
323 static void R_BuildNormalizationCube(void)
324 {
325         int x, y, side;
326         vec3_t v;
327         vec_t s, t, intensity;
328 #define NORMSIZE 64
329         unsigned char data[6][NORMSIZE][NORMSIZE][4];
330         for (side = 0;side < 6;side++)
331         {
332                 for (y = 0;y < NORMSIZE;y++)
333                 {
334                         for (x = 0;x < NORMSIZE;x++)
335                         {
336                                 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
337                                 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
338                                 switch(side)
339                                 {
340                                 default:
341                                 case 0:
342                                         v[0] = 1;
343                                         v[1] = -t;
344                                         v[2] = -s;
345                                         break;
346                                 case 1:
347                                         v[0] = -1;
348                                         v[1] = -t;
349                                         v[2] = s;
350                                         break;
351                                 case 2:
352                                         v[0] = s;
353                                         v[1] = 1;
354                                         v[2] = t;
355                                         break;
356                                 case 3:
357                                         v[0] = s;
358                                         v[1] = -1;
359                                         v[2] = -t;
360                                         break;
361                                 case 4:
362                                         v[0] = s;
363                                         v[1] = -t;
364                                         v[2] = 1;
365                                         break;
366                                 case 5:
367                                         v[0] = -s;
368                                         v[1] = -t;
369                                         v[2] = -1;
370                                         break;
371                                 }
372                                 intensity = 127.0f / sqrt(DotProduct(v, v));
373                                 data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[0]);
374                                 data[side][y][x][1] = (unsigned char)(128.0f + intensity * v[1]);
375                                 data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[2]);
376                                 data[side][y][x][3] = 255;
377                         }
378                 }
379         }
380         r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
381 }
382
383 static void R_BuildFogTexture(void)
384 {
385         int x, b;
386         double r, alpha;
387 #define FOGWIDTH 64
388         unsigned char data1[FOGWIDTH][4];
389         //unsigned char data2[FOGWIDTH][4];
390         r = (-1.0/256.0) * (FOGWIDTH * FOGWIDTH);
391         for (x = 0;x < FOGWIDTH;x++)
392         {
393                 alpha = exp(r / ((double)x*(double)x));
394                 if (x == FOGWIDTH - 1)
395                         alpha = 1;
396                 b = (int)(256.0 * alpha);
397                 b = bound(0, b, 255);
398                 data1[x][0] = 255 - b;
399                 data1[x][1] = 255 - b;
400                 data1[x][2] = 255 - b;
401                 data1[x][3] = 255;
402                 //data2[x][0] = b;
403                 //data2[x][1] = b;
404                 //data2[x][2] = b;
405                 //data2[x][3] = 255;
406         }
407         r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
408         //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
409 }
410
411 static const char *builtinshaderstring =
412 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
413 "// written by Forest 'LordHavoc' Hale\n"
414 "\n"
415 "// common definitions between vertex shader and fragment shader:\n"
416 "\n"
417 "varying vec2 TexCoord;\n"
418 "varying vec2 TexCoordLightmap;\n"
419 "\n"
420 "varying vec3 CubeVector;\n"
421 "varying vec3 LightVector;\n"
422 "varying vec3 EyeVector;\n"
423 "#ifdef USEFOG\n"
424 "varying vec3 EyeVectorModelSpace;\n"
425 "#endif\n"
426 "\n"
427 "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
428 "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
429 "varying vec3 VectorR; // direction of R texcoord (surface normal)\n"
430 "\n"
431 "\n"
432 "\n"
433 "\n"
434 "// vertex shader specific:\n"
435 "#ifdef VERTEX_SHADER\n"
436 "\n"
437 "uniform vec3 LightPosition;\n"
438 "uniform vec3 EyePosition;\n"
439 "uniform vec3 LightDir;\n"
440 "\n"
441 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3)\n"
442 "\n"
443 "void main(void)\n"
444 "{\n"
445 "       gl_FrontColor = gl_Color;\n"
446 "       // copy the surface texcoord\n"
447 "       TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n"
448 "#if !defined(MODE_LIGHTSOURCE) && !defined(MODE_LIGHTDIRECTION)\n"
449 "       TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
450 "#endif\n"
451 "\n"
452 "#ifdef MODE_LIGHTSOURCE\n"
453 "       // transform vertex position into light attenuation/cubemap space\n"
454 "       // (-1 to +1 across the light box)\n"
455 "       CubeVector = vec3(gl_TextureMatrix[3] * gl_Vertex);\n"
456 "\n"
457 "       // transform unnormalized light direction into tangent space\n"
458 "       // (we use unnormalized to ensure that it interpolates correctly and then\n"
459 "       //  normalize it per pixel)\n"
460 "       vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
461 "       LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
462 "       LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
463 "       LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
464 "#endif\n"
465 "\n"
466 "#ifdef MODE_LIGHTDIRECTION\n"
467 "       LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
468 "       LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
469 "       LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
470 "#endif\n"
471 "\n"
472 "       // transform unnormalized eye direction into tangent space\n"
473 "#ifndef USEFOG\n"
474 "       vec3 EyeVectorModelSpace;\n"
475 "#endif\n"
476 "       EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
477 "       EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
478 "       EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
479 "       EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
480 "\n"
481 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
482 "       VectorS = gl_MultiTexCoord1.xyz;\n"
483 "       VectorT = gl_MultiTexCoord2.xyz;\n"
484 "       VectorR = gl_MultiTexCoord3.xyz;\n"
485 "#endif\n"
486 "\n"
487 "       // transform vertex to camera space, using ftransform to match non-VS\n"
488 "       // rendering\n"
489 "       gl_Position = ftransform();\n"
490 "}\n"
491 "\n"
492 "#endif // VERTEX_SHADER\n"
493 "\n"
494 "\n"
495 "\n"
496 "\n"
497 "// fragment shader specific:\n"
498 "#ifdef FRAGMENT_SHADER\n"
499 "\n"
500 "uniform sampler2D Texture_Normal;\n"
501 "uniform sampler2D Texture_Color;\n"
502 "uniform sampler2D Texture_Gloss;\n"
503 "uniform samplerCube Texture_Cube;\n"
504 "uniform sampler2D Texture_FogMask;\n"
505 "uniform sampler2D Texture_Pants;\n"
506 "uniform sampler2D Texture_Shirt;\n"
507 "uniform sampler2D Texture_Lightmap;\n"
508 "uniform sampler2D Texture_Deluxemap;\n"
509 "uniform sampler2D Texture_Glow;\n"
510 "\n"
511 "uniform vec3 LightColor;\n"
512 "uniform vec3 AmbientColor;\n"
513 "uniform vec3 DiffuseColor;\n"
514 "uniform vec3 SpecularColor;\n"
515 "uniform vec3 Color_Pants;\n"
516 "uniform vec3 Color_Shirt;\n"
517 "uniform vec3 FogColor;\n"
518 "\n"
519 "uniform float OffsetMapping_Scale;\n"
520 "uniform float OffsetMapping_Bias;\n"
521 "uniform float FogRangeRecip;\n"
522 "\n"
523 "uniform float AmbientScale;\n"
524 "uniform float DiffuseScale;\n"
525 "uniform float SpecularScale;\n"
526 "uniform float SpecularPower;\n"
527 "\n"
528 "void main(void)\n"
529 "{\n"
530 "       // apply offsetmapping\n"
531 "#ifdef USEOFFSETMAPPING\n"
532 "       vec2 TexCoordOffset = TexCoord;\n"
533 "#define TexCoord TexCoordOffset\n"
534 "\n"
535 "       vec3 eyedir = vec3(normalize(EyeVector));\n"
536 "       float depthbias = 1.0 - eyedir.z; // should this be a -?\n"
537 "       depthbias = 1.0 - depthbias * depthbias;\n"
538 "\n"
539 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
540 "       // 14 sample relief mapping: linear search and then binary search\n"
541 "       vec3 OffsetVector = vec3(EyeVector.xy * (1.0 / EyeVector.z) * depthbias * OffsetMapping_Scale * vec2(-0.1, 0.1), -0.1);\n"
542 "       vec3 RT = vec3(TexCoord - OffsetVector.xy * 10.0, 1.0) + OffsetVector;\n"
543 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
544 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
545 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
546 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
547 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
548 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
549 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
550 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
551 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
552 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
553 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
554 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
555 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
556 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
557 "       TexCoord = RT.xy;\n"
558 "#else\n"
559 "       // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
560 "       vec2 OffsetVector = vec2((EyeVector.xy * (1.0 / EyeVector.z) * depthbias) * OffsetMapping_Scale * vec2(-0.333, 0.333));\n"
561 "       //TexCoord += OffsetVector * 3.0;\n"
562 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
563 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
564 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
565 "#endif\n"
566 "#endif\n"
567 "\n"
568 "       // combine the diffuse textures (base, pants, shirt)\n"
569 "       vec4 color = vec4(texture2D(Texture_Color, TexCoord));\n"
570 "#ifdef USECOLORMAPPING\n"
571 "       color.rgb += vec3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + vec3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
572 "#endif\n"
573 "\n"
574 "\n"
575 "\n"
576 "\n"
577 "#ifdef MODE_LIGHTSOURCE\n"
578 "       // light source\n"
579 "\n"
580 "       // get the surface normal and light normal\n"
581 "       vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
582 "       vec3 diffusenormal = vec3(normalize(LightVector));\n"
583 "\n"
584 "       // calculate directional shading\n"
585 "       color.rgb *= (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
586 "#ifdef USESPECULAR\n"
587 "       vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
588 "       color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
589 "#endif\n"
590 "\n"
591 "#ifdef USECUBEFILTER\n"
592 "       // apply light cubemap filter\n"
593 "       //color.rgb *= normalize(CubeVector) * 0.5 + 0.5;//vec3(textureCube(Texture_Cube, CubeVector));\n"
594 "       color.rgb *= vec3(textureCube(Texture_Cube, CubeVector));\n"
595 "#endif\n"
596 "\n"
597 "       // apply light color\n"
598 "       color.rgb *= LightColor;\n"
599 "\n"
600 "       // apply attenuation\n"
601 "       //\n"
602 "       // the attenuation is (1-(x*x+y*y+z*z)) which gives a large bright\n"
603 "       // center and sharp falloff at the edge, this is about the most efficient\n"
604 "       // we can get away with as far as providing illumination.\n"
605 "       //\n"
606 "       // pow(1-(x*x+y*y+z*z), 4) is far more realistic but needs large lights to\n"
607 "       // provide significant illumination, large = slow = pain.\n"
608 "       color.rgb *= max(1.0 - dot(CubeVector, CubeVector), 0.0);\n"
609 "\n"
610 "\n"
611 "\n"
612 "\n"
613 "#elif defined(MODE_LIGHTDIRECTION)\n"
614 "       // directional model lighting\n"
615 "\n"
616 "       // get the surface normal and light normal\n"
617 "       vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
618 "       vec3 diffusenormal = vec3(normalize(LightVector));\n"
619 "\n"
620 "       // calculate directional shading\n"
621 "       color.rgb *= AmbientColor + DiffuseColor * max(dot(surfacenormal, diffusenormal), 0.0);\n"
622 "#ifdef USESPECULAR\n"
623 "       vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
624 "       color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
625 "#endif\n"
626 "\n"
627 "\n"
628 "\n"
629 "\n"
630 "#elif defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE)\n"
631 "       // deluxemap lightmapping using light vectors in modelspace (evil q3map2)\n"
632 "\n"
633 "       // get the surface normal and light normal\n"
634 "       vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
635 "       vec3 diffusenormal_modelspace = vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5;\n"
636 "       vec3 diffusenormal = normalize(vec3(dot(diffusenormal_modelspace, VectorS), dot(diffusenormal_modelspace, VectorT), dot(diffusenormal_modelspace, VectorR)));\n"
637 "\n"
638 "       // calculate directional shading\n"
639 "       vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
640 "#ifdef USESPECULAR\n"
641 "       vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
642 "       tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
643 "#endif\n"
644 "\n"
645 "       // apply lightmap color\n"
646 "       color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n"
647 "\n"
648 "\n"
649 "\n"
650 "\n"
651 "#elif defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
652 "       // deluxemap lightmapping using light vectors in tangentspace\n"
653 "\n"
654 "       // get the surface normal and light normal\n"
655 "       vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
656 "       vec3 diffusenormal = normalize(vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5);\n"
657 "\n"
658 "       // calculate directional shading\n"
659 "       vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
660 "#ifdef USESPECULAR\n"
661 "       vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
662 "       tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
663 "#endif\n"
664 "\n"
665 "       // apply lightmap color\n"
666 "       color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n"
667 "\n"
668 "\n"
669 "\n"
670 "\n"
671 "#else // MODE none (lightmap)\n"
672 "       // apply lightmap color\n"
673 "       color.rgb *= vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + vec3(AmbientScale);\n"
674 "#endif // MODE\n"
675 "\n"
676 "       color *= gl_Color;\n"
677 "\n"
678 "#ifdef USEGLOW\n"
679 "       color.rgb += vec3(texture2D(Texture_Glow, TexCoord));\n"
680 "#endif\n"
681 "\n"
682 "#ifdef USEFOG\n"
683 "       // apply fog\n"
684 "       float fog = texture2D(Texture_FogMask, vec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0)).x;\n"
685 "       color.rgb = color.rgb * fog + FogColor * (1.0 - fog);\n"
686 "#endif\n"
687 "\n"
688 "       gl_FragColor = color;\n"
689 "}\n"
690 "\n"
691 "#endif // FRAGMENT_SHADER\n"
692 ;
693
694 void R_GLSL_CompilePermutation(int permutation)
695 {
696         r_glsl_permutation_t *p = r_glsl_permutations + permutation;
697         int vertstrings_count;
698         int fragstrings_count;
699         char *shaderstring;
700         const char *vertstrings_list[SHADERPERMUTATION_COUNT+1];
701         const char *fragstrings_list[SHADERPERMUTATION_COUNT+1];
702         char permutationname[256];
703         if (p->compiled)
704                 return;
705         p->compiled = true;
706         vertstrings_list[0] = "#define VERTEX_SHADER\n";
707         fragstrings_list[0] = "#define FRAGMENT_SHADER\n";
708         vertstrings_count = 1;
709         fragstrings_count = 1;
710         permutationname[0] = 0;
711         if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
712         {
713                 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTSOURCE\n";
714                 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTSOURCE\n";
715                 strlcat(permutationname, " lightsource", sizeof(permutationname));
716         }
717         if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE)
718         {
719                 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n";
720                 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n";
721                 strlcat(permutationname, " lightdirectionmap_modelspace", sizeof(permutationname));
722         }
723         if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)
724         {
725                 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n";
726                 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n";
727                 strlcat(permutationname, " lightdirectionmap_tangentspace", sizeof(permutationname));
728         }
729         if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
730         {
731                 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
732                 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
733                 strlcat(permutationname, " lightdirection", sizeof(permutationname));
734         }
735         if (permutation & SHADERPERMUTATION_GLOW)
736         {
737                 vertstrings_list[vertstrings_count++] = "#define USEGLOW\n";
738                 fragstrings_list[fragstrings_count++] = "#define USEGLOW\n";
739                 strlcat(permutationname, " glow", sizeof(permutationname));
740         }
741         if (permutation & SHADERPERMUTATION_COLORMAPPING)
742         {
743                 vertstrings_list[vertstrings_count++] = "#define USECOLORMAPPING\n";
744                 fragstrings_list[fragstrings_count++] = "#define USECOLORMAPPING\n";
745                 strlcat(permutationname, " colormapping", sizeof(permutationname));
746         }
747         if (permutation & SHADERPERMUTATION_SPECULAR)
748         {
749                 vertstrings_list[vertstrings_count++] = "#define USESPECULAR\n";
750                 fragstrings_list[fragstrings_count++] = "#define USESPECULAR\n";
751                 strlcat(permutationname, " specular", sizeof(permutationname));
752         }
753         if (permutation & SHADERPERMUTATION_FOG)
754         {
755                 vertstrings_list[vertstrings_count++] = "#define USEFOG\n";
756                 fragstrings_list[fragstrings_count++] = "#define USEFOG\n";
757                 strlcat(permutationname, " fog", sizeof(permutationname));
758         }
759         if (permutation & SHADERPERMUTATION_CUBEFILTER)
760         {
761                 vertstrings_list[vertstrings_count++] = "#define USECUBEFILTER\n";
762                 fragstrings_list[fragstrings_count++] = "#define USECUBEFILTER\n";
763                 strlcat(permutationname, " cubefilter", sizeof(permutationname));
764         }
765         if (permutation & SHADERPERMUTATION_OFFSETMAPPING)
766         {
767                 vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING\n";
768                 fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING\n";
769                 strlcat(permutationname, " offsetmapping", sizeof(permutationname));
770         }
771         if (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING)
772         {
773                 vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n";
774                 fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n";
775                 strlcat(permutationname, " OFFSETMAPPING_RELIEFMAPPING", sizeof(permutationname));
776         }
777         shaderstring = (char *)FS_LoadFile("glsl/default.glsl", r_main_mempool, false, NULL);
778         if (shaderstring)
779         {
780                 Con_DPrintf("GLSL shader text loaded from disk\n");
781                 vertstrings_list[vertstrings_count++] = shaderstring;
782                 fragstrings_list[fragstrings_count++] = shaderstring;
783         }
784         else
785         {
786                 vertstrings_list[vertstrings_count++] = builtinshaderstring;
787                 fragstrings_list[fragstrings_count++] = builtinshaderstring;
788         }
789         p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list);
790         if (p->program)
791         {
792                 CHECKGLERROR
793                 qglUseProgramObjectARB(p->program);
794                 p->loc_Texture_Normal      = qglGetUniformLocationARB(p->program, "Texture_Normal");
795                 p->loc_Texture_Color       = qglGetUniformLocationARB(p->program, "Texture_Color");
796                 p->loc_Texture_Gloss       = qglGetUniformLocationARB(p->program, "Texture_Gloss");
797                 p->loc_Texture_Cube        = qglGetUniformLocationARB(p->program, "Texture_Cube");
798                 p->loc_Texture_FogMask     = qglGetUniformLocationARB(p->program, "Texture_FogMask");
799                 p->loc_Texture_Pants       = qglGetUniformLocationARB(p->program, "Texture_Pants");
800                 p->loc_Texture_Shirt       = qglGetUniformLocationARB(p->program, "Texture_Shirt");
801                 p->loc_Texture_Lightmap    = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
802                 p->loc_Texture_Deluxemap   = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
803                 p->loc_Texture_Glow        = qglGetUniformLocationARB(p->program, "Texture_Glow");
804                 p->loc_FogColor            = qglGetUniformLocationARB(p->program, "FogColor");
805                 p->loc_LightPosition       = qglGetUniformLocationARB(p->program, "LightPosition");
806                 p->loc_EyePosition         = qglGetUniformLocationARB(p->program, "EyePosition");
807                 p->loc_LightColor          = qglGetUniformLocationARB(p->program, "LightColor");
808                 p->loc_Color_Pants         = qglGetUniformLocationARB(p->program, "Color_Pants");
809                 p->loc_Color_Shirt         = qglGetUniformLocationARB(p->program, "Color_Shirt");
810                 p->loc_FogRangeRecip       = qglGetUniformLocationARB(p->program, "FogRangeRecip");
811                 p->loc_AmbientScale        = qglGetUniformLocationARB(p->program, "AmbientScale");
812                 p->loc_DiffuseScale        = qglGetUniformLocationARB(p->program, "DiffuseScale");
813                 p->loc_SpecularPower       = qglGetUniformLocationARB(p->program, "SpecularPower");
814                 p->loc_SpecularScale       = qglGetUniformLocationARB(p->program, "SpecularScale");
815                 p->loc_OffsetMapping_Scale = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
816                 p->loc_AmbientColor        = qglGetUniformLocationARB(p->program, "AmbientColor");
817                 p->loc_DiffuseColor        = qglGetUniformLocationARB(p->program, "DiffuseColor");
818                 p->loc_SpecularColor       = qglGetUniformLocationARB(p->program, "SpecularColor");
819                 p->loc_LightDir            = qglGetUniformLocationARB(p->program, "LightDir");
820                 if (p->loc_Texture_Normal >= 0)    qglUniform1iARB(p->loc_Texture_Normal, 0);
821                 if (p->loc_Texture_Color >= 0)     qglUniform1iARB(p->loc_Texture_Color, 1);
822                 if (p->loc_Texture_Gloss >= 0)     qglUniform1iARB(p->loc_Texture_Gloss, 2);
823                 if (p->loc_Texture_Cube >= 0)      qglUniform1iARB(p->loc_Texture_Cube, 3);
824                 if (p->loc_Texture_FogMask >= 0)   qglUniform1iARB(p->loc_Texture_FogMask, 4);
825                 if (p->loc_Texture_Pants >= 0)     qglUniform1iARB(p->loc_Texture_Pants, 5);
826                 if (p->loc_Texture_Shirt >= 0)     qglUniform1iARB(p->loc_Texture_Shirt, 6);
827                 if (p->loc_Texture_Lightmap >= 0)  qglUniform1iARB(p->loc_Texture_Lightmap, 7);
828                 if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap, 8);
829                 if (p->loc_Texture_Glow >= 0)      qglUniform1iARB(p->loc_Texture_Glow, 9);
830                 qglUseProgramObjectARB(0);
831                 CHECKGLERROR
832         }
833         else
834                 Con_Printf("permutation%s failed for shader %s, some features may not work properly!\n", permutationname, "glsl/default.glsl");
835         if (shaderstring)
836                 Mem_Free(shaderstring);
837 }
838
839 void R_GLSL_Restart_f(void)
840 {
841         int i;
842         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
843                 if (r_glsl_permutations[i].program)
844                         GL_Backend_FreeProgram(r_glsl_permutations[i].program);
845         memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
846 }
847
848 int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting)
849 {
850         // select a permutation of the lighting shader appropriate to this
851         // combination of texture, entity, light source, and fogging, only use the
852         // minimum features necessary to avoid wasting rendering time in the
853         // fragment shader on features that are not being used
854         int permutation = 0;
855         float specularscale = rsurface_texture->specularscale;
856         r_glsl_permutation = NULL;
857         if (r_shadow_rtlight)
858         {
859                 permutation |= SHADERPERMUTATION_MODE_LIGHTSOURCE;
860                 specularscale *= r_shadow_rtlight->specularscale;
861                 if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
862                         permutation |= SHADERPERMUTATION_CUBEFILTER;
863         }
864         else
865         {
866                 if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
867                 {
868                         if (modellighting)
869                                 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
870                         else
871                         {
872                                 if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && rsurface_lightmaptexture)
873                                 {
874                                         if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
875                                                 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
876                                         else
877                                                 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
878                                 }
879                                 else if (r_glsl_deluxemapping.integer >= 2) // fake mode
880                                         permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
881                         }
882                 }
883                 if (rsurface_texture->skin.glow)
884                         permutation |= SHADERPERMUTATION_GLOW;
885         }
886         if (specularscale > 0)
887                 permutation |= SHADERPERMUTATION_SPECULAR;
888         if (fogenabled)
889                 permutation |= SHADERPERMUTATION_FOG;
890         if (rsurface_texture->colormapping)
891                 permutation |= SHADERPERMUTATION_COLORMAPPING;
892         if (r_glsl_offsetmapping.integer)
893         {
894                 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
895                 if (r_glsl_offsetmapping_reliefmapping.integer)
896                         permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
897         }
898         if (!r_glsl_permutations[permutation].program)
899         {
900                 if (!r_glsl_permutations[permutation].compiled)
901                         R_GLSL_CompilePermutation(permutation);
902                 if (!r_glsl_permutations[permutation].program)
903                 {
904                         // remove features until we find a valid permutation
905                         int i;
906                         for (i = SHADERPERMUTATION_COUNT-1;;i>>=1)
907                         {
908                                 // reduce i more quickly whenever it would not remove any bits
909                                 if (permutation < i)
910                                         continue;
911                                 permutation &= i;
912                                 if (!r_glsl_permutations[permutation].compiled)
913                                         R_GLSL_CompilePermutation(permutation);
914                                 if (r_glsl_permutations[permutation].program)
915                                         break;
916                                 if (!i)
917                                         return 0; // utterly failed
918                         }
919                 }
920         }
921         r_glsl_permutation = r_glsl_permutations + permutation;
922         CHECKGLERROR
923         qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
924         R_Mesh_TexMatrix(0, &rsurface_texture->currenttexmatrix);
925         if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
926         {
927                 if (r_glsl_permutation->loc_Texture_Cube >= 0 && r_shadow_rtlight) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap));
928                 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, r_shadow_entitylightorigin[0], r_shadow_entitylightorigin[1], r_shadow_entitylightorigin[2]);
929                 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
930                 if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_shadow_rtlight->ambientscale);
931                 if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_shadow_rtlight->diffusescale);
932                 if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale);
933         }
934         else if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
935         {
936                 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
937                 {
938                         if (r_glsl_permutation->loc_AmbientColor >= 0)
939                                 qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, 1, 1, 1);
940                         if (r_glsl_permutation->loc_DiffuseColor >= 0)
941                                 qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, 0, 0, 0);
942                         if (r_glsl_permutation->loc_SpecularColor >= 0)
943                                 qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, 0, 0, 0);
944                         if (r_glsl_permutation->loc_LightDir >= 0)
945                                 qglUniform3fARB(r_glsl_permutation->loc_LightDir, 0, 0, -1);
946                 }
947                 else
948                 {
949                         if (r_glsl_permutation->loc_AmbientColor >= 0)
950                                 qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, rsurface_entity->modellight_ambient[0], rsurface_entity->modellight_ambient[1], rsurface_entity->modellight_ambient[2]);
951                         if (r_glsl_permutation->loc_DiffuseColor >= 0)
952                                 qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, rsurface_entity->modellight_diffuse[0], rsurface_entity->modellight_diffuse[1], rsurface_entity->modellight_diffuse[2]);
953                         if (r_glsl_permutation->loc_SpecularColor >= 0)
954                                 qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, rsurface_entity->modellight_diffuse[0] * rsurface_texture->specularscale, rsurface_entity->modellight_diffuse[1] * rsurface_texture->specularscale, rsurface_entity->modellight_diffuse[2] * rsurface_texture->specularscale);
955                         if (r_glsl_permutation->loc_LightDir >= 0)
956                                 qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface_entity->modellight_lightdir[0], rsurface_entity->modellight_lightdir[1], rsurface_entity->modellight_lightdir[2]);
957                 }
958         }
959         else
960         {
961                 if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 2.0f / 128.0f);
962                 if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_lightmapintensity * 2.0f);
963                 if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_lightmapintensity * specularscale * 2.0f);
964         }
965         if (r_glsl_permutation->loc_Texture_Normal >= 0) R_Mesh_TexBind(0, R_GetTexture(rsurface_texture->skin.nmap));
966         if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(1, R_GetTexture(rsurface_texture->basetexture));
967         if (r_glsl_permutation->loc_Texture_Gloss >= 0) R_Mesh_TexBind(2, R_GetTexture(rsurface_texture->glosstexture));
968         //if (r_glsl_permutation->loc_Texture_Cube >= 0 && permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap));
969         if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
970         if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(5, R_GetTexture(rsurface_texture->skin.pants));
971         if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(6, R_GetTexture(rsurface_texture->skin.shirt));
972         //if (r_glsl_permutation->loc_Texture_Lightmap >= 0) R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
973         //if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
974         if (r_glsl_permutation->loc_Texture_Glow >= 0) R_Mesh_TexBind(9, R_GetTexture(rsurface_texture->skin.glow));
975         if (r_glsl_permutation->loc_FogColor >= 0)
976         {
977                 // additive passes are only darkened by fog, not tinted
978                 if (r_shadow_rtlight || (rsurface_texture->currentmaterialflags & MATERIALFLAG_ADD))
979                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
980                 else
981                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, fogcolor[0], fogcolor[1], fogcolor[2]);
982         }
983         if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface_modelorg[0], rsurface_modelorg[1], rsurface_modelorg[2]);
984         if (r_glsl_permutation->loc_Color_Pants >= 0)
985         {
986                 if (rsurface_texture->skin.pants)
987                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, rsurface_entity->colormap_pantscolor[0], rsurface_entity->colormap_pantscolor[1], rsurface_entity->colormap_pantscolor[2]);
988                 else
989                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
990         }
991         if (r_glsl_permutation->loc_Color_Shirt >= 0)
992         {
993                 if (rsurface_texture->skin.shirt)
994                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, rsurface_entity->colormap_shirtcolor[0], rsurface_entity->colormap_shirtcolor[1], rsurface_entity->colormap_shirtcolor[2]);
995                 else
996                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
997         }
998         if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, fograngerecip);
999         if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface_texture->specularpower);
1000         if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
1001         CHECKGLERROR
1002         return permutation;
1003 }
1004
1005 void R_SwitchSurfaceShader(int permutation)
1006 {
1007         if (r_glsl_permutation != r_glsl_permutations + permutation)
1008         {
1009                 r_glsl_permutation = r_glsl_permutations + permutation;
1010                 CHECKGLERROR
1011                 qglUseProgramObjectARB(r_glsl_permutation->program);
1012                 CHECKGLERROR
1013         }
1014 }
1015
1016 void gl_main_start(void)
1017 {
1018         r_main_texturepool = R_AllocTexturePool();
1019         r_bloom_texture_screen = NULL;
1020         r_bloom_texture_bloom = NULL;
1021         R_BuildBlankTextures();
1022         R_BuildNoTexture();
1023         if (gl_texturecubemap)
1024         {
1025                 R_BuildWhiteCube();
1026                 R_BuildNormalizationCube();
1027         }
1028         R_BuildFogTexture();
1029         memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
1030 }
1031
1032 void gl_main_shutdown(void)
1033 {
1034         R_FreeTexturePool(&r_main_texturepool);
1035         r_bloom_texture_screen = NULL;
1036         r_bloom_texture_bloom = NULL;
1037         r_texture_blanknormalmap = NULL;
1038         r_texture_white = NULL;
1039         r_texture_black = NULL;
1040         r_texture_whitecube = NULL;
1041         r_texture_normalizationcube = NULL;
1042         R_GLSL_Restart_f();
1043 }
1044
1045 extern void CL_ParseEntityLump(char *entitystring);
1046 void gl_main_newmap(void)
1047 {
1048         // FIXME: move this code to client
1049         int l;
1050         char *entities, entname[MAX_QPATH];
1051         r_framecount = 1;
1052         if (cl.worldmodel)
1053         {
1054                 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
1055                 l = (int)strlen(entname) - 4;
1056                 if (l >= 0 && !strcmp(entname + l, ".bsp"))
1057                 {
1058                         strcpy(entname + l, ".ent");
1059                         if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
1060                         {
1061                                 CL_ParseEntityLump(entities);
1062                                 Mem_Free(entities);
1063                                 return;
1064                         }
1065                 }
1066                 if (cl.worldmodel->brush.entities)
1067                         CL_ParseEntityLump(cl.worldmodel->brush.entities);
1068         }
1069 }
1070
1071 void GL_Main_Init(void)
1072 {
1073         r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
1074
1075         Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed\n");
1076         FOG_registercvars(); // FIXME: move this fog stuff to client?
1077         Cvar_RegisterVariable(&r_nearclip);
1078         Cvar_RegisterVariable(&r_showsurfaces);
1079         Cvar_RegisterVariable(&r_showtris);
1080         Cvar_RegisterVariable(&r_shownormals);
1081         Cvar_RegisterVariable(&r_showlighting);
1082         Cvar_RegisterVariable(&r_showshadowvolumes);
1083         Cvar_RegisterVariable(&r_showcollisionbrushes);
1084         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor);
1085         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset);
1086         Cvar_RegisterVariable(&r_showdisabledepthtest);
1087         Cvar_RegisterVariable(&r_drawentities);
1088         Cvar_RegisterVariable(&r_drawviewmodel);
1089         Cvar_RegisterVariable(&r_speeds);
1090         Cvar_RegisterVariable(&r_fullbrights);
1091         Cvar_RegisterVariable(&r_wateralpha);
1092         Cvar_RegisterVariable(&r_dynamic);
1093         Cvar_RegisterVariable(&r_fullbright);
1094         Cvar_RegisterVariable(&r_q1bsp_skymasking);
1095         Cvar_RegisterVariable(&r_textureunits);
1096         Cvar_RegisterVariable(&r_glsl);
1097         Cvar_RegisterVariable(&r_glsl_offsetmapping);
1098         Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
1099         Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
1100         Cvar_RegisterVariable(&r_glsl_deluxemapping);
1101         Cvar_RegisterVariable(&r_lerpsprites);
1102         Cvar_RegisterVariable(&r_lerpmodels);
1103         Cvar_RegisterVariable(&r_waterscroll);
1104         Cvar_RegisterVariable(&r_bloom);
1105         Cvar_RegisterVariable(&r_bloom_intensity);
1106         Cvar_RegisterVariable(&r_bloom_blur);
1107         Cvar_RegisterVariable(&r_bloom_resolution);
1108         Cvar_RegisterVariable(&r_bloom_power);
1109         Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
1110         Cvar_RegisterVariable(&developer_texturelogging);
1111         Cvar_RegisterVariable(&gl_lightmaps);
1112         Cvar_RegisterVariable(&r_test);
1113         if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
1114                 Cvar_SetValue("r_fullbrights", 0);
1115         R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
1116 }
1117
1118 static vec3_t r_farclip_origin;
1119 static vec3_t r_farclip_direction;
1120 static vec_t r_farclip_directiondist;
1121 static vec_t r_farclip_meshfarclip;
1122 static int r_farclip_directionbit0;
1123 static int r_farclip_directionbit1;
1124 static int r_farclip_directionbit2;
1125
1126 // enlarge farclip to accomodate box
1127 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
1128 {
1129         float d;
1130         d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
1131           + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
1132           + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
1133         if (r_farclip_meshfarclip < d)
1134                 r_farclip_meshfarclip = d;
1135 }
1136
1137 // return farclip value
1138 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
1139 {
1140         int i;
1141
1142         VectorCopy(origin, r_farclip_origin);
1143         VectorCopy(direction, r_farclip_direction);
1144         r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
1145         r_farclip_directionbit0 = r_farclip_direction[0] < 0;
1146         r_farclip_directionbit1 = r_farclip_direction[1] < 0;
1147         r_farclip_directionbit2 = r_farclip_direction[2] < 0;
1148         r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
1149
1150         if (r_refdef.worldmodel)
1151                 R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
1152         for (i = 0;i < r_refdef.numentities;i++)
1153                 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
1154
1155         return r_farclip_meshfarclip - r_farclip_directiondist;
1156 }
1157
1158 extern void R_Textures_Init(void);
1159 extern void GL_Draw_Init(void);
1160 extern void GL_Main_Init(void);
1161 extern void R_Shadow_Init(void);
1162 extern void R_Sky_Init(void);
1163 extern void GL_Surf_Init(void);
1164 extern void R_Crosshairs_Init(void);
1165 extern void R_Light_Init(void);
1166 extern void R_Particles_Init(void);
1167 extern void R_Explosion_Init(void);
1168 extern void gl_backend_init(void);
1169 extern void Sbar_Init(void);
1170 extern void R_LightningBeams_Init(void);
1171 extern void Mod_RenderInit(void);
1172
1173 void Render_Init(void)
1174 {
1175         gl_backend_init();
1176         R_Textures_Init();
1177         R_MeshQueue_Init();
1178         GL_Main_Init();
1179         GL_Draw_Init();
1180         R_Shadow_Init();
1181         R_Sky_Init();
1182         GL_Surf_Init();
1183         R_Crosshairs_Init();
1184         R_Light_Init();
1185         R_Particles_Init();
1186         R_Explosion_Init();
1187         Sbar_Init();
1188         R_LightningBeams_Init();
1189         Mod_RenderInit();
1190 }
1191
1192 /*
1193 ===============
1194 GL_Init
1195 ===============
1196 */
1197 extern char *ENGINE_EXTENSIONS;
1198 void GL_Init (void)
1199 {
1200         VID_CheckExtensions();
1201
1202         // LordHavoc: report supported extensions
1203         Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions );
1204
1205         // clear to black (loading plaque will be seen over this)
1206         qglClearColor(0,0,0,1);
1207         qglClear(GL_COLOR_BUFFER_BIT);
1208 }
1209
1210 int R_CullBox(const vec3_t mins, const vec3_t maxs)
1211 {
1212         int i;
1213         mplane_t *p;
1214         for (i = 0;i < 4;i++)
1215         {
1216                 p = frustum + i;
1217                 switch(p->signbits)
1218                 {
1219                 default:
1220                 case 0:
1221                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1222                                 return true;
1223                         break;
1224                 case 1:
1225                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1226                                 return true;
1227                         break;
1228                 case 2:
1229                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1230                                 return true;
1231                         break;
1232                 case 3:
1233                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1234                                 return true;
1235                         break;
1236                 case 4:
1237                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1238                                 return true;
1239                         break;
1240                 case 5:
1241                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1242                                 return true;
1243                         break;
1244                 case 6:
1245                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1246                                 return true;
1247                         break;
1248                 case 7:
1249                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1250                                 return true;
1251                         break;
1252                 }
1253         }
1254         return false;
1255 }
1256
1257 //==================================================================================
1258
1259 static void R_UpdateEntityLighting(entity_render_t *ent)
1260 {
1261         vec3_t tempdiffusenormal;
1262         VectorSet(ent->modellight_ambient, r_ambient.value * (2.0f / 128.0f), r_ambient.value * (2.0f / 128.0f), r_ambient.value * (2.0f / 128.0f));
1263         VectorClear(ent->modellight_diffuse);
1264         VectorClear(ent->modellight_lightdir);
1265         if ((ent->flags & RENDER_LIGHT) && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
1266                 r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, ent->origin, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
1267         else // highly rare
1268                 VectorSet(ent->modellight_ambient, 1, 1, 1);
1269         Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
1270         VectorNormalize(ent->modellight_lightdir);
1271         ent->modellight_ambient[0] *= ent->colormod[0] * r_lightmapintensity;
1272         ent->modellight_ambient[1] *= ent->colormod[1] * r_lightmapintensity;
1273         ent->modellight_ambient[2] *= ent->colormod[2] * r_lightmapintensity;
1274         ent->modellight_diffuse[0] *= ent->colormod[0] * r_lightmapintensity;
1275         ent->modellight_diffuse[1] *= ent->colormod[1] * r_lightmapintensity;
1276         ent->modellight_diffuse[2] *= ent->colormod[2] * r_lightmapintensity;
1277 }
1278
1279 static void R_MarkEntities (void)
1280 {
1281         int i, renderimask;
1282         entity_render_t *ent;
1283
1284         if (!r_drawentities.integer)
1285                 return;
1286
1287         r_refdef.worldentity->visframe = r_framecount;
1288         renderimask = envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL);
1289         if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
1290         {
1291                 // worldmodel can check visibility
1292                 for (i = 0;i < r_refdef.numentities;i++)
1293                 {
1294                         ent = r_refdef.entities[i];
1295                         // some of the renderer still relies on origin...
1296                         Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1297                         // some of the renderer still relies on scale...
1298                         ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1299                         if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && ((ent->effects & EF_NODEPTHTEST) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_worldleafvisible, ent->mins, ent->maxs)))
1300                         {
1301                                 ent->visframe = r_framecount;
1302                                 R_UpdateEntityLighting(ent);
1303                         }
1304                 }
1305         }
1306         else
1307         {
1308                 // no worldmodel or it can't check visibility
1309                 for (i = 0;i < r_refdef.numentities;i++)
1310                 {
1311                         ent = r_refdef.entities[i];
1312                         // some of the renderer still relies on origin...
1313                         Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1314                         // some of the renderer still relies on scale...
1315                         ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1316                         if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST))
1317                         {
1318                                 ent->visframe = r_framecount;
1319                                 R_UpdateEntityLighting(ent);
1320                         }
1321                 }
1322         }
1323 }
1324
1325 // only used if skyrendermasked, and normally returns false
1326 int R_DrawBrushModelsSky (void)
1327 {
1328         int i, sky;
1329         entity_render_t *ent;
1330
1331         if (!r_drawentities.integer)
1332                 return false;
1333
1334         sky = false;
1335         for (i = 0;i < r_refdef.numentities;i++)
1336         {
1337                 ent = r_refdef.entities[i];
1338                 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
1339                 {
1340                         ent->model->DrawSky(ent);
1341                         sky = true;
1342                 }
1343         }
1344         return sky;
1345 }
1346
1347 void R_DrawNoModel(entity_render_t *ent);
1348 void R_DrawModels(void)
1349 {
1350         int i;
1351         entity_render_t *ent;
1352
1353         if (!r_drawentities.integer)
1354                 return;
1355
1356         for (i = 0;i < r_refdef.numentities;i++)
1357         {
1358                 ent = r_refdef.entities[i];
1359                 if (ent->visframe == r_framecount)
1360                 {
1361                         renderstats.entities++;
1362                         if (ent->model && ent->model->Draw != NULL)
1363                                 ent->model->Draw(ent);
1364                         else
1365                                 R_DrawNoModel(ent);
1366                 }
1367         }
1368 }
1369
1370 static void R_SetFrustum(void)
1371 {
1372         // break apart the view matrix into vectors for various purposes
1373         Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
1374         VectorNegate(r_viewleft, r_viewright);
1375
1376 #if 0
1377         frustum[0].normal[0] = 0 - 1.0 / r_refdef.frustum_x;
1378         frustum[0].normal[1] = 0 - 0;
1379         frustum[0].normal[2] = -1 - 0;
1380         frustum[1].normal[0] = 0 + 1.0 / r_refdef.frustum_x;
1381         frustum[1].normal[1] = 0 + 0;
1382         frustum[1].normal[2] = -1 + 0;
1383         frustum[2].normal[0] = 0 - 0;
1384         frustum[2].normal[1] = 0 - 1.0 / r_refdef.frustum_y;
1385         frustum[2].normal[2] = -1 - 0;
1386         frustum[3].normal[0] = 0 + 0;
1387         frustum[3].normal[1] = 0 + 1.0 / r_refdef.frustum_y;
1388         frustum[3].normal[2] = -1 + 0;
1389 #endif
1390
1391 #if 0
1392         zNear = r_nearclip.value;
1393         nudge = 1.0 - 1.0 / (1<<23);
1394         frustum[4].normal[0] = 0 - 0;
1395         frustum[4].normal[1] = 0 - 0;
1396         frustum[4].normal[2] = -1 - -nudge;
1397         frustum[4].dist = 0 - -2 * zNear * nudge;
1398         frustum[5].normal[0] = 0 + 0;
1399         frustum[5].normal[1] = 0 + 0;
1400         frustum[5].normal[2] = -1 + -nudge;
1401         frustum[5].dist = 0 + -2 * zNear * nudge;
1402 #endif
1403
1404
1405
1406 #if 0
1407         frustum[0].normal[0] = m[3] - m[0];
1408         frustum[0].normal[1] = m[7] - m[4];
1409         frustum[0].normal[2] = m[11] - m[8];
1410         frustum[0].dist = m[15] - m[12];
1411
1412         frustum[1].normal[0] = m[3] + m[0];
1413         frustum[1].normal[1] = m[7] + m[4];
1414         frustum[1].normal[2] = m[11] + m[8];
1415         frustum[1].dist = m[15] + m[12];
1416
1417         frustum[2].normal[0] = m[3] - m[1];
1418         frustum[2].normal[1] = m[7] - m[5];
1419         frustum[2].normal[2] = m[11] - m[9];
1420         frustum[2].dist = m[15] - m[13];
1421
1422         frustum[3].normal[0] = m[3] + m[1];
1423         frustum[3].normal[1] = m[7] + m[5];
1424         frustum[3].normal[2] = m[11] + m[9];
1425         frustum[3].dist = m[15] + m[13];
1426
1427         frustum[4].normal[0] = m[3] - m[2];
1428         frustum[4].normal[1] = m[7] - m[6];
1429         frustum[4].normal[2] = m[11] - m[10];
1430         frustum[4].dist = m[15] - m[14];
1431
1432         frustum[5].normal[0] = m[3] + m[2];
1433         frustum[5].normal[1] = m[7] + m[6];
1434         frustum[5].normal[2] = m[11] + m[10];
1435         frustum[5].dist = m[15] + m[14];
1436 #endif
1437
1438
1439
1440         VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_x, r_viewleft, frustum[0].normal);
1441         VectorMAM(1, r_viewforward, 1.0 /  r_refdef.frustum_x, r_viewleft, frustum[1].normal);
1442         VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_y, r_viewup, frustum[2].normal);
1443         VectorMAM(1, r_viewforward, 1.0 /  r_refdef.frustum_y, r_viewup, frustum[3].normal);
1444         VectorCopy(r_viewforward, frustum[4].normal);
1445         VectorNormalize(frustum[0].normal);
1446         VectorNormalize(frustum[1].normal);
1447         VectorNormalize(frustum[2].normal);
1448         VectorNormalize(frustum[3].normal);
1449         frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1450         frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1451         frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1452         frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1453         frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1454         PlaneClassify(&frustum[0]);
1455         PlaneClassify(&frustum[1]);
1456         PlaneClassify(&frustum[2]);
1457         PlaneClassify(&frustum[3]);
1458         PlaneClassify(&frustum[4]);
1459
1460         // LordHavoc: note to all quake engine coders, Quake had a special case
1461         // for 90 degrees which assumed a square view (wrong), so I removed it,
1462         // Quake2 has it disabled as well.
1463
1464         // rotate R_VIEWFORWARD right by FOV_X/2 degrees
1465         //RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_refdef.fov_x / 2));
1466         //frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1467         //PlaneClassify(&frustum[0]);
1468
1469         // rotate R_VIEWFORWARD left by FOV_X/2 degrees
1470         //RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_refdef.fov_x / 2));
1471         //frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1472         //PlaneClassify(&frustum[1]);
1473
1474         // rotate R_VIEWFORWARD up by FOV_X/2 degrees
1475         //RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_refdef.fov_y / 2));
1476         //frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1477         //PlaneClassify(&frustum[2]);
1478
1479         // rotate R_VIEWFORWARD down by FOV_X/2 degrees
1480         //RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_refdef.fov_y / 2));
1481         //frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1482         //PlaneClassify(&frustum[3]);
1483
1484         // nearclip plane
1485         //VectorCopy(r_viewforward, frustum[4].normal);
1486         //frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1487         //PlaneClassify(&frustum[4]);
1488 }
1489
1490 static void R_BlendView(void)
1491 {
1492         int screenwidth, screenheight;
1493         qboolean dobloom;
1494         qboolean doblend;
1495         float vertex3f[12];
1496         float texcoord2f[3][8];
1497
1498         // set the (poorly named) screenwidth and screenheight variables to
1499         // a power of 2 at least as large as the screen, these will define the
1500         // size of the texture to allocate
1501         for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2);
1502         for (screenheight = 1;screenheight < vid.height;screenheight *= 2);
1503
1504         doblend = r_refdef.viewblend[3] >= 0.01f;
1505         dobloom = r_bloom.integer && screenwidth <= gl_max_texture_size && screenheight <= gl_max_texture_size && r_bloom_resolution.value >= 32 && r_bloom_power.integer >= 1 && r_bloom_power.integer < 100 && r_bloom_blur.value >= 0 && r_bloom_blur.value < 512;
1506
1507         if (!dobloom && !doblend)
1508                 return;
1509
1510         GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
1511         GL_DepthMask(true);
1512         GL_DepthTest(false);
1513         R_Mesh_Matrix(&identitymatrix);
1514         // vertex coordinates for a quad that covers the screen exactly
1515         vertex3f[0] = 0;vertex3f[1] = 0;vertex3f[2] = 0;
1516         vertex3f[3] = 1;vertex3f[4] = 0;vertex3f[5] = 0;
1517         vertex3f[6] = 1;vertex3f[7] = 1;vertex3f[8] = 0;
1518         vertex3f[9] = 0;vertex3f[10] = 1;vertex3f[11] = 0;
1519         R_Mesh_VertexPointer(vertex3f);
1520         R_Mesh_ColorPointer(NULL);
1521         R_Mesh_ResetTextureState();
1522         if (dobloom)
1523         {
1524                 int bloomwidth, bloomheight, x, range;
1525                 float xoffset, yoffset, r;
1526                 renderstats.bloom++;
1527                 // allocate textures as needed
1528                 if (!r_bloom_texture_screen)
1529                         r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1530                 if (!r_bloom_texture_bloom)
1531                         r_bloom_texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1532                 // set bloomwidth and bloomheight to the bloom resolution that will be
1533                 // used (often less than the screen resolution for faster rendering)
1534                 bloomwidth = min(r_view_width, r_bloom_resolution.integer);
1535                 bloomheight = min(r_view_height, bloomwidth * r_view_height / r_view_width);
1536                 // set up a texcoord array for the full resolution screen image
1537                 // (we have to keep this around to copy back during final render)
1538                 texcoord2f[0][0] = 0;
1539                 texcoord2f[0][1] = (float)r_view_height / (float)screenheight;
1540                 texcoord2f[0][2] = (float)r_view_width / (float)screenwidth;
1541                 texcoord2f[0][3] = (float)r_view_height / (float)screenheight;
1542                 texcoord2f[0][4] = (float)r_view_width / (float)screenwidth;
1543                 texcoord2f[0][5] = 0;
1544                 texcoord2f[0][6] = 0;
1545                 texcoord2f[0][7] = 0;
1546                 // set up a texcoord array for the reduced resolution bloom image
1547                 // (which will be additive blended over the screen image)
1548                 texcoord2f[1][0] = 0;
1549                 texcoord2f[1][1] = (float)bloomheight / (float)screenheight;
1550                 texcoord2f[1][2] = (float)bloomwidth / (float)screenwidth;
1551                 texcoord2f[1][3] = (float)bloomheight / (float)screenheight;
1552                 texcoord2f[1][4] = (float)bloomwidth / (float)screenwidth;
1553                 texcoord2f[1][5] = 0;
1554                 texcoord2f[1][6] = 0;
1555                 texcoord2f[1][7] = 0;
1556                 R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]);
1557                 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen));
1558                 // copy view into the full resolution screen image texture
1559                 GL_ActiveTexture(0);
1560                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1561                 renderstats.bloom_copypixels += r_view_width * r_view_height;
1562                 // now scale it down to the bloom size and raise to a power of itself
1563                 // to darken it (this leaves the really bright stuff bright, and
1564                 // everything else becomes very dark)
1565                 // TODO: optimize with multitexture or GLSL
1566                 qglViewport(r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1567                 GL_BlendFunc(GL_ONE, GL_ZERO);
1568                 GL_Color(1, 1, 1, 1);
1569                 R_Mesh_Draw(0, 4, 2, polygonelements);
1570                 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1571                 // render multiple times with a multiply blendfunc to raise to a power
1572                 GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
1573                 for (x = 1;x < r_bloom_power.integer;x++)
1574                 {
1575                         R_Mesh_Draw(0, 4, 2, polygonelements);
1576                         renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1577                 }
1578                 // we now have a darkened bloom image in the framebuffer, copy it into
1579                 // the bloom image texture for more processing
1580                 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom));
1581                 R_Mesh_TexCoordPointer(0, 2, texcoord2f[2]);
1582                 GL_ActiveTexture(0);
1583                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1584                 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1585                 // blend on at multiple vertical offsets to achieve a vertical blur
1586                 // TODO: do offset blends using GLSL
1587                 range = r_bloom_blur.integer * bloomwidth / 320;
1588                 GL_BlendFunc(GL_ONE, GL_ZERO);
1589                 for (x = -range;x <= range;x++)
1590                 {
1591                         xoffset = 0 / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1592                         yoffset = x / (float)bloomheight * (float)bloomheight / (float)screenheight;
1593                         // compute a texcoord array with the specified x and y offset
1594                         texcoord2f[2][0] = xoffset+0;
1595                         texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1596                         texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1597                         texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1598                         texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1599                         texcoord2f[2][5] = yoffset+0;
1600                         texcoord2f[2][6] = xoffset+0;
1601                         texcoord2f[2][7] = yoffset+0;
1602                         // this r value looks like a 'dot' particle, fading sharply to
1603                         // black at the edges
1604                         // (probably not realistic but looks good enough)
1605                         r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1606                         if (r < 0.01f)
1607                                 continue;
1608                         GL_Color(r, r, r, 1);
1609                         R_Mesh_Draw(0, 4, 2, polygonelements);
1610                         renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1611                         GL_BlendFunc(GL_ONE, GL_ONE);
1612                 }
1613                 // copy the vertically blurred bloom view to a texture
1614                 GL_ActiveTexture(0);
1615                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1616                 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1617                 // blend the vertically blurred image at multiple offsets horizontally
1618                 // to finish the blur effect
1619                 // TODO: do offset blends using GLSL
1620                 range = r_bloom_blur.integer * bloomwidth / 320;
1621                 GL_BlendFunc(GL_ONE, GL_ZERO);
1622                 for (x = -range;x <= range;x++)
1623                 {
1624                         xoffset = x / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1625                         yoffset = 0 / (float)bloomheight * (float)bloomheight / (float)screenheight;
1626                         // compute a texcoord array with the specified x and y offset
1627                         texcoord2f[2][0] = xoffset+0;
1628                         texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1629                         texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1630                         texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1631                         texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1632                         texcoord2f[2][5] = yoffset+0;
1633                         texcoord2f[2][6] = xoffset+0;
1634                         texcoord2f[2][7] = yoffset+0;
1635                         // this r value looks like a 'dot' particle, fading sharply to
1636                         // black at the edges
1637                         // (probably not realistic but looks good enough)
1638                         r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1639                         if (r < 0.01f)
1640                                 continue;
1641                         GL_Color(r, r, r, 1);
1642                         R_Mesh_Draw(0, 4, 2, polygonelements);
1643                         renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1644                         GL_BlendFunc(GL_ONE, GL_ONE);
1645                 }
1646                 // copy the blurred bloom view to a texture
1647                 GL_ActiveTexture(0);
1648                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1649                 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1650                 // go back to full view area
1651                 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1652                 // put the original screen image back in place and blend the bloom
1653                 // texture on it
1654                 GL_Color(1,1,1,1);
1655                 GL_BlendFunc(GL_ONE, GL_ZERO);
1656                 // do both in one pass if possible
1657                 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen));
1658                 R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]);
1659                 if (r_textureunits.integer >= 2 && gl_combine.integer)
1660                 {
1661                         R_Mesh_TexCombine(1, GL_ADD, GL_ADD, 1, 1);
1662                         R_Mesh_TexBind(1, R_GetTexture(r_bloom_texture_bloom));
1663                         R_Mesh_TexCoordPointer(1, 2, texcoord2f[1]);
1664                 }
1665                 else
1666                 {
1667                         R_Mesh_Draw(0, 4, 2, polygonelements);
1668                         renderstats.bloom_drawpixels += r_view_width * r_view_height;
1669                         // now blend on the bloom texture
1670                         GL_BlendFunc(GL_ONE, GL_ONE);
1671                         R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom));
1672                         R_Mesh_TexCoordPointer(0, 2, texcoord2f[1]);
1673                 }
1674                 R_Mesh_Draw(0, 4, 2, polygonelements);
1675                 renderstats.bloom_drawpixels += r_view_width * r_view_height;
1676         }
1677         if (doblend)
1678         {
1679                 // apply a color tint to the whole view
1680                 R_Mesh_ResetTextureState();
1681                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1682                 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
1683                 R_Mesh_Draw(0, 4, 2, polygonelements);
1684         }
1685 }
1686
1687 void R_RenderScene(void);
1688
1689 matrix4x4_t r_waterscrollmatrix;
1690
1691 /*
1692 ================
1693 R_RenderView
1694 ================
1695 */
1696 void R_RenderView(void)
1697 {
1698         if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1699                 return; //Host_Error ("R_RenderView: NULL worldmodel");
1700
1701         r_view_width = bound(0, r_refdef.width, vid.width);
1702         r_view_height = bound(0, r_refdef.height, vid.height);
1703         r_view_depth = 1;
1704         r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1705         r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1706         r_view_z = 0;
1707         r_view_matrix = r_refdef.viewentitymatrix;
1708         GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1709         r_rtworld = r_shadow_realtime_world.integer;
1710         r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1711         r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1712         r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1713         r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1714         r_polygonfactor = 0;
1715         r_polygonoffset = 0;
1716         r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1717         r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1718         if (r_showsurfaces.integer)
1719         {
1720                 r_rtworld = false;
1721                 r_rtworldshadows = false;
1722                 r_rtdlight = false;
1723                 r_rtdlightshadows = false;
1724                 r_lightmapintensity = 0;
1725         }
1726
1727         // GL is weird because it's bottom to top, r_view_y is top to bottom
1728         qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1729         GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1730         GL_ScissorTest(true);
1731         GL_DepthMask(true);
1732         R_ClearScreen();
1733         R_Textures_Frame();
1734         R_UpdateFog();
1735         if (r_timereport_active)
1736                 R_TimeReport("setup");
1737
1738         qglDepthFunc(GL_LEQUAL);
1739         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1740         qglEnable(GL_POLYGON_OFFSET_FILL);
1741
1742         R_RenderScene();
1743
1744         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1745         qglDisable(GL_POLYGON_OFFSET_FILL);
1746
1747         R_BlendView();
1748         if (r_timereport_active)
1749                 R_TimeReport("blendview");
1750
1751         GL_Scissor(0, 0, vid.width, vid.height);
1752         GL_ScissorTest(false);
1753 }
1754
1755 //[515]: csqc
1756 void CSQC_R_ClearScreen (void)
1757 {
1758         if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1759                 return; //Host_Error ("R_RenderView: NULL worldmodel");
1760
1761         r_view_width = bound(0, r_refdef.width, vid.width);
1762         r_view_height = bound(0, r_refdef.height, vid.height);
1763         r_view_depth = 1;
1764         r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1765         r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1766         r_view_z = 0;
1767         r_view_matrix = r_refdef.viewentitymatrix;
1768         GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1769         r_rtworld = r_shadow_realtime_world.integer;
1770         r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1771         r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1772         r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1773         r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1774         r_polygonfactor = 0;
1775         r_polygonoffset = 0;
1776         r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1777         r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1778         if (r_showsurfaces.integer)
1779         {
1780                 r_rtworld = false;
1781                 r_rtworldshadows = false;
1782                 r_rtdlight = false;
1783                 r_rtdlightshadows = false;
1784                 r_lightmapintensity = 0;
1785         }
1786
1787         // GL is weird because it's bottom to top, r_view_y is top to bottom
1788         qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1789         GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1790         GL_ScissorTest(true);
1791         GL_DepthMask(true);
1792         R_ClearScreen();
1793         R_Textures_Frame();
1794         R_UpdateFog();
1795         if (r_timereport_active)
1796                 R_TimeReport("setup");
1797 }
1798
1799 //[515]: csqc
1800 void CSQC_R_RenderScene (void)
1801 {
1802         qglDepthFunc(GL_LEQUAL);
1803         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1804         qglEnable(GL_POLYGON_OFFSET_FILL);
1805
1806         R_RenderScene();
1807
1808         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1809         qglDisable(GL_POLYGON_OFFSET_FILL);
1810
1811         R_BlendView();
1812         if (r_timereport_active)
1813                 R_TimeReport("blendview");
1814
1815         GL_Scissor(0, 0, vid.width, vid.height);
1816         GL_ScissorTest(false);
1817 }
1818
1819 extern void R_DrawLightningBeams (void);
1820 extern void VM_AddPolygonsToMeshQueue (void);
1821 void R_RenderScene(void)
1822 {
1823         float nearclip;
1824
1825         // don't let sound skip if going slow
1826         if (r_refdef.extraupdate)
1827                 S_ExtraUpdate ();
1828
1829         r_framecount++;
1830
1831         if (gl_support_fragment_shader)
1832                 qglUseProgramObjectARB(0);
1833
1834         R_MeshQueue_BeginScene();
1835
1836         R_SetFrustum();
1837
1838         r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
1839         nearclip = bound (0.001f, r_nearclip.value, r_farclip - 1.0f);
1840
1841         if (r_rtworldshadows || r_rtdlightshadows)
1842                 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_refdef.frustum_x, r_refdef.frustum_y, nearclip);
1843         else
1844                 GL_SetupView_Mode_Perspective(r_refdef.frustum_x, r_refdef.frustum_y, nearclip, r_farclip);
1845
1846         GL_SetupView_Orientation_FromEntity(&r_view_matrix);
1847
1848         Matrix4x4_CreateTranslate(&r_waterscrollmatrix, sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
1849
1850         R_SkyStartFrame();
1851
1852         R_WorldVisibility();
1853         if (r_timereport_active)
1854                 R_TimeReport("worldvis");
1855
1856         R_MarkEntities();
1857         if (r_timereport_active)
1858                 R_TimeReport("markentity");
1859
1860         R_Shadow_UpdateWorldLightSelection();
1861
1862         if (cl.csqc_vidvars.drawworld)
1863         {
1864                 // don't let sound skip if going slow
1865                 if (r_refdef.extraupdate)
1866                         S_ExtraUpdate ();
1867
1868                 if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
1869                 {
1870                         r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
1871                         if (r_timereport_active)
1872                                 R_TimeReport("worldsky");
1873                 }
1874
1875                 if (R_DrawBrushModelsSky() && r_timereport_active)
1876                         R_TimeReport("bmodelsky");
1877
1878                 if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
1879                 {
1880                         r_refdef.worldmodel->Draw(r_refdef.worldentity);
1881                         if (r_timereport_active)
1882                                 R_TimeReport("world");
1883                 }
1884         }
1885
1886         // don't let sound skip if going slow
1887         if (r_refdef.extraupdate)
1888                 S_ExtraUpdate ();
1889
1890         R_DrawModels();
1891         if (r_timereport_active)
1892                 R_TimeReport("models");
1893
1894         // don't let sound skip if going slow
1895         if (r_refdef.extraupdate)
1896                 S_ExtraUpdate ();
1897
1898         R_ShadowVolumeLighting(false);
1899         if (r_timereport_active)
1900                 R_TimeReport("rtlights");
1901
1902         // don't let sound skip if going slow
1903         if (r_refdef.extraupdate)
1904                 S_ExtraUpdate ();
1905
1906         if (cl.csqc_vidvars.drawworld)
1907         {
1908                 R_DrawLightningBeams();
1909                 if (r_timereport_active)
1910                         R_TimeReport("lightning");
1911
1912                 R_DrawParticles();
1913                 if (r_timereport_active)
1914                         R_TimeReport("particles");
1915
1916                 R_DrawExplosions();
1917                 if (r_timereport_active)
1918                         R_TimeReport("explosions");
1919         }
1920
1921         R_MeshQueue_RenderTransparent();
1922         if (r_timereport_active)
1923                 R_TimeReport("drawtrans");
1924
1925         if (cl.csqc_vidvars.drawworld)
1926         {
1927                 R_DrawCoronas();
1928                 if (r_timereport_active)
1929                         R_TimeReport("coronas");
1930         }
1931         if(cl.csqc_vidvars.drawcrosshair)
1932         {
1933                 R_DrawWorldCrosshair();
1934                 if (r_timereport_active)
1935                         R_TimeReport("crosshair");
1936         }
1937
1938         VM_AddPolygonsToMeshQueue();
1939
1940         R_MeshQueue_Render();
1941
1942         R_MeshQueue_EndScene();
1943
1944         // don't let sound skip if going slow
1945         if (r_refdef.extraupdate)
1946                 S_ExtraUpdate ();
1947
1948         if (gl_support_fragment_shader)
1949                 qglUseProgramObjectARB(0);
1950 }
1951
1952 /*
1953 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
1954 {
1955         int i;
1956         float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
1957         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1958         GL_DepthMask(false);
1959         GL_DepthTest(true);
1960         R_Mesh_Matrix(&identitymatrix);
1961
1962         vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
1963         vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
1964         vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
1965         vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
1966         vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
1967         vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
1968         vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
1969         vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
1970         R_FillColors(color, 8, cr, cg, cb, ca);
1971         if (fogenabled)
1972         {
1973                 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
1974                 {
1975                         f2 = VERTEXFOGTABLE(VectorDistance(v, r_vieworigin));
1976                         f1 = 1 - f2;
1977                         c[0] = c[0] * f1 + fogcolor[0] * f2;
1978                         c[1] = c[1] * f1 + fogcolor[1] * f2;
1979                         c[2] = c[2] * f1 + fogcolor[2] * f2;
1980                 }
1981         }
1982         R_Mesh_VertexPointer(vertex3f);
1983         R_Mesh_ColorPointer(color);
1984         R_Mesh_ResetTextureState();
1985         R_Mesh_Draw(8, 12);
1986 }
1987 */
1988
1989 int nomodelelements[24] =
1990 {
1991         5, 2, 0,
1992         5, 1, 2,
1993         5, 0, 3,
1994         5, 3, 1,
1995         0, 2, 4,
1996         2, 1, 4,
1997         3, 0, 4,
1998         1, 3, 4
1999 };
2000
2001 float nomodelvertex3f[6*3] =
2002 {
2003         -16,   0,   0,
2004          16,   0,   0,
2005           0, -16,   0,
2006           0,  16,   0,
2007           0,   0, -16,
2008           0,   0,  16
2009 };
2010
2011 float nomodelcolor4f[6*4] =
2012 {
2013         0.0f, 0.0f, 0.5f, 1.0f,
2014         0.0f, 0.0f, 0.5f, 1.0f,
2015         0.0f, 0.5f, 0.0f, 1.0f,
2016         0.0f, 0.5f, 0.0f, 1.0f,
2017         0.5f, 0.0f, 0.0f, 1.0f,
2018         0.5f, 0.0f, 0.0f, 1.0f
2019 };
2020
2021 void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
2022 {
2023         int i;
2024         float f1, f2, *c;
2025         float color4f[6*4];
2026         R_Mesh_Matrix(&ent->matrix);
2027
2028         if (ent->flags & EF_ADDITIVE)
2029         {
2030                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2031                 GL_DepthMask(false);
2032         }
2033         else if (ent->alpha < 1)
2034         {
2035                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2036                 GL_DepthMask(false);
2037         }
2038         else
2039         {
2040                 GL_BlendFunc(GL_ONE, GL_ZERO);
2041                 GL_DepthMask(true);
2042         }
2043         GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
2044         R_Mesh_VertexPointer(nomodelvertex3f);
2045         if (fogenabled)
2046         {
2047                 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2048                 R_Mesh_ColorPointer(color4f);
2049                 f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_vieworigin));
2050                 f1 = 1 - f2;
2051                 for (i = 0, c = color4f;i < 6;i++, c += 4)
2052                 {
2053                         c[0] = (c[0] * f1 + fogcolor[0] * f2);
2054                         c[1] = (c[1] * f1 + fogcolor[1] * f2);
2055                         c[2] = (c[2] * f1 + fogcolor[2] * f2);
2056                         c[3] *= ent->alpha;
2057                 }
2058         }
2059         else if (ent->alpha != 1)
2060         {
2061                 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2062                 R_Mesh_ColorPointer(color4f);
2063                 for (i = 0, c = color4f;i < 6;i++, c += 4)
2064                         c[3] *= ent->alpha;
2065         }
2066         else
2067                 R_Mesh_ColorPointer(nomodelcolor4f);
2068         R_Mesh_ResetTextureState();
2069         R_Mesh_Draw(0, 6, 8, nomodelelements);
2070 }
2071
2072 void R_DrawNoModel(entity_render_t *ent)
2073 {
2074         //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
2075                 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight);
2076         //else
2077         //      R_DrawNoModelCallback(ent, 0);
2078 }
2079
2080 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
2081 {
2082         vec3_t right1, right2, diff, normal;
2083
2084         VectorSubtract (org2, org1, normal);
2085
2086         // calculate 'right' vector for start
2087         VectorSubtract (r_vieworigin, org1, diff);
2088         CrossProduct (normal, diff, right1);
2089         VectorNormalize (right1);
2090
2091         // calculate 'right' vector for end
2092         VectorSubtract (r_vieworigin, org2, diff);
2093         CrossProduct (normal, diff, right2);
2094         VectorNormalize (right2);
2095
2096         vert[ 0] = org1[0] + width * right1[0];
2097         vert[ 1] = org1[1] + width * right1[1];
2098         vert[ 2] = org1[2] + width * right1[2];
2099         vert[ 3] = org1[0] - width * right1[0];
2100         vert[ 4] = org1[1] - width * right1[1];
2101         vert[ 5] = org1[2] - width * right1[2];
2102         vert[ 6] = org2[0] - width * right2[0];
2103         vert[ 7] = org2[1] - width * right2[1];
2104         vert[ 8] = org2[2] - width * right2[2];
2105         vert[ 9] = org2[0] + width * right2[0];
2106         vert[10] = org2[1] + width * right2[1];
2107         vert[11] = org2[2] + width * right2[2];
2108 }
2109
2110 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
2111
2112 void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_t *fogtexture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca)
2113 {
2114         float fog = 0.0f, ifog;
2115         float vertex3f[12];
2116
2117         if (fogenabled)
2118                 fog = VERTEXFOGTABLE(VectorDistance(origin, r_vieworigin));
2119         ifog = 1 - fog;
2120
2121         R_Mesh_Matrix(&identitymatrix);
2122         GL_BlendFunc(blendfunc1, blendfunc2);
2123         GL_DepthMask(false);
2124         GL_DepthTest(!depthdisable);
2125
2126         vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
2127         vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
2128         vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
2129         vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
2130         vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
2131         vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
2132         vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
2133         vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
2134         vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
2135         vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
2136         vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
2137         vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
2138
2139         R_Mesh_VertexPointer(vertex3f);
2140         R_Mesh_ColorPointer(NULL);
2141         R_Mesh_ResetTextureState();
2142         R_Mesh_TexBind(0, R_GetTexture(texture));
2143         R_Mesh_TexCoordPointer(0, 2, spritetexcoord2f);
2144         GL_Color(cr * ifog, cg * ifog, cb * ifog, ca);
2145         R_Mesh_Draw(0, 4, 2, polygonelements);
2146
2147         if (blendfunc2 == GL_ONE_MINUS_SRC_ALPHA)
2148         {
2149                 R_Mesh_TexBind(0, R_GetTexture(fogtexture));
2150                 GL_BlendFunc(blendfunc1, GL_ONE);
2151                 GL_Color(fogcolor[0] * fog, fogcolor[1] * fog, fogcolor[2] * fog, ca);
2152                 R_Mesh_Draw(0, 4, 2, polygonelements);
2153         }
2154 }
2155
2156 int R_Mesh_AddVertex3f(rmesh_t *mesh, const float *v)
2157 {
2158         int i;
2159         float *vertex3f;
2160         for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
2161                 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
2162                         break;
2163         if (i == mesh->numvertices)
2164         {
2165                 if (mesh->numvertices < mesh->maxvertices)
2166                 {
2167                         VectorCopy(v, vertex3f);
2168                         mesh->numvertices++;
2169                 }
2170                 return mesh->numvertices;
2171         }
2172         else
2173                 return i;
2174 }
2175
2176 void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
2177 {
2178         int i;
2179         int *e, element[3];
2180         element[0] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2181         element[1] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2182         e = mesh->element3i + mesh->numtriangles * 3;
2183         for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
2184         {
2185                 element[2] = R_Mesh_AddVertex3f(mesh, vertex3f);
2186                 if (mesh->numtriangles < mesh->maxtriangles)
2187                 {
2188                         *e++ = element[0];
2189                         *e++ = element[1];
2190                         *e++ = element[2];
2191                         mesh->numtriangles++;
2192                 }
2193                 element[1] = element[2];
2194         }
2195 }
2196
2197 void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
2198 {
2199         int planenum, planenum2;
2200         int w;
2201         int tempnumpoints;
2202         mplane_t *plane, *plane2;
2203         float temppoints[2][256*3];
2204         for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
2205         {
2206                 w = 0;
2207                 tempnumpoints = 4;
2208                 PolygonF_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->normal[3], 1024.0*1024.0*1024.0);
2209                 for (planenum2 = 0, plane2 = planes;planenum2 < numplanes && tempnumpoints >= 3;planenum2++, plane2++)
2210                 {
2211                         if (planenum2 == planenum)
2212                                 continue;
2213                         PolygonF_Divide(tempnumpoints, temppoints[w], plane2->normal[0], plane2->normal[1], plane2->normal[2], plane2->dist, 1.0/32.0, 0, NULL, NULL, 256, temppoints[!w], &tempnumpoints, NULL);
2214                         w = !w;
2215                 }
2216                 if (tempnumpoints < 3)
2217                         continue;
2218                 // generate elements forming a triangle fan for this polygon
2219                 R_Mesh_AddPolygon3f(mesh, tempnumpoints, temppoints[w]);
2220         }
2221 }
2222
2223 static void R_DrawCollisionBrush(const colbrushf_t *brush)
2224 {
2225         int i;
2226         R_Mesh_VertexPointer(brush->points->v);
2227         i = (int)(((size_t)brush) / sizeof(colbrushf_t));
2228         GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2229         GL_LockArrays(0, brush->numpoints);
2230         R_Mesh_Draw(0, brush->numpoints, brush->numtriangles, brush->elements);
2231         GL_LockArrays(0, 0);
2232 }
2233
2234 static void R_DrawCollisionSurface(const entity_render_t *ent, const msurface_t *surface)
2235 {
2236         int i;
2237         if (!surface->num_collisiontriangles)
2238                 return;
2239         R_Mesh_VertexPointer(surface->data_collisionvertex3f);
2240         i = (int)(((size_t)surface) / sizeof(msurface_t));
2241         GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2242         GL_LockArrays(0, surface->num_collisionvertices);
2243         R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i);
2244         GL_LockArrays(0, 0);
2245 }
2246
2247 static void R_Texture_AddLayer(texture_t *t, qboolean depthmask, int blendfunc1, int blendfunc2, texturelayertype_t type, rtexture_t *texture, const matrix4x4_t *matrix, float r, float g, float b, float a)
2248 {
2249         texturelayer_t *layer;
2250         layer = t->currentlayers + t->currentnumlayers++;
2251         layer->type = type;
2252         layer->depthmask = depthmask;
2253         layer->blendfunc1 = blendfunc1;
2254         layer->blendfunc2 = blendfunc2;
2255         layer->texture = texture;
2256         layer->texmatrix = *matrix;
2257         layer->color[0] = r;
2258         layer->color[1] = g;
2259         layer->color[2] = b;
2260         layer->color[3] = a;
2261 }
2262
2263 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
2264 {
2265         // FIXME: identify models using a better check than ent->model->brush.shadowmesh
2266         //int lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
2267
2268         {
2269                 texture_t *texture = t;
2270                 model_t *model = ent->model;
2271                 int s = ent->skinnum;
2272                 if ((unsigned int)s >= (unsigned int)model->numskins)
2273                         s = 0;
2274                 if (model->skinscenes)
2275                 {
2276                         if (model->skinscenes[s].framecount > 1)
2277                                 s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
2278                         else
2279                                 s = model->skinscenes[s].firstframe;
2280                 }
2281                 if (s > 0)
2282                         t = t + s * model->num_surfaces;
2283                 if (t->animated)
2284                         t = t->anim_frames[ent->frame != 0][(t->anim_total[ent->frame != 0] >= 2) ? ((int)(r_refdef.time * 5.0f) % t->anim_total[ent->frame != 0]) : 0];
2285                 texture->currentframe = t;
2286         }
2287
2288         t->currentmaterialflags = t->basematerialflags;
2289         t->currentalpha = ent->alpha;
2290         if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
2291                 t->currentalpha *= r_wateralpha.value;
2292         if (!(ent->flags & RENDER_LIGHT))
2293                 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
2294         if (ent->effects & EF_ADDITIVE)
2295                 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT;
2296         else if (t->currentalpha < 1)
2297                 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT;
2298         if (ent->effects & EF_NODEPTHTEST)
2299                 t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST;
2300         if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
2301                 t->currenttexmatrix = r_waterscrollmatrix;
2302         else
2303                 t->currenttexmatrix = identitymatrix;
2304
2305         t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
2306         t->basetexture = (!t->colormapping && t->skin.merged) ? t->skin.merged : t->skin.base;
2307         t->glosstexture = r_texture_white;
2308         t->specularpower = 8;
2309         t->specularscale = 0;
2310         if (r_shadow_gloss.integer > 0)
2311         {
2312                 if (t->skin.gloss)
2313                 {
2314                         if (r_shadow_glossintensity.value > 0)
2315                         {
2316                                 t->glosstexture = t->skin.gloss;
2317                                 t->specularscale = r_shadow_glossintensity.value;
2318                         }
2319                 }
2320                 else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0)
2321                         t->specularscale = r_shadow_gloss2intensity.value;
2322         }
2323
2324         t->currentnumlayers = 0;
2325         if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
2326         {
2327                 if (gl_lightmaps.integer)
2328                         R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, r_texture_white, &identitymatrix, 1, 1, 1, 1);
2329                 else if (!(t->currentmaterialflags & MATERIALFLAG_SKY))
2330                 {
2331                         int blendfunc1, blendfunc2, depthmask;
2332                         if (t->currentmaterialflags & MATERIALFLAG_ADD)
2333                         {
2334                                 blendfunc1 = GL_SRC_ALPHA;
2335                                 blendfunc2 = GL_ONE;
2336                         }
2337                         else if (t->currentmaterialflags & MATERIALFLAG_ALPHA)
2338                         {
2339                                 blendfunc1 = GL_SRC_ALPHA;
2340                                 blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
2341                         }
2342                         else if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
2343                         {
2344                                 blendfunc1 = t->customblendfunc[0];
2345                                 blendfunc2 = t->customblendfunc[1];
2346                         }
2347                         else
2348                         {
2349                                 blendfunc1 = GL_ONE;
2350                                 blendfunc2 = GL_ZERO;
2351                         }
2352                         depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
2353                         if (t->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
2354                         {
2355                                 rtexture_t *currentbasetexture;
2356                                 int layerflags = 0;
2357                                 if (fogenabled && (t->currentmaterialflags & MATERIALFLAG_BLENDED))
2358                                         layerflags |= TEXTURELAYERFLAG_FOGDARKEN;
2359                                 currentbasetexture = (VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) < (1.0f / 1048576.0f) && t->skin.merged) ? t->skin.merged : t->skin.base;
2360                                 if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2361                                 {
2362                                         // fullbright is not affected by r_lightmapintensity
2363                                         R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0], ent->colormod[1], ent->colormod[2], t->currentalpha);
2364                                         if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2365                                                 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ent->colormod[0], ent->colormap_pantscolor[1] * ent->colormod[1], ent->colormap_pantscolor[2] * ent->colormod[2], t->currentalpha);
2366                                         if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2367                                                 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * ent->colormod[0], ent->colormap_shirtcolor[1] * ent->colormod[1], ent->colormap_shirtcolor[2] * ent->colormod[2], t->currentalpha);
2368                                 }
2369                                 else
2370                                 {
2371                                         float colorscale;
2372                                         colorscale = 2;
2373                                         // q3bsp has no lightmap updates, so the lightstylevalue that
2374                                         // would normally be baked into the lightmap must be
2375                                         // applied to the color
2376                                         if (ent->model->type == mod_brushq3)
2377                                                 colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
2378                                         colorscale *= r_lightmapintensity;
2379                                         if (r_textureunits.integer >= 2 && gl_combine.integer)
2380                                                 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE_COMBINE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
2381                                         else if ((t->currentmaterialflags & MATERIALFLAG_BLENDED) == 0)
2382                                                 R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale * 0.5f, ent->colormod[1] * colorscale * 0.5f, ent->colormod[2] * colorscale * 0.5f, t->currentalpha);
2383                                         else
2384                                                 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
2385                                         if (r_ambient.value >= (1.0f/64.0f))
2386                                                 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * r_ambient.value * (1.0f / 64.0f), ent->colormod[1] * r_ambient.value * (1.0f / 64.0f), ent->colormod[2] * r_ambient.value * (1.0f / 64.0f), t->currentalpha);
2387                                         if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2388                                         {
2389                                                 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ent->colormod[0] * colorscale, ent->colormap_pantscolor[1] * ent->colormod[1] * colorscale, ent->colormap_pantscolor[2]  * ent->colormod[2] * colorscale, t->currentalpha);
2390                                                 if (r_ambient.value >= (1.0f/64.0f))
2391                                                         R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ent->colormod[0] * r_ambient.value * (1.0f / 64.0f), ent->colormap_pantscolor[1] * ent->colormod[1] * r_ambient.value * (1.0f / 64.0f), ent->colormap_pantscolor[2] * ent->colormod[2] * r_ambient.value * (1.0f / 64.0f), t->currentalpha);
2392                                         }
2393                                         if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2394                                         {
2395                                                 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * ent->colormod[0] * colorscale, ent->colormap_shirtcolor[1] * ent->colormod[1] * colorscale, ent->colormap_shirtcolor[2] * ent->colormod[2] * colorscale, t->currentalpha);
2396                                                 if (r_ambient.value >= (1.0f/64.0f))
2397                                                         R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * ent->colormod[0] * r_ambient.value * (1.0f / 64.0f), ent->colormap_shirtcolor[1] * ent->colormod[1] * r_ambient.value * (1.0f / 64.0f), ent->colormap_shirtcolor[2] * ent->colormod[2] * r_ambient.value * (1.0f / 64.0f), t->currentalpha);
2398                                         }
2399                                 }
2400                                 if (t->skin.glow != NULL)
2401                                         R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, t->currentalpha);
2402                                 if (fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
2403                                 {
2404                                         // if this is opaque use alpha blend which will darken the earlier
2405                                         // passes cheaply.
2406                                         //
2407                                         // if this is an alpha blended material, all the earlier passes
2408                                         // were darkened by fog already, so we only need to add the fog
2409                                         // color ontop through the fog mask texture
2410                                         //
2411                                         // if this is an additive blended material, all the earlier passes
2412                                         // were darkened by fog already, and we should not add fog color
2413                                         // (because the background was not darkened, there is no fog color
2414                                         // that was lost behind it).
2415                                         R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], t->currentalpha);
2416                                 }
2417                         }
2418                 }
2419         }
2420 }
2421
2422 void R_UpdateAllTextureInfo(entity_render_t *ent)
2423 {
2424         int i;
2425         if (ent->model)
2426                 for (i = 0;i < ent->model->num_textures;i++)
2427                         R_UpdateTextureInfo(ent, ent->model->data_textures + i);
2428 }
2429
2430 int rsurface_array_size = 0;
2431 float *rsurface_array_modelvertex3f = NULL;
2432 float *rsurface_array_modelsvector3f = NULL;
2433 float *rsurface_array_modeltvector3f = NULL;
2434 float *rsurface_array_modelnormal3f = NULL;
2435 float *rsurface_array_deformedvertex3f = NULL;
2436 float *rsurface_array_deformedsvector3f = NULL;
2437 float *rsurface_array_deformedtvector3f = NULL;
2438 float *rsurface_array_deformednormal3f = NULL;
2439 float *rsurface_array_color4f = NULL;
2440 float *rsurface_array_texcoord3f = NULL;
2441
2442 void R_Mesh_ResizeArrays(int newvertices)
2443 {
2444         float *base;
2445         if (rsurface_array_size >= newvertices)
2446                 return;
2447         if (rsurface_array_modelvertex3f)
2448                 Mem_Free(rsurface_array_modelvertex3f);
2449         rsurface_array_size = (newvertices + 1023) & ~1023;
2450         base = (float *)Mem_Alloc(r_main_mempool, rsurface_array_size * sizeof(float[31]));
2451         rsurface_array_modelvertex3f     = base + rsurface_array_size * 0;
2452         rsurface_array_modelsvector3f    = base + rsurface_array_size * 3;
2453         rsurface_array_modeltvector3f    = base + rsurface_array_size * 6;
2454         rsurface_array_modelnormal3f     = base + rsurface_array_size * 9;
2455         rsurface_array_deformedvertex3f  = base + rsurface_array_size * 12;
2456         rsurface_array_deformedsvector3f = base + rsurface_array_size * 15;
2457         rsurface_array_deformedtvector3f = base + rsurface_array_size * 18;
2458         rsurface_array_deformednormal3f  = base + rsurface_array_size * 21;
2459         rsurface_array_texcoord3f        = base + rsurface_array_size * 24;
2460         rsurface_array_color4f           = base + rsurface_array_size * 27;
2461 }
2462
2463 float *rsurface_modelvertex3f;
2464 float *rsurface_modelsvector3f;
2465 float *rsurface_modeltvector3f;
2466 float *rsurface_modelnormal3f;
2467 float *rsurface_vertex3f;
2468 float *rsurface_svector3f;
2469 float *rsurface_tvector3f;
2470 float *rsurface_normal3f;
2471 float *rsurface_lightmapcolor4f;
2472 vec3_t rsurface_modelorg;
2473 qboolean rsurface_generatedvertex;
2474 const entity_render_t *rsurface_entity;
2475 const model_t *rsurface_model;
2476 texture_t *rsurface_texture;
2477 rtexture_t *rsurface_lightmaptexture;
2478 rsurfmode_t rsurface_mode;
2479 texture_t *rsurface_glsl_texture;
2480 qboolean rsurface_glsl_uselightmap;
2481
2482 void RSurf_ActiveEntity(const entity_render_t *ent)
2483 {
2484         Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
2485         rsurface_entity = ent;
2486         rsurface_model = ent->model;
2487         if (rsurface_array_size < rsurface_model->surfmesh.num_vertices)
2488                 R_Mesh_ResizeArrays(rsurface_model->surfmesh.num_vertices);
2489         R_Mesh_Matrix(&ent->matrix);
2490         Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
2491         if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexboneweights))
2492         {
2493                 rsurface_modelvertex3f = rsurface_array_modelvertex3f;
2494                 rsurface_modelsvector3f = NULL;
2495                 rsurface_modeltvector3f = NULL;
2496                 rsurface_modelnormal3f = NULL;
2497                 Mod_Alias_GetMesh_Vertex3f(rsurface_model, rsurface_entity->frameblend, rsurface_array_modelvertex3f);
2498                 rsurface_generatedvertex = true;
2499         }
2500         else
2501         {
2502                 rsurface_modelvertex3f  = rsurface_model->surfmesh.data_vertex3f;
2503                 rsurface_modelsvector3f = rsurface_model->surfmesh.data_svector3f;
2504                 rsurface_modeltvector3f = rsurface_model->surfmesh.data_tvector3f;
2505                 rsurface_modelnormal3f  = rsurface_model->surfmesh.data_normal3f;
2506                 rsurface_generatedvertex = false;
2507         }
2508         rsurface_vertex3f  = rsurface_modelvertex3f;
2509         rsurface_svector3f = rsurface_modelsvector3f;
2510         rsurface_tvector3f = rsurface_modeltvector3f;
2511         rsurface_normal3f  = rsurface_modelnormal3f;
2512         rsurface_mode = RSURFMODE_NONE;
2513         rsurface_lightmaptexture = NULL;
2514         rsurface_texture = NULL;
2515         rsurface_glsl_texture = NULL;
2516         rsurface_glsl_uselightmap = false;
2517 }
2518
2519 void RSurf_CleanUp(void)
2520 {
2521         if (rsurface_mode == RSURFMODE_GLSL)
2522                 qglUseProgramObjectARB(0);
2523         GL_AlphaTest(false);
2524         rsurface_mode = RSURFMODE_NONE;
2525         rsurface_lightmaptexture = NULL;
2526         rsurface_texture = NULL;
2527         rsurface_glsl_texture = NULL;
2528         rsurface_glsl_uselightmap = false;
2529 }
2530
2531 void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist)
2532 {
2533         if (rsurface_generatedvertex)
2534         {
2535                 if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2536                         generatetangents = true;
2537                 if (generatetangents)
2538                         generatenormals = true;
2539                 if (generatenormals && !rsurface_modelnormal3f)
2540                 {
2541                         rsurface_normal3f = rsurface_modelnormal3f = rsurface_array_modelnormal3f;
2542                         Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_modelnormal3f, r_smoothnormals_areaweighting.integer);
2543                 }
2544                 if (generatetangents && !rsurface_modelsvector3f)
2545                 {
2546                         rsurface_svector3f = rsurface_modelsvector3f = rsurface_array_modelsvector3f;
2547                         rsurface_tvector3f = rsurface_modeltvector3f = rsurface_array_modeltvector3f;
2548                         Mod_BuildTextureVectorsFromNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_modelnormal3f, rsurface_model->surfmesh.data_element3i, rsurface_array_modelsvector3f, rsurface_array_modeltvector3f, r_smoothnormals_areaweighting.integer);
2549                 }
2550         }
2551         if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2552         {
2553                 int texturesurfaceindex;
2554                 float center[3], forward[3], right[3], up[3], v[4][3];
2555                 matrix4x4_t matrix1, imatrix1;
2556                 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewforward, forward);
2557                 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewright, right);
2558                 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewup, up);
2559                 // make deformed versions of only the vertices used by the specified surfaces
2560                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2561                 {
2562                         int i, j;
2563                         const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2564                         // a single autosprite surface can contain multiple sprites...
2565                         for (j = 0;j < surface->num_vertices - 3;j += 4)
2566                         {
2567                                 VectorClear(center);
2568                                 for (i = 0;i < 4;i++)
2569                                         VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
2570                                 VectorScale(center, 0.25f, center);
2571                                 if (rsurface_texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
2572                                 {
2573                                         forward[0] = rsurface_modelorg[0] - center[0];
2574                                         forward[1] = rsurface_modelorg[1] - center[1];
2575                                         forward[2] = 0;
2576                                         VectorNormalize(forward);
2577                                         right[0] = forward[1];
2578                                         right[1] = -forward[0];
2579                                         right[2] = 0;
2580                                         VectorSet(up, 0, 0, 1);
2581                                 }
2582                                 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
2583                                 Matrix4x4_FromVectors(&matrix1, (rsurface_normal3f + 3 * surface->num_firstvertex) + j*3, (rsurface_svector3f + 3 * surface->num_firstvertex) + j*3, (rsurface_tvector3f + 3 * surface->num_firstvertex) + j*3, center);
2584                                 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
2585                                 for (i = 0;i < 4;i++)
2586                                         Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
2587                                 for (i = 0;i < 4;i++)
2588                                         VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_modelvertex3f + (surface->num_firstvertex+i+j) * 3);
2589                         }
2590                         Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_deformednormal3f, r_smoothnormals_areaweighting.integer);
2591                         Mod_BuildTextureVectorsFromNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_array_deformednormal3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_deformedsvector3f, rsurface_array_deformedtvector3f, r_smoothnormals_areaweighting.integer);
2592                 }
2593                 rsurface_vertex3f = rsurface_array_deformedvertex3f;
2594                 rsurface_svector3f = rsurface_array_deformedsvector3f;
2595                 rsurface_tvector3f = rsurface_array_deformedtvector3f;
2596                 rsurface_normal3f = rsurface_array_deformednormal3f;
2597         }
2598         R_Mesh_VertexPointer(rsurface_vertex3f);
2599 }
2600
2601 static void RSurf_Draw(const msurface_t *surface)
2602 {
2603         GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2604         R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2605 }
2606
2607 static void RSurf_DrawLightmap(const msurface_t *surface, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
2608 {
2609         int i;
2610         float f;
2611         float *v, *c, *c2;
2612         if (lightmode >= 2)
2613         {
2614                 // model lighting
2615                 vec3_t ambientcolor;
2616                 vec3_t diffusecolor;
2617                 vec3_t lightdir;
2618                 VectorCopy(rsurface_entity->modellight_lightdir, lightdir);
2619                 ambientcolor[0] = rsurface_entity->modellight_ambient[0] * r * 0.5f;
2620                 ambientcolor[1] = rsurface_entity->modellight_ambient[1] * g * 0.5f;
2621                 ambientcolor[2] = rsurface_entity->modellight_ambient[2] * b * 0.5f;
2622                 diffusecolor[0] = rsurface_entity->modellight_diffuse[0] * r * 0.5f;
2623                 diffusecolor[1] = rsurface_entity->modellight_diffuse[1] * g * 0.5f;
2624                 diffusecolor[2] = rsurface_entity->modellight_diffuse[2] * b * 0.5f;
2625                 if (VectorLength2(diffusecolor) > 0)
2626                 {
2627                         int numverts = surface->num_vertices;
2628                         v = rsurface_vertex3f + 3 * surface->num_firstvertex;
2629                         c2 = rsurface_normal3f + 3 * surface->num_firstvertex;
2630                         c = rsurface_array_color4f + 4 * surface->num_firstvertex;
2631                         // q3-style directional shading
2632                         for (i = 0;i < numverts;i++, v += 3, c2 += 3, c += 4)
2633                         {
2634                                 if ((f = DotProduct(c2, lightdir)) > 0)
2635                                         VectorMA(ambientcolor, f, diffusecolor, c);
2636                                 else
2637                                         VectorCopy(ambientcolor, c);
2638                                 c[3] = a;
2639                         }
2640                         r = 1;
2641                         g = 1;
2642                         b = 1;
2643                         a = 1;
2644                         applycolor = false;
2645                         rsurface_lightmapcolor4f = rsurface_array_color4f;
2646                 }
2647                 else
2648                 {
2649                         r = ambientcolor[0];
2650                         g = ambientcolor[1];
2651                         b = ambientcolor[2];
2652                         rsurface_lightmapcolor4f = NULL;
2653                 }
2654         }
2655         else if (lightmode >= 1)
2656         {
2657                 if (surface->lightmapinfo && surface->lightmapinfo->stainsamples)
2658                 {
2659                         for (i = 0, c = rsurface_array_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
2660                         {
2661                                 if (surface->lightmapinfo->samples)
2662                                 {
2663                                         const unsigned char *lm = surface->lightmapinfo->samples + (rsurface_model->surfmesh.data_lightmapoffsets + surface->num_firstvertex)[i];
2664                                         float scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
2665                                         VectorScale(lm, scale, c);
2666                                         if (surface->lightmapinfo->styles[1] != 255)
2667                                         {
2668                                                 int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
2669                                                 lm += size3;
2670                                                 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
2671                                                 VectorMA(c, scale, lm, c);
2672                                                 if (surface->lightmapinfo->styles[2] != 255)
2673                                                 {
2674                                                         lm += size3;
2675                                                         scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
2676                                                         VectorMA(c, scale, lm, c);
2677                                                         if (surface->lightmapinfo->styles[3] != 255)
2678                                                         {
2679                                                                 lm += size3;
2680                                                                 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
2681                                                                 VectorMA(c, scale, lm, c);
2682                                                         }
2683                                                 }
2684                                         }
2685                                 }
2686                                 else
2687                                         VectorClear(c);
2688                         }
2689                         rsurface_lightmapcolor4f = rsurface_array_color4f;
2690                 }
2691                 else
2692                         rsurface_lightmapcolor4f = rsurface_model->surfmesh.data_lightmapcolor4f;
2693         }
2694         else
2695                 rsurface_lightmapcolor4f = NULL;
2696         if (applyfog)
2697         {
2698                 if (rsurface_lightmapcolor4f)
2699                 {
2700                         for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (rsurface_array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4, c2 += 4)
2701                         {
2702                                 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2703                                 c2[0] = c[0] * f;
2704                                 c2[1] = c[1] * f;
2705                                 c2[2] = c[2] * f;
2706                                 c2[3] = c[3];
2707                         }
2708                 }
2709                 else
2710                 {
2711                         for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c2 = (rsurface_array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c2 += 4)
2712                         {
2713                                 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2714                                 c2[0] = f;
2715                                 c2[1] = f;
2716                                 c2[2] = f;
2717                                 c2[3] = 1;
2718                         }
2719                 }
2720                 rsurface_lightmapcolor4f = rsurface_array_color4f;
2721         }
2722         if (applycolor && rsurface_lightmapcolor4f)
2723         {
2724                 for (i = 0, c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (rsurface_array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4, c2 += 4)
2725                 {
2726                         c2[0] = c[0] * r;
2727                         c2[1] = c[1] * g;
2728                         c2[2] = c[2] * b;
2729                         c2[3] = c[3] * a;
2730                 }
2731                 rsurface_lightmapcolor4f = rsurface_array_color4f;
2732         }
2733         R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
2734         GL_Color(r, g, b, a);
2735         RSurf_Draw(surface);
2736 }
2737
2738 static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfacelist)
2739 {
2740         int texturesurfaceindex;
2741         int lightmode;
2742         qboolean applycolor;
2743         qboolean applyfog;
2744         rmeshstate_t m;
2745         if (rsurface_texture->currentmaterialflags & MATERIALFLAG_NODRAW)
2746                 return;
2747         r_shadow_rtlight = NULL;
2748         renderstats.entities_surfaces += texturenumsurfaces;
2749         // FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
2750         lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
2751         GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
2752         if ((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE))
2753                 qglDisable(GL_CULL_FACE);
2754         if (r_showsurfaces.integer)
2755         {
2756                 if (rsurface_mode != RSURFMODE_SHOWSURFACES)
2757                 {
2758                         rsurface_mode = RSURFMODE_SHOWSURFACES;
2759                         GL_DepthMask(true);
2760                         GL_BlendFunc(GL_ONE, GL_ZERO);
2761                         R_Mesh_ColorPointer(NULL);
2762                         R_Mesh_ResetTextureState();
2763                 }
2764                 RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
2765                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2766                 {
2767                         const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2768                         int k = (int)(((size_t)surface) / sizeof(msurface_t));
2769                         GL_Color((k & 15) * (1.0f / 16.0f), ((k >> 4) & 15) * (1.0f / 16.0f), ((k >> 8) & 15) * (1.0f / 16.0f), 0.2f);
2770                         RSurf_Draw(surface);
2771                 }
2772         }
2773         else if (rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY)
2774         {
2775                 // transparent sky would be ridiculous
2776                 if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2777                 {
2778                         if (rsurface_mode != RSURFMODE_SKY)
2779                         {
2780                                 if (rsurface_mode == RSURFMODE_GLSL)
2781                                         qglUseProgramObjectARB(0);
2782                                 rsurface_mode = RSURFMODE_SKY;
2783                                 if (skyrendernow)
2784                                 {
2785                                         skyrendernow = false;
2786                                         R_Sky();
2787                                         // restore entity matrix
2788                                         R_Mesh_Matrix(&rsurface_entity->matrix);
2789                                 }
2790                                 GL_DepthMask(true);
2791                                 // LordHavoc: HalfLife maps have freaky skypolys so don't use
2792                                 // skymasking on them, and Quake3 never did sky masking (unlike
2793                                 // software Quake and software Quake2), so disable the sky masking
2794                                 // in Quake3 maps as it causes problems with q3map2 sky tricks,
2795                                 // and skymasking also looks very bad when noclipping outside the
2796                                 // level, so don't use it then either.
2797                                 if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2798                                 {
2799                                         GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
2800                                         R_Mesh_ColorPointer(NULL);
2801                                         R_Mesh_ResetTextureState();
2802                                         if (skyrendermasked)
2803                                         {
2804                                                 // depth-only (masking)
2805                                                 GL_ColorMask(0,0,0,0);
2806                                                 // just to make sure that braindead drivers don't draw
2807                                                 // anything despite that colormask...
2808                                                 GL_BlendFunc(GL_ZERO, GL_ONE);
2809                                         }
2810                                         else
2811                                         {
2812                                                 // fog sky
2813                                                 GL_BlendFunc(GL_ONE, GL_ZERO);
2814                                         }
2815                                 }
2816                         }
2817                         // LordHavoc: HalfLife maps have freaky skypolys so don't use
2818                         // skymasking on them, and Quake3 never did sky masking (unlike
2819                         // software Quake and software Quake2), so disable the sky masking
2820                         // in Quake3 maps as it causes problems with q3map2 sky tricks,
2821                         // and skymasking also looks very bad when noclipping outside the
2822                         // level, so don't use it then either.
2823                         if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2824                         {
2825                                 RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
2826                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2827                                 {
2828                                         const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2829                                         RSurf_Draw(surface);
2830                                 }
2831                                 if (skyrendermasked)
2832                                         GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
2833                         }
2834                 }
2835         }
2836         else if (rsurface_texture->currentnumlayers && r_glsl.integer && gl_support_fragment_shader)
2837         {
2838                 if (rsurface_mode != RSURFMODE_GLSL)
2839                 {
2840                         rsurface_mode = RSURFMODE_GLSL;
2841                         rsurface_glsl_texture = NULL;
2842                         rsurface_glsl_uselightmap = false;
2843                         R_Mesh_ResetTextureState();
2844                 }
2845                 if (rsurface_glsl_texture != rsurface_texture || rsurface_glsl_uselightmap != (rsurface_lightmaptexture != NULL))
2846                 {
2847                         rsurface_glsl_texture = rsurface_texture;
2848                         rsurface_glsl_uselightmap = rsurface_lightmaptexture != NULL;
2849                         GL_BlendFunc(rsurface_texture->currentlayers[0].blendfunc1, rsurface_texture->currentlayers[0].blendfunc2);
2850                         GL_DepthMask(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_BLENDED));
2851                         GL_Color(rsurface_entity->colormod[0], rsurface_entity->colormod[1], rsurface_entity->colormod[2], rsurface_texture->currentalpha);
2852                         R_SetupSurfaceShader(vec3_origin, lightmode == 2);
2853                         //permutation_deluxemapping = permutation_lightmapping = R_SetupSurfaceShader(vec3_origin, lightmode == 2, false);
2854                         //if (r_glsl_deluxemapping.integer)
2855                         //      permutation_deluxemapping = R_SetupSurfaceShader(vec3_origin, lightmode == 2, true);
2856                         R_Mesh_TexCoordPointer(0, 2, rsurface_model->surfmesh.data_texcoordtexture2f);
2857                         R_Mesh_TexCoordPointer(4, 2, rsurface_model->surfmesh.data_texcoordlightmap2f);
2858                         GL_AlphaTest((rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2859                 }
2860                 if (!r_glsl_permutation)
2861                         return;
2862                 RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist);
2863                 R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
2864                 R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
2865                 R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
2866                 if (rsurface_lightmaptexture)
2867                 {
2868                         R_Mesh_TexBind(7, R_GetTexture(rsurface_lightmaptexture));
2869                         if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2870                                 R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture));
2871                         R_Mesh_ColorPointer(NULL);
2872                 }
2873                 else
2874                 {
2875                         R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
2876                         if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2877                                 R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
2878                         R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f);
2879                 }
2880                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2881                 {
2882                         const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2883                         RSurf_Draw(surface);
2884                 }
2885         }
2886         else if (rsurface_texture->currentnumlayers)
2887         {
2888                 int layerindex;
2889                 const texturelayer_t *layer;
2890                 if (rsurface_mode != RSURFMODE_MULTIPASS)
2891                 {
2892                         if (rsurface_mode == RSURFMODE_GLSL)
2893                                 qglUseProgramObjectARB(0);
2894                         rsurface_mode = RSURFMODE_MULTIPASS;
2895                 }
2896                 RSurf_PrepareVerticesForBatch(true, false, texturenumsurfaces, texturesurfacelist);
2897                 for (layerindex = 0, layer = rsurface_texture->currentlayers;layerindex < rsurface_texture->currentnumlayers;layerindex++, layer++)
2898                 {
2899                         vec4_t layercolor;
2900                         int layertexrgbscale;
2901                         if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
2902                         {
2903                                 if (layerindex == 0)
2904                                         GL_AlphaTest(true);
2905                                 else
2906                                 {
2907                                         GL_AlphaTest(false);
2908                                         qglDepthFunc(GL_EQUAL);
2909                                 }
2910                         }
2911                         GL_DepthMask(layer->depthmask);
2912                         GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
2913                         if ((layer->color[0] > 2 || layer->color[1] > 2 || layer->color[2] > 2) && (gl_combine.integer || layer->depthmask))
2914                         {
2915                                 layertexrgbscale = 4;
2916                                 VectorScale(layer->color, 0.25f, layercolor);
2917                         }
2918                         else if ((layer->color[0] > 1 || layer->color[1] > 1 || layer->color[2] > 1) && (gl_combine.integer || layer->depthmask))
2919                         {
2920                                 layertexrgbscale = 2;
2921                                 VectorScale(layer->color, 0.5f, layercolor);
2922                         }
2923                         else
2924                         {
2925                                 layertexrgbscale = 1;
2926                                 VectorScale(layer->color, 1.0f, layercolor);
2927                         }
2928                         layercolor[3] = layer->color[3];
2929                         R_Mesh_ColorPointer(NULL);
2930                         GL_Color(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
2931                         applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
2932                         applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
2933                         switch (layer->type)
2934                         {
2935                         case TEXTURELAYERTYPE_LITTEXTURE_COMBINE:
2936                                 memset(&m, 0, sizeof(m));
2937                                 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
2938                                 m.tex[1] = R_GetTexture(layer->texture);
2939                                 m.texmatrix[1] = layer->texmatrix;
2940                                 m.texrgbscale[1] = layertexrgbscale;
2941                                 m.pointer_texcoord[1] = rsurface_model->surfmesh.data_texcoordtexture2f;
2942                                 R_Mesh_TextureState(&m);
2943                                 if (lightmode == 2)
2944                                 {
2945                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2946                                         {
2947                                                 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2948                                                 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2949                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
2950                                         }
2951                                 }
2952                                 else if (rsurface_lightmaptexture)
2953                                 {
2954                                         R_Mesh_TexBind(0, R_GetTexture(rsurface_lightmaptexture));
2955                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2956                                         {
2957                                                 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2958                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
2959                                         }
2960                                 }
2961                                 else
2962                                 {
2963                                         R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2964                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2965                                         {
2966                                                 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2967                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
2968                                         }
2969                                 }
2970                                 break;
2971                         case TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS:
2972                                 memset(&m, 0, sizeof(m));
2973                                 m.tex[0] = R_GetTexture(layer->texture);
2974                                 m.texmatrix[0] = layer->texmatrix;
2975                                 m.texrgbscale[0] = layertexrgbscale;
2976                                 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
2977                                 R_Mesh_TextureState(&m);
2978                                 if (lightmode == 2)
2979                                 {
2980                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2981                                         {
2982                                                 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2983                                                 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2984                                                 RSurf_DrawLightmap(surface, 1, 1, 1, 1, 2, false, false);
2985                                         }
2986                                 }
2987                                 else if (rsurface_lightmaptexture)
2988                                 {
2989                                         R_Mesh_TexBind(0, R_GetTexture(rsurface_lightmaptexture));
2990                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2991                                         {
2992                                                 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2993                                                 RSurf_DrawLightmap(surface, 1, 1, 1, 1, 0, false, false);
2994                                         }
2995                                 }
2996                                 else
2997                                 {
2998                                         R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2999                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3000                                         {
3001                                                 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3002                                                 RSurf_DrawLightmap(surface, 1, 1, 1, 1, 1, false, false);
3003                                         }
3004                                 }
3005                                 GL_LockArrays(0, 0);
3006                                 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
3007                                 memset(&m, 0, sizeof(m));
3008                                 m.tex[0] = R_GetTexture(layer->texture);
3009                                 m.texmatrix[0] = layer->texmatrix;
3010                                 m.texrgbscale[0] = layertexrgbscale;
3011                                 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3012                                 R_Mesh_TextureState(&m);
3013                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3014                                 {
3015                                         const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3016                                         RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, false);
3017                                 }
3018                                 break;
3019                         case TEXTURELAYERTYPE_LITTEXTURE_VERTEX:
3020                                 memset(&m, 0, sizeof(m));
3021                                 m.tex[0] = R_GetTexture(layer->texture);
3022                                 m.texmatrix[0] = layer->texmatrix;
3023                                 m.texrgbscale[0] = layertexrgbscale;
3024                                 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3025                                 R_Mesh_TextureState(&m);
3026                                 if (lightmode == 2)
3027                                 {
3028                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3029                                         {
3030                                                 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3031                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
3032                                         }
3033                                 }
3034                                 else
3035                                 {
3036                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3037                                         {
3038                                                 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3039                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
3040                                         }
3041                                 }
3042                                 break;
3043                         case TEXTURELAYERTYPE_TEXTURE:
3044                                 memset(&m, 0, sizeof(m));
3045                                 m.tex[0] = R_GetTexture(layer->texture);