]> icculus.org git repositories - divverent/darkplaces.git/blob - gl_rmain.c
increased sv_maxrate limit to 150000 from 25000
[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] = 128.0f + intensity * v[0];
374                                 data[side][y][x][1] = 128.0f + intensity * v[1];
375                                 data[side][y][x][2] = 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 "\n"
424 "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
425 "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
426 "varying vec3 VectorR; // direction of R texcoord (surface normal)\n"
427 "\n"
428 "\n"
429 "\n"
430 "\n"
431 "// vertex shader specific:\n"
432 "#ifdef VERTEX_SHADER\n"
433 "\n"
434 "uniform vec3 LightPosition;\n"
435 "uniform vec3 EyePosition;\n"
436 "uniform vec3 LightDir;\n"
437 "\n"
438 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3)\n"
439 "\n"
440 "void main(void)\n"
441 "{\n"
442 "       gl_FrontColor = gl_Color;\n"
443 "       // copy the surface texcoord\n"
444 "       TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n"
445 "#if !defined(MODE_LIGHTSOURCE) && !defined(MODE_LIGHTDIRECTION)\n"
446 "       TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
447 "#endif\n"
448 "\n"
449 "#ifdef MODE_LIGHTSOURCE\n"
450 "       // transform vertex position into light attenuation/cubemap space\n"
451 "       // (-1 to +1 across the light box)\n"
452 "       CubeVector = vec3(gl_TextureMatrix[3] * gl_Vertex);\n"
453 "\n"
454 "       // transform unnormalized light direction into tangent space\n"
455 "       // (we use unnormalized to ensure that it interpolates correctly and then\n"
456 "       //  normalize it per pixel)\n"
457 "       vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
458 "       LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
459 "       LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
460 "       LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
461 "#endif\n"
462 "\n"
463 "#ifdef MODE_LIGHTDIRECTION\n"
464 "       LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
465 "       LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
466 "       LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
467 "#endif\n"
468 "\n"
469 "       // transform unnormalized eye direction into tangent space\n"
470 "       vec3 eyeminusvertex = EyePosition - gl_Vertex.xyz;\n"
471 "       EyeVector.x = dot(eyeminusvertex, gl_MultiTexCoord1.xyz);\n"
472 "       EyeVector.y = dot(eyeminusvertex, gl_MultiTexCoord2.xyz);\n"
473 "       EyeVector.z = dot(eyeminusvertex, gl_MultiTexCoord3.xyz);\n"
474 "\n"
475 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
476 "       VectorS = gl_MultiTexCoord1.xyz;\n"
477 "       VectorT = gl_MultiTexCoord2.xyz;\n"
478 "       VectorR = gl_MultiTexCoord3.xyz;\n"
479 "#endif\n"
480 "\n"
481 "       // transform vertex to camera space, using ftransform to match non-VS\n"
482 "       // rendering\n"
483 "       gl_Position = ftransform();\n"
484 "}\n"
485 "\n"
486 "#endif // VERTEX_SHADER\n"
487 "\n"
488 "\n"
489 "\n"
490 "\n"
491 "// fragment shader specific:\n"
492 "#ifdef FRAGMENT_SHADER\n"
493 "\n"
494 "uniform sampler2D Texture_Normal;\n"
495 "uniform sampler2D Texture_Color;\n"
496 "uniform sampler2D Texture_Gloss;\n"
497 "uniform samplerCube Texture_Cube;\n"
498 "uniform sampler2D Texture_FogMask;\n"
499 "uniform sampler2D Texture_Pants;\n"
500 "uniform sampler2D Texture_Shirt;\n"
501 "uniform sampler2D Texture_Lightmap;\n"
502 "uniform sampler2D Texture_Deluxemap;\n"
503 "uniform sampler2D Texture_Glow;\n"
504 "\n"
505 "uniform vec3 LightColor;\n"
506 "uniform vec3 AmbientColor;\n"
507 "uniform vec3 DiffuseColor;\n"
508 "uniform vec3 SpecularColor;\n"
509 "uniform vec3 Color_Pants;\n"
510 "uniform vec3 Color_Shirt;\n"
511 "uniform vec3 FogColor;\n"
512 "\n"
513 "uniform float OffsetMapping_Scale;\n"
514 "uniform float OffsetMapping_Bias;\n"
515 "uniform float FogRangeRecip;\n"
516 "\n"
517 "uniform float AmbientScale;\n"
518 "uniform float DiffuseScale;\n"
519 "uniform float SpecularScale;\n"
520 "uniform float SpecularPower;\n"
521 "\n"
522 "void main(void)\n"
523 "{\n"
524 "       // apply offsetmapping\n"
525 "#ifdef USEOFFSETMAPPING\n"
526 "       vec2 TexCoordOffset = TexCoord;\n"
527 "#define TexCoord TexCoordOffset\n"
528 "\n"
529 "       vec3 eyedir = vec3(normalize(EyeVector));\n"
530 "       float depthbias = 1.0 - eyedir.z; // should this be a -?\n"
531 "       depthbias = 1.0 - depthbias * depthbias;\n"
532 "\n"
533 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
534 "       // 14 sample relief mapping: linear search and then binary search\n"
535 "       vec3 OffsetVector = vec3(EyeVector.xy * (1.0 / EyeVector.z) * depthbias * OffsetMapping_Scale * vec2(-0.1, 0.1), -0.1);\n"
536 "       vec3 RT = vec3(TexCoord - OffsetVector.xy * 10.0, 1.0) + OffsetVector;\n"
537 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
538 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
539 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
540 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
541 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
542 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += 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;OffsetVector *= 0.5;RT -= OffsetVector;\n"
546 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
547 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
548 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
549 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
550 "       if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
551 "       TexCoord = RT.xy;\n"
552 "#else\n"
553 "       // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
554 "       vec2 OffsetVector = vec2((EyeVector.xy * (1.0 / EyeVector.z) * depthbias) * OffsetMapping_Scale * vec2(-0.333, 0.333));\n"
555 "       //TexCoord += OffsetVector * 3.0;\n"
556 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
557 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
558 "       TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
559 "#endif\n"
560 "#endif\n"
561 "\n"
562 "       // combine the diffuse textures (base, pants, shirt)\n"
563 "       vec4 color = vec4(texture2D(Texture_Color, TexCoord));\n"
564 "#ifdef USECOLORMAPPING\n"
565 "       color.rgb += vec3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + vec3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
566 "#endif\n"
567 "\n"
568 "\n"
569 "\n"
570 "\n"
571 "#ifdef MODE_LIGHTSOURCE\n"
572 "       // light source\n"
573 "\n"
574 "       // get the surface normal and light normal\n"
575 "       vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
576 "       vec3 diffusenormal = vec3(normalize(LightVector));\n"
577 "\n"
578 "       // calculate directional shading\n"
579 "       color.rgb *= (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
580 "#ifdef USESPECULAR\n"
581 "       vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
582 "       color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
583 "#endif\n"
584 "\n"
585 "#ifdef USECUBEFILTER\n"
586 "       // apply light cubemap filter\n"
587 "       //color.rgb *= normalize(CubeVector) * 0.5 + 0.5;//vec3(textureCube(Texture_Cube, CubeVector));\n"
588 "       color.rgb *= vec3(textureCube(Texture_Cube, CubeVector));\n"
589 "#endif\n"
590 "\n"
591 "       // apply light color\n"
592 "       color.rgb *= LightColor;\n"
593 "\n"
594 "       // apply attenuation\n"
595 "       //\n"
596 "       // the attenuation is (1-(x*x+y*y+z*z)) which gives a large bright\n"
597 "       // center and sharp falloff at the edge, this is about the most efficient\n"
598 "       // we can get away with as far as providing illumination.\n"
599 "       //\n"
600 "       // pow(1-(x*x+y*y+z*z), 4) is far more realistic but needs large lights to\n"
601 "       // provide significant illumination, large = slow = pain.\n"
602 "       color.rgb *= max(1.0 - dot(CubeVector, CubeVector), 0.0);\n"
603 "\n"
604 "\n"
605 "\n"
606 "\n"
607 "#elif defined(MODE_LIGHTDIRECTION)\n"
608 "       // directional model lighting\n"
609 "\n"
610 "       // get the surface normal and light normal\n"
611 "       vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
612 "       vec3 diffusenormal = vec3(normalize(LightVector));\n"
613 "\n"
614 "       // calculate directional shading\n"
615 "       color.rgb *= AmbientColor + DiffuseColor * max(dot(surfacenormal, diffusenormal), 0.0);\n"
616 "#ifdef USESPECULAR\n"
617 "       vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
618 "       color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
619 "#endif\n"
620 "\n"
621 "\n"
622 "\n"
623 "\n"
624 "#elif defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE)\n"
625 "       // deluxemap lightmapping using light vectors in modelspace (evil q3map2)\n"
626 "\n"
627 "       // get the surface normal and light normal\n"
628 "       vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
629 "       vec3 diffusenormal_modelspace = vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5;\n"
630 "       vec3 diffusenormal = normalize(vec3(dot(diffusenormal_modelspace, VectorS), dot(diffusenormal_modelspace, VectorT), dot(diffusenormal_modelspace, VectorR)));\n"
631 "\n"
632 "       // calculate directional shading\n"
633 "       vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
634 "#ifdef USESPECULAR\n"
635 "       vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
636 "       tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
637 "#endif\n"
638 "\n"
639 "       // apply lightmap color\n"
640 "       color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n"
641 "\n"
642 "\n"
643 "\n"
644 "\n"
645 "#elif defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
646 "       // deluxemap lightmapping using light vectors in tangentspace\n"
647 "\n"
648 "       // get the surface normal and light normal\n"
649 "       vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
650 "       vec3 diffusenormal = normalize(vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5);\n"
651 "\n"
652 "       // calculate directional shading\n"
653 "       vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
654 "#ifdef USESPECULAR\n"
655 "       vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
656 "       tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
657 "#endif\n"
658 "\n"
659 "       // apply lightmap color\n"
660 "       color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n"
661 "\n"
662 "\n"
663 "\n"
664 "\n"
665 "#else // MODE none (lightmap)\n"
666 "       // apply lightmap color\n"
667 "       color.rgb *= vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + vec3(AmbientScale);\n"
668 "#endif // MODE\n"
669 "\n"
670 "#ifdef USEGLOW\n"
671 "       color.rgb += vec3(texture2D(Texture_Glow, TexCoord));\n"
672 "#endif\n"
673 "\n"
674 "#ifdef USEFOG\n"
675 "       // apply fog\n"
676 "       float fog = texture2D(Texture_FogMask, vec2(length(EyeVector)*FogRangeRecip, 0.0)).x;\n"
677 "       color.rgb = color.rgb * fog + FogColor * (1.0 - fog);\n"
678 "#endif\n"
679 "\n"
680 "       gl_FragColor = color * gl_Color;\n"
681 "}\n"
682 "\n"
683 "#endif // FRAGMENT_SHADER\n"
684 ;
685
686 void R_GLSL_CompilePermutation(int permutation)
687 {
688         r_glsl_permutation_t *p = r_glsl_permutations + permutation;
689         int vertstrings_count;
690         int fragstrings_count;
691         char *shaderstring;
692         const char *vertstrings_list[SHADERPERMUTATION_COUNT+1];
693         const char *fragstrings_list[SHADERPERMUTATION_COUNT+1];
694         char permutationname[256];
695         if (p->compiled)
696                 return;
697         p->compiled = true;
698         vertstrings_list[0] = "#define VERTEX_SHADER\n";
699         fragstrings_list[0] = "#define FRAGMENT_SHADER\n";
700         vertstrings_count = 1;
701         fragstrings_count = 1;
702         permutationname[0] = 0;
703         if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
704         {
705                 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTSOURCE\n";
706                 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTSOURCE\n";
707                 strlcat(permutationname, " lightsource", sizeof(permutationname));
708         }
709         if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE)
710         {
711                 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n";
712                 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n";
713                 strlcat(permutationname, " lightdirectionmap_modelspace", sizeof(permutationname));
714         }
715         if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)
716         {
717                 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n";
718                 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n";
719                 strlcat(permutationname, " lightdirectionmap_tangentspace", sizeof(permutationname));
720         }
721         if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
722         {
723                 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
724                 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
725                 strlcat(permutationname, " lightdirection", sizeof(permutationname));
726         }
727         if (permutation & SHADERPERMUTATION_GLOW)
728         {
729                 vertstrings_list[vertstrings_count++] = "#define USEGLOW\n";
730                 fragstrings_list[fragstrings_count++] = "#define USEGLOW\n";
731                 strlcat(permutationname, " glow", sizeof(permutationname));
732         }
733         if (permutation & SHADERPERMUTATION_COLORMAPPING)
734         {
735                 vertstrings_list[vertstrings_count++] = "#define USECOLORMAPPING\n";
736                 fragstrings_list[fragstrings_count++] = "#define USECOLORMAPPING\n";
737                 strlcat(permutationname, " colormapping", sizeof(permutationname));
738         }
739         if (permutation & SHADERPERMUTATION_SPECULAR)
740         {
741                 vertstrings_list[vertstrings_count++] = "#define USESPECULAR\n";
742                 fragstrings_list[fragstrings_count++] = "#define USESPECULAR\n";
743                 strlcat(permutationname, " specular", sizeof(permutationname));
744         }
745         if (permutation & SHADERPERMUTATION_FOG)
746         {
747                 vertstrings_list[vertstrings_count++] = "#define USEFOG\n";
748                 fragstrings_list[fragstrings_count++] = "#define USEFOG\n";
749                 strlcat(permutationname, " fog", sizeof(permutationname));
750         }
751         if (permutation & SHADERPERMUTATION_CUBEFILTER)
752         {
753                 vertstrings_list[vertstrings_count++] = "#define USECUBEFILTER\n";
754                 fragstrings_list[fragstrings_count++] = "#define USECUBEFILTER\n";
755                 strlcat(permutationname, " cubefilter", sizeof(permutationname));
756         }
757         if (permutation & SHADERPERMUTATION_OFFSETMAPPING)
758         {
759                 vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING\n";
760                 fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING\n";
761                 strlcat(permutationname, " offsetmapping", sizeof(permutationname));
762         }
763         if (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING)
764         {
765                 vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n";
766                 fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n";
767                 strlcat(permutationname, " OFFSETMAPPING_RELIEFMAPPING", sizeof(permutationname));
768         }
769         shaderstring = (char *)FS_LoadFile("glsl/default.glsl", r_main_mempool, false, NULL);
770         if (shaderstring)
771         {
772                 Con_DPrintf("GLSL shader text loaded from disk\n");
773                 vertstrings_list[vertstrings_count++] = shaderstring;
774                 fragstrings_list[fragstrings_count++] = shaderstring;
775         }
776         else
777         {
778                 vertstrings_list[vertstrings_count++] = builtinshaderstring;
779                 fragstrings_list[fragstrings_count++] = builtinshaderstring;
780         }
781         p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list);
782         if (p->program)
783         {
784                 CHECKGLERROR
785                 qglUseProgramObjectARB(p->program);
786                 p->loc_Texture_Normal      = qglGetUniformLocationARB(p->program, "Texture_Normal");
787                 p->loc_Texture_Color       = qglGetUniformLocationARB(p->program, "Texture_Color");
788                 p->loc_Texture_Gloss       = qglGetUniformLocationARB(p->program, "Texture_Gloss");
789                 p->loc_Texture_Cube        = qglGetUniformLocationARB(p->program, "Texture_Cube");
790                 p->loc_Texture_FogMask     = qglGetUniformLocationARB(p->program, "Texture_FogMask");
791                 p->loc_Texture_Pants       = qglGetUniformLocationARB(p->program, "Texture_Pants");
792                 p->loc_Texture_Shirt       = qglGetUniformLocationARB(p->program, "Texture_Shirt");
793                 p->loc_Texture_Lightmap    = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
794                 p->loc_Texture_Deluxemap   = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
795                 p->loc_Texture_Glow        = qglGetUniformLocationARB(p->program, "Texture_Glow");
796                 p->loc_FogColor            = qglGetUniformLocationARB(p->program, "FogColor");
797                 p->loc_LightPosition       = qglGetUniformLocationARB(p->program, "LightPosition");
798                 p->loc_EyePosition         = qglGetUniformLocationARB(p->program, "EyePosition");
799                 p->loc_LightColor          = qglGetUniformLocationARB(p->program, "LightColor");
800                 p->loc_Color_Pants         = qglGetUniformLocationARB(p->program, "Color_Pants");
801                 p->loc_Color_Shirt         = qglGetUniformLocationARB(p->program, "Color_Shirt");
802                 p->loc_FogRangeRecip       = qglGetUniformLocationARB(p->program, "FogRangeRecip");
803                 p->loc_AmbientScale        = qglGetUniformLocationARB(p->program, "AmbientScale");
804                 p->loc_DiffuseScale        = qglGetUniformLocationARB(p->program, "DiffuseScale");
805                 p->loc_SpecularPower       = qglGetUniformLocationARB(p->program, "SpecularPower");
806                 p->loc_SpecularScale       = qglGetUniformLocationARB(p->program, "SpecularScale");
807                 p->loc_OffsetMapping_Scale = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
808                 p->loc_AmbientColor        = qglGetUniformLocationARB(p->program, "AmbientColor");
809                 p->loc_DiffuseColor        = qglGetUniformLocationARB(p->program, "DiffuseColor");
810                 p->loc_SpecularColor       = qglGetUniformLocationARB(p->program, "SpecularColor");
811                 p->loc_LightDir            = qglGetUniformLocationARB(p->program, "LightDir");
812                 if (p->loc_Texture_Normal >= 0)    qglUniform1iARB(p->loc_Texture_Normal, 0);
813                 if (p->loc_Texture_Color >= 0)     qglUniform1iARB(p->loc_Texture_Color, 1);
814                 if (p->loc_Texture_Gloss >= 0)     qglUniform1iARB(p->loc_Texture_Gloss, 2);
815                 if (p->loc_Texture_Cube >= 0)      qglUniform1iARB(p->loc_Texture_Cube, 3);
816                 if (p->loc_Texture_FogMask >= 0)   qglUniform1iARB(p->loc_Texture_FogMask, 4);
817                 if (p->loc_Texture_Pants >= 0)     qglUniform1iARB(p->loc_Texture_Pants, 5);
818                 if (p->loc_Texture_Shirt >= 0)     qglUniform1iARB(p->loc_Texture_Shirt, 6);
819                 if (p->loc_Texture_Lightmap >= 0)  qglUniform1iARB(p->loc_Texture_Lightmap, 7);
820                 if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap, 8);
821                 if (p->loc_Texture_Glow >= 0)      qglUniform1iARB(p->loc_Texture_Glow, 9);
822                 qglUseProgramObjectARB(0);
823                 CHECKGLERROR
824         }
825         else
826                 Con_Printf("permutation%s failed for shader %s, some features may not work properly!\n", permutationname, "glsl/default.glsl");
827         if (shaderstring)
828                 Mem_Free(shaderstring);
829 }
830
831 void R_GLSL_Restart_f(void)
832 {
833         int i;
834         for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
835                 if (r_glsl_permutations[i].program)
836                         GL_Backend_FreeProgram(r_glsl_permutations[i].program);
837         memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
838 }
839
840 void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, const vec3_t modelorg, const vec3_t lightcolorbase, qboolean modellighting)
841 {
842         // select a permutation of the lighting shader appropriate to this
843         // combination of texture, entity, light source, and fogging, only use the
844         // minimum features necessary to avoid wasting rendering time in the
845         // fragment shader on features that are not being used
846         int permutation = 0;
847         float specularscale = texture->specularscale;
848         r_glsl_permutation = NULL;
849         if (r_shadow_rtlight)
850         {
851                 permutation |= SHADERPERMUTATION_MODE_LIGHTSOURCE;
852                 specularscale *= r_shadow_rtlight->specularscale;
853                 if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
854                         permutation |= SHADERPERMUTATION_CUBEFILTER;
855         }
856         else
857         {
858                 if (modellighting)
859                         permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
860                 else if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping)
861                 {
862                         if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
863                                 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
864                         else
865                                 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
866                 }
867                 else if (r_glsl_deluxemapping.integer >= 2) // fake mode
868                         permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
869                 if (texture->skin.glow)
870                         permutation |= SHADERPERMUTATION_GLOW;
871         }
872         if (specularscale > 0)
873                 permutation |= SHADERPERMUTATION_SPECULAR;
874         if (fogenabled)
875                 permutation |= SHADERPERMUTATION_FOG;
876         if (texture->colormapping)
877                 permutation |= SHADERPERMUTATION_COLORMAPPING;
878         if (r_glsl_offsetmapping.integer)
879         {
880                 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
881                 if (r_glsl_offsetmapping_reliefmapping.integer)
882                         permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
883         }
884         if (!r_glsl_permutations[permutation].program)
885         {
886                 if (!r_glsl_permutations[permutation].compiled)
887                         R_GLSL_CompilePermutation(permutation);
888                 if (!r_glsl_permutations[permutation].program)
889                 {
890                         // remove features until we find a valid permutation
891                         int i;
892                         for (i = SHADERPERMUTATION_COUNT-1;;i>>=1)
893                         {
894                                 // reduce i more quickly whenever it would not remove any bits
895                                 if (permutation < i)
896                                         continue;
897                                 permutation &= i;
898                                 if (!r_glsl_permutations[permutation].compiled)
899                                         R_GLSL_CompilePermutation(permutation);
900                                 if (r_glsl_permutations[permutation].program)
901                                         break;
902                                 if (!i)
903                                         return; // utterly failed
904                         }
905                 }
906         }
907         r_glsl_permutation = r_glsl_permutations + permutation;
908         CHECKGLERROR
909         qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
910         R_Mesh_TexMatrix(0, &texture->currenttexmatrix);
911         if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
912         {
913                 R_Mesh_TexMatrix(3, &r_shadow_entitytolight);
914                 //if (r_glsl_permutation->loc_Texture_Cube >= 0) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap));
915                 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]);
916                 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
917                 if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_shadow_rtlight->ambientscale);
918                 if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_shadow_rtlight->diffusescale);
919                 if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale);
920         }
921         else if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
922         {
923                 if (texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
924                 {
925                         if (r_glsl_permutation->loc_AmbientColor >= 0)
926                                 qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, 1, 1, 1);
927                         if (r_glsl_permutation->loc_DiffuseColor >= 0)
928                                 qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, 0, 0, 0);
929                         if (r_glsl_permutation->loc_SpecularColor >= 0)
930                                 qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, 0, 0, 0);
931                         if (r_glsl_permutation->loc_LightDir >= 0)
932                                 qglUniform3fARB(r_glsl_permutation->loc_LightDir, 0, 0, -1);
933                 }
934                 else
935                 {
936                         if (r_glsl_permutation->loc_AmbientColor >= 0)
937                                 qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, ent->modellight_ambient[0], ent->modellight_ambient[1], ent->modellight_ambient[2]);
938                         if (r_glsl_permutation->loc_DiffuseColor >= 0)
939                                 qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, ent->modellight_diffuse[0], ent->modellight_diffuse[1], ent->modellight_diffuse[2]);
940                         if (r_glsl_permutation->loc_SpecularColor >= 0)
941                                 qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, ent->modellight_diffuse[0] * texture->specularscale, ent->modellight_diffuse[1] * texture->specularscale, ent->modellight_diffuse[2] * texture->specularscale);
942                         if (r_glsl_permutation->loc_LightDir >= 0)
943                                 qglUniform3fARB(r_glsl_permutation->loc_LightDir, ent->modellight_lightdir[0], ent->modellight_lightdir[1], ent->modellight_lightdir[2]);
944                 }
945         }
946         else
947         {
948                 if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 2.0f / 128.0f);
949                 if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_lightmapintensity * 2.0f);
950                 if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_lightmapintensity * specularscale * 2.0f);
951         }
952         if (r_glsl_permutation->loc_Texture_Normal >= 0) R_Mesh_TexBind(0, R_GetTexture(texture->skin.nmap));
953         if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(1, R_GetTexture(texture->basetexture));
954         if (r_glsl_permutation->loc_Texture_Gloss >= 0) R_Mesh_TexBind(2, R_GetTexture(texture->glosstexture));
955         if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
956         if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(5, R_GetTexture(texture->skin.pants));
957         if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(6, R_GetTexture(texture->skin.shirt));
958         if (r_glsl_permutation->loc_Texture_Glow >= 0) R_Mesh_TexBind(9, R_GetTexture(texture->skin.glow));
959         if (r_glsl_permutation->loc_FogColor >= 0)
960         {
961                 // additive passes are only darkened by fog, not tinted
962                 if (r_shadow_rtlight || (texture->currentmaterialflags & MATERIALFLAG_ADD))
963                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
964                 else
965                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, fogcolor[0], fogcolor[1], fogcolor[2]);
966         }
967         if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, modelorg[0], modelorg[1], modelorg[2]);
968         if (r_glsl_permutation->loc_Color_Pants >= 0)
969         {
970                 if (texture->skin.pants)
971                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, ent->colormap_pantscolor[0], ent->colormap_pantscolor[1], ent->colormap_pantscolor[2]);
972                 else
973                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
974         }
975         if (r_glsl_permutation->loc_Color_Shirt >= 0)
976         {
977                 if (texture->skin.shirt)
978                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, ent->colormap_shirtcolor[0], ent->colormap_shirtcolor[1], ent->colormap_shirtcolor[2]);
979                 else
980                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
981         }
982         if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, fograngerecip);
983         if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, texture->specularpower);
984         if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
985         CHECKGLERROR
986 }
987
988 void gl_main_start(void)
989 {
990         r_main_texturepool = R_AllocTexturePool();
991         r_bloom_texture_screen = NULL;
992         r_bloom_texture_bloom = NULL;
993         R_BuildBlankTextures();
994         R_BuildNoTexture();
995         if (gl_texturecubemap)
996         {
997                 R_BuildWhiteCube();
998                 R_BuildNormalizationCube();
999         }
1000         R_BuildFogTexture();
1001         memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
1002 }
1003
1004 void gl_main_shutdown(void)
1005 {
1006         R_FreeTexturePool(&r_main_texturepool);
1007         r_bloom_texture_screen = NULL;
1008         r_bloom_texture_bloom = NULL;
1009         r_texture_blanknormalmap = NULL;
1010         r_texture_white = NULL;
1011         r_texture_black = NULL;
1012         r_texture_whitecube = NULL;
1013         r_texture_normalizationcube = NULL;
1014         R_GLSL_Restart_f();
1015 }
1016
1017 extern void CL_ParseEntityLump(char *entitystring);
1018 void gl_main_newmap(void)
1019 {
1020         // FIXME: move this code to client
1021         int l;
1022         char *entities, entname[MAX_QPATH];
1023         r_framecount = 1;
1024         if (cl.worldmodel)
1025         {
1026                 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
1027                 l = (int)strlen(entname) - 4;
1028                 if (l >= 0 && !strcmp(entname + l, ".bsp"))
1029                 {
1030                         strcpy(entname + l, ".ent");
1031                         if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
1032                         {
1033                                 CL_ParseEntityLump(entities);
1034                                 Mem_Free(entities);
1035                                 return;
1036                         }
1037                 }
1038                 if (cl.worldmodel->brush.entities)
1039                         CL_ParseEntityLump(cl.worldmodel->brush.entities);
1040         }
1041 }
1042
1043 void GL_Main_Init(void)
1044 {
1045         r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
1046
1047         Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed\n");
1048         FOG_registercvars(); // FIXME: move this fog stuff to client?
1049         Cvar_RegisterVariable(&r_nearclip);
1050         Cvar_RegisterVariable(&r_showsurfaces);
1051         Cvar_RegisterVariable(&r_showtris);
1052         Cvar_RegisterVariable(&r_shownormals);
1053         Cvar_RegisterVariable(&r_showlighting);
1054         Cvar_RegisterVariable(&r_showshadowvolumes);
1055         Cvar_RegisterVariable(&r_showcollisionbrushes);
1056         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor);
1057         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset);
1058         Cvar_RegisterVariable(&r_showdisabledepthtest);
1059         Cvar_RegisterVariable(&r_drawentities);
1060         Cvar_RegisterVariable(&r_drawviewmodel);
1061         Cvar_RegisterVariable(&r_speeds);
1062         Cvar_RegisterVariable(&r_fullbrights);
1063         Cvar_RegisterVariable(&r_wateralpha);
1064         Cvar_RegisterVariable(&r_dynamic);
1065         Cvar_RegisterVariable(&r_fullbright);
1066         Cvar_RegisterVariable(&r_q1bsp_skymasking);
1067         Cvar_RegisterVariable(&r_textureunits);
1068         Cvar_RegisterVariable(&r_glsl);
1069         Cvar_RegisterVariable(&r_glsl_offsetmapping);
1070         Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
1071         Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
1072         Cvar_RegisterVariable(&r_glsl_deluxemapping);
1073         Cvar_RegisterVariable(&r_lerpsprites);
1074         Cvar_RegisterVariable(&r_lerpmodels);
1075         Cvar_RegisterVariable(&r_waterscroll);
1076         Cvar_RegisterVariable(&r_bloom);
1077         Cvar_RegisterVariable(&r_bloom_intensity);
1078         Cvar_RegisterVariable(&r_bloom_blur);
1079         Cvar_RegisterVariable(&r_bloom_resolution);
1080         Cvar_RegisterVariable(&r_bloom_power);
1081         Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
1082         Cvar_RegisterVariable(&developer_texturelogging);
1083         Cvar_RegisterVariable(&gl_lightmaps);
1084         Cvar_RegisterVariable(&r_test);
1085         if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
1086                 Cvar_SetValue("r_fullbrights", 0);
1087         R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
1088 }
1089
1090 static vec3_t r_farclip_origin;
1091 static vec3_t r_farclip_direction;
1092 static vec_t r_farclip_directiondist;
1093 static vec_t r_farclip_meshfarclip;
1094 static int r_farclip_directionbit0;
1095 static int r_farclip_directionbit1;
1096 static int r_farclip_directionbit2;
1097
1098 // enlarge farclip to accomodate box
1099 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
1100 {
1101         float d;
1102         d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
1103           + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
1104           + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
1105         if (r_farclip_meshfarclip < d)
1106                 r_farclip_meshfarclip = d;
1107 }
1108
1109 // return farclip value
1110 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
1111 {
1112         int i;
1113
1114         VectorCopy(origin, r_farclip_origin);
1115         VectorCopy(direction, r_farclip_direction);
1116         r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
1117         r_farclip_directionbit0 = r_farclip_direction[0] < 0;
1118         r_farclip_directionbit1 = r_farclip_direction[1] < 0;
1119         r_farclip_directionbit2 = r_farclip_direction[2] < 0;
1120         r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
1121
1122         if (r_refdef.worldmodel)
1123                 R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
1124         for (i = 0;i < r_refdef.numentities;i++)
1125                 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
1126
1127         return r_farclip_meshfarclip - r_farclip_directiondist;
1128 }
1129
1130 extern void R_Textures_Init(void);
1131 extern void GL_Draw_Init(void);
1132 extern void GL_Main_Init(void);
1133 extern void R_Shadow_Init(void);
1134 extern void R_Sky_Init(void);
1135 extern void GL_Surf_Init(void);
1136 extern void R_Crosshairs_Init(void);
1137 extern void R_Light_Init(void);
1138 extern void R_Particles_Init(void);
1139 extern void R_Explosion_Init(void);
1140 extern void gl_backend_init(void);
1141 extern void Sbar_Init(void);
1142 extern void R_LightningBeams_Init(void);
1143 extern void Mod_RenderInit(void);
1144
1145 void Render_Init(void)
1146 {
1147         gl_backend_init();
1148         R_Textures_Init();
1149         R_MeshQueue_Init();
1150         GL_Main_Init();
1151         GL_Draw_Init();
1152         R_Shadow_Init();
1153         R_Sky_Init();
1154         GL_Surf_Init();
1155         R_Crosshairs_Init();
1156         R_Light_Init();
1157         R_Particles_Init();
1158         R_Explosion_Init();
1159         Sbar_Init();
1160         R_LightningBeams_Init();
1161         Mod_RenderInit();
1162 }
1163
1164 /*
1165 ===============
1166 GL_Init
1167 ===============
1168 */
1169 extern char *ENGINE_EXTENSIONS;
1170 void GL_Init (void)
1171 {
1172         VID_CheckExtensions();
1173
1174         // LordHavoc: report supported extensions
1175         Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions );
1176
1177         // clear to black (loading plaque will be seen over this)
1178         qglClearColor(0,0,0,1);
1179         qglClear(GL_COLOR_BUFFER_BIT);
1180 }
1181
1182 int R_CullBox(const vec3_t mins, const vec3_t maxs)
1183 {
1184         int i;
1185         mplane_t *p;
1186         for (i = 0;i < 4;i++)
1187         {
1188                 p = frustum + i;
1189                 switch(p->signbits)
1190                 {
1191                 default:
1192                 case 0:
1193                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1194                                 return true;
1195                         break;
1196                 case 1:
1197                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1198                                 return true;
1199                         break;
1200                 case 2:
1201                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1202                                 return true;
1203                         break;
1204                 case 3:
1205                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1206                                 return true;
1207                         break;
1208                 case 4:
1209                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1210                                 return true;
1211                         break;
1212                 case 5:
1213                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1214                                 return true;
1215                         break;
1216                 case 6:
1217                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1218                                 return true;
1219                         break;
1220                 case 7:
1221                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1222                                 return true;
1223                         break;
1224                 }
1225         }
1226         return false;
1227 }
1228
1229 //==================================================================================
1230
1231 static void R_UpdateEntityLighting(entity_render_t *ent)
1232 {
1233         vec3_t tempdiffusenormal;
1234         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));
1235         VectorClear(ent->modellight_diffuse);
1236         VectorClear(ent->modellight_lightdir);
1237         if ((ent->flags & RENDER_LIGHT) && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
1238                 r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, ent->origin, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
1239         else // highly rare
1240                 VectorSet(ent->modellight_ambient, 1, 1, 1);
1241         Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
1242         VectorNormalize(ent->modellight_lightdir);
1243         ent->modellight_ambient[0] *= ent->colormod[0] * r_lightmapintensity;
1244         ent->modellight_ambient[1] *= ent->colormod[1] * r_lightmapintensity;
1245         ent->modellight_ambient[2] *= ent->colormod[2] * r_lightmapintensity;
1246         ent->modellight_diffuse[0] *= ent->colormod[0] * r_lightmapintensity;
1247         ent->modellight_diffuse[1] *= ent->colormod[1] * r_lightmapintensity;
1248         ent->modellight_diffuse[2] *= ent->colormod[2] * r_lightmapintensity;
1249 }
1250
1251 static void R_MarkEntities (void)
1252 {
1253         int i, renderimask;
1254         entity_render_t *ent;
1255
1256         if (!r_drawentities.integer)
1257                 return;
1258
1259         r_refdef.worldentity->visframe = r_framecount;
1260         renderimask = envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL);
1261         if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
1262         {
1263                 // worldmodel can check visibility
1264                 for (i = 0;i < r_refdef.numentities;i++)
1265                 {
1266                         ent = r_refdef.entities[i];
1267                         // some of the renderer still relies on origin...
1268                         Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1269                         // some of the renderer still relies on scale...
1270                         ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1271                         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)))
1272                         {
1273                                 ent->visframe = r_framecount;
1274                                 R_UpdateEntityLighting(ent);
1275                         }
1276                 }
1277         }
1278         else
1279         {
1280                 // no worldmodel or it can't check visibility
1281                 for (i = 0;i < r_refdef.numentities;i++)
1282                 {
1283                         ent = r_refdef.entities[i];
1284                         // some of the renderer still relies on origin...
1285                         Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1286                         // some of the renderer still relies on scale...
1287                         ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1288                         if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST))
1289                         {
1290                                 ent->visframe = r_framecount;
1291                                 R_UpdateEntityLighting(ent);
1292                         }
1293                 }
1294         }
1295 }
1296
1297 // only used if skyrendermasked, and normally returns false
1298 int R_DrawBrushModelsSky (void)
1299 {
1300         int i, sky;
1301         entity_render_t *ent;
1302
1303         if (!r_drawentities.integer)
1304                 return false;
1305
1306         sky = false;
1307         for (i = 0;i < r_refdef.numentities;i++)
1308         {
1309                 ent = r_refdef.entities[i];
1310                 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
1311                 {
1312                         ent->model->DrawSky(ent);
1313                         sky = true;
1314                 }
1315         }
1316         return sky;
1317 }
1318
1319 void R_DrawNoModel(entity_render_t *ent);
1320 void R_DrawModels(void)
1321 {
1322         int i;
1323         entity_render_t *ent;
1324
1325         if (!r_drawentities.integer)
1326                 return;
1327
1328         for (i = 0;i < r_refdef.numentities;i++)
1329         {
1330                 ent = r_refdef.entities[i];
1331                 if (ent->visframe == r_framecount)
1332                 {
1333                         renderstats.entities++;
1334                         if (ent->model && ent->model->Draw != NULL)
1335                                 ent->model->Draw(ent);
1336                         else
1337                                 R_DrawNoModel(ent);
1338                 }
1339         }
1340 }
1341
1342 static void R_SetFrustum(void)
1343 {
1344         // break apart the view matrix into vectors for various purposes
1345         Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
1346         VectorNegate(r_viewleft, r_viewright);
1347
1348 #if 0
1349         frustum[0].normal[0] = 0 - 1.0 / r_refdef.frustum_x;
1350         frustum[0].normal[1] = 0 - 0;
1351         frustum[0].normal[2] = -1 - 0;
1352         frustum[1].normal[0] = 0 + 1.0 / r_refdef.frustum_x;
1353         frustum[1].normal[1] = 0 + 0;
1354         frustum[1].normal[2] = -1 + 0;
1355         frustum[2].normal[0] = 0 - 0;
1356         frustum[2].normal[1] = 0 - 1.0 / r_refdef.frustum_y;
1357         frustum[2].normal[2] = -1 - 0;
1358         frustum[3].normal[0] = 0 + 0;
1359         frustum[3].normal[1] = 0 + 1.0 / r_refdef.frustum_y;
1360         frustum[3].normal[2] = -1 + 0;
1361 #endif
1362
1363 #if 0
1364         zNear = r_nearclip.value;
1365         nudge = 1.0 - 1.0 / (1<<23);
1366         frustum[4].normal[0] = 0 - 0;
1367         frustum[4].normal[1] = 0 - 0;
1368         frustum[4].normal[2] = -1 - -nudge;
1369         frustum[4].dist = 0 - -2 * zNear * nudge;
1370         frustum[5].normal[0] = 0 + 0;
1371         frustum[5].normal[1] = 0 + 0;
1372         frustum[5].normal[2] = -1 + -nudge;
1373         frustum[5].dist = 0 + -2 * zNear * nudge;
1374 #endif
1375
1376
1377
1378 #if 0
1379         frustum[0].normal[0] = m[3] - m[0];
1380         frustum[0].normal[1] = m[7] - m[4];
1381         frustum[0].normal[2] = m[11] - m[8];
1382         frustum[0].dist = m[15] - m[12];
1383
1384         frustum[1].normal[0] = m[3] + m[0];
1385         frustum[1].normal[1] = m[7] + m[4];
1386         frustum[1].normal[2] = m[11] + m[8];
1387         frustum[1].dist = m[15] + m[12];
1388
1389         frustum[2].normal[0] = m[3] - m[1];
1390         frustum[2].normal[1] = m[7] - m[5];
1391         frustum[2].normal[2] = m[11] - m[9];
1392         frustum[2].dist = m[15] - m[13];
1393
1394         frustum[3].normal[0] = m[3] + m[1];
1395         frustum[3].normal[1] = m[7] + m[5];
1396         frustum[3].normal[2] = m[11] + m[9];
1397         frustum[3].dist = m[15] + m[13];
1398
1399         frustum[4].normal[0] = m[3] - m[2];
1400         frustum[4].normal[1] = m[7] - m[6];
1401         frustum[4].normal[2] = m[11] - m[10];
1402         frustum[4].dist = m[15] - m[14];
1403
1404         frustum[5].normal[0] = m[3] + m[2];
1405         frustum[5].normal[1] = m[7] + m[6];
1406         frustum[5].normal[2] = m[11] + m[10];
1407         frustum[5].dist = m[15] + m[14];
1408 #endif
1409
1410
1411
1412         VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_x, r_viewleft, frustum[0].normal);
1413         VectorMAM(1, r_viewforward, 1.0 /  r_refdef.frustum_x, r_viewleft, frustum[1].normal);
1414         VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_y, r_viewup, frustum[2].normal);
1415         VectorMAM(1, r_viewforward, 1.0 /  r_refdef.frustum_y, r_viewup, frustum[3].normal);
1416         VectorCopy(r_viewforward, frustum[4].normal);
1417         VectorNormalize(frustum[0].normal);
1418         VectorNormalize(frustum[1].normal);
1419         VectorNormalize(frustum[2].normal);
1420         VectorNormalize(frustum[3].normal);
1421         frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1422         frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1423         frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1424         frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1425         frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1426         PlaneClassify(&frustum[0]);
1427         PlaneClassify(&frustum[1]);
1428         PlaneClassify(&frustum[2]);
1429         PlaneClassify(&frustum[3]);
1430         PlaneClassify(&frustum[4]);
1431
1432         // LordHavoc: note to all quake engine coders, Quake had a special case
1433         // for 90 degrees which assumed a square view (wrong), so I removed it,
1434         // Quake2 has it disabled as well.
1435
1436         // rotate R_VIEWFORWARD right by FOV_X/2 degrees
1437         //RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_refdef.fov_x / 2));
1438         //frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1439         //PlaneClassify(&frustum[0]);
1440
1441         // rotate R_VIEWFORWARD left by FOV_X/2 degrees
1442         //RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_refdef.fov_x / 2));
1443         //frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1444         //PlaneClassify(&frustum[1]);
1445
1446         // rotate R_VIEWFORWARD up by FOV_X/2 degrees
1447         //RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_refdef.fov_y / 2));
1448         //frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1449         //PlaneClassify(&frustum[2]);
1450
1451         // rotate R_VIEWFORWARD down by FOV_X/2 degrees
1452         //RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_refdef.fov_y / 2));
1453         //frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1454         //PlaneClassify(&frustum[3]);
1455
1456         // nearclip plane
1457         //VectorCopy(r_viewforward, frustum[4].normal);
1458         //frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1459         //PlaneClassify(&frustum[4]);
1460 }
1461
1462 static void R_BlendView(void)
1463 {
1464         int screenwidth, screenheight;
1465         qboolean dobloom;
1466         qboolean doblend;
1467         rmeshstate_t m;
1468         float vertex3f[12];
1469         float texcoord2f[3][8];
1470
1471         // set the (poorly named) screenwidth and screenheight variables to
1472         // a power of 2 at least as large as the screen, these will define the
1473         // size of the texture to allocate
1474         for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2);
1475         for (screenheight = 1;screenheight < vid.height;screenheight *= 2);
1476
1477         doblend = r_refdef.viewblend[3] >= 0.01f;
1478         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;
1479
1480         if (!dobloom && !doblend)
1481                 return;
1482
1483         GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
1484         GL_DepthMask(true);
1485         GL_DepthTest(false);
1486         R_Mesh_Matrix(&identitymatrix);
1487         // vertex coordinates for a quad that covers the screen exactly
1488         vertex3f[0] = 0;vertex3f[1] = 0;vertex3f[2] = 0;
1489         vertex3f[3] = 1;vertex3f[4] = 0;vertex3f[5] = 0;
1490         vertex3f[6] = 1;vertex3f[7] = 1;vertex3f[8] = 0;
1491         vertex3f[9] = 0;vertex3f[10] = 1;vertex3f[11] = 0;
1492         if (dobloom)
1493         {
1494                 int bloomwidth, bloomheight, x, dobloomblend, range;
1495                 float xoffset, yoffset, r;
1496                 renderstats.bloom++;
1497                 // allocate textures as needed
1498                 if (!r_bloom_texture_screen)
1499                         r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1500                 if (!r_bloom_texture_bloom)
1501                         r_bloom_texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1502                 // set bloomwidth and bloomheight to the bloom resolution that will be
1503                 // used (often less than the screen resolution for faster rendering)
1504                 bloomwidth = min(r_view_width, r_bloom_resolution.integer);
1505                 bloomheight = min(r_view_height, bloomwidth * r_view_height / r_view_width);
1506                 // set up a texcoord array for the full resolution screen image
1507                 // (we have to keep this around to copy back during final render)
1508                 texcoord2f[0][0] = 0;
1509                 texcoord2f[0][1] = (float)r_view_height / (float)screenheight;
1510                 texcoord2f[0][2] = (float)r_view_width / (float)screenwidth;
1511                 texcoord2f[0][3] = (float)r_view_height / (float)screenheight;
1512                 texcoord2f[0][4] = (float)r_view_width / (float)screenwidth;
1513                 texcoord2f[0][5] = 0;
1514                 texcoord2f[0][6] = 0;
1515                 texcoord2f[0][7] = 0;
1516                 // set up a texcoord array for the reduced resolution bloom image
1517                 // (which will be additive blended over the screen image)
1518                 texcoord2f[1][0] = 0;
1519                 texcoord2f[1][1] = (float)bloomheight / (float)screenheight;
1520                 texcoord2f[1][2] = (float)bloomwidth / (float)screenwidth;
1521                 texcoord2f[1][3] = (float)bloomheight / (float)screenheight;
1522                 texcoord2f[1][4] = (float)bloomwidth / (float)screenwidth;
1523                 texcoord2f[1][5] = 0;
1524                 texcoord2f[1][6] = 0;
1525                 texcoord2f[1][7] = 0;
1526                 memset(&m, 0, sizeof(m));
1527                 m.pointer_vertex = vertex3f;
1528                 m.pointer_texcoord[0] = texcoord2f[0];
1529                 m.tex[0] = R_GetTexture(r_bloom_texture_screen);
1530                 R_Mesh_State(&m);
1531                 // copy view into the full resolution screen image texture
1532                 GL_ActiveTexture(0);
1533                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1534                 renderstats.bloom_copypixels += r_view_width * r_view_height;
1535                 // now scale it down to the bloom size and raise to a power of itself
1536                 // to darken it (this leaves the really bright stuff bright, and
1537                 // everything else becomes very dark)
1538                 // TODO: optimize with multitexture or GLSL
1539                 qglViewport(r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1540                 GL_BlendFunc(GL_ONE, GL_ZERO);
1541                 GL_Color(1, 1, 1, 1);
1542                 R_Mesh_Draw(0, 4, 2, polygonelements);
1543                 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1544                 // render multiple times with a multiply blendfunc to raise to a power
1545                 GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
1546                 for (x = 1;x < r_bloom_power.integer;x++)
1547                 {
1548                         R_Mesh_Draw(0, 4, 2, polygonelements);
1549                         renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1550                 }
1551                 // we now have a darkened bloom image in the framebuffer, copy it into
1552                 // the bloom image texture for more processing
1553                 memset(&m, 0, sizeof(m));
1554                 m.pointer_vertex = vertex3f;
1555                 m.tex[0] = R_GetTexture(r_bloom_texture_bloom);
1556                 m.pointer_texcoord[0] = texcoord2f[2];
1557                 R_Mesh_State(&m);
1558                 GL_ActiveTexture(0);
1559                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1560                 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1561                 // blend on at multiple vertical offsets to achieve a vertical blur
1562                 // TODO: do offset blends using GLSL
1563                 range = r_bloom_blur.integer * bloomwidth / 320;
1564                 GL_BlendFunc(GL_ONE, GL_ZERO);
1565                 for (x = -range;x <= range;x++)
1566                 {
1567                         xoffset = 0 / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1568                         yoffset = x / (float)bloomheight * (float)bloomheight / (float)screenheight;
1569                         // compute a texcoord array with the specified x and y offset
1570                         texcoord2f[2][0] = xoffset+0;
1571                         texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1572                         texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1573                         texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1574                         texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1575                         texcoord2f[2][5] = yoffset+0;
1576                         texcoord2f[2][6] = xoffset+0;
1577                         texcoord2f[2][7] = yoffset+0;
1578                         // this r value looks like a 'dot' particle, fading sharply to
1579                         // black at the edges
1580                         // (probably not realistic but looks good enough)
1581                         r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1582                         if (r < 0.01f)
1583                                 continue;
1584                         GL_Color(r, r, r, 1);
1585                         R_Mesh_Draw(0, 4, 2, polygonelements);
1586                         renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1587                         GL_BlendFunc(GL_ONE, GL_ONE);
1588                 }
1589                 // copy the vertically blurred bloom view to a texture
1590                 GL_ActiveTexture(0);
1591                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1592                 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1593                 // blend the vertically blurred image at multiple offsets horizontally
1594                 // to finish the blur effect
1595                 // TODO: do offset blends using GLSL
1596                 range = r_bloom_blur.integer * bloomwidth / 320;
1597                 GL_BlendFunc(GL_ONE, GL_ZERO);
1598                 for (x = -range;x <= range;x++)
1599                 {
1600                         xoffset = x / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1601                         yoffset = 0 / (float)bloomheight * (float)bloomheight / (float)screenheight;
1602                         // compute a texcoord array with the specified x and y offset
1603                         texcoord2f[2][0] = xoffset+0;
1604                         texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1605                         texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1606                         texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1607                         texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1608                         texcoord2f[2][5] = yoffset+0;
1609                         texcoord2f[2][6] = xoffset+0;
1610                         texcoord2f[2][7] = yoffset+0;
1611                         // this r value looks like a 'dot' particle, fading sharply to
1612                         // black at the edges
1613                         // (probably not realistic but looks good enough)
1614                         r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1615                         if (r < 0.01f)
1616                                 continue;
1617                         GL_Color(r, r, r, 1);
1618                         R_Mesh_Draw(0, 4, 2, polygonelements);
1619                         renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1620                         GL_BlendFunc(GL_ONE, GL_ONE);
1621                 }
1622                 // copy the blurred bloom view to a texture
1623                 GL_ActiveTexture(0);
1624                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1625                 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1626                 // go back to full view area
1627                 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1628                 // put the original screen image back in place and blend the bloom
1629                 // texture on it
1630                 memset(&m, 0, sizeof(m));
1631                 m.pointer_vertex = vertex3f;
1632                 m.tex[0] = R_GetTexture(r_bloom_texture_screen);
1633                 m.pointer_texcoord[0] = texcoord2f[0];
1634 #if 0
1635                 dobloomblend = false;
1636 #else
1637                 // do both in one pass if possible
1638                 if (r_textureunits.integer >= 2 && gl_combine.integer)
1639                 {
1640                         dobloomblend = false;
1641                         m.texcombinergb[1] = GL_ADD;
1642                         m.tex[1] = R_GetTexture(r_bloom_texture_bloom);
1643                         m.pointer_texcoord[1] = texcoord2f[1];
1644                 }
1645                 else
1646                         dobloomblend = true;
1647 #endif
1648                 R_Mesh_State(&m);
1649                 GL_BlendFunc(GL_ONE, GL_ZERO);
1650                 GL_Color(1,1,1,1);
1651                 R_Mesh_Draw(0, 4, 2, polygonelements);
1652                 renderstats.bloom_drawpixels += r_view_width * r_view_height;
1653                 // now blend on the bloom texture if multipass
1654                 if (dobloomblend)
1655                 {
1656                         memset(&m, 0, sizeof(m));
1657                         m.pointer_vertex = vertex3f;
1658                         m.tex[0] = R_GetTexture(r_bloom_texture_bloom);
1659                         m.pointer_texcoord[0] = texcoord2f[1];
1660                         R_Mesh_State(&m);
1661                         GL_BlendFunc(GL_ONE, GL_ONE);
1662                         GL_Color(1,1,1,1);
1663                         R_Mesh_Draw(0, 4, 2, polygonelements);
1664                         renderstats.bloom_drawpixels += r_view_width * r_view_height;
1665                 }
1666         }
1667         if (doblend)
1668         {
1669                 // apply a color tint to the whole view
1670                 memset(&m, 0, sizeof(m));
1671                 m.pointer_vertex = vertex3f;
1672                 R_Mesh_State(&m);
1673                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1674                 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
1675                 R_Mesh_Draw(0, 4, 2, polygonelements);
1676         }
1677 }
1678
1679 void R_RenderScene(void);
1680
1681 matrix4x4_t r_waterscrollmatrix;
1682
1683 /*
1684 ================
1685 R_RenderView
1686 ================
1687 */
1688 void R_RenderView(void)
1689 {
1690         if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1691                 return; //Host_Error ("R_RenderView: NULL worldmodel");
1692
1693         r_view_width = bound(0, r_refdef.width, vid.width);
1694         r_view_height = bound(0, r_refdef.height, vid.height);
1695         r_view_depth = 1;
1696         r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1697         r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1698         r_view_z = 0;
1699         r_view_matrix = r_refdef.viewentitymatrix;
1700         GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1701         r_rtworld = r_shadow_realtime_world.integer;
1702         r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1703         r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1704         r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1705         r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1706         r_polygonfactor = 0;
1707         r_polygonoffset = 0;
1708         r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1709         r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1710         if (r_showsurfaces.integer)
1711         {
1712                 r_rtworld = false;
1713                 r_rtworldshadows = false;
1714                 r_rtdlight = false;
1715                 r_rtdlightshadows = false;
1716                 r_lightmapintensity = 0;
1717         }
1718
1719         // GL is weird because it's bottom to top, r_view_y is top to bottom
1720         qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1721         GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1722         GL_ScissorTest(true);
1723         GL_DepthMask(true);
1724         R_ClearScreen();
1725         R_Textures_Frame();
1726         R_UpdateFog();
1727         if (r_timereport_active)
1728                 R_TimeReport("setup");
1729
1730         qglDepthFunc(GL_LEQUAL);
1731         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1732         qglEnable(GL_POLYGON_OFFSET_FILL);
1733
1734         R_RenderScene();
1735
1736         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1737         qglDisable(GL_POLYGON_OFFSET_FILL);
1738
1739         R_BlendView();
1740         if (r_timereport_active)
1741                 R_TimeReport("blendview");
1742
1743         GL_Scissor(0, 0, vid.width, vid.height);
1744         GL_ScissorTest(false);
1745 }
1746
1747 //[515]: csqc
1748 void CSQC_R_ClearScreen (void)
1749 {
1750         if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1751                 return; //Host_Error ("R_RenderView: NULL worldmodel");
1752
1753         r_view_width = bound(0, r_refdef.width, vid.width);
1754         r_view_height = bound(0, r_refdef.height, vid.height);
1755         r_view_depth = 1;
1756         r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1757         r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1758         r_view_z = 0;
1759         r_view_matrix = r_refdef.viewentitymatrix;
1760         GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1761         r_rtworld = r_shadow_realtime_world.integer;
1762         r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1763         r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1764         r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1765         r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1766         r_polygonfactor = 0;
1767         r_polygonoffset = 0;
1768         r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1769         r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1770         if (r_showsurfaces.integer)
1771         {
1772                 r_rtworld = false;
1773                 r_rtworldshadows = false;
1774                 r_rtdlight = false;
1775                 r_rtdlightshadows = false;
1776                 r_lightmapintensity = 0;
1777         }
1778
1779         // GL is weird because it's bottom to top, r_view_y is top to bottom
1780         qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1781         GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1782         GL_ScissorTest(true);
1783         GL_DepthMask(true);
1784         R_ClearScreen();
1785         R_Textures_Frame();
1786         R_UpdateFog();
1787         if (r_timereport_active)
1788                 R_TimeReport("setup");
1789 }
1790
1791 //[515]: csqc
1792 void CSQC_R_RenderScene (void)
1793 {
1794         qglDepthFunc(GL_LEQUAL);
1795         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1796         qglEnable(GL_POLYGON_OFFSET_FILL);
1797
1798         R_RenderScene();
1799
1800         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1801         qglDisable(GL_POLYGON_OFFSET_FILL);
1802
1803         R_BlendView();
1804         if (r_timereport_active)
1805                 R_TimeReport("blendview");
1806
1807         GL_Scissor(0, 0, vid.width, vid.height);
1808         GL_ScissorTest(false);
1809 }
1810
1811 extern void R_DrawLightningBeams (void);
1812 extern void VM_AddPolygonsToMeshQueue (void);
1813 void R_RenderScene(void)
1814 {
1815         float nearclip;
1816
1817         // don't let sound skip if going slow
1818         if (r_refdef.extraupdate)
1819                 S_ExtraUpdate ();
1820
1821         r_framecount++;
1822
1823         if (gl_support_fragment_shader)
1824                 qglUseProgramObjectARB(0);
1825
1826         R_MeshQueue_BeginScene();
1827
1828         R_SetFrustum();
1829
1830         r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
1831         nearclip = bound (0.001f, r_nearclip.value, r_farclip - 1.0f);
1832
1833         if (r_rtworldshadows || r_rtdlightshadows)
1834                 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_refdef.frustum_x, r_refdef.frustum_y, nearclip);
1835         else
1836                 GL_SetupView_Mode_Perspective(r_refdef.frustum_x, r_refdef.frustum_y, nearclip, r_farclip);
1837
1838         GL_SetupView_Orientation_FromEntity(&r_view_matrix);
1839
1840         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);
1841
1842         R_SkyStartFrame();
1843
1844         R_WorldVisibility();
1845         if (r_timereport_active)
1846                 R_TimeReport("worldvis");
1847
1848         R_MarkEntities();
1849         if (r_timereport_active)
1850                 R_TimeReport("markentity");
1851
1852         R_Shadow_UpdateWorldLightSelection();
1853
1854         if (cl.csqc_vidvars.drawworld)
1855         {
1856                 // don't let sound skip if going slow
1857                 if (r_refdef.extraupdate)
1858                         S_ExtraUpdate ();
1859
1860                 if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
1861                 {
1862                         r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
1863                         if (r_timereport_active)
1864                                 R_TimeReport("worldsky");
1865                 }
1866
1867                 if (R_DrawBrushModelsSky() && r_timereport_active)
1868                         R_TimeReport("bmodelsky");
1869
1870                 if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
1871                 {
1872                         r_refdef.worldmodel->Draw(r_refdef.worldentity);
1873                         if (r_timereport_active)
1874                                 R_TimeReport("world");
1875                 }
1876         }
1877
1878         // don't let sound skip if going slow
1879         if (r_refdef.extraupdate)
1880                 S_ExtraUpdate ();
1881
1882         R_DrawModels();
1883         if (r_timereport_active)
1884                 R_TimeReport("models");
1885
1886         // don't let sound skip if going slow
1887         if (r_refdef.extraupdate)
1888                 S_ExtraUpdate ();
1889
1890         R_ShadowVolumeLighting(false);
1891         if (r_timereport_active)
1892                 R_TimeReport("rtlights");
1893
1894         // don't let sound skip if going slow
1895         if (r_refdef.extraupdate)
1896                 S_ExtraUpdate ();
1897
1898         if (cl.csqc_vidvars.drawworld)
1899         {
1900                 R_DrawLightningBeams();
1901                 if (r_timereport_active)
1902                         R_TimeReport("lightning");
1903
1904                 R_DrawParticles();
1905                 if (r_timereport_active)
1906                         R_TimeReport("particles");
1907
1908                 R_DrawExplosions();
1909                 if (r_timereport_active)
1910                         R_TimeReport("explosions");
1911         }
1912
1913         R_MeshQueue_RenderTransparent();
1914         if (r_timereport_active)
1915                 R_TimeReport("drawtrans");
1916
1917         if (cl.csqc_vidvars.drawworld)
1918         {
1919                 R_DrawCoronas();
1920                 if (r_timereport_active)
1921                         R_TimeReport("coronas");
1922         }
1923         if(cl.csqc_vidvars.drawcrosshair)
1924         {
1925                 R_DrawWorldCrosshair();
1926                 if (r_timereport_active)
1927                         R_TimeReport("crosshair");
1928         }
1929
1930         VM_AddPolygonsToMeshQueue();
1931
1932         R_MeshQueue_Render();
1933
1934         R_MeshQueue_EndScene();
1935
1936         // don't let sound skip if going slow
1937         if (r_refdef.extraupdate)
1938                 S_ExtraUpdate ();
1939
1940         if (gl_support_fragment_shader)
1941                 qglUseProgramObjectARB(0);
1942 }
1943
1944 /*
1945 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
1946 {
1947         int i;
1948         float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
1949         rmeshstate_t m;
1950         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1951         GL_DepthMask(false);
1952         GL_DepthTest(true);
1953         R_Mesh_Matrix(&identitymatrix);
1954
1955         vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
1956         vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
1957         vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
1958         vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
1959         vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
1960         vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
1961         vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
1962         vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
1963         R_FillColors(color, 8, cr, cg, cb, ca);
1964         if (fogenabled)
1965         {
1966                 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
1967                 {
1968                         f2 = VERTEXFOGTABLE(VectorDistance(v, r_vieworigin));
1969                         f1 = 1 - f2;
1970                         c[0] = c[0] * f1 + fogcolor[0] * f2;
1971                         c[1] = c[1] * f1 + fogcolor[1] * f2;
1972                         c[2] = c[2] * f1 + fogcolor[2] * f2;
1973                 }
1974         }
1975         memset(&m, 0, sizeof(m));
1976         m.pointer_vertex = vertex3f;
1977         m.pointer_color = color;
1978         R_Mesh_State(&m);
1979         R_Mesh_Draw(8, 12);
1980 }
1981 */
1982
1983 int nomodelelements[24] =
1984 {
1985         5, 2, 0,
1986         5, 1, 2,
1987         5, 0, 3,
1988         5, 3, 1,
1989         0, 2, 4,
1990         2, 1, 4,
1991         3, 0, 4,
1992         1, 3, 4
1993 };
1994
1995 float nomodelvertex3f[6*3] =
1996 {
1997         -16,   0,   0,
1998          16,   0,   0,
1999           0, -16,   0,
2000           0,  16,   0,
2001           0,   0, -16,
2002           0,   0,  16
2003 };
2004
2005 float nomodelcolor4f[6*4] =
2006 {
2007         0.0f, 0.0f, 0.5f, 1.0f,
2008         0.0f, 0.0f, 0.5f, 1.0f,
2009         0.0f, 0.5f, 0.0f, 1.0f,
2010         0.0f, 0.5f, 0.0f, 1.0f,
2011         0.5f, 0.0f, 0.0f, 1.0f,
2012         0.5f, 0.0f, 0.0f, 1.0f
2013 };
2014
2015 void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
2016 {
2017         int i;
2018         float f1, f2, *c;
2019         float color4f[6*4];
2020         rmeshstate_t m;
2021         R_Mesh_Matrix(&ent->matrix);
2022
2023         memset(&m, 0, sizeof(m));
2024         m.pointer_vertex = nomodelvertex3f;
2025
2026         if (ent->flags & EF_ADDITIVE)
2027         {
2028                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2029                 GL_DepthMask(false);
2030         }
2031         else if (ent->alpha < 1)
2032         {
2033                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2034                 GL_DepthMask(false);
2035         }
2036         else
2037         {
2038                 GL_BlendFunc(GL_ONE, GL_ZERO);
2039                 GL_DepthMask(true);
2040         }
2041         GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
2042         if (fogenabled)
2043         {
2044                 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2045                 m.pointer_color = color4f;
2046                 f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_vieworigin));
2047                 f1 = 1 - f2;
2048                 for (i = 0, c = color4f;i < 6;i++, c += 4)
2049                 {
2050                         c[0] = (c[0] * f1 + fogcolor[0] * f2);
2051                         c[1] = (c[1] * f1 + fogcolor[1] * f2);
2052                         c[2] = (c[2] * f1 + fogcolor[2] * f2);
2053                         c[3] *= ent->alpha;
2054                 }
2055         }
2056         else if (ent->alpha != 1)
2057         {
2058                 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2059                 m.pointer_color = color4f;
2060                 for (i = 0, c = color4f;i < 6;i++, c += 4)
2061                         c[3] *= ent->alpha;
2062         }
2063         else
2064                 m.pointer_color = nomodelcolor4f;
2065         R_Mesh_State(&m);
2066         R_Mesh_Draw(0, 6, 8, nomodelelements);
2067 }
2068
2069 void R_DrawNoModel(entity_render_t *ent)
2070 {
2071         //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
2072                 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight);
2073         //else
2074         //      R_DrawNoModelCallback(ent, 0);
2075 }
2076
2077 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
2078 {
2079         vec3_t right1, right2, diff, normal;
2080
2081         VectorSubtract (org2, org1, normal);
2082
2083         // calculate 'right' vector for start
2084         VectorSubtract (r_vieworigin, org1, diff);
2085         CrossProduct (normal, diff, right1);
2086         VectorNormalize (right1);
2087
2088         // calculate 'right' vector for end
2089         VectorSubtract (r_vieworigin, org2, diff);
2090         CrossProduct (normal, diff, right2);
2091         VectorNormalize (right2);
2092
2093         vert[ 0] = org1[0] + width * right1[0];
2094         vert[ 1] = org1[1] + width * right1[1];
2095         vert[ 2] = org1[2] + width * right1[2];
2096         vert[ 3] = org1[0] - width * right1[0];
2097         vert[ 4] = org1[1] - width * right1[1];
2098         vert[ 5] = org1[2] - width * right1[2];
2099         vert[ 6] = org2[0] - width * right2[0];
2100         vert[ 7] = org2[1] - width * right2[1];
2101         vert[ 8] = org2[2] - width * right2[2];
2102         vert[ 9] = org2[0] + width * right2[0];
2103         vert[10] = org2[1] + width * right2[1];
2104         vert[11] = org2[2] + width * right2[2];
2105 }
2106
2107 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
2108
2109 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)
2110 {
2111         float fog = 0.0f, ifog;
2112         rmeshstate_t m;
2113         float vertex3f[12];
2114
2115         if (fogenabled)
2116                 fog = VERTEXFOGTABLE(VectorDistance(origin, r_vieworigin));
2117         ifog = 1 - fog;
2118
2119         R_Mesh_Matrix(&identitymatrix);
2120         GL_BlendFunc(blendfunc1, blendfunc2);
2121         GL_DepthMask(false);
2122         GL_DepthTest(!depthdisable);
2123
2124         vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
2125         vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
2126         vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
2127         vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
2128         vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
2129         vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
2130         vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
2131         vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
2132         vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
2133         vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
2134         vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
2135         vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
2136
2137         memset(&m, 0, sizeof(m));
2138         m.tex[0] = R_GetTexture(texture);
2139         m.pointer_texcoord[0] = spritetexcoord2f;
2140         m.pointer_vertex = vertex3f;
2141         R_Mesh_State(&m);
2142         GL_Color(cr * ifog, cg * ifog, cb * ifog, ca);
2143         R_Mesh_Draw(0, 4, 2, polygonelements);
2144
2145         if (blendfunc2 == GL_ONE_MINUS_SRC_ALPHA)
2146         {
2147                 R_Mesh_TexBind(0, R_GetTexture(fogtexture));
2148                 GL_BlendFunc(blendfunc1, GL_ONE);
2149                 GL_Color(fogcolor[0] * fog, fogcolor[1] * fog, fogcolor[2] * fog, ca);
2150                 R_Mesh_Draw(0, 4, 2, polygonelements);
2151         }
2152 }
2153
2154 int R_Mesh_AddVertex3f(rmesh_t *mesh, const float *v)
2155 {
2156         int i;
2157         float *vertex3f;
2158         for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
2159                 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
2160                         break;
2161         if (i == mesh->numvertices)
2162         {
2163                 if (mesh->numvertices < mesh->maxvertices)
2164                 {
2165                         VectorCopy(v, vertex3f);
2166                         mesh->numvertices++;
2167                 }
2168                 return mesh->numvertices;
2169         }
2170         else
2171                 return i;
2172 }
2173
2174 void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
2175 {
2176         int i;
2177         int *e, element[3];
2178         element[0] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2179         element[1] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2180         e = mesh->element3i + mesh->numtriangles * 3;
2181         for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
2182         {
2183                 element[2] = R_Mesh_AddVertex3f(mesh, vertex3f);
2184                 if (mesh->numtriangles < mesh->maxtriangles)
2185                 {
2186                         *e++ = element[0];
2187                         *e++ = element[1];
2188                         *e++ = element[2];
2189                         mesh->numtriangles++;
2190                 }
2191                 element[1] = element[2];
2192         }
2193 }
2194
2195 void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
2196 {
2197         int planenum, planenum2;
2198         int w;
2199         int tempnumpoints;
2200         mplane_t *plane, *plane2;
2201         float temppoints[2][256*3];
2202         for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
2203         {
2204                 w = 0;
2205                 tempnumpoints = 4;
2206                 PolygonF_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->normal[3], 1024.0*1024.0*1024.0);
2207                 for (planenum2 = 0, plane2 = planes;planenum2 < numplanes && tempnumpoints >= 3;planenum2++, plane2++)
2208                 {
2209                         if (planenum2 == planenum)
2210                                 continue;
2211                         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);
2212                         w = !w;
2213                 }
2214                 if (tempnumpoints < 3)
2215                         continue;
2216                 // generate elements forming a triangle fan for this polygon
2217                 R_Mesh_AddPolygon3f(mesh, tempnumpoints, temppoints[w]);
2218         }
2219 }
2220
2221 static void R_DrawCollisionBrush(colbrushf_t *brush)
2222 {
2223         int i;
2224         rmeshstate_t m;
2225         memset(&m, 0, sizeof(m));
2226         m.pointer_vertex = brush->points->v;
2227         R_Mesh_State(&m);
2228         i = (int)(((size_t)brush) / sizeof(colbrushf_t));
2229         GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2230         GL_LockArrays(0, brush->numpoints);
2231         R_Mesh_Draw(0, brush->numpoints, brush->numtriangles, brush->elements);
2232         GL_LockArrays(0, 0);
2233 }
2234
2235 static void R_DrawCollisionSurface(entity_render_t *ent, msurface_t *surface)
2236 {
2237         int i;
2238         rmeshstate_t m;
2239         if (!surface->num_collisiontriangles)
2240                 return;
2241         memset(&m, 0, sizeof(m));
2242         m.pointer_vertex = surface->data_collisionvertex3f;
2243         R_Mesh_State(&m);
2244         i = (int)(((size_t)surface) / sizeof(msurface_t));
2245         GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2246         GL_LockArrays(0, surface->num_collisionvertices);
2247         R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i);
2248         GL_LockArrays(0, 0);
2249 }
2250
2251 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)
2252 {
2253         texturelayer_t *layer;
2254         layer = t->currentlayers + t->currentnumlayers++;
2255         layer->type = type;
2256         layer->depthmask = depthmask;
2257         layer->blendfunc1 = blendfunc1;
2258         layer->blendfunc2 = blendfunc2;
2259         layer->texture = texture;
2260         layer->texmatrix = *matrix;
2261         layer->color[0] = r;
2262         layer->color[1] = g;
2263         layer->color[2] = b;
2264         layer->color[3] = a;
2265 }
2266
2267 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
2268 {
2269         // FIXME: identify models using a better check than ent->model->brush.shadowmesh
2270         //int lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
2271
2272         {
2273                 texture_t *texture = t;
2274                 model_t *model = ent->model;
2275                 int s = ent->skinnum;
2276                 if ((unsigned int)s >= (unsigned int)model->numskins)
2277                         s = 0;
2278                 if (model->skinscenes)
2279                 {
2280                         if (model->skinscenes[s].framecount > 1)
2281                                 s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
2282                         else
2283                                 s = model->skinscenes[s].firstframe;
2284                 }
2285                 if (s > 0)
2286                         t = t + s * model->num_surfaces;
2287                 if (t->animated)
2288                         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];
2289                 texture->currentframe = t;
2290         }
2291
2292         t->currentmaterialflags = t->basematerialflags;
2293         t->currentalpha = ent->alpha;
2294         if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
2295                 t->currentalpha *= r_wateralpha.value;
2296         if (!(ent->flags & RENDER_LIGHT))
2297                 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
2298         if (ent->effects & EF_ADDITIVE)
2299                 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_TRANSPARENT;
2300         else if (t->currentalpha < 1)
2301                 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT;
2302         if (ent->effects & EF_NODEPTHTEST)
2303                 t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST;
2304         if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
2305                 t->currenttexmatrix = r_waterscrollmatrix;
2306         else
2307                 t->currenttexmatrix = identitymatrix;
2308
2309         t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
2310         t->basetexture = (!t->colormapping && t->skin.merged) ? t->skin.merged : t->skin.base;
2311         t->glosstexture = r_texture_white;
2312         t->specularpower = 8;
2313         t->specularscale = 0;
2314         if (r_shadow_gloss.integer > 0)
2315         {
2316                 if (t->skin.gloss)
2317                 {
2318                         if (r_shadow_glossintensity.value > 0)
2319                         {
2320                                 t->glosstexture = t->skin.gloss;
2321                                 t->specularscale = r_shadow_glossintensity.value;
2322                         }
2323                 }
2324                 else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0)
2325                         t->specularscale = r_shadow_gloss2intensity.value;
2326         }
2327
2328         t->currentnumlayers = 0;
2329         if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
2330         {
2331                 if (gl_lightmaps.integer)
2332                         R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, r_texture_white, &identitymatrix, 1, 1, 1, 1);
2333                 else if (!(t->currentmaterialflags & MATERIALFLAG_SKY))
2334                 {
2335                         int blendfunc1, blendfunc2, depthmask;
2336                         if (t->currentmaterialflags & MATERIALFLAG_ADD)
2337                         {
2338                                 blendfunc1 = GL_SRC_ALPHA;
2339                                 blendfunc2 = GL_ONE;
2340                                 depthmask = false;
2341                         }
2342                         else if (t->currentmaterialflags & MATERIALFLAG_ALPHA)
2343                         {
2344                                 blendfunc1 = GL_SRC_ALPHA;
2345                                 blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
2346                                 depthmask = false;
2347                         }
2348                         else
2349                         {
2350                                 blendfunc1 = GL_ONE;
2351                                 blendfunc2 = GL_ZERO;
2352                                 depthmask = true;
2353                         }
2354                         if (t->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
2355                         {
2356                                 rtexture_t *currentbasetexture;
2357                                 int layerflags = 0;
2358                                 if (fogenabled && (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2359                                         layerflags |= TEXTURELAYERFLAG_FOGDARKEN;
2360                                 currentbasetexture = (VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) < (1.0f / 1048576.0f) && t->skin.merged) ? t->skin.merged : t->skin.base;
2361                                 if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2362                                 {
2363                                         // fullbright is not affected by r_lightmapintensity
2364                                         R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0], ent->colormod[1], ent->colormod[2], t->currentalpha);
2365                                         if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2366                                                 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);
2367                                         if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2368                                                 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);
2369                                 }
2370                                 else
2371                                 {
2372                                         float colorscale;
2373                                         colorscale = 2;
2374                                         // q3bsp has no lightmap updates, so the lightstylevalue that
2375                                         // would normally be baked into the lightmaptexture must be
2376                                         // applied to the color
2377                                         if (ent->model->type == mod_brushq3)
2378                                                 colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
2379                                         colorscale *= r_lightmapintensity;
2380                                         if (r_textureunits.integer >= 2 && gl_combine.integer)
2381                                                 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);
2382                                         else if ((t->currentmaterialflags & MATERIALFLAG_TRANSPARENT) == 0)
2383                                                 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);
2384                                         else
2385                                                 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);
2386                                         if (r_ambient.value >= (1.0f/64.0f))
2387                                                 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);
2388                                         if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2389                                         {
2390                                                 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);
2391                                                 if (r_ambient.value >= (1.0f/64.0f))
2392                                                         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);
2393                                         }
2394                                         if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2395                                         {
2396                                                 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);
2397                                                 if (r_ambient.value >= (1.0f/64.0f))
2398                                                         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);
2399                                         }
2400                                 }
2401                                 if (t->skin.glow != NULL)
2402                                         R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, t->currentalpha);
2403                                 if (fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
2404                                 {
2405                                         // if this is opaque use alpha blend which will darken the earlier
2406                                         // passes cheaply.
2407                                         //
2408                                         // if this is an alpha blended material, all the earlier passes
2409                                         // were darkened by fog already, so we only need to add the fog
2410                                         // color ontop through the fog mask texture
2411                                         //
2412                                         // if this is an additive blended material, all the earlier passes
2413                                         // were darkened by fog already, and we should not add fog color
2414                                         // (because the background was not darkened, there is no fog color
2415                                         // that was lost behind it).
2416                                         R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], t->currentalpha);
2417                                 }
2418                         }
2419                 }
2420         }
2421 }
2422
2423 void R_UpdateAllTextureInfo(entity_render_t *ent)
2424 {
2425         int i;
2426         if (ent->model)
2427                 for (i = 0;i < ent->model->num_textures;i++)
2428                         R_UpdateTextureInfo(ent, ent->model->data_textures + i);
2429 }
2430
2431 int rsurface_array_size = 0;
2432 float *rsurface_array_vertex3f = NULL;
2433 float *rsurface_array_svector3f = NULL;
2434 float *rsurface_array_tvector3f = NULL;
2435 float *rsurface_array_normal3f = NULL;
2436 float *rsurface_array_color4f = NULL;
2437 float *rsurface_array_texcoord3f = NULL;
2438
2439 void R_Mesh_ResizeArrays(int newvertices)
2440 {
2441         if (rsurface_array_size >= newvertices)
2442                 return;
2443         if (rsurface_array_vertex3f)
2444                 Mem_Free(rsurface_array_vertex3f);
2445         rsurface_array_size = (newvertices + 1023) & ~1023;
2446         rsurface_array_vertex3f = Mem_Alloc(r_main_mempool, rsurface_array_size * sizeof(float[19]));
2447         rsurface_array_svector3f = rsurface_array_vertex3f + rsurface_array_size * 3;
2448         rsurface_array_tvector3f = rsurface_array_vertex3f + rsurface_array_size * 6;
2449         rsurface_array_normal3f = rsurface_array_vertex3f + rsurface_array_size * 9;
2450         rsurface_array_color4f = rsurface_array_vertex3f + rsurface_array_size * 12;
2451         rsurface_array_texcoord3f = rsurface_array_vertex3f + rsurface_array_size * 16;
2452 }
2453
2454 float *rsurface_vertex3f;
2455 float *rsurface_svector3f;
2456 float *rsurface_tvector3f;
2457 float *rsurface_normal3f;
2458 float *rsurface_lightmapcolor4f;
2459 qboolean rsurface_generatevertex;
2460 qboolean rsurface_generatetangents;
2461 qboolean rsurface_generatenormals;
2462 qboolean rsurface_deformvertex;
2463 qboolean rsurface_dynamicvertex;
2464 vec3_t rsurface_modelorg;
2465 const entity_render_t *rsurface_entity;
2466 const model_t *rsurface_model;
2467 const texture_t *rsurface_texture;
2468
2469 void RSurf_PrepareForBatch(const entity_render_t *ent, const texture_t *texture, const vec3_t modelorg)
2470 {
2471         VectorCopy(modelorg, rsurface_modelorg);
2472         rsurface_entity = ent;
2473         rsurface_model = ent->model;
2474         rsurface_texture = texture;
2475 }
2476
2477 void RSurf_SetPointersForPass(qboolean generatenormals, qboolean generatetangents)
2478 {
2479         if (rsurface_array_size < rsurface_model->surfmesh.num_vertices)
2480                 R_Mesh_ResizeArrays(rsurface_model->surfmesh.num_vertices);
2481         if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexboneweights))
2482         {
2483                 rsurface_generatevertex = true;
2484                 rsurface_generatetangents = false;
2485                 rsurface_generatenormals = false;
2486                 rsurface_vertex3f = rsurface_array_vertex3f;
2487                 if (generatetangents || (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)))
2488                 {
2489                         rsurface_generatetangents = true;
2490                         rsurface_svector3f = rsurface_array_svector3f;
2491                         rsurface_tvector3f = rsurface_array_tvector3f;
2492                         rsurface_normal3f = rsurface_array_normal3f;
2493                 }
2494                 else
2495                 {
2496                         rsurface_svector3f = NULL;
2497                         rsurface_tvector3f = NULL;
2498                         if (generatenormals)
2499                         {
2500                                 rsurface_generatenormals = true;
2501                                 rsurface_normal3f = rsurface_array_normal3f;
2502                         }
2503                         else
2504                                 rsurface_normal3f = NULL;
2505                 }
2506         }
2507         else
2508         {
2509                 rsurface_generatevertex = false;
2510                 rsurface_generatetangents = false;
2511                 rsurface_generatenormals = false;
2512                 rsurface_vertex3f = rsurface_model->surfmesh.data_vertex3f;
2513                 rsurface_svector3f = rsurface_model->surfmesh.data_svector3f;
2514                 rsurface_tvector3f = rsurface_model->surfmesh.data_tvector3f;
2515                 rsurface_normal3f = rsurface_model->surfmesh.data_normal3f;
2516         }
2517         if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2518         {
2519                 rsurface_deformvertex = true;
2520                 rsurface_vertex3f = rsurface_array_vertex3f;
2521                 rsurface_svector3f = rsurface_array_svector3f;
2522                 rsurface_tvector3f = rsurface_array_tvector3f;
2523                 rsurface_normal3f = rsurface_array_normal3f;
2524         }
2525         else
2526                 rsurface_deformvertex = false;
2527         R_Mesh_VertexPointer(rsurface_vertex3f);
2528         rsurface_dynamicvertex = rsurface_generatevertex || rsurface_deformvertex;
2529 }
2530
2531 void RSurf_PrepareDynamicSurfaceVertices(const msurface_t *surface)
2532 {
2533         float *vertex3f, *svector3f, *tvector3f, *normal3f;
2534         model_t *model = rsurface_entity->model;
2535         if (!rsurface_dynamicvertex)
2536                 return;
2537         if (rsurface_generatevertex)
2538         {
2539                 Mod_Alias_GetMesh_Vertex3f(model, rsurface_entity->frameblend, rsurface_array_vertex3f);
2540                 if (rsurface_generatetangents)
2541                         Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, model->surfmesh.data_texcoordtexture2f, model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
2542                 else if (rsurface_generatenormals)
2543                         Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
2544         }
2545         if (rsurface_deformvertex)
2546         {
2547                 int i, j;
2548                 float center[3], forward[3], right[3], up[3], v[4][3];
2549                 matrix4x4_t matrix1, imatrix1;
2550                 if (rsurface_generatevertex)
2551                 {
2552                         vertex3f = rsurface_array_vertex3f;
2553                         svector3f = rsurface_array_svector3f;
2554                         tvector3f = rsurface_array_tvector3f;
2555                         normal3f = rsurface_array_normal3f;
2556                 }
2557                 else
2558                 {
2559                         vertex3f = rsurface_vertex3f;
2560                         svector3f = rsurface_svector3f;
2561                         tvector3f = rsurface_tvector3f;
2562                         normal3f = rsurface_normal3f;
2563                 }
2564                 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewforward, forward);
2565                 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewright, right);
2566                 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewup, up);
2567                 // a single autosprite surface can contain multiple sprites...
2568                 for (j = 0;j < surface->num_vertices - 3;j += 4)
2569                 {
2570                         VectorClear(center);
2571                         for (i = 0;i < 4;i++)
2572                                 VectorAdd(center, (vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
2573                         VectorScale(center, 0.25f, center);
2574                         // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
2575                         Matrix4x4_FromVectors(&matrix1, (normal3f + 3 * surface->num_firstvertex) + j*3, (svector3f + 3 * surface->num_firstvertex) + j*3, (tvector3f + 3 * surface->num_firstvertex) + j*3, center);
2576                         Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
2577                         for (i = 0;i < 4;i++)
2578                                 Matrix4x4_Transform(&imatrix1, (vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
2579                         if (rsurface_texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
2580                         {
2581                                 forward[0] = rsurface_modelorg[0] - center[0];
2582                                 forward[1] = rsurface_modelorg[1] - center[1];
2583                                 forward[2] = 0;
2584                                 VectorNormalize(forward);
2585                                 right[0] = forward[1];
2586                                 right[1] = -forward[0];
2587                                 right[2] = 0;
2588                                 VectorSet(up, 0, 0, 1);
2589                         }
2590                         for (i = 0;i < 4;i++)
2591                                 VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_vertex3f + (surface->num_firstvertex+i+j) * 3);
2592                 }
2593                 Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, model->surfmesh.data_texcoordtexture2f, model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
2594         }
2595 }
2596
2597 static void RSurf_Draw(const msurface_t *surface)
2598 {
2599         GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2600         R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2601         GL_LockArrays(0, 0);
2602 }
2603
2604 static void RSurf_DrawLightmap(const msurface_t *surface, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
2605 {
2606         int i;
2607         float f;
2608         float *v, *c, *c2;
2609         if (lightmode >= 2)
2610         {
2611                 // model lighting
2612                 vec3_t ambientcolor;
2613                 vec3_t diffusecolor;
2614                 vec3_t lightdir;
2615                 VectorCopy(rsurface_entity->modellight_lightdir, lightdir);
2616                 ambientcolor[0] = rsurface_entity->modellight_ambient[0] * r * 0.5f;
2617                 ambientcolor[1] = rsurface_entity->modellight_ambient[1] * g * 0.5f;
2618                 ambientcolor[2] = rsurface_entity->modellight_ambient[2] * b * 0.5f;
2619                 diffusecolor[0] = rsurface_entity->modellight_diffuse[0] * r * 0.5f;
2620                 diffusecolor[1] = rsurface_entity->modellight_diffuse[1] * g * 0.5f;
2621                 diffusecolor[2] = rsurface_entity->modellight_diffuse[2] * b * 0.5f;
2622                 if (VectorLength2(diffusecolor) > 0)
2623                 {
2624                         int numverts = surface->num_vertices;
2625                         v = rsurface_vertex3f + 3 * surface->num_firstvertex;
2626                         c2 = rsurface_normal3f + 3 * surface->num_firstvertex;
2627                         c = rsurface_array_color4f + 4 * surface->num_firstvertex;
2628                         // q3-style directional shading
2629                         for (i = 0;i < numverts;i++, v += 3, c2 += 3, c += 4)
2630                         {
2631                                 if ((f = DotProduct(c2, lightdir)) > 0)
2632                                         VectorMA(ambientcolor, f, diffusecolor, c);
2633                                 else
2634                                         VectorCopy(ambientcolor, c);
2635                                 c[3] = a;
2636                         }
2637                         r = 1;
2638                         g = 1;
2639                         b = 1;
2640                         a = 1;
2641                         applycolor = false;
2642                         rsurface_lightmapcolor4f = rsurface_array_color4f;
2643                 }
2644                 else
2645                 {
2646                         r = ambientcolor[0];
2647                         g = ambientcolor[1];
2648                         b = ambientcolor[2];
2649                         rsurface_lightmapcolor4f = NULL;
2650                 }
2651         }
2652         else if (lightmode >= 1)
2653         {
2654                 if (surface->lightmapinfo && surface->lightmapinfo->stainsamples)
2655                 {
2656                         for (i = 0, c = rsurface_array_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
2657                         {
2658                                 if (surface->lightmapinfo->samples)
2659                                 {
2660                                         const unsigned char *lm = surface->lightmapinfo->samples + (rsurface_model->surfmesh.data_lightmapoffsets + surface->num_firstvertex)[i];
2661                                         float scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
2662                                         VectorScale(lm, scale, c);
2663                                         if (surface->lightmapinfo->styles[1] != 255)
2664                                         {
2665                                                 int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
2666                                                 lm += size3;
2667                                                 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
2668                                                 VectorMA(c, scale, lm, c);
2669                                                 if (surface->lightmapinfo->styles[2] != 255)
2670                                                 {
2671                                                         lm += size3;
2672                                                         scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
2673                                                         VectorMA(c, scale, lm, c);
2674                                                         if (surface->lightmapinfo->styles[3] != 255)
2675                                                         {
2676                                                                 lm += size3;
2677                                                                 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
2678                                                                 VectorMA(c, scale, lm, c);
2679                                                         }
2680                                                 }
2681                                         }
2682                                 }
2683                                 else
2684                                         VectorClear(c);
2685                         }
2686                         rsurface_lightmapcolor4f = rsurface_array_color4f;
2687                 }
2688                 else
2689                         rsurface_lightmapcolor4f = rsurface_model->surfmesh.data_lightmapcolor4f;
2690         }
2691         else
2692                 rsurface_lightmapcolor4f = NULL;
2693         if (applyfog)
2694         {
2695                 if (rsurface_lightmapcolor4f)
2696                 {
2697                         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)
2698                         {
2699                                 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2700                                 c2[0] = c[0] * f;
2701                                 c2[1] = c[1] * f;
2702                                 c2[2] = c[2] * f;
2703                                 c2[3] = c[3];
2704                         }
2705                 }
2706                 else
2707                 {
2708                         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)
2709                         {
2710                                 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2711                                 c2[0] = f;
2712                                 c2[1] = f;
2713                                 c2[2] = f;
2714                                 c2[3] = 1;
2715                         }
2716                 }
2717                 rsurface_lightmapcolor4f = rsurface_array_color4f;
2718         }
2719         if (applycolor && rsurface_lightmapcolor4f)
2720         {
2721                 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)
2722                 {
2723                         c2[0] = c[0] * r;
2724                         c2[1] = c[1] * g;
2725                         c2[2] = c[2] * b;
2726                         c2[3] = c[3] * a;
2727                 }
2728                 rsurface_lightmapcolor4f = rsurface_array_color4f;
2729         }
2730         R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
2731         GL_Color(r, g, b, a);
2732         RSurf_Draw(surface);
2733 }
2734
2735 static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
2736 {
2737         int texturesurfaceindex;
2738         int lightmode;
2739         const msurface_t *surface;
2740         model_t *model = ent->model;
2741         qboolean applycolor;
2742         qboolean applyfog;
2743         rmeshstate_t m;
2744         if (texture->currentmaterialflags & MATERIALFLAG_NODRAW)
2745                 return;
2746         r_shadow_rtlight = NULL;
2747         renderstats.entities_surfaces += texturenumsurfaces;
2748         // FIXME: identify models using a better check than model->brush.shadowmesh
2749         lightmode = ((ent->effects & EF_FULLBRIGHT) || model->brush.shadowmesh) ? 0 : 2;
2750         GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
2751         if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
2752                 qglDisable(GL_CULL_FACE);
2753         RSurf_PrepareForBatch(ent, texture, modelorg);
2754         if (texture->currentmaterialflags & MATERIALFLAG_SKY)
2755         {
2756                 // transparent sky would be ridiculous
2757                 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2758                 {
2759                         if (skyrendernow)
2760                         {
2761                                 skyrendernow = false;
2762                                 R_Sky();
2763                                 // restore entity matrix
2764                                 R_Mesh_Matrix(&ent->matrix);
2765                         }
2766                         GL_DepthMask(true);
2767                         // LordHavoc: HalfLife maps have freaky skypolys so don't use
2768                         // skymasking on them, and Quake3 never did sky masking (unlike
2769                         // software Quake and software Quake2), so disable the sky masking
2770                         // in Quake3 maps as it causes problems with q3map2 sky tricks,
2771                         // and skymasking also looks very bad when noclipping outside the
2772                         // level, so don't use it then either.
2773                         if (model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2774                         {
2775                                 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
2776                                 memset(&m, 0, sizeof(m));
2777                                 R_Mesh_State(&m);
2778                                 if (skyrendermasked)
2779                                 {
2780                                         // depth-only (masking)
2781                                         GL_ColorMask(0,0,0,0);
2782                                         // just to make sure that braindead drivers don't draw
2783                                         // anything despite that colormask...
2784                                         GL_BlendFunc(GL_ZERO, GL_ONE);
2785                                 }
2786                                 else
2787                                 {
2788                                         // fog sky
2789                                         GL_BlendFunc(GL_ONE, GL_ZERO);
2790                                 }
2791                                 RSurf_SetPointersForPass(false, false);
2792                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2793                                 {
2794                                         surface = texturesurfacelist[texturesurfaceindex];
2795                                         if (rsurface_dynamicvertex)
2796                                                 RSurf_PrepareDynamicSurfaceVertices(surface);
2797                                         RSurf_Draw(surface);
2798                                 }
2799                                 if (skyrendermasked)
2800                                         GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
2801                         }
2802                 }
2803         }
2804         else if (r_glsl.integer && gl_support_fragment_shader)
2805         {
2806                 if (texture->currentmaterialflags & MATERIALFLAG_ADD)
2807                 {
2808                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2809                         GL_DepthMask(false);
2810                 }
2811                 else if (texture->currentmaterialflags & MATERIALFLAG_ALPHA)
2812                 {
2813                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2814                         GL_DepthMask(false);
2815                 }
2816                 else
2817                 {
2818                         GL_BlendFunc(GL_ONE, GL_ZERO);
2819                         GL_DepthMask(true);
2820                 }
2821
2822                 memset(&m, 0, sizeof(m));
2823                 R_Mesh_State(&m);
2824                 GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], texture->currentalpha);
2825                 R_SetupSurfaceShader(ent, texture, modelorg, vec3_origin, lightmode == 2);
2826                 if (!r_glsl_permutation)
2827                         return;
2828                 RSurf_SetPointersForPass(false, true);
2829                 if (lightmode == 2)
2830                 {
2831                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2832                         {
2833                                 surface = texturesurfacelist[texturesurfaceindex];
2834                                 if (rsurface_dynamicvertex)
2835                                         RSurf_PrepareDynamicSurfaceVertices(surface);
2836                                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f);
2837                                 R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
2838                                 R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
2839                                 R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
2840                                 RSurf_Draw(surface);
2841                         }
2842                 }
2843                 else
2844                 {
2845                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2846                         {
2847                                 surface = texturesurfacelist[texturesurfaceindex];
2848                                 if (rsurface_dynamicvertex)
2849                                         RSurf_PrepareDynamicSurfaceVertices(surface);
2850                                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f);
2851                                 R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
2852                                 R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
2853                                 R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
2854                                 R_Mesh_TexCoordPointer(4, 2, model->surfmesh.data_texcoordlightmap2f);
2855                                 if (surface->lightmaptexture)
2856                                 {
2857                                         R_Mesh_TexBind(7, R_GetTexture(surface->lightmaptexture));
2858                                         if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2859                                                 R_Mesh_TexBind(8, R_GetTexture(surface->deluxemaptexture));
2860                                         R_Mesh_ColorPointer(NULL);
2861                                 }
2862                                 else
2863                                 {
2864                                         R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
2865                                         if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2866                                                 R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
2867                                         R_Mesh_ColorPointer(model->surfmesh.data_lightmapcolor4f);
2868                                 }
2869                                 RSurf_Draw(surface);
2870                         }
2871                 }
2872                 qglUseProgramObjectARB(0);
2873         }
2874         else if (texture->currentnumlayers)
2875         {
2876                 int layerindex;
2877                 texturelayer_t *layer;
2878                 for (layerindex = 0, layer = texture->currentlayers;layerindex < texture->currentnumlayers;layerindex++, layer++)
2879                 {
2880                         vec4_t layercolor;
2881                         int layertexrgbscale;
2882                         GL_DepthMask(layer->depthmask);
2883                         GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
2884                         if ((layer->color[0] > 2 || layer->color[1] > 2 || layer->color[2] > 2) && (gl_combine.integer || layer->depthmask))
2885                         {
2886                                 layertexrgbscale = 4;
2887                                 VectorScale(layer->color, 0.25f, layercolor);
2888                         }
2889                         else if ((layer->color[0] > 1 || layer->color[1] > 1 || layer->color[2] > 1) && (gl_combine.integer || layer->depthmask))
2890                         {
2891                                 layertexrgbscale = 2;
2892                                 VectorScale(layer->color, 0.5f, layercolor);
2893                         }
2894                         else
2895                         {
2896                                 layertexrgbscale = 1;
2897                                 VectorScale(layer->color, 1.0f, layercolor);
2898                         }
2899                         layercolor[3] = layer->color[3];
2900                         GL_Color(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
2901                         applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
2902                         applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
2903                         switch (layer->type)
2904                         {
2905                         case TEXTURELAYERTYPE_LITTEXTURE_COMBINE:
2906                                 memset(&m, 0, sizeof(m));
2907                                 m.tex[1] = R_GetTexture(layer->texture);
2908                                 m.texmatrix[1] = layer->texmatrix;
2909                                 m.texrgbscale[1] = layertexrgbscale;
2910                                 m.pointer_color = rsurface_array_color4f;
2911                                 R_Mesh_State(&m);
2912                                 RSurf_SetPointersForPass(lightmode == 2, false);
2913                                 if (lightmode == 2)
2914                                 {
2915                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2916                                         {
2917                                                 surface = texturesurfacelist[texturesurfaceindex];
2918                                                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f);
2919                                                 R_Mesh_TexCoordPointer(1, 2, model->surfmesh.data_texcoordtexture2f);
2920                                                 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2921                                                 if (rsurface_dynamicvertex)
2922                                                         RSurf_PrepareDynamicSurfaceVertices(surface);
2923                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
2924                                         }
2925                                 }
2926                                 else
2927                                 {
2928                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2929                                         {
2930                                                 surface = texturesurfacelist[texturesurfaceindex];
2931                                                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f);
2932                                                 R_Mesh_TexCoordPointer(1, 2, model->surfmesh.data_texcoordtexture2f);
2933                                                 if (rsurface_dynamicvertex)
2934                                                         RSurf_PrepareDynamicSurfaceVertices(surface);
2935                                                 if (surface->lightmaptexture)
2936                                                 {
2937                                                         R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
2938                                                         RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
2939                                                 }
2940                                                 else
2941                                                 {
2942                                                         R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2943                                                         RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
2944                                                 }
2945                                         }
2946                                 }
2947                                 break;
2948                         case TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS:
2949                                 memset(&m, 0, sizeof(m));
2950                                 m.tex[0] = R_GetTexture(layer->texture);
2951                                 m.texmatrix[0] = layer->texmatrix;
2952                                 m.pointer_color = rsurface_array_color4f;
2953                                 m.texrgbscale[0] = layertexrgbscale;
2954                                 R_Mesh_State(&m);
2955                                 RSurf_SetPointersForPass(lightmode == 2, false);
2956                                 if (lightmode == 2)
2957                                 {
2958                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2959                                         {
2960                                                 surface = texturesurfacelist[texturesurfaceindex];
2961                                                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f);
2962                                                 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2963                                                 if (rsurface_dynamicvertex)
2964                                                         RSurf_PrepareDynamicSurfaceVertices(surface);
2965                                                 RSurf_DrawLightmap(surface, 1, 1, 1, 1, 2, false, false);
2966                                         }
2967                                 }
2968                                 else
2969                                 {
2970                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2971                                         {
2972                                                 surface = texturesurfacelist[texturesurfaceindex];
2973                                                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f);
2974                                                 if (rsurface_dynamicvertex)
2975                                                         RSurf_PrepareDynamicSurfaceVertices(surface);
2976                                                 if (surface->lightmaptexture)
2977                                                 {
2978                                                         R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
2979                                                         RSurf_DrawLightmap(surface, 1, 1, 1, 1, 0, false, false);
2980                                                 }
2981                                                 else
2982                                                 {
2983                                                         R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2984                                                         RSurf_DrawLightmap(surface, 1, 1, 1, 1, 1, false, false);
2985                                                 }
2986                                         }
2987                                 }
2988                                 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
2989                                 memset(&m, 0, sizeof(m));
2990                                 m.tex[0] = R_GetTexture(layer->texture);
2991                                 m.texmatrix[0] = layer->texmatrix;
2992                                 m.pointer_color = rsurface_array_color4f;
2993                                 m.texrgbscale[0] = layertexrgbscale;
2994                                 R_Mesh_State(&m);
2995                                 RSurf_SetPointersForPass(false, false);
2996                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2997                                 {
2998                                         surface = texturesurfacelist[texturesurfaceindex];
2999                                         R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f);
3000                                         if (rsurface_dynamicvertex)
3001                                                 RSurf_PrepareDynamicSurfaceVertices(surface);
3002                                         RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, false);
3003                                 }
3004                                 break;
3005                         case TEXTURELAYERTYPE_LITTEXTURE_VERTEX:
3006                                 memset(&m, 0, sizeof(m));
3007                                 m.tex[0] = R_GetTexture(layer->texture);
3008                                 m.texmatrix[0] = layer->texmatrix;
3009                                 m.texrgbscale[0] = layertexrgbscale;
3010                                 m.pointer_color = rsurface_array_color4f;
3011                                 R_Mesh_State(&m);
3012                                 RSurf_SetPointersForPass(lightmode == 2, false);
3013                                 if (lightmode == 2)
3014                                 {
3015                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3016                                         {
3017                                                 surface = texturesurfacelist[texturesurfaceindex];
3018                                                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f);
3019                                                 if (rsurface_dynamicvertex)
3020                                                         RSurf_PrepareDynamicSurfaceVertices(surface);
3021                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
3022                                         }
3023                                 }
3024                                 else
3025                                 {
3026                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3027                                         {
3028                                                 surface = texturesurfacelist[texturesurfaceindex];
3029                                                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f);
3030                                                 if (rsurface_dynamicvertex)
3031                                                         RSurf_PrepareDynamicSurfaceVertices(surface);
3032                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
3033                                         }
3034                                 }
3035                                 break;
3036                         case TEXTURELAYERTYPE_TEXTURE:
3037                                 memset(&m, 0, sizeof(m));
3038                                 m.tex[0] = R_GetTexture(layer->texture);
3039                                 m.texmatrix[0] = layer->texmatrix;
3040                                 m.pointer_color = rsurface_array_color4f;
3041                                 m.texrgbscale[0] = layertexrgbscale;
3042                                 R_Mesh_State(&m);
3043                                 RSurf_SetPointersForPass(false, false);
3044                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3045                                 {
3046                                         surface = texturesurfacelist[texturesurfaceindex];
3047                                         R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f);
3048                                         if (rsurface_dynamicvertex)
3049                                                 RSurf_PrepareDynamicSurfaceVertices(surface);
3050                                         RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
3051                                 }
3052                                 break;
3053                         case TEXTURELAYERTYPE_FOG:
3054                                 memset(&m, 0, sizeof(m));
3055                                 if (layer->texture)
3056                                 {
3057                                         m.tex[0] = R_GetTexture(layer->texture);
3058                                         m.texmatrix[0] = layer->texmatrix;
3059                                 }
3060                                 R_Mesh_State(&m);
3061                                 RSurf_SetPointersForPass(false, false);
3062                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3063                                 {
3064                                         int i;
3065                                         float f, *v, *c;
3066                                         surface = texturesurfacelist[texturesurfaceindex];
3067                                         if (layer->texture)
3068                                                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f);
3069                                         R_Mesh_ColorPointer(rsurface_array_color4f);
3070                                         if (rsurface_dynamicvertex)
3071                                                 RSurf_PrepareDynamicSurfaceVertices(surface);
3072                                         for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (rsurface_array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
3073                                         {
3074                                                 f = VERTEXFOGTABLE(VectorDistance(v, modelorg));
3075                                                 c[0] = layercolor[0];
3076                                                 c[1] = layercolor[1];
3077                                                 c[2] = layercolor[2];
3078                                                 c[3] = f * layercolor[3];
3079                                         }
3080                                         RSurf_Draw(surface);
3081                                 }
3082                                 break;
3083                         default:
3084                                 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
3085                         }
3086                         // if trying to do overbright on first pass of an opaque surface
3087                         // when combine is not supported, brighten as a post process
3088                         if (layertexrgbscale > 1 && !gl_combine.integer && layer->depthmask)
3089                         {
3090                                 int scale;
3091                                 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
3092                                 GL_Color(1, 1, 1, 1);
3093                                 memset(&m, 0, sizeof(m));
3094                                 R_Mesh_State(&m);
3095                                 RSurf_SetPointersForPass(false, false);
3096                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3097                                 {
3098                                         surface = texturesurfacelist[texturesurfaceindex];
3099                                         if (rsurface_dynamicvertex)
3100                                                 RSurf_PrepareDynamicSurfaceVertices(surface);
3101                                         for (scale = 1;scale < layertexrgbscale;scale <<= 1)
3102                                                 RSurf_Draw(surface);
3103                                 }
3104                         }
3105                 }
3106         }
3107         if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
3108                 qglEnable(GL_CULL_FACE);
3109 }
3110
3111 static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
3112 {
3113         const msurface_t *surface = ent->model->data_surfaces + surfacenumber;
3114         vec3_t modelorg;
3115         texture_t *texture;
3116
3117         texture = surface->texture;
3118         if (texture->basematerialflags & MATERIALFLAG_SKY)
3119                 return; // transparent sky is too difficult
3120         R_UpdateTextureInfo(ent, texture);
3121
3122         R_Mesh_Matrix(&ent->matrix);
3123         Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
3124         R_DrawTextureSurfaceList(ent, texture->currentframe, 1, &surface, modelorg);
3125 }
3126
3127 void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
3128 {
3129         int texturesurfaceindex;
3130         const msurface_t *surface;
3131         vec3_t tempcenter, center;
3132         if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)
3133         {
3134                 // drawing sky transparently would be too difficult
3135                 if (!(texture->currentmaterialflags & MATERIALFLAG_SKY))
3136                 {
3137                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3138                         {
3139                                 surface = texturesurfacelist[texturesurfaceindex];
3140                                 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
3141                                 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
3142                                 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
3143                                 Matrix4x4_Transform(&ent->matrix, tempcenter, center);
3144                                 R_MeshQueue_AddTransparent(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, R_DrawSurface_TransparentCallback, ent, surface - ent->model->data_surfaces, r_shadow_rtlight);
3145                         }
3146                 }
3147         }
3148         else
3149                 R_DrawTextureSurfaceList(ent, texture, texturenumsurfaces, texturesurfacelist, modelorg);
3150 }
3151
3152 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
3153 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
3154 {
3155         int i, j, f, flagsmask;
3156         int counttriangles = 0;
3157         msurface_t *surface, **surfacechain;
3158         texture_t *t, *texture;
3159         model_t *model = ent->model;
3160         vec3_t modelorg;
3161         const int maxsurfacelist = 1024;
3162         int numsurfacelist = 0;
3163         const msurface_t *surfacelist[1024];
3164         if (model == NULL)
3165                 return;
3166         R_Mesh_Matrix(&ent->matrix);
3167         Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
3168
3169         // update light styles
3170         if (!skysurfaces && model->brushq1.light_styleupdatechains)
3171         {
3172                 for (i = 0;i < model->brushq1.light_styles;i++)
3173                 {
3174                         if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
3175                         {
3176                                 model->brushq1.light_stylevalue[i] = r_refdef.lightstylevalue[model->brushq1.light_style[i]];
3177                                 if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
3178                                         for (;(surface = *surfacechain);surfacechain++)
3179                                                 surface->cached_dlight = true;
3180                         }
3181                 }
3182         }
3183
3184         R_UpdateAllTextureInfo(ent);
3185         flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
3186         f = 0;
3187         t = NULL;
3188         texture = NULL;
3189         numsurfacelist = 0;
3190         if (r_showsurfaces.integer)
3191         {
3192                 rmeshstate_t m;
3193                 GL_DepthTest(true);
3194                 GL_DepthMask(true);
3195                 GL_BlendFunc(GL_ONE, GL_ZERO);
3196                 memset(&m, 0, sizeof(m));
3197                 R_Mesh_State(&m);
3198                 t = NULL;
3199                 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3200                 {
3201                         if (ent == r_refdef.worldentity && !r_worldsurfacevisible[j])
3202                                 continue;
3203                         if (t != surface->texture)
3204                         {
3205                                 t = surface->texture;
3206                                 texture = t->currentframe;
3207                                 RSurf_PrepareForBatch(ent, texture, modelorg);
3208                                 RSurf_SetPointersForPass(false, false);
3209                         }
3210                         if ((texture->currentmaterialflags & flagsmask) && surface->num_triangles)
3211                         {
3212                                 int k = (int)(((size_t)surface) / sizeof(msurface_t));
3213                                 GL_Color((k & 15) * (1.0f / 16.0f), ((k >> 4) & 15) * (1.0f / 16.0f), ((k >> 8) & 15) * (1.0f / 16.0f), 0.2f);
3214                                 if (rsurface_dynamicvertex)
3215                                         RSurf_PrepareDynamicSurfaceVertices(surface);
3216                                 RSurf_Draw(surface);
3217                                 renderstats.entities_triangles += surface->num_triangles;
3218                         }
3219                         renderstats.entities_surfaces++;
3220                 }
3221         }
3222         else if (ent == r_refdef.worldentity)
3223         {
3224                 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3225                 {
3226                         if (!r_worldsurfacevisible[j])
3227                                 continue;
3228                         if (t != surface->texture)
3229                         {
3230                                 if (numsurfacelist)
3231                                 {
3232                                         R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3233                                         numsurfacelist = 0;
3234                                 }
3235                                 t = surface->texture;
3236                                 texture = t->currentframe;
3237                                 f = texture->currentmaterialflags & flagsmask;
3238                         }
3239                         if (f && surface->num_triangles)
3240                         {
3241                                 // if lightmap parameters changed, rebuild lightmap texture
3242                                 if (surface->cached_dlight)
3243                                         R_BuildLightMap(ent, surface);
3244                                 // add face to draw list
3245                                 surfacelist[numsurfacelist++] = surface;
3246                                 counttriangles += surface->num_triangles;
3247                                 if (numsurfacelist >= maxsurfacelist)
3248                                 {
3249                                         R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3250                                         numsurfacelist = 0;
3251                                 }
3252                         }
3253                 }
3254         }
3255         else
3256         {
3257                 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3258                 {
3259                         if (t != surface->texture)
3260                         {
3261                                 if (numsurfacelist)
3262                                 {
3263                                         R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3264                                         numsurfacelist = 0;
3265                                 }
3266                                 t = surface->texture;
3267                                 texture = t->currentframe;
3268                                 f = texture->currentmaterialflags & flagsmask;
3269                         }
3270                         if (f && surface->num_triangles)
3271                         {
3272                                 // if lightmap parameters changed, rebuild lightmap texture
3273                                 if (surface->cached_dlight)
3274                                         R_BuildLightMap(ent, surface);
3275                                 // add face to draw list
3276                                 surfacelist[numsurfacelist++] = surface;
3277                                 counttriangles += surface->num_triangles;
3278                                 if (numsurfacelist >= maxsurfacelist)
3279                                 {
3280                                         R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3281                                         numsurfacelist = 0;
3282                                 }
3283                         }
3284                 }
3285         }
3286         if (numsurfacelist)
3287                 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3288         renderstats.entities_triangles += counttriangles;
3289         if (gl_support_fragment_shader)
3290                 qglUseProgramObjectARB(0);
3291
3292         if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces)
3293         {
3294                 int i;
3295                 msurface_t *surface;
3296                 q3mbrush_t *brush;
3297                 R_Mesh_Matrix(&ent->matrix);
3298                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
3299                 GL_DepthMask(false);
3300                 GL_DepthTest(!r_showdisabledepthtest.integer);
3301                 qglPolygonOffset(r_polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_polygonoffset + r_showcollisionbrushes_polygonoffset.value);
3302                 for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
3303                         if (brush->colbrushf && brush->colbrushf->numtriangles)
3304                                 R_DrawCollisionBrush(brush->colbrushf);
3305                 for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
3306                         if (surface->num_collisiontriangles)
3307                                 R_DrawCollisionSurface(ent, surface);
3308                 qglPolygonOffset(r_polygonfactor, r_polygonoffset);
3309         }
3310
3311         if (r_showtris.integer || r_shownormals.integer)
3312         {
3313                 int k, l;
3314                 const int *elements;
3315                 rmeshstate_t m;
3316                 vec3_t v;
3317                 GL_DepthTest(true);
3318                 GL_DepthMask(true);
3319                 if (r_showdisabledepthtest.integer)
3320                         qglDepthFunc(GL_ALWAYS);
3321                 GL_BlendFunc(GL_ONE, GL_ZERO);
3322                 memset(&m, 0, sizeof(m));
3323                 R_Mesh_State(&m);
3324                 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3325                 {
3326                         if (ent == r_refdef.worldentity && !r_worldsurfacevisible[j])
3327                                 continue;
3328                         texture = surface->texture->currentframe;
3329                         if ((texture->currentmaterialflags & flagsmask) && surface->num_triangles)
3330                         {
3331                                 RSurf_PrepareForBatch(ent, texture, modelorg);
3332                                 RSurf_SetPointersForPass(false, r_shownormals.integer != 0);
3333                                 if (rsurface_dynamicvertex)
3334                                         RSurf_PrepareDynamicSurfaceVertices(surface);
3335                                 if (r_showtris.integer)
3336                                 {
3337                                         if (!texture->currentlayers->depthmask)
3338                                                 GL_Color(r_showtris.value, 0, 0, 1);
3339                                         else if (ent == r_refdef.worldentity)
3340                                                 GL_Color(r_showtris.value, r_showtris.value, r_showtris.value, 1);
3341                                         else
3342                                                 GL_Color(0, r_showtris.value, 0, 1);
3343                                         elements = (ent->model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);
3344                                         qglBegin(GL_LINES);
3345                                         for (k = 0;k < surface->num_triangles;k++, elements += 3)
3346                                         {
3347                                                 qglArrayElement(elements[0]);qglArrayElement(elements[1]);
3348                                                 qglArrayElement(elements[1]);qglArrayElement(elements[2]);
3349                                                 qglArrayElement(elements[2]);qglArrayElement(elements[0]);
3350                                         }
3351                                         qglEnd();
3352                                 }
3353                                 if (r_shownormals.integer)
3354                                 {
3355                                         GL_Color(r_shownormals.value, 0, 0, 1);
3356                                         qglBegin(GL_LINES);
3357                                         for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3358                                         {
3359                                                 VectorCopy(rsurface_vertex3f + l * 3, v);
3360                                                 qglVertex3f(v[0], v[1], v[2]);
3361                                                 VectorMA(v, 8, rsurface_svector3f + l * 3, v);
3362                                                 qglVertex3f(v[0], v[1], v[2]);
3363                                         }
3364                                         qglEnd();
3365                                         GL_Color(0, 0, r_shownormals.value, 1);
3366                                         qglBegin(GL_LINES);
3367                                         for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3368                                         {
3369                                                 VectorCopy(rsurface_vertex3f + l * 3, v);
3370                                                 qglVertex3f(v[0], v[1], v[2]);
3371                                                 VectorMA(v, 8, rsurface_tvector3f + l * 3, v);
3372                                                 qglVertex3f(v[0], v[1], v[2]);
3373                                         }
3374                                         qglEnd();
3375                                         GL_Color(0, r_shownormals.value, 0, 1);
3376                                         qglBegin(GL_LINES);
3377                                         for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3378                                         {
3379                                                 VectorCopy(rsurface_vertex3f + l * 3, v);
3380                                                 qglVertex3f(v[0], v[1], v[2]);
3381                                                 VectorMA(v, 8, rsurface_normal3f + l * 3, v);
3382                                                 qglVertex3f(v[0], v[1], v[2]);
3383                                         }
3384                                         qglEnd();
3385                                 }
3386                         }
3387                 }
3388                 if (r_showdisabledepthtest.integer)
3389                         qglDepthFunc(GL_LEQUAL);
3390         }
3391 }
3392