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