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