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
126 rtexture_t *r_bloom_texture_screen;
127 rtexture_t *r_bloom_texture_bloom;
128 rtexture_t *r_texture_blanknormalmap;
129 rtexture_t *r_texture_white;
130 rtexture_t *r_texture_black;
131 rtexture_t *r_texture_notexture;
132 rtexture_t *r_texture_whitecube;
133 rtexture_t *r_texture_normalizationcube;
134 rtexture_t *r_texture_fogattenuation;
135 //rtexture_t *r_texture_fogintensity;
137 // information about each possible shader permutation
138 r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_COUNT];
139 // currently selected permutation
140 r_glsl_permutation_t *r_glsl_permutation;
142 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
145 for (i = 0;i < verts;i++)
156 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
159 for (i = 0;i < verts;i++)
174 vec_t fogtabledistmultiplier;
175 float fogtable[FOGTABLEWIDTH];
176 float fog_density, fog_red, fog_green, fog_blue;
178 qboolean oldgl_fogenable;
179 void R_UpdateFog(void)
181 if (gamemode == GAME_NEHAHRA)
183 if (gl_fogenable.integer)
185 oldgl_fogenable = true;
186 fog_density = gl_fogdensity.value;
187 fog_red = gl_fogred.value;
188 fog_green = gl_foggreen.value;
189 fog_blue = gl_fogblue.value;
191 else if (oldgl_fogenable)
193 oldgl_fogenable = false;
202 fogcolor[0] = fog_red = bound(0.0f, fog_red , 1.0f);
203 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
204 fogcolor[2] = fog_blue = bound(0.0f, fog_blue , 1.0f);
209 fogdensity = -4000.0f / (fog_density * fog_density);
210 // this is the point where the fog reaches 0.9986 alpha, which we
211 // consider a good enough cutoff point for the texture
212 // (0.9986 * 256 == 255.6)
213 fogrange = 400 / fog_density;
214 fograngerecip = 1.0f / fogrange;
215 fogtabledistmultiplier = FOGTABLEWIDTH * fograngerecip;
216 // fog color was already set
222 // FIXME: move this to client?
225 if (gamemode == GAME_NEHAHRA)
227 Cvar_Set("gl_fogenable", "0");
228 Cvar_Set("gl_fogdensity", "0.2");
229 Cvar_Set("gl_fogred", "0.3");
230 Cvar_Set("gl_foggreen", "0.3");
231 Cvar_Set("gl_fogblue", "0.3");
233 fog_density = fog_red = fog_green = fog_blue = 0.0f;
236 // FIXME: move this to client?
237 void FOG_registercvars(void)
242 if (gamemode == GAME_NEHAHRA)
244 Cvar_RegisterVariable (&gl_fogenable);
245 Cvar_RegisterVariable (&gl_fogdensity);
246 Cvar_RegisterVariable (&gl_fogred);
247 Cvar_RegisterVariable (&gl_foggreen);
248 Cvar_RegisterVariable (&gl_fogblue);
249 Cvar_RegisterVariable (&gl_fogstart);
250 Cvar_RegisterVariable (&gl_fogend);
253 r = (-1.0/256.0) * (FOGTABLEWIDTH * FOGTABLEWIDTH);
254 for (x = 0;x < FOGTABLEWIDTH;x++)
256 alpha = exp(r / ((double)x*(double)x));
257 if (x == FOGTABLEWIDTH - 1)
259 fogtable[x] = bound(0, alpha, 1);
263 static void R_BuildBlankTextures(void)
265 unsigned char data[4];
266 data[0] = 128; // normal X
267 data[1] = 128; // normal Y
268 data[2] = 255; // normal Z
269 data[3] = 128; // height
270 r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
275 r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
280 r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
283 static void R_BuildNoTexture(void)
286 unsigned char pix[16][16][4];
287 // this makes a light grey/dark grey checkerboard texture
288 for (y = 0;y < 16;y++)
290 for (x = 0;x < 16;x++)
292 if ((y < 8) ^ (x < 8))
308 r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL);
311 static void R_BuildWhiteCube(void)
313 unsigned char data[6*1*1*4];
314 data[ 0] = 255;data[ 1] = 255;data[ 2] = 255;data[ 3] = 255;
315 data[ 4] = 255;data[ 5] = 255;data[ 6] = 255;data[ 7] = 255;
316 data[ 8] = 255;data[ 9] = 255;data[10] = 255;data[11] = 255;
317 data[12] = 255;data[13] = 255;data[14] = 255;data[15] = 255;
318 data[16] = 255;data[17] = 255;data[18] = 255;data[19] = 255;
319 data[20] = 255;data[21] = 255;data[22] = 255;data[23] = 255;
320 r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
323 static void R_BuildNormalizationCube(void)
327 vec_t s, t, intensity;
329 unsigned char data[6][NORMSIZE][NORMSIZE][4];
330 for (side = 0;side < 6;side++)
332 for (y = 0;y < NORMSIZE;y++)
334 for (x = 0;x < NORMSIZE;x++)
336 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
337 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
372 intensity = 127.0f / sqrt(DotProduct(v, v));
373 data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[0]);
374 data[side][y][x][1] = (unsigned char)(128.0f + intensity * v[1]);
375 data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[2]);
376 data[side][y][x][3] = 255;
380 r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
383 static void R_BuildFogTexture(void)
388 unsigned char data1[FOGWIDTH][4];
389 //unsigned char data2[FOGWIDTH][4];
390 r = (-1.0/256.0) * (FOGWIDTH * FOGWIDTH);
391 for (x = 0;x < FOGWIDTH;x++)
393 alpha = exp(r / ((double)x*(double)x));
394 if (x == FOGWIDTH - 1)
396 b = (int)(256.0 * alpha);
397 b = bound(0, b, 255);
398 data1[x][0] = 255 - b;
399 data1[x][1] = 255 - b;
400 data1[x][2] = 255 - b;
407 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
408 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
411 static const char *builtinshaderstring =
412 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
413 "// written by Forest 'LordHavoc' Hale\n"
415 "// common definitions between vertex shader and fragment shader:\n"
417 "varying vec2 TexCoord;\n"
418 "varying vec2 TexCoordLightmap;\n"
420 "varying vec3 CubeVector;\n"
421 "varying vec3 LightVector;\n"
422 "varying vec3 EyeVector;\n"
424 "varying vec3 EyeVectorModelSpace;\n"
427 "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
428 "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
429 "varying vec3 VectorR; // direction of R texcoord (surface normal)\n"
434 "// vertex shader specific:\n"
435 "#ifdef VERTEX_SHADER\n"
437 "uniform vec3 LightPosition;\n"
438 "uniform vec3 EyePosition;\n"
439 "uniform vec3 LightDir;\n"
441 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3)\n"
445 " gl_FrontColor = gl_Color;\n"
446 " // copy the surface texcoord\n"
447 " TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n"
448 "#if !defined(MODE_LIGHTSOURCE) && !defined(MODE_LIGHTDIRECTION)\n"
449 " TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
452 "#ifdef MODE_LIGHTSOURCE\n"
453 " // transform vertex position into light attenuation/cubemap space\n"
454 " // (-1 to +1 across the light box)\n"
455 " CubeVector = vec3(gl_TextureMatrix[3] * gl_Vertex);\n"
457 " // transform unnormalized light direction into tangent space\n"
458 " // (we use unnormalized to ensure that it interpolates correctly and then\n"
459 " // normalize it per pixel)\n"
460 " vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
461 " LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
462 " LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
463 " LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
466 "#ifdef MODE_LIGHTDIRECTION\n"
467 " LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
468 " LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
469 " LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
472 " // transform unnormalized eye direction into tangent space\n"
474 " vec3 EyeVectorModelSpace;\n"
476 " EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
477 " EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
478 " EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
479 " EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
481 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
482 " VectorS = gl_MultiTexCoord1.xyz;\n"
483 " VectorT = gl_MultiTexCoord2.xyz;\n"
484 " VectorR = gl_MultiTexCoord3.xyz;\n"
487 " // transform vertex to camera space, using ftransform to match non-VS\n"
489 " gl_Position = ftransform();\n"
492 "#endif // VERTEX_SHADER\n"
497 "// fragment shader specific:\n"
498 "#ifdef FRAGMENT_SHADER\n"
500 "uniform sampler2D Texture_Normal;\n"
501 "uniform sampler2D Texture_Color;\n"
502 "uniform sampler2D Texture_Gloss;\n"
503 "uniform samplerCube Texture_Cube;\n"
504 "uniform sampler2D Texture_FogMask;\n"
505 "uniform sampler2D Texture_Pants;\n"
506 "uniform sampler2D Texture_Shirt;\n"
507 "uniform sampler2D Texture_Lightmap;\n"
508 "uniform sampler2D Texture_Deluxemap;\n"
509 "uniform sampler2D Texture_Glow;\n"
511 "uniform vec3 LightColor;\n"
512 "uniform vec3 AmbientColor;\n"
513 "uniform vec3 DiffuseColor;\n"
514 "uniform vec3 SpecularColor;\n"
515 "uniform vec3 Color_Pants;\n"
516 "uniform vec3 Color_Shirt;\n"
517 "uniform vec3 FogColor;\n"
519 "uniform float OffsetMapping_Scale;\n"
520 "uniform float OffsetMapping_Bias;\n"
521 "uniform float FogRangeRecip;\n"
523 "uniform float AmbientScale;\n"
524 "uniform float DiffuseScale;\n"
525 "uniform float SpecularScale;\n"
526 "uniform float SpecularPower;\n"
530 " // apply offsetmapping\n"
531 "#ifdef USEOFFSETMAPPING\n"
532 " vec2 TexCoordOffset = TexCoord;\n"
533 "#define TexCoord TexCoordOffset\n"
535 " vec3 eyedir = vec3(normalize(EyeVector));\n"
536 " float depthbias = 1.0 - eyedir.z; // should this be a -?\n"
537 " depthbias = 1.0 - depthbias * depthbias;\n"
539 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
540 " // 14 sample relief mapping: linear search and then binary search\n"
541 " vec3 OffsetVector = vec3(EyeVector.xy * (1.0 / EyeVector.z) * depthbias * OffsetMapping_Scale * vec2(-0.1, 0.1), -0.1);\n"
542 " vec3 RT = vec3(TexCoord - OffsetVector.xy * 10.0, 1.0) + OffsetVector;\n"
543 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
544 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
545 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
546 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
547 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
548 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
549 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
550 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;\n"
551 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
552 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
553 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
554 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
555 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
556 " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n"
557 " TexCoord = RT.xy;\n"
559 " // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
560 " vec2 OffsetVector = vec2((EyeVector.xy * (1.0 / EyeVector.z) * depthbias) * OffsetMapping_Scale * vec2(-0.333, 0.333));\n"
561 " //TexCoord += OffsetVector * 3.0;\n"
562 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
563 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
564 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
568 " // combine the diffuse textures (base, pants, shirt)\n"
569 " vec4 color = vec4(texture2D(Texture_Color, TexCoord));\n"
570 "#ifdef USECOLORMAPPING\n"
571 " color.rgb += vec3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + vec3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
577 "#ifdef MODE_LIGHTSOURCE\n"
580 " // get the surface normal and light normal\n"
581 " vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
582 " vec3 diffusenormal = vec3(normalize(LightVector));\n"
584 " // calculate directional shading\n"
585 " color.rgb *= (AmbientScale + DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
586 "#ifdef USESPECULAR\n"
587 " vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
588 " color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
591 "#ifdef USECUBEFILTER\n"
592 " // apply light cubemap filter\n"
593 " //color.rgb *= normalize(CubeVector) * 0.5 + 0.5;//vec3(textureCube(Texture_Cube, CubeVector));\n"
594 " color.rgb *= vec3(textureCube(Texture_Cube, CubeVector));\n"
597 " // apply light color\n"
598 " color.rgb *= LightColor;\n"
600 " // apply attenuation\n"
602 " // the attenuation is (1-(x*x+y*y+z*z)) which gives a large bright\n"
603 " // center and sharp falloff at the edge, this is about the most efficient\n"
604 " // we can get away with as far as providing illumination.\n"
606 " // pow(1-(x*x+y*y+z*z), 4) is far more realistic but needs large lights to\n"
607 " // provide significant illumination, large = slow = pain.\n"
608 " color.rgb *= max(1.0 - dot(CubeVector, CubeVector), 0.0);\n"
613 "#elif defined(MODE_LIGHTDIRECTION)\n"
614 " // directional model lighting\n"
616 " // get the surface normal and light normal\n"
617 " vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
618 " vec3 diffusenormal = vec3(normalize(LightVector));\n"
620 " // calculate directional shading\n"
621 " color.rgb *= AmbientColor + DiffuseColor * max(dot(surfacenormal, diffusenormal), 0.0);\n"
622 "#ifdef USESPECULAR\n"
623 " vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
624 " color.rgb += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
630 "#elif defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE)\n"
631 " // deluxemap lightmapping using light vectors in modelspace (evil q3map2)\n"
633 " // get the surface normal and light normal\n"
634 " vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
635 " vec3 diffusenormal_modelspace = vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5;\n"
636 " vec3 diffusenormal = normalize(vec3(dot(diffusenormal_modelspace, VectorS), dot(diffusenormal_modelspace, VectorT), dot(diffusenormal_modelspace, VectorR)));\n"
638 " // calculate directional shading\n"
639 " vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
640 "#ifdef USESPECULAR\n"
641 " vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
642 " tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
645 " // apply lightmap color\n"
646 " color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n"
651 "#elif defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
652 " // deluxemap lightmapping using light vectors in tangentspace\n"
654 " // get the surface normal and light normal\n"
655 " vec3 surfacenormal = normalize(vec3(texture2D(Texture_Normal, TexCoord)) - 0.5);\n"
656 " vec3 diffusenormal = normalize(vec3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - 0.5);\n"
658 " // calculate directional shading\n"
659 " vec3 tempcolor = color.rgb * (DiffuseScale * max(dot(surfacenormal, diffusenormal), 0.0));\n"
660 "#ifdef USESPECULAR\n"
661 " vec3 specularnormal = vec3(normalize(diffusenormal + vec3(normalize(EyeVector))));\n"
662 " tempcolor += vec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(max(dot(surfacenormal, specularnormal), 0.0), SpecularPower);\n"
665 " // apply lightmap color\n"
666 " color.rgb = tempcolor * vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) + color.rgb * vec3(AmbientScale);\n"
671 "#else // MODE none (lightmap)\n"
672 " // apply lightmap color\n"
673 " color.rgb *= vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + vec3(AmbientScale);\n"
676 " color *= gl_Color;\n"
679 " color.rgb += vec3(texture2D(Texture_Glow, TexCoord));\n"
684 " float fog = texture2D(Texture_FogMask, vec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0)).x;\n"
685 " color.rgb = color.rgb * fog + FogColor * (1.0 - fog);\n"
688 " gl_FragColor = color;\n"
691 "#endif // FRAGMENT_SHADER\n"
694 void R_GLSL_CompilePermutation(int permutation)
696 r_glsl_permutation_t *p = r_glsl_permutations + permutation;
697 int vertstrings_count;
698 int fragstrings_count;
700 const char *vertstrings_list[SHADERPERMUTATION_COUNT+1];
701 const char *fragstrings_list[SHADERPERMUTATION_COUNT+1];
702 char permutationname[256];
706 vertstrings_list[0] = "#define VERTEX_SHADER\n";
707 fragstrings_list[0] = "#define FRAGMENT_SHADER\n";
708 vertstrings_count = 1;
709 fragstrings_count = 1;
710 permutationname[0] = 0;
711 if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
713 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTSOURCE\n";
714 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTSOURCE\n";
715 strlcat(permutationname, " lightsource", sizeof(permutationname));
717 if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE)
719 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n";
720 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n";
721 strlcat(permutationname, " lightdirectionmap_modelspace", sizeof(permutationname));
723 if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)
725 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n";
726 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n";
727 strlcat(permutationname, " lightdirectionmap_tangentspace", sizeof(permutationname));
729 if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
731 vertstrings_list[vertstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
732 fragstrings_list[fragstrings_count++] = "#define MODE_LIGHTDIRECTION\n";
733 strlcat(permutationname, " lightdirection", sizeof(permutationname));
735 if (permutation & SHADERPERMUTATION_GLOW)
737 vertstrings_list[vertstrings_count++] = "#define USEGLOW\n";
738 fragstrings_list[fragstrings_count++] = "#define USEGLOW\n";
739 strlcat(permutationname, " glow", sizeof(permutationname));
741 if (permutation & SHADERPERMUTATION_COLORMAPPING)
743 vertstrings_list[vertstrings_count++] = "#define USECOLORMAPPING\n";
744 fragstrings_list[fragstrings_count++] = "#define USECOLORMAPPING\n";
745 strlcat(permutationname, " colormapping", sizeof(permutationname));
747 if (permutation & SHADERPERMUTATION_SPECULAR)
749 vertstrings_list[vertstrings_count++] = "#define USESPECULAR\n";
750 fragstrings_list[fragstrings_count++] = "#define USESPECULAR\n";
751 strlcat(permutationname, " specular", sizeof(permutationname));
753 if (permutation & SHADERPERMUTATION_FOG)
755 vertstrings_list[vertstrings_count++] = "#define USEFOG\n";
756 fragstrings_list[fragstrings_count++] = "#define USEFOG\n";
757 strlcat(permutationname, " fog", sizeof(permutationname));
759 if (permutation & SHADERPERMUTATION_CUBEFILTER)
761 vertstrings_list[vertstrings_count++] = "#define USECUBEFILTER\n";
762 fragstrings_list[fragstrings_count++] = "#define USECUBEFILTER\n";
763 strlcat(permutationname, " cubefilter", sizeof(permutationname));
765 if (permutation & SHADERPERMUTATION_OFFSETMAPPING)
767 vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING\n";
768 fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING\n";
769 strlcat(permutationname, " offsetmapping", sizeof(permutationname));
771 if (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING)
773 vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n";
774 fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING_RELIEFMAPPING\n";
775 strlcat(permutationname, " OFFSETMAPPING_RELIEFMAPPING", sizeof(permutationname));
777 shaderstring = (char *)FS_LoadFile("glsl/default.glsl", r_main_mempool, false, NULL);
780 Con_DPrintf("GLSL shader text loaded from disk\n");
781 vertstrings_list[vertstrings_count++] = shaderstring;
782 fragstrings_list[fragstrings_count++] = shaderstring;
786 vertstrings_list[vertstrings_count++] = builtinshaderstring;
787 fragstrings_list[fragstrings_count++] = builtinshaderstring;
789 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list);
793 qglUseProgramObjectARB(p->program);
794 p->loc_Texture_Normal = qglGetUniformLocationARB(p->program, "Texture_Normal");
795 p->loc_Texture_Color = qglGetUniformLocationARB(p->program, "Texture_Color");
796 p->loc_Texture_Gloss = qglGetUniformLocationARB(p->program, "Texture_Gloss");
797 p->loc_Texture_Cube = qglGetUniformLocationARB(p->program, "Texture_Cube");
798 p->loc_Texture_FogMask = qglGetUniformLocationARB(p->program, "Texture_FogMask");
799 p->loc_Texture_Pants = qglGetUniformLocationARB(p->program, "Texture_Pants");
800 p->loc_Texture_Shirt = qglGetUniformLocationARB(p->program, "Texture_Shirt");
801 p->loc_Texture_Lightmap = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
802 p->loc_Texture_Deluxemap = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
803 p->loc_Texture_Glow = qglGetUniformLocationARB(p->program, "Texture_Glow");
804 p->loc_FogColor = qglGetUniformLocationARB(p->program, "FogColor");
805 p->loc_LightPosition = qglGetUniformLocationARB(p->program, "LightPosition");
806 p->loc_EyePosition = qglGetUniformLocationARB(p->program, "EyePosition");
807 p->loc_LightColor = qglGetUniformLocationARB(p->program, "LightColor");
808 p->loc_Color_Pants = qglGetUniformLocationARB(p->program, "Color_Pants");
809 p->loc_Color_Shirt = qglGetUniformLocationARB(p->program, "Color_Shirt");
810 p->loc_FogRangeRecip = qglGetUniformLocationARB(p->program, "FogRangeRecip");
811 p->loc_AmbientScale = qglGetUniformLocationARB(p->program, "AmbientScale");
812 p->loc_DiffuseScale = qglGetUniformLocationARB(p->program, "DiffuseScale");
813 p->loc_SpecularPower = qglGetUniformLocationARB(p->program, "SpecularPower");
814 p->loc_SpecularScale = qglGetUniformLocationARB(p->program, "SpecularScale");
815 p->loc_OffsetMapping_Scale = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
816 p->loc_AmbientColor = qglGetUniformLocationARB(p->program, "AmbientColor");
817 p->loc_DiffuseColor = qglGetUniformLocationARB(p->program, "DiffuseColor");
818 p->loc_SpecularColor = qglGetUniformLocationARB(p->program, "SpecularColor");
819 p->loc_LightDir = qglGetUniformLocationARB(p->program, "LightDir");
820 if (p->loc_Texture_Normal >= 0) qglUniform1iARB(p->loc_Texture_Normal, 0);
821 if (p->loc_Texture_Color >= 0) qglUniform1iARB(p->loc_Texture_Color, 1);
822 if (p->loc_Texture_Gloss >= 0) qglUniform1iARB(p->loc_Texture_Gloss, 2);
823 if (p->loc_Texture_Cube >= 0) qglUniform1iARB(p->loc_Texture_Cube, 3);
824 if (p->loc_Texture_FogMask >= 0) qglUniform1iARB(p->loc_Texture_FogMask, 4);
825 if (p->loc_Texture_Pants >= 0) qglUniform1iARB(p->loc_Texture_Pants, 5);
826 if (p->loc_Texture_Shirt >= 0) qglUniform1iARB(p->loc_Texture_Shirt, 6);
827 if (p->loc_Texture_Lightmap >= 0) qglUniform1iARB(p->loc_Texture_Lightmap, 7);
828 if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap, 8);
829 if (p->loc_Texture_Glow >= 0) qglUniform1iARB(p->loc_Texture_Glow, 9);
830 qglUseProgramObjectARB(0);
834 Con_Printf("permutation%s failed for shader %s, some features may not work properly!\n", permutationname, "glsl/default.glsl");
836 Mem_Free(shaderstring);
839 void R_GLSL_Restart_f(void)
842 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
843 if (r_glsl_permutations[i].program)
844 GL_Backend_FreeProgram(r_glsl_permutations[i].program);
845 memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
848 int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting)
850 // select a permutation of the lighting shader appropriate to this
851 // combination of texture, entity, light source, and fogging, only use the
852 // minimum features necessary to avoid wasting rendering time in the
853 // fragment shader on features that are not being used
855 float specularscale = rsurface_texture->specularscale;
856 r_glsl_permutation = NULL;
857 if (r_shadow_rtlight)
859 permutation |= SHADERPERMUTATION_MODE_LIGHTSOURCE;
860 specularscale *= r_shadow_rtlight->specularscale;
861 if (r_shadow_rtlight->currentcubemap != r_texture_whitecube)
862 permutation |= SHADERPERMUTATION_CUBEFILTER;
866 if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
869 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
872 if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && rsurface_lightmaptexture)
874 if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace)
875 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE;
877 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
879 else if (r_glsl_deluxemapping.integer >= 2) // fake mode
880 permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
883 if (rsurface_texture->skin.glow)
884 permutation |= SHADERPERMUTATION_GLOW;
886 if (specularscale > 0)
887 permutation |= SHADERPERMUTATION_SPECULAR;
889 permutation |= SHADERPERMUTATION_FOG;
890 if (rsurface_texture->colormapping)
891 permutation |= SHADERPERMUTATION_COLORMAPPING;
892 if (r_glsl_offsetmapping.integer)
894 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
895 if (r_glsl_offsetmapping_reliefmapping.integer)
896 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
898 if (!r_glsl_permutations[permutation].program)
900 if (!r_glsl_permutations[permutation].compiled)
901 R_GLSL_CompilePermutation(permutation);
902 if (!r_glsl_permutations[permutation].program)
904 // remove features until we find a valid permutation
906 for (i = SHADERPERMUTATION_COUNT-1;;i>>=1)
908 // reduce i more quickly whenever it would not remove any bits
912 if (!r_glsl_permutations[permutation].compiled)
913 R_GLSL_CompilePermutation(permutation);
914 if (r_glsl_permutations[permutation].program)
917 return 0; // utterly failed
921 r_glsl_permutation = r_glsl_permutations + permutation;
923 qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
924 R_Mesh_TexMatrix(0, &rsurface_texture->currenttexmatrix);
925 if (permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE)
927 if (r_glsl_permutation->loc_Texture_Cube >= 0 && r_shadow_rtlight) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap));
928 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, r_shadow_entitylightorigin[0], r_shadow_entitylightorigin[1], r_shadow_entitylightorigin[2]);
929 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
930 if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_shadow_rtlight->ambientscale);
931 if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_shadow_rtlight->diffusescale);
932 if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale);
934 else if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION)
936 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
938 if (r_glsl_permutation->loc_AmbientColor >= 0)
939 qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, 1, 1, 1);
940 if (r_glsl_permutation->loc_DiffuseColor >= 0)
941 qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, 0, 0, 0);
942 if (r_glsl_permutation->loc_SpecularColor >= 0)
943 qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, 0, 0, 0);
944 if (r_glsl_permutation->loc_LightDir >= 0)
945 qglUniform3fARB(r_glsl_permutation->loc_LightDir, 0, 0, -1);
949 if (r_glsl_permutation->loc_AmbientColor >= 0)
950 qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, rsurface_entity->modellight_ambient[0], rsurface_entity->modellight_ambient[1], rsurface_entity->modellight_ambient[2]);
951 if (r_glsl_permutation->loc_DiffuseColor >= 0)
952 qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, rsurface_entity->modellight_diffuse[0], rsurface_entity->modellight_diffuse[1], rsurface_entity->modellight_diffuse[2]);
953 if (r_glsl_permutation->loc_SpecularColor >= 0)
954 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);
955 if (r_glsl_permutation->loc_LightDir >= 0)
956 qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface_entity->modellight_lightdir[0], rsurface_entity->modellight_lightdir[1], rsurface_entity->modellight_lightdir[2]);
961 if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 2.0f / 128.0f);
962 if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_lightmapintensity * 2.0f);
963 if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_lightmapintensity * specularscale * 2.0f);
965 if (r_glsl_permutation->loc_Texture_Normal >= 0) R_Mesh_TexBind(0, R_GetTexture(rsurface_texture->skin.nmap));
966 if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(1, R_GetTexture(rsurface_texture->basetexture));
967 if (r_glsl_permutation->loc_Texture_Gloss >= 0) R_Mesh_TexBind(2, R_GetTexture(rsurface_texture->glosstexture));
968 //if (r_glsl_permutation->loc_Texture_Cube >= 0 && permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap));
969 if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
970 if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(5, R_GetTexture(rsurface_texture->skin.pants));
971 if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(6, R_GetTexture(rsurface_texture->skin.shirt));
972 //if (r_glsl_permutation->loc_Texture_Lightmap >= 0) R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
973 //if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
974 if (r_glsl_permutation->loc_Texture_Glow >= 0) R_Mesh_TexBind(9, R_GetTexture(rsurface_texture->skin.glow));
975 if (r_glsl_permutation->loc_FogColor >= 0)
977 // additive passes are only darkened by fog, not tinted
978 if (r_shadow_rtlight || (rsurface_texture->currentmaterialflags & MATERIALFLAG_ADD))
979 qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
981 qglUniform3fARB(r_glsl_permutation->loc_FogColor, fogcolor[0], fogcolor[1], fogcolor[2]);
983 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface_modelorg[0], rsurface_modelorg[1], rsurface_modelorg[2]);
984 if (r_glsl_permutation->loc_Color_Pants >= 0)
986 if (rsurface_texture->skin.pants)
987 qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, rsurface_entity->colormap_pantscolor[0], rsurface_entity->colormap_pantscolor[1], rsurface_entity->colormap_pantscolor[2]);
989 qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
991 if (r_glsl_permutation->loc_Color_Shirt >= 0)
993 if (rsurface_texture->skin.shirt)
994 qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, rsurface_entity->colormap_shirtcolor[0], rsurface_entity->colormap_shirtcolor[1], rsurface_entity->colormap_shirtcolor[2]);
996 qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
998 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, fograngerecip);
999 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface_texture->specularpower);
1000 if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
1005 void R_SwitchSurfaceShader(int permutation)
1007 if (r_glsl_permutation != r_glsl_permutations + permutation)
1009 r_glsl_permutation = r_glsl_permutations + permutation;
1011 qglUseProgramObjectARB(r_glsl_permutation->program);
1016 void gl_main_start(void)
1018 r_main_texturepool = R_AllocTexturePool();
1019 r_bloom_texture_screen = NULL;
1020 r_bloom_texture_bloom = NULL;
1021 R_BuildBlankTextures();
1023 if (gl_texturecubemap)
1026 R_BuildNormalizationCube();
1028 R_BuildFogTexture();
1029 memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
1032 void gl_main_shutdown(void)
1034 R_FreeTexturePool(&r_main_texturepool);
1035 r_bloom_texture_screen = NULL;
1036 r_bloom_texture_bloom = NULL;
1037 r_texture_blanknormalmap = NULL;
1038 r_texture_white = NULL;
1039 r_texture_black = NULL;
1040 r_texture_whitecube = NULL;
1041 r_texture_normalizationcube = NULL;
1045 extern void CL_ParseEntityLump(char *entitystring);
1046 void gl_main_newmap(void)
1048 // FIXME: move this code to client
1050 char *entities, entname[MAX_QPATH];
1054 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
1055 l = (int)strlen(entname) - 4;
1056 if (l >= 0 && !strcmp(entname + l, ".bsp"))
1058 strcpy(entname + l, ".ent");
1059 if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
1061 CL_ParseEntityLump(entities);
1066 if (cl.worldmodel->brush.entities)
1067 CL_ParseEntityLump(cl.worldmodel->brush.entities);
1071 void GL_Main_Init(void)
1073 r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
1075 Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed\n");
1076 FOG_registercvars(); // FIXME: move this fog stuff to client?
1077 Cvar_RegisterVariable(&r_nearclip);
1078 Cvar_RegisterVariable(&r_showsurfaces);
1079 Cvar_RegisterVariable(&r_showtris);
1080 Cvar_RegisterVariable(&r_shownormals);
1081 Cvar_RegisterVariable(&r_showlighting);
1082 Cvar_RegisterVariable(&r_showshadowvolumes);
1083 Cvar_RegisterVariable(&r_showcollisionbrushes);
1084 Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor);
1085 Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset);
1086 Cvar_RegisterVariable(&r_showdisabledepthtest);
1087 Cvar_RegisterVariable(&r_drawentities);
1088 Cvar_RegisterVariable(&r_drawviewmodel);
1089 Cvar_RegisterVariable(&r_speeds);
1090 Cvar_RegisterVariable(&r_fullbrights);
1091 Cvar_RegisterVariable(&r_wateralpha);
1092 Cvar_RegisterVariable(&r_dynamic);
1093 Cvar_RegisterVariable(&r_fullbright);
1094 Cvar_RegisterVariable(&r_q1bsp_skymasking);
1095 Cvar_RegisterVariable(&r_textureunits);
1096 Cvar_RegisterVariable(&r_glsl);
1097 Cvar_RegisterVariable(&r_glsl_offsetmapping);
1098 Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
1099 Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
1100 Cvar_RegisterVariable(&r_glsl_deluxemapping);
1101 Cvar_RegisterVariable(&r_lerpsprites);
1102 Cvar_RegisterVariable(&r_lerpmodels);
1103 Cvar_RegisterVariable(&r_waterscroll);
1104 Cvar_RegisterVariable(&r_bloom);
1105 Cvar_RegisterVariable(&r_bloom_intensity);
1106 Cvar_RegisterVariable(&r_bloom_blur);
1107 Cvar_RegisterVariable(&r_bloom_resolution);
1108 Cvar_RegisterVariable(&r_bloom_power);
1109 Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
1110 Cvar_RegisterVariable(&developer_texturelogging);
1111 Cvar_RegisterVariable(&gl_lightmaps);
1112 Cvar_RegisterVariable(&r_test);
1113 if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
1114 Cvar_SetValue("r_fullbrights", 0);
1115 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
1118 static vec3_t r_farclip_origin;
1119 static vec3_t r_farclip_direction;
1120 static vec_t r_farclip_directiondist;
1121 static vec_t r_farclip_meshfarclip;
1122 static int r_farclip_directionbit0;
1123 static int r_farclip_directionbit1;
1124 static int r_farclip_directionbit2;
1126 // enlarge farclip to accomodate box
1127 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
1130 d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
1131 + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
1132 + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
1133 if (r_farclip_meshfarclip < d)
1134 r_farclip_meshfarclip = d;
1137 // return farclip value
1138 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
1142 VectorCopy(origin, r_farclip_origin);
1143 VectorCopy(direction, r_farclip_direction);
1144 r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
1145 r_farclip_directionbit0 = r_farclip_direction[0] < 0;
1146 r_farclip_directionbit1 = r_farclip_direction[1] < 0;
1147 r_farclip_directionbit2 = r_farclip_direction[2] < 0;
1148 r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
1150 if (r_refdef.worldmodel)
1151 R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
1152 for (i = 0;i < r_refdef.numentities;i++)
1153 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
1155 return r_farclip_meshfarclip - r_farclip_directiondist;
1158 extern void R_Textures_Init(void);
1159 extern void GL_Draw_Init(void);
1160 extern void GL_Main_Init(void);
1161 extern void R_Shadow_Init(void);
1162 extern void R_Sky_Init(void);
1163 extern void GL_Surf_Init(void);
1164 extern void R_Crosshairs_Init(void);
1165 extern void R_Light_Init(void);
1166 extern void R_Particles_Init(void);
1167 extern void R_Explosion_Init(void);
1168 extern void gl_backend_init(void);
1169 extern void Sbar_Init(void);
1170 extern void R_LightningBeams_Init(void);
1171 extern void Mod_RenderInit(void);
1173 void Render_Init(void)
1183 R_Crosshairs_Init();
1188 R_LightningBeams_Init();
1197 extern char *ENGINE_EXTENSIONS;
1200 VID_CheckExtensions();
1202 // LordHavoc: report supported extensions
1203 Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions );
1205 // clear to black (loading plaque will be seen over this)
1206 qglClearColor(0,0,0,1);
1207 qglClear(GL_COLOR_BUFFER_BIT);
1210 int R_CullBox(const vec3_t mins, const vec3_t maxs)
1214 for (i = 0;i < 4;i++)
1221 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1225 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1229 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1233 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1237 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1241 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1245 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1249 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1257 //==================================================================================
1259 static void R_UpdateEntityLighting(entity_render_t *ent)
1261 vec3_t tempdiffusenormal;
1262 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));
1263 VectorClear(ent->modellight_diffuse);
1264 VectorClear(ent->modellight_lightdir);
1265 if ((ent->flags & RENDER_LIGHT) && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
1266 r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, ent->origin, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
1268 VectorSet(ent->modellight_ambient, 1, 1, 1);
1269 Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
1270 VectorNormalize(ent->modellight_lightdir);
1271 ent->modellight_ambient[0] *= ent->colormod[0] * r_lightmapintensity;
1272 ent->modellight_ambient[1] *= ent->colormod[1] * r_lightmapintensity;
1273 ent->modellight_ambient[2] *= ent->colormod[2] * r_lightmapintensity;
1274 ent->modellight_diffuse[0] *= ent->colormod[0] * r_lightmapintensity;
1275 ent->modellight_diffuse[1] *= ent->colormod[1] * r_lightmapintensity;
1276 ent->modellight_diffuse[2] *= ent->colormod[2] * r_lightmapintensity;
1279 static void R_MarkEntities (void)
1282 entity_render_t *ent;
1284 if (!r_drawentities.integer)
1287 r_refdef.worldentity->visframe = r_framecount;
1288 renderimask = envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL);
1289 if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
1291 // worldmodel can check visibility
1292 for (i = 0;i < r_refdef.numentities;i++)
1294 ent = r_refdef.entities[i];
1295 // some of the renderer still relies on origin...
1296 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1297 // some of the renderer still relies on scale...
1298 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1299 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)))
1301 ent->visframe = r_framecount;
1302 R_UpdateEntityLighting(ent);
1308 // no worldmodel or it can't check visibility
1309 for (i = 0;i < r_refdef.numentities;i++)
1311 ent = r_refdef.entities[i];
1312 // some of the renderer still relies on origin...
1313 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
1314 // some of the renderer still relies on scale...
1315 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
1316 if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST))
1318 ent->visframe = r_framecount;
1319 R_UpdateEntityLighting(ent);
1325 // only used if skyrendermasked, and normally returns false
1326 int R_DrawBrushModelsSky (void)
1329 entity_render_t *ent;
1331 if (!r_drawentities.integer)
1335 for (i = 0;i < r_refdef.numentities;i++)
1337 ent = r_refdef.entities[i];
1338 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
1340 ent->model->DrawSky(ent);
1347 void R_DrawNoModel(entity_render_t *ent);
1348 void R_DrawModels(void)
1351 entity_render_t *ent;
1353 if (!r_drawentities.integer)
1356 for (i = 0;i < r_refdef.numentities;i++)
1358 ent = r_refdef.entities[i];
1359 if (ent->visframe == r_framecount)
1361 renderstats.entities++;
1362 if (ent->model && ent->model->Draw != NULL)
1363 ent->model->Draw(ent);
1370 static void R_SetFrustum(void)
1372 // break apart the view matrix into vectors for various purposes
1373 Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
1374 VectorNegate(r_viewleft, r_viewright);
1377 frustum[0].normal[0] = 0 - 1.0 / r_refdef.frustum_x;
1378 frustum[0].normal[1] = 0 - 0;
1379 frustum[0].normal[2] = -1 - 0;
1380 frustum[1].normal[0] = 0 + 1.0 / r_refdef.frustum_x;
1381 frustum[1].normal[1] = 0 + 0;
1382 frustum[1].normal[2] = -1 + 0;
1383 frustum[2].normal[0] = 0 - 0;
1384 frustum[2].normal[1] = 0 - 1.0 / r_refdef.frustum_y;
1385 frustum[2].normal[2] = -1 - 0;
1386 frustum[3].normal[0] = 0 + 0;
1387 frustum[3].normal[1] = 0 + 1.0 / r_refdef.frustum_y;
1388 frustum[3].normal[2] = -1 + 0;
1392 zNear = r_nearclip.value;
1393 nudge = 1.0 - 1.0 / (1<<23);
1394 frustum[4].normal[0] = 0 - 0;
1395 frustum[4].normal[1] = 0 - 0;
1396 frustum[4].normal[2] = -1 - -nudge;
1397 frustum[4].dist = 0 - -2 * zNear * nudge;
1398 frustum[5].normal[0] = 0 + 0;
1399 frustum[5].normal[1] = 0 + 0;
1400 frustum[5].normal[2] = -1 + -nudge;
1401 frustum[5].dist = 0 + -2 * zNear * nudge;
1407 frustum[0].normal[0] = m[3] - m[0];
1408 frustum[0].normal[1] = m[7] - m[4];
1409 frustum[0].normal[2] = m[11] - m[8];
1410 frustum[0].dist = m[15] - m[12];
1412 frustum[1].normal[0] = m[3] + m[0];
1413 frustum[1].normal[1] = m[7] + m[4];
1414 frustum[1].normal[2] = m[11] + m[8];
1415 frustum[1].dist = m[15] + m[12];
1417 frustum[2].normal[0] = m[3] - m[1];
1418 frustum[2].normal[1] = m[7] - m[5];
1419 frustum[2].normal[2] = m[11] - m[9];
1420 frustum[2].dist = m[15] - m[13];
1422 frustum[3].normal[0] = m[3] + m[1];
1423 frustum[3].normal[1] = m[7] + m[5];
1424 frustum[3].normal[2] = m[11] + m[9];
1425 frustum[3].dist = m[15] + m[13];
1427 frustum[4].normal[0] = m[3] - m[2];
1428 frustum[4].normal[1] = m[7] - m[6];
1429 frustum[4].normal[2] = m[11] - m[10];
1430 frustum[4].dist = m[15] - m[14];
1432 frustum[5].normal[0] = m[3] + m[2];
1433 frustum[5].normal[1] = m[7] + m[6];
1434 frustum[5].normal[2] = m[11] + m[10];
1435 frustum[5].dist = m[15] + m[14];
1440 VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_x, r_viewleft, frustum[0].normal);
1441 VectorMAM(1, r_viewforward, 1.0 / r_refdef.frustum_x, r_viewleft, frustum[1].normal);
1442 VectorMAM(1, r_viewforward, 1.0 / -r_refdef.frustum_y, r_viewup, frustum[2].normal);
1443 VectorMAM(1, r_viewforward, 1.0 / r_refdef.frustum_y, r_viewup, frustum[3].normal);
1444 VectorCopy(r_viewforward, frustum[4].normal);
1445 VectorNormalize(frustum[0].normal);
1446 VectorNormalize(frustum[1].normal);
1447 VectorNormalize(frustum[2].normal);
1448 VectorNormalize(frustum[3].normal);
1449 frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1450 frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1451 frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1452 frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1453 frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1454 PlaneClassify(&frustum[0]);
1455 PlaneClassify(&frustum[1]);
1456 PlaneClassify(&frustum[2]);
1457 PlaneClassify(&frustum[3]);
1458 PlaneClassify(&frustum[4]);
1460 // LordHavoc: note to all quake engine coders, Quake had a special case
1461 // for 90 degrees which assumed a square view (wrong), so I removed it,
1462 // Quake2 has it disabled as well.
1464 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
1465 //RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_refdef.fov_x / 2));
1466 //frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
1467 //PlaneClassify(&frustum[0]);
1469 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
1470 //RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_refdef.fov_x / 2));
1471 //frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
1472 //PlaneClassify(&frustum[1]);
1474 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
1475 //RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_refdef.fov_y / 2));
1476 //frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
1477 //PlaneClassify(&frustum[2]);
1479 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
1480 //RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_refdef.fov_y / 2));
1481 //frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
1482 //PlaneClassify(&frustum[3]);
1485 //VectorCopy(r_viewforward, frustum[4].normal);
1486 //frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + r_nearclip.value;
1487 //PlaneClassify(&frustum[4]);
1490 static void R_BlendView(void)
1492 int screenwidth, screenheight;
1496 float texcoord2f[3][8];
1498 // set the (poorly named) screenwidth and screenheight variables to
1499 // a power of 2 at least as large as the screen, these will define the
1500 // size of the texture to allocate
1501 for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2);
1502 for (screenheight = 1;screenheight < vid.height;screenheight *= 2);
1504 doblend = r_refdef.viewblend[3] >= 0.01f;
1505 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;
1507 if (!dobloom && !doblend)
1510 GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
1512 GL_DepthTest(false);
1513 R_Mesh_Matrix(&identitymatrix);
1514 // vertex coordinates for a quad that covers the screen exactly
1515 vertex3f[0] = 0;vertex3f[1] = 0;vertex3f[2] = 0;
1516 vertex3f[3] = 1;vertex3f[4] = 0;vertex3f[5] = 0;
1517 vertex3f[6] = 1;vertex3f[7] = 1;vertex3f[8] = 0;
1518 vertex3f[9] = 0;vertex3f[10] = 1;vertex3f[11] = 0;
1519 R_Mesh_VertexPointer(vertex3f);
1520 R_Mesh_ColorPointer(NULL);
1521 R_Mesh_ResetTextureState();
1524 int bloomwidth, bloomheight, x, range;
1525 float xoffset, yoffset, r;
1526 renderstats.bloom++;
1527 // allocate textures as needed
1528 if (!r_bloom_texture_screen)
1529 r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1530 if (!r_bloom_texture_bloom)
1531 r_bloom_texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
1532 // set bloomwidth and bloomheight to the bloom resolution that will be
1533 // used (often less than the screen resolution for faster rendering)
1534 bloomwidth = min(r_view_width, r_bloom_resolution.integer);
1535 bloomheight = min(r_view_height, bloomwidth * r_view_height / r_view_width);
1536 // set up a texcoord array for the full resolution screen image
1537 // (we have to keep this around to copy back during final render)
1538 texcoord2f[0][0] = 0;
1539 texcoord2f[0][1] = (float)r_view_height / (float)screenheight;
1540 texcoord2f[0][2] = (float)r_view_width / (float)screenwidth;
1541 texcoord2f[0][3] = (float)r_view_height / (float)screenheight;
1542 texcoord2f[0][4] = (float)r_view_width / (float)screenwidth;
1543 texcoord2f[0][5] = 0;
1544 texcoord2f[0][6] = 0;
1545 texcoord2f[0][7] = 0;
1546 // set up a texcoord array for the reduced resolution bloom image
1547 // (which will be additive blended over the screen image)
1548 texcoord2f[1][0] = 0;
1549 texcoord2f[1][1] = (float)bloomheight / (float)screenheight;
1550 texcoord2f[1][2] = (float)bloomwidth / (float)screenwidth;
1551 texcoord2f[1][3] = (float)bloomheight / (float)screenheight;
1552 texcoord2f[1][4] = (float)bloomwidth / (float)screenwidth;
1553 texcoord2f[1][5] = 0;
1554 texcoord2f[1][6] = 0;
1555 texcoord2f[1][7] = 0;
1556 R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]);
1557 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen));
1558 // copy view into the full resolution screen image texture
1559 GL_ActiveTexture(0);
1560 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1561 renderstats.bloom_copypixels += r_view_width * r_view_height;
1562 // now scale it down to the bloom size and raise to a power of itself
1563 // to darken it (this leaves the really bright stuff bright, and
1564 // everything else becomes very dark)
1565 // TODO: optimize with multitexture or GLSL
1566 qglViewport(r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1567 GL_BlendFunc(GL_ONE, GL_ZERO);
1568 GL_Color(1, 1, 1, 1);
1569 R_Mesh_Draw(0, 4, 2, polygonelements);
1570 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1571 // render multiple times with a multiply blendfunc to raise to a power
1572 GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
1573 for (x = 1;x < r_bloom_power.integer;x++)
1575 R_Mesh_Draw(0, 4, 2, polygonelements);
1576 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1578 // we now have a darkened bloom image in the framebuffer, copy it into
1579 // the bloom image texture for more processing
1580 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom));
1581 R_Mesh_TexCoordPointer(0, 2, texcoord2f[2]);
1582 GL_ActiveTexture(0);
1583 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1584 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1585 // blend on at multiple vertical offsets to achieve a vertical blur
1586 // TODO: do offset blends using GLSL
1587 range = r_bloom_blur.integer * bloomwidth / 320;
1588 GL_BlendFunc(GL_ONE, GL_ZERO);
1589 for (x = -range;x <= range;x++)
1591 xoffset = 0 / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1592 yoffset = x / (float)bloomheight * (float)bloomheight / (float)screenheight;
1593 // compute a texcoord array with the specified x and y offset
1594 texcoord2f[2][0] = xoffset+0;
1595 texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1596 texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1597 texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1598 texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1599 texcoord2f[2][5] = yoffset+0;
1600 texcoord2f[2][6] = xoffset+0;
1601 texcoord2f[2][7] = yoffset+0;
1602 // this r value looks like a 'dot' particle, fading sharply to
1603 // black at the edges
1604 // (probably not realistic but looks good enough)
1605 r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1608 GL_Color(r, r, r, 1);
1609 R_Mesh_Draw(0, 4, 2, polygonelements);
1610 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1611 GL_BlendFunc(GL_ONE, GL_ONE);
1613 // copy the vertically blurred bloom view to a texture
1614 GL_ActiveTexture(0);
1615 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1616 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1617 // blend the vertically blurred image at multiple offsets horizontally
1618 // to finish the blur effect
1619 // TODO: do offset blends using GLSL
1620 range = r_bloom_blur.integer * bloomwidth / 320;
1621 GL_BlendFunc(GL_ONE, GL_ZERO);
1622 for (x = -range;x <= range;x++)
1624 xoffset = x / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
1625 yoffset = 0 / (float)bloomheight * (float)bloomheight / (float)screenheight;
1626 // compute a texcoord array with the specified x and y offset
1627 texcoord2f[2][0] = xoffset+0;
1628 texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
1629 texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
1630 texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
1631 texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
1632 texcoord2f[2][5] = yoffset+0;
1633 texcoord2f[2][6] = xoffset+0;
1634 texcoord2f[2][7] = yoffset+0;
1635 // this r value looks like a 'dot' particle, fading sharply to
1636 // black at the edges
1637 // (probably not realistic but looks good enough)
1638 r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
1641 GL_Color(r, r, r, 1);
1642 R_Mesh_Draw(0, 4, 2, polygonelements);
1643 renderstats.bloom_drawpixels += bloomwidth * bloomheight;
1644 GL_BlendFunc(GL_ONE, GL_ONE);
1646 // copy the blurred bloom view to a texture
1647 GL_ActiveTexture(0);
1648 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
1649 renderstats.bloom_copypixels += bloomwidth * bloomheight;
1650 // go back to full view area
1651 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1652 // put the original screen image back in place and blend the bloom
1655 GL_BlendFunc(GL_ONE, GL_ZERO);
1656 // do both in one pass if possible
1657 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen));
1658 R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]);
1659 if (r_textureunits.integer >= 2 && gl_combine.integer)
1661 R_Mesh_TexCombine(1, GL_ADD, GL_ADD, 1, 1);
1662 R_Mesh_TexBind(1, R_GetTexture(r_bloom_texture_bloom));
1663 R_Mesh_TexCoordPointer(1, 2, texcoord2f[1]);
1667 R_Mesh_Draw(0, 4, 2, polygonelements);
1668 renderstats.bloom_drawpixels += r_view_width * r_view_height;
1669 // now blend on the bloom texture
1670 GL_BlendFunc(GL_ONE, GL_ONE);
1671 R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom));
1672 R_Mesh_TexCoordPointer(0, 2, texcoord2f[1]);
1674 R_Mesh_Draw(0, 4, 2, polygonelements);
1675 renderstats.bloom_drawpixels += r_view_width * r_view_height;
1679 // apply a color tint to the whole view
1680 R_Mesh_ResetTextureState();
1681 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1682 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
1683 R_Mesh_Draw(0, 4, 2, polygonelements);
1687 void R_RenderScene(void);
1689 matrix4x4_t r_waterscrollmatrix;
1696 void R_RenderView(void)
1698 if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1699 return; //Host_Error ("R_RenderView: NULL worldmodel");
1701 r_view_width = bound(0, r_refdef.width, vid.width);
1702 r_view_height = bound(0, r_refdef.height, vid.height);
1704 r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1705 r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1707 r_view_matrix = r_refdef.viewentitymatrix;
1708 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1709 r_rtworld = r_shadow_realtime_world.integer;
1710 r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1711 r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1712 r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1713 r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1714 r_polygonfactor = 0;
1715 r_polygonoffset = 0;
1716 r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1717 r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1718 if (r_showsurfaces.integer)
1721 r_rtworldshadows = false;
1723 r_rtdlightshadows = false;
1724 r_lightmapintensity = 0;
1727 // GL is weird because it's bottom to top, r_view_y is top to bottom
1728 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1729 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1730 GL_ScissorTest(true);
1735 if (r_timereport_active)
1736 R_TimeReport("setup");
1738 qglDepthFunc(GL_LEQUAL);
1739 qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1740 qglEnable(GL_POLYGON_OFFSET_FILL);
1744 qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1745 qglDisable(GL_POLYGON_OFFSET_FILL);
1748 if (r_timereport_active)
1749 R_TimeReport("blendview");
1751 GL_Scissor(0, 0, vid.width, vid.height);
1752 GL_ScissorTest(false);
1756 void CSQC_R_ClearScreen (void)
1758 if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1759 return; //Host_Error ("R_RenderView: NULL worldmodel");
1761 r_view_width = bound(0, r_refdef.width, vid.width);
1762 r_view_height = bound(0, r_refdef.height, vid.height);
1764 r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1765 r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1767 r_view_matrix = r_refdef.viewentitymatrix;
1768 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1769 r_rtworld = r_shadow_realtime_world.integer;
1770 r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1771 r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1772 r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1773 r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1774 r_polygonfactor = 0;
1775 r_polygonoffset = 0;
1776 r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value;
1777 r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value;
1778 if (r_showsurfaces.integer)
1781 r_rtworldshadows = false;
1783 r_rtdlightshadows = false;
1784 r_lightmapintensity = 0;
1787 // GL is weird because it's bottom to top, r_view_y is top to bottom
1788 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1789 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1790 GL_ScissorTest(true);
1795 if (r_timereport_active)
1796 R_TimeReport("setup");
1800 void CSQC_R_RenderScene (void)
1802 qglDepthFunc(GL_LEQUAL);
1803 qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1804 qglEnable(GL_POLYGON_OFFSET_FILL);
1808 qglPolygonOffset(r_polygonfactor, r_polygonoffset);
1809 qglDisable(GL_POLYGON_OFFSET_FILL);
1812 if (r_timereport_active)
1813 R_TimeReport("blendview");
1815 GL_Scissor(0, 0, vid.width, vid.height);
1816 GL_ScissorTest(false);
1819 extern void R_DrawLightningBeams (void);
1820 extern void VM_AddPolygonsToMeshQueue (void);
1821 void R_RenderScene(void)
1825 // don't let sound skip if going slow
1826 if (r_refdef.extraupdate)
1831 if (gl_support_fragment_shader)
1832 qglUseProgramObjectARB(0);
1834 R_MeshQueue_BeginScene();
1838 r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
1839 nearclip = bound (0.001f, r_nearclip.value, r_farclip - 1.0f);
1841 if (r_rtworldshadows || r_rtdlightshadows)
1842 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_refdef.frustum_x, r_refdef.frustum_y, nearclip);
1844 GL_SetupView_Mode_Perspective(r_refdef.frustum_x, r_refdef.frustum_y, nearclip, r_farclip);
1846 GL_SetupView_Orientation_FromEntity(&r_view_matrix);
1848 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);
1852 R_WorldVisibility();
1853 if (r_timereport_active)
1854 R_TimeReport("worldvis");
1857 if (r_timereport_active)
1858 R_TimeReport("markentity");
1860 R_Shadow_UpdateWorldLightSelection();
1862 if (cl.csqc_vidvars.drawworld)
1864 // don't let sound skip if going slow
1865 if (r_refdef.extraupdate)
1868 if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
1870 r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
1871 if (r_timereport_active)
1872 R_TimeReport("worldsky");
1875 if (R_DrawBrushModelsSky() && r_timereport_active)
1876 R_TimeReport("bmodelsky");
1878 if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
1880 r_refdef.worldmodel->Draw(r_refdef.worldentity);
1881 if (r_timereport_active)
1882 R_TimeReport("world");
1886 // don't let sound skip if going slow
1887 if (r_refdef.extraupdate)
1891 if (r_timereport_active)
1892 R_TimeReport("models");
1894 // don't let sound skip if going slow
1895 if (r_refdef.extraupdate)
1898 R_ShadowVolumeLighting(false);
1899 if (r_timereport_active)
1900 R_TimeReport("rtlights");
1902 // don't let sound skip if going slow
1903 if (r_refdef.extraupdate)
1906 if (cl.csqc_vidvars.drawworld)
1908 R_DrawLightningBeams();
1909 if (r_timereport_active)
1910 R_TimeReport("lightning");
1913 if (r_timereport_active)
1914 R_TimeReport("particles");
1917 if (r_timereport_active)
1918 R_TimeReport("explosions");
1921 R_MeshQueue_RenderTransparent();
1922 if (r_timereport_active)
1923 R_TimeReport("drawtrans");
1925 if (cl.csqc_vidvars.drawworld)
1928 if (r_timereport_active)
1929 R_TimeReport("coronas");
1931 if(cl.csqc_vidvars.drawcrosshair)
1933 R_DrawWorldCrosshair();
1934 if (r_timereport_active)
1935 R_TimeReport("crosshair");
1938 VM_AddPolygonsToMeshQueue();
1940 R_MeshQueue_Render();
1942 R_MeshQueue_EndScene();
1944 // don't let sound skip if going slow
1945 if (r_refdef.extraupdate)
1948 if (gl_support_fragment_shader)
1949 qglUseProgramObjectARB(0);
1953 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
1956 float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
1957 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1958 GL_DepthMask(false);
1960 R_Mesh_Matrix(&identitymatrix);
1962 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
1963 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
1964 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
1965 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
1966 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
1967 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
1968 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
1969 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
1970 R_FillColors(color, 8, cr, cg, cb, ca);
1973 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
1975 f2 = VERTEXFOGTABLE(VectorDistance(v, r_vieworigin));
1977 c[0] = c[0] * f1 + fogcolor[0] * f2;
1978 c[1] = c[1] * f1 + fogcolor[1] * f2;
1979 c[2] = c[2] * f1 + fogcolor[2] * f2;
1982 R_Mesh_VertexPointer(vertex3f);
1983 R_Mesh_ColorPointer(color);
1984 R_Mesh_ResetTextureState();
1989 int nomodelelements[24] =
2001 float nomodelvertex3f[6*3] =
2011 float nomodelcolor4f[6*4] =
2013 0.0f, 0.0f, 0.5f, 1.0f,
2014 0.0f, 0.0f, 0.5f, 1.0f,
2015 0.0f, 0.5f, 0.0f, 1.0f,
2016 0.0f, 0.5f, 0.0f, 1.0f,
2017 0.5f, 0.0f, 0.0f, 1.0f,
2018 0.5f, 0.0f, 0.0f, 1.0f
2021 void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
2026 R_Mesh_Matrix(&ent->matrix);
2028 if (ent->flags & EF_ADDITIVE)
2030 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2031 GL_DepthMask(false);
2033 else if (ent->alpha < 1)
2035 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2036 GL_DepthMask(false);
2040 GL_BlendFunc(GL_ONE, GL_ZERO);
2043 GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
2044 R_Mesh_VertexPointer(nomodelvertex3f);
2047 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2048 R_Mesh_ColorPointer(color4f);
2049 f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_vieworigin));
2051 for (i = 0, c = color4f;i < 6;i++, c += 4)
2053 c[0] = (c[0] * f1 + fogcolor[0] * f2);
2054 c[1] = (c[1] * f1 + fogcolor[1] * f2);
2055 c[2] = (c[2] * f1 + fogcolor[2] * f2);
2059 else if (ent->alpha != 1)
2061 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
2062 R_Mesh_ColorPointer(color4f);
2063 for (i = 0, c = color4f;i < 6;i++, c += 4)
2067 R_Mesh_ColorPointer(nomodelcolor4f);
2068 R_Mesh_ResetTextureState();
2069 R_Mesh_Draw(0, 6, 8, nomodelelements);
2072 void R_DrawNoModel(entity_render_t *ent)
2074 //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
2075 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight);
2077 // R_DrawNoModelCallback(ent, 0);
2080 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
2082 vec3_t right1, right2, diff, normal;
2084 VectorSubtract (org2, org1, normal);
2086 // calculate 'right' vector for start
2087 VectorSubtract (r_vieworigin, org1, diff);
2088 CrossProduct (normal, diff, right1);
2089 VectorNormalize (right1);
2091 // calculate 'right' vector for end
2092 VectorSubtract (r_vieworigin, org2, diff);
2093 CrossProduct (normal, diff, right2);
2094 VectorNormalize (right2);
2096 vert[ 0] = org1[0] + width * right1[0];
2097 vert[ 1] = org1[1] + width * right1[1];
2098 vert[ 2] = org1[2] + width * right1[2];
2099 vert[ 3] = org1[0] - width * right1[0];
2100 vert[ 4] = org1[1] - width * right1[1];
2101 vert[ 5] = org1[2] - width * right1[2];
2102 vert[ 6] = org2[0] - width * right2[0];
2103 vert[ 7] = org2[1] - width * right2[1];
2104 vert[ 8] = org2[2] - width * right2[2];
2105 vert[ 9] = org2[0] + width * right2[0];
2106 vert[10] = org2[1] + width * right2[1];
2107 vert[11] = org2[2] + width * right2[2];
2110 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
2112 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)
2114 float fog = 0.0f, ifog;
2118 fog = VERTEXFOGTABLE(VectorDistance(origin, r_vieworigin));
2121 R_Mesh_Matrix(&identitymatrix);
2122 GL_BlendFunc(blendfunc1, blendfunc2);
2123 GL_DepthMask(false);
2124 GL_DepthTest(!depthdisable);
2126 vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
2127 vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
2128 vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
2129 vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
2130 vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
2131 vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
2132 vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
2133 vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
2134 vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
2135 vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
2136 vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
2137 vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
2139 R_Mesh_VertexPointer(vertex3f);
2140 R_Mesh_ColorPointer(NULL);
2141 R_Mesh_ResetTextureState();
2142 R_Mesh_TexBind(0, R_GetTexture(texture));
2143 R_Mesh_TexCoordPointer(0, 2, spritetexcoord2f);
2144 GL_Color(cr * ifog, cg * ifog, cb * ifog, ca);
2145 R_Mesh_Draw(0, 4, 2, polygonelements);
2147 if (blendfunc2 == GL_ONE_MINUS_SRC_ALPHA)
2149 R_Mesh_TexBind(0, R_GetTexture(fogtexture));
2150 GL_BlendFunc(blendfunc1, GL_ONE);
2151 GL_Color(fogcolor[0] * fog, fogcolor[1] * fog, fogcolor[2] * fog, ca);
2152 R_Mesh_Draw(0, 4, 2, polygonelements);
2156 int R_Mesh_AddVertex3f(rmesh_t *mesh, const float *v)
2160 for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
2161 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
2163 if (i == mesh->numvertices)
2165 if (mesh->numvertices < mesh->maxvertices)
2167 VectorCopy(v, vertex3f);
2168 mesh->numvertices++;
2170 return mesh->numvertices;
2176 void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
2180 element[0] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2181 element[1] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
2182 e = mesh->element3i + mesh->numtriangles * 3;
2183 for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
2185 element[2] = R_Mesh_AddVertex3f(mesh, vertex3f);
2186 if (mesh->numtriangles < mesh->maxtriangles)
2191 mesh->numtriangles++;
2193 element[1] = element[2];
2197 void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
2199 int planenum, planenum2;
2202 mplane_t *plane, *plane2;
2203 float temppoints[2][256*3];
2204 for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
2208 PolygonF_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->normal[3], 1024.0*1024.0*1024.0);
2209 for (planenum2 = 0, plane2 = planes;planenum2 < numplanes && tempnumpoints >= 3;planenum2++, plane2++)
2211 if (planenum2 == planenum)
2213 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);
2216 if (tempnumpoints < 3)
2218 // generate elements forming a triangle fan for this polygon
2219 R_Mesh_AddPolygon3f(mesh, tempnumpoints, temppoints[w]);
2223 static void R_DrawCollisionBrush(const colbrushf_t *brush)
2226 R_Mesh_VertexPointer(brush->points->v);
2227 i = (int)(((size_t)brush) / sizeof(colbrushf_t));
2228 GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2229 GL_LockArrays(0, brush->numpoints);
2230 R_Mesh_Draw(0, brush->numpoints, brush->numtriangles, brush->elements);
2231 GL_LockArrays(0, 0);
2234 static void R_DrawCollisionSurface(const entity_render_t *ent, const msurface_t *surface)
2237 if (!surface->num_collisiontriangles)
2239 R_Mesh_VertexPointer(surface->data_collisionvertex3f);
2240 i = (int)(((size_t)surface) / sizeof(msurface_t));
2241 GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f);
2242 GL_LockArrays(0, surface->num_collisionvertices);
2243 R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i);
2244 GL_LockArrays(0, 0);
2247 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)
2249 texturelayer_t *layer;
2250 layer = t->currentlayers + t->currentnumlayers++;
2252 layer->depthmask = depthmask;
2253 layer->blendfunc1 = blendfunc1;
2254 layer->blendfunc2 = blendfunc2;
2255 layer->texture = texture;
2256 layer->texmatrix = *matrix;
2257 layer->color[0] = r;
2258 layer->color[1] = g;
2259 layer->color[2] = b;
2260 layer->color[3] = a;
2263 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
2265 // FIXME: identify models using a better check than ent->model->brush.shadowmesh
2266 //int lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
2269 texture_t *texture = t;
2270 model_t *model = ent->model;
2271 int s = ent->skinnum;
2272 if ((unsigned int)s >= (unsigned int)model->numskins)
2274 if (model->skinscenes)
2276 if (model->skinscenes[s].framecount > 1)
2277 s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
2279 s = model->skinscenes[s].firstframe;
2282 t = t + s * model->num_surfaces;
2284 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];
2285 texture->currentframe = t;
2288 t->currentmaterialflags = t->basematerialflags;
2289 t->currentalpha = ent->alpha;
2290 if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
2291 t->currentalpha *= r_wateralpha.value;
2292 if (!(ent->flags & RENDER_LIGHT))
2293 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
2294 if (ent->effects & EF_ADDITIVE)
2295 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT;
2296 else if (t->currentalpha < 1)
2297 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT;
2298 if (ent->effects & EF_NODEPTHTEST)
2299 t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST;
2300 if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
2301 t->currenttexmatrix = r_waterscrollmatrix;
2303 t->currenttexmatrix = identitymatrix;
2305 t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
2306 t->basetexture = (!t->colormapping && t->skin.merged) ? t->skin.merged : t->skin.base;
2307 t->glosstexture = r_texture_white;
2308 t->specularpower = 8;
2309 t->specularscale = 0;
2310 if (r_shadow_gloss.integer > 0)
2314 if (r_shadow_glossintensity.value > 0)
2316 t->glosstexture = t->skin.gloss;
2317 t->specularscale = r_shadow_glossintensity.value;
2320 else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0)
2321 t->specularscale = r_shadow_gloss2intensity.value;
2324 t->currentnumlayers = 0;
2325 if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
2327 if (gl_lightmaps.integer)
2328 R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, r_texture_white, &identitymatrix, 1, 1, 1, 1);
2329 else if (!(t->currentmaterialflags & MATERIALFLAG_SKY))
2331 int blendfunc1, blendfunc2, depthmask;
2332 if (t->currentmaterialflags & MATERIALFLAG_ADD)
2334 blendfunc1 = GL_SRC_ALPHA;
2335 blendfunc2 = GL_ONE;
2337 else if (t->currentmaterialflags & MATERIALFLAG_ALPHA)
2339 blendfunc1 = GL_SRC_ALPHA;
2340 blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
2342 else if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
2344 blendfunc1 = t->customblendfunc[0];
2345 blendfunc2 = t->customblendfunc[1];
2349 blendfunc1 = GL_ONE;
2350 blendfunc2 = GL_ZERO;
2352 depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
2353 if (t->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
2355 rtexture_t *currentbasetexture;
2357 if (fogenabled && (t->currentmaterialflags & MATERIALFLAG_BLENDED))
2358 layerflags |= TEXTURELAYERFLAG_FOGDARKEN;
2359 currentbasetexture = (VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) < (1.0f / 1048576.0f) && t->skin.merged) ? t->skin.merged : t->skin.base;
2360 if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2362 // fullbright is not affected by r_lightmapintensity
2363 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0], ent->colormod[1], ent->colormod[2], t->currentalpha);
2364 if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2365 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);
2366 if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2367 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);
2373 // q3bsp has no lightmap updates, so the lightstylevalue that
2374 // would normally be baked into the lightmap must be
2375 // applied to the color
2376 if (ent->model->type == mod_brushq3)
2377 colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
2378 colorscale *= r_lightmapintensity;
2379 if (r_textureunits.integer >= 2 && gl_combine.integer)
2380 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE_COMBINE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
2381 else if ((t->currentmaterialflags & MATERIALFLAG_BLENDED) == 0)
2382 R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale * 0.5f, ent->colormod[1] * colorscale * 0.5f, ent->colormod[2] * colorscale * 0.5f, t->currentalpha);
2384 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
2385 if (r_ambient.value >= (1.0f/64.0f))
2386 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);
2387 if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
2389 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ent->colormod[0] * colorscale, ent->colormap_pantscolor[1] * ent->colormod[1] * colorscale, ent->colormap_pantscolor[2] * ent->colormod[2] * colorscale, t->currentalpha);
2390 if (r_ambient.value >= (1.0f/64.0f))
2391 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);
2393 if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
2395 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * ent->colormod[0] * colorscale, ent->colormap_shirtcolor[1] * ent->colormod[1] * colorscale, ent->colormap_shirtcolor[2] * ent->colormod[2] * colorscale, t->currentalpha);
2396 if (r_ambient.value >= (1.0f/64.0f))
2397 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);
2400 if (t->skin.glow != NULL)
2401 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, t->currentalpha);
2402 if (fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
2404 // if this is opaque use alpha blend which will darken the earlier
2407 // if this is an alpha blended material, all the earlier passes
2408 // were darkened by fog already, so we only need to add the fog
2409 // color ontop through the fog mask texture
2411 // if this is an additive blended material, all the earlier passes
2412 // were darkened by fog already, and we should not add fog color
2413 // (because the background was not darkened, there is no fog color
2414 // that was lost behind it).
2415 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);
2422 void R_UpdateAllTextureInfo(entity_render_t *ent)
2426 for (i = 0;i < ent->model->num_textures;i++)
2427 R_UpdateTextureInfo(ent, ent->model->data_textures + i);
2430 int rsurface_array_size = 0;
2431 float *rsurface_array_modelvertex3f = NULL;
2432 float *rsurface_array_modelsvector3f = NULL;
2433 float *rsurface_array_modeltvector3f = NULL;
2434 float *rsurface_array_modelnormal3f = NULL;
2435 float *rsurface_array_deformedvertex3f = NULL;
2436 float *rsurface_array_deformedsvector3f = NULL;
2437 float *rsurface_array_deformedtvector3f = NULL;
2438 float *rsurface_array_deformednormal3f = NULL;
2439 float *rsurface_array_color4f = NULL;
2440 float *rsurface_array_texcoord3f = NULL;
2442 void R_Mesh_ResizeArrays(int newvertices)
2445 if (rsurface_array_size >= newvertices)
2447 if (rsurface_array_modelvertex3f)
2448 Mem_Free(rsurface_array_modelvertex3f);
2449 rsurface_array_size = (newvertices + 1023) & ~1023;
2450 base = (float *)Mem_Alloc(r_main_mempool, rsurface_array_size * sizeof(float[31]));
2451 rsurface_array_modelvertex3f = base + rsurface_array_size * 0;
2452 rsurface_array_modelsvector3f = base + rsurface_array_size * 3;
2453 rsurface_array_modeltvector3f = base + rsurface_array_size * 6;
2454 rsurface_array_modelnormal3f = base + rsurface_array_size * 9;
2455 rsurface_array_deformedvertex3f = base + rsurface_array_size * 12;
2456 rsurface_array_deformedsvector3f = base + rsurface_array_size * 15;
2457 rsurface_array_deformedtvector3f = base + rsurface_array_size * 18;
2458 rsurface_array_deformednormal3f = base + rsurface_array_size * 21;
2459 rsurface_array_texcoord3f = base + rsurface_array_size * 24;
2460 rsurface_array_color4f = base + rsurface_array_size * 27;
2463 float *rsurface_modelvertex3f;
2464 float *rsurface_modelsvector3f;
2465 float *rsurface_modeltvector3f;
2466 float *rsurface_modelnormal3f;
2467 float *rsurface_vertex3f;
2468 float *rsurface_svector3f;
2469 float *rsurface_tvector3f;
2470 float *rsurface_normal3f;
2471 float *rsurface_lightmapcolor4f;
2472 vec3_t rsurface_modelorg;
2473 qboolean rsurface_generatedvertex;
2474 const entity_render_t *rsurface_entity;
2475 const model_t *rsurface_model;
2476 texture_t *rsurface_texture;
2477 rtexture_t *rsurface_lightmaptexture;
2478 rsurfmode_t rsurface_mode;
2479 texture_t *rsurface_glsl_texture;
2480 qboolean rsurface_glsl_uselightmap;
2482 void RSurf_ActiveEntity(const entity_render_t *ent)
2484 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
2485 rsurface_entity = ent;
2486 rsurface_model = ent->model;
2487 if (rsurface_array_size < rsurface_model->surfmesh.num_vertices)
2488 R_Mesh_ResizeArrays(rsurface_model->surfmesh.num_vertices);
2489 R_Mesh_Matrix(&ent->matrix);
2490 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, rsurface_modelorg);
2491 if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexboneweights))
2493 rsurface_modelvertex3f = rsurface_array_modelvertex3f;
2494 rsurface_modelsvector3f = NULL;
2495 rsurface_modeltvector3f = NULL;
2496 rsurface_modelnormal3f = NULL;
2497 Mod_Alias_GetMesh_Vertex3f(rsurface_model, rsurface_entity->frameblend, rsurface_array_modelvertex3f);
2498 rsurface_generatedvertex = true;
2502 rsurface_modelvertex3f = rsurface_model->surfmesh.data_vertex3f;
2503 rsurface_modelsvector3f = rsurface_model->surfmesh.data_svector3f;
2504 rsurface_modeltvector3f = rsurface_model->surfmesh.data_tvector3f;
2505 rsurface_modelnormal3f = rsurface_model->surfmesh.data_normal3f;
2506 rsurface_generatedvertex = false;
2508 rsurface_vertex3f = rsurface_modelvertex3f;
2509 rsurface_svector3f = rsurface_modelsvector3f;
2510 rsurface_tvector3f = rsurface_modeltvector3f;
2511 rsurface_normal3f = rsurface_modelnormal3f;
2512 rsurface_mode = RSURFMODE_NONE;
2513 rsurface_lightmaptexture = NULL;
2514 rsurface_texture = NULL;
2515 rsurface_glsl_texture = NULL;
2516 rsurface_glsl_uselightmap = false;
2519 void RSurf_CleanUp(void)
2521 if (rsurface_mode == RSURFMODE_GLSL)
2522 qglUseProgramObjectARB(0);
2523 GL_AlphaTest(false);
2524 rsurface_mode = RSURFMODE_NONE;
2525 rsurface_lightmaptexture = NULL;
2526 rsurface_texture = NULL;
2527 rsurface_glsl_texture = NULL;
2528 rsurface_glsl_uselightmap = false;
2531 void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist)
2533 if (rsurface_generatedvertex)
2535 if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2536 generatetangents = true;
2537 if (generatetangents)
2538 generatenormals = true;
2539 if (generatenormals && !rsurface_modelnormal3f)
2541 rsurface_normal3f = rsurface_modelnormal3f = rsurface_array_modelnormal3f;
2542 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);
2544 if (generatetangents && !rsurface_modelsvector3f)
2546 rsurface_svector3f = rsurface_modelsvector3f = rsurface_array_modelsvector3f;
2547 rsurface_tvector3f = rsurface_modeltvector3f = rsurface_array_modeltvector3f;
2548 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);
2551 if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
2553 int texturesurfaceindex;
2554 float center[3], forward[3], right[3], up[3], v[4][3];
2555 matrix4x4_t matrix1, imatrix1;
2556 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewforward, forward);
2557 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewright, right);
2558 Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewup, up);
2559 // make deformed versions of only the vertices used by the specified surfaces
2560 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2563 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2564 // a single autosprite surface can contain multiple sprites...
2565 for (j = 0;j < surface->num_vertices - 3;j += 4)
2567 VectorClear(center);
2568 for (i = 0;i < 4;i++)
2569 VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
2570 VectorScale(center, 0.25f, center);
2571 if (rsurface_texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
2573 forward[0] = rsurface_modelorg[0] - center[0];
2574 forward[1] = rsurface_modelorg[1] - center[1];
2576 VectorNormalize(forward);
2577 right[0] = forward[1];
2578 right[1] = -forward[0];
2580 VectorSet(up, 0, 0, 1);
2582 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
2583 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);
2584 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
2585 for (i = 0;i < 4;i++)
2586 Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
2587 for (i = 0;i < 4;i++)
2588 VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_modelvertex3f + (surface->num_firstvertex+i+j) * 3);
2590 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);
2591 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);
2593 rsurface_vertex3f = rsurface_array_deformedvertex3f;
2594 rsurface_svector3f = rsurface_array_deformedsvector3f;
2595 rsurface_tvector3f = rsurface_array_deformedtvector3f;
2596 rsurface_normal3f = rsurface_array_deformednormal3f;
2598 R_Mesh_VertexPointer(rsurface_vertex3f);
2601 static void RSurf_Draw(const msurface_t *surface)
2603 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2604 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle));
2607 static void RSurf_DrawLightmap(const msurface_t *surface, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
2615 vec3_t ambientcolor;
2616 vec3_t diffusecolor;
2618 VectorCopy(rsurface_entity->modellight_lightdir, lightdir);
2619 ambientcolor[0] = rsurface_entity->modellight_ambient[0] * r * 0.5f;
2620 ambientcolor[1] = rsurface_entity->modellight_ambient[1] * g * 0.5f;
2621 ambientcolor[2] = rsurface_entity->modellight_ambient[2] * b * 0.5f;
2622 diffusecolor[0] = rsurface_entity->modellight_diffuse[0] * r * 0.5f;
2623 diffusecolor[1] = rsurface_entity->modellight_diffuse[1] * g * 0.5f;
2624 diffusecolor[2] = rsurface_entity->modellight_diffuse[2] * b * 0.5f;
2625 if (VectorLength2(diffusecolor) > 0)
2627 int numverts = surface->num_vertices;
2628 v = rsurface_vertex3f + 3 * surface->num_firstvertex;
2629 c2 = rsurface_normal3f + 3 * surface->num_firstvertex;
2630 c = rsurface_array_color4f + 4 * surface->num_firstvertex;
2631 // q3-style directional shading
2632 for (i = 0;i < numverts;i++, v += 3, c2 += 3, c += 4)
2634 if ((f = DotProduct(c2, lightdir)) > 0)
2635 VectorMA(ambientcolor, f, diffusecolor, c);
2637 VectorCopy(ambientcolor, c);
2645 rsurface_lightmapcolor4f = rsurface_array_color4f;
2649 r = ambientcolor[0];
2650 g = ambientcolor[1];
2651 b = ambientcolor[2];
2652 rsurface_lightmapcolor4f = NULL;
2655 else if (lightmode >= 1)
2657 if (surface->lightmapinfo && surface->lightmapinfo->stainsamples)
2659 for (i = 0, c = rsurface_array_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
2661 if (surface->lightmapinfo->samples)
2663 const unsigned char *lm = surface->lightmapinfo->samples + (rsurface_model->surfmesh.data_lightmapoffsets + surface->num_firstvertex)[i];
2664 float scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
2665 VectorScale(lm, scale, c);
2666 if (surface->lightmapinfo->styles[1] != 255)
2668 int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
2670 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
2671 VectorMA(c, scale, lm, c);
2672 if (surface->lightmapinfo->styles[2] != 255)
2675 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
2676 VectorMA(c, scale, lm, c);
2677 if (surface->lightmapinfo->styles[3] != 255)
2680 scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
2681 VectorMA(c, scale, lm, c);
2689 rsurface_lightmapcolor4f = rsurface_array_color4f;
2692 rsurface_lightmapcolor4f = rsurface_model->surfmesh.data_lightmapcolor4f;
2695 rsurface_lightmapcolor4f = NULL;
2698 if (rsurface_lightmapcolor4f)
2700 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)
2702 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2711 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)
2713 f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
2720 rsurface_lightmapcolor4f = rsurface_array_color4f;
2722 if (applycolor && rsurface_lightmapcolor4f)
2724 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)
2731 rsurface_lightmapcolor4f = rsurface_array_color4f;
2733 R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
2734 GL_Color(r, g, b, a);
2735 RSurf_Draw(surface);
2738 static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfacelist)
2740 int texturesurfaceindex;
2742 qboolean applycolor;
2745 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_NODRAW)
2747 r_shadow_rtlight = NULL;
2748 renderstats.entities_surfaces += texturenumsurfaces;
2749 // FIXME: identify models using a better check than rsurface_model->brush.shadowmesh
2750 lightmode = ((rsurface_entity->effects & EF_FULLBRIGHT) || rsurface_model->brush.shadowmesh) ? 0 : 2;
2751 GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
2752 if ((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE))
2753 qglDisable(GL_CULL_FACE);
2754 if (r_showsurfaces.integer)
2756 if (rsurface_mode != RSURFMODE_SHOWSURFACES)
2758 rsurface_mode = RSURFMODE_SHOWSURFACES;
2760 GL_BlendFunc(GL_ONE, GL_ZERO);
2761 R_Mesh_ColorPointer(NULL);
2762 R_Mesh_ResetTextureState();
2764 RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
2765 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2767 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2768 int k = (int)(((size_t)surface) / sizeof(msurface_t));
2769 GL_Color((k & 15) * (1.0f / 16.0f), ((k >> 4) & 15) * (1.0f / 16.0f), ((k >> 8) & 15) * (1.0f / 16.0f), 0.2f);
2770 RSurf_Draw(surface);
2773 else if (rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY)
2775 // transparent sky would be ridiculous
2776 if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2778 if (rsurface_mode != RSURFMODE_SKY)
2780 if (rsurface_mode == RSURFMODE_GLSL)
2781 qglUseProgramObjectARB(0);
2782 rsurface_mode = RSURFMODE_SKY;
2785 skyrendernow = false;
2787 // restore entity matrix
2788 R_Mesh_Matrix(&rsurface_entity->matrix);
2791 // LordHavoc: HalfLife maps have freaky skypolys so don't use
2792 // skymasking on them, and Quake3 never did sky masking (unlike
2793 // software Quake and software Quake2), so disable the sky masking
2794 // in Quake3 maps as it causes problems with q3map2 sky tricks,
2795 // and skymasking also looks very bad when noclipping outside the
2796 // level, so don't use it then either.
2797 if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2799 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
2800 R_Mesh_ColorPointer(NULL);
2801 R_Mesh_ResetTextureState();
2802 if (skyrendermasked)
2804 // depth-only (masking)
2805 GL_ColorMask(0,0,0,0);
2806 // just to make sure that braindead drivers don't draw
2807 // anything despite that colormask...
2808 GL_BlendFunc(GL_ZERO, GL_ONE);
2813 GL_BlendFunc(GL_ONE, GL_ZERO);
2817 // LordHavoc: HalfLife maps have freaky skypolys so don't use
2818 // skymasking on them, and Quake3 never did sky masking (unlike
2819 // software Quake and software Quake2), so disable the sky masking
2820 // in Quake3 maps as it causes problems with q3map2 sky tricks,
2821 // and skymasking also looks very bad when noclipping outside the
2822 // level, so don't use it then either.
2823 if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis)
2825 RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist);
2826 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2828 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2829 RSurf_Draw(surface);
2831 if (skyrendermasked)
2832 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
2836 else if (rsurface_texture->currentnumlayers && r_glsl.integer && gl_support_fragment_shader)
2838 if (rsurface_mode != RSURFMODE_GLSL)
2840 rsurface_mode = RSURFMODE_GLSL;
2841 rsurface_glsl_texture = NULL;
2842 rsurface_glsl_uselightmap = false;
2843 R_Mesh_ResetTextureState();
2845 if (rsurface_glsl_texture != rsurface_texture || rsurface_glsl_uselightmap != (rsurface_lightmaptexture != NULL))
2847 rsurface_glsl_texture = rsurface_texture;
2848 rsurface_glsl_uselightmap = rsurface_lightmaptexture != NULL;
2849 GL_BlendFunc(rsurface_texture->currentlayers[0].blendfunc1, rsurface_texture->currentlayers[0].blendfunc2);
2850 GL_DepthMask(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_BLENDED));
2851 GL_Color(rsurface_entity->colormod[0], rsurface_entity->colormod[1], rsurface_entity->colormod[2], rsurface_texture->currentalpha);
2852 R_SetupSurfaceShader(vec3_origin, lightmode == 2);
2853 //permutation_deluxemapping = permutation_lightmapping = R_SetupSurfaceShader(vec3_origin, lightmode == 2, false);
2854 //if (r_glsl_deluxemapping.integer)
2855 // permutation_deluxemapping = R_SetupSurfaceShader(vec3_origin, lightmode == 2, true);
2856 R_Mesh_TexCoordPointer(0, 2, rsurface_model->surfmesh.data_texcoordtexture2f);
2857 R_Mesh_TexCoordPointer(4, 2, rsurface_model->surfmesh.data_texcoordlightmap2f);
2858 GL_AlphaTest((rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2860 if (!r_glsl_permutation)
2862 RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist);
2863 R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f);
2864 R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f);
2865 R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f);
2866 if (rsurface_lightmaptexture)
2868 R_Mesh_TexBind(7, R_GetTexture(rsurface_lightmaptexture));
2869 if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2870 R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture));
2871 R_Mesh_ColorPointer(NULL);
2875 R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
2876 if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
2877 R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
2878 R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f);
2880 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2882 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2883 RSurf_Draw(surface);
2886 else if (rsurface_texture->currentnumlayers)
2889 const texturelayer_t *layer;
2890 if (rsurface_mode != RSURFMODE_MULTIPASS)
2892 if (rsurface_mode == RSURFMODE_GLSL)
2893 qglUseProgramObjectARB(0);
2894 rsurface_mode = RSURFMODE_MULTIPASS;
2896 RSurf_PrepareVerticesForBatch(true, false, texturenumsurfaces, texturesurfacelist);
2897 for (layerindex = 0, layer = rsurface_texture->currentlayers;layerindex < rsurface_texture->currentnumlayers;layerindex++, layer++)
2900 int layertexrgbscale;
2901 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
2903 if (layerindex == 0)
2907 GL_AlphaTest(false);
2908 qglDepthFunc(GL_EQUAL);
2911 GL_DepthMask(layer->depthmask);
2912 GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
2913 if ((layer->color[0] > 2 || layer->color[1] > 2 || layer->color[2] > 2) && (gl_combine.integer || layer->depthmask))
2915 layertexrgbscale = 4;
2916 VectorScale(layer->color, 0.25f, layercolor);
2918 else if ((layer->color[0] > 1 || layer->color[1] > 1 || layer->color[2] > 1) && (gl_combine.integer || layer->depthmask))
2920 layertexrgbscale = 2;
2921 VectorScale(layer->color, 0.5f, layercolor);
2925 layertexrgbscale = 1;
2926 VectorScale(layer->color, 1.0f, layercolor);
2928 layercolor[3] = layer->color[3];
2929 R_Mesh_ColorPointer(NULL);
2930 GL_Color(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
2931 applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
2932 applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0;
2933 switch (layer->type)
2935 case TEXTURELAYERTYPE_LITTEXTURE_COMBINE:
2936 memset(&m, 0, sizeof(m));
2937 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
2938 m.tex[1] = R_GetTexture(layer->texture);
2939 m.texmatrix[1] = layer->texmatrix;
2940 m.texrgbscale[1] = layertexrgbscale;
2941 m.pointer_texcoord[1] = rsurface_model->surfmesh.data_texcoordtexture2f;
2942 R_Mesh_TextureState(&m);
2945 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2947 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2948 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2949 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
2952 else if (rsurface_lightmaptexture)
2954 R_Mesh_TexBind(0, R_GetTexture(rsurface_lightmaptexture));
2955 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2957 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2958 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
2963 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2964 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2966 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2967 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
2971 case TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS:
2972 memset(&m, 0, sizeof(m));
2973 m.tex[0] = R_GetTexture(layer->texture);
2974 m.texmatrix[0] = layer->texmatrix;
2975 m.texrgbscale[0] = layertexrgbscale;
2976 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
2977 R_Mesh_TextureState(&m);
2980 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2982 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2983 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2984 RSurf_DrawLightmap(surface, 1, 1, 1, 1, 2, false, false);
2987 else if (rsurface_lightmaptexture)
2989 R_Mesh_TexBind(0, R_GetTexture(rsurface_lightmaptexture));
2990 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2992 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
2993 RSurf_DrawLightmap(surface, 1, 1, 1, 1, 0, false, false);
2998 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2999 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3001 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3002 RSurf_DrawLightmap(surface, 1, 1, 1, 1, 1, false, false);
3005 GL_LockArrays(0, 0);
3006 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
3007 memset(&m, 0, sizeof(m));
3008 m.tex[0] = R_GetTexture(layer->texture);
3009 m.texmatrix[0] = layer->texmatrix;
3010 m.texrgbscale[0] = layertexrgbscale;
3011 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3012 R_Mesh_TextureState(&m);
3013 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3015 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3016 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, false);
3019 case TEXTURELAYERTYPE_LITTEXTURE_VERTEX:
3020 memset(&m, 0, sizeof(m));
3021 m.tex[0] = R_GetTexture(layer->texture);
3022 m.texmatrix[0] = layer->texmatrix;
3023 m.texrgbscale[0] = layertexrgbscale;
3024 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3025 R_Mesh_TextureState(&m);
3028 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3030 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3031 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog);
3036 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3038 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3039 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog);
3043 case TEXTURELAYERTYPE_TEXTURE:
3044 memset(&m, 0, sizeof(m));
3045 m.tex[0] = R_GetTexture(layer->texture);
3046 m.texmatrix[0] = layer->texmatrix;
3047 m.texrgbscale[0] = layertexrgbscale;
3048 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3049 R_Mesh_TextureState(&m);
3050 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3052 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3053 RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog);
3056 case TEXTURELAYERTYPE_FOG:
3057 R_Mesh_ColorPointer(rsurface_array_color4f);
3060 memset(&m, 0, sizeof(m));
3061 m.tex[0] = R_GetTexture(layer->texture);
3062 m.texmatrix[0] = layer->texmatrix;
3063 m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
3064 R_Mesh_TextureState(&m);
3067 R_Mesh_ResetTextureState();
3068 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3072 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3073 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)
3075 f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg));
3076 c[0] = layercolor[0];
3077 c[1] = layercolor[1];
3078 c[2] = layercolor[2];
3079 c[3] = f * layercolor[3];
3081 RSurf_Draw(surface);
3085 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
3087 GL_LockArrays(0, 0);
3088 // if trying to do overbright on first pass of an opaque surface
3089 // when combine is not supported, brighten as a post process
3090 if (layertexrgbscale > 1 && !gl_combine.integer && layer->depthmask)
3093 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
3094 R_Mesh_ColorPointer(NULL);
3095 GL_Color(1, 1, 1, 1);
3096 R_Mesh_ResetTextureState();
3097 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3099 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3100 for (scale = 1;scale < layertexrgbscale;scale <<= 1)
3101 RSurf_Draw(surface);
3103 GL_LockArrays(0, 0);
3106 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
3108 qglDepthFunc(GL_LEQUAL);
3109 GL_AlphaTest(false);
3112 GL_LockArrays(0, 0);
3113 if ((rsurface_texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (rsurface_entity->flags & RENDER_NOCULLFACE))
3114 qglEnable(GL_CULL_FACE);
3117 static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
3119 msurface_t *surface = ent->model->data_surfaces + surfacenumber;
3121 if (surface->texture->basematerialflags & MATERIALFLAG_SKY)
3122 return; // transparent sky is too difficult
3124 RSurf_ActiveEntity(ent);
3125 R_UpdateTextureInfo(ent, surface->texture);
3126 rsurface_texture = surface->texture->currentframe;
3127 R_DrawTextureSurfaceList(1, &surface);
3131 void R_QueueTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfacelist)
3133 int texturesurfaceindex;
3134 vec3_t tempcenter, center;
3135 if (rsurface_texture->currentmaterialflags & MATERIALFLAG_BLENDED)
3137 // drawing sky transparently would be too difficult
3138 if (!(rsurface_texture->currentmaterialflags & MATERIALFLAG_SKY))
3140 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
3142 const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
3143 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
3144 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
3145 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
3146 Matrix4x4_Transform(&rsurface_entity->matrix, tempcenter, center);
3147 R_MeshQueue_AddTransparent(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, R_DrawSurface_TransparentCallback, rsurface_entity, surface - rsurface_model->data_surfaces, r_shadow_rtlight);
3152 R_DrawTextureSurfaceList(texturenumsurfaces, texturesurfacelist);
3155 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
3156 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
3158 int i, j, f, flagsmask;
3159 int counttriangles = 0;
3161 model_t *model = ent->model;
3162 const int maxsurfacelist = 1024;
3163 int numsurfacelist = 0;
3164 msurface_t *surfacelist[1024];
3168 RSurf_ActiveEntity(ent);
3170 // update light styles
3171 if (!skysurfaces && model->brushq1.light_styleupdatechains)
3173 msurface_t *surface, **surfacechain;
3174 for (i = 0;i < model->brushq1.light_styles;i++)
3176 if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]])
3178 model->brushq1.light_stylevalue[i] = r_refdef.lightstylevalue[model->brushq1.light_style[i]];
3179 if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
3180 for (;(surface = *surfacechain);surfacechain++)
3181 surface->cached_dlight = true;
3186 R_UpdateAllTextureInfo(ent);
3187 flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
3190 rsurface_lightmaptexture = NULL;
3191 rsurface_texture = NULL;
3193 if (ent == r_refdef.worldentity)
3195 msurface_t *surface;
3196 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3198 if (!r_worldsurfacevisible[j])
3200 if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
3204 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3207 t = surface->texture;
3208 rsurface_lightmaptexture = surface->lightmaptexture;
3209 rsurface_texture = t->currentframe;
3210 f = rsurface_texture->currentmaterialflags & flagsmask;
3212 if (f && surface->num_triangles)
3214 // if lightmap parameters changed, rebuild lightmap texture
3215 if (surface->cached_dlight)
3216 R_BuildLightMap(ent, surface);
3217 // add face to draw list
3218 surfacelist[numsurfacelist++] = surface;
3219 counttriangles += surface->num_triangles;
3220 if (numsurfacelist >= maxsurfacelist)
3222 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3230 msurface_t *surface;
3231 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3233 if (t != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture)
3237 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3240 t = surface->texture;
3241 rsurface_lightmaptexture = surface->lightmaptexture;
3242 rsurface_texture = t->currentframe;
3243 f = rsurface_texture->currentmaterialflags & flagsmask;
3245 if (f && surface->num_triangles)
3247 // if lightmap parameters changed, rebuild lightmap texture
3248 if (surface->cached_dlight)
3249 R_BuildLightMap(ent, surface);
3250 // add face to draw list
3251 surfacelist[numsurfacelist++] = surface;
3252 counttriangles += surface->num_triangles;
3253 if (numsurfacelist >= maxsurfacelist)
3255 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3262 R_QueueTextureSurfaceList(numsurfacelist, surfacelist);
3263 renderstats.entities_triangles += counttriangles;
3266 if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces)
3269 const msurface_t *surface;
3271 R_Mesh_Matrix(&ent->matrix);
3272 R_Mesh_ColorPointer(NULL);
3273 R_Mesh_ResetTextureState();
3274 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
3275 GL_DepthMask(false);
3276 GL_DepthTest(!r_showdisabledepthtest.integer);
3277 qglPolygonOffset(r_polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_polygonoffset + r_showcollisionbrushes_polygonoffset.value);
3278 for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
3279 if (brush->colbrushf && brush->colbrushf->numtriangles)
3280 R_DrawCollisionBrush(brush->colbrushf);
3281 for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
3282 if (surface->num_collisiontriangles)
3283 R_DrawCollisionSurface(ent, surface);
3284 qglPolygonOffset(r_polygonfactor, r_polygonoffset);
3287 if (r_showtris.integer || r_shownormals.integer)
3290 msurface_t *surface;
3291 const int *elements;
3295 if (r_showdisabledepthtest.integer)
3296 qglDepthFunc(GL_ALWAYS);
3297 GL_BlendFunc(GL_ONE, GL_ZERO);
3298 R_Mesh_ColorPointer(NULL);
3299 R_Mesh_ResetTextureState();
3300 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
3302 if (ent == r_refdef.worldentity && !r_worldsurfacevisible[j])
3304 rsurface_texture = surface->texture->currentframe;
3305 if ((rsurface_texture->currentmaterialflags & flagsmask) && surface->num_triangles)
3307 RSurf_PrepareVerticesForBatch(true, true, 1, &surface);
3308 if (r_showtris.integer)
3310 if (!rsurface_texture->currentlayers->depthmask)
3311 GL_Color(r_showtris.value, 0, 0, 1);
3312 else if (ent == r_refdef.worldentity)
3313 GL_Color(r_showtris.value, r_showtris.value, r_showtris.value, 1);
3315 GL_Color(0, r_showtris.value, 0, 1);
3316 elements = (ent->model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);
3318 for (k = 0;k < surface->num_triangles;k++, elements += 3)
3320 qglArrayElement(elements[0]);qglArrayElement(elements[1]);
3321 qglArrayElement(elements[1]);qglArrayElement(elements[2]);
3322 qglArrayElement(elements[2]);qglArrayElement(elements[0]);
3326 if (r_shownormals.integer)
3328 GL_Color(r_shownormals.value, 0, 0, 1);
3330 for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3332 VectorCopy(rsurface_vertex3f + l * 3, v);
3333 qglVertex3f(v[0], v[1], v[2]);
3334 VectorMA(v, 8, rsurface_svector3f + l * 3, v);
3335 qglVertex3f(v[0], v[1], v[2]);
3338 GL_Color(0, 0, r_shownormals.value, 1);
3340 for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3342 VectorCopy(rsurface_vertex3f + l * 3, v);
3343 qglVertex3f(v[0], v[1], v[2]);
3344 VectorMA(v, 8, rsurface_tvector3f + l * 3, v);
3345 qglVertex3f(v[0], v[1], v[2]);
3348 GL_Color(0, r_shownormals.value, 0, 1);
3350 for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
3352 VectorCopy(rsurface_vertex3f + l * 3, v);
3353 qglVertex3f(v[0], v[1], v[2]);
3354 VectorMA(v, 8, rsurface_normal3f + l * 3, v);
3355 qglVertex3f(v[0], v[1], v[2]);
3361 rsurface_texture = NULL;
3362 if (r_showdisabledepthtest.integer)
3363 qglDepthFunc(GL_LEQUAL);