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, 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 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
2391 if (r_ambient.value >= (1.0f/64.0f))
2392 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);
2393 if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2395 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, 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);
2396 if (r_ambient.value >= (1.0f/64.0f))
2397 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);
2399 if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2401 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, 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);
2402 if (r_ambient.value >= (1.0f/64.0f))
2403 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);
2406 if (t->skin.glow != NULL)
2407 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, t->currentalpha);
2408 if (fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
2410 // if this is opaque use alpha blend which will darken the earlier
2413 // if this is an alpha blended material, all the earlier passes
2414 // were darkened by fog already, so we only need to add the fog
2415 // color ontop through the fog mask texture
2417 // if this is an additive blended material, all the earlier passes
2418 // were darkened by fog already, and we should not add fog color
2419 // (because the background was not darkened, there is no fog color
2420 // that was lost behind it).
2421 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);
2428 void R_UpdateAllTextureInfo(entity_render_t *ent)
2432 for (i = 0;i < ent->model->num_textures;i++)
2433 R_UpdateTextureInfo(ent, ent->model->data_textures + i);
2436 int rsurface_array_size = 0;
2437 float *rsurface_array_modelvertex3f = NULL;
2438 float *rsurface_array_modelsvector3f = NULL;
2439 float *rsurface_array_modeltvector3f = NULL;
2440 float *rsurface_array_modelnormal3f = NULL;
2441 float *rsurface_array_deformedvertex3f = NULL;
2442 float *rsurface_array_deformedsvector3f = NULL;
2443 float *rsurface_array_deformedtvector3f = NULL;
2444 float *rsurface_array_deformednormal3f = NULL;
2445 float *rsurface_array_color4f = NULL;
2446 float *rsurface_array_texcoord3f = NULL;
2448 void R_Mesh_ResizeArrays(int newvertices)
2451 if (rsurface_array_size >= newvertices)
2453 if (rsurface_array_modelvertex3f)
2454 Mem_Free(rsurface_array_modelvertex3f);
2455 rsurface_array_size = (newvertices + 1023) & ~1023;
2456 base = (float *)Mem_Alloc(r_main_mempool, rsurface_array_size * sizeof(float[31]));
2457 rsurface_array_modelvertex3f = base + rsurface_array_size * 0;
2458 rsurface_array_modelsvector3f = base + rsurface_array_size * 3;
2459 rsurface_array_modeltvector3f = base + rsurface_array_size * 6;
2460 rsurface_array_modelnormal3f = base + rsurface_array_size * 9;
2461 rsurface_array_deformedvertex3f = base + rsurface_array_size * 12;
2462 rsurface_array_deformedsvector3f = base + rsurface_array_size * 15;
2463 rsurface_array_deformedtvector3f = base + rsurface_array_size * 18;
2464 rsurface_array_deformednormal3f = base + rsurface_array_size * 21;
2465 rsurface_array_texcoord3f = base + rsurface_array_size * 24;
2466 rsurface_array_color4f = base + rsurface_array_size * 27;
2469 float *rsurface_modelvertex3f;
2470 float *rsurface_modelsvector3f;
2471 float *rsurface_modeltvector3f;
2472 float *rsurface_modelnormal3f;
2473 float *rsurface_vertex3f;
2474 float *rsurface_svector3f;
2475 float *rsurface_tvector3f;
2476 float *rsurface_normal3f;
2477 float *rsurface_lightmapcolor4f;
2478 vec3_t rsurface_modelorg;
2479 qboolean rsurface_generatedvertex;
2480 const entity_render_t *rsurface_entity;
2481 const model_t *rsurface_model;
2482 texture_t *rsurface_texture;
2483 rtexture_t *rsurface_lightmaptexture;
2484 rsurfmode_t rsurface_mode;
2485 texture_t *rsurface_glsl_texture;
2486 qboolean rsurface_glsl_uselightmap;
2488 void RSurf_ActiveEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents)
2490 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
2491 rsurface_entity = ent;
2492 rsurface_model = ent->model;
2493 if (rsurface_array_size < rsurface_model->surfmesh.num_vertices)
2494 R_Mesh_ResizeArrays(rsurface_model->surfmesh.num_vertices);
2495 R_Mesh_Matrix(&ent->matrix);
2496 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
2497 if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexweightindex4i))
2501 rsurface_modelvertex3f = rsurface_array_modelvertex3f;
2502 rsurface_modelsvector3f = rsurface_array_modelsvector3f;
2503 rsurface_modeltvector3f = rsurface_array_modeltvector3f;
2504 rsurface_modelnormal3f = rsurface_array_modelnormal3f;
2505 Mod_Alias_GetMesh_Vertices(rsurface_model, rsurface_entity->frameblend, rsurface_array_modelvertex3f, rsurface_array_modelnormal3f, rsurface_array_modelsvector3f, rsurface_array_modeltvector3f);
2507 else if (wantnormals)
2509 rsurface_modelvertex3f = rsurface_array_modelvertex3f;
2510 rsurface_modelsvector3f = NULL;
2511 rsurface_modeltvector3f = NULL;
2512 rsurface_modelnormal3f = rsurface_array_modelnormal3f;
2513 Mod_Alias_GetMesh_Vertices(rsurface_model, rsurface_entity->frameblend, rsurface_array_modelvertex3f, rsurface_array_modelnormal3f, NULL, NULL);
2517 rsurface_modelvertex3f = rsurface_array_modelvertex3f;
2518 rsurface_modelsvector3f = NULL;
2519 rsurface_modeltvector3f = NULL;
2520 rsurface_modelnormal3f = NULL;
2521 Mod_Alias_GetMesh_Vertices(rsurface_model, rsurface_entity->frameblend, rsurface_array_modelvertex3f, NULL, NULL, NULL);
2523 rsurface_generatedvertex = true;
2527 rsurface_modelvertex3f = rsurface_model->surfmesh.data_vertex3f;
2528 rsurface_modelsvector3f = rsurface_model->surfmesh.data_svector3f;
2529 rsurface_modeltvector3f = rsurface_model->surfmesh.data_tvector3f;
2530 rsurface_modelnormal3f = rsurface_model->surfmesh.data_normal3f;
2531 rsurface_generatedvertex = false;
2533 rsurface_vertex3f = rsurface_modelvertex3f;
2534 rsurface_svector3f = rsurface_modelsvector3f;
2535 rsurface_tvector3f = rsurface_modeltvector3f;
2536 rsurface_normal3f = rsurface_modelnormal3f;
2537 rsurface_mode = RSURFMODE_NONE;
2538 rsurface_lightmaptexture = NULL;
2539 rsurface_texture = NULL;
2540 rsurface_glsl_texture = NULL;
2541 rsurface_glsl_uselightmap = false;
2544 void RSurf_CleanUp(void)
2547 if (rsurface_mode == RSURFMODE_GLSL)
2549 qglUseProgramObjectARB(0);CHECKGLERROR
2551 GL_AlphaTest(false);
2552 rsurface_mode = RSURFMODE_NONE;
2553 rsurface_lightmaptexture = NULL;
2554 rsurface_texture = NULL;
2555 rsurface_glsl_texture = NULL;
2556 rsurface_glsl_uselightmap = false;
2559 void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist)
2561 if (rsurface_generatedvertex)
2563 if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2564 generatetangents = true;
2565 if (generatetangents)
2566 generatenormals = true;
2567 if (generatenormals && !rsurface_modelnormal3f)
2569 rsurface_normal3f = rsurface_modelnormal3f = rsurface_array_modelnormal3f;
2570 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);
2572 if (generatetangents && !rsurface_modelsvector3f)
2574 rsurface_svector3f = rsurface_modelsvector3f = rsurface_array_modelsvector3f;
2575 rsurface_tvector3f = rsurface_modeltvector3f = rsurface_array_modeltvector3f;
2576 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);
2579 if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2581 int texturesurfaceindex;
2582 float center[3], forward[3], right[3], up[3], v[4][3];
2583 matrix4x4_t matrix1, imatrix1;
2584 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewforward, forward);
2585 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewright, right);
2586 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewup, up);
2587 // make deformed versions of only the vertices used by the specified surfaces
2588 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2591 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2592 // a single autosprite surface can contain multiple sprites...
2593 for (j = 0;j < surface->num_vertices - 3;j += 4)
2595 VectorClear(center);
2596 for (i = 0;i < 4;i++)
2597 VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
2598 VectorScale(center, 0.25f, center);
2599 if (rsurface_texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
2601 forward[0] = rsurface_modelorg[0] - center[0];
2602 forward[1] = rsurface_modelorg[1] - center[1];
2604 VectorNormalize(forward);
2605 right[0] = forward[1];
2606 right[1] = -forward[0];
2608 VectorSet(up, 0, 0, 1);
2610 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
2611 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);
2612 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
2613 for (i = 0;i < 4;i++)
2614 Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
2615 for (i = 0;i < 4;i++)
2616 VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_modelvertex3f + (surface->num_firstvertex+i+j) * 3);
2618 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);
2619 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);
2621 rsurface_vertex3f = rsurface_array_deformedvertex3f;
2622 rsurface_svector3f = rsurface_array_deformedsvector3f;
2623 rsurface_tvector3f = rsurface_array_deformedtvector3f;
2624 rsurface_normal3f = rsurface_array_deformednormal3f;
2626 R_Mesh_VertexPointer(rsurface_vertex3f);
2629 void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacelist)
2631 int texturesurfaceindex;
2632 const msurface_t *surface = texturesurfacelist[0];
2633 int firstvertex = surface->num_firstvertex;
2634 int endvertex = surface->num_firstvertex + surface->num_vertices;
2635 if (texturenumsurfaces == 1)
2637 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2638 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2640 else if (r_batchmode.integer == 2)
2642 #define MAXBATCHTRIANGLES 4096
2643 int batchtriangles = 0;
2644 int batchelements[MAXBATCHTRIANGLES*3];
2645 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2647 surface = texturesurfacelist[texturesurfaceindex];
2648 if (surface->num_triangles >= 256 || (batchtriangles == 0 && texturesurfaceindex + 1 >= texturenumsurfaces))
2650 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2653 if (batchtriangles + surface->num_triangles > MAXBATCHTRIANGLES)
2655 R_Mesh_Draw(firstvertex, endvertex - firstvertex, batchtriangles, batchelements);
2657 firstvertex = surface->num_firstvertex;
2658 endvertex = surface->num_firstvertex + surface->num_vertices;
2662 firstvertex = min(firstvertex, surface->num_firstvertex);
2663 endvertex = max(endvertex, surface->num_firstvertex + surface->num_vertices);
2665 memcpy(batchelements + batchtriangles * 3, rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3]));
2666 batchtriangles += surface->num_triangles;
2669 R_Mesh_Draw(firstvertex, endvertex - firstvertex, batchtriangles, batchelements);
2671 else if (r_batchmode.integer == 1)
2673 int firsttriangle = 0;
2674 int endtriangle = -1;
2675 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2677 surface = texturesurfacelist[texturesurfaceindex];
2678 if (surface->num_firsttriangle != endtriangle)
2680 if (endtriangle > firsttriangle)
2682 GL_LockArrays(firstvertex, endvertex - firstvertex);
2683 R_Mesh_Draw(firstvertex, endvertex - firstvertex, endtriangle - firsttriangle, (rsurface_model->surfmesh.data_element3i + 3 * firsttriangle));
2685 firstvertex = surface->num_firstvertex;
2686 endvertex = surface->num_firstvertex + surface->num_vertices;
2687 firsttriangle = surface->num_firsttriangle;
2691 firstvertex = min(firstvertex, surface->num_firstvertex);
2692 endvertex = max(endvertex, surface->num_firstvertex + surface->num_vertices);
2694 endtriangle = surface->num_firsttriangle + surface->num_triangles;
2696 if (endtriangle > firsttriangle)
2698 GL_LockArrays(firstvertex, endvertex - firstvertex);
2699 R_Mesh_Draw(firstvertex, endvertex - firstvertex, endtriangle - firsttriangle, (rsurface_model->surfmesh.data_element3i + 3 * firsttriangle));
2704 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2706 surface = texturesurfacelist[texturesurfaceindex];
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));
2713 static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
2715 int texturesurfaceindex;
2716 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2718 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2719 int k = (int)(((size_t)surface) / sizeof(msurface_t));
2720 GL_Color((k & 15) * (1.0f / 16.0f), ((k >> 4) & 15) * (1.0f / 16.0f), ((k >> 8) & 15) * (1.0f / 16.0f), 0.2f);
2721 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2722 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2726 static void RSurf_DrawBatch_Lightmap(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
2728 int texturesurfaceindex;
2736 vec3_t ambientcolor;
2737 vec3_t diffusecolor;
2739 VectorCopy(rsurface_entity->modellight_lightdir, lightdir);
2740 ambientcolor[0] = rsurface_entity->modellight_ambient[0] * r * 0.5f;
2741 ambientcolor[1] = rsurface_entity->modellight_ambient[1] * g * 0.5f;
2742 ambientcolor[2] = rsurface_entity->modellight_ambient[2] * b * 0.5f;
2743 diffusecolor[0] = rsurface_entity->modellight_diffuse[0] * r * 0.5f;
2744 diffusecolor[1] = rsurface_entity->modellight_diffuse[1] * g * 0.5f;
2745 diffusecolor[2] = rsurface_entity->modellight_diffuse[2] * b * 0.5f;
2746 if (VectorLength2(diffusecolor) > 0)
2748 // generate color arrays for the surfaces in this list
2749 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2751 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2752 int numverts = surface->num_vertices;
2753 v = rsurface_vertex3f + 3 * surface->num_firstvertex;
2754 c2 = rsurface_normal3f + 3 * surface->num_firstvertex;
2755 c = rsurface_array_color4f + 4 * surface->num_firstvertex;
2756 // q3-style directional shading
2757 for (i = 0;i < numverts;i++, v += 3, c2 += 3, c += 4)
2759 if ((f = DotProduct(c2, lightdir)) > 0)
2760 VectorMA(ambientcolor, f, diffusecolor, c);
2762 VectorCopy(ambientcolor, c);
2771 rsurface_lightmapcolor4f = rsurface_array_color4f;
2775 r = ambientcolor[0];
2776 g = ambientcolor[1];
2777 b = ambientcolor[2];
2778 rsurface_lightmapcolor4f = NULL;
2781 else if (lightmode >= 1 || !rsurface_lightmaptexture)
2783 if (texturesurfacelist[0]->lightmapinfo && texturesurfacelist[0]->lightmapinfo->stainsamples)
2785 // generate color arrays for the surfaces in this list
2786 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2788 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2789 for (i = 0, c = rsurface_array_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
2791 if (surface->lightmapinfo->samples)
2793 const unsigned char *lm = surface->lightmapinfo->samples + (rsurface_model->surfmesh.data_lightmapoffsets + surface->num_firstvertex)[i];
2794 float scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
2795 VectorScale(lm, scale, c);
2796 if (surface->lightmapinfo->styles[1] != 255)
2798 int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
2800 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
2801 VectorMA(c, scale, lm, c);
2802 if (surface->lightmapinfo->styles[2] != 255)
2805 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
2806 VectorMA(c, scale, lm, c);
2807 if (surface->lightmapinfo->styles[3] != 255)
2810 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
2811 VectorMA(c, scale, lm, c);
2821 rsurface_lightmapcolor4f = rsurface_array_color4f;
2824 rsurface_lightmapcolor4f = rsurface_model->surfmesh.data_lightmapcolor4f;
2829 rsurface_lightmapcolor4f = NULL;
2833 if (rsurface_lightmapcolor4f)
2835 // generate color arrays for the surfaces in this list
2836 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2838 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2839 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)
2841 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2851 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2853 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2854 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)
2856 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2864 rsurface_lightmapcolor4f = rsurface_array_color4f;
2866 if (applycolor && rsurface_lightmapcolor4f)
2868 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2870 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2871 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)
2879 rsurface_lightmapcolor4f = rsurface_array_color4f;
2881 R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
2882 GL_Color(r, g, b, a);
2883 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
2886 static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
2888 if (rsurface_mode != RSURFMODE_SHOWSURFACES)
2890 rsurface_mode = RSURFMODE_SHOWSURFACES;
2892 GL_BlendFunc(GL_ONE, GL_ZERO);
2893 R_Mesh_ColorPointer(NULL);
2894 R_Mesh_ResetTextureState();
2896 RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
2897 RSurf_DrawBatch_ShowSurfaces(texturenumsurfaces, texturesurfacelist);
2900 static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **texturesurfacelist)
2902 // transparent sky would be ridiculous
2903 if ((rsurface_texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2905 if (rsurface_mode != RSURFMODE_SKY)
2907 if (rsurface_mode == RSURFMODE_GLSL)
2909 qglUseProgramObjectARB(0);CHECKGLERROR
2911 rsurface_mode = RSURFMODE_SKY;
2915 skyrendernow = false;
2917 // restore entity matrix
2918 R_Mesh_Matrix(&rsurface_entity->matrix);
2921 // LordHavoc: HalfLife maps have freaky skypolys so don't use
2922 // skymasking on them, and Quake3 never did sky masking (unlike
2923 // software Quake and software Quake2), so disable the sky masking
2924 // in Quake3 maps as it causes problems with q3map2 sky tricks,
2925 // and skymasking also looks very bad when noclipping outside the
2926 // level, so don't use it then either.
2927 if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2929 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
2930 R_Mesh_ColorPointer(NULL);
2931 R_Mesh_ResetTextureState();
2932 if (skyrendermasked)
2934 // depth-only (masking)
2935 GL_ColorMask(0,0,0,0);
2936 // just to make sure that braindead drivers don't draw
2937 // anything despite that colormask...
2938 GL_BlendFunc(GL_ZERO, GL_ONE);
2943 GL_BlendFunc(GL_ONE, GL_ZERO);
2946 // LordHavoc: HalfLife maps have freaky skypolys so don't use
2947 // skymasking on them, and Quake3 never did sky masking (unlike
2948 // software Quake and software Quake2), so disable the sky masking
2949 // in Quake3 maps as it causes problems with q3map2 sky tricks,
2950 // and skymasking also looks very bad when noclipping outside the
2951 // level, so don't use it then either.
2952 if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2954 RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
2955 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
2956 if (skyrendermasked)
2957 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
2961 static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **texturesurfacelist)
2964 // FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
2965 lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
2966 if (rsurface_mode != RSURFMODE_GLSL)
2968 rsurface_mode = RSURFMODE_GLSL;
2969 rsurface_glsl_texture = NULL;
2970 rsurface_glsl_uselightmap = false;
2971 R_Mesh_ResetTextureState();
2973 if (rsurface_glsl_texture != rsurface_texture || rsurface_glsl_uselightmap != (rsurface_lightmaptexture != NULL))
2975 rsurface_glsl_texture = rsurface_texture;
2976 rsurface_glsl_uselightmap = rsurface_lightmaptexture != NULL;
2977 GL_BlendFunc(rsurface_texture->currentlayers[0].blendfunc1, rsurface_texture->currentlayers[0].blendfunc2);
2978 GL_DepthMask(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_BLENDED));
2979 GL_Color(rsurface_entity->colormod[0], rsurface_entity->colormod[1], rsurface_entity->colormod[2], rsurface_texture->currentalpha);
2980 R_SetupSurfaceShader(vec3_origin, lightmode == 2);
2981 //permutation_deluxemapping = permutation_lightmapping = R_SetupSurfaceShader(vec3_origin, lightmode == 2, false);
2982 //if (r_glsl_deluxemapping.integer)
2983 // permutation_deluxemapping = R_SetupSurfaceShader(vec3_origin, lightmode == 2, true);
2984 R_Mesh_TexCoordPointer(0, 2, rsurface_model->surfmesh.data_texcoordtexture2f);
2985 R_Mesh_TexCoordPointer(4, 2, rsurface_model->surfmesh.data_texcoordlightmap2f);
2986 GL_AlphaTest((rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2988 if (!r_glsl_permutation)
2990 RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist);
2991 R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
2992 R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
2993 R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
2994 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2996 R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
2997 if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2998 R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
2999 R_Mesh_ColorPointer(NULL);
3001 else if (rsurface_lightmaptexture)
3003 R_Mesh_TexBind(7, R_GetTexture(rsurface_lightmaptexture));
3004 if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
3005 R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture));
3006 R_Mesh_ColorPointer(NULL);
3010 R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
3011 if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
3012 R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
3013 R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f);
3015 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
3018 static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **texturesurfacelist)
3020 // OpenGL 1.3 path - anything not completely ancient
3021 int texturesurfaceindex;
3023 qboolean applycolor;
3027 const texturelayer_t *layer;
3029 // FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
3030 lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
3031 if (rsurface_mode != RSURFMODE_MULTIPASS)
3032 rsurface_mode = RSURFMODE_MULTIPASS;
3033 RSurf_PrepareVerticesForBatch(true, false, texturenumsurfaces, texturesurfacelist);
3034 for (layerindex = 0, layer = rsurface_texture->currentlayers;layerindex < rsurface_texture->currentnumlayers;layerindex++, layer++)
3037 int layertexrgbscale;
3038 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
3040 if (layerindex == 0)
3044 GL_AlphaTest(false);
3045 qglDepthFunc(GL_EQUAL);CHECKGLERROR
3048 GL_DepthMask(layer->depthmask);
3049 GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
3050 if ((layer->color[0] > 2 || layer->color[1] > 2 || layer->color[2] > 2) && (gl_combine.integer || layer->depthmask))
3052 layertexrgbscale = 4;
3053 VectorScale(layer->color, 0.25f, layercolor);
3055 else if ((layer->color[0] > 1 || layer->color[1] > 1 || layer->color[2] > 1) && (gl_combine.integer || layer->depthmask))
3057 layertexrgbscale = 2;
3058 VectorScale(layer->color, 0.5f, layercolor);
3062 layertexrgbscale = 1;
3063 VectorScale(layer->color, 1.0f, layercolor);
3065 layercolor[3] = layer->color[3];
3066 applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
3067 R_Mesh_ColorPointer(NULL);
3068 applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
3069 switch (layer->type)
3071 case TEXTURELAYERTYPE_LITTEXTURE:
3072 memset(&m, 0, sizeof(m));
3073 if (lightmode >= 1 || !rsurface_lightmaptexture)
3074 m.tex[0] = R_GetTexture(r_texture_white);
3076 m.tex[0] = R_GetTexture(rsurface_lightmaptexture);
3077 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
3078 m.tex[1] = R_GetTexture(layer->texture);
3079 m.texmatrix[1] = layer->texmatrix;
3080 m.texrgbscale[1] = layertexrgbscale;
3081 m.pointer_texcoord[1] = rsurface_model->surfmesh.data_texcoordtexture2f;
3082 R_Mesh_TextureState(&m);
3083 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], lightmode, applycolor, applyfog);
3085 case TEXTURELAYERTYPE_TEXTURE:
3086 memset(&m, 0, sizeof(m));
3087 m.tex[0] = R_GetTexture(layer->texture);
3088 m.texmatrix[0] = layer->texmatrix;
3089 m.texrgbscale[0] = layertexrgbscale;
3090 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3091 R_Mesh_TextureState(&m);
3092 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
3094 case TEXTURELAYERTYPE_FOG:
3095 memset(&m, 0, sizeof(m));
3096 m.texrgbscale[0] = layertexrgbscale;
3099 m.tex[0] = R_GetTexture(layer->texture);
3100 m.texmatrix[0] = layer->texmatrix;
3101 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3103 R_Mesh_TextureState(&m);
3104 // generate a color array for the fog pass
3105 R_Mesh_ColorPointer(rsurface_array_color4f);
3106 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3110 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3111 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)
3113 f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
3114 c[0] = layercolor[0];
3115 c[1] = layercolor[1];
3116 c[2] = layercolor[2];
3117 c[3] = f * layercolor[3];
3120 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
3123 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
3125 GL_LockArrays(0, 0);
3128 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
3130 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
3131 GL_AlphaTest(false);
3135 static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **texturesurfacelist)
3137 // OpenGL 1.1 - crusty old voodoo path
3138 int texturesurfaceindex;
3143 const texturelayer_t *layer;
3145 // FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
3146 lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
3147 if (rsurface_mode != RSURFMODE_MULTIPASS)
3148 rsurface_mode = RSURFMODE_MULTIPASS;
3149 RSurf_PrepareVerticesForBatch(true, false, texturenumsurfaces, texturesurfacelist);
3150 for (layerindex = 0, layer = rsurface_texture->currentlayers;layerindex < rsurface_texture->currentnumlayers;layerindex++, layer++)
3152 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
3154 if (layerindex == 0)
3158 GL_AlphaTest(false);
3159 qglDepthFunc(GL_EQUAL);CHECKGLERROR
3162 GL_DepthMask(layer->depthmask);
3163 GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
3164 R_Mesh_ColorPointer(NULL);
3165 applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
3166 switch (layer->type)
3168 case TEXTURELAYERTYPE_LITTEXTURE:
3169 if (layer->blendfunc1 == GL_ONE && layer->blendfunc2 == GL_ZERO)
3171 // two-pass lit texture with 2x rgbscale
3172 // first the lightmap pass
3173 memset(&m, 0, sizeof(m));
3174 if (lightmode >= 1 || !rsurface_lightmaptexture)
3175 m.tex[0] = R_GetTexture(r_texture_white);
3177 m.tex[0] = R_GetTexture(rsurface_lightmaptexture);
3178 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
3179 R_Mesh_TextureState(&m);
3180 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, 1, 1, 1, 1, lightmode, false, false);
3181 GL_LockArrays(0, 0);
3182 // then apply the texture to it
3183 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
3184 memset(&m, 0, sizeof(m));
3185 m.tex[0] = R_GetTexture(layer->texture);
3186 m.texmatrix[0] = layer->texmatrix;
3187 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3188 R_Mesh_TextureState(&m);
3189 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, layer->color[0] * 0.5f, layer->color[1] * 0.5f, layer->color[2] * 0.5f, layer->color[3], 0, layer->color[0] != 2 || layer->color[1] != 2 || layer->color[2] != 2 || layer->color[3] != 1, false);
3193 // single pass vertex-lighting-only texture with 1x rgbscale and transparency support
3194 memset(&m, 0, sizeof(m));
3195 m.tex[0] = R_GetTexture(layer->texture);
3196 m.texmatrix[0] = layer->texmatrix;
3197 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3198 R_Mesh_TextureState(&m);
3199 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, layer->color[0], layer->color[1], layer->color[2], layer->color[3], lightmode == 2 ? 2 : 1, layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
3202 case TEXTURELAYERTYPE_TEXTURE:
3203 // singletexture unlit texture with transparency support
3204 memset(&m, 0, sizeof(m));
3205 m.tex[0] = R_GetTexture(layer->texture);
3206 m.texmatrix[0] = layer->texmatrix;
3207 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3208 R_Mesh_TextureState(&m);
3209 RSurf_DrawBatch_Lightmap(texturenumsurfaces, texturesurfacelist, layer->color[0], layer->color[1], layer->color[2], layer->color[3], 0, layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
3211 case TEXTURELAYERTYPE_FOG:
3212 // singletexture fogging
3213 R_Mesh_ColorPointer(rsurface_array_color4f);
3216 memset(&m, 0, sizeof(m));
3217 m.tex[0] = R_GetTexture(layer->texture);
3218 m.texmatrix[0] = layer->texmatrix;
3219 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3220 R_Mesh_TextureState(&m);
3223 R_Mesh_ResetTextureState();
3224 // generate a color array for the fog pass
3225 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3229 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3230 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)
3232 f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
3233 c[0] = layer->color[0];
3234 c[1] = layer->color[1];
3235 c[2] = layer->color[2];
3236 c[3] = f * layer->color[3];
3239 RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
3242 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
3244 GL_LockArrays(0, 0);
3247 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
3249 qglDepthFunc(GL_LEQUAL);CHECKGLERROR
3250 GL_AlphaTest(false);
3254 static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfacelist)
3256 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_NODRAW)
3258 r_shadow_rtlight = NULL;
3259 renderstats.entities_surfaces += texturenumsurfaces;
3261 GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
3262 if ((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE))
3264 qglDisable(GL_CULL_FACE);CHECKGLERROR
3266 if (r_showsurfaces.integer)
3267 R_DrawTextureSurfaceList_ShowSurfaces(texturenumsurfaces, texturesurfacelist);
3268 else if (rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY)
3269 R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
3270 else if (rsurface_texture->currentnumlayers)
3272 if (r_glsl.integer && gl_support_fragment_shader)
3273 R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist);
3274 else if (gl_combine.integer && r_textureunits.integer >= 2)
3275 R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist);
3277 R_DrawTextureSurfaceList_GL11(texturenumsurfaces, texturesurfacelist);
3280 GL_LockArrays(0, 0);
3281 if ((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE))
3283 qglEnable(GL_CULL_FACE);CHECKGLERROR
3287 #define BATCHSIZE 256
3288 static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
3290 int surfacelistindex;
3293 msurface_t *texturesurfacelist[BATCHSIZE];
3294 // if the model is static it doesn't matter what value we give for
3295 // wantnormals and wanttangents, so this logic uses only rules applicable
3296 // to a model, knowing that they are meaningless otherwise
3297 if ((ent->effects & EF_FULLBRIGHT) || r_showsurfaces.integer || VectorLength2(ent->modellight_diffuse) < (1.0f / 256.0f))
3298 RSurf_ActiveEntity(ent, false, false);
3300 RSurf_ActiveEntity(ent, true, r_glsl.integer && gl_support_fragment_shader);
3303 for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
3305 msurface_t *surface = ent->model->data_surfaces + surfacelist[surfacelistindex];
3307 if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
3310 R_DrawTextureSurfaceList(batchcount, texturesurfacelist);
3312 t = surface->texture;
3313 rsurface_lightmaptexture = surface->lightmaptexture;
3314 R_UpdateTextureInfo(ent, t);
3315 rsurface_texture = t->currentframe;
3317 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY)
3318 continue; // transparent sky is too difficult
3320 texturesurfacelist[batchcount++] = surface;
3323 R_DrawTextureSurfaceList(batchcount, texturesurfacelist);
3327 void R_QueueTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfacelist)
3329 int texturesurfaceindex;
3330 vec3_t tempcenter, center;
3331 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_BLENDED)
3333 // drawing sky transparently would be too difficult
3334 if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY))
3336 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3338 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3339 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
3340 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
3341 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
3342 Matrix4x4_Transform(&rsurface_entity->matrix, tempcenter, center);
3343 R_MeshQueue_AddTransparent(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, R_DrawSurface_TransparentCallback, rsurface_entity, surface - rsurface_model->data_surfaces, r_shadow_rtlight);
3348 R_DrawTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
3351 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
3352 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
3354 int i, j, f, flagsmask;
3355 int counttriangles = 0;
3357 model_t *model = ent->model;
3358 const int maxsurfacelist = 1024;
3359 int numsurfacelist = 0;
3360 msurface_t *surfacelist[1024];
3364 // if the model is static it doesn't matter what value we give for
3365 // wantnormals and wanttangents, so this logic uses only rules applicable
3366 // to a model, knowing that they are meaningless otherwise
3367 if ((ent->effects & EF_FULLBRIGHT) || r_showsurfaces.integer || VectorLength2(ent->modellight_diffuse) < (1.0f / 256.0f))
3368 RSurf_ActiveEntity(ent, false, false);
3370 RSurf_ActiveEntity(ent, true, r_glsl.integer && gl_support_fragment_shader);
3372 // update light styles
3373 if (!skysurfaces && model->brushq1.light_styleupdatechains)
3375 msurface_t *surface, **surfacechain;
3376 for (i = 0;i < model->brushq1.light_styles;i++)
3378 if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
3380 model->brushq1.light_stylevalue[i] = r_refdef.lightstylevalue[model->brushq1.light_style[i]];
3381 if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
3382 for (;(surface = *surfacechain);surfacechain++)
3383 surface->cached_dlight = true;
3388 R_UpdateAllTextureInfo(ent);
3389 flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
3392 rsurface_lightmaptexture = NULL;
3393 rsurface_texture = NULL;
3395 if (ent == r_refdef.worldentity)
3397 msurface_t *surface;
3398 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3400 if (!r_worldsurfacevisible[j])
3402 if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
3406 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3409 t = surface->texture;
3410 rsurface_lightmaptexture = surface->lightmaptexture;
3411 rsurface_texture = t->currentframe;
3412 f = rsurface_texture->currentmaterialflags & flagsmask;
3414 if (f && surface->num_triangles)
3416 // if lightmap parameters changed, rebuild lightmap texture
3417 if (surface->cached_dlight)
3418 R_BuildLightMap(ent, surface);
3419 // add face to draw list
3420 surfacelist[numsurfacelist++] = surface;
3421 counttriangles += surface->num_triangles;
3422 if (numsurfacelist >= maxsurfacelist)
3424 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3432 msurface_t *surface;
3433 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3435 if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
3439 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3442 t = surface->texture;
3443 rsurface_lightmaptexture = surface->lightmaptexture;
3444 rsurface_texture = t->currentframe;
3445 f = rsurface_texture->currentmaterialflags & flagsmask;
3447 if (f && surface->num_triangles)
3449 // if lightmap parameters changed, rebuild lightmap texture
3450 if (surface->cached_dlight)
3451 R_BuildLightMap(ent, surface);
3452 // add face to draw list
3453 surfacelist[numsurfacelist++] = surface;
3454 counttriangles += surface->num_triangles;
3455 if (numsurfacelist >= maxsurfacelist)
3457 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3464 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3465 renderstats.entities_triangles += counttriangles;
3468 if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces)
3471 const msurface_t *surface;
3474 R_Mesh_Matrix(&ent->matrix);
3475 R_Mesh_ColorPointer(NULL);
3476 R_Mesh_ResetTextureState();
3477 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
3478 GL_DepthMask(false);
3479 GL_DepthTest(!r_showdisabledepthtest.integer);
3480 qglPolygonOffset(r_polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_polygonoffset + r_showcollisionbrushes_polygonoffset.value);CHECKGLERROR
3481 for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
3482 if (brush->colbrushf && brush->colbrushf->numtriangles)
3483 R_DrawCollisionBrush(brush->colbrushf);
3484 for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
3485 if (surface->num_collisiontriangles)
3486 R_DrawCollisionSurface(ent, surface);
3487 qglPolygonOffset(r_polygonfactor, r_polygonoffset);CHECKGLERROR
3490 if (r_showtris.integer || r_shownormals.integer)
3493 msurface_t *surface;
3494 const int *elements;
3499 if (r_showdisabledepthtest.integer)
3501 qglDepthFunc(GL_ALWAYS);CHECKGLERROR
3503 GL_BlendFunc(GL_ONE, GL_ZERO);
3504 R_Mesh_ColorPointer(NULL);
3505 R_Mesh_ResetTextureState();
3506 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3508 if (ent == r_refdef.worldentity && !r_worldsurfacevisible[j])
3510 rsurface_texture = surface->texture->currentframe;
3511 if ((rsurface_texture->currentmaterialflags & flagsmask) && surface->num_triangles)
3513 RSurf_PrepareVerticesForBatch(true, true, 1, &surface);
3514 if (r_showtris.integer)
3516 if (!rsurface_texture->currentlayers->depthmask)
3517 GL_Color(r_showtris.value, 0, 0, 1);
3518 else if (ent == r_refdef.worldentity)
3519 GL_Color(r_showtris.value, r_showtris.value, r_showtris.value, 1);
3521 GL_Color(0, r_showtris.value, 0, 1);
3522 elements = (ent->model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);
3525 for (k = 0;k < surface->num_triangles;k++, elements += 3)
3527 qglArrayElement(elements[0]);qglArrayElement(elements[1]);
3528 qglArrayElement(elements[1]);qglArrayElement(elements[2]);
3529 qglArrayElement(elements[2]);qglArrayElement(elements[0]);
3534 if (r_shownormals.integer)
3536 GL_Color(r_shownormals.value, 0, 0, 1);
3538 for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3540 VectorCopy(rsurface_vertex3f + l * 3, v);
3541 qglVertex3f(v[0], v[1], v[2]);
3542 VectorMA(v, 8, rsurface_svector3f + l * 3, v);
3543 qglVertex3f(v[0], v[1], v[2]);
3547 GL_Color(0, 0, r_shownormals.value, 1);
3549 for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3551 VectorCopy(rsurface_vertex3f + l * 3, v);
3552 qglVertex3f(v[0], v[1], v[2]);
3553 VectorMA(v, 8, rsurface_tvector3f + l * 3, v);
3554 qglVertex3f(v[0], v[1], v[2]);
3558 GL_Color(0, r_shownormals.value, 0, 1);
3560 for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3562 VectorCopy(rsurface_vertex3f + l * 3, v);
3563 qglVertex3f(v[0], v[1], v[2]);
3564 VectorMA(v, 8, rsurface_normal3f + l * 3, v);
3565 qglVertex3f(v[0], v[1], v[2]);
3572 rsurface_texture = NULL;
3573 if (r_showdisabledepthtest.integer)
3575 qglDepthFunc(GL_LEQUAL);CHECKGLERROR