2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
26 mempool_t *r_main_mempool;
27 rtexturepool_t *r_main_texturepool;
29 // used for dlight push checking and other things
34 renderstats_t renderstats;
36 // true during envmap command capture
39 // maximum visible distance (recalculated from world box each frame)
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
46 qboolean r_rtworldshadows;
48 qboolean r_rtdlightshadows;
63 matrix4x4_t r_view_matrix;
64 float r_polygonfactor;
65 float r_polygonoffset;
66 float r_shadowpolygonfactor;
67 float r_shadowpolygonoffset;
73 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
74 cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "shows surfaces as different colors"};
75 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
76 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
77 cvar_t r_showlighting = {0, "r_showlighting", "0", "shows areas lit by lights, useful for finding out why some areas of a map render slowly (bright orange = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
78 cvar_t r_showshadowvolumes = {0, "r_showshadowvolumes", "0", "shows areas shadowed by lights, useful for finding out why some areas of a map render slowly (bright blue = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
79 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
80 cvar_t r_showcollisionbrushes_polygonfactor = {0, "r_showcollisionbrushes_polygonfactor", "-1", "expands outward the brush polygons a little bit, used to make collision brushes appear infront of walls"};
81 cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygonoffset", "0", "nudges brush polygon depth in hardware depth units, used to make collision brushes appear infront of walls"};
82 cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing\n"};
83 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
84 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
85 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
86 cvar_t r_fullbright = {0, "r_fullbright","0", "make everything bright cheat (not allowed in multiplayer)"};
87 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
88 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
89 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
90 cvar_t r_q1bsp_skymasking = {0, "r_qb1sp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
92 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
93 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
94 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
95 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
96 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
97 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
98 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
100 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of hardware texture units reported by driver (note: setting this to 1 turns off gl_combine)"};
102 cvar_t r_glsl = {0, "r_glsl", "1", "enables use of OpenGL 2.0 pixel shaders for lighting"};
103 cvar_t r_glsl_offsetmapping = {0, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
104 cvar_t r_glsl_offsetmapping_reliefmapping = {0, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
105 cvar_t r_glsl_offsetmapping_scale = {0, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
106 cvar_t r_glsl_deluxemapping = {0, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"};
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"};
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"};
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"};
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"};
122 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
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 cvar_t r_batchmode = {0, "r_batchmode", "1", "selects method of rendering multiple surfaces with one driver call (values are 0, 1, 2, etc...)"};
127 rtexture_t *r_bloom_texture_screen;
128 rtexture_t *r_bloom_texture_bloom;
129 rtexture_t *r_texture_blanknormalmap;
130 rtexture_t *r_texture_white;
131 rtexture_t *r_texture_black;
132 rtexture_t *r_texture_notexture;
133 rtexture_t *r_texture_whitecube;
134 rtexture_t *r_texture_normalizationcube;
135 rtexture_t *r_texture_fogattenuation;
136 //rtexture_t *r_texture_fogintensity;
138 // information about each possible shader permutation
139 r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_COUNT];
140 // currently selected permutation
141 r_glsl_permutation_t *r_glsl_permutation;
143 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
146 for (i = 0;i < verts;i++)
157 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
160 for (i = 0;i < verts;i++)
175 vec_t fogtabledistmultiplier;
176 float fogtable[FOGTABLEWIDTH];
177 float fog_density, fog_red, fog_green, fog_blue;
179 qboolean oldgl_fogenable;
180 void R_UpdateFog(void)
182 if (gamemode == GAME_NEHAHRA)
184 if (gl_fogenable.integer)
186 oldgl_fogenable = true;
187 fog_density = gl_fogdensity.value;
188 fog_red = gl_fogred.value;
189 fog_green = gl_foggreen.value;
190 fog_blue = gl_fogblue.value;
192 else if (oldgl_fogenable)
194 oldgl_fogenable = false;
203 fogcolor[0] = fog_red = bound(0.0f, fog_red , 1.0f);
204 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
205 fogcolor[2] = fog_blue = bound(0.0f, fog_blue , 1.0f);
210 fogdensity = -4000.0f / (fog_density * fog_density);
211 // this is the point where the fog reaches 0.9986 alpha, which we
212 // consider a good enough cutoff point for the texture
213 // (0.9986 * 256 == 255.6)
214 fogrange = 400 / fog_density;
215 fograngerecip = 1.0f / fogrange;
216 fogtabledistmultiplier = FOGTABLEWIDTH * fograngerecip;
217 // fog color was already set
223 // FIXME: move this to client?
226 if (gamemode == GAME_NEHAHRA)
228 Cvar_Set("gl_fogenable", "0");
229 Cvar_Set("gl_fogdensity", "0.2");
230 Cvar_Set("gl_fogred", "0.3");
231 Cvar_Set("gl_foggreen", "0.3");
232 Cvar_Set("gl_fogblue", "0.3");
234 fog_density = fog_red = fog_green = fog_blue = 0.0f;
237 // FIXME: move this to client?
238 void FOG_registercvars(void)
243 if (gamemode == GAME_NEHAHRA)
245 Cvar_RegisterVariable (&gl_fogenable);
246 Cvar_RegisterVariable (&gl_fogdensity);
247 Cvar_RegisterVariable (&gl_fogred);
248 Cvar_RegisterVariable (&gl_foggreen);
249 Cvar_RegisterVariable (&gl_fogblue);
250 Cvar_RegisterVariable (&gl_fogstart);
251 Cvar_RegisterVariable (&gl_fogend);
254 r = (-1.0/256.0) * (FOGTABLEWIDTH * FOGTABLEWIDTH);
255 for (x = 0;x < FOGTABLEWIDTH;x++)
257 alpha = exp(r / ((double)x*(double)x));
258 if (x == FOGTABLEWIDTH - 1)
260 fogtable[x] = bound(0, alpha, 1);
264 static void R_BuildBlankTextures(void)
266 unsigned char data[4];
267 data[0] = 128; // normal X
268 data[1] = 128; // normal Y
269 data[2] = 255; // normal Z
270 data[3] = 128; // height
271 r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
276 r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
281 r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
284 static void R_BuildNoTexture(void)
287 unsigned char pix[16][16][4];
288 // this makes a light grey/dark grey checkerboard texture
289 for (y = 0;y < 16;y++)
291 for (x = 0;x < 16;x++)
293 if ((y < 8) ^ (x < 8))
309 r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL);
312 static void R_BuildWhiteCube(void)
314 unsigned char data[6*1*1*4];
315 data[ 0] = 255;data[ 1] = 255;data[ 2] = 255;data[ 3] = 255;
316 data[ 4] = 255;data[ 5] = 255;data[ 6] = 255;data[ 7] = 255;
317 data[ 8] = 255;data[ 9] = 255;data[10] = 255;data[11] = 255;
318 data[12] = 255;data[13] = 255;data[14] = 255;data[15] = 255;
319 data[16] = 255;data[17] = 255;data[18] = 255;data[19] = 255;
320 data[20] = 255;data[21] = 255;data[22] = 255;data[23] = 255;
321 r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
324 static void R_BuildNormalizationCube(void)
328 vec_t s, t, intensity;
330 unsigned char data[6][NORMSIZE][NORMSIZE][4];
331 for (side = 0;side < 6;side++)
333 for (y = 0;y < NORMSIZE;y++)
335 for (x = 0;x < NORMSIZE;x++)
337 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
338 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
373 intensity = 127.0f / sqrt(DotProduct(v, v));
374 data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[0]);
375 data[side][y][x][1] = (unsigned char)(128.0f + intensity * v[1]);
376 data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[2]);
377 data[side][y][x][3] = 255;
381 r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
384 static void R_BuildFogTexture(void)
389 unsigned char data1[FOGWIDTH][4];
390 //unsigned char data2[FOGWIDTH][4];
391 r = (-1.0/256.0) * (FOGWIDTH * FOGWIDTH);
392 for (x = 0;x < FOGWIDTH;x++)
394 alpha = exp(r / ((double)x*(double)x));
395 if (x == FOGWIDTH - 1)
397 b = (int)(256.0 * alpha);
398 b = bound(0, b, 255);
399 data1[x][0] = 255 - b;
400 data1[x][1] = 255 - b;
401 data1[x][2] = 255 - b;
408 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
409 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
412 static const char *builtinshaderstring =
413 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
414 "// written by Forest 'LordHavoc' Hale\n"
416 "// common definitions between vertex shader and fragment shader:\n"
418 "varying vec2 TexCoord;\n"
419 "varying vec2 TexCoordLightmap;\n"
421 "varying vec3 CubeVector;\n"
422 "varying vec3 LightVector;\n"
423 "varying vec3 EyeVector;\n"
425 "varying vec3 EyeVectorModelSpace;\n"
428 "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
429 "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
430 "varying vec3 VectorR; // direction of R texcoord (surface normal)\n"
435 "// vertex shader specific:\n"
436 "#ifdef VERTEX_SHADER\n"
438 "uniform vec3 LightPosition;\n"
439 "uniform vec3 EyePosition;\n"
440 "uniform vec3 LightDir;\n"
442 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3)\n"
446 " gl_FrontColor = gl_Color;\n"
447 " // copy the surface texcoord\n"
448 " TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n"
449 "#if !defined(MODE_LIGHTSOURCE) && !defined(MODE_LIGHTDIRECTION)\n"
450 " TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
453 "#ifdef MODE_LIGHTSOURCE\n"
454 " // transform vertex position into light attenuation/cubemap space\n"
455 " // (-1 to +1 across the light box)\n"
456 " CubeVector = vec3(gl_TextureMatrix[3] * gl_Vertex);\n"
458 " // transform unnormalized light direction into tangent space\n"
459 " // (we use unnormalized to ensure that it interpolates correctly and then\n"
460 " // normalize it per pixel)\n"
461 " vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
462 " LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
463 " LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
464 " LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
467 "#ifdef MODE_LIGHTDIRECTION\n"
468 " LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
469 " LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
470 " LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
473 " // transform unnormalized eye direction into tangent space\n"
475 " vec3 EyeVectorModelSpace;\n"
477 " EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
478 " EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
479 " EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
480 " EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
482 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
483 " VectorS = gl_MultiTexCoord1.xyz;\n"
484 " VectorT = gl_MultiTexCoord2.xyz;\n"
485 " VectorR = gl_MultiTexCoord3.xyz;\n"
488 " // transform vertex to camera space, using ftransform to match non-VS\n"
490 " gl_Position = ftransform();\n"
493 "#endif // VERTEX_SHADER\n"
498 "// fragment shader specific:\n"
499 "#ifdef FRAGMENT_SHADER\n"
501 "uniform sampler2D Texture_Normal;\n"
502 "uniform sampler2D Texture_Color;\n"
503 "uniform sampler2D Texture_Gloss;\n"
504 "uniform samplerCube Texture_Cube;\n"
505 "uniform sampler2D Texture_FogMask;\n"
506 "uniform sampler2D Texture_Pants;\n"
507 "uniform sampler2D Texture_Shirt;\n"
508 "uniform sampler2D Texture_Lightmap;\n"
509 "uniform sampler2D Texture_Deluxemap;\n"
510 "uniform sampler2D Texture_Glow;\n"
512 "uniform vec3 LightColor;\n"
513 "uniform vec3 AmbientColor;\n"
514 "uniform vec3 DiffuseColor;\n"
515 "uniform vec3 SpecularColor;\n"
516 "uniform vec3 Color_Pants;\n"
517 "uniform vec3 Color_Shirt;\n"
518 "uniform vec3 FogColor;\n"
520 "uniform float OffsetMapping_Scale;\n"
521 "uniform float OffsetMapping_Bias;\n"
522 "uniform float FogRangeRecip;\n"
524 "uniform float AmbientScale;\n"
525 "uniform float DiffuseScale;\n"
526 "uniform float SpecularScale;\n"
527 "uniform float SpecularPower;\n"
531 " // apply offsetmapping\n"
532 "#ifdef USEOFFSETMAPPING\n"
533 " vec2 TexCoordOffset = TexCoord;\n"
534 "#define TexCoord TexCoordOffset\n"
536 " vec3 eyedir = vec3(normalize(EyeVector));\n"
537 " float depthbias = 1.0 - eyedir.z; // should this be a -?\n"
538 " depthbias = 1.0 - depthbias * depthbias;\n"
540 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
541 " // 14 sample relief mapping: linear search and then binary search\n"
542 " vec3 OffsetVector = vec3(EyeVector.xy * (1.0 / EyeVector.z) * depthbias * OffsetMapping_Scale * vec2(-0.1, 0.1), -0.1);\n"
543 " vec3 RT = vec3(TexCoord - OffsetVector.xy * 10.0, 1.0) + OffsetVector;\n"
544 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
545 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
546 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
547 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
548 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
549 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
550 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
551 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
552 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
553 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
554 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
555 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
556 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
557 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
558 " TexCoord = RT.xy;\n"
560 " // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
561 " vec2 OffsetVector = vec2((EyeVector.xy * (1.0 / EyeVector.z) * depthbias) * OffsetMapping_Scale * vec2(-0.333, 0.333));\n"
562 " //TexCoord += OffsetVector * 3.0;\n"
563 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
564 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
565 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
569 " // combine the diffuse textures (base, pants, shirt)\n"
570 " vec4 color = vec4(texture2D(Texture_Color, TexCoord));\n"
571 "#ifdef USECOLORMAPPING\n"
572 " color.rgb += vec3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + vec3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
578 "#ifdef MODE_LIGHTSOURCE\n"
581 " // get the surface normal and light normal\n"
582 " vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
583 " vec3 diffusenormal = vec3(normalize(LightVector));\n"
585 " // calculate directional shading\n"
586 " color.rgb *= (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
587 "#ifdef USESPECULAR\n"
588 " vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
589 " color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
592 "#ifdef USECUBEFILTER\n"
593 " // apply light cubemap filter\n"
594 " //color.rgb *= normalize(CubeVector) * 0.5 + 0.5;//vec3(textureCube(Texture_Cube, CubeVector));\n"
595 " color.rgb *= vec3(textureCube(Texture_Cube, CubeVector));\n"
598 " // apply light color\n"
599 " color.rgb *= LightColor;\n"
601 " // apply attenuation\n"
603 " // the attenuation is (1-(x*x+y*y+z*z)) which gives a large bright\n"
604 " // center and sharp falloff at the edge, this is about the most efficient\n"
605 " // we can get away with as far as providing illumination.\n"
607 " // pow(1-(x*x+y*y+z*z), 4) is far more realistic but needs large lights to\n"
608 " // provide significant illumination, large = slow = pain.\n"
609 " color.rgb *= max(1.0 - dot(CubeVector, CubeVector), 0.0);\n"
614 "#elif defined(MODE_LIGHTDIRECTION)\n"
615 " // directional model lighting\n"
617 " // get the surface normal and light normal\n"
618 " vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
619 " vec3 diffusenormal = vec3(normalize(LightVector));\n"
621 " // calculate directional shading\n"
622 " color.rgb *= AmbientColor + DiffuseColor * max(dot(surfacenormal, diffusenormal), 0.0);\n"
623 "#ifdef USESPECULAR\n"
624 " vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
625 " color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
631 "#elif defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE)\n"
632 " // deluxemap lightmapping using light vectors in modelspace (evil q3map2)\n"
634 " // get the surface normal and light normal\n"
635 " vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
636 " vec3 diffusenormal_modelspace = vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5;\n"
637 " vec3 diffusenormal = normalize(vec3(dot(diffusenormal_modelspace, VectorS), dot(diffusenormal_modelspace, VectorT), dot(diffusenormal_modelspace, VectorR)));\n"
639 " // calculate directional shading\n"
640 " vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
641 "#ifdef USESPECULAR\n"
642 " vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
643 " tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
646 " // apply lightmap color\n"
647 " color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n"
652 "#elif defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
653 " // deluxemap lightmapping using light vectors in tangentspace\n"
655 " // get the surface normal and light normal\n"
656 " vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
657 " vec3 diffusenormal = normalize(vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5);\n"
659 " // calculate directional shading\n"
660 " vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
661 "#ifdef USESPECULAR\n"
662 " vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
663 " tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
666 " // apply lightmap color\n"
667 " color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n"
672 "#else // MODE none (lightmap)\n"
673 " // apply lightmap color\n"
674 " color.rgb *= vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + vec3(AmbientScale);\n"
677 " color *= gl_Color;\n"
680 " color.rgb += vec3(texture2D(Texture_Glow, TexCoord));\n"
685 " float fog = texture2D(Texture_FogMask, vec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0)).x;\n"
686 " color.rgb = color.rgb * fog + FogColor * (1.0 - fog);\n"
689 " gl_FragColor = color;\n"
692 "#endif // FRAGMENT_SHADER\n"
695 void R_GLSL_CompilePermutation(int permutation)
697 r_glsl_permutation_t *p = r_glsl_permutations + permutation;
698 int vertstrings_count;
699 int fragstrings_count;
701 const char *vertstrings_list[SHADERPERMUTATION_COUNT+1];
702 const char *fragstrings_list[SHADERPERMUTATION_COUNT+1];
703 char permutationname[256];
707 vertstrings_list[0] = "#define VERTEX_SHADER\n";
708 fragstrings_list[0] = "#define FRAGMENT_SHADER\n";
709 vertstrings_count = 1;
710 fragstrings_count = 1;
711 permutationname[0] = 0;
712 if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
714 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTSOURCE\n";
715 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTSOURCE\n";
716 strlcat(permutationname, " lightsource", sizeof(permutationname));
718 if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE)
720 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n";
721 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n";
722 strlcat(permutationname, " lightdirectionmap_modelspace", sizeof(permutationname));
724 if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)
726 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n";
727 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n";
728 strlcat(permutationname, " lightdirectionmap_tangentspace", sizeof(permutationname));
730 if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
732 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
733 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
734 strlcat(permutationname, " lightdirection", sizeof(permutationname));
736 if (permutation & SHADERPERMUTATION_GLOW)
738 vertstrings_list[vertstrings_count++] = "#define USEGLOW\n";
739 fragstrings_list[fragstrings_count++] = "#define USEGLOW\n";
740 strlcat(permutationname, " glow", sizeof(permutationname));
742 if (permutation & SHADERPERMUTATION_COLORMAPPING)
744 vertstrings_list[vertstrings_count++] = "#define USECOLORMAPPING\n";
745 fragstrings_list[fragstrings_count++] = "#define USECOLORMAPPING\n";
746 strlcat(permutationname, " colormapping", sizeof(permutationname));
748 if (permutation & SHADERPERMUTATION_SPECULAR)
750 vertstrings_list[vertstrings_count++] = "#define USESPECULAR\n";
751 fragstrings_list[fragstrings_count++] = "#define USESPECULAR\n";
752 strlcat(permutationname, " specular", sizeof(permutationname));
754 if (permutation & SHADERPERMUTATION_FOG)
756 vertstrings_list[vertstrings_count++] = "#define USEFOG\n";
757 fragstrings_list[fragstrings_count++] = "#define USEFOG\n";
758 strlcat(permutationname, " fog", sizeof(permutationname));
760 if (permutation & SHADERPERMUTATION_CUBEFILTER)
762 vertstrings_list[vertstrings_count++] = "#define USECUBEFILTER\n";
763 fragstrings_list[fragstrings_count++] = "#define USECUBEFILTER\n";
764 strlcat(permutationname, " cubefilter", sizeof(permutationname));
766 if (permutation & SHADERPERMUTATION_OFFSETMAPPING)
768 vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING\n";
769 fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING\n";
770 strlcat(permutationname, " offsetmapping", sizeof(permutationname));
772 if (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING)
774 vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n";
775 fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n";
776 strlcat(permutationname, " OFFSETMAPPING_RELIEFMAPPING", sizeof(permutationname));
778 shaderstring = (char *)FS_LoadFile("glsl/default.glsl", r_main_mempool, false, NULL);
781 Con_DPrintf("GLSL shader text loaded from disk\n");
782 vertstrings_list[vertstrings_count++] = shaderstring;
783 fragstrings_list[fragstrings_count++] = shaderstring;
787 vertstrings_list[vertstrings_count++] = builtinshaderstring;
788 fragstrings_list[fragstrings_count++] = builtinshaderstring;
790 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list);
794 qglUseProgramObjectARB(p->program);CHECKGLERROR
795 p->loc_Texture_Normal = qglGetUniformLocationARB(p->program, "Texture_Normal");
796 p->loc_Texture_Color = qglGetUniformLocationARB(p->program, "Texture_Color");
797 p->loc_Texture_Gloss = qglGetUniformLocationARB(p->program, "Texture_Gloss");
798 p->loc_Texture_Cube = qglGetUniformLocationARB(p->program, "Texture_Cube");
799 p->loc_Texture_FogMask = qglGetUniformLocationARB(p->program, "Texture_FogMask");
800 p->loc_Texture_Pants = qglGetUniformLocationARB(p->program, "Texture_Pants");
801 p->loc_Texture_Shirt = qglGetUniformLocationARB(p->program, "Texture_Shirt");
802 p->loc_Texture_Lightmap = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
803 p->loc_Texture_Deluxemap = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
804 p->loc_Texture_Glow = qglGetUniformLocationARB(p->program, "Texture_Glow");
805 p->loc_FogColor = qglGetUniformLocationARB(p->program, "FogColor");
806 p->loc_LightPosition = qglGetUniformLocationARB(p->program, "LightPosition");
807 p->loc_EyePosition = qglGetUniformLocationARB(p->program, "EyePosition");
808 p->loc_LightColor = qglGetUniformLocationARB(p->program, "LightColor");
809 p->loc_Color_Pants = qglGetUniformLocationARB(p->program, "Color_Pants");
810 p->loc_Color_Shirt = qglGetUniformLocationARB(p->program, "Color_Shirt");
811 p->loc_FogRangeRecip = qglGetUniformLocationARB(p->program, "FogRangeRecip");
812 p->loc_AmbientScale = qglGetUniformLocationARB(p->program, "AmbientScale");
813 p->loc_DiffuseScale = qglGetUniformLocationARB(p->program, "DiffuseScale");
814 p->loc_SpecularPower = qglGetUniformLocationARB(p->program, "SpecularPower");
815 p->loc_SpecularScale = qglGetUniformLocationARB(p->program, "SpecularScale");
816 p->loc_OffsetMapping_Scale = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
817 p->loc_AmbientColor = qglGetUniformLocationARB(p->program, "AmbientColor");
818 p->loc_DiffuseColor = qglGetUniformLocationARB(p->program, "DiffuseColor");
819 p->loc_SpecularColor = qglGetUniformLocationARB(p->program, "SpecularColor");
820 p->loc_LightDir = qglGetUniformLocationARB(p->program, "LightDir");
821 if (p->loc_Texture_Normal >= 0) qglUniform1iARB(p->loc_Texture_Normal, 0);
822 if (p->loc_Texture_Color >= 0) qglUniform1iARB(p->loc_Texture_Color, 1);
823 if (p->loc_Texture_Gloss >= 0) qglUniform1iARB(p->loc_Texture_Gloss, 2);
824 if (p->loc_Texture_Cube >= 0) qglUniform1iARB(p->loc_Texture_Cube, 3);
825 if (p->loc_Texture_FogMask >= 0) qglUniform1iARB(p->loc_Texture_FogMask, 4);
826 if (p->loc_Texture_Pants >= 0) qglUniform1iARB(p->loc_Texture_Pants, 5);
827 if (p->loc_Texture_Shirt >= 0) qglUniform1iARB(p->loc_Texture_Shirt, 6);
828 if (p->loc_Texture_Lightmap >= 0) qglUniform1iARB(p->loc_Texture_Lightmap, 7);
829 if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap, 8);
830 if (p->loc_Texture_Glow >= 0) qglUniform1iARB(p->loc_Texture_Glow, 9);
832 qglUseProgramObjectARB(0);CHECKGLERROR
835 Con_Printf("permutation%s failed for shader %s, some features may not work properly!\n", permutationname, "glsl/default.glsl");
837 Mem_Free(shaderstring);
840 void R_GLSL_Restart_f(void)
843 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
844 if (r_glsl_permutations[i].program)
845 GL_Backend_FreeProgram(r_glsl_permutations[i].program);
846 memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
849 int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting)
851 // select a permutation of the lighting shader appropriate to this
852 // combination of texture, entity, light source, and fogging, only use the
853 // minimum features necessary to avoid wasting rendering time in the
854 // fragment shader on features that are not being used
856 float specularscale = rsurface_texture->specularscale;
857 r_glsl_permutation = NULL;
858 if (r_shadow_rtlight)
860 permutation |= SHADERPERMUTATION_MODE_LIGHTSOURCE;
861 specularscale *= r_shadow_rtlight->specularscale;
862 if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
863 permutation |= SHADERPERMUTATION_CUBEFILTER;
867 if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
870 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
873 if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && rsurface_lightmaptexture)
875 if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
876 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
878 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
880 else if (r_glsl_deluxemapping.integer >= 2) // fake mode
881 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
884 if (rsurface_texture->skin.glow)
885 permutation |= SHADERPERMUTATION_GLOW;
887 if (specularscale > 0)
888 permutation |= SHADERPERMUTATION_SPECULAR;
890 permutation |= SHADERPERMUTATION_FOG;
891 if (rsurface_texture->colormapping)
892 permutation |= SHADERPERMUTATION_COLORMAPPING;
893 if (r_glsl_offsetmapping.integer)
895 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
896 if (r_glsl_offsetmapping_reliefmapping.integer)
897 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
899 if (!r_glsl_permutations[permutation].program)
901 if (!r_glsl_permutations[permutation].compiled)
902 R_GLSL_CompilePermutation(permutation);
903 if (!r_glsl_permutations[permutation].program)
905 // remove features until we find a valid permutation
907 for (i = SHADERPERMUTATION_COUNT-1;;i>>=1)
909 // reduce i more quickly whenever it would not remove any bits
913 if (!r_glsl_permutations[permutation].compiled)
914 R_GLSL_CompilePermutation(permutation);
915 if (r_glsl_permutations[permutation].program)
918 return 0; // utterly failed
922 r_glsl_permutation = r_glsl_permutations + permutation;
924 qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
925 R_Mesh_TexMatrix(0, &rsurface_texture->currenttexmatrix);
926 if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
928 if (r_glsl_permutation->loc_Texture_Cube >= 0 && r_shadow_rtlight) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap));
929 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]);
930 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
931 if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_shadow_rtlight->ambientscale);
932 if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_shadow_rtlight->diffusescale);
933 if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale);
935 else if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
937 if (r_glsl_permutation->loc_AmbientColor >= 0)
938 qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, rsurface_entity->modellight_ambient[0], rsurface_entity->modellight_ambient[1], rsurface_entity->modellight_ambient[2]);
939 if (r_glsl_permutation->loc_DiffuseColor >= 0)
940 qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, rsurface_entity->modellight_diffuse[0], rsurface_entity->modellight_diffuse[1], rsurface_entity->modellight_diffuse[2]);
941 if (r_glsl_permutation->loc_SpecularColor >= 0)
942 qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, rsurface_entity->modellight_diffuse[0] * rsurface_texture->specularscale, rsurface_entity->modellight_diffuse[1] * rsurface_texture->specularscale, rsurface_entity->modellight_diffuse[2] * rsurface_texture->specularscale);
943 if (r_glsl_permutation->loc_LightDir >= 0)
944 qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface_entity->modellight_lightdir[0], rsurface_entity->modellight_lightdir[1], rsurface_entity->modellight_lightdir[2]);
948 if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 2.0f / 128.0f);
949 if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_lightmapintensity * 2.0f);
950 if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_lightmapintensity * specularscale * 2.0f);
952 if (r_glsl_permutation->loc_Texture_Normal >= 0) R_Mesh_TexBind(0, R_GetTexture(rsurface_texture->skin.nmap));
953 if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(1, R_GetTexture(rsurface_texture->basetexture));
954 if (r_glsl_permutation->loc_Texture_Gloss >= 0) R_Mesh_TexBind(2, R_GetTexture(rsurface_texture->glosstexture));
955 //if (r_glsl_permutation->loc_Texture_Cube >= 0 && permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap));
956 if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
957 if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(5, R_GetTexture(rsurface_texture->skin.pants));
958 if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(6, R_GetTexture(rsurface_texture->skin.shirt));
959 //if (r_glsl_permutation->loc_Texture_Lightmap >= 0) R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
960 //if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
961 if (r_glsl_permutation->loc_Texture_Glow >= 0) R_Mesh_TexBind(9, R_GetTexture(rsurface_texture->skin.glow));
962 if (r_glsl_permutation->loc_FogColor >= 0)
964 // additive passes are only darkened by fog, not tinted
965 if (r_shadow_rtlight || (rsurface_texture->currentmaterialflags & MATERIALFLAG_ADD))
966 qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
968 qglUniform3fARB(r_glsl_permutation->loc_FogColor, fogcolor[0], fogcolor[1], fogcolor[2]);
970 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface_modelorg[0], rsurface_modelorg[1], rsurface_modelorg[2]);
971 if (r_glsl_permutation->loc_Color_Pants >= 0)
973 if (rsurface_texture->skin.pants)
974 qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, rsurface_entity->colormap_pantscolor[0], rsurface_entity->colormap_pantscolor[1], rsurface_entity->colormap_pantscolor[2]);
976 qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
978 if (r_glsl_permutation->loc_Color_Shirt >= 0)
980 if (rsurface_texture->skin.shirt)
981 qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, rsurface_entity->colormap_shirtcolor[0], rsurface_entity->colormap_shirtcolor[1], rsurface_entity->colormap_shirtcolor[2]);
983 qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
985 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, fograngerecip);
986 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface_texture->specularpower);
987 if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
992 void R_SwitchSurfaceShader(int permutation)
994 if (r_glsl_permutation != r_glsl_permutations + permutation)
996 r_glsl_permutation = r_glsl_permutations + permutation;
998 qglUseProgramObjectARB(r_glsl_permutation->program);
1003 void gl_main_start(void)
1005 r_main_texturepool = R_AllocTexturePool();
1006 r_bloom_texture_screen = NULL;
1007 r_bloom_texture_bloom = NULL;
1008 R_BuildBlankTextures();
1010 if (gl_texturecubemap)
1013 R_BuildNormalizationCube();
1015 R_BuildFogTexture();
1016 memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
1019 void gl_main_shutdown(void)
1021 R_FreeTexturePool(&r_main_texturepool);
1022 r_bloom_texture_screen = NULL;
1023 r_bloom_texture_bloom = NULL;
1024 r_texture_blanknormalmap = NULL;
1025 r_texture_white = NULL;
1026 r_texture_black = NULL;
1027 r_texture_whitecube = NULL;
1028 r_texture_normalizationcube = NULL;
1032 extern void CL_ParseEntityLump(char *entitystring);
1033 void gl_main_newmap(void)
1035 // FIXME: move this code to client
1037 char *entities, entname[MAX_QPATH];
1041 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
1042 l = (int)strlen(entname) - 4;
1043 if (l >= 0 && !strcmp(entname + l, ".bsp"))
1045 strcpy(entname + l, ".ent");
1046 if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
1048 CL_ParseEntityLump(entities);
1053 if (cl.worldmodel->brush.entities)
1054 CL_ParseEntityLump(cl.worldmodel->brush.entities);
1058 void GL_Main_Init(void)
1060 r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
1062 Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed\n");
1063 FOG_registercvars(); // FIXME: move this fog stuff to client?
1064 Cvar_RegisterVariable(&r_nearclip);
1065 Cvar_RegisterVariable(&r_showsurfaces);
1066 Cvar_RegisterVariable(&r_showtris);
1067 Cvar_RegisterVariable(&r_shownormals);
1068 Cvar_RegisterVariable(&r_showlighting);
1069 Cvar_RegisterVariable(&r_showshadowvolumes);
1070 Cvar_RegisterVariable(&r_showcollisionbrushes);
1071 Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor);
1072 Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset);
1073 Cvar_RegisterVariable(&r_showdisabledepthtest);
1074 Cvar_RegisterVariable(&r_drawentities);
1075 Cvar_RegisterVariable(&r_drawviewmodel);
1076 Cvar_RegisterVariable(&r_speeds);
1077 Cvar_RegisterVariable(&r_fullbrights);
1078 Cvar_RegisterVariable(&r_wateralpha);
1079 Cvar_RegisterVariable(&r_dynamic);
1080 Cvar_RegisterVariable(&r_fullbright);
1081 Cvar_RegisterVariable(&r_q1bsp_skymasking);
1082 Cvar_RegisterVariable(&r_textureunits);
1083 Cvar_RegisterVariable(&r_glsl);
1084 Cvar_RegisterVariable(&r_glsl_offsetmapping);
1085 Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
1086 Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
1087 Cvar_RegisterVariable(&r_glsl_deluxemapping);
1088 Cvar_RegisterVariable(&r_lerpsprites);
1089 Cvar_RegisterVariable(&r_lerpmodels);
1090 Cvar_RegisterVariable(&r_waterscroll);
1091 Cvar_RegisterVariable(&r_bloom);
1092 Cvar_RegisterVariable(&r_bloom_intensity);
1093 Cvar_RegisterVariable(&r_bloom_blur);
1094 Cvar_RegisterVariable(&r_bloom_resolution);
1095 Cvar_RegisterVariable(&r_bloom_power);
1096 Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
1097 Cvar_RegisterVariable(&developer_texturelogging);
1098 Cvar_RegisterVariable(&gl_lightmaps);
1099 Cvar_RegisterVariable(&r_test);
1100 Cvar_RegisterVariable(&r_batchmode);
1101 if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
1102 Cvar_SetValue("r_fullbrights", 0);
1103 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
1106 static vec3_t r_farclip_origin;
1107 static vec3_t r_farclip_direction;
1108 static vec_t r_farclip_directiondist;
1109 static vec_t r_farclip_meshfarclip;
1110 static int r_farclip_directionbit0;
1111 static int r_farclip_directionbit1;
1112 static int r_farclip_directionbit2;
1114 // enlarge farclip to accomodate box
1115 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
1118 d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
1119 + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
1120 + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
1121 if (r_farclip_meshfarclip < d)
1122 r_farclip_meshfarclip = d;
1125 // return farclip value
1126 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
1130 VectorCopy(origin, r_farclip_origin);
1131 VectorCopy(direction, r_farclip_direction);
1132 r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
1133 r_farclip_directionbit0 = r_farclip_direction[0] < 0;
1134 r_farclip_directionbit1 = r_farclip_direction[1] < 0;
1135 r_farclip_directionbit2 = r_farclip_direction[2] < 0;
1136 r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
1138 if (r_refdef.worldmodel)
1139 R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
1140 for (i = 0;i < r_refdef.numentities;i++)
1141 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
1143 return r_farclip_meshfarclip - r_farclip_directiondist;
1146 extern void R_Textures_Init(void);
1147 extern void GL_Draw_Init(void);
1148 extern void GL_Main_Init(void);
1149 extern void R_Shadow_Init(void);
1150 extern void R_Sky_Init(void);
1151 extern void GL_Surf_Init(void);
1152 extern void R_Crosshairs_Init(void);
1153 extern void R_Light_Init(void);
1154 extern void R_Particles_Init(void);
1155 extern void R_Explosion_Init(void);
1156 extern void gl_backend_init(void);
1157 extern void Sbar_Init(void);
1158 extern void R_LightningBeams_Init(void);
1159 extern void Mod_RenderInit(void);
1161 void Render_Init(void)
1171 R_Crosshairs_Init();
1176 R_LightningBeams_Init();
1185 extern char *ENGINE_EXTENSIONS;
1188 VID_CheckExtensions();
1190 // LordHavoc: report supported extensions
1191 Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions );
1193 // clear to black (loading plaque will be seen over this)
1195 qglClearColor(0,0,0,1);CHECKGLERROR
1196 qglClear(GL_COLOR_BUFFER_BIT);CHECKGLERROR
1199 int R_CullBox(const vec3_t mins, const vec3_t maxs)
1203 for (i = 0;i < 4;i++)
1210 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1214 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1218 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1222 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1226 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1230 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1234 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1238 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1246 //==================================================================================
1248 static void R_UpdateEntityLighting(entity_render_t *ent)
1250 vec3_t tempdiffusenormal;
1251 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));
1252 VectorClear(ent->modellight_diffuse);
1253 VectorClear(ent->modellight_lightdir);
1254 if ((ent->flags & RENDER_LIGHT) && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
1255 r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, ent->origin, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
1257 VectorSet(ent->modellight_ambient, 1, 1, 1);
1258 Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
1259 VectorNormalize(ent->modellight_lightdir);
1260 ent->modellight_ambient[0] *= ent->colormod[0] * r_lightmapintensity;
1261 ent->modellight_ambient[1] *= ent->colormod[1] * r_lightmapintensity;
1262 ent->modellight_ambient[2] *= ent->colormod[2] * r_lightmapintensity;
1263 ent->modellight_diffuse[0] *= ent->colormod[0] * r_lightmapintensity;
1264 ent->modellight_diffuse[1] *= ent->colormod[1] * r_lightmapintensity;
1265 ent->modellight_diffuse[2] *= ent->colormod[2] * r_lightmapintensity;
1268 static void R_MarkEntities (void)
1271 entity_render_t *ent;
1273 if (!r_drawentities.integer)
1276 r_refdef.worldentity->visframe = r_framecount;
1277 renderimask = envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL);
1278 if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
1280 // worldmodel can check visibility
1281 for (i = 0;i < r_refdef.numentities;i++)
1283 ent = r_refdef.entities[i];
1284 // some of the renderer still relies on origin...
1285 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1286 // some of the renderer still relies on scale...
1287 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1288 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)))
1290 ent->visframe = r_framecount;
1291 R_UpdateEntityLighting(ent);
1297 // no worldmodel or it can't check visibility
1298 for (i = 0;i < r_refdef.numentities;i++)
1300 ent = r_refdef.entities[i];
1301 // some of the renderer still relies on origin...
1302 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1303 // some of the renderer still relies on scale...
1304 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1305 if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST))
1307 ent->visframe = r_framecount;
1308 R_UpdateEntityLighting(ent);
1314 // only used if skyrendermasked, and normally returns false
1315 int R_DrawBrushModelsSky (void)
1318 entity_render_t *ent;
1320 if (!r_drawentities.integer)
1324 for (i = 0;i < r_refdef.numentities;i++)
1326 ent = r_refdef.entities[i];
1327 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
1329 ent->model->DrawSky(ent);
1336 void R_DrawNoModel(entity_render_t *ent);
1337 void R_DrawModels(void)
1340 entity_render_t *ent;
1342 if (!r_drawentities.integer)
1345 for (i = 0;i < r_refdef.numentities;i++)
1347 ent = r_refdef.entities[i];
1348 if (ent->visframe == r_framecount)
1350 renderstats.entities++;
1351 if (ent->model && ent->model->Draw != NULL)
1352 ent->model->Draw(ent);
1359 static void R_SetFrustum(void)
1361 // break apart the view matrix into vectors for various purposes
1362 Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
1363 VectorNegate(r_viewleft, r_viewright);
1366 frustum[0].normal[0] = 0 - 1.0 / r_refdef.frustum_x;
1367 frustum[0].normal[1] = 0 - 0;
1368 frustum[0].normal[2] = -1 - 0;
1369 frustum[1].normal[0] = 0 + 1.0 / r_refdef.frustum_x;
1370 frustum[1].normal[1] = 0 + 0;
1371 frustum[1].normal[2] = -1 + 0;
1372 frustum[2].normal[0] = 0 - 0;
1373 frustum[2].normal[1] = 0 - 1.0 / r_refdef.frustum_y;
1374 frustum[2].normal[2] = -1 - 0;
1375 frustum[3].normal[0] = 0 + 0;
1376 frustum[3].normal[1] = 0 + 1.0 / r_refdef.frustum_y;
1377 frustum[3].normal[2] = -1 + 0;
1381 zNear = r_nearclip.value;
1382 nudge = 1.0 - 1.0 / (1<<23);
1383 frustum[4].normal[0] = 0 - 0;
1384 frustum[4].normal[1] = 0 - 0;
1385 frustum[4].normal[2] = -1 - -nudge;
1386 frustum[4].dist = 0 - -2 * zNear * nudge;
1387 frustum[5].normal[0] = 0 + 0;
1388 frustum[5].normal[1] = 0 + 0;
1389 frustum[5].normal[2] = -1 + -nudge;
1390 frustum[5].dist = 0 + -2 * zNear * nudge;
1396 frustum[0].normal[0] = m[3] - m[0];
1397 frustum[0].normal[1] = m[7] - m[4];
1398 frustum[0].normal[2] = m[11] - m[8];
1399 frustum[0].dist = m[15] - m[12];
1401 frustum[1].normal[0] = m[3] + m[0];
1402 frustum[1].normal[1] = m[7] + m[4];
1403 frustum[1].normal[2] = m[11] + m[8];
1404 frustum[1].dist = m[15] + m[12];
1406 frustum[2].normal[0] = m[3] - m[1];
1407 frustum[2].normal[1] = m[7] - m[5];
1408 frustum[2].normal[2] = m[11] - m[9];
1409 frustum[2].dist = m[15] - m[13];
1411 frustum[3].normal[0] = m[3] + m[1];
1412 frustum[3].normal[1] = m[7] + m[5];
1413 frustum[3].normal[2] = m[11] + m[9];
1414 frustum[3].dist = m[15] + m[13];
1416 frustum[4].normal[0] = m[3] - m[2];
1417 frustum[4].normal[1] = m[7] - m[6];
1418 frustum[4].normal[2] = m[11] - m[10];
1419 frustum[4].dist = m[15] - m[14];
1421 frustum[5].normal[0] = m[3] + m[2];
1422 frustum[5].normal[1] = m[7] + m[6];
1423 frustum[5].normal[2] = m[11] + m[10];
1424 frustum[5].dist = m[15] + m[14];
1429 VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_x, r_viewleft, frustum[0].normal);
1430 VectorMAM(1, r_viewforward, 1.0 / r_refdef.frustum_x, r_viewleft, frustum[1].normal);
1431 VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_y, r_viewup, frustum[2].normal);
1432 VectorMAM(1, r_viewforward, 1.0 / r_refdef.frustum_y, r_viewup, frustum[3].normal);
1433 VectorCopy(r_viewforward, frustum[4].normal);
1434 VectorNormalize(frustum[0].normal);
1435 VectorNormalize(frustum[1].normal);
1436 VectorNormalize(frustum[2].normal);
1437 VectorNormalize(frustum[3].normal);
1438 frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1439 frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1440 frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1441 frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1442 frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1443 PlaneClassify(&frustum[0]);
1444 PlaneClassify(&frustum[1]);
1445 PlaneClassify(&frustum[2]);
1446 PlaneClassify(&frustum[3]);
1447 PlaneClassify(&frustum[4]);
1449 // LordHavoc: note to all quake engine coders, Quake had a special case
1450 // for 90 degrees which assumed a square view (wrong), so I removed it,
1451 // Quake2 has it disabled as well.
1453 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
1454 //RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_refdef.fov_x / 2));
1455 //frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1456 //PlaneClassify(&frustum[0]);
1458 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
1459 //RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_refdef.fov_x / 2));
1460 //frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1461 //PlaneClassify(&frustum[1]);
1463 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
1464 //RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_refdef.fov_y / 2));
1465 //frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1466 //PlaneClassify(&frustum[2]);
1468 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
1469 //RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_refdef.fov_y / 2));
1470 //frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1471 //PlaneClassify(&frustum[3]);
1474 //VectorCopy(r_viewforward, frustum[4].normal);
1475 //frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1476 //PlaneClassify(&frustum[4]);
1479 static void R_BlendView(void)
1481 int screenwidth, screenheight;
1485 float texcoord2f[3][8];
1487 // set the (poorly named) screenwidth and screenheight variables to
1488 // a power of 2 at least as large as the screen, these will define the
1489 // size of the texture to allocate
1490 for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2);
1491 for (screenheight = 1;screenheight < vid.height;screenheight *= 2);
1493 doblend = r_refdef.viewblend[3] >= 0.01f;
1494 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;
1496 if (!dobloom && !doblend)
1499 GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
1501 GL_DepthTest(false);
1502 R_Mesh_Matrix(&identitymatrix);
1503 // vertex coordinates for a quad that covers the screen exactly
1504 vertex3f[0] = 0;vertex3f[1] = 0;vertex3f[2] = 0;
1505 vertex3f[3] = 1;vertex3f[4] = 0;vertex3f[5] = 0;
1506 vertex3f[6] = 1;vertex3f[7] = 1;vertex3f[8] = 0;
1507 vertex3f[9] = 0;vertex3f[10] = 1;vertex3f[11] = 0;
1508 R_Mesh_VertexPointer(vertex3f);
1509 R_Mesh_ColorPointer(NULL);
1510 R_Mesh_ResetTextureState();
1513 int bloomwidth, bloomheight, x, range;
1514 float xoffset, yoffset, r;
1515 renderstats.bloom++;
1516 // allocate textures as needed
1517 if (!r_bloom_texture_screen)
1518 r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1519 if (!r_bloom_texture_bloom)
1520 r_bloom_texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1521 // set bloomwidth and bloomheight to the bloom resolution that will be
1522 // used (often less than the screen resolution for faster rendering)
1523 bloomwidth = min(r_view_width, r_bloom_resolution.integer);
1524 bloomheight = min(r_view_height, bloomwidth * r_view_height / r_view_width);
1525 // set up a texcoord array for the full resolution screen image
1526 // (we have to keep this around to copy back during final render)
1527 texcoord2f[0][0] = 0;
1528 texcoord2f[0][1] = (float)r_view_height / (float)screenheight;
1529 texcoord2f[0][2] = (float)r_view_width / (float)screenwidth;
1530 texcoord2f[0][3] = (float)r_view_height / (float)screenheight;
1531 texcoord2f[0][4] = (float)r_view_width / (float)screenwidth;
1532 texcoord2f[0][5] = 0;
1533 texcoord2f[0][6] = 0;
1534 texcoord2f[0][7] = 0;
1535 // set up a texcoord array for the reduced resolution bloom image
1536 // (which will be additive blended over the screen image)
1537 texcoord2f[1][0] = 0;
1538 texcoord2f[1][1] = (float)bloomheight / (float)screenheight;
1539 texcoord2f[1][2] = (float)bloomwidth / (float)screenwidth;
1540 texcoord2f[1][3] = (float)bloomheight / (float)screenheight;
1541 texcoord2f[1][4] = (float)bloomwidth / (float)screenwidth;
1542 texcoord2f[1][5] = 0;
1543 texcoord2f[1][6] = 0;
1544 texcoord2f[1][7] = 0;
1545 R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]);
1546 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen));
1547 // copy view into the full resolution screen image texture
1548 GL_ActiveTexture(0);
1550 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);CHECKGLERROR
1551 renderstats.bloom_copypixels += r_view_width * r_view_height;
1552 // now scale it down to the bloom size and raise to a power of itself
1553 // to darken it (this leaves the really bright stuff bright, and
1554 // everything else becomes very dark)
1555 // TODO: optimize with multitexture or GLSL
1557 qglViewport(r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
1558 GL_BlendFunc(GL_ONE, GL_ZERO);
1559 GL_Color(1, 1, 1, 1);
1560 R_Mesh_Draw(0, 4, 2, polygonelements);
1561 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1562 // render multiple times with a multiply blendfunc to raise to a power
1563 GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
1564 for (x = 1;x < r_bloom_power.integer;x++)
1566 R_Mesh_Draw(0, 4, 2, polygonelements);
1567 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1569 // we now have a darkened bloom image in the framebuffer, copy it into
1570 // the bloom image texture for more processing
1571 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom));
1572 R_Mesh_TexCoordPointer(0, 2, texcoord2f[2]);
1573 GL_ActiveTexture(0);
1575 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
1576 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1577 // blend on at multiple vertical offsets to achieve a vertical blur
1578 // TODO: do offset blends using GLSL
1579 range = r_bloom_blur.integer * bloomwidth / 320;
1580 GL_BlendFunc(GL_ONE, GL_ZERO);
1581 for (x = -range;x <= range;x++)
1583 xoffset = 0 / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1584 yoffset = x / (float)bloomheight * (float)bloomheight / (float)screenheight;
1585 // compute a texcoord array with the specified x and y offset
1586 texcoord2f[2][0] = xoffset+0;
1587 texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1588 texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1589 texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1590 texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1591 texcoord2f[2][5] = yoffset+0;
1592 texcoord2f[2][6] = xoffset+0;
1593 texcoord2f[2][7] = yoffset+0;
1594 // this r value looks like a 'dot' particle, fading sharply to
1595 // black at the edges
1596 // (probably not realistic but looks good enough)
1597 r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1600 GL_Color(r, r, r, 1);
1601 R_Mesh_Draw(0, 4, 2, polygonelements);
1602 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1603 GL_BlendFunc(GL_ONE, GL_ONE);
1605 // copy the vertically blurred bloom view to a texture
1606 GL_ActiveTexture(0);
1608 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
1609 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1610 // blend the vertically blurred image at multiple offsets horizontally
1611 // to finish the blur effect
1612 // TODO: do offset blends using GLSL
1613 range = r_bloom_blur.integer * bloomwidth / 320;
1614 GL_BlendFunc(GL_ONE, GL_ZERO);
1615 for (x = -range;x <= range;x++)
1617 xoffset = x / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1618 yoffset = 0 / (float)bloomheight * (float)bloomheight / (float)screenheight;
1619 // compute a texcoord array with the specified x and y offset
1620 texcoord2f[2][0] = xoffset+0;
1621 texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1622 texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1623 texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1624 texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1625 texcoord2f[2][5] = yoffset+0;
1626 texcoord2f[2][6] = xoffset+0;
1627 texcoord2f[2][7] = yoffset+0;
1628 // this r value looks like a 'dot' particle, fading sharply to
1629 // black at the edges
1630 // (probably not realistic but looks good enough)
1631 r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1634 GL_Color(r, r, r, 1);
1635 R_Mesh_Draw(0, 4, 2, polygonelements);
1636 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1637 GL_BlendFunc(GL_ONE, GL_ONE);
1639 // copy the blurred bloom view to a texture
1640 GL_ActiveTexture(0);
1642 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);CHECKGLERROR
1643 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1644 // go back to full view area
1645 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);CHECKGLERROR
1646 // put the original screen image back in place and blend the bloom
1649 GL_BlendFunc(GL_ONE, GL_ZERO);
1650 // do both in one pass if possible
1651 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen));
1652 R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]);
1653 if (r_textureunits.integer >= 2 && gl_combine.integer)
1655 R_Mesh_TexCombine(1, GL_ADD, GL_ADD, 1, 1);
1656 R_Mesh_TexBind(1, R_GetTexture(r_bloom_texture_bloom));
1657 R_Mesh_TexCoordPointer(1, 2, texcoord2f[1]);
1661 R_Mesh_Draw(0, 4, 2, polygonelements);
1662 renderstats.bloom_drawpixels += r_view_width * r_view_height;
1663 // now blend on the bloom texture
1664 GL_BlendFunc(GL_ONE, GL_ONE);
1665 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom));
1666 R_Mesh_TexCoordPointer(0, 2, texcoord2f[1]);
1668 R_Mesh_Draw(0, 4, 2, polygonelements);
1669 renderstats.bloom_drawpixels += r_view_width * r_view_height;
1673 // apply a color tint to the whole view
1674 R_Mesh_ResetTextureState();
1675 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1676 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
1677 R_Mesh_Draw(0, 4, 2, polygonelements);
1681 void R_RenderScene(void);
1683 matrix4x4_t r_waterscrollmatrix;
1690 void R_RenderView(void)
1692 if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1693 return; //Host_Error ("R_RenderView: NULL worldmodel");
1695 r_view_width = bound(0, r_refdef.width, vid.width);
1696 r_view_height = bound(0, r_refdef.height, vid.height);
1698 r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1699 r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1701 r_view_matrix = r_refdef.viewentitymatrix;
1702 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1703 r_rtworld = r_shadow_realtime_world.integer;
1704 r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1705 r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1706 r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1707 r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1708 r_polygonfactor = 0;
1709 r_polygonoffset = 0;
1710 r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1711 r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1712 if (r_showsurfaces.integer)
1715 r_rtworldshadows = false;
1717 r_rtdlightshadows = false;
1718 r_lightmapintensity = 0;
1721 // GL is weird because it's bottom to top, r_view_y is top to bottom
1723 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);CHECKGLERROR
1724 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1725 GL_ScissorTest(true);
1730 if (r_timereport_active)
1731 R_TimeReport("setup");
1734 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1735 qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
1736 qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
1741 qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
1742 qglDisable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
1745 if (r_timereport_active)
1746 R_TimeReport("blendview");
1748 GL_Scissor(0, 0, vid.width, vid.height);
1749 GL_ScissorTest(false);
1754 void CSQC_R_ClearScreen (void)
1756 if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1757 return; //Host_Error ("R_RenderView: NULL worldmodel");
1759 r_view_width = bound(0, r_refdef.width, vid.width);
1760 r_view_height = bound(0, r_refdef.height, vid.height);
1762 r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1763 r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1765 r_view_matrix = r_refdef.viewentitymatrix;
1766 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1767 r_rtworld = r_shadow_realtime_world.integer;
1768 r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1769 r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1770 r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1771 r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1772 r_polygonfactor = 0;
1773 r_polygonoffset = 0;
1774 r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1775 r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1776 if (r_showsurfaces.integer)
1779 r_rtworldshadows = false;
1781 r_rtdlightshadows = false;
1782 r_lightmapintensity = 0;
1785 // GL is weird because it's bottom to top, r_view_y is top to bottom
1787 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);CHECKGLERROR
1788 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1789 GL_ScissorTest(true);
1794 if (r_timereport_active)
1795 R_TimeReport("setup");
1800 void CSQC_R_RenderScene (void)
1803 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
1804 qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
1805 qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
1810 qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
1811 qglDisable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
1814 if (r_timereport_active)
1815 R_TimeReport("blendview");
1817 GL_Scissor(0, 0, vid.width, vid.height);
1818 GL_ScissorTest(false);
1822 extern void R_DrawLightningBeams (void);
1823 extern void VM_AddPolygonsToMeshQueue (void);
1824 void R_RenderScene(void)
1828 // don't let sound skip if going slow
1829 if (r_refdef.extraupdate)
1835 if (gl_support_fragment_shader)
1837 qglUseProgramObjectARB(0);CHECKGLERROR
1840 R_MeshQueue_BeginScene();
1844 r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
1845 nearclip = bound (0.001f, r_nearclip.value, r_farclip - 1.0f);
1847 if (r_rtworldshadows || r_rtdlightshadows)
1848 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_refdef.frustum_x, r_refdef.frustum_y, nearclip);
1850 GL_SetupView_Mode_Perspective(r_refdef.frustum_x, r_refdef.frustum_y, nearclip, r_farclip);
1852 GL_SetupView_Orientation_FromEntity(&r_view_matrix);
1854 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);
1858 R_WorldVisibility();
1859 if (r_timereport_active)
1860 R_TimeReport("worldvis");
1863 if (r_timereport_active)
1864 R_TimeReport("markentity");
1866 R_Shadow_UpdateWorldLightSelection();
1868 if (cl.csqc_vidvars.drawworld)
1870 // don't let sound skip if going slow
1871 if (r_refdef.extraupdate)
1874 if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
1876 r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
1877 if (r_timereport_active)
1878 R_TimeReport("worldsky");
1881 if (R_DrawBrushModelsSky() && r_timereport_active)
1882 R_TimeReport("bmodelsky");
1884 if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
1886 r_refdef.worldmodel->Draw(r_refdef.worldentity);
1887 if (r_timereport_active)
1888 R_TimeReport("world");
1892 // don't let sound skip if going slow
1893 if (r_refdef.extraupdate)
1897 if (r_timereport_active)
1898 R_TimeReport("models");
1900 // don't let sound skip if going slow
1901 if (r_refdef.extraupdate)
1904 R_ShadowVolumeLighting(false);
1905 if (r_timereport_active)
1906 R_TimeReport("rtlights");
1908 // don't let sound skip if going slow
1909 if (r_refdef.extraupdate)
1912 if (cl.csqc_vidvars.drawworld)
1914 R_DrawLightningBeams();
1915 if (r_timereport_active)
1916 R_TimeReport("lightning");
1919 if (r_timereport_active)
1920 R_TimeReport("particles");
1923 if (r_timereport_active)
1924 R_TimeReport("explosions");
1927 R_MeshQueue_RenderTransparent();
1928 if (r_timereport_active)
1929 R_TimeReport("drawtrans");
1931 if (cl.csqc_vidvars.drawworld)
1934 if (r_timereport_active)
1935 R_TimeReport("coronas");
1937 if(cl.csqc_vidvars.drawcrosshair)
1939 R_DrawWorldCrosshair();
1940 if (r_timereport_active)
1941 R_TimeReport("crosshair");
1944 VM_AddPolygonsToMeshQueue();
1946 R_MeshQueue_Render();
1948 R_MeshQueue_EndScene();
1950 // don't let sound skip if going slow
1951 if (r_refdef.extraupdate)
1955 if (gl_support_fragment_shader)
1957 qglUseProgramObjectARB(0);CHECKGLERROR
1962 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
1965 float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
1966 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1967 GL_DepthMask(false);
1969 R_Mesh_Matrix(&identitymatrix);
1971 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
1972 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
1973 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
1974 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
1975 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
1976 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
1977 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
1978 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
1979 R_FillColors(color, 8, cr, cg, cb, ca);
1982 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
1984 f2 = VERTEXFOGTABLE(VectorDistance(v, r_vieworigin));
1986 c[0] = c[0] * f1 + fogcolor[0] * f2;
1987 c[1] = c[1] * f1 + fogcolor[1] * f2;
1988 c[2] = c[2] * f1 + fogcolor[2] * f2;
1991 R_Mesh_VertexPointer(vertex3f);
1992 R_Mesh_ColorPointer(color);
1993 R_Mesh_ResetTextureState();
1998 int nomodelelements[24] =
2010 float nomodelvertex3f[6*3] =
2020 float nomodelcolor4f[6*4] =
2022 0.0f, 0.0f, 0.5f, 1.0f,
2023 0.0f, 0.0f, 0.5f, 1.0f,
2024 0.0f, 0.5f, 0.0f, 1.0f,
2025 0.0f, 0.5f, 0.0f, 1.0f,
2026 0.5f, 0.0f, 0.0f, 1.0f,
2027 0.5f, 0.0f, 0.0f, 1.0f
2030 void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
2035 // this is only called once per entity so numsurfaces is always 1, and
2036 // surfacelist is always {0}, so this code does not handle batches
2037 R_Mesh_Matrix(&ent->matrix);
2039 if (ent->flags & EF_ADDITIVE)
2041 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2042 GL_DepthMask(false);
2044 else if (ent->alpha < 1)
2046 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2047 GL_DepthMask(false);
2051 GL_BlendFunc(GL_ONE, GL_ZERO);
2054 GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
2055 R_Mesh_VertexPointer(nomodelvertex3f);
2058 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2059 R_Mesh_ColorPointer(color4f);
2060 f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_vieworigin));
2062 for (i = 0, c = color4f;i < 6;i++, c += 4)
2064 c[0] = (c[0] * f1 + fogcolor[0] * f2);
2065 c[1] = (c[1] * f1 + fogcolor[1] * f2);
2066 c[2] = (c[2] * f1 + fogcolor[2] * f2);
2070 else if (ent->alpha != 1)
2072 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2073 R_Mesh_ColorPointer(color4f);
2074 for (i = 0, c = color4f;i < 6;i++, c += 4)
2078 R_Mesh_ColorPointer(nomodelcolor4f);
2079 R_Mesh_ResetTextureState();
2080 R_Mesh_Draw(0, 6, 8, nomodelelements);
2083 void R_DrawNoModel(entity_render_t *ent)
2085 //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
2086 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight);
2088 // R_DrawNoModelCallback(ent, 0);
2091 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
2093 vec3_t right1, right2, diff, normal;
2095 VectorSubtract (org2, org1, normal);
2097 // calculate 'right' vector for start
2098 VectorSubtract (r_vieworigin, org1, diff);
2099 CrossProduct (normal, diff, right1);
2100 VectorNormalize (right1);
2102 // calculate 'right' vector for end
2103 VectorSubtract (r_vieworigin, org2, diff);
2104 CrossProduct (normal, diff, right2);
2105 VectorNormalize (right2);
2107 vert[ 0] = org1[0] + width * right1[0];
2108 vert[ 1] = org1[1] + width * right1[1];
2109 vert[ 2] = org1[2] + width * right1[2];
2110 vert[ 3] = org1[0] - width * right1[0];
2111 vert[ 4] = org1[1] - width * right1[1];
2112 vert[ 5] = org1[2] - width * right1[2];
2113 vert[ 6] = org2[0] - width * right2[0];
2114 vert[ 7] = org2[1] - width * right2[1];
2115 vert[ 8] = org2[2] - width * right2[2];
2116 vert[ 9] = org2[0] + width * right2[0];
2117 vert[10] = org2[1] + width * right2[1];
2118 vert[11] = org2[2] + width * right2[2];
2121 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
2123 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)
2125 float fog = 0.0f, ifog;
2129 fog = VERTEXFOGTABLE(VectorDistance(origin, r_vieworigin));
2132 R_Mesh_Matrix(&identitymatrix);
2133 GL_BlendFunc(blendfunc1, blendfunc2);
2134 GL_DepthMask(false);
2135 GL_DepthTest(!depthdisable);
2137 vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
2138 vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
2139 vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
2140 vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
2141 vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
2142 vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
2143 vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
2144 vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
2145 vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
2146 vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
2147 vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
2148 vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
2150 R_Mesh_VertexPointer(vertex3f);
2151 R_Mesh_ColorPointer(NULL);
2152 R_Mesh_ResetTextureState();
2153 R_Mesh_TexBind(0, R_GetTexture(texture));
2154 R_Mesh_TexCoordPointer(0, 2, spritetexcoord2f);
2155 GL_Color(cr * ifog, cg * ifog, cb * ifog, ca);
2156 R_Mesh_Draw(0, 4, 2, polygonelements);
2158 if (blendfunc2 == GL_ONE_MINUS_SRC_ALPHA)
2160 R_Mesh_TexBind(0, R_GetTexture(fogtexture));
2161 GL_BlendFunc(blendfunc1, GL_ONE);
2162 GL_Color(fogcolor[0] * fog, fogcolor[1] * fog, fogcolor[2] * fog, ca);
2163 R_Mesh_Draw(0, 4, 2, polygonelements);
2167 int R_Mesh_AddVertex3f(rmesh_t *mesh, const float *v)
2171 for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
2172 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
2174 if (i == mesh->numvertices)
2176 if (mesh->numvertices < mesh->maxvertices)
2178 VectorCopy(v, vertex3f);
2179 mesh->numvertices++;
2181 return mesh->numvertices;
2187 void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
2191 element[0] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2192 element[1] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2193 e = mesh->element3i + mesh->numtriangles * 3;
2194 for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
2196 element[2] = R_Mesh_AddVertex3f(mesh, vertex3f);
2197 if (mesh->numtriangles < mesh->maxtriangles)
2202 mesh->numtriangles++;
2204 element[1] = element[2];
2208 void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
2210 int planenum, planenum2;
2213 mplane_t *plane, *plane2;
2214 float temppoints[2][256*3];
2215 for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
2219 PolygonF_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->normal[3], 1024.0*1024.0*1024.0);
2220 for (planenum2 = 0, plane2 = planes;planenum2 < numplanes && tempnumpoints >= 3;planenum2++, plane2++)
2222 if (planenum2 == planenum)
2224 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);
2227 if (tempnumpoints < 3)
2229 // generate elements forming a triangle fan for this polygon
2230 R_Mesh_AddPolygon3f(mesh, tempnumpoints, temppoints[w]);
2234 static void R_DrawCollisionBrush(const colbrushf_t *brush)
2237 R_Mesh_VertexPointer(brush->points->v);
2238 i = (int)(((size_t)brush) / sizeof(colbrushf_t));
2239 GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2240 GL_LockArrays(0, brush->numpoints);
2241 R_Mesh_Draw(0, brush->numpoints, brush->numtriangles, brush->elements);
2242 GL_LockArrays(0, 0);
2245 static void R_DrawCollisionSurface(const entity_render_t *ent, const msurface_t *surface)
2248 if (!surface->num_collisiontriangles)
2250 R_Mesh_VertexPointer(surface->data_collisionvertex3f);
2251 i = (int)(((size_t)surface) / sizeof(msurface_t));
2252 GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2253 GL_LockArrays(0, surface->num_collisionvertices);
2254 R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i);
2255 GL_LockArrays(0, 0);
2258 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)
2260 texturelayer_t *layer;
2261 layer = t->currentlayers + t->currentnumlayers++;
2263 layer->depthmask = depthmask;
2264 layer->blendfunc1 = blendfunc1;
2265 layer->blendfunc2 = blendfunc2;
2266 layer->texture = texture;
2267 layer->texmatrix = *matrix;
2268 layer->color[0] = r;
2269 layer->color[1] = g;
2270 layer->color[2] = b;
2271 layer->color[3] = a;
2274 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
2276 // FIXME: identify models using a better check than ent->model->brush.shadowmesh
2277 //int lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
2280 texture_t *texture = t;
2281 model_t *model = ent->model;
2282 int s = ent->skinnum;
2283 if ((unsigned int)s >= (unsigned int)model->numskins)
2285 if (model->skinscenes)
2287 if (model->skinscenes[s].framecount > 1)
2288 s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
2290 s = model->skinscenes[s].firstframe;
2293 t = t + s * model->num_surfaces;
2295 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];
2296 texture->currentframe = t;
2299 t->currentmaterialflags = t->basematerialflags;
2300 t->currentalpha = ent->alpha;
2301 if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
2302 t->currentalpha *= r_wateralpha.value;
2303 if (!(ent->flags & RENDER_LIGHT))
2304 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
2305 if (ent->effects & EF_ADDITIVE)
2306 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT;
2307 else if (t->currentalpha < 1)
2308 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT;
2309 if (ent->effects & EF_NODEPTHTEST)
2310 t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST;
2311 if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
2312 t->currenttexmatrix = r_waterscrollmatrix;
2314 t->currenttexmatrix = identitymatrix;
2316 t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
2317 t->basetexture = (!t->colormapping && t->skin.merged) ? t->skin.merged : t->skin.base;
2318 t->glosstexture = r_texture_white;
2319 t->specularpower = 8;
2320 t->specularscale = 0;
2321 if (r_shadow_gloss.integer > 0)
2325 if (r_shadow_glossintensity.value > 0)
2327 t->glosstexture = t->skin.gloss;
2328 t->specularscale = r_shadow_glossintensity.value;
2331 else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0)
2332 t->specularscale = r_shadow_gloss2intensity.value;
2335 t->currentnumlayers = 0;
2336 if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
2338 if (gl_lightmaps.integer)
2339 R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, r_texture_white, &identitymatrix, 1, 1, 1, 1);
2340 else if (!(t->currentmaterialflags & MATERIALFLAG_SKY))
2342 int blendfunc1, blendfunc2, depthmask;
2343 if (t->currentmaterialflags & MATERIALFLAG_ADD)
2345 blendfunc1 = GL_SRC_ALPHA;
2346 blendfunc2 = GL_ONE;
2348 else if (t->currentmaterialflags & MATERIALFLAG_ALPHA)
2350 blendfunc1 = GL_SRC_ALPHA;
2351 blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
2353 else if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
2355 blendfunc1 = t->customblendfunc[0];
2356 blendfunc2 = t->customblendfunc[1];
2360 blendfunc1 = GL_ONE;
2361 blendfunc2 = GL_ZERO;
2363 depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
2364 if (t->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
2366 rtexture_t *currentbasetexture;
2368 if (fogenabled && (t->currentmaterialflags & MATERIALFLAG_BLENDED))
2369 layerflags |= TEXTURELAYERFLAG_FOGDARKEN;
2370 currentbasetexture = (VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) < (1.0f / 1048576.0f) && t->skin.merged) ? t->skin.merged : t->skin.base;
2371 if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2373 // fullbright is not affected by r_lightmapintensity
2374 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0], ent->colormod[1], ent->colormod[2], t->currentalpha);
2375 if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2376 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);
2377 if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2378 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);
2384 // q3bsp has no lightmap updates, so the lightstylevalue that
2385 // would normally be baked into the lightmap must be
2386 // applied to the color
2387 if (ent->model->type == mod_brushq3)
2388 colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
2389 colorscale *= r_lightmapintensity;
2390 if (r_textureunits.integer >= 2 && gl_combine.integer)
2391 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);
2392 else if ((t->currentmaterialflags & MATERIALFLAG_BLENDED) == 0)
2393 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);
2395 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);
2396 if (r_ambient.value >= (1.0f/64.0f))
2397 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);
2398 if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2400 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);
2401 if (r_ambient.value >= (1.0f/64.0f))
2402 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);
2404 if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2406 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);
2407 if (r_ambient.value >= (1.0f/64.0f))
2408 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);
2411 if (t->skin.glow != NULL)
2412 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, t->currentalpha);
2413 if (fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
2415 // if this is opaque use alpha blend which will darken the earlier
2418 // if this is an alpha blended material, all the earlier passes
2419 // were darkened by fog already, so we only need to add the fog
2420 // color ontop through the fog mask texture
2422 // if this is an additive blended material, all the earlier passes
2423 // were darkened by fog already, and we should not add fog color
2424 // (because the background was not darkened, there is no fog color
2425 // that was lost behind it).
2426 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], t->currentalpha);
2433 void R_UpdateAllTextureInfo(entity_render_t *ent)
2437 for (i = 0;i < ent->model->num_textures;i++)
2438 R_UpdateTextureInfo(ent, ent->model->data_textures + i);
2441 int rsurface_array_size = 0;
2442 float *rsurface_array_modelvertex3f = NULL;
2443 float *rsurface_array_modelsvector3f = NULL;
2444 float *rsurface_array_modeltvector3f = NULL;
2445 float *rsurface_array_modelnormal3f = NULL;
2446 float *rsurface_array_deformedvertex3f = NULL;
2447 float *rsurface_array_deformedsvector3f = NULL;
2448 float *rsurface_array_deformedtvector3f = NULL;
2449 float *rsurface_array_deformednormal3f = NULL;
2450 float *rsurface_array_color4f = NULL;
2451 float *rsurface_array_texcoord3f = NULL;
2453 void R_Mesh_ResizeArrays(int newvertices)
2456 if (rsurface_array_size >= newvertices)
2458 if (rsurface_array_modelvertex3f)
2459 Mem_Free(rsurface_array_modelvertex3f);
2460 rsurface_array_size = (newvertices + 1023) & ~1023;
2461 base = (float *)Mem_Alloc(r_main_mempool, rsurface_array_size * sizeof(float[31]));
2462 rsurface_array_modelvertex3f = base + rsurface_array_size * 0;
2463 rsurface_array_modelsvector3f = base + rsurface_array_size * 3;
2464 rsurface_array_modeltvector3f = base + rsurface_array_size * 6;
2465 rsurface_array_modelnormal3f = base + rsurface_array_size * 9;
2466 rsurface_array_deformedvertex3f = base + rsurface_array_size * 12;
2467 rsurface_array_deformedsvector3f = base + rsurface_array_size * 15;
2468 rsurface_array_deformedtvector3f = base + rsurface_array_size * 18;
2469 rsurface_array_deformednormal3f = base + rsurface_array_size * 21;
2470 rsurface_array_texcoord3f = base + rsurface_array_size * 24;
2471 rsurface_array_color4f = base + rsurface_array_size * 27;
2474 float *rsurface_modelvertex3f;
2475 float *rsurface_modelsvector3f;
2476 float *rsurface_modeltvector3f;
2477 float *rsurface_modelnormal3f;
2478 float *rsurface_vertex3f;
2479 float *rsurface_svector3f;
2480 float *rsurface_tvector3f;
2481 float *rsurface_normal3f;
2482 float *rsurface_lightmapcolor4f;
2483 vec3_t rsurface_modelorg;
2484 qboolean rsurface_generatedvertex;
2485 const entity_render_t *rsurface_entity;
2486 const model_t *rsurface_model;
2487 texture_t *rsurface_texture;
2488 rtexture_t *rsurface_lightmaptexture;
2489 rsurfmode_t rsurface_mode;
2490 texture_t *rsurface_glsl_texture;
2491 qboolean rsurface_glsl_uselightmap;
2493 void RSurf_ActiveEntity(const entity_render_t *ent)
2495 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
2496 rsurface_entity = ent;
2497 rsurface_model = ent->model;
2498 if (rsurface_array_size < rsurface_model->surfmesh.num_vertices)
2499 R_Mesh_ResizeArrays(rsurface_model->surfmesh.num_vertices);
2500 R_Mesh_Matrix(&ent->matrix);
2501 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
2502 if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexboneweights))
2504 rsurface_modelvertex3f = rsurface_array_modelvertex3f;
2505 rsurface_modelsvector3f = NULL;
2506 rsurface_modeltvector3f = NULL;
2507 rsurface_modelnormal3f = NULL;
2508 Mod_Alias_GetMesh_Vertex3f(rsurface_model, rsurface_entity->frameblend, rsurface_array_modelvertex3f);
2509 rsurface_generatedvertex = true;
2513 rsurface_modelvertex3f = rsurface_model->surfmesh.data_vertex3f;
2514 rsurface_modelsvector3f = rsurface_model->surfmesh.data_svector3f;
2515 rsurface_modeltvector3f = rsurface_model->surfmesh.data_tvector3f;
2516 rsurface_modelnormal3f = rsurface_model->surfmesh.data_normal3f;
2517 rsurface_generatedvertex = false;
2519 rsurface_vertex3f = rsurface_modelvertex3f;
2520 rsurface_svector3f = rsurface_modelsvector3f;
2521 rsurface_tvector3f = rsurface_modeltvector3f;
2522 rsurface_normal3f = rsurface_modelnormal3f;
2523 rsurface_mode = RSURFMODE_NONE;
2524 rsurface_lightmaptexture = NULL;
2525 rsurface_texture = NULL;
2526 rsurface_glsl_texture = NULL;
2527 rsurface_glsl_uselightmap = false;
2530 void RSurf_CleanUp(void)
2533 if (rsurface_mode == RSURFMODE_GLSL)
2535 qglUseProgramObjectARB(0);CHECKGLERROR
2537 GL_AlphaTest(false);
2538 rsurface_mode = RSURFMODE_NONE;
2539 rsurface_lightmaptexture = NULL;
2540 rsurface_texture = NULL;
2541 rsurface_glsl_texture = NULL;
2542 rsurface_glsl_uselightmap = false;
2545 void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist)
2547 if (rsurface_generatedvertex)
2549 if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2550 generatetangents = true;
2551 if (generatetangents)
2552 generatenormals = true;
2553 if (generatenormals && !rsurface_modelnormal3f)
2555 rsurface_normal3f = rsurface_modelnormal3f = rsurface_array_modelnormal3f;
2556 Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_modelnormal3f, r_smoothnormals_areaweighting.integer);
2558 if (generatetangents && !rsurface_modelsvector3f)
2560 rsurface_svector3f = rsurface_modelsvector3f = rsurface_array_modelsvector3f;
2561 rsurface_tvector3f = rsurface_modeltvector3f = rsurface_array_modeltvector3f;
2562 Mod_BuildTextureVectorsFromNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_modelnormal3f, rsurface_model->surfmesh.data_element3i, rsurface_array_modelsvector3f, rsurface_array_modeltvector3f, r_smoothnormals_areaweighting.integer);
2565 if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2567 int texturesurfaceindex;
2568 float center[3], forward[3], right[3], up[3], v[4][3];
2569 matrix4x4_t matrix1, imatrix1;
2570 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewforward, forward);
2571 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewright, right);
2572 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewup, up);
2573 // make deformed versions of only the vertices used by the specified surfaces
2574 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2577 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2578 // a single autosprite surface can contain multiple sprites...
2579 for (j = 0;j < surface->num_vertices - 3;j += 4)
2581 VectorClear(center);
2582 for (i = 0;i < 4;i++)
2583 VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
2584 VectorScale(center, 0.25f, center);
2585 if (rsurface_texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
2587 forward[0] = rsurface_modelorg[0] - center[0];
2588 forward[1] = rsurface_modelorg[1] - center[1];
2590 VectorNormalize(forward);
2591 right[0] = forward[1];
2592 right[1] = -forward[0];
2594 VectorSet(up, 0, 0, 1);
2596 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
2597 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);
2598 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
2599 for (i = 0;i < 4;i++)
2600 Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
2601 for (i = 0;i < 4;i++)
2602 VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_modelvertex3f + (surface->num_firstvertex+i+j) * 3);
2604 Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_deformednormal3f, r_smoothnormals_areaweighting.integer);
2605 Mod_BuildTextureVectorsFromNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_array_deformednormal3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_deformedsvector3f, rsurface_array_deformedtvector3f, r_smoothnormals_areaweighting.integer);
2607 rsurface_vertex3f = rsurface_array_deformedvertex3f;
2608 rsurface_svector3f = rsurface_array_deformedsvector3f;
2609 rsurface_tvector3f = rsurface_array_deformedtvector3f;
2610 rsurface_normal3f = rsurface_array_deformednormal3f;
2612 R_Mesh_VertexPointer(rsurface_vertex3f);
2615 void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacelist)
2617 int texturesurfaceindex;
2618 const msurface_t *surface = texturesurfacelist[0];
2619 int firstvertex = surface->num_firstvertex;
2620 int endvertex = surface->num_firstvertex + surface->num_vertices;
2621 if (texturenumsurfaces == 1)
2623 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2624 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2626 else if (r_batchmode.integer == 2)
2628 #define MAXBATCHTRIANGLES 4096
2629 int batchtriangles = 0;
2630 int batchelements[MAXBATCHTRIANGLES*3];
2631 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2633 surface = texturesurfacelist[texturesurfaceindex];
2634 if (surface->num_triangles >= 256 || (batchtriangles == 0 && texturesurfaceindex + 1 >= texturenumsurfaces))
2636 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2639 if (batchtriangles + surface->num_triangles > MAXBATCHTRIANGLES)
2641 R_Mesh_Draw(firstvertex, endvertex - firstvertex, batchtriangles, batchelements);
2643 firstvertex = surface->num_firstvertex;
2644 endvertex = surface->num_firstvertex + surface->num_vertices;
2648 firstvertex = min(firstvertex, surface->num_firstvertex);
2649 endvertex = max(endvertex, surface->num_firstvertex + surface->num_vertices);
2651 memcpy(batchelements + batchtriangles * 3, rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3]));
2652 batchtriangles += surface->num_triangles;
2655 R_Mesh_Draw(firstvertex, endvertex - firstvertex, batchtriangles, batchelements);
2657 else if (r_batchmode.integer == 1)
2659 int firsttriangle = 0;
2660 int endtriangle = -1;
2661 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2663 surface = texturesurfacelist[texturesurfaceindex];
2664 if (surface->num_firsttriangle != endtriangle)
2666 if (endtriangle > firsttriangle)
2668 GL_LockArrays(firstvertex, endvertex - firstvertex);
2669 R_Mesh_Draw(firstvertex, endvertex - firstvertex, endtriangle - firsttriangle, (rsurface_model->surfmesh.data_element3i + 3 * firsttriangle));
2671 firstvertex = surface->num_firstvertex;
2672 endvertex = surface->num_firstvertex + surface->num_vertices;
2673 firsttriangle = surface->num_firsttriangle;
2677 firstvertex = min(firstvertex, surface->num_firstvertex);
2678 endvertex = max(endvertex, surface->num_firstvertex + surface->num_vertices);
2680 endtriangle = surface->num_firsttriangle + surface->num_triangles;
2682 if (endtriangle > firsttriangle)
2684 GL_LockArrays(firstvertex, endvertex - firstvertex);
2685 R_Mesh_Draw(firstvertex, endvertex - firstvertex, endtriangle - firsttriangle, (rsurface_model->surfmesh.data_element3i + 3 * firsttriangle));
2690 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2692 surface = texturesurfacelist[texturesurfaceindex];
2693 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2694 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2699 static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
2701 int texturesurfaceindex;
2702 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2704 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2705 int k = (int)(((size_t)surface) / sizeof(msurface_t));
2706 GL_Color((k & 15) * (1.0f / 16.0f), ((k >> 4) & 15) * (1.0f / 16.0f), ((k >> 8) & 15) * (1.0f / 16.0f), 0.2f);
2707 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2708 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2712 static void RSurf_DrawBatch_Lightmap(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
2714 int texturesurfaceindex;
2722 vec3_t ambientcolor;
2723 vec3_t diffusecolor;
2725 VectorCopy(rsurface_entity->modellight_lightdir, lightdir);
2726 ambientcolor[0] = rsurface_entity->modellight_ambient[0] * r * 0.5f;
2727 ambientcolor[1] = rsurface_entity->modellight_ambient[1] * g * 0.5f;
2728 ambientcolor[2] = rsurface_entity->modellight_ambient[2] * b * 0.5f;
2729 diffusecolor[0] = rsurface_entity->modellight_diffuse[0] * r * 0.5f;
2730 diffusecolor[1] = rsurface_entity->modellight_diffuse[1] * g * 0.5f;
2731 diffusecolor[2] = rsurface_entity->modellight_diffuse[2] * b * 0.5f;
2732 if (VectorLength2(diffusecolor) > 0)
2734 // generate color arrays for the surfaces in this list
2735 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2737 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2738 int numverts = surface->num_vertices;
2739 v = rsurface_vertex3f + 3 * surface->num_firstvertex;
2740 c2 = rsurface_normal3f + 3 * surface->num_firstvertex;
2741 c = rsurface_array_color4f + 4 * surface->num_firstvertex;
2742 // q3-style directional shading
2743 for (i = 0;i < numverts;i++, v += 3, c2 += 3, c += 4)
2745 if ((f = DotProduct(c2, lightdir)) > 0)
2746 VectorMA(ambientcolor, f, diffusecolor, c);
2748 VectorCopy(ambientcolor, c);
2757 rsurface_lightmapcolor4f = rsurface_array_color4f;
2761 r = ambientcolor[0];
2762 g = ambientcolor[1];
2763 b = ambientcolor[2];
2764 rsurface_lightmapcolor4f = NULL;
2767 else if (lightmode >= 1 || !rsurface_lightmaptexture)
2769 if (texturesurfacelist[0]->lightmapinfo && texturesurfacelist[0]->lightmapinfo->stainsamples)
2771 // generate color arrays for the surfaces in this list
2772 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2774 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2775 for (i = 0, c = rsurface_array_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
2777 if (surface->lightmapinfo->samples)
2779 const unsigned char *lm = surface->lightmapinfo->samples + (rsurface_model->surfmesh.data_lightmapoffsets + surface->num_firstvertex)[i];
2780 float scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
2781 VectorScale(lm, scale, c);
2782 if (surface->lightmapinfo->styles[1] != 255)
2784 int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
2786 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
2787 VectorMA(c, scale, lm, c);
2788 if (surface->lightmapinfo->styles[2] != 255)
2791 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
2792 VectorMA(c, scale, lm, c);
2793 if (surface->lightmapinfo->styles[3] != 255)
2796 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
2797 VectorMA(c, scale, lm, c);
2807 rsurface_lightmapcolor4f = rsurface_array_color4f;
2810 rsurface_lightmapcolor4f = rsurface_model->surfmesh.data_lightmapcolor4f;
2815 rsurface_lightmapcolor4f = NULL;
2819 if (rsurface_lightmapcolor4f)
2821 // generate color arrays for the surfaces in this list
2822 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2824 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2825 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)
2827 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2837 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2839 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2840 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)
2842 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2850 rsurface_lightmapcolor4f = rsurface_array_color4f;
2852 if (applycolor && rsurface_lightmapcolor4f)
2854 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2856 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2857 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)
2865 rsurface_lightmapcolor4f = rsurface_array_color4f;
2867 R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
2868 GL_Color(r, g, b, a);
2869 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
2872 static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfacelist)
2874 int texturesurfaceindex;
2876 qboolean applycolor;
2879 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_NODRAW)
2881 r_shadow_rtlight = NULL;
2882 renderstats.entities_surfaces += texturenumsurfaces;
2883 // FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
2884 lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
2886 GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
2887 if ((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE))
2889 qglDisable(GL_CULL_FACE);CHECKGLERROR
2891 if (r_showsurfaces.integer)
2893 if (rsurface_mode != RSURFMODE_SHOWSURFACES)
2895 rsurface_mode = RSURFMODE_SHOWSURFACES;
2897 GL_BlendFunc(GL_ONE, GL_ZERO);
2898 R_Mesh_ColorPointer(NULL);
2899 R_Mesh_ResetTextureState();
2901 RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
2902 RSurf_DrawBatch_ShowSurfaces(texturenumsurfaces, texturesurfacelist);
2904 else if (rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY)
2906 // transparent sky would be ridiculous
2907 if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2909 if (rsurface_mode != RSURFMODE_SKY)
2911 if (rsurface_mode == RSURFMODE_GLSL)
2913 qglUseProgramObjectARB(0);CHECKGLERROR
2915 rsurface_mode = RSURFMODE_SKY;
2918 skyrendernow = false;
2920 // restore entity matrix
2921 R_Mesh_Matrix(&rsurface_entity->matrix);
2924 // LordHavoc: HalfLife maps have freaky skypolys so don't use
2925 // skymasking on them, and Quake3 never did sky masking (unlike
2926 // software Quake and software Quake2), so disable the sky masking
2927 // in Quake3 maps as it causes problems with q3map2 sky tricks,
2928 // and skymasking also looks very bad when noclipping outside the
2929 // level, so don't use it then either.
2930 if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2932 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
2933 R_Mesh_ColorPointer(NULL);
2934 R_Mesh_ResetTextureState();
2935 if (skyrendermasked)
2937 // depth-only (masking)
2938 GL_ColorMask(0,0,0,0);
2939 // just to make sure that braindead drivers don't draw
2940 // anything despite that colormask...
2941 GL_BlendFunc(GL_ZERO, GL_ONE);
2946 GL_BlendFunc(GL_ONE, GL_ZERO);
2950 // LordHavoc: HalfLife maps have freaky skypolys so don't use
2951 // skymasking on them, and Quake3 never did sky masking (unlike
2952 // software Quake and software Quake2), so disable the sky masking
2953 // in Quake3 maps as it causes problems with q3map2 sky tricks,
2954 // and skymasking also looks very bad when noclipping outside the
2955 // level, so don't use it then either.
2956 if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2958 RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
2959 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
2960 if (skyrendermasked)
2961 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
2965 else if (rsurface_texture->currentnumlayers && r_glsl.integer && gl_support_fragment_shader)
2967 if (rsurface_mode != RSURFMODE_GLSL)
2969 rsurface_mode = RSURFMODE_GLSL;
2970 rsurface_glsl_texture = NULL;
2971 rsurface_glsl_uselightmap = false;
2972 R_Mesh_ResetTextureState();
2974 if (rsurface_glsl_texture != rsurface_texture || rsurface_glsl_uselightmap != (rsurface_lightmaptexture != NULL))
2976 rsurface_glsl_texture = rsurface_texture;
2977 rsurface_glsl_uselightmap = rsurface_lightmaptexture != NULL;
2978 GL_BlendFunc(rsurface_texture->currentlayers[0].blendfunc1, rsurface_texture->currentlayers[0].blendfunc2);
2979 GL_DepthMask(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_BLENDED));
2980 GL_Color(rsurface_entity->colormod[0], rsurface_entity->colormod[1], rsurface_entity->colormod[2], rsurface_texture->currentalpha);
2981 R_SetupSurfaceShader(vec3_origin, lightmode == 2);
2982 //permutation_deluxemapping = permutation_lightmapping = R_SetupSurfaceShader(vec3_origin, lightmode == 2, false);
2983 //if (r_glsl_deluxemapping.integer)
2984 // permutation_deluxemapping = R_SetupSurfaceShader(vec3_origin, lightmode == 2, true);
2985 R_Mesh_TexCoordPointer(0, 2, rsurface_model->surfmesh.data_texcoordtexture2f);
2986 R_Mesh_TexCoordPointer(4, 2, rsurface_model->surfmesh.data_texcoordlightmap2f);
2987 GL_AlphaTest((rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2989 if (!r_glsl_permutation)
2991 RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist);
2992 R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
2993 R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
2994 R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
2995 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2997 R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
2998 if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2999 R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
3000 R_Mesh_ColorPointer(NULL);
3002 else if (rsurface_lightmaptexture)
3004 R_Mesh_TexBind(7, R_GetTexture(rsurface_lightmaptexture));
3005 if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
3006 R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture));
3007 R_Mesh_ColorPointer(NULL);
3011 R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
3012 if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
3013 R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
3014 R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f);
3016 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
3018 else if (rsurface_texture->currentnumlayers)
3021 const texturelayer_t *layer;
3023 if (rsurface_mode != RSURFMODE_MULTIPASS)
3025 if (rsurface_mode == RSURFMODE_GLSL)
3027 qglUseProgramObjectARB(0);CHECKGLERROR
3029 rsurface_mode = RSURFMODE_MULTIPASS;
3031 RSurf_PrepareVerticesForBatch(true, false, texturenumsurfaces, texturesurfacelist);
3032 for (layerindex = 0, layer = rsurface_texture->currentlayers;layerindex < rsurface_texture->currentnumlayers;layerindex++, layer++)
3035 int layertexrgbscale;
3036 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
3038 if (layerindex == 0)
3042 GL_AlphaTest(false);
3043 qglDepthFunc(GL_EQUAL);CHECKGLERROR
3046 GL_DepthMask(layer->depthmask);
3047 GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
3048 if ((layer->color[0] > 2 || layer->color[1] > 2 || layer->color[2] > 2) && (gl_combine.integer || layer->depthmask))
3050 layertexrgbscale = 4;
3051 VectorScale(layer->color, 0.25f, layercolor);
3053 else if ((layer->color[0] > 1 || layer->color[1] > 1 || layer->color[2] > 1) && (gl_combine.integer || layer->depthmask))
3055 layertexrgbscale = 2;
3056 VectorScale(layer->color, 0.5f, layercolor);
3060 layertexrgbscale = 1;
3061 VectorScale(layer->color, 1.0f, layercolor);
3063 layercolor[3] = layer->color[3];
3064 R_Mesh_ColorPointer(NULL);
3065 GL_Color(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
3066 applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
3067 applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
3068 switch (layer->type)
3070 case TEXTURELAYERTYPE_LITTEXTURE_COMBINE:
3071 memset(&m, 0, sizeof(m));
3072 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
3073 m.tex[1] = R_GetTexture(layer->texture);
3074 m.texmatrix[1] = layer->texmatrix;
3075 m.texrgbscale[1] = layertexrgbscale;
3076 m.pointer_texcoord[1] = rsurface_model->surfmesh.data_texcoordtexture2f;
3077 R_Mesh_TextureState(&m);
3078 if (lightmode >= 1 || !rsurface_lightmaptexture)
3079 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
3081 R_Mesh_TexBind(0, R_GetTexture(rsurface_lightmaptexture));
3082 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], lightmode, applycolor, applyfog);
3084 case TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS:
3085 memset(&m, 0, sizeof(m));
3086 if (lightmode >= 1 || !rsurface_lightmaptexture)
3087 m.tex[0] = R_GetTexture(r_texture_white);
3089 m.tex[0] = R_GetTexture(rsurface_lightmaptexture);
3090 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
3091 R_Mesh_TextureState(&m);
3092 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, 1, 1, 1, 1, lightmode, false, false);
3093 GL_LockArrays(0, 0);
3094 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
3095 memset(&m, 0, sizeof(m));
3096 m.tex[0] = R_GetTexture(layer->texture);
3097 m.texmatrix[0] = layer->texmatrix;
3098 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3099 R_Mesh_TextureState(&m);
3100 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, false);
3102 case TEXTURELAYERTYPE_LITTEXTURE_VERTEX:
3103 memset(&m, 0, sizeof(m));
3104 m.tex[0] = R_GetTexture(layer->texture);
3105 m.texmatrix[0] = layer->texmatrix;
3106 m.texrgbscale[0] = layertexrgbscale;
3107 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3108 R_Mesh_TextureState(&m);
3109 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], lightmode == 2 ? 2 : 1, applycolor, applyfog);
3111 case TEXTURELAYERTYPE_TEXTURE:
3112 memset(&m, 0, sizeof(m));
3113 m.tex[0] = R_GetTexture(layer->texture);
3114 m.texmatrix[0] = layer->texmatrix;
3115 m.texrgbscale[0] = layertexrgbscale;
3116 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3117 R_Mesh_TextureState(&m);
3118 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
3120 case TEXTURELAYERTYPE_FOG:
3121 R_Mesh_ColorPointer(rsurface_array_color4f);
3124 memset(&m, 0, sizeof(m));
3125 m.tex[0] = R_GetTexture(layer->texture);
3126 m.texmatrix[0] = layer->texmatrix;
3127 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3128 R_Mesh_TextureState(&m);
3131 R_Mesh_ResetTextureState();
3132 // generate a color array for the fog pass
3133 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3137 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3138 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)
3140 f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
3141 c[0] = layercolor[0];
3142 c[1] = layercolor[1];
3143 c[2] = layercolor[2];
3144 c[3] = f * layercolor[3];
3147 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
3150 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
3152 GL_LockArrays(0, 0);
3153 // if trying to do overbright on first pass of an opaque surface
3154 // when combine is not supported, brighten as a post process
3155 if (layertexrgbscale > 1 && !gl_combine.integer && layer->depthmask)
3158 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
3159 R_Mesh_ColorPointer(NULL);
3160 GL_Color(1, 1, 1, 1);
3161 R_Mesh_ResetTextureState();
3162 for (scale = 1;scale < layertexrgbscale;scale <<= 1)
3163 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
3164 GL_LockArrays(0, 0);
3168 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
3170 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
3171 GL_AlphaTest(false);
3175 GL_LockArrays(0, 0);
3176 if ((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE))
3178 qglEnable(GL_CULL_FACE);CHECKGLERROR
3182 #define BATCHSIZE 256
3183 static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
3185 int surfacelistindex;
3188 msurface_t *texturesurfacelist[BATCHSIZE];
3189 RSurf_ActiveEntity(ent);
3192 for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
3194 msurface_t *surface = ent->model->data_surfaces + surfacelist[surfacelistindex];
3196 if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
3199 R_DrawTextureSurfaceList(batchcount, texturesurfacelist);
3201 t = surface->texture;
3202 rsurface_lightmaptexture = surface->lightmaptexture;
3203 R_UpdateTextureInfo(ent, t);
3204 rsurface_texture = t->currentframe;
3206 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY)
3207 continue; // transparent sky is too difficult
3209 texturesurfacelist[batchcount++] = surface;
3212 R_DrawTextureSurfaceList(batchcount, texturesurfacelist);
3216 void R_QueueTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfacelist)
3218 int texturesurfaceindex;
3219 vec3_t tempcenter, center;
3220 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_BLENDED)
3222 // drawing sky transparently would be too difficult
3223 if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY))
3225 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3227 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3228 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
3229 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
3230 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
3231 Matrix4x4_Transform(&rsurface_entity->matrix, tempcenter, center);
3232 R_MeshQueue_AddTransparent(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, R_DrawSurface_TransparentCallback, rsurface_entity, surface - rsurface_model->data_surfaces, r_shadow_rtlight);
3237 R_DrawTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
3240 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
3241 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
3243 int i, j, f, flagsmask;
3244 int counttriangles = 0;
3246 model_t *model = ent->model;
3247 const int maxsurfacelist = 1024;
3248 int numsurfacelist = 0;
3249 msurface_t *surfacelist[1024];
3253 RSurf_ActiveEntity(ent);
3255 // update light styles
3256 if (!skysurfaces && model->brushq1.light_styleupdatechains)
3258 msurface_t *surface, **surfacechain;
3259 for (i = 0;i < model->brushq1.light_styles;i++)
3261 if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
3263 model->brushq1.light_stylevalue[i] = r_refdef.lightstylevalue[model->brushq1.light_style[i]];
3264 if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
3265 for (;(surface = *surfacechain);surfacechain++)
3266 surface->cached_dlight = true;
3271 R_UpdateAllTextureInfo(ent);
3272 flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
3275 rsurface_lightmaptexture = NULL;
3276 rsurface_texture = NULL;
3278 if (ent == r_refdef.worldentity)
3280 msurface_t *surface;
3281 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3283 if (!r_worldsurfacevisible[j])
3285 if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
3289 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3292 t = surface->texture;
3293 rsurface_lightmaptexture = surface->lightmaptexture;
3294 rsurface_texture = t->currentframe;
3295 f = rsurface_texture->currentmaterialflags & flagsmask;
3297 if (f && surface->num_triangles)
3299 // if lightmap parameters changed, rebuild lightmap texture
3300 if (surface->cached_dlight)
3301 R_BuildLightMap(ent, surface);
3302 // add face to draw list
3303 surfacelist[numsurfacelist++] = surface;
3304 counttriangles += surface->num_triangles;
3305 if (numsurfacelist >= maxsurfacelist)
3307 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3315 msurface_t *surface;
3316 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3318 if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
3322 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3325 t = surface->texture;
3326 rsurface_lightmaptexture = surface->lightmaptexture;
3327 rsurface_texture = t->currentframe;
3328 f = rsurface_texture->currentmaterialflags & flagsmask;
3330 if (f && surface->num_triangles)
3332 // if lightmap parameters changed, rebuild lightmap texture
3333 if (surface->cached_dlight)
3334 R_BuildLightMap(ent, surface);
3335 // add face to draw list
3336 surfacelist[numsurfacelist++] = surface;
3337 counttriangles += surface->num_triangles;
3338 if (numsurfacelist >= maxsurfacelist)
3340 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3347 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3348 renderstats.entities_triangles += counttriangles;
3351 if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces)
3354 const msurface_t *surface;
3357 R_Mesh_Matrix(&ent->matrix);
3358 R_Mesh_ColorPointer(NULL);
3359 R_Mesh_ResetTextureState();
3360 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
3361 GL_DepthMask(false);
3362 GL_DepthTest(!r_showdisabledepthtest.integer);
3363 qglPolygonOffset(r_polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_polygonoffset + r_showcollisionbrushes_polygonoffset.value);CHECKGLERROR
3364 for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
3365 if (brush->colbrushf && brush->colbrushf->numtriangles)
3366 R_DrawCollisionBrush(brush->colbrushf);
3367 for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
3368 if (surface->num_collisiontriangles)
3369 R_DrawCollisionSurface(ent, surface);
3370 qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
3373 if (r_showtris.integer || r_shownormals.integer)
3376 msurface_t *surface;
3377 const int *elements;
3382 if (r_showdisabledepthtest.integer)
3384 qglDepthFunc(GL_ALWAYS);CHECKGLERROR
3386 GL_BlendFunc(GL_ONE, GL_ZERO);
3387 R_Mesh_ColorPointer(NULL);
3388 R_Mesh_ResetTextureState();
3389 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3391 if (ent == r_refdef.worldentity && !r_worldsurfacevisible[j])
3393 rsurface_texture = surface->texture->currentframe;
3394 if ((rsurface_texture->currentmaterialflags & flagsmask) && surface->num_triangles)
3396 RSurf_PrepareVerticesForBatch(true, true, 1, &surface);
3397 if (r_showtris.integer)
3399 if (!rsurface_texture->currentlayers->depthmask)
3400 GL_Color(r_showtris.value, 0, 0, 1);
3401 else if (ent == r_refdef.worldentity)
3402 GL_Color(r_showtris.value, r_showtris.value, r_showtris.value, 1);
3404 GL_Color(0, r_showtris.value, 0, 1);
3405 elements = (ent->model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);
3408 for (k = 0;k < surface->num_triangles;k++, elements += 3)
3410 qglArrayElement(elements[0]);qglArrayElement(elements[1]);
3411 qglArrayElement(elements[1]);qglArrayElement(elements[2]);
3412 qglArrayElement(elements[2]);qglArrayElement(elements[0]);
3417 if (r_shownormals.integer)
3419 GL_Color(r_shownormals.value, 0, 0, 1);
3421 for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3423 VectorCopy(rsurface_vertex3f + l * 3, v);
3424 qglVertex3f(v[0], v[1], v[2]);
3425 VectorMA(v, 8, rsurface_svector3f + l * 3, v);
3426 qglVertex3f(v[0], v[1], v[2]);
3430 GL_Color(0, 0, r_shownormals.value, 1);
3432 for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3434 VectorCopy(rsurface_vertex3f + l * 3, v);
3435 qglVertex3f(v[0], v[1], v[2]);
3436 VectorMA(v, 8, rsurface_tvector3f + l * 3, v);
3437 qglVertex3f(v[0], v[1], v[2]);
3441 GL_Color(0, r_shownormals.value, 0, 1);
3443 for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3445 VectorCopy(rsurface_vertex3f + l * 3, v);
3446 qglVertex3f(v[0], v[1], v[2]);
3447 VectorMA(v, 8, rsurface_normal3f + l * 3, v);
3448 qglVertex3f(v[0], v[1], v[2]);
3455 rsurface_texture = NULL;
3456 if (r_showdisabledepthtest.integer)
3458 qglDepthFunc(GL_LEQUAL);CHECKGLERROR