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 // current entity info
// //
extern qboolean insubmodel;
void R_DrawAlphaSurfaces(const entity_t *currententity); void R_DrawAlphaSurfaces(const entity_t *currententity);
void R_DrawSprite(entity_t *currententity, const model_t *currentmodel); 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_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); void R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf, int r_currentbkey);
void R_TransformFrustum(void); void R_TransformFrustum(void);
void R_DrawSubmodelPolygons(entity_t *currententity, const model_t *currentmodel, int clipflags, mnode_t *topnode); 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 bbextents, bbextentt;
extern int r_currentkey; extern int r_currentkey;
extern int r_currentbkey;
void R_DrawParticles (void); void R_DrawParticles (void);
@ -506,7 +503,9 @@ void R_PolysetDrawSpans8_Opaque(const entity_t *currententity, spanpackage_t *ps
extern byte **warp_rowptr; extern byte **warp_rowptr;
extern int *warp_column; extern int *warp_column;
extern espan_t *edge_basespans; extern espan_t *edge_basespans;
extern espan_t *max_span_p;
extern int r_numallocatedverts; extern int r_numallocatedverts;
extern int r_numallocatededgebasespans;
extern finalvert_t *finalverts, *finalverts_max; extern finalvert_t *finalverts, *finalverts_max;
extern int r_aliasblendcolor; extern int r_aliasblendcolor;
@ -517,6 +516,7 @@ extern qboolean r_outofsurfaces;
extern qboolean r_outofedges; extern qboolean r_outofedges;
extern qboolean r_outofverts; extern qboolean r_outofverts;
extern qboolean r_outoftriangles; extern qboolean r_outoftriangles;
extern qboolean r_outedgebasespans;
extern mvertex_t *r_pcurrentvertbase; 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 r_time1;
extern float da_time1, da_time2; extern float da_time1, da_time2;
extern float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_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_viewcluster, r_oldviewcluster;
extern int r_clipflags; 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]; static float entity_rotation[3][3];
int r_currentbkey;
typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t; typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t;
#define MAX_BMODEL_VERTS 500 // 6K #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 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 // split into two edges, one on each side, and remember entering
// and exiting points // and exiting points
// FIXME: share the clip edge by having a winding direction flag? // FIXME: share the clip edge by having a winding direction flag?
if (numbedges >= (MAX_BMODEL_EDGES - 1)) ptedge = &bedges[numbedges++];
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
ptedge = &bedges[numbedges];
ptedge->pnext = psideedges[lastside]; ptedge->pnext = psideedges[lastside];
psideedges[lastside] = ptedge; psideedges[lastside] = ptedge;
ptedge->v[0] = plastvert; ptedge->v[0] = plastvert;
ptedge->v[1] = ptvert; ptedge->v[1] = ptvert;
ptedge = &bedges[numbedges + 1]; ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[side]; ptedge->pnext = psideedges[side];
psideedges[side] = ptedge; psideedges[side] = ptedge;
ptedge->v[0] = ptvert; ptedge->v[0] = ptvert;
ptedge->v[1] = pvert; 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) 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) // plane to both sides (but in opposite directions)
if (makeclippededge && pfrontexit != pfrontenter) if (makeclippededge && pfrontexit != pfrontenter)
{ {
if (numbedges >= (MAX_BMODEL_EDGES - 2)) ptedge = &bedges[numbedges++];
{
R_Printf(PRINT_ALL,"Out of edges for bmodel\n");
return;
}
ptedge = &bedges[numbedges];
ptedge->pnext = psideedges[0]; ptedge->pnext = psideedges[0];
psideedges[0] = ptedge; psideedges[0] = ptedge;
ptedge->v[0] = pfrontexit; ptedge->v[0] = pfrontexit;
ptedge->v[1] = pfrontenter; ptedge->v[1] = pfrontenter;
ptedge = &bedges[numbedges + 1]; ptedge = &bedges[numbedges++];
ptedge->pnext = psideedges[1]; ptedge->pnext = psideedges[1];
psideedges[1] = ptedge; psideedges[1] = ptedge;
ptedge->v[0] = pfrontenter; ptedge->v[0] = pfrontenter;
ptedge->v[1] = pfrontexit; 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 // 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 (pn->contents != CONTENTS_SOLID)
{ {
if (r_newrefdef.areabits) int r_currentbkey;
{
int area;
area = ((mleaf_t *)pn)->area; if (!R_AreaVisible((mleaf_t *)pn))
if (! (r_newrefdef.areabits[area>>3] & (1<<(area&7)) ) ) continue;
continue; // not visible
}
r_currentbkey = ((mleaf_t *)pn)->key; r_currentbkey = ((mleaf_t *)pn)->key;
R_RenderBmodelFace(currententity, psideedges[i], psurf); R_RenderBmodelFace(currententity, psideedges[i], psurf, r_currentbkey);
} }
} }
else else
@ -399,14 +407,14 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre
pbedge[j-1].pnext = NULL; // mark end of edges pbedge[j-1].pnext = NULL; // mark end of edges
if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ) ) if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ))
{ {
// FIXME: Fan broken in borehole // FIXME: Fan broken in borehole
R_RecursiveClipBPoly(currententity, pbedge, topnode, psurf); R_RecursiveClipBPoly(currententity, pbedge, topnode, psurf);
} }
else 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; r_currentkey = ((mleaf_t *)topnode)->key;
// FIXME: use bounding-box-based frustum clipping info? // 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 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; int c;
vec3_t acceptpt, rejectpt; vec3_t acceptpt, rejectpt;
@ -519,12 +528,8 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
msurface_t **mark; msurface_t **mark;
pleaf = (mleaf_t *)node; pleaf = (mleaf_t *)node;
// check for door connected areas if (!R_AreaVisible(pleaf))
if (r_newrefdef.areabits)
{
if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
return; // not visible return; // not visible
}
mark = pleaf->firstmarksurface; mark = pleaf->firstmarksurface;
c = pleaf->nummarksurfaces; c = pleaf->nummarksurfaces;
@ -573,7 +578,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
side = 1; side = 1;
// recurse down the children, front side first // 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 // draw stuff
c = node->numsurfaces; c = node->numsurfaces;
@ -591,7 +596,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
if ((surf->flags & SURF_PLANEBACK) && if ((surf->flags & SURF_PLANEBACK) &&
(surf->visframe == r_framecount)) (surf->visframe == r_framecount))
{ {
R_RenderFace (currententity, currentmodel, surf, clipflags); R_RenderFace (currententity, currentmodel, surf, clipflags, insubmodel);
} }
surf++; surf++;
@ -604,7 +609,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
if (!(surf->flags & SURF_PLANEBACK) && if (!(surf->flags & SURF_PLANEBACK) &&
(surf->visframe == r_framecount)) (surf->visframe == r_framecount))
{ {
R_RenderFace (currententity, currentmodel, surf, clipflags); R_RenderFace (currententity, currentmodel, surf, clipflags, insubmodel);
} }
surf++; surf++;
@ -616,7 +621,7 @@ R_RecursiveWorldNode (entity_t *currententity, const model_t *currentmodel, mnod
} }
// recurse down the back side // 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); VectorCopy (r_origin, modelorg);
r_pcurrentvertbase = currentmodel->vertexes; 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 **newedges;
edge_t **removeedges; edge_t **removeedges;
espan_t *edge_basespans; 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; int r_currentkey;
@ -107,7 +108,8 @@ R_BeginEdgeFrame (void)
R_InsertNewEdges R_InsertNewEdges
Adds the edges in the linked list edgestoadd, adding them to the edges in the 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 sentinel at the end (actually, this is the active edge table starting at
edge_head.next). 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 R_CleanupSpan
@ -214,22 +232,11 @@ static void
R_CleanupSpan (void) R_CleanupSpan (void)
{ {
surf_t *surf; 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 // 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 // unfinished surfaces, so emit a span for whatever's on top
surf = surfaces[1].next; surf = surfaces[1].next;
iu = edge_tail_u_shift20; R_InsertSpan (surf, 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;
}
// reset spanstate for all surfaces in the surface stack // reset spanstate for all surfaces in the surface stack
do do
@ -295,17 +302,7 @@ R_LeadingEdgeBackwards (const edge_t *edge)
// emit a span (obscures current top) // emit a span (obscures current top)
iu = edge->u >> shift_size; iu = edge->u >> shift_size;
if (iu > surf2->last_u) R_InsertSpan (surf2, iu);
{
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;
}
// set last_u on the new span // set last_u on the new span
surf->last_u = iu; surf->last_u = iu;
@ -332,8 +329,6 @@ R_TrailingEdge
static void static void
R_TrailingEdge (surf_t *surf, edge_t *edge) 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 // 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 // edge preceding the start edge (that is, we haven't seen the
// start edge yet) // start edge yet)
@ -345,15 +340,7 @@ R_TrailingEdge (surf_t *surf, edge_t *edge)
// emit a span (current top going away) // emit a span (current top going away)
iu = edge->u >> shift_size; iu = edge->u >> shift_size;
if (iu > surf->last_u) R_InsertSpan (surf, iu);
{
span = span_p++;
span->u = surf->last_u;
span->count = iu - span->u;
span->v = current_iv;
span->pnext = surf->spans;
surf->spans = span;
}
// set last_u on the surface below // set last_u on the surface below
surf->next->last_u = iu; 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; iu = edge->u >> shift_size;
if (iu > surf2->last_u) R_InsertSpan (surf2, iu);
{
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;
}
// set last_u on the new span // set last_u on the new span
surf->last_u = iu; surf->last_u = iu;
@ -623,18 +600,23 @@ void
R_ScanEdges (surf_t *surface) R_ScanEdges (surf_t *surface)
{ {
shift20_t iv, bottom; shift20_t iv, bottom;
espan_t *basespan_p;
surf_t *s; surf_t *s;
basespan_p = edge_basespans; // clear the surface span pointers
max_span_p = edge_basespans + vid.width * 2 - r_refdef.vrect.width; for (s = &surfaces[1] ; s<surf_max ; s++)
if ((vid.width * 2 - r_refdef.vrect.width) < 0)
{ {
R_Printf(PRINT_ALL,"No space in edge_basespans\n"); s->last_u = 0;
return; 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 // clear active edges to just the background edges around the whole screen
// FIXME: most of this only needs to be set up once // 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 // flush the span list if we can't be sure we have enough spans left for
// the next scan // the next scan
if (span_p >= max_span_p) if (span_p + r_refdef.vrect.width >= max_span_p)
{ {
// Draw stuff on screen // Draw stuff on screen
D_DrawSurfaces (surface); D_DrawSurfaces (surface);
@ -696,7 +678,10 @@ R_ScanEdges (surf_t *surface)
for (s = &surfaces[1] ; s<surface ; s++) for (s = &surfaces[1] ; s<surface ; s++)
s->spans = NULL; s->spans = NULL;
span_p = basespan_p; span_p = edge_basespans;
// Need to more space
r_outedgebasespans = true;
} }
if (removeedges[iv]) if (removeedges[iv])

View File

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

View File

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