Skip to content

Commit 1ffaad0

Browse files
committed
Re-implement R_RenderBspNodes in non-recursive way
Constant stack size is guaranteed.
1 parent c7cc9ca commit 1ffaad0

File tree

1 file changed

+61
-16
lines changed

1 file changed

+61
-16
lines changed

src/r_bsp.c

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,20 @@ void R_Subsector (int num)
542542
}
543543

544544

545+
// Render a BSP subsector if bspnum is a leaf node.
546+
// Return false if bspnum is frame node.
547+
static boolean R_RenderBspSubsector(int bspnum)
548+
{
549+
// Found a subsector?
550+
if (bspnum & NF_SUBSECTOR)
551+
{
552+
R_Subsector((bspnum == -1) ? 0 :
553+
bspnum & (~NF_SUBSECTOR));
554+
return true;
555+
}
545556

557+
return false;
558+
}
546559

547560
//
548561
// RenderBSPNode
@@ -554,27 +567,59 @@ void R_RenderBSPNode (int bspnum)
554567
node_t* bsp;
555568
int side;
556569

557-
// Found a subsector?
558-
if (bspnum & NF_SUBSECTOR)
570+
// constant stack space used
571+
#define MAX_BSP_DEPTH 128
572+
int stack[MAX_BSP_DEPTH];
573+
int sp = 0;
574+
575+
while (true)
559576
{
560-
if (bspnum == -1)
561-
R_Subsector (0);
562-
else
563-
R_Subsector (bspnum&(~NF_SUBSECTOR));
564-
return;
565-
}
577+
// Front side
578+
while (!R_RenderBspSubsector(bspnum))
579+
{
580+
if (sp == MAX_BSP_DEPTH)
581+
break;
566582

567-
bsp = &nodes[bspnum];
583+
bsp = &nodes[bspnum];
584+
side = R_PointOnSide (viewx, viewy, bsp);
568585

569-
// Decide which side the view point is on.
570-
side = R_PointOnSide (viewx, viewy, bsp);
586+
stack[sp++] = bspnum;
587+
stack[sp++] = side;
571588

572-
// Recursively divide front space.
573-
R_RenderBSPNode (bsp->children[side]);
589+
bspnum = bsp->children[side];
590+
}
574591

575-
// Possibly divide back space.
576-
if (R_CheckBBox (bsp->bbox[side^1]))
577-
R_RenderBSPNode (bsp->children[side^1]);
592+
if (sp == 0)
593+
{
594+
//back at root node and not visible. All done!
595+
return;
596+
}
597+
598+
// Back side
599+
side = stack[--sp];
600+
bspnum = stack[--sp];
601+
bsp = &nodes[bspnum];
602+
603+
// Possibly divide back space.
604+
// Walk back up the tree until we find a node that has a visable
605+
// backspace.
606+
while(!R_CheckBBox (bsp->bbox[side^1]))
607+
{
608+
if (sp == 0)
609+
{
610+
// back at root node and not visible. All done!
611+
return;
612+
}
613+
614+
// Back side next.
615+
side = stack[--sp];
616+
bspnum = stack[--sp];
617+
618+
bsp = &nodes[bspnum];
619+
}
620+
621+
bspnum = bsp->children[side^1];
622+
}
578623
}
579624

580625

0 commit comments

Comments
 (0)