mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-24 04:51:41 +00:00
Change draw segment list to use TArray
This commit is contained in:
parent
812cc61b16
commit
da346427d3
9 changed files with 67 additions and 80 deletions
|
@ -318,8 +318,6 @@ namespace swrenderer
|
|||
I_FatalError("Bad R_StoreWallRange: %i to %i", start, stop);
|
||||
#endif
|
||||
|
||||
DrawSegment *draw_segment = DrawSegmentList::Instance()->Add();
|
||||
|
||||
if (!rw_prepped)
|
||||
{
|
||||
rw_prepped = true;
|
||||
|
@ -331,6 +329,9 @@ namespace swrenderer
|
|||
|
||||
RenderPortal *renderportal = RenderPortal::Instance();
|
||||
|
||||
DrawSegment *draw_segment = RenderMemory::NewObject<DrawSegment>();
|
||||
DrawSegmentList::Instance()->Push(draw_segment);
|
||||
|
||||
draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||
draw_segment->sx1 = WallC.sx1;
|
||||
draw_segment->sx2 = WallC.sx2;
|
||||
|
@ -516,8 +517,7 @@ namespace swrenderer
|
|||
|
||||
if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr)
|
||||
{
|
||||
size_t drawsegnum = draw_segment - DrawSegmentList::Instance()->drawsegs;
|
||||
DrawSegmentList::Instance()->InterestingDrawsegs.Push(drawsegnum);
|
||||
DrawSegmentList::Instance()->PushInteresting(draw_segment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,8 +104,6 @@ namespace swrenderer
|
|||
int savedextralight = extralight;
|
||||
DVector3 savedpos = ViewPos;
|
||||
DAngle savedangle = ViewAngle;
|
||||
ptrdiff_t savedds_p = drawseglist->ds_p - drawseglist->drawsegs;
|
||||
size_t savedinteresting = drawseglist->FirstInterestingDrawseg;
|
||||
double savedvisibility = LightVisibility::Instance()->GetVisibility();
|
||||
AActor *savedcamera = camera;
|
||||
sector_t *savedsector = viewsector;
|
||||
|
@ -188,7 +186,7 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
// Create a drawseg to clip sprites to the sky plane
|
||||
DrawSegment *draw_segment = drawseglist->Add();
|
||||
DrawSegment *draw_segment = RenderMemory::NewObject<DrawSegment>();
|
||||
draw_segment->CurrentPortalUniq = CurrentPortalUniq;
|
||||
draw_segment->siz1 = INT_MAX;
|
||||
draw_segment->siz2 = INT_MAX;
|
||||
|
@ -207,13 +205,9 @@ namespace swrenderer
|
|||
draw_segment->foggy = false;
|
||||
memcpy(draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short));
|
||||
memcpy(draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left) * sizeof(short));
|
||||
drawseglist->Push(draw_segment);
|
||||
|
||||
drawseglist->firstdrawseg = draw_segment;
|
||||
drawseglist->FirstInterestingDrawseg = drawseglist->InterestingDrawsegs.Size();
|
||||
|
||||
interestingStack.Push(drawseglist->FirstInterestingDrawseg);
|
||||
ptrdiff_t diffnum = drawseglist->firstdrawseg - drawseglist->drawsegs;
|
||||
drawsegStack.Push(diffnum);
|
||||
drawseglist->PushPortal();
|
||||
VisibleSpriteList::Instance()->PushPortal();
|
||||
viewposStack.Push(ViewPos);
|
||||
visplaneStack.Push(pl);
|
||||
|
@ -229,33 +223,23 @@ namespace swrenderer
|
|||
// Draw all the masked textures in a second pass, in the reverse order they
|
||||
// were added. This must be done separately from the previous step for the
|
||||
// sake of nested skyboxes.
|
||||
while (interestingStack.Pop(drawseglist->FirstInterestingDrawseg))
|
||||
while (viewposStack.Size() > 0)
|
||||
{
|
||||
ptrdiff_t pd = 0;
|
||||
|
||||
drawsegStack.Pop(pd);
|
||||
drawseglist->firstdrawseg = drawseglist->drawsegs + pd;
|
||||
|
||||
// Masked textures and planes need the view coordinates restored for proper positioning.
|
||||
viewposStack.Pop(ViewPos);
|
||||
|
||||
RenderTranslucentPass::Instance()->Render();
|
||||
|
||||
drawseglist->ds_p = drawseglist->firstdrawseg;
|
||||
|
||||
VisibleSpriteList::Instance()->PopPortal();
|
||||
|
||||
VisiblePlane *pl;
|
||||
visplaneStack.Pop(pl);
|
||||
if (pl->Alpha > 0 && pl->picnum != skyflatnum)
|
||||
{
|
||||
pl->Render(pl->Alpha, pl->Additive, true);
|
||||
}
|
||||
|
||||
VisibleSpriteList::Instance()->PopPortal();
|
||||
drawseglist->PopPortal();
|
||||
}
|
||||
drawseglist->firstdrawseg = drawseglist->drawsegs;
|
||||
drawseglist->ds_p = drawseglist->drawsegs + savedds_p;
|
||||
drawseglist->InterestingDrawsegs.Resize((unsigned int)drawseglist->FirstInterestingDrawseg);
|
||||
drawseglist->FirstInterestingDrawseg = savedinteresting;
|
||||
|
||||
camera = savedcamera;
|
||||
viewsector = savedsector;
|
||||
|
|
|
@ -55,8 +55,6 @@ namespace swrenderer
|
|||
void RenderLinePortal(PortalDrawseg* pds, int depth);
|
||||
void RenderLinePortalHighlight(PortalDrawseg* pds);
|
||||
|
||||
TArray<size_t> interestingStack;
|
||||
TArray<ptrdiff_t> drawsegStack;
|
||||
TArray<DVector3> viewposStack;
|
||||
TArray<VisiblePlane *> visplaneStack;
|
||||
TArray<PortalDrawseg *> WallPortals;
|
||||
|
|
|
@ -248,7 +248,6 @@ namespace swrenderer
|
|||
{
|
||||
RenderTranslucentPass::Instance()->Deinit();
|
||||
Clip3DFloors::Instance()->Cleanup();
|
||||
DrawSegmentList::Instance()->Deinit();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -72,8 +72,10 @@ namespace swrenderer
|
|||
// b) skip most of the collected drawsegs which have no portal attached.
|
||||
portaldrawsegs.Clear();
|
||||
DrawSegmentList *drawseglist = DrawSegmentList::Instance();
|
||||
for (DrawSegment* seg = drawseglist->ds_p; seg-- > drawseglist->firstdrawseg; )
|
||||
for (auto index = drawseglist->BeginIndex(); index != drawseglist->EndIndex(); index++)
|
||||
{
|
||||
DrawSegment *seg = drawseglist->Segment(index);
|
||||
|
||||
// I don't know what makes this happen (some old top-down portal code or possibly skybox code? something adds null lines...)
|
||||
// crashes at the first frame of the first map of Action2.wad
|
||||
if (!seg->curline) continue;
|
||||
|
@ -141,9 +143,12 @@ namespace swrenderer
|
|||
{
|
||||
Clip3DFloors::Instance()->fake3D |= FAKE3D_REFRESHCLIP;
|
||||
}
|
||||
|
||||
DrawSegmentList *drawseglist = DrawSegmentList::Instance();
|
||||
for (DrawSegment *ds = drawseglist->ds_p; ds-- > drawseglist->firstdrawseg; )
|
||||
for (auto index = drawseglist->BeginIndex(); index != drawseglist->EndIndex(); index++)
|
||||
{
|
||||
DrawSegment *ds = drawseglist->Segment(index);
|
||||
|
||||
// [ZZ] the same as above
|
||||
if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
||||
continue;
|
||||
|
|
|
@ -49,40 +49,39 @@ namespace swrenderer
|
|||
return &instance;
|
||||
}
|
||||
|
||||
void DrawSegmentList::Deinit()
|
||||
{
|
||||
if (drawsegs != nullptr)
|
||||
{
|
||||
M_Free(drawsegs);
|
||||
drawsegs = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSegmentList::Clear()
|
||||
{
|
||||
if (drawsegs == nullptr)
|
||||
{
|
||||
MaxDrawSegs = 256; // [RH] Default. Increased as needed.
|
||||
firstdrawseg = drawsegs = (DrawSegment *)M_Malloc (MaxDrawSegs * sizeof(DrawSegment));
|
||||
}
|
||||
FirstInterestingDrawseg = 0;
|
||||
InterestingDrawsegs.Clear ();
|
||||
ds_p = drawsegs;
|
||||
Segments.Clear();
|
||||
StartIndices.Clear();
|
||||
StartIndices.Push(0);
|
||||
|
||||
InterestingSegments.Clear();
|
||||
StartInterestingIndices.Clear();
|
||||
StartInterestingIndices.Push(0);
|
||||
}
|
||||
|
||||
DrawSegment *DrawSegmentList::Add()
|
||||
void DrawSegmentList::PushPortal()
|
||||
{
|
||||
if (ds_p == &drawsegs[MaxDrawSegs])
|
||||
{ // [RH] Grab some more drawsegs
|
||||
size_t newdrawsegs = MaxDrawSegs ? MaxDrawSegs * 2 : 32;
|
||||
ptrdiff_t firstofs = firstdrawseg - drawsegs;
|
||||
drawsegs = (DrawSegment *)M_Realloc(drawsegs, newdrawsegs * sizeof(DrawSegment));
|
||||
firstdrawseg = drawsegs + firstofs;
|
||||
ds_p = drawsegs + MaxDrawSegs;
|
||||
MaxDrawSegs = newdrawsegs;
|
||||
DPrintf(DMSG_NOTIFY, "MaxDrawSegs increased to %zu\n", MaxDrawSegs);
|
||||
StartIndices.Push(Segments.Size());
|
||||
StartInterestingIndices.Push(InterestingSegments.Size());
|
||||
}
|
||||
|
||||
return ds_p++;
|
||||
void DrawSegmentList::PopPortal()
|
||||
{
|
||||
Segments.Resize(StartIndices.Last());
|
||||
StartIndices.Pop();
|
||||
|
||||
StartInterestingIndices.Resize(StartInterestingIndices.Last());
|
||||
StartInterestingIndices.Pop();
|
||||
}
|
||||
|
||||
void DrawSegmentList::Push(DrawSegment *segment)
|
||||
{
|
||||
Segments.Push(segment);
|
||||
}
|
||||
|
||||
void DrawSegmentList::PushInteresting(DrawSegment *segment)
|
||||
{
|
||||
InterestingSegments.Push(segment);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,19 +52,25 @@ namespace swrenderer
|
|||
public:
|
||||
static DrawSegmentList *Instance();
|
||||
|
||||
DrawSegment *firstdrawseg = nullptr;
|
||||
DrawSegment *ds_p = nullptr;
|
||||
DrawSegment *drawsegs = nullptr;
|
||||
unsigned int BeginIndex() const { return StartIndices.Last(); }
|
||||
unsigned int EndIndex() const { return Segments.Size(); }
|
||||
DrawSegment *Segment(int index) const { return Segments[Segments.Size() - 1 - index]; }
|
||||
|
||||
TArray<size_t> InterestingDrawsegs; // drawsegs that have something drawn on them
|
||||
size_t FirstInterestingDrawseg = 0;
|
||||
unsigned int BeginInterestingIndex() const { return StartInterestingIndices.Last(); }
|
||||
unsigned int EndInterestingIndex() const { return InterestingSegments.Size(); }
|
||||
DrawSegment *InterestingSegment(int index) const { return InterestingSegments[Segments.Size() - 1 - index]; }
|
||||
|
||||
void Clear();
|
||||
void Deinit();
|
||||
|
||||
DrawSegment *Add();
|
||||
void PushPortal();
|
||||
void PopPortal();
|
||||
void Push(DrawSegment *segment);
|
||||
void PushInteresting(DrawSegment *segment);
|
||||
|
||||
private:
|
||||
size_t MaxDrawSegs = 0;
|
||||
TArray<DrawSegment *> Segments;
|
||||
TArray<unsigned int> StartIndices;
|
||||
|
||||
TArray<DrawSegment *> InterestingSegments; // drawsegs that have something drawn on them
|
||||
TArray<unsigned int> StartInterestingIndices;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -266,9 +266,10 @@ namespace swrenderer
|
|||
// Draw any masked textures behind this particle so that when the
|
||||
// particle is drawn, it will be in front of them.
|
||||
DrawSegmentList *segmentlist = DrawSegmentList::Instance();
|
||||
for (unsigned int p = segmentlist->InterestingDrawsegs.Size(); p-- > segmentlist->FirstInterestingDrawseg; )
|
||||
for (unsigned int index = segmentlist->BeginInterestingIndex(); index != segmentlist->EndInterestingIndex(); index++)
|
||||
{
|
||||
DrawSegment *ds = &segmentlist->drawsegs[segmentlist->InterestingDrawsegs[p]];
|
||||
DrawSegment *ds = segmentlist->InterestingSegment(index);
|
||||
|
||||
// kg3D - no fake segs
|
||||
if (ds->fake) continue;
|
||||
if (ds->x1 >= x2 || ds->x2 <= x1)
|
||||
|
|
|
@ -47,7 +47,6 @@ namespace swrenderer
|
|||
|
||||
VisibleSprite *spr = this;
|
||||
|
||||
DrawSegment *ds;
|
||||
int i;
|
||||
int x1, x2;
|
||||
int r1, r2;
|
||||
|
@ -280,15 +279,11 @@ namespace swrenderer
|
|||
// Scan drawsegs from end to start for obscuring segs.
|
||||
// The first drawseg that is closer than the sprite is the clip seg.
|
||||
|
||||
// Modified by Lee Killough:
|
||||
// (pointer check was originally nonportable
|
||||
// and buggy, by going past LEFT end of array):
|
||||
|
||||
// for (ds=ds_p-1 ; ds >= drawsegs ; ds--) old buggy code
|
||||
|
||||
DrawSegmentList *segmentlist = DrawSegmentList::Instance();
|
||||
for (ds = segmentlist->ds_p; ds-- > segmentlist->firstdrawseg; ) // new -- killough
|
||||
for (unsigned int index = segmentlist->BeginIndex(); index != segmentlist->EndIndex(); index++)
|
||||
{
|
||||
DrawSegment *ds = segmentlist->Segment(index);
|
||||
|
||||
// [ZZ] portal handling here
|
||||
//if (ds->CurrentPortalUniq != spr->CurrentPortalUniq)
|
||||
// continue;
|
||||
|
|
Loading…
Reference in a new issue