render code cleanup and allocate spans at once

This commit is contained in:
Denis Pauk 2019-05-15 23:00:20 +03:00
parent 5f2293bf0d
commit 25a2aff688
5 changed files with 194 additions and 159 deletions

View file

@ -454,14 +454,12 @@ extern msurface_t *r_alpha_surfaces;
//
// current entity info
//
extern qboolean insubmodel;
void R_DrawAlphaSurfaces(const entity_t *currententity);
void R_DrawSprite(entity_t *currententity, const model_t *currentmodel);
void R_RenderFace(entity_t *currententity, const model_t *currentmodel, msurface_t *fa, int clipflags);
void R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf);
void R_RenderFace(entity_t *currententity, const model_t *currentmodel, msurface_t *fa, int clipflags, qboolean insubmodel);
void R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf, int r_currentbkey);
void R_TransformFrustum(void);
void R_DrawSubmodelPolygons(entity_t *currententity, const model_t *currentmodel, int clipflags, mnode_t *topnode);
@ -480,7 +478,6 @@ extern int sadjust, tadjust;
extern int bbextents, bbextentt;
extern int r_currentkey;
extern int r_currentbkey;
void R_DrawParticles (void);
@ -506,7 +503,9 @@ void R_PolysetDrawSpans8_Opaque(const entity_t *currententity, spanpackage_t *ps
extern byte **warp_rowptr;
extern int *warp_column;
extern espan_t *edge_basespans;
extern espan_t *max_span_p;
extern int r_numallocatedverts;
extern int r_numallocatededgebasespans;
extern finalvert_t *finalverts, *finalverts_max;
extern int r_aliasblendcolor;
@ -517,6 +516,7 @@ extern qboolean r_outofsurfaces;
extern qboolean r_outofedges;
extern qboolean r_outofverts;
extern qboolean r_outoftriangles;
extern qboolean r_outedgebasespans;
extern mvertex_t *r_pcurrentvertbase;
@ -527,7 +527,7 @@ void R_AliasClipTriangle(const entity_t *currententity, const finalvert_t *index
extern float r_time1;
extern float da_time1, da_time2;
extern float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
extern float se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2;
extern float se_time1, se_time2, de_time1, de_time2;
extern int r_viewcluster, r_oldviewcluster;
extern int r_clipflags;

View file

@ -31,8 +31,6 @@ vec3_t r_entorigin; // the currently rendering entity in world
static float entity_rotation[3][3];
int r_currentbkey;
typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t;
#define MAX_BMODEL_VERTS 500 // 6K
@ -141,6 +139,24 @@ R_RotateBmodel(const entity_t *currententity)
}
static qboolean
R_AreaVisible(mleaf_t *pleaf)
{
int area;
// check for door connected areas
if (!r_newrefdef.areabits)
return true;
area = pleaf->area;
if ((r_newrefdef.areabits[area>>3] & (1<<(area&7))))
return true;
return false; // not visible
}
/*
================
R_RecursiveClipBPoly
@ -223,25 +239,23 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m
// split into two edges, one on each side, and remember entering
// and exiting points
// FIXME: share the clip edge by having a winding direction flag?
if (numbedges >= (MAX_BMODEL_EDGES - 1))
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
ptedge = &bedges[numbedges];
ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[lastside];
psideedges[lastside] = ptedge;
ptedge->v[0] = plastvert;
ptedge->v[1] = ptvert;
ptedge = &bedges[numbedges + 1];
ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[side];
psideedges[side] = ptedge;
ptedge->v[0] = ptvert;
ptedge->v[1] = pvert;
numbedges += 2;
if (numbedges >= MAX_BMODEL_EDGES)
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
if (side == 0)
{
@ -266,25 +280,23 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m
// plane to both sides (but in opposite directions)
if (makeclippededge && pfrontexit != pfrontenter)
{
if (numbedges >= (MAX_BMODEL_EDGES - 2))
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
ptedge = &bedges[numbedges];
ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[0];
psideedges[0] = ptedge;
ptedge->v[0] = pfrontexit;
ptedge->v[1] = pfrontenter;
ptedge = &bedges[numbedges + 1];
ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[1];
psideedges[1] = ptedge;
ptedge->v[0] = pfrontenter;
ptedge->v[1] = pfrontexit;
numbedges += 2;
if (numbedges >= MAX_BMODEL_EDGES)
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
}
// draw or recurse further
@ -303,17 +315,13 @@ R_RecursiveClipBPoly(entity_t *currententity, bedge_t *pedges, mnode_t *pnode, m
{
if (pn->contents != CONTENTS_SOLID)
{
if (r_newrefdef.areabits)
{
int area;
int r_currentbkey;
area = ((mleaf_t *)pn)->area;
if (! (r_newrefdef.areabits[area>>3] & (1<<(area&7)) ) )
continue; // not visible
}
if (!R_AreaVisible((mleaf_t *)pn))
continue;
r_currentbkey = ((mleaf_t *)pn)->key;
R_RenderBmodelFace(currententity, psideedges[i], psurf);
R_RenderBmodelFace(currententity, psideedges[i], psurf, r_currentbkey);
}
}
else
@ -406,7 +414,7 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre
}
else
{
R_RenderBmodelFace(currententity, pbedge, psurf );
R_RenderBmodelFace(currententity, pbedge, psurf, ((mleaf_t *)topnode)->key);
}
}
}
@ -446,7 +454,7 @@ R_DrawSubmodelPolygons(entity_t *currententity, const model_t *currentmodel, int
r_currentkey = ((mleaf_t *)topnode)->key;
// FIXME: use bounding-box-based frustum clipping info?
R_RenderFace(currententity, currentmodel, psurf, clipflags);
R_RenderFace(currententity, currentmodel, psurf, clipflags, true);
}
}
}
@ -460,7 +468,8 @@ R_RecursiveWorldNode
================
*/
static void
R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnode_t *node, int clipflags)
R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnode_t *node,
int clipflags, qboolean insubmodel)
{
int c;
vec3_t acceptpt, rejectpt;
@ -519,12 +528,8 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
msurface_t **mark;
pleaf = (mleaf_t *)node;
// check for door connected areas
if (r_newrefdef.areabits)
{
if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
if (!R_AreaVisible(pleaf))
return; // not visible
}
mark = pleaf->firstmarksurface;
c = pleaf->nummarksurfaces;
@ -573,7 +578,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
side = 1;
// recurse down the children, front side first
R_RecursiveWorldNode (currententity, currentmodel, node->children[side], clipflags);
R_RecursiveWorldNode (currententity, currentmodel, node->children[side], clipflags, insubmodel);
// draw stuff
c = node->numsurfaces;
@ -591,7 +596,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
if ((surf->flags & SURF_PLANEBACK) &&
(surf->visframe == r_framecount))
{
R_RenderFace (currententity, currentmodel, surf, clipflags);
R_RenderFace (currententity, currentmodel, surf, clipflags, insubmodel);
}
surf++;
@ -604,7 +609,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
if (!(surf->flags & SURF_PLANEBACK) &&
(surf->visframe == r_framecount))
{
R_RenderFace (currententity, currentmodel, surf, clipflags);
R_RenderFace (currententity, currentmodel, surf, clipflags, insubmodel);
}
surf++;
@ -616,7 +621,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
}
// recurse down the back side
R_RecursiveWorldNode (currententity, currentmodel, node->children[!side], clipflags);
R_RecursiveWorldNode (currententity, currentmodel, node->children[!side], clipflags, insubmodel);
}
}
@ -643,5 +648,5 @@ R_RenderWorld (void)
VectorCopy (r_origin, modelorg);
r_pcurrentvertbase = currentmodel->vertexes;
R_RecursiveWorldNode (&r_worldentity, currentmodel, currentmodel->nodes, ALIAS_XY_CLIP_MASK);
R_RecursiveWorldNode (&r_worldentity, currentmodel, currentmodel->nodes, ALIAS_XY_CLIP_MASK, false);
}

