mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-03-13 06:13:39 +00:00
Merge surface mark & cull optimization from vkQuake
* Remove separate surface culling pass. Instead always build texture chains every frame & cull in mark surfaces. * Optimize R_CullBox & R_BackFaceCull
This commit is contained in:
parent
d6e68b6f19
commit
3fc32bf7fe
6 changed files with 173 additions and 339 deletions
|
@ -140,7 +140,6 @@ typedef struct glpoly_s
|
|||
typedef struct msurface_s
|
||||
{
|
||||
int visframe; // should be drawn when node is crossed
|
||||
qboolean culled; // johnfitz -- for frustum culling
|
||||
float mins[3]; // johnfitz -- for frustum culling
|
||||
float maxs[3]; // johnfitz -- for frustum culling
|
||||
|
||||
|
|
|
@ -272,48 +272,21 @@ qboolean R_CullBox (vec3_t emins, vec3_t emaxs)
|
|||
{
|
||||
int i;
|
||||
mplane_t *p;
|
||||
byte signbits;
|
||||
float vec[3];
|
||||
for (i = 0;i < 4;i++)
|
||||
{
|
||||
p = frustum + i;
|
||||
switch(p->signbits)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
|
||||
return true;
|
||||
break;
|
||||
case 1:
|
||||
if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist)
|
||||
return true;
|
||||
break;
|
||||
case 2:
|
||||
if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
|
||||
return true;
|
||||
break;
|
||||
case 3:
|
||||
if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist)
|
||||
return true;
|
||||
break;
|
||||
case 4:
|
||||
if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
|
||||
return true;
|
||||
break;
|
||||
case 5:
|
||||
if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist)
|
||||
return true;
|
||||
break;
|
||||
case 6:
|
||||
if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
|
||||
return true;
|
||||
break;
|
||||
case 7:
|
||||
if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
signbits = p->signbits;
|
||||
vec[0] = ((signbits % 2)<1) ? emaxs[0] : emins[0];
|
||||
vec[1] = ((signbits % 4)<2) ? emaxs[1] : emins[1];
|
||||
vec[2] = ((signbits % 8)<4) ? emaxs[2] : emins[2];
|
||||
if (p->normal[0]*vec[0] + p->normal[1]*vec[1] + p->normal[2]*vec[2] < p->dist)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_CullModelForEntity -- johnfitz -- uses correct bounds based on rotation
|
||||
|
@ -585,8 +558,6 @@ void R_SetupView (void)
|
|||
|
||||
R_MarkSurfaces (); //johnfitz -- create texture chains from PVS
|
||||
|
||||
R_CullSurfaces (); //johnfitz -- do after R_SetFrustum and R_MarkSurfaces
|
||||
|
||||
R_UpdateWarpTextures (); //johnfitz -- do this before R_Clear
|
||||
|
||||
R_Clear ();
|
||||
|
|
|
@ -86,17 +86,6 @@ static void R_SetClearColor_f (cvar_t *var)
|
|||
glClearColor (rgb[0]/255.0,rgb[1]/255.0,rgb[2]/255.0,0);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
R_Novis_f -- johnfitz
|
||||
====================
|
||||
*/
|
||||
static void R_VisChanged (cvar_t *var)
|
||||
{
|
||||
extern int vis_changed;
|
||||
vis_changed = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_Model_ExtraFlags_List_f -- johnfitz -- called when r_nolerp_list or r_noshadow_list cvar changes
|
||||
|
@ -189,7 +178,6 @@ void R_Init (void)
|
|||
Cvar_SetCallback (&r_wateralpha, R_SetWateralpha_f);
|
||||
Cvar_RegisterVariable (&r_dynamic);
|
||||
Cvar_RegisterVariable (&r_novis);
|
||||
Cvar_SetCallback (&r_novis, R_VisChanged);
|
||||
Cvar_RegisterVariable (&r_speeds);
|
||||
Cvar_RegisterVariable (&r_pos);
|
||||
|
||||
|
@ -214,7 +202,6 @@ void R_Init (void)
|
|||
Cvar_RegisterVariable (&r_drawflat);
|
||||
Cvar_RegisterVariable (&r_flatlightstyles);
|
||||
Cvar_RegisterVariable (&r_oldskyleaf);
|
||||
Cvar_SetCallback (&r_oldskyleaf, R_VisChanged);
|
||||
Cvar_RegisterVariable (&r_drawworld);
|
||||
Cvar_RegisterVariable (&r_showtris);
|
||||
Cvar_RegisterVariable (&r_showbboxes);
|
||||
|
@ -595,6 +582,7 @@ void R_DeleteShaders (void)
|
|||
}
|
||||
gl_num_programs = 0;
|
||||
}
|
||||
|
||||
GLuint current_array_buffer, current_element_array_buffer;
|
||||
|
||||
/*
|
||||
|
|
|
@ -550,8 +550,7 @@ void Sky_ProcessTextureChains (void)
|
|||
continue;
|
||||
|
||||
for (s = t->texturechains[chain_world]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
Sky_ProcessPoly (s->polys);
|
||||
Sky_ProcessPoly (s->polys);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -693,7 +692,7 @@ FIXME: eliminate cracks by adding an extra vert on tjuncs
|
|||
*/
|
||||
void Sky_DrawSkyBox (void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
|
@ -980,10 +979,10 @@ called once per frame before drawing anything else
|
|||
*/
|
||||
void Sky_DrawSky (void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
//in these special render modes, the sky faces are handled in the normal world/brush renderer
|
||||
if (r_drawflat_cheatsafe || r_lightmap_cheatsafe )
|
||||
if (r_drawflat_cheatsafe || r_lightmap_cheatsafe)
|
||||
return;
|
||||
|
||||
//
|
||||
|
@ -1020,7 +1019,7 @@ void Sky_DrawSky (void)
|
|||
if (skybox_name[0])
|
||||
Sky_DrawSkyBox ();
|
||||
else
|
||||
Sky_DrawSkyLayers();
|
||||
Sky_DrawSkyLayers ();
|
||||
|
||||
glDepthMask(1);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
|
|
@ -341,7 +341,6 @@ void R_NewGame (void);
|
|||
|
||||
void R_AnimateLight (void);
|
||||
void R_MarkSurfaces (void);
|
||||
void R_CullSurfaces (void);
|
||||
qboolean R_CullBox (vec3_t emins, vec3_t emaxs);
|
||||
void R_StoreEfrags (efrag_t **ppefrag);
|
||||
qboolean R_CullModelForEntity (entity_t *e);
|
||||
|
|
432
Quake/r_world.c
432
Quake/r_world.c
|
@ -28,8 +28,6 @@ extern cvar_t gl_fullbrights, r_drawflat, gl_overbright, r_oldwater, r_oldskylea
|
|||
|
||||
byte *SV_FatPVS (vec3_t org, qmodel_t *worldmodel);
|
||||
|
||||
int vis_changed; //if true, force pvs to be refreshed
|
||||
|
||||
//==============================================================================
|
||||
//
|
||||
// SETUP CHAINS
|
||||
|
@ -69,6 +67,26 @@ void R_ChainSurface (msurface_t *surf, texchain_t chain)
|
|||
surf->texinfo->texture->texturechains[chain] = surf;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_BackFaceCull -- johnfitz -- returns true if the surface is facing away from vieworg
|
||||
================
|
||||
*/
|
||||
qboolean R_BackFaceCull (msurface_t *surf)
|
||||
{
|
||||
double dot;
|
||||
|
||||
if (surf->plane->type < 3)
|
||||
dot = r_refdef.vieworg[surf->plane->type] - surf->plane->dist;
|
||||
else
|
||||
dot = DotProduct (r_refdef.vieworg, surf->plane->normal) - surf->plane->dist;
|
||||
|
||||
if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_MarkSurfaces -- johnfitz -- mark surfaces based on PVS and rebuild texture chains
|
||||
|
@ -78,7 +96,6 @@ void R_MarkSurfaces (void)
|
|||
{
|
||||
byte *vis;
|
||||
mleaf_t *leaf;
|
||||
mnode_t *node;
|
||||
msurface_t *surf, **mark;
|
||||
int i, j;
|
||||
qboolean nearwaterportal;
|
||||
|
@ -102,20 +119,12 @@ void R_MarkSurfaces (void)
|
|||
else
|
||||
vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);
|
||||
|
||||
// if surface chains don't need regenerating, just add static entities and return
|
||||
if (r_oldviewleaf == r_viewleaf && !vis_changed && !nearwaterportal)
|
||||
{
|
||||
leaf = &cl.worldmodel->leafs[1];
|
||||
for (i=0 ; i<cl.worldmodel->numleafs ; i++, leaf++)
|
||||
if (vis[i>>3] & (1<<(i&7)))
|
||||
if (leaf->efrags)
|
||||
R_StoreEfrags (&leaf->efrags);
|
||||
return;
|
||||
}
|
||||
|
||||
vis_changed = false;
|
||||
r_visframecount++;
|
||||
r_oldviewleaf = r_viewleaf;
|
||||
|
||||
// set all chains to null
|
||||
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
|
||||
if (cl.worldmodel->textures[i])
|
||||
cl.worldmodel->textures[i]->texturechains[chain_world] = NULL;
|
||||
|
||||
// iterate through leaves, marking surfaces
|
||||
leaf = &cl.worldmodel->leafs[1];
|
||||
|
@ -123,145 +132,32 @@ void R_MarkSurfaces (void)
|
|||
{
|
||||
if (vis[i>>3] & (1<<(i&7)))
|
||||
{
|
||||
if (R_CullBox(leaf->minmaxs, leaf->minmaxs + 3))
|
||||
continue;
|
||||
|
||||
if (r_oldskyleaf.value || leaf->contents != CONTENTS_SKY)
|
||||
for (j=0, mark = leaf->firstmarksurface; j<leaf->nummarksurfaces; j++, mark++)
|
||||
(*mark)->visframe = r_visframecount;
|
||||
{
|
||||
surf = *mark;
|
||||
if (surf->visframe != r_visframecount)
|
||||
{
|
||||
surf->visframe = r_visframecount;
|
||||
if (!R_CullBox(surf->mins, surf->maxs) && !R_BackFaceCull (surf))
|
||||
{
|
||||
rs_brushpolys++; //count wpolys here
|
||||
R_ChainSurface(surf, chain_world);
|
||||
R_RenderDynamicLightmaps(surf);
|
||||
if (surf->texinfo->texture->warpimage)
|
||||
surf->texinfo->texture->update_warp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add static models
|
||||
if (leaf->efrags)
|
||||
R_StoreEfrags (&leaf->efrags);
|
||||
}
|
||||
}
|
||||
|
||||
// set all chains to null
|
||||
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
|
||||
if (cl.worldmodel->textures[i])
|
||||
cl.worldmodel->textures[i]->texturechains[chain_world] = NULL;
|
||||
|
||||
// rebuild chains
|
||||
#if 1
|
||||
//iterate through surfaces one node at a time to rebuild chains
|
||||
//need to do it this way if we want to work with tyrann's skip removal tool
|
||||
//becuase his tool doesn't actually remove the surfaces from the bsp surfaces lump
|
||||
//nor does it remove references to them in each leaf's marksurfaces list
|
||||
for (i=0, node = cl.worldmodel->nodes ; i<cl.worldmodel->numnodes ; i++, node++)
|
||||
for (j=0, surf=&cl.worldmodel->surfaces[node->firstsurface] ; j<node->numsurfaces ; j++, surf++)
|
||||
if (surf->visframe == r_visframecount)
|
||||
{
|
||||
R_ChainSurface(surf, chain_world);
|
||||
}
|
||||
#else
|
||||
//the old way
|
||||
surf = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface];
|
||||
for (i=0 ; i<cl.worldmodel->nummodelsurfaces ; i++, surf++)
|
||||
{
|
||||
if (surf->visframe == r_visframecount)
|
||||
{
|
||||
R_ChainSurface(surf, chain_world);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_BackFaceCull -- johnfitz -- returns true if the surface is facing away from vieworg
|
||||
================
|
||||
*/
|
||||
qboolean R_BackFaceCull (msurface_t *surf)
|
||||
{
|
||||
double dot;
|
||||
|
||||
switch (surf->plane->type)
|
||||
{
|
||||
case PLANE_X:
|
||||
dot = r_refdef.vieworg[0] - surf->plane->dist;
|
||||
break;
|
||||
case PLANE_Y:
|
||||
dot = r_refdef.vieworg[1] - surf->plane->dist;
|
||||
break;
|
||||
case PLANE_Z:
|
||||
dot = r_refdef.vieworg[2] - surf->plane->dist;
|
||||
break;
|
||||
default:
|
||||
dot = DotProduct (r_refdef.vieworg, surf->plane->normal) - surf->plane->dist;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_CullSurfaces -- johnfitz
|
||||
================
|
||||
*/
|
||||
void R_CullSurfaces (void)
|
||||
{
|
||||
msurface_t *s;
|
||||
int i;
|
||||
texture_t *t;
|
||||
|
||||
if (!r_drawworld_cheatsafe)
|
||||
return;
|
||||
|
||||
// ericw -- instead of testing (s->visframe == r_visframecount) on all world
|
||||
// surfaces, use the chained surfaces, which is exactly the same set of sufaces
|
||||
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
|
||||
{
|
||||
t = cl.worldmodel->textures[i];
|
||||
|
||||
if (!t || !t->texturechains[chain_world])
|
||||
continue;
|
||||
|
||||
for (s = t->texturechains[chain_world]; s; s = s->texturechain)
|
||||
{
|
||||
if (R_CullBox(s->mins, s->maxs) || R_BackFaceCull (s))
|
||||
s->culled = true;
|
||||
else
|
||||
{
|
||||
s->culled = false;
|
||||
rs_brushpolys++; //count wpolys here
|
||||
if (s->texinfo->texture->warpimage)
|
||||
s->texinfo->texture->update_warp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_BuildLightmapChains -- johnfitz -- used for r_lightmap 1
|
||||
|
||||
ericw -- now always used at the start of R_DrawTextureChains for the
|
||||
mh dynamic lighting speedup
|
||||
================
|
||||
*/
|
||||
void R_BuildLightmapChains (qmodel_t *model, texchain_t chain)
|
||||
{
|
||||
texture_t *t;
|
||||
msurface_t *s;
|
||||
int i;
|
||||
|
||||
// clear lightmap chains (already done in r_marksurfaces, but clearing them here to be safe becuase of r_stereo)
|
||||
for (i=0 ; i<lightmap_count ; i++)
|
||||
lightmaps[i].polys = NULL;
|
||||
|
||||
// now rebuild them
|
||||
for (i=0 ; i<model->numtextures ; i++)
|
||||
{
|
||||
t = model->textures[i];
|
||||
|
||||
if (!t || !t->texturechains[chain])
|
||||
continue;
|
||||
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
R_RenderDynamicLightmaps (s);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
@ -323,19 +219,17 @@ void R_DrawTextureChains_ShowTris (qmodel_t *model, texchain_t chain)
|
|||
if (r_oldwater.value && t->texturechains[chain] && (t->texturechains[chain]->flags & SURF_DRAWTURB))
|
||||
{
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
for (p = s->polys->next; p; p = p->next)
|
||||
{
|
||||
DrawGLTriangleFan (p);
|
||||
}
|
||||
for (p = s->polys->next; p; p = p->next)
|
||||
{
|
||||
DrawGLTriangleFan (p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
DrawGLTriangleFan (s->polys);
|
||||
}
|
||||
{
|
||||
DrawGLTriangleFan (s->polys);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -361,25 +255,23 @@ void R_DrawTextureChains_Drawflat (qmodel_t *model, texchain_t chain)
|
|||
if (r_oldwater.value && t->texturechains[chain] && (t->texturechains[chain]->flags & SURF_DRAWTURB))
|
||||
{
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
for (p = s->polys->next; p; p = p->next)
|
||||
{
|
||||
srand((unsigned int) (uintptr_t) p);
|
||||
glColor3f (rand()%256/255.0, rand()%256/255.0, rand()%256/255.0);
|
||||
DrawGLPoly (p);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
for (p = s->polys->next; p; p = p->next)
|
||||
{
|
||||
srand((unsigned int) (uintptr_t) p);
|
||||
glColor3f (rand()%256/255.0, rand()%256/255.0, rand()%256/255.0);
|
||||
DrawGLPoly (p);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
srand((unsigned int) (uintptr_t) s->polys);
|
||||
glColor3f (rand()%256/255.0, rand()%256/255.0, rand()%256/255.0);
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
{
|
||||
srand((unsigned int) (uintptr_t) s->polys);
|
||||
glColor3f (rand()%256/255.0, rand()%256/255.0, rand()%256/255.0);
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
}
|
||||
}
|
||||
glColor3f (1,1,1);
|
||||
|
@ -409,16 +301,15 @@ void R_DrawTextureChains_Glow (qmodel_t *model, entity_t *ent, texchain_t chain)
|
|||
bound = false;
|
||||
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
GL_Bind (glt);
|
||||
bound = true;
|
||||
}
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
GL_Bind (glt);
|
||||
bound = true;
|
||||
}
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,30 +417,29 @@ void R_DrawTextureChains_Multitexture (qmodel_t *model, entity_t *ent, texchain_
|
|||
|
||||
bound = false;
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
|
||||
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
|
||||
|
||||
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||
glEnable (GL_ALPHA_TEST); // Flip alpha test back on
|
||||
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||
glEnable (GL_ALPHA_TEST); // Flip alpha test back on
|
||||
|
||||
GL_EnableMultitexture(); // selects TEXTURE1
|
||||
bound = true;
|
||||
}
|
||||
GL_Bind (lightmaps[s->lightmaptexturenum].texture);
|
||||
glBegin(GL_POLYGON);
|
||||
v = s->polys->verts[0];
|
||||
for (j=0 ; j<s->polys->numverts ; j++, v+= VERTEXSIZE)
|
||||
{
|
||||
GL_MTexCoord2fFunc (GL_TEXTURE0_ARB, v[3], v[4]);
|
||||
GL_MTexCoord2fFunc (GL_TEXTURE1_ARB, v[5], v[6]);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd ();
|
||||
rs_brushpasses++;
|
||||
GL_EnableMultitexture(); // selects TEXTURE1
|
||||
bound = true;
|
||||
}
|
||||
GL_Bind (lightmaps[s->lightmaptexturenum].texture);
|
||||
glBegin(GL_POLYGON);
|
||||
v = s->polys->verts[0];
|
||||
for (j=0 ; j<s->polys->numverts ; j++, v+= VERTEXSIZE)
|
||||
{
|
||||
GL_MTexCoord2fFunc (GL_TEXTURE0_ARB, v[3], v[4]);
|
||||
GL_MTexCoord2fFunc (GL_TEXTURE1_ARB, v[5], v[6]);
|
||||
glVertex3fv (v);
|
||||
}
|
||||
glEnd ();
|
||||
rs_brushpasses++;
|
||||
}
|
||||
GL_DisableMultitexture(); // selects TEXTURE0
|
||||
|
||||
if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||
|
@ -581,16 +471,15 @@ void R_DrawTextureChains_NoTexture (qmodel_t *model, texchain_t chain)
|
|||
bound = false;
|
||||
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
GL_Bind (t->gltexture);
|
||||
bound = true;
|
||||
}
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
GL_Bind (t->gltexture);
|
||||
bound = true;
|
||||
}
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -616,20 +505,19 @@ void R_DrawTextureChains_TextureOnly (qmodel_t *model, entity_t *ent, texchain_t
|
|||
bound = false;
|
||||
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
|
||||
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
|
||||
|
||||
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||
glEnable (GL_ALPHA_TEST); // Flip alpha test back on
|
||||
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||
glEnable (GL_ALPHA_TEST); // Flip alpha test back on
|
||||
|
||||
bound = true;
|
||||
}
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
bound = true;
|
||||
}
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
|
||||
if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||
glDisable (GL_ALPHA_TEST); // Flip alpha test back off
|
||||
|
@ -680,21 +568,20 @@ void R_DrawTextureChains_Water (qmodel_t *model, entity_t *ent, texchain_t chain
|
|||
bound = false;
|
||||
entalpha = 1.0f;
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
entalpha = GL_WaterAlphaForEntitySurface (ent, s);
|
||||
R_BeginTransparentDrawing (entalpha);
|
||||
GL_Bind (t->gltexture);
|
||||
bound = true;
|
||||
}
|
||||
for (p = s->polys->next; p; p = p->next)
|
||||
{
|
||||
DrawWaterPoly (p);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
entalpha = GL_WaterAlphaForEntitySurface (ent, s);
|
||||
R_BeginTransparentDrawing (entalpha);
|
||||
GL_Bind (t->gltexture);
|
||||
bound = true;
|
||||
}
|
||||
for (p = s->polys->next; p; p = p->next)
|
||||
{
|
||||
DrawWaterPoly (p);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
}
|
||||
R_EndTransparentDrawing (entalpha);
|
||||
}
|
||||
}
|
||||
|
@ -708,27 +595,26 @@ void R_DrawTextureChains_Water (qmodel_t *model, entity_t *ent, texchain_t chain
|
|||
bound = false;
|
||||
entalpha = 1.0f;
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
entalpha = GL_WaterAlphaForEntitySurface (ent, s);
|
||||
R_BeginTransparentDrawing (entalpha);
|
||||
GL_Bind (t->warpimage);
|
||||
|
||||
if (model != cl.worldmodel)
|
||||
{
|
||||
entalpha = GL_WaterAlphaForEntitySurface (ent, s);
|
||||
R_BeginTransparentDrawing (entalpha);
|
||||
GL_Bind (t->warpimage);
|
||||
|
||||
if (model != cl.worldmodel)
|
||||
{
|
||||
// ericw -- this is copied from R_DrawSequentialPoly.
|
||||
// If the poly is not part of the world we have to
|
||||
// set this flag
|
||||
t->update_warp = true; // FIXME: one frame too late!
|
||||
}
|
||||
|
||||
bound = true;
|
||||
// ericw -- this is copied from R_DrawSequentialPoly.
|
||||
// If the poly is not part of the world we have to
|
||||
// set this flag
|
||||
t->update_warp = true; // FIXME: one frame too late!
|
||||
}
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
|
||||
bound = true;
|
||||
}
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
R_EndTransparentDrawing (entalpha);
|
||||
}
|
||||
}
|
||||
|
@ -754,11 +640,10 @@ void R_DrawTextureChains_White (qmodel_t *model, texchain_t chain)
|
|||
continue;
|
||||
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
{
|
||||
DrawGLPoly (s->polys);
|
||||
rs_brushpasses++;
|
||||
}
|
||||
}
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
}
|
||||
|
@ -971,31 +856,30 @@ void R_DrawTextureChains_GLSL (qmodel_t *model, entity_t *ent, texchain_t chain)
|
|||
bound = false;
|
||||
lastlightmap = 0; // avoid compiler warning
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
if (!bound) //only bind once we are sure we need this texture
|
||||
{
|
||||
GL_SelectTexture (GL_TEXTURE0);
|
||||
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
|
||||
GL_SelectTexture (GL_TEXTURE0);
|
||||
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
|
||||
|
||||
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||
GL_Uniform1iFunc (useAlphaTestLoc, 1); // Flip alpha test back on
|
||||
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||
GL_Uniform1iFunc (useAlphaTestLoc, 1); // Flip alpha test back on
|
||||
|
||||
bound = true;
|
||||
lastlightmap = s->lightmaptexturenum;
|
||||
}
|
||||
|
||||
if (s->lightmaptexturenum != lastlightmap)
|
||||
R_FlushBatch ();
|
||||
|
||||
GL_SelectTexture (GL_TEXTURE1);
|
||||
GL_Bind (lightmaps[s->lightmaptexturenum].texture);
|
||||
bound = true;
|
||||
lastlightmap = s->lightmaptexturenum;
|
||||
R_BatchSurface (s);
|
||||
|
||||
rs_brushpasses++;
|
||||
}
|
||||
|
||||
if (s->lightmaptexturenum != lastlightmap)
|
||||
R_FlushBatch ();
|
||||
|
||||
GL_SelectTexture (GL_TEXTURE1);
|
||||
GL_Bind (lightmaps[s->lightmaptexturenum].texture);
|
||||
lastlightmap = s->lightmaptexturenum;
|
||||
R_BatchSurface (s);
|
||||
|
||||
rs_brushpasses++;
|
||||
}
|
||||
|
||||
R_FlushBatch ();
|
||||
|
||||
if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||
|
@ -1031,12 +915,6 @@ void R_DrawTextureChains (qmodel_t *model, entity_t *ent, texchain_t chain)
|
|||
else
|
||||
entalpha = 1;
|
||||
|
||||
// ericw -- the mh dynamic lightmap speedup: make a first pass through all
|
||||
// surfaces we are going to draw, and rebuild any lightmaps that need it.
|
||||
// this also chains surfaces by lightmap which is used by r_lightmap 1.
|
||||
// the previous implementation of the speedup uploaded lightmaps one frame
|
||||
// late which was visible under some conditions, this method avoids that.
|
||||
R_BuildLightmapChains (model, chain);
|
||||
R_UploadLightmaps ();
|
||||
|
||||
if (r_drawflat_cheatsafe)
|
||||
|
|
Loading…
Reference in a new issue