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