View file

@ -36,8 +36,9 @@ have a sentinal at both ends?
edge_t **newedges;
edge_t **removeedges;
espan_t *edge_basespans;
espan_t *max_span_p;
static espan_t *span_p, *max_span_p;
static espan_t *span_p;
int r_currentkey;
@ -107,7 +108,8 @@ R_BeginEdgeFrame (void)
R_InsertNewEdges
Adds the edges in the linked list edgestoadd, adding them to the edges in the
linked list edgelist. edgestoadd is assumed to be sorted on u, and non-empty (this is actually newedges[v]). edgelist is assumed to be sorted on u, with a
linked list edgelist. edgestoadd is assumed to be sorted on u, and non-empty
(this is actually newedges[v]). edgelist is assumed to be sorted on u, with a
sentinel at the end (actually, this is the active edge table starting at
edge_head.next).
==============
@ -205,6 +207,22 @@ R_StepActiveU (edge_t *pedge)
}
}
static void
R_InsertSpan (surf_t *surf, shift20_t iu)
{
if (iu > surf->last_u)
{
espan_t *span;
span = span_p++;
span->u = surf->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf->spans;
surf->spans = span;
}
}
/*
==============
R_CleanupSpan
@ -214,22 +232,11 @@ static void
R_CleanupSpan (void)
{
surf_t *surf;
shift20_t iu;
espan_t *span;
// now that we've reached the right edge of the screen, we're done with any
// unfinished surfaces, so emit a span for whatever's on top
surf = surfaces[1].next;
iu = edge_tail_u_shift20;
if (iu > surf->last_u)
{
span = span_p++;
span->u = surf->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf->spans;
surf->spans = span;
}
R_InsertSpan (surf, edge_tail_u_shift20);
// reset spanstate for all surfaces in the surface stack
do
@ -295,17 +302,7 @@ R_LeadingEdgeBackwards (const edge_t *edge)
// emit a span (obscures current top)
iu = edge->u >> shift_size;
if (iu > surf2->last_u)
{
espan_t *span;
span = span_p++;
span->u = surf2->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf2->spans;
surf2->spans = span;
}
R_InsertSpan (surf2, iu);
// set last_u on the new span
surf->last_u = iu;
@ -332,8 +329,6 @@ R_TrailingEdge
static void
R_TrailingEdge (surf_t *surf, edge_t *edge)
{
espan_t *span;
// don't generate a span if this is an inverted span, with the end
// edge preceding the start edge (that is, we haven't seen the
// start edge yet)
@ -345,15 +340,7 @@ R_TrailingEdge (surf_t *surf, edge_t *edge)
// emit a span (current top going away)
iu = edge->u >> shift_size;
if (iu > surf->last_u)
{
span = span_p++;
span->u = surf->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf->spans;
surf->spans = span;
}
R_InsertSpan (surf, iu);
// set last_u on the surface below
surf->next->last_u = iu;
@ -451,17 +438,7 @@ R_EmitSpanBeforeTop(const edge_t *edge, surf_t *surf, surf_t *surf2)
iu = edge->u >> shift_size;
if (iu > surf2->last_u)
{
espan_t *span;
span = span_p++;
span->u = surf2->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf2->spans;
surf2->spans = span;
}
R_InsertSpan (surf2, iu);
// set last_u on the new span
surf->last_u = iu;
@ -623,18 +600,23 @@ void
R_ScanEdges (surf_t *surface)
{
shift20_t iv, bottom;
espan_t *basespan_p;
surf_t *s;
basespan_p = edge_basespans;
max_span_p = edge_basespans + vid.width * 2 - r_refdef.vrect.width;
if ((vid.width * 2 - r_refdef.vrect.width) < 0)
// clear the surface span pointers
for (s = &surfaces[1] ; s<surf_max ; s++)
{
R_Printf(PRINT_ALL,"No space in edge_basespans\n");
return;
s->last_u = 0;
s->spans = NULL;
}
span_p = basespan_p;
span_p = edge_basespans;
if (span_p + r_refdef.vrect.width >= max_span_p)
{
// Need to more space
r_outedgebasespans = true;
return;
}
// clear active edges to just the background edges around the whole screen
// FIXME: most of this only needs to be set up once
@ -687,7 +669,7 @@ R_ScanEdges (surf_t *surface)
// flush the span list if we can't be sure we have enough spans left for
// the next scan
if (span_p >= max_span_p)
if (span_p + r_refdef.vrect.width >= max_span_p)
{
// Draw stuff on screen
D_DrawSurfaces (surface);
@ -696,7 +678,10 @@ R_ScanEdges (surf_t *surface)
for (s = &surfaces[1] ; s<surface ; s++)
s->spans = NULL;
span_p = basespan_p;
span_p = edge_basespans;
// Need to more space
r_outedgebasespans = true;
}
if (removeedges[iv])

View file

@ -68,11 +68,13 @@ float r_time1;
int r_numallocatededges;
int r_numallocatedverts;
int r_numallocatedtriangles;
int r_numallocatededgebasespans;
float r_aliasuvscale = 1.0;
qboolean r_outofsurfaces;
qboolean r_outofedges;
qboolean r_outofverts;
qboolean r_outoftriangles;
qboolean r_outedgebasespans;
qboolean r_dowarp;
@ -187,8 +189,6 @@ int cachewidth;
pixel_t *d_viewbuffer;
zvalue_t *d_pzbuffer;
qboolean insubmodel;
static void Draw_GetPalette (void);
static void RE_BeginFrame( float camera_separation );
static void Draw_BuildGammaTable(void);
@ -401,11 +401,13 @@ R_ReallocateMapBuffers (void)
surfaces = lsurfs;
// set limits
surf_max = &surfaces[r_cnumsurfs];
surface_p = lsurfs;
// surface 0 doesn't really exist; it's just a dummy because index 0
// is used to indicate no edge attached to surface
surfaces--;
surface_p = &surfaces[2]; // background is surface 1,
// surface 0 is a dummy
R_Printf(PRINT_ALL, "Allocated %d surfaces\n", r_cnumsurfs);
}
@ -495,6 +497,35 @@ R_ReallocateMapBuffers (void)
R_Printf(PRINT_ALL, "Allocated %d triangles\n", r_numallocatedtriangles);
}
if (!r_numallocatededgebasespans || r_outedgebasespans)
{
if (edge_basespans)
{
free(edge_basespans);
}
if (r_outedgebasespans)
{
r_numallocatededgebasespans *= 2;
r_outedgebasespans = false;
}
// used up to 8 * width spans for render, allocate once before use
if (r_numallocatededgebasespans < vid.width * 8)
r_numallocatededgebasespans = vid.width * 8;
edge_basespans = malloc(r_numallocatededgebasespans * sizeof(espan_t));
if (!edge_basespans)
{
R_Printf(PRINT_ALL, "%s: Couldn't malloc %d bytes\n",
__func__, (int)(r_numallocatededgebasespans * sizeof(espan_t)));
return;
}
max_span_p = &edge_basespans[r_numallocatededgebasespans];
R_Printf(PRINT_ALL, "Allocated %d edgespans\n", r_numallocatededgebasespans);
}
}
@ -847,7 +878,6 @@ R_DrawBEntitiesOnList (void)
return;
VectorCopy (modelorg, oldorigin);
insubmodel = true;
for (i=0 ; i<r_newrefdef.num_entities ; i++)
{
@ -909,8 +939,6 @@ R_DrawBEntitiesOnList (void)
VectorCopy (oldorigin, modelorg);
R_TransformFrustum ();
}
insubmodel = false;
}
/*
@ -1827,17 +1855,24 @@ SWimp_CreateRender(void)
warp_rowptr = malloc((vid.width+AMP2*2) * sizeof(byte*));
warp_column = malloc((vid.width+AMP2*2) * sizeof(int));
edge_basespans = malloc((vid.width*2) * sizeof(espan_t));
// count of "out of items"
r_outofsurfaces = r_outofedges = r_outofverts = r_outoftriangles = false;
r_outofsurfaces = false;
r_outofedges = false;
r_outofverts = false;
r_outoftriangles = false;
r_outedgebasespans = false;
// pointers to allocated buffers
finalverts = NULL;
r_edges = NULL;
lsurfs = NULL;
triangle_spans = NULL;
edge_basespans = NULL;
// curently allocated items
r_cnumsurfs = r_numallocatededges = r_numallocatedverts = r_numallocatedtriangles = 0;
r_cnumsurfs = 0;
r_numallocatededges = 0;
r_numallocatedverts = 0;
r_numallocatedtriangles = 0;
r_numallocatededgebasespans = 0;
R_ReallocateMapBuffers();

View file

@ -35,15 +35,9 @@ int c_faceclip; // number of faces clipped
clipplane_t view_clipplanes[4];
medge_t *r_pedge;
edge_t *r_edges = NULL, *edge_p = NULL, *edge_max = NULL;
surf_t *surfaces = NULL, *surface_p = NULL, *surf_max = NULL;
static qboolean r_leftclipped, r_rightclipped;
static qboolean makeleftedge, makerightedge;
static qboolean r_nearzionly;
int *sintable;
int *intsintable;
int *blanktable;
@ -163,7 +157,7 @@ R_EmitSkyBox
================
*/
static void
R_EmitSkyBox(entity_t *currententity, const model_t *currentmodel)
R_EmitSkyBox(entity_t *currententity, const model_t *currentmodel, qboolean insubmodel)
{
int i, j;
int oldkey;
@ -199,7 +193,7 @@ R_EmitSkyBox(entity_t *currententity, const model_t *currentmodel)
r_currentkey = 0x7ffffff0;
for (i=0 ; i<6 ; i++)
{
R_RenderFace(currententity, currentmodel, r_skyfaces + i, ALIAS_XY_CLIP_MASK);
R_RenderFace(currententity, currentmodel, r_skyfaces + i, ALIAS_XY_CLIP_MASK, insubmodel);
}
r_currentkey = oldkey; // bsp sorting order
}
@ -210,7 +204,7 @@ R_EmitEdge
================
*/
static void
R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1, medge_t *r_pedge, qboolean r_nearzionly)
{
edge_t *edge, *pcheck;
int u_check;
@ -387,14 +381,15 @@ R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
removeedges[v2] = edge;
}
/*
================
R_ClipEdge
================
*/
static void
R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip, medge_t *r_pedge,
qboolean *r_leftclipped, qboolean *r_rightclipped,
qboolean r_nearzionly)
{
if (clip)
{
@ -429,16 +424,18 @@ R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
if (clip->leftedge)
{
r_leftclipped = true;
*r_leftclipped = true;
r_leftexit = clipvert;
}
else if (clip->rightedge)
{
r_rightclipped = true;
*r_rightclipped = true;
r_rightexit = clipvert;
}
R_ClipEdge (pv0, &clipvert, clip->next);
R_ClipEdge (pv0, &clipvert, clip->next, r_pedge,
r_leftclipped, r_rightclipped,
r_nearzionly);
return;
}
else
@ -470,23 +467,25 @@ R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
if (clip->leftedge)
{
r_leftclipped = true;
*r_leftclipped = true;
r_leftenter = clipvert;
}
else if (clip->rightedge)
{
r_rightclipped = true;
*r_rightclipped = true;
r_rightenter = clipvert;
}
R_ClipEdge (&clipvert, pv1, clip->next);
R_ClipEdge (&clipvert, pv1, clip->next, r_pedge,
r_leftclipped, r_rightclipped,
r_nearzionly);
return;
}
} while ((clip = clip->next) != NULL);
}
// add the edge
R_EmitEdge (pv0, pv1);
R_EmitEdge (pv0, pv1, r_pedge, r_nearzionly);
}
/*
@ -495,7 +494,7 @@ R_EmitCachedEdge
================
*/
static void
R_EmitCachedEdge (void)
R_EmitCachedEdge (medge_t *r_pedge)
{
edge_t *pedge_t;
@ -519,7 +518,8 @@ R_RenderFace
================
*/
void
R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *fa, int clipflags)
R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *fa,
int clipflags, qboolean insubmodel)
{
int i;
unsigned mask;
@ -528,6 +528,9 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
vec3_t p_normal;
medge_t *pedges, tedge;
clipplane_t *pclip;
qboolean r_leftclipped, r_rightclipped;
qboolean makeleftedge, makerightedge;
qboolean r_nearzionly;
// translucent surfaces are not drawn by the edge renderer
if (fa->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
@ -541,7 +544,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
// environment box surfaces to be emited
if ( fa->texinfo->flags & SURF_SKY )
{
R_EmitSkyBox (currententity, currentmodel);
R_EmitSkyBox (currententity, currentmodel, insubmodel);
return;
}
@ -552,7 +555,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
return;
}
// ditto if not enough edges left, or switch to auxedges if possible
// ditto if not enough edges left
if ((edge_p + fa->numedges + 4) >= edge_max)
{
r_outofedges = true;
@ -589,7 +592,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
if (lindex > 0)
{
r_pedge = &pedges[lindex];
medge_t *r_pedge = &pedges[lindex];
// if the edge is cached, we can just reuse the edge
if (!insubmodel)
@ -610,7 +613,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
(((edge_t *)((uintptr_t)r_edges +
r_pedge->cachededgeoffset))->owner == r_pedge))
{
R_EmitCachedEdge ();
R_EmitCachedEdge (r_pedge);
r_lastvertvalid = false;
continue;
}
@ -622,7 +625,9 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
r_leftclipped = r_rightclipped = false;
R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]],
&r_pcurrentvertbase[r_pedge->v[1]],
pclip);
pclip, r_pedge,
&r_leftclipped, &r_rightclipped,
r_nearzionly);
r_pedge->cachededgeoffset = cacheoffset;
if (r_leftclipped)
@ -633,6 +638,8 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
}
else
{
medge_t *r_pedge;
lindex = -lindex;
r_pedge = &pedges[lindex];
// if the edge is cached, we can just reuse the edge
@ -656,7 +663,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
(((edge_t *)((uintptr_t)r_edges +
r_pedge->cachededgeoffset))->owner == r_pedge))
{
R_EmitCachedEdge ();
R_EmitCachedEdge (r_pedge);
r_lastvertvalid = false;
continue;
}
@ -668,7 +675,9 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
r_leftclipped = r_rightclipped = false;
R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]],
&r_pcurrentvertbase[r_pedge->v[0]],
pclip);
pclip, r_pedge,
&r_leftclipped, &r_rightclipped,
r_nearzionly);
r_pedge->cachededgeoffset = cacheoffset;
if (r_leftclipped)
@ -684,18 +693,18 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
// FIXME: share clipped edges?
if (makeleftedge)
{
r_pedge = &tedge;
r_lastvertvalid = false;
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
}
// if there was a clip off the right edge, get the right r_nearzi
if (makerightedge)
{
r_pedge = &tedge;
r_lastvertvalid = false;
r_nearzionly = true;
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
}
// if no edges made it out, return without posting the surface
@ -735,7 +744,7 @@ R_RenderBmodelFace
================
*/
void
R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf, int r_currentbkey)
{
int i;
unsigned mask;
@ -744,6 +753,9 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
vec3_t p_normal;
medge_t tedge;
clipplane_t *pclip;
qboolean r_leftclipped, r_rightclipped;
qboolean makeleftedge, makerightedge;
qboolean r_nearzionly;
if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
{
@ -759,7 +771,7 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
return;
}
// ditto if not enough edges left, or switch to auxedges if possible
// ditto if not enough edges left
if ((edge_p + psurf->numedges + 4) >= edge_max)
{
r_outofedges = true;
@ -768,9 +780,6 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
c_faceclip++;
// this is a dummy to give the caching mechanism someplace to write to
r_pedge = &tedge;
// set up clip planes
pclip = NULL;
@ -795,7 +804,8 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
for ( ; pedges ; pedges = pedges->pnext)
{
r_leftclipped = r_rightclipped = false;
R_ClipEdge (pedges->v[0], pedges->v[1], pclip);
R_ClipEdge (pedges->v[0], pedges->v[1], pclip, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
if (r_leftclipped)
makeleftedge = true;
@ -808,16 +818,16 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf)
// FIXME: share clipped edges?
if (makeleftedge)
{
r_pedge = &tedge;
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
}
// if there was a clip off the right edge, get the right r_nearzi
if (makerightedge)
{
r_pedge = &tedge;
r_nearzionly = true;
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next, &tedge,
&r_leftclipped, &r_rightclipped, r_nearzionly);
}
// if no edges made it out, return without posting the surface