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