]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - gl_rmain.c
a81e4305a0321105bb368d49d42efb30d88c69cf
[xonotic/darkplaces.git] / gl_rmain.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20 // r_main.c
21
22 #include "quakedef.h"
23 #include "r_shadow.h"
24 #include "polygon.h"
25
26 mempool_t *r_main_mempool;
27 rtexturepool_t *r_main_texturepool;
28
29 // used for dlight push checking and other things
30 int r_framecount;
31
32 mplane_t frustum[5];
33
34 renderstats_t renderstats;
35
36 // true during envmap command capture
37 qboolean envmap;
38
39 // maximum visible distance (recalculated from world box each frame)
40 float r_farclip;
41 // brightness of world lightmaps and related lighting
42 // (often reduced when world rtlights are enabled)
43 float r_lightmapintensity;
44 // whether to draw world lights realtime, dlights realtime, and their shadows
45 qboolean r_rtworld;
46 qboolean r_rtworldshadows;
47 qboolean r_rtdlight;
48 qboolean r_rtdlightshadows;
49
50
51 // view origin
52 vec3_t r_vieworigin;
53 vec3_t r_viewforward;
54 vec3_t r_viewleft;
55 vec3_t r_viewright;
56 vec3_t r_viewup;
57 int r_view_x;
58 int r_view_y;
59 int r_view_z;
60 int r_view_width;
61 int r_view_height;
62 int r_view_depth;
63 matrix4x4_t r_view_matrix;
64 float r_polygonfactor;
65 float r_polygonoffset;
66 float r_shadowpolygonfactor;
67 float r_shadowpolygonoffset;
68 //
69 // screen size info
70 //
71 refdef_t r_refdef;
72
73 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
74 cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "shows surfaces as different colors"};
75 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
76 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
77 cvar_t r_showlighting = {0, "r_showlighting", "0", "shows areas lit by lights, useful for finding out why some areas of a map render slowly (bright orange = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
78 cvar_t r_showshadowvolumes = {0, "r_showshadowvolumes", "0", "shows areas shadowed by lights, useful for finding out why some areas of a map render slowly (bright blue = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
79 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
80 cvar_t r_showcollisionbrushes_polygonfactor = {0, "r_showcollisionbrushes_polygonfactor", "-1", "expands outward the brush polygons a little bit, used to make collision brushes appear infront of walls"};
81 cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygonoffset", "0", "nudges brush polygon depth in hardware depth units, used to make collision brushes appear infront of walls"};
82 cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing\n"};
83 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
84 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
85 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
86 cvar_t r_fullbright = {0, "r_fullbright","0", "make everything bright cheat (not allowed in multiplayer)"};
87 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
88 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
89 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
90 cvar_t r_q1bsp_skymasking = {0, "r_qb1sp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
91
92 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
93 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
94 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
95 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
96 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
97 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
98 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
99
100 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of hardware texture units reported by driver (note: setting this to 1 turns off gl_combine)"};
101
102 cvar_t r_glsl = {0, "r_glsl", "1", "enables use of OpenGL 2.0 pixel shaders for lighting"};
103 cvar_t r_glsl_offsetmapping = {0, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
104 cvar_t r_glsl_offsetmapping_reliefmapping = {0, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
105 cvar_t r_glsl_offsetmapping_scale = {0, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
106 cvar_t r_glsl_deluxemapping = {0, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"};
107
108 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1", "enables animation smoothing on sprites (requires r_lerpmodels 1)"};
109 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
110 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
111
112 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
113 cvar_t r_bloom_intensity = {CVAR_SAVE, "r_bloom_intensity", "1.5", "how bright the glow is"};
114 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
115 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
116 cvar_t r_bloom_power = {CVAR_SAVE, "r_bloom_power", "2", "how much to darken the image before blurring to make the bloom effect"};
117
118 cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1", "uses significantly faster (and supposedly higher quality) area-weighted vertex normals and tangent vectors rather than summing normalized triangle normals and tangents"};
119
120 cvar_t developer_texturelogging = {0, "developer_texturelogging", "0", "produces a textures.log file containing names of skins and map textures the engine tried to load"};
121
122 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
123
124 cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"}; // used for testing renderer code changes, otherwise does nothing
125
126 rtexture_t *r_bloom_texture_screen;
127 rtexture_t *r_bloom_texture_bloom;
128 rtexture_t *r_texture_blanknormalmap;
129 rtexture_t *r_texture_white;
130 rtexture_t *r_texture_black;
131 rtexture_t *r_texture_notexture;
132 rtexture_t *r_texture_whitecube;
133 rtexture_t *r_texture_normalizationcube;
134 rtexture_t *r_texture_fogattenuation;
135 rtexture_t *r_texture_fogintensity;
136
137 // information about each possible shader permutation
138 r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_COUNT];
139 // currently selected permutation
140 r_glsl_permutation_t *r_glsl_permutation;
141
142 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
143 {
144         int i;
145         for (i = 0;i < verts;i++)
146         {
147                 out[0] = in[0] * r;
148                 out[1] = in[1] * g;
149                 out[2] = in[2] * b;
150                 out[3] = in[3];
151                 in += 4;
152                 out += 4;
153         }
154 }
155
156 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
157 {
158         int i;
159         for (i = 0;i < verts;i++)
160         {
161                 out[0] = r;
162                 out[1] = g;
163                 out[2] = b;
164                 out[3] = a;
165                 out += 4;
166         }
167 }
168
169 vec3_t fogcolor;
170 vec_t fogdensity;
171 vec_t fogrange;
172 vec_t fograngerecip;
173 int fogtableindex;
174 vec_t fogtabledistmultiplier;
175 float fogtable[FOGTABLEWIDTH];
176 float fog_density, fog_red, fog_green, fog_blue;
177 qboolean fogenabled;
178 qboolean oldgl_fogenable;
179 void R_UpdateFog(void)
180 {
181         if (gamemode == GAME_NEHAHRA)
182         {
183                 if (gl_fogenable.integer)
184                 {
185                         oldgl_fogenable = true;
186                         fog_density = gl_fogdensity.value;
187                         fog_red = gl_fogred.value;
188                         fog_green = gl_foggreen.value;
189                         fog_blue = gl_fogblue.value;
190                 }
191                 else if (oldgl_fogenable)
192                 {
193                         oldgl_fogenable = false;
194                         fog_density = 0;
195                         fog_red = 0;
196                         fog_green = 0;
197                         fog_blue = 0;
198                 }
199         }
200         if (fog_density)
201         {
202                 fogcolor[0] = fog_red   = bound(0.0f, fog_red  , 1.0f);
203                 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
204                 fogcolor[2] = fog_blue  = bound(0.0f, fog_blue , 1.0f);
205         }
206         if (fog_density)
207         {
208                 fogenabled = true;
209                 fogdensity = -4000.0f / (fog_density * fog_density);
210                 // this is the point where the fog reaches 0.9986 alpha, which we
211                 // consider a good enough cutoff point for the texture
212                 // (0.9986 * 256 == 255.6)
213                 fogrange = 400 / fog_density;
214                 fograngerecip = 1.0f / fogrange;
215                 fogtabledistmultiplier = FOGTABLEWIDTH * fograngerecip;
216                 // fog color was already set
217         }
218         else
219                 fogenabled = false;
220 }
221
222 // FIXME: move this to client?
223 void FOG_clear(void)
224 {
225         if (gamemode == GAME_NEHAHRA)
226         {
227                 Cvar_Set("gl_fogenable", "0");
228                 Cvar_Set("gl_fogdensity", "0.2");
229                 Cvar_Set("gl_fogred", "0.3");
230                 Cvar_Set("gl_foggreen", "0.3");
231                 Cvar_Set("gl_fogblue", "0.3");
232         }
233         fog_density = fog_red = fog_green = fog_blue = 0.0f;
234 }
235
236 // FIXME: move this to client?
237 void FOG_registercvars(void)
238 {
239         int x;
240         double r, alpha;
241
242         if (gamemode == GAME_NEHAHRA)
243         {
244                 Cvar_RegisterVariable (&gl_fogenable);
245                 Cvar_RegisterVariable (&gl_fogdensity);
246                 Cvar_RegisterVariable (&gl_fogred);
247                 Cvar_RegisterVariable (&gl_foggreen);
248                 Cvar_RegisterVariable (&gl_fogblue);
249                 Cvar_RegisterVariable (&gl_fogstart);
250                 Cvar_RegisterVariable (&gl_fogend);
251         }
252
253         r = (-1.0/256.0) * (FOGTABLEWIDTH * FOGTABLEWIDTH);
254         for (x = 0;x < FOGTABLEWIDTH;x++)
255         {
256                 alpha = exp(r / ((double)x*(double)x));
257                 if (x == FOGTABLEWIDTH - 1)
258                         alpha = 1;
259                 fogtable[x] = bound(0, alpha, 1);
260         }
261 }
262
263 static void R_BuildBlankTextures(void)
264 {
265         unsigned char data[4];
266         data[0] = 128; // normal X
267         data[1] = 128; // normal Y
268         data[2] = 255; // normal Z
269         data[3] = 128; // height
270         r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
271         data[0] = 255;
272         data[1] = 255;
273         data[2] = 255;
274         data[3] = 255;
275         r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
276         data[0] = 0;
277         data[1] = 0;
278         data[2] = 0;
279         data[3] = 255;
280         r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
281 }
282
283 static void R_BuildNoTexture(void)
284 {
285         int x, y;
286         unsigned char pix[16][16][4];
287         // this makes a light grey/dark grey checkerboard texture
288         for (y = 0;y < 16;y++)
289         {
290                 for (x = 0;x < 16;x++)
291                 {
292                         if ((y < 8) ^ (x < 8))
293                         {
294                                 pix[y][x][0] = 128;
295                                 pix[y][x][1] = 128;
296                                 pix[y][x][2] = 128;
297                                 pix[y][x][3] = 255;
298                         }
299                         else
300                         {
301                                 pix[y][x][0] = 64;
302                                 pix[y][x][1] = 64;
303                                 pix[y][x][2] = 64;
304                                 pix[y][x][3] = 255;
305                         }
306                 }
307         }
308         r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL);
309 }
310
311 static void R_BuildWhiteCube(void)
312 {
313         unsigned char data[6*1*1*4];
314         data[ 0] = 255;data[ 1] = 255;data[ 2] = 255;data[ 3] = 255;
315         data[ 4] = 255;data[ 5] = 255;data[ 6] = 255;data[ 7] = 255;
316         data[ 8] = 255;data[ 9] = 255;data[10] = 255;data[11] = 255;
317         data[12] = 255;data[13] = 255;data[14] = 255;data[15] = 255;
318         data[16] = 255;data[17] = 255;data[18] = 255;data[19] = 255;
319         data[20] = 255;data[21] = 255;data[22] = 255;data[23] = 255;
320         r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
321 }
322
323 static void R_BuildNormalizationCube(void)
324 {
325         int x, y, side;
326         vec3_t v;
327         vec_t s, t, intensity;
328 #define NORMSIZE 64
329         unsigned char data[6][NORMSIZE][NORMSIZE][4];
330         for (side = 0;side < 6;side++)
331         {
332                 for (y = 0;y < NORMSIZE;y++)
333                 {
334                         for (x = 0;x < NORMSIZE;x++)
335                         {
336                                 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
337                                 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
338                                 switch(side)
339                                 {
340                                 default:
341                                 case 0:
342                                         v[0] = 1;
343                                         v[1] = -t;
344                                         v[2] = -s;
345                                         break;
346                                 case 1:
347                                         v[0] = -1;
348                                         v[1] = -t;
349                                         v[2] = s;
350                                         break;
351                                 case 2:
352                                         v[0] = s;
353                                         v[1] = 1;
354                                         v[2] = t;
355                                         break;
356                                 case 3:
357                                         v[0] = s;
358                                         v[1] = -1;
359                                         v[2] = -t;
360                                         break;
361                                 case 4:
362                                         v[0] = s;
363                                         v[1] = -t;
364                                         v[2] = 1;
365                                         break;
366                                 case 5:
367                                         v[0] = -s;
368                                         v[1] = -t;
369                                         v[2] = -1;
370                                         break;
371                                 }
372                                 intensity = 127.0f / sqrt(DotProduct(v, v));
373                                 data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[0]);
374                                 data[side][y][x][1] = (unsigned char)(128.0f + intensity * v[1]);
375                                 data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[2]);
376                                 data[side][y][x][3] = 255;
377                         }
378                 }
379         }
380         r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
381 }
382
383 static void R_BuildFogTexture(void)
384 {
385         int x, b;
386         double r, alpha;
387 #define FOGWIDTH 64
388         unsigned char data1[FOGWIDTH][4];
389         unsigned char data2[FOGWIDTH][4];
390         r = (-1.0/256.0) * (FOGWIDTH * FOGWIDTH);
391         for (x = 0;x < FOGWIDTH;x++)
392         {
393                 alpha = exp(r / ((double)x*(double)x));
394                 if (x == FOGWIDTH - 1)
395                         alpha = 1;
396                 b = (int)(256.0 * alpha);
397                 b = bound(0, b, 255);
398                 data1[x][0] = 255 - b;
399                 data1[x][1] = 255 - b;
400                 data1[x][2] = 255 - b;
401                 data1[x][3] = 255;
402                 data2[x][0] = b;
403                 data2[x][1] = b;
404                 data2[x][2] = b;
405                 data2[x][3] = 255;
406         }
407         r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
408         r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
409 }
410
411 static const char *builtinshaderstring =
412 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
413 "// written by Forest 'LordHavoc' Hale\n"
414 "\n"
415 "// common definitions between vertex shader and fragment shader:\n"
416 "\n"
417 "varying vec2 TexCoord;\n"
418 "varying vec2 TexCoordLightmap;\n"
419 "\n"
420 "varying vec3 CubeVector;\n"
421 "varying vec3 LightVector;\n"
422 "varying vec3 EyeVector;\n"
423 "\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_Cube >= 0 && permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap));
956         if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
957         if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(5, R_GetTexture(texture->skin.pants));
958         if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(6, R_GetTexture(texture->skin.shirt));
959         if (r_glsl_permutation->loc_Texture_Lightmap >= 0) R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
960         if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
961         if (r_glsl_permutation->loc_Texture_Glow >= 0) R_Mesh_TexBind(9, R_GetTexture(texture->skin.glow));
962         if (r_glsl_permutation->loc_FogColor >= 0)
963         {
964                 // additive passes are only darkened by fog, not tinted
965                 if (r_shadow_rtlight || (texture->currentmaterialflags & MATERIALFLAG_ADD))
966                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
967                 else
968                         qglUniform3fARB(r_glsl_permutation->loc_FogColor, fogcolor[0], fogcolor[1], fogcolor[2]);
969         }
970         if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, modelorg[0], modelorg[1], modelorg[2]);
971         if (r_glsl_permutation->loc_Color_Pants >= 0)
972         {
973                 if (texture->skin.pants)
974                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, ent->colormap_pantscolor[0], ent->colormap_pantscolor[1], ent->colormap_pantscolor[2]);
975                 else
976                         qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
977         }
978         if (r_glsl_permutation->loc_Color_Shirt >= 0)
979         {
980                 if (texture->skin.shirt)
981                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, ent->colormap_shirtcolor[0], ent->colormap_shirtcolor[1], ent->colormap_shirtcolor[2]);
982                 else
983                         qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
984         }
985         if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, fograngerecip);
986         if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, texture->specularpower);
987         if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
988         CHECKGLERROR
989 }
990
991 void gl_main_start(void)
992 {
993         r_main_texturepool = R_AllocTexturePool();
994         r_bloom_texture_screen = NULL;
995         r_bloom_texture_bloom = NULL;
996         R_BuildBlankTextures();
997         R_BuildNoTexture();
998         if (gl_texturecubemap)
999         {
1000                 R_BuildWhiteCube();
1001                 R_BuildNormalizationCube();
1002         }
1003         R_BuildFogTexture();
1004         memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
1005 }
1006
1007 void gl_main_shutdown(void)
1008 {
1009         R_FreeTexturePool(&r_main_texturepool);
1010         r_bloom_texture_screen = NULL;
1011         r_bloom_texture_bloom = NULL;
1012         r_texture_blanknormalmap = NULL;
1013         r_texture_white = NULL;
1014         r_texture_black = NULL;
1015         r_texture_whitecube = NULL;
1016         r_texture_normalizationcube = NULL;
1017         R_GLSL_Restart_f();
1018 }
1019
1020 extern void CL_ParseEntityLump(char *entitystring);
1021 void gl_main_newmap(void)
1022 {
1023         // FIXME: move this code to client
1024         int l;
1025         char *entities, entname[MAX_QPATH];
1026         r_framecount = 1;
1027         if (cl.worldmodel)
1028         {
1029                 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
1030                 l = (int)strlen(entname) - 4;
1031                 if (l >= 0 && !strcmp(entname + l, ".bsp"))
1032                 {
1033                         strcpy(entname + l, ".ent");
1034                         if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
1035                         {
1036                                 CL_ParseEntityLump(entities);
1037                                 Mem_Free(entities);
1038                                 return;
1039                         }
1040                 }
1041                 if (cl.worldmodel->brush.entities)
1042                         CL_ParseEntityLump(cl.worldmodel->brush.entities);
1043         }
1044 }
1045
1046 void GL_Main_Init(void)
1047 {
1048         r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
1049
1050         Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed\n");
1051         FOG_registercvars(); // FIXME: move this fog stuff to client?
1052         Cvar_RegisterVariable(&r_nearclip);
1053         Cvar_RegisterVariable(&r_showsurfaces);
1054         Cvar_RegisterVariable(&r_showtris);
1055         Cvar_RegisterVariable(&r_shownormals);
1056         Cvar_RegisterVariable(&r_showlighting);
1057         Cvar_RegisterVariable(&r_showshadowvolumes);
1058         Cvar_RegisterVariable(&r_showcollisionbrushes);
1059         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor);
1060         Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset);
1061         Cvar_RegisterVariable(&r_showdisabledepthtest);
1062         Cvar_RegisterVariable(&r_drawentities);
1063         Cvar_RegisterVariable(&r_drawviewmodel);
1064         Cvar_RegisterVariable(&r_speeds);
1065         Cvar_RegisterVariable(&r_fullbrights);
1066         Cvar_RegisterVariable(&r_wateralpha);
1067         Cvar_RegisterVariable(&r_dynamic);
1068         Cvar_RegisterVariable(&r_fullbright);
1069         Cvar_RegisterVariable(&r_q1bsp_skymasking);
1070         Cvar_RegisterVariable(&r_textureunits);
1071         Cvar_RegisterVariable(&r_glsl);
1072         Cvar_RegisterVariable(&r_glsl_offsetmapping);
1073         Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
1074         Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
1075         Cvar_RegisterVariable(&r_glsl_deluxemapping);
1076         Cvar_RegisterVariable(&r_lerpsprites);
1077         Cvar_RegisterVariable(&r_lerpmodels);
1078         Cvar_RegisterVariable(&r_waterscroll);
1079         Cvar_RegisterVariable(&r_bloom);
1080         Cvar_RegisterVariable(&r_bloom_intensity);
1081         Cvar_RegisterVariable(&r_bloom_blur);
1082         Cvar_RegisterVariable(&r_bloom_resolution);
1083         Cvar_RegisterVariable(&r_bloom_power);
1084         Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
1085         Cvar_RegisterVariable(&developer_texturelogging);
1086         Cvar_RegisterVariable(&gl_lightmaps);
1087         Cvar_RegisterVariable(&r_test);
1088         if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
1089                 Cvar_SetValue("r_fullbrights", 0);
1090         R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
1091 }
1092
1093 static vec3_t r_farclip_origin;
1094 static vec3_t r_farclip_direction;
1095 static vec_t r_farclip_directiondist;
1096 static vec_t r_farclip_meshfarclip;
1097 static int r_farclip_directionbit0;
1098 static int r_farclip_directionbit1;
1099 static int r_farclip_directionbit2;
1100
1101 // enlarge farclip to accomodate box
1102 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
1103 {
1104         float d;
1105         d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
1106           + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
1107           + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
1108         if (r_farclip_meshfarclip < d)
1109                 r_farclip_meshfarclip = d;
1110 }
1111
1112 // return farclip value
1113 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
1114 {
1115         int i;
1116
1117         VectorCopy(origin, r_farclip_origin);
1118         VectorCopy(direction, r_farclip_direction);
1119         r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
1120         r_farclip_directionbit0 = r_farclip_direction[0] < 0;
1121         r_farclip_directionbit1 = r_farclip_direction[1] < 0;
1122         r_farclip_directionbit2 = r_farclip_direction[2] < 0;
1123         r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
1124
1125         if (r_refdef.worldmodel)
1126                 R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
1127         for (i = 0;i < r_refdef.numentities;i++)
1128                 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
1129
1130         return r_farclip_meshfarclip - r_farclip_directiondist;
1131 }
1132
1133 extern void R_Textures_Init(void);
1134 extern void GL_Draw_Init(void);
1135 extern void GL_Main_Init(void);
1136 extern void R_Shadow_Init(void);
1137 extern void R_Sky_Init(void);
1138 extern void GL_Surf_Init(void);
1139 extern void R_Crosshairs_Init(void);
1140 extern void R_Light_Init(void);
1141 extern void R_Particles_Init(void);
1142 extern void R_Explosion_Init(void);
1143 extern void gl_backend_init(void);
1144 extern void Sbar_Init(void);
1145 extern void R_LightningBeams_Init(void);
1146 extern void Mod_RenderInit(void);
1147
1148 void Render_Init(void)
1149 {
1150         gl_backend_init();
1151         R_Textures_Init();
1152         R_MeshQueue_Init();
1153         GL_Main_Init();
1154         GL_Draw_Init();
1155         R_Shadow_Init();
1156         R_Sky_Init();
1157         GL_Surf_Init();
1158         R_Crosshairs_Init();
1159         R_Light_Init();
1160         R_Particles_Init();
1161         R_Explosion_Init();
1162         Sbar_Init();
1163         R_LightningBeams_Init();
1164         Mod_RenderInit();
1165 }
1166
1167 /*
1168 ===============
1169 GL_Init
1170 ===============
1171 */
1172 extern char *ENGINE_EXTENSIONS;
1173 void GL_Init (void)
1174 {
1175         VID_CheckExtensions();
1176
1177         // LordHavoc: report supported extensions
1178         Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions );
1179
1180         // clear to black (loading plaque will be seen over this)
1181         qglClearColor(0,0,0,1);
1182         qglClear(GL_COLOR_BUFFER_BIT);
1183 }
1184
1185 int R_CullBox(const vec3_t mins, const vec3_t maxs)
1186 {
1187         int i;
1188         mplane_t *p;
1189         for (i = 0;i < 4;i++)
1190         {
1191                 p = frustum + i;
1192                 switch(p->signbits)
1193                 {
1194                 default:
1195                 case 0:
1196                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1197                                 return true;
1198                         break;
1199                 case 1:
1200                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1201                                 return true;
1202                         break;
1203                 case 2:
1204                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1205                                 return true;
1206                         break;
1207                 case 3:
1208                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1209                                 return true;
1210                         break;
1211                 case 4:
1212                         if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1213                                 return true;
1214                         break;
1215                 case 5:
1216                         if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1217                                 return true;
1218                         break;
1219                 case 6:
1220                         if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1221                                 return true;
1222                         break;
1223                 case 7:
1224                         if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1225                                 return true;
1226                         break;
1227                 }
1228         }
1229         return false;
1230 }
1231
1232 //==================================================================================
1233
1234 static void R_UpdateEntityLighting(entity_render_t *ent)
1235 {
1236         vec3_t tempdiffusenormal;
1237         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));
1238         VectorClear(ent->modellight_diffuse);
1239         VectorClear(ent->modellight_lightdir);
1240         if ((ent->flags & RENDER_LIGHT) && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
1241                 r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, ent->origin, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
1242         else // highly rare
1243                 VectorSet(ent->modellight_ambient, 1, 1, 1);
1244         Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
1245         VectorNormalize(ent->modellight_lightdir);
1246         ent->modellight_ambient[0] *= ent->colormod[0] * r_lightmapintensity;
1247         ent->modellight_ambient[1] *= ent->colormod[1] * r_lightmapintensity;
1248         ent->modellight_ambient[2] *= ent->colormod[2] * r_lightmapintensity;
1249         ent->modellight_diffuse[0] *= ent->colormod[0] * r_lightmapintensity;
1250         ent->modellight_diffuse[1] *= ent->colormod[1] * r_lightmapintensity;
1251         ent->modellight_diffuse[2] *= ent->colormod[2] * r_lightmapintensity;
1252 }
1253
1254 static void R_MarkEntities (void)
1255 {
1256         int i, renderimask;
1257         entity_render_t *ent;
1258
1259         if (!r_drawentities.integer)
1260                 return;
1261
1262         r_refdef.worldentity->visframe = r_framecount;
1263         renderimask = envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL);
1264         if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
1265         {
1266                 // worldmodel can check visibility
1267                 for (i = 0;i < r_refdef.numentities;i++)
1268                 {
1269                         ent = r_refdef.entities[i];
1270                         // some of the renderer still relies on origin...
1271                         Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1272                         // some of the renderer still relies on scale...
1273                         ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1274                         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)))
1275                         {
1276                                 ent->visframe = r_framecount;
1277                                 R_UpdateEntityLighting(ent);
1278                         }
1279                 }
1280         }
1281         else
1282         {
1283                 // no worldmodel or it can't check visibility
1284                 for (i = 0;i < r_refdef.numentities;i++)
1285                 {
1286                         ent = r_refdef.entities[i];
1287                         // some of the renderer still relies on origin...
1288                         Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1289                         // some of the renderer still relies on scale...
1290                         ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1291                         if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST))
1292                         {
1293                                 ent->visframe = r_framecount;
1294                                 R_UpdateEntityLighting(ent);
1295                         }
1296                 }
1297         }
1298 }
1299
1300 // only used if skyrendermasked, and normally returns false
1301 int R_DrawBrushModelsSky (void)
1302 {
1303         int i, sky;
1304         entity_render_t *ent;
1305
1306         if (!r_drawentities.integer)
1307                 return false;
1308
1309         sky = false;
1310         for (i = 0;i < r_refdef.numentities;i++)
1311         {
1312                 ent = r_refdef.entities[i];
1313                 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
1314                 {
1315                         ent->model->DrawSky(ent);
1316                         sky = true;
1317                 }
1318         }
1319         return sky;
1320 }
1321
1322 void R_DrawNoModel(entity_render_t *ent);
1323 void R_DrawModels(void)
1324 {
1325         int i;
1326         entity_render_t *ent;
1327
1328         if (!r_drawentities.integer)
1329                 return;
1330
1331         for (i = 0;i < r_refdef.numentities;i++)
1332         {
1333                 ent = r_refdef.entities[i];
1334                 if (ent->visframe == r_framecount)
1335                 {
1336                         renderstats.entities++;
1337                         if (ent->model && ent->model->Draw != NULL)
1338                                 ent->model->Draw(ent);
1339                         else
1340                                 R_DrawNoModel(ent);
1341                 }
1342         }
1343 }
1344
1345 static void R_SetFrustum(void)
1346 {
1347         // break apart the view matrix into vectors for various purposes
1348         Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
1349         VectorNegate(r_viewleft, r_viewright);
1350
1351 #if 0
1352         frustum[0].normal[0] = 0 - 1.0 / r_refdef.frustum_x;
1353         frustum[0].normal[1] = 0 - 0;
1354         frustum[0].normal[2] = -1 - 0;
1355         frustum[1].normal[0] = 0 + 1.0 / r_refdef.frustum_x;
1356         frustum[1].normal[1] = 0 + 0;
1357         frustum[1].normal[2] = -1 + 0;
1358         frustum[2].normal[0] = 0 - 0;
1359         frustum[2].normal[1] = 0 - 1.0 / r_refdef.frustum_y;
1360         frustum[2].normal[2] = -1 - 0;
1361         frustum[3].normal[0] = 0 + 0;
1362         frustum[3].normal[1] = 0 + 1.0 / r_refdef.frustum_y;
1363         frustum[3].normal[2] = -1 + 0;
1364 #endif
1365
1366 #if 0
1367         zNear = r_nearclip.value;
1368         nudge = 1.0 - 1.0 / (1<<23);
1369         frustum[4].normal[0] = 0 - 0;
1370         frustum[4].normal[1] = 0 - 0;
1371         frustum[4].normal[2] = -1 - -nudge;
1372         frustum[4].dist = 0 - -2 * zNear * nudge;
1373         frustum[5].normal[0] = 0 + 0;
1374         frustum[5].normal[1] = 0 + 0;
1375         frustum[5].normal[2] = -1 + -nudge;
1376         frustum[5].dist = 0 + -2 * zNear * nudge;
1377 #endif
1378
1379
1380
1381 #if 0
1382         frustum[0].normal[0] = m[3] - m[0];
1383         frustum[0].normal[1] = m[7] - m[4];
1384         frustum[0].normal[2] = m[11] - m[8];
1385         frustum[0].dist = m[15] - m[12];
1386
1387         frustum[1].normal[0] = m[3] + m[0];
1388         frustum[1].normal[1] = m[7] + m[4];
1389         frustum[1].normal[2] = m[11] + m[8];
1390         frustum[1].dist = m[15] + m[12];
1391
1392         frustum[2].normal[0] = m[3] - m[1];
1393         frustum[2].normal[1] = m[7] - m[5];
1394         frustum[2].normal[2] = m[11] - m[9];
1395         frustum[2].dist = m[15] - m[13];
1396
1397         frustum[3].normal[0] = m[3] + m[1];
1398         frustum[3].normal[1] = m[7] + m[5];
1399         frustum[3].normal[2] = m[11] + m[9];
1400         frustum[3].dist = m[15] + m[13];
1401
1402         frustum[4].normal[0] = m[3] - m[2];
1403         frustum[4].normal[1] = m[7] - m[6];
1404         frustum[4].normal[2] = m[11] - m[10];
1405         frustum[4].dist = m[15] - m[14];
1406
1407         frustum[5].normal[0] = m[3] + m[2];
1408         frustum[5].normal[1] = m[7] + m[6];
1409         frustum[5].normal[2] = m[11] + m[10];
1410         frustum[5].dist = m[15] + m[14];
1411 #endif
1412
1413
1414
1415         VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_x, r_viewleft, frustum[0].normal);
1416         VectorMAM(1, r_viewforward, 1.0 /  r_refdef.frustum_x, r_viewleft, frustum[1].normal);
1417         VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_y, r_viewup, frustum[2].normal);
1418         VectorMAM(1, r_viewforward, 1.0 /  r_refdef.frustum_y, r_viewup, frustum[3].normal);
1419         VectorCopy(r_viewforward, frustum[4].normal);
1420         VectorNormalize(frustum[0].normal);
1421         VectorNormalize(frustum[1].normal);
1422         VectorNormalize(frustum[2].normal);
1423         VectorNormalize(frustum[3].normal);
1424         frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1425         frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1426         frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1427         frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1428         frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1429         PlaneClassify(&frustum[0]);
1430         PlaneClassify(&frustum[1]);
1431         PlaneClassify(&frustum[2]);
1432         PlaneClassify(&frustum[3]);
1433         PlaneClassify(&frustum[4]);
1434
1435         // LordHavoc: note to all quake engine coders, Quake had a special case
1436         // for 90 degrees which assumed a square view (wrong), so I removed it,
1437         // Quake2 has it disabled as well.
1438
1439         // rotate R_VIEWFORWARD right by FOV_X/2 degrees
1440         //RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_refdef.fov_x / 2));
1441         //frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1442         //PlaneClassify(&frustum[0]);
1443
1444         // rotate R_VIEWFORWARD left by FOV_X/2 degrees
1445         //RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_refdef.fov_x / 2));
1446         //frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1447         //PlaneClassify(&frustum[1]);
1448
1449         // rotate R_VIEWFORWARD up by FOV_X/2 degrees
1450         //RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_refdef.fov_y / 2));
1451         //frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1452         //PlaneClassify(&frustum[2]);
1453
1454         // rotate R_VIEWFORWARD down by FOV_X/2 degrees
1455         //RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_refdef.fov_y / 2));
1456         //frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1457         //PlaneClassify(&frustum[3]);
1458
1459         // nearclip plane
1460         //VectorCopy(r_viewforward, frustum[4].normal);
1461         //frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1462         //PlaneClassify(&frustum[4]);
1463 }
1464
1465 static void R_BlendView(void)
1466 {
1467         int screenwidth, screenheight;
1468         qboolean dobloom;
1469         qboolean doblend;
1470         float vertex3f[12];
1471         float texcoord2f[3][8];
1472
1473         // set the (poorly named) screenwidth and screenheight variables to
1474         // a power of 2 at least as large as the screen, these will define the
1475         // size of the texture to allocate
1476         for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2);
1477         for (screenheight = 1;screenheight < vid.height;screenheight *= 2);
1478
1479         doblend = r_refdef.viewblend[3] >= 0.01f;
1480         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;
1481
1482         if (!dobloom && !doblend)
1483                 return;
1484
1485         GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
1486         GL_DepthMask(true);
1487         GL_DepthTest(false);
1488         R_Mesh_Matrix(&identitymatrix);
1489         // vertex coordinates for a quad that covers the screen exactly
1490         vertex3f[0] = 0;vertex3f[1] = 0;vertex3f[2] = 0;
1491         vertex3f[3] = 1;vertex3f[4] = 0;vertex3f[5] = 0;
1492         vertex3f[6] = 1;vertex3f[7] = 1;vertex3f[8] = 0;
1493         vertex3f[9] = 0;vertex3f[10] = 1;vertex3f[11] = 0;
1494         R_Mesh_VertexPointer(vertex3f);
1495         R_Mesh_ColorPointer(NULL);
1496         R_Mesh_ResetTextureState();
1497         if (dobloom)
1498         {
1499                 int bloomwidth, bloomheight, x, range;
1500                 float xoffset, yoffset, r;
1501                 renderstats.bloom++;
1502                 // allocate textures as needed
1503                 if (!r_bloom_texture_screen)
1504                         r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1505                 if (!r_bloom_texture_bloom)
1506                         r_bloom_texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1507                 // set bloomwidth and bloomheight to the bloom resolution that will be
1508                 // used (often less than the screen resolution for faster rendering)
1509                 bloomwidth = min(r_view_width, r_bloom_resolution.integer);
1510                 bloomheight = min(r_view_height, bloomwidth * r_view_height / r_view_width);
1511                 // set up a texcoord array for the full resolution screen image
1512                 // (we have to keep this around to copy back during final render)
1513                 texcoord2f[0][0] = 0;
1514                 texcoord2f[0][1] = (float)r_view_height / (float)screenheight;
1515                 texcoord2f[0][2] = (float)r_view_width / (float)screenwidth;
1516                 texcoord2f[0][3] = (float)r_view_height / (float)screenheight;
1517                 texcoord2f[0][4] = (float)r_view_width / (float)screenwidth;
1518                 texcoord2f[0][5] = 0;
1519                 texcoord2f[0][6] = 0;
1520                 texcoord2f[0][7] = 0;
1521                 // set up a texcoord array for the reduced resolution bloom image
1522                 // (which will be additive blended over the screen image)
1523                 texcoord2f[1][0] = 0;
1524                 texcoord2f[1][1] = (float)bloomheight / (float)screenheight;
1525                 texcoord2f[1][2] = (float)bloomwidth / (float)screenwidth;
1526                 texcoord2f[1][3] = (float)bloomheight / (float)screenheight;
1527                 texcoord2f[1][4] = (float)bloomwidth / (float)screenwidth;
1528                 texcoord2f[1][5] = 0;
1529                 texcoord2f[1][6] = 0;
1530                 texcoord2f[1][7] = 0;
1531                 R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]);
1532                 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen));
1533                 // copy view into the full resolution screen image texture
1534                 GL_ActiveTexture(0);
1535                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1536                 renderstats.bloom_copypixels += r_view_width * r_view_height;
1537                 // now scale it down to the bloom size and raise to a power of itself
1538                 // to darken it (this leaves the really bright stuff bright, and
1539                 // everything else becomes very dark)
1540                 // TODO: optimize with multitexture or GLSL
1541                 qglViewport(r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1542                 GL_BlendFunc(GL_ONE, GL_ZERO);
1543                 GL_Color(1, 1, 1, 1);
1544                 R_Mesh_Draw(0, 4, 2, polygonelements);
1545                 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1546                 // render multiple times with a multiply blendfunc to raise to a power
1547                 GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
1548                 for (x = 1;x < r_bloom_power.integer;x++)
1549                 {
1550                         R_Mesh_Draw(0, 4, 2, polygonelements);
1551                         renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1552                 }
1553                 // we now have a darkened bloom image in the framebuffer, copy it into
1554                 // the bloom image texture for more processing
1555                 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom));
1556                 R_Mesh_TexCoordPointer(0, 2, texcoord2f[2]);
1557                 GL_ActiveTexture(0);
1558                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1559                 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1560                 // blend on at multiple vertical offsets to achieve a vertical blur
1561                 // TODO: do offset blends using GLSL
1562                 range = r_bloom_blur.integer * bloomwidth / 320;
1563                 GL_BlendFunc(GL_ONE, GL_ZERO);
1564                 for (x = -range;x <= range;x++)
1565                 {
1566                         xoffset = 0 / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1567                         yoffset = x / (float)bloomheight * (float)bloomheight / (float)screenheight;
1568                         // compute a texcoord array with the specified x and y offset
1569                         texcoord2f[2][0] = xoffset+0;
1570                         texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1571                         texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1572                         texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1573                         texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1574                         texcoord2f[2][5] = yoffset+0;
1575                         texcoord2f[2][6] = xoffset+0;
1576                         texcoord2f[2][7] = yoffset+0;
1577                         // this r value looks like a 'dot' particle, fading sharply to
1578                         // black at the edges
1579                         // (probably not realistic but looks good enough)
1580                         r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1581                         if (r < 0.01f)
1582                                 continue;
1583                         GL_Color(r, r, r, 1);
1584                         R_Mesh_Draw(0, 4, 2, polygonelements);
1585                         renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1586                         GL_BlendFunc(GL_ONE, GL_ONE);
1587                 }
1588                 // copy the vertically blurred bloom view to a texture
1589                 GL_ActiveTexture(0);
1590                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1591                 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1592                 // blend the vertically blurred image at multiple offsets horizontally
1593                 // to finish the blur effect
1594                 // TODO: do offset blends using GLSL
1595                 range = r_bloom_blur.integer * bloomwidth / 320;
1596                 GL_BlendFunc(GL_ONE, GL_ZERO);
1597                 for (x = -range;x <= range;x++)
1598                 {
1599                         xoffset = x / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1600                         yoffset = 0 / (float)bloomheight * (float)bloomheight / (float)screenheight;
1601                         // compute a texcoord array with the specified x and y offset
1602                         texcoord2f[2][0] = xoffset+0;
1603                         texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1604                         texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1605                         texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1606                         texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1607                         texcoord2f[2][5] = yoffset+0;
1608                         texcoord2f[2][6] = xoffset+0;
1609                         texcoord2f[2][7] = yoffset+0;
1610                         // this r value looks like a 'dot' particle, fading sharply to
1611                         // black at the edges
1612                         // (probably not realistic but looks good enough)
1613                         r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1614                         if (r < 0.01f)
1615                                 continue;
1616                         GL_Color(r, r, r, 1);
1617                         R_Mesh_Draw(0, 4, 2, polygonelements);
1618                         renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1619                         GL_BlendFunc(GL_ONE, GL_ONE);
1620                 }
1621                 // copy the blurred bloom view to a texture
1622                 GL_ActiveTexture(0);
1623                 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1624                 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1625                 // go back to full view area
1626                 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1627                 // put the original screen image back in place and blend the bloom
1628                 // texture on it
1629                 GL_Color(1,1,1,1);
1630                 GL_BlendFunc(GL_ONE, GL_ZERO);
1631                 // do both in one pass if possible
1632                 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen));
1633                 R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]);
1634                 if (r_textureunits.integer >= 2 && gl_combine.integer)
1635                 {
1636                         R_Mesh_TexCombine(1, GL_ADD, GL_ADD, 1, 1);
1637                         R_Mesh_TexBind(1, R_GetTexture(r_bloom_texture_bloom));
1638                         R_Mesh_TexCoordPointer(1, 2, texcoord2f[1]);
1639                 }
1640                 else
1641                 {
1642                         R_Mesh_Draw(0, 4, 2, polygonelements);
1643                         renderstats.bloom_drawpixels += r_view_width * r_view_height;
1644                         // now blend on the bloom texture
1645                         GL_BlendFunc(GL_ONE, GL_ONE);
1646                         R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom));
1647                         R_Mesh_TexCoordPointer(0, 2, texcoord2f[1]);
1648                 }
1649                 R_Mesh_Draw(0, 4, 2, polygonelements);
1650                 renderstats.bloom_drawpixels += r_view_width * r_view_height;
1651         }
1652         if (doblend)
1653         {
1654                 // apply a color tint to the whole view
1655                 R_Mesh_ResetTextureState();
1656                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1657                 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
1658                 R_Mesh_Draw(0, 4, 2, polygonelements);
1659         }
1660 }
1661
1662 void R_RenderScene(void);
1663
1664 matrix4x4_t r_waterscrollmatrix;
1665
1666 /*
1667 ================
1668 R_RenderView
1669 ================
1670 */
1671 void R_RenderView(void)
1672 {
1673         if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1674                 return; //Host_Error ("R_RenderView: NULL worldmodel");
1675
1676         r_view_width = bound(0, r_refdef.width, vid.width);
1677         r_view_height = bound(0, r_refdef.height, vid.height);
1678         r_view_depth = 1;
1679         r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1680         r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1681         r_view_z = 0;
1682         r_view_matrix = r_refdef.viewentitymatrix;
1683         GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1684         r_rtworld = r_shadow_realtime_world.integer;
1685         r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1686         r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1687         r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1688         r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1689         r_polygonfactor = 0;
1690         r_polygonoffset = 0;
1691         r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1692         r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1693         if (r_showsurfaces.integer)
1694         {
1695                 r_rtworld = false;
1696                 r_rtworldshadows = false;
1697                 r_rtdlight = false;
1698                 r_rtdlightshadows = false;
1699                 r_lightmapintensity = 0;
1700         }
1701
1702         // GL is weird because it's bottom to top, r_view_y is top to bottom
1703         qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1704         GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1705         GL_ScissorTest(true);
1706         GL_DepthMask(true);
1707         R_ClearScreen();
1708         R_Textures_Frame();
1709         R_UpdateFog();
1710         if (r_timereport_active)
1711                 R_TimeReport("setup");
1712
1713         qglDepthFunc(GL_LEQUAL);
1714         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1715         qglEnable(GL_POLYGON_OFFSET_FILL);
1716
1717         R_RenderScene();
1718
1719         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1720         qglDisable(GL_POLYGON_OFFSET_FILL);
1721
1722         R_BlendView();
1723         if (r_timereport_active)
1724                 R_TimeReport("blendview");
1725
1726         GL_Scissor(0, 0, vid.width, vid.height);
1727         GL_ScissorTest(false);
1728 }
1729
1730 //[515]: csqc
1731 void CSQC_R_ClearScreen (void)
1732 {
1733         if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1734                 return; //Host_Error ("R_RenderView: NULL worldmodel");
1735
1736         r_view_width = bound(0, r_refdef.width, vid.width);
1737         r_view_height = bound(0, r_refdef.height, vid.height);
1738         r_view_depth = 1;
1739         r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1740         r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1741         r_view_z = 0;
1742         r_view_matrix = r_refdef.viewentitymatrix;
1743         GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1744         r_rtworld = r_shadow_realtime_world.integer;
1745         r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1746         r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1747         r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1748         r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1749         r_polygonfactor = 0;
1750         r_polygonoffset = 0;
1751         r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1752         r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1753         if (r_showsurfaces.integer)
1754         {
1755                 r_rtworld = false;
1756                 r_rtworldshadows = false;
1757                 r_rtdlight = false;
1758                 r_rtdlightshadows = false;
1759                 r_lightmapintensity = 0;
1760         }
1761
1762         // GL is weird because it's bottom to top, r_view_y is top to bottom
1763         qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1764         GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1765         GL_ScissorTest(true);
1766         GL_DepthMask(true);
1767         R_ClearScreen();
1768         R_Textures_Frame();
1769         R_UpdateFog();
1770         if (r_timereport_active)
1771                 R_TimeReport("setup");
1772 }
1773
1774 //[515]: csqc
1775 void CSQC_R_RenderScene (void)
1776 {
1777         qglDepthFunc(GL_LEQUAL);
1778         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1779         qglEnable(GL_POLYGON_OFFSET_FILL);
1780
1781         R_RenderScene();
1782
1783         qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1784         qglDisable(GL_POLYGON_OFFSET_FILL);
1785
1786         R_BlendView();
1787         if (r_timereport_active)
1788                 R_TimeReport("blendview");
1789
1790         GL_Scissor(0, 0, vid.width, vid.height);
1791         GL_ScissorTest(false);
1792 }
1793
1794 extern void R_DrawLightningBeams (void);
1795 extern void VM_AddPolygonsToMeshQueue (void);
1796 void R_RenderScene(void)
1797 {
1798         float nearclip;
1799
1800         // don't let sound skip if going slow
1801         if (r_refdef.extraupdate)
1802                 S_ExtraUpdate ();
1803
1804         r_framecount++;
1805
1806         if (gl_support_fragment_shader)
1807                 qglUseProgramObjectARB(0);
1808
1809         R_MeshQueue_BeginScene();
1810
1811         R_SetFrustum();
1812
1813         r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
1814         nearclip = bound (0.001f, r_nearclip.value, r_farclip - 1.0f);
1815
1816         if (r_rtworldshadows || r_rtdlightshadows)
1817                 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_refdef.frustum_x, r_refdef.frustum_y, nearclip);
1818         else
1819                 GL_SetupView_Mode_Perspective(r_refdef.frustum_x, r_refdef.frustum_y, nearclip, r_farclip);
1820
1821         GL_SetupView_Orientation_FromEntity(&r_view_matrix);
1822
1823         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);
1824
1825         R_SkyStartFrame();
1826
1827         R_WorldVisibility();
1828         if (r_timereport_active)
1829                 R_TimeReport("worldvis");
1830
1831         R_MarkEntities();
1832         if (r_timereport_active)
1833                 R_TimeReport("markentity");
1834
1835         R_Shadow_UpdateWorldLightSelection();
1836
1837         if (cl.csqc_vidvars.drawworld)
1838         {
1839                 // don't let sound skip if going slow
1840                 if (r_refdef.extraupdate)
1841                         S_ExtraUpdate ();
1842
1843                 if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
1844                 {
1845                         r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
1846                         if (r_timereport_active)
1847                                 R_TimeReport("worldsky");
1848                 }
1849
1850                 if (R_DrawBrushModelsSky() && r_timereport_active)
1851                         R_TimeReport("bmodelsky");
1852
1853                 if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
1854                 {
1855                         r_refdef.worldmodel->Draw(r_refdef.worldentity);
1856                         if (r_timereport_active)
1857                                 R_TimeReport("world");
1858                 }
1859         }
1860
1861         // don't let sound skip if going slow
1862         if (r_refdef.extraupdate)
1863                 S_ExtraUpdate ();
1864
1865         R_DrawModels();
1866         if (r_timereport_active)
1867                 R_TimeReport("models");
1868
1869         // don't let sound skip if going slow
1870         if (r_refdef.extraupdate)
1871                 S_ExtraUpdate ();
1872
1873         R_ShadowVolumeLighting(false);
1874         if (r_timereport_active)
1875                 R_TimeReport("rtlights");
1876
1877         // don't let sound skip if going slow
1878         if (r_refdef.extraupdate)
1879                 S_ExtraUpdate ();
1880
1881         if (cl.csqc_vidvars.drawworld)
1882         {
1883                 R_DrawLightningBeams();
1884                 if (r_timereport_active)
1885                         R_TimeReport("lightning");
1886
1887                 R_DrawParticles();
1888                 if (r_timereport_active)
1889                         R_TimeReport("particles");
1890
1891                 R_DrawExplosions();
1892                 if (r_timereport_active)
1893                         R_TimeReport("explosions");
1894         }
1895
1896         R_MeshQueue_RenderTransparent();
1897         if (r_timereport_active)
1898                 R_TimeReport("drawtrans");
1899
1900         if (cl.csqc_vidvars.drawworld)
1901         {
1902                 R_DrawCoronas();
1903                 if (r_timereport_active)
1904                         R_TimeReport("coronas");
1905         }
1906         if(cl.csqc_vidvars.drawcrosshair)
1907         {
1908                 R_DrawWorldCrosshair();
1909                 if (r_timereport_active)
1910                         R_TimeReport("crosshair");
1911         }
1912
1913         VM_AddPolygonsToMeshQueue();
1914
1915         R_MeshQueue_Render();
1916
1917         R_MeshQueue_EndScene();
1918
1919         // don't let sound skip if going slow
1920         if (r_refdef.extraupdate)
1921                 S_ExtraUpdate ();
1922
1923         if (gl_support_fragment_shader)
1924                 qglUseProgramObjectARB(0);
1925 }
1926
1927 /*
1928 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
1929 {
1930         int i;
1931         float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
1932         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1933         GL_DepthMask(false);
1934         GL_DepthTest(true);
1935         R_Mesh_Matrix(&identitymatrix);
1936
1937         vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
1938         vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
1939         vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
1940         vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
1941         vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
1942         vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
1943         vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
1944         vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
1945         R_FillColors(color, 8, cr, cg, cb, ca);
1946         if (fogenabled)
1947         {
1948                 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
1949                 {
1950                         f2 = VERTEXFOGTABLE(VectorDistance(v, r_vieworigin));
1951                         f1 = 1 - f2;
1952                         c[0] = c[0] * f1 + fogcolor[0] * f2;
1953                         c[1] = c[1] * f1 + fogcolor[1] * f2;
1954                         c[2] = c[2] * f1 + fogcolor[2] * f2;
1955                 }
1956         }
1957         R_Mesh_VertexPointer(vertex3f);
1958         R_Mesh_ColorPointer(color);
1959         R_Mesh_ResetTextureState();
1960         R_Mesh_Draw(8, 12);
1961 }
1962 */
1963
1964 int nomodelelements[24] =
1965 {
1966         5, 2, 0,
1967         5, 1, 2,
1968         5, 0, 3,
1969         5, 3, 1,
1970         0, 2, 4,
1971         2, 1, 4,
1972         3, 0, 4,
1973         1, 3, 4
1974 };
1975
1976 float nomodelvertex3f[6*3] =
1977 {
1978         -16,   0,   0,
1979          16,   0,   0,
1980           0, -16,   0,
1981           0,  16,   0,
1982           0,   0, -16,
1983           0,   0,  16
1984 };
1985
1986 float nomodelcolor4f[6*4] =
1987 {
1988         0.0f, 0.0f, 0.5f, 1.0f,
1989         0.0f, 0.0f, 0.5f, 1.0f,
1990         0.0f, 0.5f, 0.0f, 1.0f,
1991         0.0f, 0.5f, 0.0f, 1.0f,
1992         0.5f, 0.0f, 0.0f, 1.0f,
1993         0.5f, 0.0f, 0.0f, 1.0f
1994 };
1995
1996 void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
1997 {
1998         int i;
1999         float f1, f2, *c;
2000         float color4f[6*4];
2001         R_Mesh_Matrix(&ent->matrix);
2002
2003         if (ent->flags & EF_ADDITIVE)
2004         {
2005                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2006                 GL_DepthMask(false);
2007         }
2008         else if (ent->alpha < 1)
2009         {
2010                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2011                 GL_DepthMask(false);
2012         }
2013         else
2014         {
2015                 GL_BlendFunc(GL_ONE, GL_ZERO);
2016                 GL_DepthMask(true);
2017         }
2018         GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
2019         R_Mesh_VertexPointer(nomodelvertex3f);
2020         if (fogenabled)
2021         {
2022                 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2023                 R_Mesh_ColorPointer(color4f);
2024                 f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_vieworigin));
2025                 f1 = 1 - f2;
2026                 for (i = 0, c = color4f;i < 6;i++, c += 4)
2027                 {
2028                         c[0] = (c[0] * f1 + fogcolor[0] * f2);
2029                         c[1] = (c[1] * f1 + fogcolor[1] * f2);
2030                         c[2] = (c[2] * f1 + fogcolor[2] * f2);
2031                         c[3] *= ent->alpha;
2032                 }
2033         }
2034         else if (ent->alpha != 1)
2035         {
2036                 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2037                 R_Mesh_ColorPointer(color4f);
2038                 for (i = 0, c = color4f;i < 6;i++, c += 4)
2039                         c[3] *= ent->alpha;
2040         }
2041         else
2042                 R_Mesh_ColorPointer(nomodelcolor4f);
2043         R_Mesh_ResetTextureState();
2044         R_Mesh_Draw(0, 6, 8, nomodelelements);
2045 }
2046
2047 void R_DrawNoModel(entity_render_t *ent)
2048 {
2049         //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
2050                 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight);
2051         //else
2052         //      R_DrawNoModelCallback(ent, 0);
2053 }
2054
2055 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
2056 {
2057         vec3_t right1, right2, diff, normal;
2058
2059         VectorSubtract (org2, org1, normal);
2060
2061         // calculate 'right' vector for start
2062         VectorSubtract (r_vieworigin, org1, diff);
2063         CrossProduct (normal, diff, right1);
2064         VectorNormalize (right1);
2065
2066         // calculate 'right' vector for end
2067         VectorSubtract (r_vieworigin, org2, diff);
2068         CrossProduct (normal, diff, right2);
2069         VectorNormalize (right2);
2070
2071         vert[ 0] = org1[0] + width * right1[0];
2072         vert[ 1] = org1[1] + width * right1[1];
2073         vert[ 2] = org1[2] + width * right1[2];
2074         vert[ 3] = org1[0] - width * right1[0];
2075         vert[ 4] = org1[1] - width * right1[1];
2076         vert[ 5] = org1[2] - width * right1[2];
2077         vert[ 6] = org2[0] - width * right2[0];
2078         vert[ 7] = org2[1] - width * right2[1];
2079         vert[ 8] = org2[2] - width * right2[2];
2080         vert[ 9] = org2[0] + width * right2[0];
2081         vert[10] = org2[1] + width * right2[1];
2082         vert[11] = org2[2] + width * right2[2];
2083 }
2084
2085 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
2086
2087 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)
2088 {
2089         float fog = 0.0f, ifog;
2090         float vertex3f[12];
2091
2092         if (fogenabled)
2093                 fog = VERTEXFOGTABLE(VectorDistance(origin, r_vieworigin));
2094         ifog = 1 - fog;
2095
2096         R_Mesh_Matrix(&identitymatrix);
2097         GL_BlendFunc(blendfunc1, blendfunc2);
2098         GL_DepthMask(false);
2099         GL_DepthTest(!depthdisable);
2100
2101         vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
2102         vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
2103         vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
2104         vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
2105         vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
2106         vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
2107         vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
2108         vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
2109         vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
2110         vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
2111         vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
2112         vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
2113
2114         R_Mesh_VertexPointer(vertex3f);
2115         R_Mesh_ColorPointer(NULL);
2116         R_Mesh_ResetTextureState();
2117         R_Mesh_TexBind(0, R_GetTexture(texture));
2118         R_Mesh_TexCoordPointer(0, 2, spritetexcoord2f);
2119         GL_Color(cr * ifog, cg * ifog, cb * ifog, ca);
2120         R_Mesh_Draw(0, 4, 2, polygonelements);
2121
2122         if (blendfunc2 == GL_ONE_MINUS_SRC_ALPHA)
2123         {
2124                 R_Mesh_TexBind(0, R_GetTexture(fogtexture));
2125                 GL_BlendFunc(blendfunc1, GL_ONE);
2126                 GL_Color(fogcolor[0] * fog, fogcolor[1] * fog, fogcolor[2] * fog, ca);
2127                 R_Mesh_Draw(0, 4, 2, polygonelements);
2128         }
2129 }
2130
2131 int R_Mesh_AddVertex3f(rmesh_t *mesh, const float *v)
2132 {
2133         int i;
2134         float *vertex3f;
2135         for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
2136                 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
2137                         break;
2138         if (i == mesh->numvertices)
2139         {
2140                 if (mesh->numvertices < mesh->maxvertices)
2141                 {
2142                         VectorCopy(v, vertex3f);
2143                         mesh->numvertices++;
2144                 }
2145                 return mesh->numvertices;
2146         }
2147         else
2148                 return i;
2149 }
2150
2151 void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
2152 {
2153         int i;
2154         int *e, element[3];
2155         element[0] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2156         element[1] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2157         e = mesh->element3i + mesh->numtriangles * 3;
2158         for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
2159         {
2160                 element[2] = R_Mesh_AddVertex3f(mesh, vertex3f);
2161                 if (mesh->numtriangles < mesh->maxtriangles)
2162                 {
2163                         *e++ = element[0];
2164                         *e++ = element[1];
2165                         *e++ = element[2];
2166                         mesh->numtriangles++;
2167                 }
2168                 element[1] = element[2];
2169         }
2170 }
2171
2172 void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
2173 {
2174         int planenum, planenum2;
2175         int w;
2176         int tempnumpoints;
2177         mplane_t *plane, *plane2;
2178         float temppoints[2][256*3];
2179         for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
2180         {
2181                 w = 0;
2182                 tempnumpoints = 4;
2183                 PolygonF_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->normal[3], 1024.0*1024.0*1024.0);
2184                 for (planenum2 = 0, plane2 = planes;planenum2 < numplanes && tempnumpoints >= 3;planenum2++, plane2++)
2185                 {
2186                         if (planenum2 == planenum)
2187                                 continue;
2188                         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);
2189                         w = !w;
2190                 }
2191                 if (tempnumpoints < 3)
2192                         continue;
2193                 // generate elements forming a triangle fan for this polygon
2194                 R_Mesh_AddPolygon3f(mesh, tempnumpoints, temppoints[w]);
2195         }
2196 }
2197
2198 static void R_DrawCollisionBrush(colbrushf_t *brush)
2199 {
2200         int i;
2201         R_Mesh_VertexPointer(brush->points->v);
2202         i = (int)(((size_t)brush) / sizeof(colbrushf_t));
2203         GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2204         GL_LockArrays(0, brush->numpoints);
2205         R_Mesh_Draw(0, brush->numpoints, brush->numtriangles, brush->elements);
2206         GL_LockArrays(0, 0);
2207 }
2208
2209 static void R_DrawCollisionSurface(entity_render_t *ent, msurface_t *surface)
2210 {
2211         int i;
2212         if (!surface->num_collisiontriangles)
2213                 return;
2214         R_Mesh_VertexPointer(surface->data_collisionvertex3f);
2215         i = (int)(((size_t)surface) / sizeof(msurface_t));
2216         GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2217         GL_LockArrays(0, surface->num_collisionvertices);
2218         R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i);
2219         GL_LockArrays(0, 0);
2220 }
2221
2222 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)
2223 {
2224         texturelayer_t *layer;
2225         layer = t->currentlayers + t->currentnumlayers++;
2226         layer->type = type;
2227         layer->depthmask = depthmask;
2228         layer->blendfunc1 = blendfunc1;
2229         layer->blendfunc2 = blendfunc2;
2230         layer->texture = texture;
2231         layer->texmatrix = *matrix;
2232         layer->color[0] = r;
2233         layer->color[1] = g;
2234         layer->color[2] = b;
2235         layer->color[3] = a;
2236 }
2237
2238 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
2239 {
2240         // FIXME: identify models using a better check than ent->model->brush.shadowmesh
2241         //int lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
2242
2243         {
2244                 texture_t *texture = t;
2245                 model_t *model = ent->model;
2246                 int s = ent->skinnum;
2247                 if ((unsigned int)s >= (unsigned int)model->numskins)
2248                         s = 0;
2249                 if (model->skinscenes)
2250                 {
2251                         if (model->skinscenes[s].framecount > 1)
2252                                 s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
2253                         else
2254                                 s = model->skinscenes[s].firstframe;
2255                 }
2256                 if (s > 0)
2257                         t = t + s * model->num_surfaces;
2258                 if (t->animated)
2259                         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];
2260                 texture->currentframe = t;
2261         }
2262
2263         t->currentmaterialflags = t->basematerialflags;
2264         t->currentalpha = ent->alpha;
2265         if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
2266                 t->currentalpha *= r_wateralpha.value;
2267         if (!(ent->flags & RENDER_LIGHT))
2268                 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
2269         if (ent->effects & EF_ADDITIVE)
2270                 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_TRANSPARENT;
2271         else if (t->currentalpha < 1)
2272                 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT;
2273         if (ent->effects & EF_NODEPTHTEST)
2274                 t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST;
2275         if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
2276                 t->currenttexmatrix = r_waterscrollmatrix;
2277         else
2278                 t->currenttexmatrix = identitymatrix;
2279
2280         t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
2281         t->basetexture = (!t->colormapping && t->skin.merged) ? t->skin.merged : t->skin.base;
2282         t->glosstexture = r_texture_white;
2283         t->specularpower = 8;
2284         t->specularscale = 0;
2285         if (r_shadow_gloss.integer > 0)
2286         {
2287                 if (t->skin.gloss)
2288                 {
2289                         if (r_shadow_glossintensity.value > 0)
2290                         {
2291                                 t->glosstexture = t->skin.gloss;
2292                                 t->specularscale = r_shadow_glossintensity.value;
2293                         }
2294                 }
2295                 else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0)
2296                         t->specularscale = r_shadow_gloss2intensity.value;
2297         }
2298
2299         t->currentnumlayers = 0;
2300         if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
2301         {
2302                 if (gl_lightmaps.integer)
2303                         R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, r_texture_white, &identitymatrix, 1, 1, 1, 1);
2304                 else if (!(t->currentmaterialflags & MATERIALFLAG_SKY))
2305                 {
2306                         int blendfunc1, blendfunc2, depthmask;
2307                         if (t->currentmaterialflags & MATERIALFLAG_ADD)
2308                         {
2309                                 blendfunc1 = GL_SRC_ALPHA;
2310                                 blendfunc2 = GL_ONE;
2311                                 depthmask = false;
2312                         }
2313                         else if (t->currentmaterialflags & MATERIALFLAG_ALPHA)
2314                         {
2315                                 blendfunc1 = GL_SRC_ALPHA;
2316                                 blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
2317                                 depthmask = false;
2318                         }
2319                         else
2320                         {
2321                                 blendfunc1 = GL_ONE;
2322                                 blendfunc2 = GL_ZERO;
2323                                 depthmask = true;
2324                         }
2325                         if (t->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
2326                         {
2327                                 rtexture_t *currentbasetexture;
2328                                 int layerflags = 0;
2329                                 if (fogenabled && (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2330                                         layerflags |= TEXTURELAYERFLAG_FOGDARKEN;
2331                                 currentbasetexture = (VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) < (1.0f / 1048576.0f) && t->skin.merged) ? t->skin.merged : t->skin.base;
2332                                 if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2333                                 {
2334                                         // fullbright is not affected by r_lightmapintensity
2335                                         R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0], ent->colormod[1], ent->colormod[2], t->currentalpha);
2336                                         if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2337                                                 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);
2338                                         if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2339                                                 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);
2340                                 }
2341                                 else
2342                                 {
2343                                         float colorscale;
2344                                         colorscale = 2;
2345                                         // q3bsp has no lightmap updates, so the lightstylevalue that
2346                                         // would normally be baked into the lightmaptexture must be
2347                                         // applied to the color
2348                                         if (ent->model->type == mod_brushq3)
2349                                                 colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
2350                                         colorscale *= r_lightmapintensity;
2351                                         if (r_textureunits.integer >= 2 && gl_combine.integer)
2352                                                 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);
2353                                         else if ((t->currentmaterialflags & MATERIALFLAG_TRANSPARENT) == 0)
2354                                                 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);
2355                                         else
2356                                                 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);
2357                                         if (r_ambient.value >= (1.0f/64.0f))
2358                                                 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);
2359                                         if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2360                                         {
2361                                                 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);
2362                                                 if (r_ambient.value >= (1.0f/64.0f))
2363                                                         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);
2364                                         }
2365                                         if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2366                                         {
2367                                                 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);
2368                                                 if (r_ambient.value >= (1.0f/64.0f))
2369                                                         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);
2370                                         }
2371                                 }
2372                                 if (t->skin.glow != NULL)
2373                                         R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, t->currentalpha);
2374                                 if (fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
2375                                 {
2376                                         // if this is opaque use alpha blend which will darken the earlier
2377                                         // passes cheaply.
2378                                         //
2379                                         // if this is an alpha blended material, all the earlier passes
2380                                         // were darkened by fog already, so we only need to add the fog
2381                                         // color ontop through the fog mask texture
2382                                         //
2383                                         // if this is an additive blended material, all the earlier passes
2384                                         // were darkened by fog already, and we should not add fog color
2385                                         // (because the background was not darkened, there is no fog color
2386                                         // that was lost behind it).
2387                                         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);
2388                                 }
2389                         }
2390                 }
2391         }
2392 }
2393
2394 void R_UpdateAllTextureInfo(entity_render_t *ent)
2395 {
2396         int i;
2397         if (ent->model)
2398                 for (i = 0;i < ent->model->num_textures;i++)
2399                         R_UpdateTextureInfo(ent, ent->model->data_textures + i);
2400 }
2401
2402 int rsurface_array_size = 0;
2403 float *rsurface_array_vertex3f = NULL;
2404 float *rsurface_array_svector3f = NULL;
2405 float *rsurface_array_tvector3f = NULL;
2406 float *rsurface_array_normal3f = NULL;
2407 float *rsurface_array_color4f = NULL;
2408 float *rsurface_array_texcoord3f = NULL;
2409
2410 void R_Mesh_ResizeArrays(int newvertices)
2411 {
2412         if (rsurface_array_size >= newvertices)
2413                 return;
2414         if (rsurface_array_vertex3f)
2415                 Mem_Free(rsurface_array_vertex3f);
2416         rsurface_array_size = (newvertices + 1023) & ~1023;
2417         rsurface_array_vertex3f = (float *)Mem_Alloc(r_main_mempool, rsurface_array_size * sizeof(float[19]));
2418         rsurface_array_svector3f = rsurface_array_vertex3f + rsurface_array_size * 3;
2419         rsurface_array_tvector3f = rsurface_array_vertex3f + rsurface_array_size * 6;
2420         rsurface_array_normal3f = rsurface_array_vertex3f + rsurface_array_size * 9;
2421         rsurface_array_color4f = rsurface_array_vertex3f + rsurface_array_size * 12;
2422         rsurface_array_texcoord3f = rsurface_array_vertex3f + rsurface_array_size * 16;
2423 }
2424
2425 float *rsurface_vertex3f;
2426 float *rsurface_svector3f;
2427 float *rsurface_tvector3f;
2428 float *rsurface_normal3f;
2429 float *rsurface_lightmapcolor4f;
2430 vec3_t rsurface_modelorg;
2431 const entity_render_t *rsurface_entity;
2432 const model_t *rsurface_model;
2433 const texture_t *rsurface_texture;
2434
2435 void RSurf_PrepareVerticesForBatch(const entity_render_t *ent, const texture_t *texture, const vec3_t modelorg, qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist)
2436 {
2437         VectorCopy(modelorg, rsurface_modelorg);
2438         rsurface_entity = ent;
2439         rsurface_model = ent->model;
2440         rsurface_texture = texture;
2441         if (rsurface_array_size < rsurface_model->surfmesh.num_vertices)
2442                 R_Mesh_ResizeArrays(rsurface_model->surfmesh.num_vertices);
2443         if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexboneweights))
2444         {
2445                 rsurface_vertex3f = rsurface_array_vertex3f;
2446                 Mod_Alias_GetMesh_Vertex3f(rsurface_model, rsurface_entity->frameblend, rsurface_array_vertex3f);
2447                 if (generatetangents || (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)))
2448                 {
2449                         rsurface_svector3f = rsurface_array_svector3f;
2450                         rsurface_tvector3f = rsurface_array_tvector3f;
2451                         rsurface_normal3f = rsurface_array_normal3f;
2452                         Mod_BuildTextureVectorsAndNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_model->surfmesh.data_element3i, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
2453                 }
2454                 else
2455                 {
2456                         rsurface_svector3f = NULL;
2457                         rsurface_tvector3f = NULL;
2458                         if (generatenormals)
2459                         {
2460                                 rsurface_normal3f = rsurface_array_normal3f;
2461                                 Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
2462                         }
2463                         else
2464                                 rsurface_normal3f = NULL;
2465                 }
2466         }
2467         else
2468         {
2469                 rsurface_vertex3f = rsurface_model->surfmesh.data_vertex3f;
2470                 rsurface_svector3f = rsurface_model->surfmesh.data_svector3f;
2471                 rsurface_tvector3f = rsurface_model->surfmesh.data_tvector3f;
2472                 rsurface_normal3f = rsurface_model->surfmesh.data_normal3f;
2473         }
2474         if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2475         {
2476                 int texturesurfaceindex;
2477                 float center[3], forward[3], right[3], up[3], v[4][3];
2478                 matrix4x4_t matrix1, imatrix1;
2479                 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewforward, forward);
2480                 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewright, right);
2481                 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewup, up);
2482                 if (rsurface_texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
2483                 {
2484                         forward[0] = rsurface_modelorg[0] - center[0];
2485                         forward[1] = rsurface_modelorg[1] - center[1];
2486                         forward[2] = 0;
2487                         VectorNormalize(forward);
2488                         right[0] = forward[1];
2489                         right[1] = -forward[0];
2490                         right[2] = 0;
2491                         VectorSet(up, 0, 0, 1);
2492                 }
2493                 // make deformed versions of only the vertices used by the specified surfaces
2494                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2495                 {
2496                         int i, j;
2497                         const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2498                         // a single autosprite surface can contain multiple sprites...
2499                         for (j = 0;j < surface->num_vertices - 3;j += 4)
2500                         {
2501                                 VectorClear(center);
2502                                 for (i = 0;i < 4;i++)
2503                                         VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
2504                                 VectorScale(center, 0.25f, center);
2505                                 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
2506                                 Matrix4x4_FromVectors(&matrix1, (rsurface_normal3f + 3 * surface->num_firstvertex) + j*3, (rsurface_svector3f + 3 * surface->num_firstvertex) + j*3, (rsurface_tvector3f + 3 * surface->num_firstvertex) + j*3, center);
2507                                 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
2508                                 for (i = 0;i < 4;i++)
2509                                         Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
2510                                 for (i = 0;i < 4;i++)
2511                                         VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_vertex3f + (surface->num_firstvertex+i+j) * 3);
2512                         }
2513                         Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer);
2514                 }
2515                 rsurface_vertex3f = rsurface_array_vertex3f;
2516                 rsurface_svector3f = rsurface_array_svector3f;
2517                 rsurface_tvector3f = rsurface_array_tvector3f;
2518                 rsurface_normal3f = rsurface_array_normal3f;
2519         }
2520         R_Mesh_VertexPointer(rsurface_vertex3f);
2521 }
2522
2523 static void RSurf_Draw(const msurface_t *surface)
2524 {
2525         GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2526         R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2527 }
2528
2529 static void RSurf_DrawLightmap(const msurface_t *surface, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
2530 {
2531         int i;
2532         float f;
2533         float *v, *c, *c2;
2534         if (lightmode >= 2)
2535         {
2536                 // model lighting
2537                 vec3_t ambientcolor;
2538                 vec3_t diffusecolor;
2539                 vec3_t lightdir;
2540                 VectorCopy(rsurface_entity->modellight_lightdir, lightdir);
2541                 ambientcolor[0] = rsurface_entity->modellight_ambient[0] * r * 0.5f;
2542                 ambientcolor[1] = rsurface_entity->modellight_ambient[1] * g * 0.5f;
2543                 ambientcolor[2] = rsurface_entity->modellight_ambient[2] * b * 0.5f;
2544                 diffusecolor[0] = rsurface_entity->modellight_diffuse[0] * r * 0.5f;
2545                 diffusecolor[1] = rsurface_entity->modellight_diffuse[1] * g * 0.5f;
2546                 diffusecolor[2] = rsurface_entity->modellight_diffuse[2] * b * 0.5f;
2547                 if (VectorLength2(diffusecolor) > 0)
2548                 {
2549                         int numverts = surface->num_vertices;
2550                         v = rsurface_vertex3f + 3 * surface->num_firstvertex;
2551                         c2 = rsurface_normal3f + 3 * surface->num_firstvertex;
2552                         c = rsurface_array_color4f + 4 * surface->num_firstvertex;
2553                         // q3-style directional shading
2554                         for (i = 0;i < numverts;i++, v += 3, c2 += 3, c += 4)
2555                         {
2556                                 if ((f = DotProduct(c2, lightdir)) > 0)
2557                                         VectorMA(ambientcolor, f, diffusecolor, c);
2558                                 else
2559                                         VectorCopy(ambientcolor, c);
2560                                 c[3] = a;
2561                         }
2562                         r = 1;
2563                         g = 1;
2564                         b = 1;
2565                         a = 1;
2566                         applycolor = false;
2567                         rsurface_lightmapcolor4f = rsurface_array_color4f;
2568                 }
2569                 else
2570                 {
2571                         r = ambientcolor[0];
2572                         g = ambientcolor[1];
2573                         b = ambientcolor[2];
2574                         rsurface_lightmapcolor4f = NULL;
2575                 }
2576         }
2577         else if (lightmode >= 1)
2578         {
2579                 if (surface->lightmapinfo && surface->lightmapinfo->stainsamples)
2580                 {
2581                         for (i = 0, c = rsurface_array_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
2582                         {
2583                                 if (surface->lightmapinfo->samples)
2584                                 {
2585                                         const unsigned char *lm = surface->lightmapinfo->samples + (rsurface_model->surfmesh.data_lightmapoffsets + surface->num_firstvertex)[i];
2586                                         float scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
2587                                         VectorScale(lm, scale, c);
2588                                         if (surface->lightmapinfo->styles[1] != 255)
2589                                         {
2590                                                 int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
2591                                                 lm += size3;
2592                                                 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
2593                                                 VectorMA(c, scale, lm, c);
2594                                                 if (surface->lightmapinfo->styles[2] != 255)
2595                                                 {
2596                                                         lm += size3;
2597                                                         scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
2598                                                         VectorMA(c, scale, lm, c);
2599                                                         if (surface->lightmapinfo->styles[3] != 255)
2600                                                         {
2601                                                                 lm += size3;
2602                                                                 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
2603                                                                 VectorMA(c, scale, lm, c);
2604                                                         }
2605                                                 }
2606                                         }
2607                                 }
2608                                 else
2609                                         VectorClear(c);
2610                         }
2611                         rsurface_lightmapcolor4f = rsurface_array_color4f;
2612                 }
2613                 else
2614                         rsurface_lightmapcolor4f = rsurface_model->surfmesh.data_lightmapcolor4f;
2615         }
2616         else
2617                 rsurface_lightmapcolor4f = NULL;
2618         if (applyfog)
2619         {
2620                 if (rsurface_lightmapcolor4f)
2621                 {
2622                         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)
2623                         {
2624                                 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2625                                 c2[0] = c[0] * f;
2626                                 c2[1] = c[1] * f;
2627                                 c2[2] = c[2] * f;
2628                                 c2[3] = c[3];
2629                         }
2630                 }
2631                 else
2632                 {
2633                         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)
2634                         {
2635                                 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2636                                 c2[0] = f;
2637                                 c2[1] = f;
2638                                 c2[2] = f;
2639                                 c2[3] = 1;
2640                         }
2641                 }
2642                 rsurface_lightmapcolor4f = rsurface_array_color4f;
2643         }
2644         if (applycolor && rsurface_lightmapcolor4f)
2645         {
2646                 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)
2647                 {
2648                         c2[0] = c[0] * r;
2649                         c2[1] = c[1] * g;
2650                         c2[2] = c[2] * b;
2651                         c2[3] = c[3] * a;
2652                 }
2653                 rsurface_lightmapcolor4f = rsurface_array_color4f;
2654         }
2655         R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
2656         GL_Color(r, g, b, a);
2657         RSurf_Draw(surface);
2658 }
2659
2660 static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, msurface_t **texturesurfacelist, const vec3_t modelorg)
2661 {
2662         int texturesurfaceindex;
2663         int lightmode;
2664         const msurface_t *surface;
2665         model_t *model = ent->model;
2666         qboolean applycolor;
2667         qboolean applyfog;
2668         rmeshstate_t m;
2669         if (texture->currentmaterialflags & MATERIALFLAG_NODRAW)
2670                 return;
2671         r_shadow_rtlight = NULL;
2672         renderstats.entities_surfaces += texturenumsurfaces;
2673         // FIXME: identify models using a better check than model->brush.shadowmesh
2674         lightmode = ((ent->effects & EF_FULLBRIGHT) || model->brush.shadowmesh) ? 0 : 2;
2675         GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
2676         if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
2677                 qglDisable(GL_CULL_FACE);
2678         if (r_showsurfaces.integer)
2679         {
2680                 GL_DepthMask(true);
2681                 GL_BlendFunc(GL_ONE, GL_ZERO);
2682                 R_Mesh_ColorPointer(NULL);
2683                 R_Mesh_ResetTextureState();
2684                 RSurf_PrepareVerticesForBatch(ent, texture, modelorg, false, false, texturenumsurfaces, texturesurfacelist);
2685                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2686                 {
2687                         int k = (int)(((size_t)surface) / sizeof(msurface_t));
2688                         GL_Color((k & 15) * (1.0f / 16.0f), ((k >> 4) & 15) * (1.0f / 16.0f), ((k >> 8) & 15) * (1.0f / 16.0f), 0.2f);
2689                         surface = texturesurfacelist[texturesurfaceindex];
2690                         RSurf_Draw(surface);
2691                 }
2692         }
2693         else if (texture->currentmaterialflags & MATERIALFLAG_SKY)
2694         {
2695                 // transparent sky would be ridiculous
2696                 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2697                 {
2698                         if (skyrendernow)
2699                         {
2700                                 skyrendernow = false;
2701                                 R_Sky();
2702                                 // restore entity matrix
2703                                 R_Mesh_Matrix(&ent->matrix);
2704                         }
2705                         GL_DepthMask(true);
2706                         // LordHavoc: HalfLife maps have freaky skypolys so don't use
2707                         // skymasking on them, and Quake3 never did sky masking (unlike
2708                         // software Quake and software Quake2), so disable the sky masking
2709                         // in Quake3 maps as it causes problems with q3map2 sky tricks,
2710                         // and skymasking also looks very bad when noclipping outside the
2711                         // level, so don't use it then either.
2712                         if (model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2713                         {
2714                                 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
2715                                 R_Mesh_ColorPointer(NULL);
2716                                 R_Mesh_ResetTextureState();
2717                                 if (skyrendermasked)
2718                                 {
2719                                         // depth-only (masking)
2720                                         GL_ColorMask(0,0,0,0);
2721                                         // just to make sure that braindead drivers don't draw
2722                                         // anything despite that colormask...
2723                                         GL_BlendFunc(GL_ZERO, GL_ONE);
2724                                 }
2725                                 else
2726                                 {
2727                                         // fog sky
2728                                         GL_BlendFunc(GL_ONE, GL_ZERO);
2729                                 }
2730                                 RSurf_PrepareVerticesForBatch(ent, texture, modelorg, false, false, texturenumsurfaces, texturesurfacelist);
2731                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2732                                 {
2733                                         surface = texturesurfacelist[texturesurfaceindex];
2734                                         RSurf_Draw(surface);
2735                                 }
2736                                 if (skyrendermasked)
2737                                         GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
2738                         }
2739                 }
2740         }
2741         else if (r_glsl.integer && gl_support_fragment_shader)
2742         {
2743                 if (texture->currentmaterialflags & MATERIALFLAG_ADD)
2744                 {
2745                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2746                         GL_DepthMask(false);
2747                 }
2748                 else if (texture->currentmaterialflags & MATERIALFLAG_ALPHA)
2749                 {
2750                         GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2751                         GL_DepthMask(false);
2752                 }
2753                 else
2754                 {
2755                         GL_BlendFunc(GL_ONE, GL_ZERO);
2756                         GL_DepthMask(true);
2757                 }
2758
2759                 R_Mesh_ColorPointer(NULL);
2760                 R_Mesh_ResetTextureState();
2761                 GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], texture->currentalpha);
2762                 R_SetupSurfaceShader(ent, texture, modelorg, vec3_origin, lightmode == 2);
2763                 if (!r_glsl_permutation)
2764                         return;
2765                 RSurf_PrepareVerticesForBatch(ent, texture, modelorg, true, true, texturenumsurfaces, texturesurfacelist);
2766                 R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f);
2767                 R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
2768                 R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
2769                 R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
2770                 if (lightmode == 2)
2771                 {
2772                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2773                         {
2774                                 surface = texturesurfacelist[texturesurfaceindex];
2775                                 RSurf_Draw(surface);
2776                         }
2777                 }
2778                 else
2779                 {
2780                         R_Mesh_TexCoordPointer(4, 2, model->surfmesh.data_texcoordlightmap2f);
2781                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2782                         {
2783                                 surface = texturesurfacelist[texturesurfaceindex];
2784                                 if (surface->lightmaptexture)
2785                                 {
2786                                         R_Mesh_TexBind(7, R_GetTexture(surface->lightmaptexture));
2787                                         if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2788                                                 R_Mesh_TexBind(8, R_GetTexture(surface->deluxemaptexture));
2789                                         R_Mesh_ColorPointer(NULL);
2790                                 }
2791                                 else
2792                                 {
2793                                         R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
2794                                         if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2795                                                 R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
2796                                         R_Mesh_ColorPointer(model->surfmesh.data_lightmapcolor4f);
2797                                 }
2798                                 RSurf_Draw(surface);
2799                         }
2800                 }
2801                 qglUseProgramObjectARB(0);
2802         }
2803         else if (texture->currentnumlayers)
2804         {
2805                 int layerindex;
2806                 texturelayer_t *layer;
2807                 RSurf_PrepareVerticesForBatch(ent, texture, modelorg, true, false, texturenumsurfaces, texturesurfacelist);
2808                 for (layerindex = 0, layer = texture->currentlayers;layerindex < texture->currentnumlayers;layerindex++, layer++)
2809                 {
2810                         vec4_t layercolor;
2811                         int layertexrgbscale;
2812                         GL_DepthMask(layer->depthmask);
2813                         GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
2814                         if ((layer->color[0] > 2 || layer->color[1] > 2 || layer->color[2] > 2) && (gl_combine.integer || layer->depthmask))
2815                         {
2816                                 layertexrgbscale = 4;
2817                                 VectorScale(layer->color, 0.25f, layercolor);
2818                         }
2819                         else if ((layer->color[0] > 1 || layer->color[1] > 1 || layer->color[2] > 1) && (gl_combine.integer || layer->depthmask))
2820                         {
2821                                 layertexrgbscale = 2;
2822                                 VectorScale(layer->color, 0.5f, layercolor);
2823                         }
2824                         else
2825                         {
2826                                 layertexrgbscale = 1;
2827                                 VectorScale(layer->color, 1.0f, layercolor);
2828                         }
2829                         layercolor[3] = layer->color[3];
2830                         R_Mesh_ColorPointer(NULL);
2831                         GL_Color(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
2832                         applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
2833                         applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
2834                         switch (layer->type)
2835                         {
2836                         case TEXTURELAYERTYPE_LITTEXTURE_COMBINE:
2837                                 memset(&m, 0, sizeof(m));
2838                                 m.pointer_texcoord[0] = model->surfmesh.data_texcoordlightmap2f;
2839                                 m.tex[1] = R_GetTexture(layer->texture);
2840                                 m.texmatrix[1] = layer->texmatrix;
2841                                 m.texrgbscale[1] = layertexrgbscale;
2842                                 m.pointer_texcoord[1] = model->surfmesh.data_texcoordtexture2f;
2843                                 R_Mesh_TextureState(&m);
2844                                 if (lightmode == 2)
2845                                 {
2846                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2847                                         {
2848                                                 surface = texturesurfacelist[texturesurfaceindex];
2849                                                 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2850                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
2851                                         }
2852                                 }
2853                                 else
2854                                 {
2855                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2856                                         {
2857                                                 surface = texturesurfacelist[texturesurfaceindex];
2858                                                 if (surface->lightmaptexture)
2859                                                 {
2860                                                         R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
2861                                                         RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
2862                                                 }
2863                                                 else
2864                                                 {
2865                                                         R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2866                                                         RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
2867                                                 }
2868                                         }
2869                                 }
2870                                 break;
2871                         case TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS:
2872                                 memset(&m, 0, sizeof(m));
2873                                 m.tex[0] = R_GetTexture(layer->texture);
2874                                 m.texmatrix[0] = layer->texmatrix;
2875                                 m.texrgbscale[0] = layertexrgbscale;
2876                                 m.pointer_texcoord[0] = model->surfmesh.data_texcoordlightmap2f;
2877                                 R_Mesh_TextureState(&m);
2878                                 if (lightmode == 2)
2879                                 {
2880                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2881                                         {
2882                                                 surface = texturesurfacelist[texturesurfaceindex];
2883                                                 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2884                                                 RSurf_DrawLightmap(surface, 1, 1, 1, 1, 2, false, false);
2885                                         }
2886                                 }
2887                                 else
2888                                 {
2889                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2890                                         {
2891                                                 surface = texturesurfacelist[texturesurfaceindex];
2892                                                 if (surface->lightmaptexture)
2893                                                 {
2894                                                         R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
2895                                                         RSurf_DrawLightmap(surface, 1, 1, 1, 1, 0, false, false);
2896                                                 }
2897                                                 else
2898                                                 {
2899                                                         R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2900                                                         RSurf_DrawLightmap(surface, 1, 1, 1, 1, 1, false, false);
2901                                                 }
2902                                         }
2903                                 }
2904                                 GL_LockArrays(0, 0);
2905                                 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
2906                                 memset(&m, 0, sizeof(m));
2907                                 m.tex[0] = R_GetTexture(layer->texture);
2908                                 m.texmatrix[0] = layer->texmatrix;
2909                                 m.texrgbscale[0] = layertexrgbscale;
2910                                 m.pointer_texcoord[0] = model->surfmesh.data_texcoordtexture2f;
2911                                 R_Mesh_TextureState(&m);
2912                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2913                                 {
2914                                         surface = texturesurfacelist[texturesurfaceindex];
2915                                         RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, false);
2916                                 }
2917                                 break;
2918                         case TEXTURELAYERTYPE_LITTEXTURE_VERTEX:
2919                                 memset(&m, 0, sizeof(m));
2920                                 m.tex[0] = R_GetTexture(layer->texture);
2921                                 m.texmatrix[0] = layer->texmatrix;
2922                                 m.texrgbscale[0] = layertexrgbscale;
2923                                 m.pointer_texcoord[0] = model->surfmesh.data_texcoordtexture2f;
2924                                 R_Mesh_TextureState(&m);
2925                                 if (lightmode == 2)
2926                                 {
2927                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2928                                         {
2929                                                 surface = texturesurfacelist[texturesurfaceindex];
2930                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
2931                                         }
2932                                 }
2933                                 else
2934                                 {
2935                                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2936                                         {
2937                                                 surface = texturesurfacelist[texturesurfaceindex];
2938                                                 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
2939                                         }
2940                                 }
2941                                 break;
2942                         case TEXTURELAYERTYPE_TEXTURE:
2943                                 memset(&m, 0, sizeof(m));
2944                                 m.tex[0] = R_GetTexture(layer->texture);
2945                                 m.texmatrix[0] = layer->texmatrix;
2946                                 m.texrgbscale[0] = layertexrgbscale;
2947                                 m.pointer_texcoord[0] = model->surfmesh.data_texcoordtexture2f;
2948                                 R_Mesh_TextureState(&m);
2949                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2950                                 {
2951                                         surface = texturesurfacelist[texturesurfaceindex];
2952                                         RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
2953                                 }
2954                                 break;
2955                         case TEXTURELAYERTYPE_FOG:
2956                                 R_Mesh_ColorPointer(rsurface_array_color4f);
2957                                 if (layer->texture)
2958                                 {
2959                                         memset(&m, 0, sizeof(m));
2960                                         m.tex[0] = R_GetTexture(layer->texture);
2961                                         m.texmatrix[0] = layer->texmatrix;
2962                                         m.pointer_texcoord[0] = model->surfmesh.data_texcoordtexture2f;
2963                                         R_Mesh_TextureState(&m);
2964                                 }
2965                                 else
2966                                         R_Mesh_ResetTextureState();
2967                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2968                                 {
2969                                         int i;
2970                                         float f, *v, *c;
2971                                         surface = texturesurfacelist[texturesurfaceindex];
2972                                         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)
2973                                         {
2974                                                 f = VERTEXFOGTABLE(VectorDistance(v, modelorg));
2975                                                 c[0] = layercolor[0];
2976                                                 c[1] = layercolor[1];
2977                                                 c[2] = layercolor[2];
2978                                                 c[3] = f * layercolor[3];
2979                                         }
2980                                         RSurf_Draw(surface);
2981                                 }
2982                                 break;
2983                         default:
2984                                 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
2985                         }
2986                         GL_LockArrays(0, 0);
2987                         // if trying to do overbright on first pass of an opaque surface
2988                         // when combine is not supported, brighten as a post process
2989                         if (layertexrgbscale > 1 && !gl_combine.integer && layer->depthmask)
2990                         {
2991                                 int scale;
2992                                 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
2993                                 R_Mesh_ColorPointer(NULL);
2994                                 GL_Color(1, 1, 1, 1);
2995                                 R_Mesh_ResetTextureState();
2996                                 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2997                                 {
2998                                         surface = texturesurfacelist[texturesurfaceindex];
2999                                         for (scale = 1;scale < layertexrgbscale;scale <<= 1)
3000                                                 RSurf_Draw(surface);
3001                                 }
3002                                 GL_LockArrays(0, 0);
3003                         }
3004                 }
3005         }
3006         GL_LockArrays(0, 0);
3007         if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
3008                 qglEnable(GL_CULL_FACE);
3009 }
3010
3011 static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
3012 {
3013         msurface_t *surface = ent->model->data_surfaces + surfacenumber;
3014         vec3_t modelorg;
3015         texture_t *texture;
3016
3017         texture = surface->texture;
3018         if (texture->basematerialflags & MATERIALFLAG_SKY)
3019                 return; // transparent sky is too difficult
3020         R_UpdateTextureInfo(ent, texture);
3021
3022         R_Mesh_Matrix(&ent->matrix);
3023         Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
3024         R_DrawTextureSurfaceList(ent, texture->currentframe, 1, &surface, modelorg);
3025 }
3026
3027 void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int texturenumsurfaces, msurface_t **texturesurfacelist, const vec3_t modelorg)
3028 {
3029         int texturesurfaceindex;
3030         const msurface_t *surface;
3031         vec3_t tempcenter, center;
3032         if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)
3033         {
3034                 // drawing sky transparently would be too difficult
3035                 if (!(texture->currentmaterialflags & MATERIALFLAG_SKY))
3036                 {
3037                         for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3038                         {
3039                                 surface = texturesurfacelist[texturesurfaceindex];
3040                                 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
3041                                 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
3042                                 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
3043                                 Matrix4x4_Transform(&ent->matrix, tempcenter, center);
3044                                 R_MeshQueue_AddTransparent(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, R_DrawSurface_TransparentCallback, ent, surface - ent->model->data_surfaces, r_shadow_rtlight);
3045                         }
3046                 }
3047         }
3048         else
3049                 R_DrawTextureSurfaceList(ent, texture, texturenumsurfaces, texturesurfacelist, modelorg);
3050 }
3051
3052 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
3053 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
3054 {
3055         int i, j, f, flagsmask;
3056         int counttriangles = 0;
3057         msurface_t *surface, **surfacechain;
3058         texture_t *t, *texture;
3059         model_t *model = ent->model;
3060         vec3_t modelorg;
3061         const int maxsurfacelist = 1024;
3062         int numsurfacelist = 0;
3063         msurface_t *surfacelist[1024];
3064         if (model == NULL)
3065                 return;
3066         R_Mesh_Matrix(&ent->matrix);
3067         Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
3068
3069         // update light styles
3070         if (!skysurfaces && model->brushq1.light_styleupdatechains)
3071         {
3072                 for (i = 0;i < model->brushq1.light_styles;i++)
3073                 {
3074                         if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
3075                         {
3076                                 model->brushq1.light_stylevalue[i] = r_refdef.lightstylevalue[model->brushq1.light_style[i]];
3077                                 if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
3078                                         for (;(surface = *surfacechain);surfacechain++)
3079                                                 surface->cached_dlight = true;
3080                         }
3081                 }
3082         }
3083
3084         R_UpdateAllTextureInfo(ent);
3085         flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
3086         f = 0;
3087         t = NULL;
3088         texture = NULL;
3089         numsurfacelist = 0;
3090         if (ent == r_refdef.worldentity)
3091         {
3092                 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3093                 {
3094                         if (!r_worldsurfacevisible[j])
3095                                 continue;
3096                         if (t != surface->texture)
3097                         {
3098                                 if (numsurfacelist)
3099                                 {
3100                                         R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3101                                         numsurfacelist = 0;
3102                                 }
3103                                 t = surface->texture;
3104                                 texture = t->currentframe;
3105                                 f = texture->currentmaterialflags & flagsmask;
3106                         }
3107                         if (f && surface->num_triangles)
3108                         {
3109                                 // if lightmap parameters changed, rebuild lightmap texture
3110                                 if (surface->cached_dlight)
3111                                         R_BuildLightMap(ent, surface);
3112                                 // add face to draw list
3113                                 surfacelist[numsurfacelist++] = surface;
3114                                 counttriangles += surface->num_triangles;
3115                                 if (numsurfacelist >= maxsurfacelist)
3116                                 {
3117                                         R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3118                                         numsurfacelist = 0;
3119                                 }
3120                         }
3121                 }
3122         }
3123         else
3124         {
3125                 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3126                 {
3127                         if (t != surface->texture)
3128                         {
3129                                 if (numsurfacelist)
3130                                 {
3131                                         R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3132                                         numsurfacelist = 0;
3133                                 }
3134                                 t = surface->texture;
3135                                 texture = t->currentframe;
3136                                 f = texture->currentmaterialflags & flagsmask;
3137                         }
3138                         if (f && surface->num_triangles)
3139                         {
3140                                 // if lightmap parameters changed, rebuild lightmap texture
3141                                 if (surface->cached_dlight)
3142                                         R_BuildLightMap(ent, surface);
3143                                 // add face to draw list
3144                                 surfacelist[numsurfacelist++] = surface;
3145                                 counttriangles += surface->num_triangles;
3146                                 if (numsurfacelist >= maxsurfacelist)
3147                                 {
3148                                         R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3149                                         numsurfacelist = 0;
3150                                 }
3151                         }
3152                 }
3153         }
3154         if (numsurfacelist)
3155                 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
3156         renderstats.entities_triangles += counttriangles;
3157         if (gl_support_fragment_shader)
3158                 qglUseProgramObjectARB(0);
3159
3160         if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces)
3161         {
3162                 int i;
3163                 msurface_t *surface;
3164                 q3mbrush_t *brush;
3165                 R_Mesh_Matrix(&ent->matrix);
3166                 R_Mesh_ColorPointer(NULL);
3167                 R_Mesh_ResetTextureState();
3168                 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
3169                 GL_DepthMask(false);
3170                 GL_DepthTest(!r_showdisabledepthtest.integer);
3171                 qglPolygonOffset(r_polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_polygonoffset + r_showcollisionbrushes_polygonoffset.value);
3172                 for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
3173                         if (brush->colbrushf && brush->colbrushf->numtriangles)
3174                                 R_DrawCollisionBrush(brush->colbrushf);
3175                 for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
3176                         if (surface->num_collisiontriangles)
3177                                 R_DrawCollisionSurface(ent, surface);
3178                 qglPolygonOffset(r_polygonfactor, r_polygonoffset);
3179         }
3180
3181         if (r_showtris.integer || r_shownormals.integer)
3182         {
3183                 int k, l;
3184                 const int *elements;
3185                 vec3_t v;
3186                 GL_DepthTest(true);
3187                 GL_DepthMask(true);
3188                 if (r_showdisabledepthtest.integer)
3189                         qglDepthFunc(GL_ALWAYS);
3190                 GL_BlendFunc(GL_ONE, GL_ZERO);
3191                 R_Mesh_ColorPointer(NULL);
3192                 R_Mesh_ResetTextureState();
3193                 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3194                 {
3195                         if (ent == r_refdef.worldentity && !r_worldsurfacevisible[j])
3196                                 continue;
3197                         texture = surface->texture->currentframe;
3198                         if ((texture->currentmaterialflags & flagsmask) && surface->num_triangles)
3199                         {
3200                                 RSurf_PrepareVerticesForBatch(ent, texture, modelorg, false, r_shownormals.integer != 0, 1, &surface);
3201                                 if (r_showtris.integer)
3202                                 {
3203                                         if (!texture->currentlayers->depthmask)
3204                                                 GL_Color(r_showtris.value, 0, 0, 1);
3205                                         else if (ent == r_refdef.worldentity)
3206                                                 GL_Color(r_showtris.value, r_showtris.value, r_showtris.value, 1);
3207                                         else
3208                                                 GL_Color(0, r_showtris.value, 0, 1);
3209                                         elements = (ent->model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);
3210                                         qglBegin(GL_LINES);
3211                                         for (k = 0;k < surface->num_triangles;k++, elements += 3)
3212                                         {
3213                                                 qglArrayElement(elements[0]);qglArrayElement(elements[1]);
3214                                                 qglArrayElement(elements[1]);qglArrayElement(elements[2]);
3215                                                 qglArrayElement(elements[2]);qglArrayElement(elements[0]);
3216                                         }
3217                                         qglEnd();
3218                                 }
3219                                 if (r_shownormals.integer)
3220                                 {
3221                                         GL_Color(r_shownormals.value, 0, 0, 1);
3222                                         qglBegin(GL_LINES);
3223                                         for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3224                                         {
3225                                                 VectorCopy(rsurface_vertex3f + l * 3, v);
3226                                                 qglVertex3f(v[0], v[1], v[2]);
3227                                                 VectorMA(v, 8, rsurface_svector3f + l * 3, v);
3228                                                 qglVertex3f(v[0], v[1], v[2]);
3229                                         }
3230                                         qglEnd();
3231                                         GL_Color(0, 0, r_shownormals.value, 1);
3232                                         qglBegin(GL_LINES);
3233                                         for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3234                                         {
3235                                                 VectorCopy(rsurface_vertex3f + l * 3, v);
3236                                                 qglVertex3f(v[0], v[1], v[2]);
3237                                                 VectorMA(v, 8, rsurface_tvector3f + l * 3, v);
3238                                                 qglVertex3f(v[0], v[1], v[2]);
3239                                         }
3240                                         qglEnd();
3241                                         GL_Color(0, r_shownormals.value, 0, 1);
3242                                         qglBegin(GL_LINES);
3243                                         for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3244                                         {
3245                                                 VectorCopy(rsurface_vertex3f + l * 3, v);
3246                                                 qglVertex3f(v[0], v[1], v[2]);
3247                                                 VectorMA(v, 8, rsurface_normal3f + l * 3, v);
3248                                                 qglVertex3f(v[0], v[1], v[2]);
3249                                         }
3250                                         qglEnd();
3251                                 }
3252                         }
3253                 }
3254                 if (r_showdisabledepthtest.integer)
3255                         qglDepthFunc(GL_LEQUAL);
3256         }
3257 }
3258