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