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