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 // used for dlight push checking and other things
31 matrix4x4_t r_identitymatrix;
33 int c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights, c_meshs, c_meshelements, c_rt_lights, c_rt_clears, c_rt_scissored, c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris, c_rtcached_shadowmeshes, c_rtcached_shadowtris, c_bloom, c_bloomcopies, c_bloomcopypixels, c_bloomdraws, c_bloomdrawpixels;
35 // true during envmap command capture
38 // maximum visible distance (recalculated from world box each frame)
40 // brightness of world lightmaps and related lighting
41 // (often reduced when world rtlights are enabled)
42 float r_lightmapintensity;
43 // whether to draw world lights realtime, dlights realtime, and their shadows
45 qboolean r_rtworldshadows;
47 qboolean r_rtdlightshadows;
50 // forces all rendering to draw triangle outlines
67 matrix4x4_t r_view_matrix;
74 // 8.8 fraction of base light value
75 unsigned short d_lightstylevalue[256];
77 cvar_t r_showtris = {0, "r_showtris", "0"};
78 cvar_t r_drawentities = {0, "r_drawentities","1"};
79 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"};
80 cvar_t r_speeds = {0, "r_speeds","0"};
81 cvar_t r_fullbright = {0, "r_fullbright","0"};
82 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1"};
83 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1"};
84 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"};
85 cvar_t r_drawcollisionbrushes = {0, "r_drawcollisionbrushes", "0"};
87 cvar_t gl_fogenable = {0, "gl_fogenable", "0"};
88 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25"};
89 cvar_t gl_fogred = {0, "gl_fogred","0.3"};
90 cvar_t gl_foggreen = {0, "gl_foggreen","0.3"};
91 cvar_t gl_fogblue = {0, "gl_fogblue","0.3"};
92 cvar_t gl_fogstart = {0, "gl_fogstart", "0"};
93 cvar_t gl_fogend = {0, "gl_fogend","0"};
95 cvar_t r_textureunits = {0, "r_textureunits", "32"};
97 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1"};
98 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1"};
99 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1"};
100 cvar_t r_watershader = {CVAR_SAVE, "r_watershader", "1"};
102 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0"};
103 cvar_t r_bloom_intensity = {CVAR_SAVE, "r_bloom_intensity", "2"};
104 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "8"};
105 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320"};
106 cvar_t r_bloom_power = {CVAR_SAVE, "r_bloom_power", "4"};
108 cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1"};
110 cvar_t developer_texturelogging = {0, "developer_texturelogging", "0"};
112 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"};
114 rtexturepool_t *r_main_texturepool;
115 rtexture_t *r_bloom_texture_screen;
116 rtexture_t *r_bloom_texture_bloom;
117 rtexture_t *r_texture_blanknormalmap;
118 rtexture_t *r_texture_white;
119 rtexture_t *r_texture_black;
120 rtexture_t *r_texture_notexture;
121 rtexture_t *r_texture_whitecube;
122 rtexture_t *r_texture_normalizationcube;
123 rtexture_t *r_texture_detailtextures[NUM_DETAILTEXTURES];
124 rtexture_t *r_texture_distorttexture[64];
126 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
129 for (i = 0;i < verts;i++)
140 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
143 for (i = 0;i < verts;i++)
155 float fog_density, fog_red, fog_green, fog_blue;
157 qboolean oldgl_fogenable;
158 void R_UpdateFog(void)
160 if (gamemode == GAME_NEHAHRA)
162 if (gl_fogenable.integer)
164 oldgl_fogenable = true;
165 fog_density = gl_fogdensity.value;
166 fog_red = gl_fogred.value;
167 fog_green = gl_foggreen.value;
168 fog_blue = gl_fogblue.value;
170 else if (oldgl_fogenable)
172 oldgl_fogenable = false;
181 fogcolor[0] = fog_red = bound(0.0f, fog_red , 1.0f);
182 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
183 fogcolor[2] = fog_blue = bound(0.0f, fog_blue , 1.0f);
188 fogdensity = -4000.0f / (fog_density * fog_density);
189 // fog color was already set
195 // FIXME: move this to client?
198 if (gamemode == GAME_NEHAHRA)
200 Cvar_Set("gl_fogenable", "0");
201 Cvar_Set("gl_fogdensity", "0.2");
202 Cvar_Set("gl_fogred", "0.3");
203 Cvar_Set("gl_foggreen", "0.3");
204 Cvar_Set("gl_fogblue", "0.3");
206 fog_density = fog_red = fog_green = fog_blue = 0.0f;
209 // FIXME: move this to client?
210 void FOG_registercvars(void)
212 if (gamemode == GAME_NEHAHRA)
214 Cvar_RegisterVariable (&gl_fogenable);
215 Cvar_RegisterVariable (&gl_fogdensity);
216 Cvar_RegisterVariable (&gl_fogred);
217 Cvar_RegisterVariable (&gl_foggreen);
218 Cvar_RegisterVariable (&gl_fogblue);
219 Cvar_RegisterVariable (&gl_fogstart);
220 Cvar_RegisterVariable (&gl_fogend);
224 static void R_BuildDetailTextures (void)
227 float vc[3], vx[3], vy[3], vn[3], lightdir[3];
228 #define DETAILRESOLUTION 256
229 qbyte (*data)[DETAILRESOLUTION][4];
230 qbyte (*noise)[DETAILRESOLUTION];
232 // Allocate the buffers dynamically to avoid having such big guys on the stack
233 data = Mem_Alloc(tempmempool, DETAILRESOLUTION * sizeof(*data));
234 noise = Mem_Alloc(tempmempool, DETAILRESOLUTION * sizeof(*noise));
239 VectorNormalize(lightdir);
240 for (i = 0;i < NUM_DETAILTEXTURES;i++)
242 fractalnoise(&noise[0][0], DETAILRESOLUTION, DETAILRESOLUTION >> 4);
243 for (y = 0;y < DETAILRESOLUTION;y++)
245 for (x = 0;x < DETAILRESOLUTION;x++)
249 vc[2] = noise[y][x] * (1.0f / 32.0f);
252 vx[2] = noise[y][(x + 1) % DETAILRESOLUTION] * (1.0f / 32.0f);
255 vy[2] = noise[(y + 1) % DETAILRESOLUTION][x] * (1.0f / 32.0f);
256 VectorSubtract(vx, vc, vx);
257 VectorSubtract(vy, vc, vy);
258 CrossProduct(vx, vy, vn);
260 light = 128 - DotProduct(vn, lightdir) * 128;
261 light = bound(0, light, 255);
262 data[y][x][0] = data[y][x][1] = data[y][x][2] = light;
266 r_texture_detailtextures[i] = R_LoadTexture2D(r_main_texturepool, va("detailtexture%i", i), DETAILRESOLUTION, DETAILRESOLUTION, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE, NULL);
273 static qbyte R_MorphDistortTexture (double y0, double y1, double y2, double y3, double morph)
275 int m = (int)(((y1 + y3 - (y0 + y2)) * morph * morph * morph) +
276 ((2 * (y0 - y1) + y2 - y3) * morph * morph) +
277 ((y2 - y0) * morph) +
279 return (qbyte)bound(0, m, 255);
282 static void R_BuildDistortTexture (void)
285 #define DISTORTRESOLUTION 32
286 qbyte data[5][DISTORTRESOLUTION][DISTORTRESOLUTION][2];
290 for (y=0; y<DISTORTRESOLUTION; y++)
292 for (x=0; x<DISTORTRESOLUTION; x++)
294 data[i][y][x][0] = rand () & 255;
295 data[i][y][x][1] = rand () & 255;
304 r_texture_distorttexture[i*16+j] = NULL;
305 if (gl_textureshader)
307 for (y=0; y<DISTORTRESOLUTION; y++)
309 for (x=0; x<DISTORTRESOLUTION; x++)
311 data[4][y][x][0] = R_MorphDistortTexture (data[(i-1)&3][y][x][0], data[i][y][x][0], data[(i+1)&3][y][x][0], data[(i+2)&3][y][x][0], 0.0625*j);
312 data[4][y][x][1] = R_MorphDistortTexture (data[(i-1)&3][y][x][1], data[i][y][x][1], data[(i+1)&3][y][x][1], data[(i+2)&3][y][x][1], 0.0625*j);
315 r_texture_distorttexture[i*16+j] = R_LoadTexture2D(r_main_texturepool, va("distorttexture%i", i*16+j), DISTORTRESOLUTION, DISTORTRESOLUTION, &data[4][0][0][0], TEXTYPE_DSDT, TEXF_PRECACHE, NULL);
321 static void R_BuildBlankTextures(void)
324 data[0] = 128; // normal X
325 data[1] = 128; // normal Y
326 data[2] = 255; // normal Z
327 data[3] = 128; // height
328 r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
333 r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
338 r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
341 static void R_BuildNoTexture(void)
344 qbyte pix[16][16][4];
345 // this makes a light grey/dark grey checkerboard texture
346 for (y = 0;y < 16;y++)
348 for (x = 0;x < 16;x++)
350 if ((y < 8) ^ (x < 8))
366 r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL);
369 static void R_BuildWhiteCube(void)
372 data[ 0] = 255;data[ 1] = 255;data[ 2] = 255;data[ 3] = 255;
373 data[ 4] = 255;data[ 5] = 255;data[ 6] = 255;data[ 7] = 255;
374 data[ 8] = 255;data[ 9] = 255;data[10] = 255;data[11] = 255;
375 data[12] = 255;data[13] = 255;data[14] = 255;data[15] = 255;
376 data[16] = 255;data[17] = 255;data[18] = 255;data[19] = 255;
377 data[20] = 255;data[21] = 255;data[22] = 255;data[23] = 255;
378 r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
381 static void R_BuildNormalizationCube(void)
385 vec_t s, t, intensity;
387 qbyte data[6][NORMSIZE][NORMSIZE][4];
388 for (side = 0;side < 6;side++)
390 for (y = 0;y < NORMSIZE;y++)
392 for (x = 0;x < NORMSIZE;x++)
394 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
395 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
429 intensity = 127.0f / sqrt(DotProduct(v, v));
430 data[side][y][x][0] = 128.0f + intensity * v[0];
431 data[side][y][x][1] = 128.0f + intensity * v[1];
432 data[side][y][x][2] = 128.0f + intensity * v[2];
433 data[side][y][x][3] = 255;
437 r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
440 void gl_main_start(void)
442 r_main_texturepool = R_AllocTexturePool();
443 r_bloom_texture_screen = NULL;
444 r_bloom_texture_bloom = NULL;
445 R_BuildBlankTextures();
447 R_BuildDetailTextures();
448 R_BuildDistortTexture();
449 if (gl_texturecubemap)
452 R_BuildNormalizationCube();
456 void gl_main_shutdown(void)
458 R_FreeTexturePool(&r_main_texturepool);
459 r_bloom_texture_screen = NULL;
460 r_bloom_texture_bloom = NULL;
461 r_texture_blanknormalmap = NULL;
462 r_texture_white = NULL;
463 r_texture_black = NULL;
464 r_texture_whitecube = NULL;
465 r_texture_normalizationcube = NULL;
468 extern void CL_ParseEntityLump(char *entitystring);
469 void gl_main_newmap(void)
471 // FIXME: move this code to client
473 char *entities, entname[MAX_QPATH];
477 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
478 l = (int)strlen(entname) - 4;
479 if (l >= 0 && !strcmp(entname + l, ".bsp"))
481 strcpy(entname + l, ".ent");
482 if ((entities = FS_LoadFile(entname, tempmempool, true)))
484 CL_ParseEntityLump(entities);
489 if (cl.worldmodel->brush.entities)
490 CL_ParseEntityLump(cl.worldmodel->brush.entities);
494 void GL_Main_Init(void)
496 Matrix4x4_CreateIdentity(&r_identitymatrix);
497 // FIXME: move this to client?
499 Cvar_RegisterVariable(&r_showtris);
500 Cvar_RegisterVariable(&r_drawentities);
501 Cvar_RegisterVariable(&r_drawviewmodel);
502 Cvar_RegisterVariable(&r_speeds);
503 Cvar_RegisterVariable(&r_fullbrights);
504 Cvar_RegisterVariable(&r_wateralpha);
505 Cvar_RegisterVariable(&r_dynamic);
506 Cvar_RegisterVariable(&r_fullbright);
507 Cvar_RegisterVariable(&r_textureunits);
508 Cvar_RegisterVariable(&r_lerpsprites);
509 Cvar_RegisterVariable(&r_lerpmodels);
510 Cvar_RegisterVariable(&r_waterscroll);
511 Cvar_RegisterVariable(&r_watershader);
512 Cvar_RegisterVariable(&r_drawcollisionbrushes);
513 Cvar_RegisterVariable(&r_bloom);
514 Cvar_RegisterVariable(&r_bloom_intensity);
515 Cvar_RegisterVariable(&r_bloom_blur);
516 Cvar_RegisterVariable(&r_bloom_resolution);
517 Cvar_RegisterVariable(&r_bloom_power);
518 Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
519 Cvar_RegisterVariable(&developer_texturelogging);
520 Cvar_RegisterVariable(&gl_lightmaps);
521 if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE)
522 Cvar_SetValue("r_fullbrights", 0);
523 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
526 static vec3_t r_farclip_origin;
527 static vec3_t r_farclip_direction;
528 static vec_t r_farclip_directiondist;
529 static vec_t r_farclip_meshfarclip;
530 static int r_farclip_directionbit0;
531 static int r_farclip_directionbit1;
532 static int r_farclip_directionbit2;
534 // enlarge farclip to accomodate box
535 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
538 d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
539 + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
540 + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
541 if (r_farclip_meshfarclip < d)
542 r_farclip_meshfarclip = d;
545 // return farclip value
546 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
550 VectorCopy(origin, r_farclip_origin);
551 VectorCopy(direction, r_farclip_direction);
552 r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
553 r_farclip_directionbit0 = r_farclip_direction[0] < 0;
554 r_farclip_directionbit1 = r_farclip_direction[1] < 0;
555 r_farclip_directionbit2 = r_farclip_direction[2] < 0;
556 r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
558 if (r_refdef.worldmodel)
559 R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
560 for (i = 0;i < r_refdef.numentities;i++)
561 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
563 return r_farclip_meshfarclip - r_farclip_directiondist;
566 extern void R_Textures_Init(void);
567 extern void GL_Draw_Init(void);
568 extern void GL_Main_Init(void);
569 extern void R_Shadow_Init(void);
570 extern void R_Sky_Init(void);
571 extern void GL_Surf_Init(void);
572 extern void R_Crosshairs_Init(void);
573 extern void R_Light_Init(void);
574 extern void R_Particles_Init(void);
575 extern void R_Explosion_Init(void);
576 extern void gl_backend_init(void);
577 extern void Sbar_Init(void);
578 extern void R_LightningBeams_Init(void);
579 extern void Mod_RenderInit(void);
581 void Render_Init(void)
597 R_LightningBeams_Init();
606 extern char *ENGINE_EXTENSIONS;
609 VID_CheckExtensions();
611 // LordHavoc: report supported extensions
612 Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions );
614 // clear to black (loading plaque will be seen over this)
615 qglClearColor(0,0,0,1);
616 qglClear(GL_COLOR_BUFFER_BIT);
619 int R_CullBox(const vec3_t mins, const vec3_t maxs)
623 for (i = 0;i < 4;i++)
630 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
634 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
638 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
642 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
646 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
650 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
654 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
658 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
666 //==================================================================================
668 static void R_MarkEntities (void)
671 entity_render_t *ent;
673 if (!r_drawentities.integer)
676 r_refdef.worldentity->visframe = r_framecount;
677 renderimask = envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL);
678 if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
680 // worldmodel can check visibility
681 for (i = 0;i < r_refdef.numentities;i++)
683 ent = r_refdef.entities[i];
684 Mod_CheckLoaded(ent->model);
685 // some of the renderer still relies on origin...
686 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
687 // some of the renderer still relies on scale...
688 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
689 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)))
691 R_UpdateEntLights(ent);
692 ent->visframe = r_framecount;
698 // no worldmodel or it can't check visibility
699 for (i = 0;i < r_refdef.numentities;i++)
701 ent = r_refdef.entities[i];
702 Mod_CheckLoaded(ent->model);
703 // some of the renderer still relies on origin...
704 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
705 // some of the renderer still relies on scale...
706 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
707 if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST))
709 R_UpdateEntLights(ent);
710 ent->visframe = r_framecount;
716 // only used if skyrendermasked, and normally returns false
717 int R_DrawBrushModelsSky (void)
720 entity_render_t *ent;
722 if (!r_drawentities.integer)
726 for (i = 0;i < r_refdef.numentities;i++)
728 ent = r_refdef.entities[i];
729 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
731 ent->model->DrawSky(ent);
738 void R_DrawNoModel(entity_render_t *ent);
739 void R_DrawModels(void)
742 entity_render_t *ent;
744 if (!r_drawentities.integer)
747 for (i = 0;i < r_refdef.numentities;i++)
749 ent = r_refdef.entities[i];
750 if (ent->visframe == r_framecount)
752 if (ent->model && ent->model->Draw != NULL)
753 ent->model->Draw(ent);
760 static void R_SetFrustum(void)
762 // break apart the view matrix into vectors for various purposes
763 Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
764 VectorNegate(r_viewleft, r_viewright);
766 // LordHavoc: note to all quake engine coders, the special case for 90
767 // degrees assumed a square view (wrong), so I removed it, Quake2 has it
770 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
771 RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_view_fov_x / 2));
772 frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
773 PlaneClassify(&frustum[0]);
775 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
776 RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_view_fov_x / 2));
777 frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
778 PlaneClassify(&frustum[1]);
780 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
781 RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_view_fov_y / 2));
782 frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
783 PlaneClassify(&frustum[2]);
785 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
786 RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_view_fov_y / 2));
787 frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
788 PlaneClassify(&frustum[3]);
791 VectorCopy(r_viewforward, frustum[4].normal);
792 frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + 1.0f;
793 PlaneClassify(&frustum[4]);
796 static void R_BlendView(void)
800 if (r_refdef.viewblend[3] < 0.01f && !r_bloom.integer)
803 GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
806 R_Mesh_Matrix(&r_identitymatrix);
807 // vertex coordinates for a quad that covers the screen exactly
808 varray_vertex3f[0] = 0;varray_vertex3f[1] = 0;varray_vertex3f[2] = 0;
809 varray_vertex3f[3] = 1;varray_vertex3f[4] = 0;varray_vertex3f[5] = 0;
810 varray_vertex3f[6] = 1;varray_vertex3f[7] = 1;varray_vertex3f[8] = 0;
811 varray_vertex3f[9] = 0;varray_vertex3f[10] = 1;varray_vertex3f[11] = 0;
812 if (r_bloom.integer && 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)
814 int screenwidth, screenheight, bloomwidth, bloomheight, x, dobloomblend, range;
815 float xoffset, yoffset, r;
817 // set the (poorly named) screenwidth and screenheight variables to
818 // a power of 2 at least as large as the screen, these will define the
819 // size of the texture to allocate
820 for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2);
821 for (screenheight = 1;screenheight < vid.height;screenheight *= 2);
822 // allocate textures as needed
823 if (!r_bloom_texture_screen)
824 r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
825 if (!r_bloom_texture_bloom)
826 r_bloom_texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
827 // set bloomwidth and bloomheight to the bloom resolution that will be
828 // used (often less than the screen resolution for faster rendering)
829 bloomwidth = min(r_view_width, r_bloom_resolution.integer);
830 bloomheight = min(r_view_height, bloomwidth * r_view_height / r_view_width);
831 // set up a texcoord array for the full resolution screen image
832 // (we have to keep this around to copy back during final render)
833 varray_texcoord2f[0][0] = 0;
834 varray_texcoord2f[0][1] = (float)r_view_height / (float)screenheight;
835 varray_texcoord2f[0][2] = (float)r_view_width / (float)screenwidth;
836 varray_texcoord2f[0][3] = (float)r_view_height / (float)screenheight;
837 varray_texcoord2f[0][4] = (float)r_view_width / (float)screenwidth;
838 varray_texcoord2f[0][5] = 0;
839 varray_texcoord2f[0][6] = 0;
840 varray_texcoord2f[0][7] = 0;
841 // set up a texcoord array for the reduced resolution bloom image
842 // (which will be additive blended over the screen image)
843 varray_texcoord2f[1][0] = 0;
844 varray_texcoord2f[1][1] = (float)bloomheight / (float)screenheight;
845 varray_texcoord2f[1][2] = (float)bloomwidth / (float)screenwidth;
846 varray_texcoord2f[1][3] = (float)bloomheight / (float)screenheight;
847 varray_texcoord2f[1][4] = (float)bloomwidth / (float)screenwidth;
848 varray_texcoord2f[1][5] = 0;
849 varray_texcoord2f[1][6] = 0;
850 varray_texcoord2f[1][7] = 0;
851 memset(&m, 0, sizeof(m));
852 m.pointer_vertex = varray_vertex3f;
853 m.pointer_texcoord[0] = varray_texcoord2f[0];
854 m.tex[0] = R_GetTexture(r_bloom_texture_screen);
856 // copy view into the full resolution screen image texture
858 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
860 c_bloomcopypixels += r_view_width * r_view_height;
861 // now scale it down to the bloom size and raise to a power of itself
862 // to darken it (this leaves the really bright stuff bright, and
863 // everything else becomes very dark)
864 // TODO: optimize with multitexture or GLSL
865 qglViewport(r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
866 GL_BlendFunc(GL_ONE, GL_ZERO);
867 GL_Color(1, 1, 1, 1);
868 R_Mesh_Draw(0, 4, 2, polygonelements);
870 c_bloomdrawpixels += bloomwidth * bloomheight;
871 // render multiple times with a multiply blendfunc to raise to a power
872 GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
873 for (x = 1;x < r_bloom_power.integer;x++)
875 R_Mesh_Draw(0, 4, 2, polygonelements);
877 c_bloomdrawpixels += bloomwidth * bloomheight;
879 // we now have a darkened bloom image in the framebuffer, copy it into
880 // the bloom image texture for more processing
881 memset(&m, 0, sizeof(m));
882 m.pointer_vertex = varray_vertex3f;
883 m.tex[0] = R_GetTexture(r_bloom_texture_bloom);
884 m.pointer_texcoord[0] = varray_texcoord2f[2];
887 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
889 c_bloomcopypixels += bloomwidth * bloomheight;
890 // blend on at multiple vertical offsets to achieve a vertical blur
891 // TODO: do offset blends using GLSL
892 range = r_bloom_blur.integer * bloomwidth / 320;
893 GL_BlendFunc(GL_ONE, GL_ZERO);
894 for (x = -range;x <= range;x++)
896 xoffset = 0 / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
897 yoffset = x / (float)bloomheight * (float)bloomheight / (float)screenheight;
898 // compute a texcoord array with the specified x and y offset
899 varray_texcoord2f[2][0] = xoffset+0;
900 varray_texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
901 varray_texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
902 varray_texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
903 varray_texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
904 varray_texcoord2f[2][5] = yoffset+0;
905 varray_texcoord2f[2][6] = xoffset+0;
906 varray_texcoord2f[2][7] = yoffset+0;
907 // this r value looks like a 'dot' particle, fading sharply to
908 // black at the edges
909 // (probably not realistic but looks good enough)
910 r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
913 GL_Color(r, r, r, 1);
914 R_Mesh_Draw(0, 4, 2, polygonelements);
916 c_bloomdrawpixels += bloomwidth * bloomheight;
917 GL_BlendFunc(GL_ONE, GL_ONE);
919 // copy the vertically blurred bloom view to a texture
921 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
923 c_bloomcopypixels += bloomwidth * bloomheight;
924 // blend the vertically blurred image at multiple offsets horizontally
925 // to finish the blur effect
926 // TODO: do offset blends using GLSL
927 range = r_bloom_blur.integer * bloomwidth / 320;
928 GL_BlendFunc(GL_ONE, GL_ZERO);
929 for (x = -range;x <= range;x++)
931 xoffset = x / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
932 yoffset = 0 / (float)bloomheight * (float)bloomheight / (float)screenheight;
933 // compute a texcoord array with the specified x and y offset
934 varray_texcoord2f[2][0] = xoffset+0;
935 varray_texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
936 varray_texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
937 varray_texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
938 varray_texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
939 varray_texcoord2f[2][5] = yoffset+0;
940 varray_texcoord2f[2][6] = xoffset+0;
941 varray_texcoord2f[2][7] = yoffset+0;
942 // this r value looks like a 'dot' particle, fading sharply to
943 // black at the edges
944 // (probably not realistic but looks good enough)
945 r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
948 GL_Color(r, r, r, 1);
949 R_Mesh_Draw(0, 4, 2, polygonelements);
951 c_bloomdrawpixels += bloomwidth * bloomheight;
952 GL_BlendFunc(GL_ONE, GL_ONE);
954 // copy the blurred bloom view to a texture
956 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
958 c_bloomcopypixels += bloomwidth * bloomheight;
959 // go back to full view area
960 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
961 // put the original screen image back in place and blend the bloom
963 memset(&m, 0, sizeof(m));
964 m.pointer_vertex = varray_vertex3f;
965 m.tex[0] = R_GetTexture(r_bloom_texture_screen);
966 m.pointer_texcoord[0] = varray_texcoord2f[0];
968 dobloomblend = false;
970 // do both in one pass if possible
971 if (r_textureunits.integer >= 2 && gl_combine.integer)
973 dobloomblend = false;
974 m.texcombinergb[1] = GL_ADD;
975 m.tex[1] = R_GetTexture(r_bloom_texture_bloom);
976 m.pointer_texcoord[1] = varray_texcoord2f[1];
982 GL_BlendFunc(GL_ONE, GL_ZERO);
984 R_Mesh_Draw(0, 4, 2, polygonelements);
986 c_bloomdrawpixels += r_view_width * r_view_height;
987 // now blend on the bloom texture if multipass
990 memset(&m, 0, sizeof(m));
991 m.pointer_vertex = varray_vertex3f;
992 m.tex[0] = R_GetTexture(r_bloom_texture_bloom);
993 m.pointer_texcoord[0] = varray_texcoord2f[1];
995 GL_BlendFunc(GL_ONE, GL_ONE);
997 R_Mesh_Draw(0, 4, 2, polygonelements);
999 c_bloomdrawpixels += r_view_width * r_view_height;
1002 if (r_refdef.viewblend[3] >= 0.01f)
1004 // apply a color tint to the whole view
1005 memset(&m, 0, sizeof(m));
1006 m.pointer_vertex = varray_vertex3f;
1008 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1009 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
1010 R_Mesh_Draw(0, 4, 2, polygonelements);
1014 void R_RenderScene(void);
1016 matrix4x4_t r_waterscrollmatrix;
1023 void R_RenderView(void)
1025 if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
1026 return; //Host_Error ("R_RenderView: NULL worldmodel");
1028 r_view_width = bound(0, r_refdef.width, vid.width);
1029 r_view_height = bound(0, r_refdef.height, vid.height);
1031 r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
1032 r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
1034 r_view_fov_x = bound(1, r_refdef.fov_x, 170);
1035 r_view_fov_y = bound(1, r_refdef.fov_y, 170);
1036 r_view_matrix = r_refdef.viewentitymatrix;
1037 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1038 r_rtworld = r_shadow_realtime_world.integer;
1039 r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
1040 r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
1041 r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
1042 r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
1044 // GL is weird because it's bottom to top, r_view_y is top to bottom
1045 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
1046 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
1047 GL_ScissorTest(true);
1053 R_TimeReport("setup");
1055 qglDepthFunc(GL_LEQUAL);
1056 qglPolygonOffset(0, 0);
1057 qglEnable(GL_POLYGON_OFFSET_FILL);
1061 qglPolygonOffset(0, 0);
1062 qglDisable(GL_POLYGON_OFFSET_FILL);
1065 R_TimeReport("blendview");
1067 GL_Scissor(0, 0, vid.width, vid.height);
1068 GL_ScissorTest(false);
1071 extern void R_DrawLightningBeams (void);
1072 void R_RenderScene(void)
1074 // don't let sound skip if going slow
1075 if (r_refdef.extraupdate)
1080 R_MeshQueue_BeginScene();
1082 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
1086 r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
1087 if (r_rtworldshadows || r_rtdlightshadows)
1088 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f);
1090 GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip);
1092 GL_SetupView_Orientation_FromEntity(&r_view_matrix);
1094 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);
1098 R_WorldVisibility();
1099 R_TimeReport("worldvis");
1102 R_TimeReport("markentity");
1104 R_Shadow_UpdateWorldLightSelection();
1106 // don't let sound skip if going slow
1107 if (r_refdef.extraupdate)
1110 GL_ShowTrisColor(0.025, 0.025, 0, 1);
1111 if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
1113 r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
1114 R_TimeReport("worldsky");
1117 if (R_DrawBrushModelsSky())
1118 R_TimeReport("bmodelsky");
1120 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
1121 if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
1123 r_refdef.worldmodel->Draw(r_refdef.worldentity);
1124 R_TimeReport("world");
1127 // don't let sound skip if going slow
1128 if (r_refdef.extraupdate)
1131 GL_ShowTrisColor(0, 0.015, 0, 1);
1134 R_TimeReport("models");
1136 // don't let sound skip if going slow
1137 if (r_refdef.extraupdate)
1140 GL_ShowTrisColor(0, 0, 0.033, 1);
1141 R_ShadowVolumeLighting(false);
1142 R_TimeReport("rtlights");
1144 // don't let sound skip if going slow
1145 if (r_refdef.extraupdate)
1148 GL_ShowTrisColor(0.1, 0, 0, 1);
1150 R_DrawLightningBeams();
1151 R_TimeReport("lightning");
1154 R_TimeReport("particles");
1157 R_TimeReport("explosions");
1159 R_MeshQueue_RenderTransparent();
1160 R_TimeReport("drawtrans");
1163 R_TimeReport("coronas");
1165 R_DrawWorldCrosshair();
1166 R_TimeReport("crosshair");
1168 R_MeshQueue_Render();
1169 R_MeshQueue_EndScene();
1171 if ((r_shadow_visiblelighting.integer || r_shadow_visiblevolumes.integer) && !r_showtrispass)
1173 R_ShadowVolumeLighting(true);
1174 R_TimeReport("visiblevolume");
1177 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
1179 // don't let sound skip if going slow
1180 if (r_refdef.extraupdate)
1185 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
1188 float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
1190 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1191 GL_DepthMask(false);
1193 R_Mesh_Matrix(&r_identitymatrix);
1195 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
1196 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
1197 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
1198 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
1199 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
1200 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
1201 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
1202 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
1203 R_FillColors(color, 8, cr, cg, cb, ca);
1206 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
1208 VectorSubtract(v, r_vieworigin, diff);
1209 f2 = exp(fogdensity/DotProduct(diff, diff));
1211 c[0] = c[0] * f1 + fogcolor[0] * f2;
1212 c[1] = c[1] * f1 + fogcolor[1] * f2;
1213 c[2] = c[2] * f1 + fogcolor[2] * f2;
1216 memset(&m, 0, sizeof(m));
1217 m.pointer_vertex = vertex3f;
1218 m.pointer_color = color;
1224 int nomodelelements[24] =
1236 float nomodelvertex3f[6*3] =
1246 float nomodelcolor4f[6*4] =
1248 0.0f, 0.0f, 0.5f, 1.0f,
1249 0.0f, 0.0f, 0.5f, 1.0f,
1250 0.0f, 0.5f, 0.0f, 1.0f,
1251 0.0f, 0.5f, 0.0f, 1.0f,
1252 0.5f, 0.0f, 0.0f, 1.0f,
1253 0.5f, 0.0f, 0.0f, 1.0f
1256 void R_DrawNoModelCallback(const void *calldata1, int calldata2)
1258 const entity_render_t *ent = calldata1;
1260 float f1, f2, *c, diff[3];
1263 R_Mesh_Matrix(&ent->matrix);
1265 memset(&m, 0, sizeof(m));
1266 m.pointer_vertex = nomodelvertex3f;
1268 if (ent->flags & EF_ADDITIVE)
1270 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
1271 GL_DepthMask(false);
1273 else if (ent->alpha < 1)
1275 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1276 GL_DepthMask(false);
1280 GL_BlendFunc(GL_ONE, GL_ZERO);
1283 GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
1286 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
1287 m.pointer_color = color4f;
1288 VectorSubtract(ent->origin, r_vieworigin, diff);
1289 f2 = exp(fogdensity/DotProduct(diff, diff));
1291 for (i = 0, c = color4f;i < 6;i++, c += 4)
1293 c[0] = (c[0] * f1 + fogcolor[0] * f2);
1294 c[1] = (c[1] * f1 + fogcolor[1] * f2);
1295 c[2] = (c[2] * f1 + fogcolor[2] * f2);
1299 else if (ent->alpha != 1)
1301 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
1302 m.pointer_color = color4f;
1303 for (i = 0, c = color4f;i < 6;i++, c += 4)
1307 m.pointer_color = nomodelcolor4f;
1309 R_Mesh_Draw(0, 6, 8, nomodelelements);
1312 void R_DrawNoModel(entity_render_t *ent)
1314 //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
1315 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModelCallback, ent, 0);
1317 // R_DrawNoModelCallback(ent, 0);
1320 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
1322 vec3_t right1, right2, diff, normal;
1324 VectorSubtract (org2, org1, normal);
1326 // calculate 'right' vector for start
1327 VectorSubtract (r_vieworigin, org1, diff);
1328 CrossProduct (normal, diff, right1);
1329 VectorNormalize (right1);
1331 // calculate 'right' vector for end
1332 VectorSubtract (r_vieworigin, org2, diff);
1333 CrossProduct (normal, diff, right2);
1334 VectorNormalize (right2);
1336 vert[ 0] = org1[0] + width * right1[0];
1337 vert[ 1] = org1[1] + width * right1[1];
1338 vert[ 2] = org1[2] + width * right1[2];
1339 vert[ 3] = org1[0] - width * right1[0];
1340 vert[ 4] = org1[1] - width * right1[1];
1341 vert[ 5] = org1[2] - width * right1[2];
1342 vert[ 6] = org2[0] - width * right2[0];
1343 vert[ 7] = org2[1] - width * right2[1];
1344 vert[ 8] = org2[2] - width * right2[2];
1345 vert[ 9] = org2[0] + width * right2[0];
1346 vert[10] = org2[1] + width * right2[1];
1347 vert[11] = org2[2] + width * right2[2];
1350 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
1352 void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, 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)
1359 VectorSubtract(origin, r_vieworigin, diff);
1360 ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
1363 R_Mesh_Matrix(&r_identitymatrix);
1364 GL_BlendFunc(blendfunc1, blendfunc2);
1365 GL_DepthMask(false);
1366 GL_DepthTest(!depthdisable);
1368 varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
1369 varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
1370 varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
1371 varray_vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
1372 varray_vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
1373 varray_vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
1374 varray_vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
1375 varray_vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
1376 varray_vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
1377 varray_vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
1378 varray_vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
1379 varray_vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
1381 memset(&m, 0, sizeof(m));
1382 m.tex[0] = R_GetTexture(texture);
1383 m.pointer_texcoord[0] = spritetexcoord2f;
1384 m.pointer_vertex = varray_vertex3f;
1386 GL_Color(cr, cg, cb, ca);
1387 R_Mesh_Draw(0, 4, 2, polygonelements);
1390 int R_Mesh_AddVertex3f(rmesh_t *mesh, const float *v)
1394 for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
1395 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
1397 if (i == mesh->numvertices)
1399 if (mesh->numvertices < mesh->maxvertices)
1401 VectorCopy(v, vertex3f);
1402 mesh->numvertices++;
1404 return mesh->numvertices;
1410 void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
1414 element[0] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
1415 element[1] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
1416 e = mesh->element3i + mesh->numtriangles * 3;
1417 for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
1419 element[2] = R_Mesh_AddVertex3f(mesh, vertex3f);
1420 if (mesh->numtriangles < mesh->maxtriangles)
1425 mesh->numtriangles++;
1427 element[1] = element[2];
1431 void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
1433 int planenum, planenum2;
1436 mplane_t *plane, *plane2;
1437 float temppoints[2][256*3];
1438 for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
1442 PolygonF_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->normal[3], 1024.0*1024.0*1024.0);
1443 for (planenum2 = 0, plane2 = planes;planenum2 < numplanes && tempnumpoints >= 3;planenum2++, plane2++)
1445 if (planenum2 == planenum)
1447 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);
1450 if (tempnumpoints < 3)
1452 // generate elements forming a triangle fan for this polygon
1453 R_Mesh_AddPolygon3f(mesh, tempnumpoints, temppoints[w]);
1457 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
1459 texture_t *texture = t;
1460 model_t *model = ent->model;
1461 int s = ent->skinnum;
1462 if ((unsigned int)s >= (unsigned int)model->numskins)
1466 if (model->skinscenes)
1468 if (model->skinscenes[s].framecount > 1)
1469 s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
1471 s = model->skinscenes[s].firstframe;
1474 t = t + s * model->num_surfaces;
1476 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];
1477 texture->currentframe = t;
1478 t->currentmaterialflags = t->basematerialflags;
1479 t->currentalpha = ent->alpha;
1480 if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
1481 t->currentalpha *= r_wateralpha.value;
1482 if (!(ent->flags & RENDER_LIGHT))
1483 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
1484 if (ent->effects & EF_ADDITIVE)
1485 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_TRANSPARENT;
1486 else if (t->currentalpha < 1)
1487 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT;
1488 if (ent->effects & EF_NODEPTHTEST)
1489 t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST;
1490 if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
1491 t->currenttexmatrix = r_waterscrollmatrix;
1493 t->currenttexmatrix = r_identitymatrix;
1496 void R_UpdateAllTextureInfo(entity_render_t *ent)
1500 for (i = 0;i < ent->model->num_textures;i++)
1501 R_UpdateTextureInfo(ent, ent->model->data_textures + i);
1504 float *rsurface_vertex3f;
1505 float *rsurface_svector3f;
1506 float *rsurface_tvector3f;
1507 float *rsurface_normal3f;
1508 float *rsurface_lightmapcolor4f;
1510 void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg)
1513 float center[3], forward[3], right[3], up[3], v[4][3];
1514 matrix4x4_t matrix1, imatrix1;
1515 if ((ent->frameblend[0].lerp != 1 || ent->frameblend[0].frame != 0) && (surface->groupmesh->data_morphvertex3f || surface->groupmesh->data_vertexboneweights))
1517 rsurface_vertex3f = varray_vertex3f;
1518 rsurface_svector3f = NULL;
1519 rsurface_tvector3f = NULL;
1520 rsurface_normal3f = NULL;
1521 Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, surface->groupmesh, rsurface_vertex3f);
1525 rsurface_vertex3f = surface->groupmesh->data_vertex3f;
1526 rsurface_svector3f = surface->groupmesh->data_svector3f;
1527 rsurface_tvector3f = surface->groupmesh->data_tvector3f;
1528 rsurface_normal3f = surface->groupmesh->data_normal3f;
1530 if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
1532 if (!rsurface_svector3f)
1534 rsurface_svector3f = varray_svector3f;
1535 rsurface_tvector3f = varray_tvector3f;
1536 rsurface_normal3f = varray_normal3f;
1537 Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer);
1539 // a single autosprite surface can contain multiple sprites...
1540 VectorClear(forward);
1542 VectorSet(up, 0, 0, 1);
1543 for (j = 0;j < surface->num_vertices - 3;j += 4)
1545 VectorClear(center);
1546 for (i = 0;i < 4;i++)
1547 VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
1548 VectorScale(center, 0.25f, center);
1549 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
1550 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);
1551 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
1552 for (i = 0;i < 4;i++)
1553 Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
1554 forward[0] = modelorg[0] - center[0];
1555 forward[1] = modelorg[1] - center[1];
1556 VectorNormalize(forward);
1557 right[0] = forward[1];
1558 right[1] = -forward[0];
1559 for (i = 0;i < 4;i++)
1560 VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (surface->num_firstvertex+i+j) * 3);
1562 rsurface_vertex3f = varray_vertex3f;
1563 rsurface_svector3f = NULL;
1564 rsurface_tvector3f = NULL;
1565 rsurface_normal3f = NULL;
1567 else if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE)
1569 if (!rsurface_svector3f)
1571 rsurface_svector3f = varray_svector3f;
1572 rsurface_tvector3f = varray_tvector3f;
1573 rsurface_normal3f = varray_normal3f;
1574 Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer);
1576 Matrix4x4_Transform(&ent->inversematrix, r_viewforward, forward);
1577 Matrix4x4_Transform(&ent->inversematrix, r_viewright, right);
1578 Matrix4x4_Transform(&ent->inversematrix, r_viewup, up);
1579 // a single autosprite surface can contain multiple sprites...
1580 for (j = 0;j < surface->num_vertices - 3;j += 4)
1582 VectorClear(center);
1583 for (i = 0;i < 4;i++)
1584 VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
1585 VectorScale(center, 0.25f, center);
1586 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
1587 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);
1588 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
1589 for (i = 0;i < 4;i++)
1590 Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
1591 for (i = 0;i < 4;i++)
1592 VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (surface->num_firstvertex+i+j) * 3);
1594 rsurface_vertex3f = varray_vertex3f;
1595 rsurface_svector3f = NULL;
1596 rsurface_tvector3f = NULL;
1597 rsurface_normal3f = NULL;
1599 R_Mesh_VertexPointer(rsurface_vertex3f);
1602 void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface, const vec3_t modelorg, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog)
1610 vec4_t ambientcolor4f;
1611 vec3_t diffusecolor;
1612 vec3_t diffusenormal;
1613 if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, r*0.5f, g*0.5f, b*0.5f, a, false))
1615 rsurface_lightmapcolor4f = varray_color4f;
1616 if (rsurface_normal3f == NULL)
1618 rsurface_normal3f = varray_normal3f;
1619 Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle, rsurface_normal3f, r_smoothnormals_areaweighting.integer);
1621 R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, surface->groupmesh->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, rsurface_lightmapcolor4f + 4 * surface->num_firstvertex);
1630 r = ambientcolor4f[0];
1631 g = ambientcolor4f[1];
1632 b = ambientcolor4f[2];
1633 a = ambientcolor4f[3];
1634 rsurface_lightmapcolor4f = NULL;
1637 else if (lightmode >= 1)
1639 if (surface->lightmapinfo)
1641 rsurface_lightmapcolor4f = varray_color4f;
1642 for (i = 0, c = rsurface_lightmapcolor4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
1644 const qbyte *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i];
1645 float scale = d_lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
1646 VectorScale(lm, scale, c);
1647 if (surface->lightmapinfo->styles[1] != 255)
1649 int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
1651 scale = d_lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
1652 VectorMA(c, scale, lm, c);
1653 if (surface->lightmapinfo->styles[2] != 255)
1656 scale = d_lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
1657 VectorMA(c, scale, lm, c);
1658 if (surface->lightmapinfo->styles[3] != 255)
1661 scale = d_lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
1662 VectorMA(c, scale, lm, c);
1669 rsurface_lightmapcolor4f = surface->groupmesh->data_lightmapcolor4f;
1672 rsurface_lightmapcolor4f = NULL;
1675 if (rsurface_lightmapcolor4f)
1677 for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4, c2 += 4)
1679 VectorSubtract(v, modelorg, diff);
1680 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1689 for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c2 += 4)
1691 VectorSubtract(v, modelorg, diff);
1692 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1699 rsurface_lightmapcolor4f = varray_color4f;
1701 if (applycolor && rsurface_lightmapcolor4f)
1703 for (i = 0, c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4, c2 += 4)
1711 R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
1712 GL_Color(r, g, b, a);
1716 static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
1719 int texturesurfaceindex;
1723 float colorpants[3], colorshirt[3];
1724 float f, r, g, b, a, colorscale;
1725 const msurface_t *surface;
1726 qboolean dolightmap;
1731 qboolean fogallpasses;
1734 qboolean dofullbrightpants;
1735 qboolean dofullbrightshirt;
1736 qboolean applycolor;
1737 qboolean lightmode = 0;
1738 rtexture_t *basetexture;
1740 if (texture->currentmaterialflags & MATERIALFLAG_NODRAW)
1742 c_faces += texturenumsurfaces;
1743 // FIXME: identify models using a better check than ent->model->shadowmesh
1744 if (!(ent->effects & EF_FULLBRIGHT) && !ent->model->brush.shadowmesh)
1746 // gl_lightmaps debugging mode skips normal texturing
1747 if (gl_lightmaps.integer)
1749 GL_BlendFunc(GL_ONE, GL_ZERO);
1752 qglDisable(GL_CULL_FACE);
1753 GL_Color(1, 1, 1, 1);
1754 memset(&m, 0, sizeof(m));
1756 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1758 surface = texturesurfacelist[texturesurfaceindex];
1759 R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
1760 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
1761 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
1762 RSurf_SetColorPointer(ent, surface, modelorg, 1, 1, 1, 1, lightmode ? lightmode : !surface->lightmaptexture, false, false);
1763 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
1764 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
1765 GL_LockArrays(0, 0);
1767 qglEnable(GL_CULL_FACE);
1770 GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
1771 GL_DepthMask(!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT));
1772 if (texture->currentmaterialflags & MATERIALFLAG_ADD)
1773 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
1774 else if (texture->currentmaterialflags & MATERIALFLAG_ALPHA)
1775 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1777 GL_BlendFunc(GL_ONE, GL_ZERO);
1778 if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
1779 qglDisable(GL_CULL_FACE);
1780 if (texture->currentmaterialflags & MATERIALFLAG_SKY)
1784 skyrendernow = false;
1785 if (skyrendermasked)
1788 // LordHavoc: HalfLife maps have freaky skypolys...
1789 //if (!ent->model->brush.ishlbsp)
1791 R_Mesh_Matrix(&ent->matrix);
1792 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
1793 if (skyrendermasked)
1795 // depth-only (masking)
1796 GL_ColorMask(0,0,0,0);
1797 // just to make sure that braindead drivers don't draw anything
1798 // despite that colormask...
1799 GL_BlendFunc(GL_ZERO, GL_ONE);
1804 GL_BlendFunc(GL_ONE, GL_ZERO);
1808 memset(&m, 0, sizeof(m));
1810 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1812 surface = texturesurfacelist[texturesurfaceindex];
1813 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
1814 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
1815 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
1816 GL_LockArrays(0, 0);
1818 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1821 else if ((texture->currentmaterialflags & MATERIALFLAG_WATER) && r_watershader.value && gl_textureshader && !texture->skin.glow && !fogenabled && ent->colormod[0] == 1 && ent->colormod[1] == 1 && ent->colormod[2] == 1)
1823 // NVIDIA Geforce3 distortion texture shader on water
1824 float args[4] = {0.05f,0,0,0.04f};
1825 memset(&m, 0, sizeof(m));
1826 m.tex[0] = R_GetTexture(r_texture_distorttexture[(int)(r_refdef.time * 16)&63]);
1827 m.tex[1] = R_GetTexture(texture->skin.base);
1828 m.texcombinergb[0] = GL_REPLACE;
1829 m.texcombinergb[1] = GL_REPLACE;
1830 Matrix4x4_CreateFromQuakeEntity(&m.texmatrix[0], 0, 0, 0, 0, 0, 0, r_watershader.value);
1831 m.texmatrix[1] = texture->currenttexmatrix;
1834 GL_Color(1, 1, 1, texture->currentalpha);
1835 GL_ActiveTexture(0);
1836 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
1837 GL_ActiveTexture(1);
1838 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
1839 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB);
1840 qglTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[0]);
1841 qglEnable(GL_TEXTURE_SHADER_NV);
1843 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1845 surface = texturesurfacelist[texturesurfaceindex];
1846 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
1847 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
1848 R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
1849 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
1850 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
1851 GL_LockArrays(0, 0);
1854 qglDisable(GL_TEXTURE_SHADER_NV);
1855 qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
1856 GL_ActiveTexture(0);
1858 else if (texture->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
1860 // normal surface (wall or water)
1861 dolightmap = !(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT);
1862 doambient = r_ambient.value >= (1/64.0f);
1863 dodetail = r_detailtextures.integer && texture->skin.detail != NULL && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
1864 doglow = texture->skin.glow != NULL;
1865 dofogpass = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_ADD);
1866 fogallpasses = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
1867 if (ent->colormap >= 0)
1871 basetexture = texture->skin.base;
1872 dopants = texture->skin.pants != NULL;
1873 doshirt = texture->skin.shirt != NULL;
1874 // 128-224 are backwards ranges
1875 b = (ent->colormap & 0xF) << 4;b += (b >= 128 && b < 224) ? 4 : 12;
1876 dofullbrightpants = b >= 224;
1877 bcolor = (qbyte *) (&palette_complete[b]);
1878 VectorScale(bcolor, (1.0f / 255.0f), colorpants);
1879 // 128-224 are backwards ranges
1880 b = (ent->colormap & 0xF0);b += (b >= 128 && b < 224) ? 4 : 12;
1881 dofullbrightshirt = b >= 224;
1882 bcolor = (qbyte *) (&palette_complete[b]);
1883 VectorScale(bcolor, (1.0f / 255.0f), colorshirt);
1887 basetexture = texture->skin.merged ? texture->skin.merged : texture->skin.base;
1890 dofullbrightshirt = false;
1891 dofullbrightpants = false;
1893 if (dolightmap && r_textureunits.integer >= 2 && gl_combine.integer)
1895 memset(&m, 0, sizeof(m));
1896 m.tex[1] = R_GetTexture(basetexture);
1897 m.texmatrix[1] = texture->currenttexmatrix;
1898 m.texrgbscale[1] = 2;
1899 m.pointer_color = varray_color4f;
1901 // transparent is not affected by r_lightmapintensity
1902 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1903 colorscale = r_lightmapintensity;
1906 // q3bsp has no lightmap updates, so the lightstylevalue that
1907 // would normally be baked into the lightmaptexture must be
1908 // applied to the color
1909 if (ent->model->type == mod_brushq3)
1910 colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f);
1911 r = ent->colormod[0] * colorscale;
1912 g = ent->colormod[1] * colorscale;
1913 b = ent->colormod[2] * colorscale;
1914 a = texture->currentalpha;
1915 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
1916 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1918 surface = texturesurfacelist[texturesurfaceindex];
1919 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
1920 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
1921 R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
1922 if (surface->lightmaptexture)
1923 R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
1925 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
1926 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode ? lightmode : !surface->lightmaptexture, applycolor, fogallpasses);
1927 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
1928 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
1929 GL_LockArrays(0, 0);
1932 else if (dolightmap && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT) && !lightmode)
1935 GL_BlendFunc(GL_ONE, GL_ZERO);
1937 GL_Color(1, 1, 1, 1);
1938 memset(&m, 0, sizeof(m));
1940 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1942 surface = texturesurfacelist[texturesurfaceindex];
1943 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
1944 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
1945 if (surface->lightmaptexture)
1947 R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
1948 R_Mesh_ColorPointer(NULL);
1952 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
1953 R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f);
1955 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
1956 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
1957 GL_LockArrays(0, 0);
1959 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
1960 GL_DepthMask(false);
1961 GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
1962 memset(&m, 0, sizeof(m));
1963 m.tex[0] = R_GetTexture(basetexture);
1964 m.texmatrix[0] = texture->currenttexmatrix;
1966 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1968 surface = texturesurfacelist[texturesurfaceindex];
1969 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
1970 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
1971 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
1972 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
1973 GL_LockArrays(0, 0);
1978 memset(&m, 0, sizeof(m));
1979 m.tex[0] = R_GetTexture(basetexture);
1980 m.texmatrix[0] = texture->currenttexmatrix;
1981 m.pointer_color = varray_color4f;
1983 if (gl_combine.integer)
1985 m.texrgbscale[0] = 2;
1988 // transparent is not affected by r_lightmapintensity
1989 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1990 colorscale *= r_lightmapintensity;
1991 // q3bsp has no lightmap updates, so the lightstylevalue that
1992 // would normally be baked into the lightmaptexture must be
1993 // applied to the color
1994 if (dolightmap && ent->model->type == mod_brushq3)
1995 colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f);
1997 r = ent->colormod[0] * colorscale;
1998 g = ent->colormod[1] * colorscale;
1999 b = ent->colormod[2] * colorscale;
2000 a = texture->currentalpha;
2001 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2004 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2006 surface = texturesurfacelist[texturesurfaceindex];
2007 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2008 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2009 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode, applycolor, fogallpasses);
2010 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2011 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2012 GL_LockArrays(0, 0);
2017 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2019 surface = texturesurfacelist[texturesurfaceindex];
2020 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2021 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2022 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses);
2023 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2024 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2025 GL_LockArrays(0, 0);
2031 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2032 memset(&m, 0, sizeof(m));
2033 m.tex[0] = R_GetTexture(texture->skin.pants);
2034 m.texmatrix[0] = texture->currenttexmatrix;
2035 m.pointer_color = varray_color4f;
2037 if (gl_combine.integer)
2039 m.texrgbscale[0] = 2;
2042 // transparent is not affected by r_lightmapintensity
2043 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2044 colorscale *= r_lightmapintensity;
2045 // q3bsp has no lightmap updates, so the lightstylevalue that
2046 // would normally be baked into the lightmaptexture must be
2047 // applied to the color
2048 if (dolightmap && !dofullbrightpants && ent->model->type == mod_brushq3)
2049 colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f);
2051 r = ent->colormod[0] * colorpants[0] * colorscale;
2052 g = ent->colormod[1] * colorpants[1] * colorscale;
2053 b = ent->colormod[2] * colorpants[2] * colorscale;
2054 a = texture->currentalpha;
2055 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2056 if (dolightmap && !dofullbrightpants)
2058 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2060 surface = texturesurfacelist[texturesurfaceindex];
2061 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2062 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2063 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode, applycolor, fogallpasses);
2064 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2065 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2066 GL_LockArrays(0, 0);
2071 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2073 surface = texturesurfacelist[texturesurfaceindex];
2074 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2075 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2076 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses);
2077 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2078 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2079 GL_LockArrays(0, 0);
2085 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2086 memset(&m, 0, sizeof(m));
2087 m.tex[0] = R_GetTexture(texture->skin.shirt);
2088 m.texmatrix[0] = texture->currenttexmatrix;
2089 m.pointer_color = varray_color4f;
2091 if (gl_combine.integer)
2093 m.texrgbscale[0] = 2;
2096 // transparent is not affected by r_lightmapintensity
2097 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2098 colorscale *= r_lightmapintensity;
2099 // q3bsp has no lightmap updates, so the lightstylevalue that
2100 // would normally be baked into the lightmaptexture must be
2101 // applied to the color
2102 if (dolightmap && !dofullbrightshirt && ent->model->type == mod_brushq3)
2103 colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f);
2105 r = ent->colormod[0] * colorshirt[0] * colorscale;
2106 g = ent->colormod[1] * colorshirt[1] * colorscale;
2107 b = ent->colormod[2] * colorshirt[2] * colorscale;
2108 a = texture->currentalpha;
2109 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2110 if (dolightmap && !dofullbrightshirt)
2112 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2114 surface = texturesurfacelist[texturesurfaceindex];
2115 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2116 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2117 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode, applycolor, fogallpasses);
2118 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2119 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2120 GL_LockArrays(0, 0);
2125 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2127 surface = texturesurfacelist[texturesurfaceindex];
2128 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2129 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2130 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses);
2131 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2132 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2133 GL_LockArrays(0, 0);
2140 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2141 GL_DepthMask(false);
2142 memset(&m, 0, sizeof(m));
2143 m.tex[0] = R_GetTexture(texture->skin.base);
2144 m.texmatrix[0] = texture->currenttexmatrix;
2145 m.pointer_color = varray_color4f;
2147 if (gl_combine.integer && (ent->colormod[0] > 1 || ent->colormod[1] > 1 || ent->colormod[2] > 1))
2149 m.texrgbscale[0] = 4;
2153 colorscale *= r_ambient.value * (1.0f / 64.0f);
2154 r = ent->colormod[0] * colorscale;
2155 g = ent->colormod[1] * colorscale;
2156 b = ent->colormod[2] * colorscale;
2157 a = texture->currentalpha;
2158 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2159 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2161 surface = texturesurfacelist[texturesurfaceindex];
2162 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2163 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2164 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses);
2165 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2166 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2167 GL_LockArrays(0, 0);
2172 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
2173 GL_DepthMask(false);
2174 GL_Color(1, 1, 1, 1);
2175 memset(&m, 0, sizeof(m));
2176 m.tex[0] = R_GetTexture(texture->skin.detail);
2178 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2180 surface = texturesurfacelist[texturesurfaceindex];
2181 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2182 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoorddetail2f);
2183 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2184 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2185 GL_LockArrays(0, 0);
2190 // if glow was not already done using multitexture, do it now.
2191 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2192 GL_DepthMask(false);
2193 memset(&m, 0, sizeof(m));
2194 m.tex[0] = R_GetTexture(texture->skin.glow);
2195 m.texmatrix[0] = texture->currenttexmatrix;
2196 m.pointer_color = varray_color4f;
2201 a = texture->currentalpha;
2202 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2203 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2205 surface = texturesurfacelist[texturesurfaceindex];
2206 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2207 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2208 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses);
2209 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2210 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2211 GL_LockArrays(0, 0);
2216 // if this is opaque use alpha blend which will darken the earlier
2219 // if this is an alpha blended material, all the earlier passes
2220 // were darkened by fog already, so we only need to add the fog
2221 // color ontop through the fog mask texture
2223 // if this is an additive blended material, all the earlier passes
2224 // were darkened by fog already, and we should not add fog color
2225 // (because the background was not darkened, there is no fog color
2226 // that was lost behind it).
2228 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2230 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2231 GL_DepthMask(false);
2232 memset(&m, 0, sizeof(m));
2233 m.tex[0] = R_GetTexture(texture->skin.fog);
2234 m.texmatrix[0] = texture->currenttexmatrix;
2239 a = texture->currentalpha;
2240 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2241 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2243 surface = texturesurfacelist[texturesurfaceindex];
2244 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2245 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2246 R_Mesh_ColorPointer(varray_color4f);
2247 //RSurf_FogPassColors_Vertex3f_Color4f((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], texture->currentalpha, 1, surface->num_vertices, modelorg);
2248 if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2250 for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
2252 VectorSubtract(v, modelorg, diff);
2253 f = exp(fogdensity/DotProduct(diff, diff));
2257 c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * f * a;
2262 for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
2264 VectorSubtract(v, modelorg, diff);
2265 f = exp(fogdensity/DotProduct(diff, diff));
2272 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2273 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2274 GL_LockArrays(0, 0);
2278 if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
2279 qglEnable(GL_CULL_FACE);
2282 static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata2)
2284 const entity_render_t *ent = calldata1;
2285 const msurface_t *surface = ent->model->data_surfaces + calldata2;
2289 texture = surface->texture;
2290 if (texture->basematerialflags & MATERIALFLAG_SKY)
2291 return; // transparent sky is too difficult
2292 R_UpdateTextureInfo(ent, texture);
2294 R_Mesh_Matrix(&ent->matrix);
2295 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
2296 R_DrawTextureSurfaceList(ent, texture->currentframe, 1, &surface, modelorg);
2299 void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
2301 int texturesurfaceindex;
2302 const msurface_t *surface;
2303 vec3_t tempcenter, center;
2304 if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)
2306 // drawing sky transparently would be too difficult
2307 if (!(texture->currentmaterialflags & MATERIALFLAG_SKY))
2309 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2311 surface = texturesurfacelist[texturesurfaceindex];
2312 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
2313 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
2314 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
2315 Matrix4x4_Transform(&ent->matrix, tempcenter, center);
2316 R_MeshQueue_AddTransparent(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, RSurfShader_Transparent_Callback, ent, surface - ent->model->data_surfaces);
2321 R_DrawTextureSurfaceList(ent, texture, texturenumsurfaces, texturesurfacelist, modelorg);
2324 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
2325 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
2327 int i, j, f, flagsmask;
2328 msurface_t *surface, **surfacechain;
2329 texture_t *t, *texture;
2330 model_t *model = ent->model;
2332 const int maxsurfacelist = 1024;
2333 int numsurfacelist = 0;
2334 const msurface_t *surfacelist[1024];
2337 R_Mesh_Matrix(&ent->matrix);
2338 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
2340 // update light styles
2341 if (!skysurfaces && model->brushq1.light_styleupdatechains)
2343 for (i = 0;i < model->brushq1.light_styles;i++)
2345 if (model->brushq1.light_stylevalue[i] != d_lightstylevalue[model->brushq1.light_style[i]])
2347 model->brushq1.light_stylevalue[i] = d_lightstylevalue[model->brushq1.light_style[i]];
2348 if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
2349 for (;(surface = *surfacechain);surfacechain++)
2350 surface->cached_dlight = true;
2355 R_UpdateAllTextureInfo(ent);
2356 flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
2361 if (ent == r_refdef.worldentity)
2363 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
2365 if (!r_worldsurfacevisible[j])
2367 if (t != surface->texture)
2371 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2374 t = surface->texture;
2375 texture = t->currentframe;
2376 f = texture->currentmaterialflags & flagsmask;
2378 if (f && surface->num_triangles)
2380 // if lightmap parameters changed, rebuild lightmap texture
2381 if (surface->cached_dlight && surface->lightmapinfo->samples)
2382 R_BuildLightMap(ent, surface);
2383 // add face to draw list
2384 surfacelist[numsurfacelist++] = surface;
2385 if (numsurfacelist >= maxsurfacelist)
2387 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2395 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
2397 if (t != surface->texture)
2401 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2404 t = surface->texture;
2405 texture = t->currentframe;
2406 f = texture->currentmaterialflags & flagsmask;
2408 if (f && surface->num_triangles)
2410 // if lightmap parameters changed, rebuild lightmap texture
2411 if (surface->cached_dlight && surface->lightmapinfo->samples)
2412 R_BuildLightMap(ent, surface);
2413 // add face to draw list
2414 surfacelist[numsurfacelist++] = surface;
2415 if (numsurfacelist >= maxsurfacelist)
2417 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2424 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);