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"};
101 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0"};
102 cvar_t r_bloom_intensity = {CVAR_SAVE, "r_bloom_intensity", "2"};
103 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "8"};
104 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320"};
105 cvar_t r_bloom_power = {CVAR_SAVE, "r_bloom_power", "4"};
107 cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1"};
109 cvar_t developer_texturelogging = {0, "developer_texturelogging", "0"};
111 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"};
113 cvar_t r_test = {0, "r_test", "0"}; // used for testing renderer code changes, otherwise does nothing
115 rtexturepool_t *r_main_texturepool;
116 rtexture_t *r_bloom_texture_screen;
117 rtexture_t *r_bloom_texture_bloom;
118 rtexture_t *r_texture_blanknormalmap;
119 rtexture_t *r_texture_white;
120 rtexture_t *r_texture_black;
121 rtexture_t *r_texture_notexture;
122 rtexture_t *r_texture_whitecube;
123 rtexture_t *r_texture_normalizationcube;
125 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
128 for (i = 0;i < verts;i++)
139 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
142 for (i = 0;i < verts;i++)
154 float fog_density, fog_red, fog_green, fog_blue;
156 qboolean oldgl_fogenable;
157 void R_UpdateFog(void)
159 if (gamemode == GAME_NEHAHRA)
161 if (gl_fogenable.integer)
163 oldgl_fogenable = true;
164 fog_density = gl_fogdensity.value;
165 fog_red = gl_fogred.value;
166 fog_green = gl_foggreen.value;
167 fog_blue = gl_fogblue.value;
169 else if (oldgl_fogenable)
171 oldgl_fogenable = false;
180 fogcolor[0] = fog_red = bound(0.0f, fog_red , 1.0f);
181 fogcolor[1] = fog_green = bound(0.0f, fog_green, 1.0f);
182 fogcolor[2] = fog_blue = bound(0.0f, fog_blue , 1.0f);
187 fogdensity = -4000.0f / (fog_density * fog_density);
188 // fog color was already set
194 // FIXME: move this to client?
197 if (gamemode == GAME_NEHAHRA)
199 Cvar_Set("gl_fogenable", "0");
200 Cvar_Set("gl_fogdensity", "0.2");
201 Cvar_Set("gl_fogred", "0.3");
202 Cvar_Set("gl_foggreen", "0.3");
203 Cvar_Set("gl_fogblue", "0.3");
205 fog_density = fog_red = fog_green = fog_blue = 0.0f;
208 // FIXME: move this to client?
209 void FOG_registercvars(void)
211 if (gamemode == GAME_NEHAHRA)
213 Cvar_RegisterVariable (&gl_fogenable);
214 Cvar_RegisterVariable (&gl_fogdensity);
215 Cvar_RegisterVariable (&gl_fogred);
216 Cvar_RegisterVariable (&gl_foggreen);
217 Cvar_RegisterVariable (&gl_fogblue);
218 Cvar_RegisterVariable (&gl_fogstart);
219 Cvar_RegisterVariable (&gl_fogend);
223 static void R_BuildBlankTextures(void)
226 data[0] = 128; // normal X
227 data[1] = 128; // normal Y
228 data[2] = 255; // normal Z
229 data[3] = 128; // height
230 r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
235 r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
240 r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
243 static void R_BuildNoTexture(void)
246 qbyte pix[16][16][4];
247 // this makes a light grey/dark grey checkerboard texture
248 for (y = 0;y < 16;y++)
250 for (x = 0;x < 16;x++)
252 if ((y < 8) ^ (x < 8))
268 r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL);
271 static void R_BuildWhiteCube(void)
274 data[ 0] = 255;data[ 1] = 255;data[ 2] = 255;data[ 3] = 255;
275 data[ 4] = 255;data[ 5] = 255;data[ 6] = 255;data[ 7] = 255;
276 data[ 8] = 255;data[ 9] = 255;data[10] = 255;data[11] = 255;
277 data[12] = 255;data[13] = 255;data[14] = 255;data[15] = 255;
278 data[16] = 255;data[17] = 255;data[18] = 255;data[19] = 255;
279 data[20] = 255;data[21] = 255;data[22] = 255;data[23] = 255;
280 r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
283 static void R_BuildNormalizationCube(void)
287 vec_t s, t, intensity;
289 qbyte data[6][NORMSIZE][NORMSIZE][4];
290 for (side = 0;side < 6;side++)
292 for (y = 0;y < NORMSIZE;y++)
294 for (x = 0;x < NORMSIZE;x++)
296 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
297 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
331 intensity = 127.0f / sqrt(DotProduct(v, v));
332 data[side][y][x][0] = 128.0f + intensity * v[0];
333 data[side][y][x][1] = 128.0f + intensity * v[1];
334 data[side][y][x][2] = 128.0f + intensity * v[2];
335 data[side][y][x][3] = 255;
339 r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
342 void gl_main_start(void)
344 r_main_texturepool = R_AllocTexturePool();
345 r_bloom_texture_screen = NULL;
346 r_bloom_texture_bloom = NULL;
347 R_BuildBlankTextures();
349 if (gl_texturecubemap)
352 R_BuildNormalizationCube();
356 void gl_main_shutdown(void)
358 R_FreeTexturePool(&r_main_texturepool);
359 r_bloom_texture_screen = NULL;
360 r_bloom_texture_bloom = NULL;
361 r_texture_blanknormalmap = NULL;
362 r_texture_white = NULL;
363 r_texture_black = NULL;
364 r_texture_whitecube = NULL;
365 r_texture_normalizationcube = NULL;
368 extern void CL_ParseEntityLump(char *entitystring);
369 void gl_main_newmap(void)
371 // FIXME: move this code to client
373 char *entities, entname[MAX_QPATH];
377 strlcpy(entname, cl.worldmodel->name, sizeof(entname));
378 l = (int)strlen(entname) - 4;
379 if (l >= 0 && !strcmp(entname + l, ".bsp"))
381 strcpy(entname + l, ".ent");
382 if ((entities = FS_LoadFile(entname, tempmempool, true)))
384 CL_ParseEntityLump(entities);
389 if (cl.worldmodel->brush.entities)
390 CL_ParseEntityLump(cl.worldmodel->brush.entities);
394 void GL_Main_Init(void)
396 Matrix4x4_CreateIdentity(&r_identitymatrix);
397 // FIXME: move this to client?
399 Cvar_RegisterVariable(&r_showtris);
400 Cvar_RegisterVariable(&r_drawentities);
401 Cvar_RegisterVariable(&r_drawviewmodel);
402 Cvar_RegisterVariable(&r_speeds);
403 Cvar_RegisterVariable(&r_fullbrights);
404 Cvar_RegisterVariable(&r_wateralpha);
405 Cvar_RegisterVariable(&r_dynamic);
406 Cvar_RegisterVariable(&r_fullbright);
407 Cvar_RegisterVariable(&r_textureunits);
408 Cvar_RegisterVariable(&r_lerpsprites);
409 Cvar_RegisterVariable(&r_lerpmodels);
410 Cvar_RegisterVariable(&r_waterscroll);
411 Cvar_RegisterVariable(&r_drawcollisionbrushes);
412 Cvar_RegisterVariable(&r_bloom);
413 Cvar_RegisterVariable(&r_bloom_intensity);
414 Cvar_RegisterVariable(&r_bloom_blur);
415 Cvar_RegisterVariable(&r_bloom_resolution);
416 Cvar_RegisterVariable(&r_bloom_power);
417 Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
418 Cvar_RegisterVariable(&developer_texturelogging);
419 Cvar_RegisterVariable(&gl_lightmaps);
420 Cvar_RegisterVariable(&r_test);
421 if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE)
422 Cvar_SetValue("r_fullbrights", 0);
423 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
426 static vec3_t r_farclip_origin;
427 static vec3_t r_farclip_direction;
428 static vec_t r_farclip_directiondist;
429 static vec_t r_farclip_meshfarclip;
430 static int r_farclip_directionbit0;
431 static int r_farclip_directionbit1;
432 static int r_farclip_directionbit2;
434 // enlarge farclip to accomodate box
435 static void R_FarClip_Box(vec3_t mins, vec3_t maxs)
438 d = (r_farclip_directionbit0 ? mins[0] : maxs[0]) * r_farclip_direction[0]
439 + (r_farclip_directionbit1 ? mins[1] : maxs[1]) * r_farclip_direction[1]
440 + (r_farclip_directionbit2 ? mins[2] : maxs[2]) * r_farclip_direction[2];
441 if (r_farclip_meshfarclip < d)
442 r_farclip_meshfarclip = d;
445 // return farclip value
446 static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
450 VectorCopy(origin, r_farclip_origin);
451 VectorCopy(direction, r_farclip_direction);
452 r_farclip_directiondist = DotProduct(r_farclip_origin, r_farclip_direction);
453 r_farclip_directionbit0 = r_farclip_direction[0] < 0;
454 r_farclip_directionbit1 = r_farclip_direction[1] < 0;
455 r_farclip_directionbit2 = r_farclip_direction[2] < 0;
456 r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
458 if (r_refdef.worldmodel)
459 R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
460 for (i = 0;i < r_refdef.numentities;i++)
461 R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
463 return r_farclip_meshfarclip - r_farclip_directiondist;
466 extern void R_Textures_Init(void);
467 extern void GL_Draw_Init(void);
468 extern void GL_Main_Init(void);
469 extern void R_Shadow_Init(void);
470 extern void R_Sky_Init(void);
471 extern void GL_Surf_Init(void);
472 extern void R_Crosshairs_Init(void);
473 extern void R_Light_Init(void);
474 extern void R_Particles_Init(void);
475 extern void R_Explosion_Init(void);
476 extern void gl_backend_init(void);
477 extern void Sbar_Init(void);
478 extern void R_LightningBeams_Init(void);
479 extern void Mod_RenderInit(void);
481 void Render_Init(void)
497 R_LightningBeams_Init();
506 extern char *ENGINE_EXTENSIONS;
509 VID_CheckExtensions();
511 // LordHavoc: report supported extensions
512 Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions );
514 // clear to black (loading plaque will be seen over this)
515 qglClearColor(0,0,0,1);
516 qglClear(GL_COLOR_BUFFER_BIT);
519 int R_CullBox(const vec3_t mins, const vec3_t maxs)
523 for (i = 0;i < 4;i++)
530 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
534 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
538 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
542 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
546 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
550 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
554 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
558 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
566 //==================================================================================
568 static void R_MarkEntities (void)
571 entity_render_t *ent;
573 if (!r_drawentities.integer)
576 r_refdef.worldentity->visframe = r_framecount;
577 renderimask = envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL) : (chase_active.integer ? 0 : RENDER_EXTERIORMODEL);
578 if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs)
580 // worldmodel can check visibility
581 for (i = 0;i < r_refdef.numentities;i++)
583 ent = r_refdef.entities[i];
584 Mod_CheckLoaded(ent->model);
585 // some of the renderer still relies on origin...
586 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
587 // some of the renderer still relies on scale...
588 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
589 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)))
591 R_UpdateEntLights(ent);
592 ent->visframe = r_framecount;
598 // no worldmodel or it can't check visibility
599 for (i = 0;i < r_refdef.numentities;i++)
601 ent = r_refdef.entities[i];
602 Mod_CheckLoaded(ent->model);
603 // some of the renderer still relies on origin...
604 Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin);
605 // some of the renderer still relies on scale...
606 ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix);
607 if (!(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && (ent->effects & EF_NODEPTHTEST))
609 R_UpdateEntLights(ent);
610 ent->visframe = r_framecount;
616 // only used if skyrendermasked, and normally returns false
617 int R_DrawBrushModelsSky (void)
620 entity_render_t *ent;
622 if (!r_drawentities.integer)
626 for (i = 0;i < r_refdef.numentities;i++)
628 ent = r_refdef.entities[i];
629 if (ent->visframe == r_framecount && ent->model && ent->model->DrawSky)
631 ent->model->DrawSky(ent);
638 void R_DrawNoModel(entity_render_t *ent);
639 void R_DrawModels(void)
642 entity_render_t *ent;
644 if (!r_drawentities.integer)
647 for (i = 0;i < r_refdef.numentities;i++)
649 ent = r_refdef.entities[i];
650 if (ent->visframe == r_framecount)
652 if (ent->model && ent->model->Draw != NULL)
653 ent->model->Draw(ent);
660 static void R_SetFrustum(void)
662 // break apart the view matrix into vectors for various purposes
663 Matrix4x4_ToVectors(&r_view_matrix, r_viewforward, r_viewleft, r_viewup, r_vieworigin);
664 VectorNegate(r_viewleft, r_viewright);
666 // LordHavoc: note to all quake engine coders, the special case for 90
667 // degrees assumed a square view (wrong), so I removed it, Quake2 has it
670 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
671 RotatePointAroundVector( frustum[0].normal, r_viewup, r_viewforward, -(90 - r_view_fov_x / 2));
672 frustum[0].dist = DotProduct (r_vieworigin, frustum[0].normal);
673 PlaneClassify(&frustum[0]);
675 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
676 RotatePointAroundVector( frustum[1].normal, r_viewup, r_viewforward, (90 - r_view_fov_x / 2));
677 frustum[1].dist = DotProduct (r_vieworigin, frustum[1].normal);
678 PlaneClassify(&frustum[1]);
680 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
681 RotatePointAroundVector( frustum[2].normal, r_viewleft, r_viewforward, -(90 - r_view_fov_y / 2));
682 frustum[2].dist = DotProduct (r_vieworigin, frustum[2].normal);
683 PlaneClassify(&frustum[2]);
685 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
686 RotatePointAroundVector( frustum[3].normal, r_viewleft, r_viewforward, (90 - r_view_fov_y / 2));
687 frustum[3].dist = DotProduct (r_vieworigin, frustum[3].normal);
688 PlaneClassify(&frustum[3]);
691 VectorCopy(r_viewforward, frustum[4].normal);
692 frustum[4].dist = DotProduct (r_vieworigin, frustum[4].normal) + 1.0f;
693 PlaneClassify(&frustum[4]);
696 static void R_BlendView(void)
700 if (r_refdef.viewblend[3] < 0.01f && !r_bloom.integer)
703 GL_SetupView_Mode_Ortho(0, 0, 1, 1, -10, 100);
706 R_Mesh_Matrix(&r_identitymatrix);
707 // vertex coordinates for a quad that covers the screen exactly
708 varray_vertex3f[0] = 0;varray_vertex3f[1] = 0;varray_vertex3f[2] = 0;
709 varray_vertex3f[3] = 1;varray_vertex3f[4] = 0;varray_vertex3f[5] = 0;
710 varray_vertex3f[6] = 1;varray_vertex3f[7] = 1;varray_vertex3f[8] = 0;
711 varray_vertex3f[9] = 0;varray_vertex3f[10] = 1;varray_vertex3f[11] = 0;
712 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)
714 int screenwidth, screenheight, bloomwidth, bloomheight, x, dobloomblend, range;
715 float xoffset, yoffset, r;
717 // set the (poorly named) screenwidth and screenheight variables to
718 // a power of 2 at least as large as the screen, these will define the
719 // size of the texture to allocate
720 for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2);
721 for (screenheight = 1;screenheight < vid.height;screenheight *= 2);
722 // allocate textures as needed
723 if (!r_bloom_texture_screen)
724 r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
725 if (!r_bloom_texture_bloom)
726 r_bloom_texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
727 // set bloomwidth and bloomheight to the bloom resolution that will be
728 // used (often less than the screen resolution for faster rendering)
729 bloomwidth = min(r_view_width, r_bloom_resolution.integer);
730 bloomheight = min(r_view_height, bloomwidth * r_view_height / r_view_width);
731 // set up a texcoord array for the full resolution screen image
732 // (we have to keep this around to copy back during final render)
733 varray_texcoord2f[0][0] = 0;
734 varray_texcoord2f[0][1] = (float)r_view_height / (float)screenheight;
735 varray_texcoord2f[0][2] = (float)r_view_width / (float)screenwidth;
736 varray_texcoord2f[0][3] = (float)r_view_height / (float)screenheight;
737 varray_texcoord2f[0][4] = (float)r_view_width / (float)screenwidth;
738 varray_texcoord2f[0][5] = 0;
739 varray_texcoord2f[0][6] = 0;
740 varray_texcoord2f[0][7] = 0;
741 // set up a texcoord array for the reduced resolution bloom image
742 // (which will be additive blended over the screen image)
743 varray_texcoord2f[1][0] = 0;
744 varray_texcoord2f[1][1] = (float)bloomheight / (float)screenheight;
745 varray_texcoord2f[1][2] = (float)bloomwidth / (float)screenwidth;
746 varray_texcoord2f[1][3] = (float)bloomheight / (float)screenheight;
747 varray_texcoord2f[1][4] = (float)bloomwidth / (float)screenwidth;
748 varray_texcoord2f[1][5] = 0;
749 varray_texcoord2f[1][6] = 0;
750 varray_texcoord2f[1][7] = 0;
751 memset(&m, 0, sizeof(m));
752 m.pointer_vertex = varray_vertex3f;
753 m.pointer_texcoord[0] = varray_texcoord2f[0];
754 m.tex[0] = R_GetTexture(r_bloom_texture_screen);
756 // copy view into the full resolution screen image texture
758 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
760 c_bloomcopypixels += r_view_width * r_view_height;
761 // now scale it down to the bloom size and raise to a power of itself
762 // to darken it (this leaves the really bright stuff bright, and
763 // everything else becomes very dark)
764 // TODO: optimize with multitexture or GLSL
765 qglViewport(r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
766 GL_BlendFunc(GL_ONE, GL_ZERO);
767 GL_Color(1, 1, 1, 1);
768 R_Mesh_Draw(0, 4, 2, polygonelements);
770 c_bloomdrawpixels += bloomwidth * bloomheight;
771 // render multiple times with a multiply blendfunc to raise to a power
772 GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
773 for (x = 1;x < r_bloom_power.integer;x++)
775 R_Mesh_Draw(0, 4, 2, polygonelements);
777 c_bloomdrawpixels += bloomwidth * bloomheight;
779 // we now have a darkened bloom image in the framebuffer, copy it into
780 // the bloom image texture for more processing
781 memset(&m, 0, sizeof(m));
782 m.pointer_vertex = varray_vertex3f;
783 m.tex[0] = R_GetTexture(r_bloom_texture_bloom);
784 m.pointer_texcoord[0] = varray_texcoord2f[2];
787 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
789 c_bloomcopypixels += bloomwidth * bloomheight;
790 // blend on at multiple vertical offsets to achieve a vertical blur
791 // TODO: do offset blends using GLSL
792 range = r_bloom_blur.integer * bloomwidth / 320;
793 GL_BlendFunc(GL_ONE, GL_ZERO);
794 for (x = -range;x <= range;x++)
796 xoffset = 0 / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
797 yoffset = x / (float)bloomheight * (float)bloomheight / (float)screenheight;
798 // compute a texcoord array with the specified x and y offset
799 varray_texcoord2f[2][0] = xoffset+0;
800 varray_texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
801 varray_texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
802 varray_texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
803 varray_texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
804 varray_texcoord2f[2][5] = yoffset+0;
805 varray_texcoord2f[2][6] = xoffset+0;
806 varray_texcoord2f[2][7] = yoffset+0;
807 // this r value looks like a 'dot' particle, fading sharply to
808 // black at the edges
809 // (probably not realistic but looks good enough)
810 r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
813 GL_Color(r, r, r, 1);
814 R_Mesh_Draw(0, 4, 2, polygonelements);
816 c_bloomdrawpixels += bloomwidth * bloomheight;
817 GL_BlendFunc(GL_ONE, GL_ONE);
819 // copy the vertically blurred bloom view to a texture
821 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
823 c_bloomcopypixels += bloomwidth * bloomheight;
824 // blend the vertically blurred image at multiple offsets horizontally
825 // to finish the blur effect
826 // TODO: do offset blends using GLSL
827 range = r_bloom_blur.integer * bloomwidth / 320;
828 GL_BlendFunc(GL_ONE, GL_ZERO);
829 for (x = -range;x <= range;x++)
831 xoffset = x / (float)bloomwidth * (float)bloomwidth / (float)screenwidth;
832 yoffset = 0 / (float)bloomheight * (float)bloomheight / (float)screenheight;
833 // compute a texcoord array with the specified x and y offset
834 varray_texcoord2f[2][0] = xoffset+0;
835 varray_texcoord2f[2][1] = yoffset+(float)bloomheight / (float)screenheight;
836 varray_texcoord2f[2][2] = xoffset+(float)bloomwidth / (float)screenwidth;
837 varray_texcoord2f[2][3] = yoffset+(float)bloomheight / (float)screenheight;
838 varray_texcoord2f[2][4] = xoffset+(float)bloomwidth / (float)screenwidth;
839 varray_texcoord2f[2][5] = yoffset+0;
840 varray_texcoord2f[2][6] = xoffset+0;
841 varray_texcoord2f[2][7] = yoffset+0;
842 // this r value looks like a 'dot' particle, fading sharply to
843 // black at the edges
844 // (probably not realistic but looks good enough)
845 r = r_bloom_intensity.value/(range*2+1)*(1 - x*x/(float)(range*range));
848 GL_Color(r, r, r, 1);
849 R_Mesh_Draw(0, 4, 2, polygonelements);
851 c_bloomdrawpixels += bloomwidth * bloomheight;
852 GL_BlendFunc(GL_ONE, GL_ONE);
854 // copy the blurred bloom view to a texture
856 qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight);
858 c_bloomcopypixels += bloomwidth * bloomheight;
859 // go back to full view area
860 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
861 // put the original screen image back in place and blend the bloom
863 memset(&m, 0, sizeof(m));
864 m.pointer_vertex = varray_vertex3f;
865 m.tex[0] = R_GetTexture(r_bloom_texture_screen);
866 m.pointer_texcoord[0] = varray_texcoord2f[0];
868 dobloomblend = false;
870 // do both in one pass if possible
871 if (r_textureunits.integer >= 2 && gl_combine.integer)
873 dobloomblend = false;
874 m.texcombinergb[1] = GL_ADD;
875 m.tex[1] = R_GetTexture(r_bloom_texture_bloom);
876 m.pointer_texcoord[1] = varray_texcoord2f[1];
882 GL_BlendFunc(GL_ONE, GL_ZERO);
884 R_Mesh_Draw(0, 4, 2, polygonelements);
886 c_bloomdrawpixels += r_view_width * r_view_height;
887 // now blend on the bloom texture if multipass
890 memset(&m, 0, sizeof(m));
891 m.pointer_vertex = varray_vertex3f;
892 m.tex[0] = R_GetTexture(r_bloom_texture_bloom);
893 m.pointer_texcoord[0] = varray_texcoord2f[1];
895 GL_BlendFunc(GL_ONE, GL_ONE);
897 R_Mesh_Draw(0, 4, 2, polygonelements);
899 c_bloomdrawpixels += r_view_width * r_view_height;
902 if (r_refdef.viewblend[3] >= 0.01f)
904 // apply a color tint to the whole view
905 memset(&m, 0, sizeof(m));
906 m.pointer_vertex = varray_vertex3f;
908 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
909 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
910 R_Mesh_Draw(0, 4, 2, polygonelements);
914 void R_RenderScene(void);
916 matrix4x4_t r_waterscrollmatrix;
923 void R_RenderView(void)
925 if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
926 return; //Host_Error ("R_RenderView: NULL worldmodel");
928 r_view_width = bound(0, r_refdef.width, vid.width);
929 r_view_height = bound(0, r_refdef.height, vid.height);
931 r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
932 r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
934 r_view_fov_x = bound(1, r_refdef.fov_x, 170);
935 r_view_fov_y = bound(1, r_refdef.fov_y, 170);
936 r_view_matrix = r_refdef.viewentitymatrix;
937 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
938 r_rtworld = r_shadow_realtime_world.integer;
939 r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
940 r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
941 r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
942 r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
944 // GL is weird because it's bottom to top, r_view_y is top to bottom
945 qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
946 GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
947 GL_ScissorTest(true);
953 R_TimeReport("setup");
955 qglDepthFunc(GL_LEQUAL);
956 qglPolygonOffset(0, 0);
957 qglEnable(GL_POLYGON_OFFSET_FILL);
961 qglPolygonOffset(0, 0);
962 qglDisable(GL_POLYGON_OFFSET_FILL);
965 R_TimeReport("blendview");
967 GL_Scissor(0, 0, vid.width, vid.height);
968 GL_ScissorTest(false);
971 extern void R_DrawLightningBeams (void);
972 void R_RenderScene(void)
974 // don't let sound skip if going slow
975 if (r_refdef.extraupdate)
980 R_MeshQueue_BeginScene();
982 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
986 r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
987 if (r_rtworldshadows || r_rtdlightshadows)
988 GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f);
990 GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip);
992 GL_SetupView_Orientation_FromEntity(&r_view_matrix);
994 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);
999 R_TimeReport("worldvis");
1002 R_TimeReport("markentity");
1004 R_Shadow_UpdateWorldLightSelection();
1006 // don't let sound skip if going slow
1007 if (r_refdef.extraupdate)
1010 GL_ShowTrisColor(0.025, 0.025, 0, 1);
1011 if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
1013 r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
1014 R_TimeReport("worldsky");
1017 if (R_DrawBrushModelsSky())
1018 R_TimeReport("bmodelsky");
1020 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
1021 if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
1023 r_refdef.worldmodel->Draw(r_refdef.worldentity);
1024 R_TimeReport("world");
1027 // don't let sound skip if going slow
1028 if (r_refdef.extraupdate)
1031 GL_ShowTrisColor(0, 0.015, 0, 1);
1034 R_TimeReport("models");
1036 // don't let sound skip if going slow
1037 if (r_refdef.extraupdate)
1040 GL_ShowTrisColor(0, 0, 0.033, 1);
1041 R_ShadowVolumeLighting(false);
1042 R_TimeReport("rtlights");
1044 // don't let sound skip if going slow
1045 if (r_refdef.extraupdate)
1048 GL_ShowTrisColor(0.1, 0, 0, 1);
1050 R_DrawLightningBeams();
1051 R_TimeReport("lightning");
1054 R_TimeReport("particles");
1057 R_TimeReport("explosions");
1059 R_MeshQueue_RenderTransparent();
1060 R_TimeReport("drawtrans");
1063 R_TimeReport("coronas");
1065 R_DrawWorldCrosshair();
1066 R_TimeReport("crosshair");
1068 R_MeshQueue_Render();
1069 R_MeshQueue_EndScene();
1071 if ((r_shadow_visiblelighting.integer || r_shadow_visiblevolumes.integer) && !r_showtrispass)
1073 R_ShadowVolumeLighting(true);
1074 R_TimeReport("visiblevolume");
1077 GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
1079 // don't let sound skip if going slow
1080 if (r_refdef.extraupdate)
1085 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
1088 float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
1090 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1091 GL_DepthMask(false);
1093 R_Mesh_Matrix(&r_identitymatrix);
1095 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2];
1096 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
1097 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
1098 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
1099 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
1100 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
1101 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
1102 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
1103 R_FillColors(color, 8, cr, cg, cb, ca);
1106 for (i = 0, v = vertex, c = color;i < 8;i++, v += 4, c += 4)
1108 VectorSubtract(v, r_vieworigin, diff);
1109 f2 = exp(fogdensity/DotProduct(diff, diff));
1111 c[0] = c[0] * f1 + fogcolor[0] * f2;
1112 c[1] = c[1] * f1 + fogcolor[1] * f2;
1113 c[2] = c[2] * f1 + fogcolor[2] * f2;
1116 memset(&m, 0, sizeof(m));
1117 m.pointer_vertex = vertex3f;
1118 m.pointer_color = color;
1124 int nomodelelements[24] =
1136 float nomodelvertex3f[6*3] =
1146 float nomodelcolor4f[6*4] =
1148 0.0f, 0.0f, 0.5f, 1.0f,
1149 0.0f, 0.0f, 0.5f, 1.0f,
1150 0.0f, 0.5f, 0.0f, 1.0f,
1151 0.0f, 0.5f, 0.0f, 1.0f,
1152 0.5f, 0.0f, 0.0f, 1.0f,
1153 0.5f, 0.0f, 0.0f, 1.0f
1156 void R_DrawNoModelCallback(const void *calldata1, int calldata2)
1158 const entity_render_t *ent = calldata1;
1160 float f1, f2, *c, diff[3];
1163 R_Mesh_Matrix(&ent->matrix);
1165 memset(&m, 0, sizeof(m));
1166 m.pointer_vertex = nomodelvertex3f;
1168 if (ent->flags & EF_ADDITIVE)
1170 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
1171 GL_DepthMask(false);
1173 else if (ent->alpha < 1)
1175 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1176 GL_DepthMask(false);
1180 GL_BlendFunc(GL_ONE, GL_ZERO);
1183 GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
1186 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
1187 m.pointer_color = color4f;
1188 VectorSubtract(ent->origin, r_vieworigin, diff);
1189 f2 = exp(fogdensity/DotProduct(diff, diff));
1191 for (i = 0, c = color4f;i < 6;i++, c += 4)
1193 c[0] = (c[0] * f1 + fogcolor[0] * f2);
1194 c[1] = (c[1] * f1 + fogcolor[1] * f2);
1195 c[2] = (c[2] * f1 + fogcolor[2] * f2);
1199 else if (ent->alpha != 1)
1201 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
1202 m.pointer_color = color4f;
1203 for (i = 0, c = color4f;i < 6;i++, c += 4)
1207 m.pointer_color = nomodelcolor4f;
1209 R_Mesh_Draw(0, 6, 8, nomodelelements);
1212 void R_DrawNoModel(entity_render_t *ent)
1214 //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
1215 R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModelCallback, ent, 0);
1217 // R_DrawNoModelCallback(ent, 0);
1220 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
1222 vec3_t right1, right2, diff, normal;
1224 VectorSubtract (org2, org1, normal);
1226 // calculate 'right' vector for start
1227 VectorSubtract (r_vieworigin, org1, diff);
1228 CrossProduct (normal, diff, right1);
1229 VectorNormalize (right1);
1231 // calculate 'right' vector for end
1232 VectorSubtract (r_vieworigin, org2, diff);
1233 CrossProduct (normal, diff, right2);
1234 VectorNormalize (right2);
1236 vert[ 0] = org1[0] + width * right1[0];
1237 vert[ 1] = org1[1] + width * right1[1];
1238 vert[ 2] = org1[2] + width * right1[2];
1239 vert[ 3] = org1[0] - width * right1[0];
1240 vert[ 4] = org1[1] - width * right1[1];
1241 vert[ 5] = org1[2] - width * right1[2];
1242 vert[ 6] = org2[0] - width * right2[0];
1243 vert[ 7] = org2[1] - width * right2[1];
1244 vert[ 8] = org2[2] - width * right2[2];
1245 vert[ 9] = org2[0] + width * right2[0];
1246 vert[10] = org2[1] + width * right2[1];
1247 vert[11] = org2[2] + width * right2[2];
1250 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
1252 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)
1259 VectorSubtract(origin, r_vieworigin, diff);
1260 ca *= 1 - exp(fogdensity/DotProduct(diff,diff));
1263 R_Mesh_Matrix(&r_identitymatrix);
1264 GL_BlendFunc(blendfunc1, blendfunc2);
1265 GL_DepthMask(false);
1266 GL_DepthTest(!depthdisable);
1268 varray_vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
1269 varray_vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
1270 varray_vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
1271 varray_vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
1272 varray_vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
1273 varray_vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
1274 varray_vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
1275 varray_vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
1276 varray_vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
1277 varray_vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
1278 varray_vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
1279 varray_vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
1281 memset(&m, 0, sizeof(m));
1282 m.tex[0] = R_GetTexture(texture);
1283 m.pointer_texcoord[0] = spritetexcoord2f;
1284 m.pointer_vertex = varray_vertex3f;
1286 GL_Color(cr, cg, cb, ca);
1287 R_Mesh_Draw(0, 4, 2, polygonelements);
1290 int R_Mesh_AddVertex3f(rmesh_t *mesh, const float *v)
1294 for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
1295 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
1297 if (i == mesh->numvertices)
1299 if (mesh->numvertices < mesh->maxvertices)
1301 VectorCopy(v, vertex3f);
1302 mesh->numvertices++;
1304 return mesh->numvertices;
1310 void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
1314 element[0] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
1315 element[1] = R_Mesh_AddVertex3f(mesh, vertex3f);vertex3f += 3;
1316 e = mesh->element3i + mesh->numtriangles * 3;
1317 for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
1319 element[2] = R_Mesh_AddVertex3f(mesh, vertex3f);
1320 if (mesh->numtriangles < mesh->maxtriangles)
1325 mesh->numtriangles++;
1327 element[1] = element[2];
1331 void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
1333 int planenum, planenum2;
1336 mplane_t *plane, *plane2;
1337 float temppoints[2][256*3];
1338 for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
1342 PolygonF_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->normal[3], 1024.0*1024.0*1024.0);
1343 for (planenum2 = 0, plane2 = planes;planenum2 < numplanes && tempnumpoints >= 3;planenum2++, plane2++)
1345 if (planenum2 == planenum)
1347 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);
1350 if (tempnumpoints < 3)
1352 // generate elements forming a triangle fan for this polygon
1353 R_Mesh_AddPolygon3f(mesh, tempnumpoints, temppoints[w]);
1357 void R_Texture_AddLayer(texture_t *t, qboolean depthmask, int blendfunc1, int blendfunc2, texturelayertype_t type, rtexture_t *texture, matrix4x4_t *matrix, float r, float g, float b, float a, int texrgbscale)
1359 texturelayer_t *layer;
1360 layer = t->currentlayers + t->currentnumlayers++;
1362 layer->depthmask = depthmask;
1363 layer->blendfunc1 = blendfunc1;
1364 layer->blendfunc2 = blendfunc2;
1365 layer->texture = texture;
1366 layer->texmatrix = *matrix;
1367 layer->color[0] = r;
1368 layer->color[1] = g;
1369 layer->color[2] = b;
1370 layer->color[3] = a;
1371 layer->texrgbscale = texrgbscale;
1374 void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
1376 // FIXME: identify models using a better check than ent->model->brush.shadowmesh
1377 //int lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
1380 texture_t *texture = t;
1381 model_t *model = ent->model;
1382 int s = ent->skinnum;
1383 if ((unsigned int)s >= (unsigned int)model->numskins)
1387 if (model->skinscenes)
1389 if (model->skinscenes[s].framecount > 1)
1390 s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
1392 s = model->skinscenes[s].firstframe;
1395 t = t + s * model->num_surfaces;
1397 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];
1398 texture->currentframe = t;
1401 t->currentmaterialflags = t->basematerialflags;
1402 t->currentcolorbase[0] = ent->colormod[0];
1403 t->currentcolorbase[1] = ent->colormod[1];
1404 t->currentcolorbase[2] = ent->colormod[2];
1405 t->currentcolorbase[3] = ent->alpha;
1406 if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
1407 t->currentcolorbase[3] *= r_wateralpha.value;
1408 if (!(ent->flags & RENDER_LIGHT))
1409 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
1410 if (ent->effects & EF_ADDITIVE)
1411 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_TRANSPARENT;
1412 else if (t->currentcolorbase[3] < 1)
1413 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT;
1414 if (ent->effects & EF_NODEPTHTEST)
1415 t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST;
1416 if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
1417 t->currenttexmatrix = r_waterscrollmatrix;
1419 t->currenttexmatrix = r_identitymatrix;
1420 if (ent->colormap >= 0)
1424 t->currentbasetexture = t->skin.base;
1425 t->currentdopants = t->skin.pants != NULL;
1426 t->currentdoshirt = t->skin.shirt != NULL;
1427 // 128-224 are backwards ranges
1428 b = (ent->colormap & 0xF) << 4;b += (b >= 128 && b < 224) ? 4 : 12;
1429 t->currentdofullbrightpants = (b >= 224) || (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT);
1430 bcolor = (qbyte *) (&palette_complete[b]);
1431 t->currentcolorpants[0] = bcolor[0] * (1.0f / 255.0f) * t->currentcolorbase[0];
1432 t->currentcolorpants[1] = bcolor[1] * (1.0f / 255.0f) * t->currentcolorbase[1];
1433 t->currentcolorpants[2] = bcolor[2] * (1.0f / 255.0f) * t->currentcolorbase[2];
1434 t->currentcolorpants[3] = t->currentcolorbase[3];
1435 // 128-224 are backwards ranges
1436 b = (ent->colormap & 0xF0);b += (b >= 128 && b < 224) ? 4 : 12;
1437 t->currentdofullbrightshirt = (b >= 224) || (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT);
1438 bcolor = (qbyte *) (&palette_complete[b]);
1439 t->currentcolorshirt[0] = bcolor[0] * (1.0f / 255.0f) * t->currentcolorbase[0];
1440 t->currentcolorshirt[1] = bcolor[1] * (1.0f / 255.0f) * t->currentcolorbase[1];
1441 t->currentcolorshirt[2] = bcolor[2] * (1.0f / 255.0f) * t->currentcolorbase[2];
1442 t->currentcolorshirt[3] = t->currentcolorbase[3];
1446 t->currentbasetexture = t->skin.merged ? t->skin.merged : t->skin.base;
1447 t->currentdopants = false;
1448 t->currentdoshirt = false;
1449 t->currentdofullbrightpants = false;
1450 t->currentdofullbrightshirt = false;
1452 t->currentfogallpasses = fogenabled && (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
1453 t->currentnumlayers = 0;
1454 if (!(t->currentmaterialflags & MATERIALFLAG_NODRAW))
1456 int blendfunc1, blendfunc2, depthmask;
1457 if (t->currentmaterialflags & MATERIALFLAG_ADD)
1459 blendfunc1 = GL_SRC_ALPHA;
1460 blendfunc2 = GL_ONE;
1463 else if (t->currentmaterialflags & MATERIALFLAG_ALPHA)
1465 blendfunc1 = GL_SRC_ALPHA;
1466 blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
1471 blendfunc1 = GL_ONE;
1472 blendfunc2 = GL_ZERO;
1475 if (gl_lightmaps.integer)
1476 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LIGHTMAP, r_texture_white, &r_identitymatrix, 1, 1, 1, 1, 1);
1477 else if (t->currentmaterialflags & MATERIALFLAG_SKY)
1479 // transparent sky would be ridiculous
1480 if (!(t->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
1481 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_SKY, r_texture_white, &r_identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], 1, 1);
1483 else if (t->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
1486 float colorscale, r, g, b;
1487 rtexture_t *currentbasetexture;
1489 // q3bsp has no lightmap updates, so the lightstylevalue that
1490 // would normally be baked into the lightmaptexture must be
1491 // applied to the color
1492 if (!(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) && ent->model->type == mod_brushq3)
1493 colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f);
1494 r = t->currentcolorbase[0] * colorscale;
1495 g = t->currentcolorbase[1] * colorscale;
1496 b = t->currentcolorbase[2] * colorscale;
1497 // transparent and fullbright are not affected by r_lightmapintensity
1498 if (!(t->currentmaterialflags & (MATERIALFLAG_TRANSPARENT | MATERIALFLAG_FULLBRIGHT)))
1500 r *= r_lightmapintensity;
1501 g *= r_lightmapintensity;
1502 b *= r_lightmapintensity;
1504 currentbasetexture = (ent->colormap >= 0 && t->skin.merged) ? t->skin.merged : t->skin.base;
1505 if (!(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) && r_textureunits.integer >= 2 && gl_combine.integer)
1507 if ((r > 2 || g > 2 || b > 2) && gl_combine.integer)
1508 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LIGHTMAP_DOUBLEMODULATE_TEXTURE, currentbasetexture, &t->currenttexmatrix, r * 0.25f, g * 0.25f, b * 0.25f, t->currentcolorbase[3], 4);
1509 else if ((r > 1 || g > 1 || b > 1) && gl_combine.integer)
1510 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LIGHTMAP_DOUBLEMODULATE_TEXTURE, currentbasetexture, &t->currenttexmatrix, r * 0.5f, g * 0.5f, b * 0.5f, t->currentcolorbase[3], 2);
1512 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LIGHTMAP_DOUBLEMODULATE_TEXTURE, currentbasetexture, &t->currenttexmatrix, r, g, b, t->currentcolorbase[3], 1);
1514 else if ((t->currentmaterialflags & (MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_TRANSPARENT)) == 0)
1516 R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LIGHTMAP, r_texture_white, &r_identitymatrix, 1, 1, 1, 1, 1);
1517 if (r > 1 || g > 1 || b > 1)
1518 R_Texture_AddLayer(t, false, GL_DST_COLOR, GL_SRC_COLOR, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, r * 0.5f, g * 0.5f, b * 0.5f, t->currentcolorbase[3], 1);
1520 R_Texture_AddLayer(t, false, GL_ZERO, GL_SRC_COLOR, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, r, g, b, t->currentcolorbase[3], 1);
1524 if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
1526 type = TEXTURELAYERTYPE_TEXTURE;
1532 type = TEXTURELAYERTYPE_VERTEXTEXTURE;
1533 if ((r > 2 || g > 2 || b > 2) && gl_combine.integer)
1534 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, type, currentbasetexture, &t->currenttexmatrix, r * 0.25f, g * 0.25f, b * 0.25f, t->currentcolorbase[3], 4);
1535 else if ((r > 1 || g > 1 || b > 1) && gl_combine.integer)
1536 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, type, currentbasetexture, &t->currenttexmatrix, r * 0.5f, g * 0.5f, b * 0.5f, t->currentcolorbase[3], 2);
1538 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, type, currentbasetexture, &t->currenttexmatrix, r, g, b, t->currentcolorbase[3], 1);
1540 if (ent->colormap >= 0 && t->skin.pants)
1544 // 128-224 are backwards ranges
1545 cb = (ent->colormap & 0xF) << 4;cb += (cb >= 128 && cb < 224) ? 4 : 12;
1546 cbcolor = (qbyte *) (&palette_complete[cb]);
1547 r = cbcolor[0] * (1.0f / 255.0f) * t->currentcolorbase[0] * colorscale;
1548 g = cbcolor[1] * (1.0f / 255.0f) * t->currentcolorbase[1] * colorscale;
1549 b = cbcolor[2] * (1.0f / 255.0f) * t->currentcolorbase[2] * colorscale;
1550 // transparent and fullbright are not affected by r_lightmapintensity
1551 if ((cb >= 224) || (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
1553 type = TEXTURELAYERTYPE_TEXTURE;
1560 type = TEXTURELAYERTYPE_VERTEXTEXTURE;
1561 if (!(t->currentmaterialflags & (MATERIALFLAG_TRANSPARENT | MATERIALFLAG_FULLBRIGHT)))
1563 r *= r_lightmapintensity;
1564 g *= r_lightmapintensity;
1565 b *= r_lightmapintensity;
1568 if ((r > 2 || g > 2 || b > 2) && gl_combine.integer)
1569 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, type, t->skin.pants, &t->currenttexmatrix, r * 0.25f, g * 0.25f, b * 0.25f, t->currentcolorbase[3], 4);
1570 else if ((r > 1 || g > 1 || b > 1) && gl_combine.integer)
1571 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, type, t->skin.pants, &t->currenttexmatrix, r * 0.5f, g * 0.5f, b * 0.5f, t->currentcolorbase[3], 2);
1573 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, type, t->skin.pants, &t->currenttexmatrix, r, g, b, t->currentcolorbase[3], 1);
1575 if (ent->colormap >= 0 && t->skin.shirt)
1579 // 128-224 are backwards ranges
1580 cb = (ent->colormap & 0xF0);cb += (cb >= 128 && cb < 224) ? 4 : 12;
1581 cbcolor = (qbyte *) (&palette_complete[cb]);
1582 r = cbcolor[0] * (1.0f / 255.0f) * t->currentcolorbase[0] * colorscale;
1583 g = cbcolor[1] * (1.0f / 255.0f) * t->currentcolorbase[1] * colorscale;
1584 b = cbcolor[2] * (1.0f / 255.0f) * t->currentcolorbase[2] * colorscale;
1585 // transparent and fullbright are not affected by r_lightmapintensity
1586 if ((cb >= 224) || (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
1588 type = TEXTURELAYERTYPE_TEXTURE;
1595 type = TEXTURELAYERTYPE_VERTEXTEXTURE;
1596 if (!(t->currentmaterialflags & (MATERIALFLAG_TRANSPARENT | MATERIALFLAG_FULLBRIGHT)))
1598 r *= r_lightmapintensity;
1599 g *= r_lightmapintensity;
1600 b *= r_lightmapintensity;
1603 if ((r > 2 || g > 2 || b > 2) && gl_combine.integer)
1604 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, type, t->skin.shirt, &t->currenttexmatrix, r * 0.25f, g * 0.25f, b * 0.25f, t->currentcolorbase[3], 4);
1605 else if ((r > 1 || g > 1 || b > 1) && gl_combine.integer)
1606 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, type, t->skin.shirt, &t->currenttexmatrix, r * 0.5f, g * 0.5f, b * 0.5f, t->currentcolorbase[3], 2);
1608 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, type, t->skin.shirt, &t->currenttexmatrix, r, g, b, t->currentcolorbase[3], 1);
1610 if (r_ambient.value >= (1.0f/64.0f))
1612 r = t->currentcolorbase[0] * colorscale * r_ambient.value * (1.0f / 64.0f);
1613 g = t->currentcolorbase[1] * colorscale * r_ambient.value * (1.0f / 64.0f);
1614 b = t->currentcolorbase[2] * colorscale * r_ambient.value * (1.0f / 64.0f);
1615 if ((r > 2 || g > 2 || b > 2) && gl_combine.integer)
1616 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, r * 0.25f, g * 0.25f, b * 0.25f, t->currentcolorbase[3], 4);
1617 else if ((r > 1 || g > 1 || b > 1) && gl_combine.integer)
1618 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, r * 0.5f, g * 0.5f, b * 0.5f, t->currentcolorbase[3], 2);
1620 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, r, g, b, t->currentcolorbase[3], 1);
1622 if (t->skin.glow != NULL)
1623 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, t->currentcolorbase[3], 1);
1624 if (fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
1626 // if this is opaque use alpha blend which will darken the earlier
1629 // if this is an alpha blended material, all the earlier passes
1630 // were darkened by fog already, so we only need to add the fog
1631 // color ontop through the fog mask texture
1633 // if this is an additive blended material, all the earlier passes
1634 // were darkened by fog already, and we should not add fog color
1635 // (because the background was not darkened, there is no fog color
1636 // that was lost behind it).
1637 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, t->currentfogallpasses ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &r_identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], t->currentcolorbase[3], 1);
1643 void R_UpdateAllTextureInfo(entity_render_t *ent)
1647 for (i = 0;i < ent->model->num_textures;i++)
1648 R_UpdateTextureInfo(ent, ent->model->data_textures + i);
1651 float *rsurface_vertex3f;
1652 float *rsurface_svector3f;
1653 float *rsurface_tvector3f;
1654 float *rsurface_normal3f;
1655 float *rsurface_lightmapcolor4f;
1657 void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg)
1660 float center[3], forward[3], right[3], up[3], v[4][3];
1661 matrix4x4_t matrix1, imatrix1;
1662 if ((ent->frameblend[0].lerp != 1 || ent->frameblend[0].frame != 0) && (surface->groupmesh->data_morphvertex3f || surface->groupmesh->data_vertexboneweights))
1664 rsurface_vertex3f = varray_vertex3f;
1665 rsurface_svector3f = NULL;
1666 rsurface_tvector3f = NULL;
1667 rsurface_normal3f = NULL;
1668 Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, surface->groupmesh, rsurface_vertex3f);
1672 rsurface_vertex3f = surface->groupmesh->data_vertex3f;
1673 rsurface_svector3f = surface->groupmesh->data_svector3f;
1674 rsurface_tvector3f = surface->groupmesh->data_tvector3f;
1675 rsurface_normal3f = surface->groupmesh->data_normal3f;
1677 if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
1679 if (!rsurface_svector3f)
1681 rsurface_svector3f = varray_svector3f;
1682 rsurface_tvector3f = varray_tvector3f;
1683 rsurface_normal3f = varray_normal3f;
1684 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);
1686 // a single autosprite surface can contain multiple sprites...
1687 VectorClear(forward);
1689 VectorSet(up, 0, 0, 1);
1690 for (j = 0;j < surface->num_vertices - 3;j += 4)
1692 VectorClear(center);
1693 for (i = 0;i < 4;i++)
1694 VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
1695 VectorScale(center, 0.25f, center);
1696 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
1697 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);
1698 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
1699 for (i = 0;i < 4;i++)
1700 Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
1701 forward[0] = modelorg[0] - center[0];
1702 forward[1] = modelorg[1] - center[1];
1703 VectorNormalize(forward);
1704 right[0] = forward[1];
1705 right[1] = -forward[0];
1706 for (i = 0;i < 4;i++)
1707 VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (surface->num_firstvertex+i+j) * 3);
1709 rsurface_vertex3f = varray_vertex3f;
1710 rsurface_svector3f = NULL;
1711 rsurface_tvector3f = NULL;
1712 rsurface_normal3f = NULL;
1714 else if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE)
1716 if (!rsurface_svector3f)
1718 rsurface_svector3f = varray_svector3f;
1719 rsurface_tvector3f = varray_tvector3f;
1720 rsurface_normal3f = varray_normal3f;
1721 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);
1723 Matrix4x4_Transform(&ent->inversematrix, r_viewforward, forward);
1724 Matrix4x4_Transform(&ent->inversematrix, r_viewright, right);
1725 Matrix4x4_Transform(&ent->inversematrix, r_viewup, up);
1726 // a single autosprite surface can contain multiple sprites...
1727 for (j = 0;j < surface->num_vertices - 3;j += 4)
1729 VectorClear(center);
1730 for (i = 0;i < 4;i++)
1731 VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
1732 VectorScale(center, 0.25f, center);
1733 // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
1734 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);
1735 Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
1736 for (i = 0;i < 4;i++)
1737 Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
1738 for (i = 0;i < 4;i++)
1739 VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (surface->num_firstvertex+i+j) * 3);
1741 rsurface_vertex3f = varray_vertex3f;
1742 rsurface_svector3f = NULL;
1743 rsurface_tvector3f = NULL;
1744 rsurface_normal3f = NULL;
1746 R_Mesh_VertexPointer(rsurface_vertex3f);
1749 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)
1758 vec4_t ambientcolor4f;
1759 vec3_t diffusecolor;
1760 vec3_t diffusenormal;
1761 if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, r*0.5f, g*0.5f, b*0.5f, a, false))
1763 rsurface_lightmapcolor4f = varray_color4f;
1764 if (rsurface_normal3f == NULL)
1766 rsurface_normal3f = varray_normal3f;
1767 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);
1769 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);
1778 r = ambientcolor4f[0];
1779 g = ambientcolor4f[1];
1780 b = ambientcolor4f[2];
1781 a = ambientcolor4f[3];
1782 rsurface_lightmapcolor4f = NULL;
1785 else if (lightmode >= 1)
1787 if (surface->lightmapinfo)
1789 for (i = 0, c = varray_color4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
1791 const qbyte *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i];
1792 float scale = d_lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
1793 VectorScale(lm, scale, c);
1794 if (surface->lightmapinfo->styles[1] != 255)
1796 int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
1798 scale = d_lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
1799 VectorMA(c, scale, lm, c);
1800 if (surface->lightmapinfo->styles[2] != 255)
1803 scale = d_lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
1804 VectorMA(c, scale, lm, c);
1805 if (surface->lightmapinfo->styles[3] != 255)
1808 scale = d_lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
1809 VectorMA(c, scale, lm, c);
1814 rsurface_lightmapcolor4f = varray_color4f;
1817 rsurface_lightmapcolor4f = surface->groupmesh->data_lightmapcolor4f;
1820 rsurface_lightmapcolor4f = NULL;
1823 if (rsurface_lightmapcolor4f)
1825 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)
1827 VectorSubtract(v, modelorg, diff);
1828 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1837 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)
1839 VectorSubtract(v, modelorg, diff);
1840 f = 1 - exp(fogdensity/DotProduct(diff, diff));
1847 rsurface_lightmapcolor4f = varray_color4f;
1849 if (applycolor && rsurface_lightmapcolor4f)
1851 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)
1858 rsurface_lightmapcolor4f = varray_color4f;
1860 R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
1861 GL_Color(r, g, b, a);
1865 static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
1868 int texturesurfaceindex;
1873 float f, r, g, b, a, colorscale;
1874 const msurface_t *surface;
1875 qboolean applycolor;
1877 if (texture->currentmaterialflags & MATERIALFLAG_NODRAW)
1879 c_faces += texturenumsurfaces;
1880 // FIXME: identify models using a better check than ent->model->brush.shadowmesh
1881 lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
1882 // gl_lightmaps debugging mode skips normal texturing
1883 if (gl_lightmaps.integer)
1885 GL_BlendFunc(GL_ONE, GL_ZERO);
1888 qglDisable(GL_CULL_FACE);
1889 GL_Color(1, 1, 1, 1);
1890 memset(&m, 0, sizeof(m));
1892 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1894 surface = texturesurfacelist[texturesurfaceindex];
1895 R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
1896 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
1897 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
1898 RSurf_SetColorPointer(ent, surface, modelorg, 1, 1, 1, 1, lightmode ? lightmode : !surface->lightmaptexture, false, false);
1899 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
1900 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
1901 GL_LockArrays(0, 0);
1903 qglEnable(GL_CULL_FACE);
1906 GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
1907 if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
1908 qglDisable(GL_CULL_FACE);
1911 if (texture->currentnumlayers)
1914 texturelayer_t *layer;
1915 for (layerindex = 0, layer = texture->currentlayers;layerindex < texture->currentnumlayers;layerindex++, layer++)
1917 GL_DepthMask(layer->depthmask);
1918 GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
1919 GL_Color(layer->color[0], layer->color[1], layer->color[2], layer->color[3]);
1920 applycolor = layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1;
1921 switch (layer->type)
1923 case TEXTURELAYERTYPE_SKY:
1926 skyrendernow = false;
1927 if (skyrendermasked)
1930 // restore entity matrix and GL_Color
1931 R_Mesh_Matrix(&ent->matrix);
1932 GL_Color(layer->color[0], layer->color[1], layer->color[2], layer->color[3]);
1935 // LordHavoc: HalfLife maps have freaky skypolys...
1936 //if (!ent->model->brush.ishlbsp)
1938 if (skyrendermasked)
1940 // depth-only (masking)
1941 GL_ColorMask(0,0,0,0);
1942 // just to make sure that braindead drivers don't draw anything
1943 // despite that colormask...
1944 GL_BlendFunc(GL_ZERO, GL_ONE);
1949 GL_BlendFunc(GL_ONE, GL_ZERO);
1951 memset(&m, 0, sizeof(m));
1953 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1955 surface = texturesurfacelist[texturesurfaceindex];
1956 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
1957 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
1958 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
1959 GL_LockArrays(0, 0);
1961 if (skyrendermasked)
1962 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
1965 case TEXTURELAYERTYPE_LIGHTMAP_DOUBLEMODULATE_TEXTURE:
1966 memset(&m, 0, sizeof(m));
1967 m.tex[1] = R_GetTexture(layer->texture);
1968 m.texmatrix[1] = layer->texmatrix;
1969 m.texrgbscale[1] = layer->texrgbscale;
1970 m.pointer_color = varray_color4f;
1972 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
1974 surface = texturesurfacelist[texturesurfaceindex];
1975 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
1976 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
1977 R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
1980 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
1981 RSurf_SetColorPointer(ent, surface, modelorg, layer->color[0], layer->color[1], layer->color[2], layer->color[3], 2, applycolor, texture->currentfogallpasses);
1983 else if (surface->lightmaptexture)
1985 R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
1986 RSurf_SetColorPointer(ent, surface, modelorg, layer->color[0], layer->color[1], layer->color[2], layer->color[3], 0, applycolor, texture->currentfogallpasses);
1990 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
1991 RSurf_SetColorPointer(ent, surface, modelorg, layer->color[0], layer->color[1], layer->color[2], layer->color[3], 1, applycolor, texture->currentfogallpasses);
1993 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
1994 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
1995 GL_LockArrays(0, 0);
1998 case TEXTURELAYERTYPE_LIGHTMAP:
1999 memset(&m, 0, sizeof(m));
2001 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2003 surface = texturesurfacelist[texturesurfaceindex];
2004 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2005 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
2008 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2009 RSurf_SetColorPointer(ent, surface, modelorg, layer->color[0], layer->color[1], layer->color[2], layer->color[3], 2, applycolor, false);
2011 else if (surface->lightmaptexture)
2013 R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
2014 R_Mesh_ColorPointer(NULL);
2018 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2019 // TODO: use a specialized RSurf_SetColorPointer
2020 RSurf_SetColorPointer(ent, surface, modelorg, layer->color[0], layer->color[1], layer->color[2], layer->color[3], 1, applycolor, false);
2022 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2023 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2024 GL_LockArrays(0, 0);
2027 case TEXTURELAYERTYPE_VERTEXTEXTURE:
2028 memset(&m, 0, sizeof(m));
2029 m.tex[0] = R_GetTexture(layer->texture);
2030 m.texmatrix[0] = layer->texmatrix;
2031 m.pointer_color = varray_color4f;
2032 m.texrgbscale[0] = layer->texrgbscale;
2034 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2036 surface = texturesurfacelist[texturesurfaceindex];
2037 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2038 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2039 RSurf_SetColorPointer(ent, surface, modelorg, layer->color[0], layer->color[1], layer->color[2], layer->color[3], lightmode ? lightmode : 1, applycolor, texture->currentfogallpasses);
2040 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2041 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2042 GL_LockArrays(0, 0);
2045 case TEXTURELAYERTYPE_TEXTURE:
2046 memset(&m, 0, sizeof(m));
2047 m.tex[0] = R_GetTexture(layer->texture);
2048 m.texmatrix[0] = layer->texmatrix;
2049 m.pointer_color = varray_color4f;
2050 m.texrgbscale[0] = layer->texrgbscale;
2052 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2054 surface = texturesurfacelist[texturesurfaceindex];
2055 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2056 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2057 RSurf_SetColorPointer(ent, surface, modelorg, layer->color[0], layer->color[1], layer->color[2], layer->color[3], 0, applycolor, texture->currentfogallpasses);
2058 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2059 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2060 GL_LockArrays(0, 0);
2063 case TEXTURELAYERTYPE_FOG:
2064 memset(&m, 0, sizeof(m));
2067 m.tex[0] = R_GetTexture(layer->texture);
2068 m.texmatrix[0] = layer->texmatrix;
2071 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2075 surface = texturesurfacelist[texturesurfaceindex];
2076 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2078 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2079 R_Mesh_ColorPointer(varray_color4f);
2080 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)
2082 VectorSubtract(v, modelorg, diff);
2083 f = exp(fogdensity/DotProduct(diff, diff));
2084 c[0] = layer->color[0];
2085 c[1] = layer->color[1];
2086 c[2] = layer->color[2];
2087 c[3] = f * layer->color[3];
2089 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2090 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2091 GL_LockArrays(0, 0);
2095 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
2102 GL_DepthMask(!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT));
2103 if (texture->currentmaterialflags & MATERIALFLAG_ADD)
2104 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2105 else if (texture->currentmaterialflags & MATERIALFLAG_ALPHA)
2106 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2108 GL_BlendFunc(GL_ONE, GL_ZERO);
2109 if (texture->currentmaterialflags & MATERIALFLAG_SKY)
2113 skyrendernow = false;
2114 if (skyrendermasked)
2117 // LordHavoc: HalfLife maps have freaky skypolys...
2118 //if (!ent->model->brush.ishlbsp)
2120 R_Mesh_Matrix(&ent->matrix);
2121 GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
2122 if (skyrendermasked)
2124 // depth-only (masking)
2125 GL_ColorMask(0,0,0,0);
2126 // just to make sure that braindead drivers don't draw anything
2127 // despite that colormask...
2128 GL_BlendFunc(GL_ZERO, GL_ONE);
2133 GL_BlendFunc(GL_ONE, GL_ZERO);
2137 memset(&m, 0, sizeof(m));
2139 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2141 surface = texturesurfacelist[texturesurfaceindex];
2142 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2143 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2144 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2145 GL_LockArrays(0, 0);
2147 GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
2150 else if (texture->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
2152 // normal surface (wall or water)
2153 if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) && r_textureunits.integer >= 2 && gl_combine.integer)
2155 // multitexture single pass
2156 memset(&m, 0, sizeof(m));
2157 m.tex[1] = R_GetTexture(texture->currentbasetexture);
2158 m.texmatrix[1] = texture->currenttexmatrix;
2159 m.texrgbscale[1] = 2;
2160 m.pointer_color = varray_color4f;
2162 // transparent is not affected by r_lightmapintensity
2163 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2164 colorscale = r_lightmapintensity;
2167 // q3bsp has no lightmap updates, so the lightstylevalue that
2168 // would normally be baked into the lightmaptexture must be
2169 // applied to the color
2170 if (ent->model->type == mod_brushq3)
2171 colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f);
2172 r = texture->currentcolorbase[0] * colorscale;
2173 g = texture->currentcolorbase[1] * colorscale;
2174 b = texture->currentcolorbase[2] * colorscale;
2175 a = texture->currentcolorbase[3];
2176 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2177 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2179 surface = texturesurfacelist[texturesurfaceindex];
2180 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2181 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
2182 R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
2183 if (surface->lightmaptexture)
2184 R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
2186 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2187 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode ? lightmode : !surface->lightmaptexture, applycolor, texture->currentfogallpasses);
2188 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2189 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2190 GL_LockArrays(0, 0);
2193 // FIXME: identify models using a better check than ent->model->brush.shadowmesh
2194 else if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT) && ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh))
2196 // single texture two pass
2197 GL_BlendFunc(GL_ONE, GL_ZERO);
2199 GL_Color(1, 1, 1, 1);
2200 memset(&m, 0, sizeof(m));
2202 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2204 surface = texturesurfacelist[texturesurfaceindex];
2205 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2206 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
2207 if (surface->lightmaptexture)
2209 R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
2210 R_Mesh_ColorPointer(NULL);
2214 R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
2215 R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f);
2217 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2218 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2219 GL_LockArrays(0, 0);
2221 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
2222 GL_DepthMask(false);
2223 GL_Color(r_lightmapintensity * texture->currentcolorbase[0], r_lightmapintensity * texture->currentcolorbase[1], r_lightmapintensity * texture->currentcolorbase[2], texture->currentcolorbase[3]);
2224 memset(&m, 0, sizeof(m));
2225 m.tex[0] = R_GetTexture(texture->currentbasetexture);
2226 m.texmatrix[0] = texture->currenttexmatrix;
2228 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2230 surface = texturesurfacelist[texturesurfaceindex];
2231 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2232 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2233 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2234 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2235 GL_LockArrays(0, 0);
2240 // single texture single pass (vertex lit only)
2241 memset(&m, 0, sizeof(m));
2242 m.tex[0] = R_GetTexture(texture->currentbasetexture);
2243 m.texmatrix[0] = texture->currenttexmatrix;
2244 m.pointer_color = varray_color4f;
2246 if (gl_combine.integer)
2248 m.texrgbscale[0] = 2;
2251 // transparent is not affected by r_lightmapintensity
2252 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2253 colorscale *= r_lightmapintensity;
2254 // q3bsp has no lightmap updates, so the lightstylevalue that
2255 // would normally be baked into the lightmaptexture must be
2256 // applied to the color
2257 if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) && ent->model->type == mod_brushq3)
2258 colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f);
2260 r = texture->currentcolorbase[0] * colorscale;
2261 g = texture->currentcolorbase[1] * colorscale;
2262 b = texture->currentcolorbase[2] * colorscale;
2263 a = texture->currentcolorbase[3];
2264 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2265 if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
2267 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2269 surface = texturesurfacelist[texturesurfaceindex];
2270 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2271 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2272 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode ? lightmode : 1, applycolor, texture->currentfogallpasses);
2273 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2274 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2275 GL_LockArrays(0, 0);
2280 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2282 surface = texturesurfacelist[texturesurfaceindex];
2283 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2284 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2285 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, texture->currentfogallpasses);
2286 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2287 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2288 GL_LockArrays(0, 0);
2292 if (texture->currentdopants)
2294 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2295 memset(&m, 0, sizeof(m));
2296 m.tex[0] = R_GetTexture(texture->skin.pants);
2297 m.texmatrix[0] = texture->currenttexmatrix;
2298 m.pointer_color = varray_color4f;
2300 if (gl_combine.integer)
2302 m.texrgbscale[0] = 2;
2305 // transparent is not affected by r_lightmapintensity
2306 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2307 colorscale *= r_lightmapintensity;
2308 // q3bsp has no lightmap updates, so the lightstylevalue that
2309 // would normally be baked into the lightmaptexture must be
2310 // applied to the color
2311 if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) && !texture->currentdofullbrightpants && ent->model->type == mod_brushq3)
2312 colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f);
2314 r = texture->currentcolorpants[0] * colorscale;
2315 g = texture->currentcolorpants[1] * colorscale;
2316 b = texture->currentcolorpants[2] * colorscale;
2317 a = texture->currentcolorpants[3];
2318 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2319 if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) && !texture->currentdofullbrightpants)
2321 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2323 surface = texturesurfacelist[texturesurfaceindex];
2324 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2325 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2326 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode, applycolor, texture->currentfogallpasses);
2327 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2328 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2329 GL_LockArrays(0, 0);
2334 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2336 surface = texturesurfacelist[texturesurfaceindex];
2337 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2338 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2339 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, texture->currentfogallpasses);
2340 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2341 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2342 GL_LockArrays(0, 0);
2346 if (texture->currentdoshirt)
2348 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2349 memset(&m, 0, sizeof(m));
2350 m.tex[0] = R_GetTexture(texture->skin.shirt);
2351 m.texmatrix[0] = texture->currenttexmatrix;
2352 m.pointer_color = varray_color4f;
2354 if (gl_combine.integer)
2356 m.texrgbscale[0] = 2;
2359 // transparent is not affected by r_lightmapintensity
2360 if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2361 colorscale *= r_lightmapintensity;
2362 // q3bsp has no lightmap updates, so the lightstylevalue that
2363 // would normally be baked into the lightmaptexture must be
2364 // applied to the color
2365 if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) && !texture->currentdofullbrightshirt && ent->model->type == mod_brushq3)
2366 colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f);
2368 r = texture->currentcolorshirt[0] * colorscale;
2369 g = texture->currentcolorshirt[1] * colorscale;
2370 b = texture->currentcolorshirt[2] * colorscale;
2371 a = texture->currentcolorshirt[3];
2372 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2373 if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) && !texture->currentdofullbrightshirt)
2375 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2377 surface = texturesurfacelist[texturesurfaceindex];
2378 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2379 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2380 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode, applycolor, texture->currentfogallpasses);
2381 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2382 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2383 GL_LockArrays(0, 0);
2388 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2390 surface = texturesurfacelist[texturesurfaceindex];
2391 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2392 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2393 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, texture->currentfogallpasses);
2394 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2395 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2396 GL_LockArrays(0, 0);
2400 if (r_ambient.value >= (1/64.0f))
2402 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2403 GL_DepthMask(false);
2404 memset(&m, 0, sizeof(m));
2405 m.tex[0] = R_GetTexture(texture->skin.base);
2406 m.texmatrix[0] = texture->currenttexmatrix;
2407 m.pointer_color = varray_color4f;
2409 if (gl_combine.integer && (ent->colormod[0] > 1 || ent->colormod[1] > 1 || ent->colormod[2] > 1))
2411 m.texrgbscale[0] = 4;
2415 colorscale *= r_ambient.value * (1.0f / 64.0f);
2416 r = texture->currentcolorbase[0] * colorscale;
2417 g = texture->currentcolorbase[1] * colorscale;
2418 b = texture->currentcolorbase[2] * colorscale;
2419 a = texture->currentcolorbase[3];
2420 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2421 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2423 surface = texturesurfacelist[texturesurfaceindex];
2424 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2425 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2426 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, texture->currentfogallpasses);
2427 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2428 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2429 GL_LockArrays(0, 0);
2432 if (texture->skin.glow != NULL)
2434 // if glow was not already done using multitexture, do it now.
2435 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2436 GL_DepthMask(false);
2437 memset(&m, 0, sizeof(m));
2438 m.tex[0] = R_GetTexture(texture->skin.glow);
2439 m.texmatrix[0] = texture->currenttexmatrix;
2440 m.pointer_color = varray_color4f;
2445 a = texture->currentcolorbase[3];
2446 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2447 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2449 surface = texturesurfacelist[texturesurfaceindex];
2450 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2451 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2452 RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, texture->currentfogallpasses);
2453 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2454 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2455 GL_LockArrays(0, 0);
2458 if (fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_ADD))
2460 // if this is opaque use alpha blend which will darken the earlier
2463 // if this is an alpha blended material, all the earlier passes
2464 // were darkened by fog already, so we only need to add the fog
2465 // color ontop through the fog mask texture
2467 // if this is an additive blended material, all the earlier passes
2468 // were darkened by fog already, and we should not add fog color
2469 // (because the background was not darkened, there is no fog color
2470 // that was lost behind it).
2471 if (texture->currentfogallpasses)
2472 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2474 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2475 GL_DepthMask(false);
2476 memset(&m, 0, sizeof(m));
2477 m.tex[0] = R_GetTexture(texture->skin.fog);
2478 m.texmatrix[0] = texture->currenttexmatrix;
2483 a = texture->currentcolorbase[3];
2484 applycolor = r != 1 || g != 1 || b != 1 || a != 1;
2485 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2487 surface = texturesurfacelist[texturesurfaceindex];
2488 RSurf_SetVertexPointer(ent, texture, surface, modelorg);
2489 R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
2490 R_Mesh_ColorPointer(varray_color4f);
2491 //RSurf_FogPassColors_Vertex3f_Color4f((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], texture->currentcolorbase[3], 1, surface->num_vertices, modelorg);
2492 if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
2494 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)
2496 VectorSubtract(v, modelorg, diff);
2497 f = exp(fogdensity/DotProduct(diff, diff));
2501 c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * f * a;
2506 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)
2508 VectorSubtract(v, modelorg, diff);
2509 f = exp(fogdensity/DotProduct(diff, diff));
2516 GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
2517 R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
2518 GL_LockArrays(0, 0);
2523 if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
2524 qglEnable(GL_CULL_FACE);
2527 static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata2)
2529 const entity_render_t *ent = calldata1;
2530 const msurface_t *surface = ent->model->data_surfaces + calldata2;
2534 texture = surface->texture;
2535 if (texture->basematerialflags & MATERIALFLAG_SKY)
2536 return; // transparent sky is too difficult
2537 R_UpdateTextureInfo(ent, texture);
2539 R_Mesh_Matrix(&ent->matrix);
2540 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
2541 R_DrawTextureSurfaceList(ent, texture->currentframe, 1, &surface, modelorg);
2544 void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
2546 int texturesurfaceindex;
2547 const msurface_t *surface;
2548 vec3_t tempcenter, center;
2549 if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)
2551 // drawing sky transparently would be too difficult
2552 if (!(texture->currentmaterialflags & MATERIALFLAG_SKY))
2554 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
2556 surface = texturesurfacelist[texturesurfaceindex];
2557 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
2558 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
2559 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
2560 Matrix4x4_Transform(&ent->matrix, tempcenter, center);
2561 R_MeshQueue_AddTransparent(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, RSurfShader_Transparent_Callback, ent, surface - ent->model->data_surfaces);
2566 R_DrawTextureSurfaceList(ent, texture, texturenumsurfaces, texturesurfacelist, modelorg);
2569 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
2570 void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces)
2572 int i, j, f, flagsmask;
2573 msurface_t *surface, **surfacechain;
2574 texture_t *t, *texture;
2575 model_t *model = ent->model;
2577 const int maxsurfacelist = 1024;
2578 int numsurfacelist = 0;
2579 const msurface_t *surfacelist[1024];
2582 R_Mesh_Matrix(&ent->matrix);
2583 Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
2585 // update light styles
2586 if (!skysurfaces && model->brushq1.light_styleupdatechains)
2588 for (i = 0;i < model->brushq1.light_styles;i++)
2590 if (model->brushq1.light_stylevalue[i] != d_lightstylevalue[model->brushq1.light_style[i]])
2592 model->brushq1.light_stylevalue[i] = d_lightstylevalue[model->brushq1.light_style[i]];
2593 if ((surfacechain = model->brushq1.light_styleupdatechains[i]))
2594 for (;(surface = *surfacechain);surfacechain++)
2595 surface->cached_dlight = true;
2600 R_UpdateAllTextureInfo(ent);
2601 flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL);
2606 if (ent == r_refdef.worldentity)
2608 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
2610 if (!r_worldsurfacevisible[j])
2612 if (t != surface->texture)
2616 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2619 t = surface->texture;
2620 texture = t->currentframe;
2621 f = texture->currentmaterialflags & flagsmask;
2623 if (f && surface->num_triangles)
2625 // if lightmap parameters changed, rebuild lightmap texture
2626 if (surface->cached_dlight && surface->lightmapinfo->samples)
2627 R_BuildLightMap(ent, surface);
2628 // add face to draw list
2629 surfacelist[numsurfacelist++] = surface;
2630 if (numsurfacelist >= maxsurfacelist)
2632 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2640 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
2642 if (t != surface->texture)
2646 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2649 t = surface->texture;
2650 texture = t->currentframe;
2651 f = texture->currentmaterialflags & flagsmask;
2653 if (f && surface->num_triangles)
2655 // if lightmap parameters changed, rebuild lightmap texture
2656 if (surface->cached_dlight && surface->lightmapinfo->samples)
2657 R_BuildLightMap(ent, surface);
2658 // add face to draw list
2659 surfacelist[numsurfacelist++] = surface;
2660 if (numsurfacelist >= maxsurfacelist)
2662 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);
2669 R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg);