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);
|
I_FatalError("Bad R_StoreWallRange: %i to %i", start, stop);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DrawSegment *draw_segment = DrawSegmentList::Instance()->Add();
|
|
||||||
|
|
||||||
if (!rw_prepped)
|
if (!rw_prepped)
|
||||||
{
|
{
|
||||||
rw_prepped = true;
|
rw_prepped = true;
|
||||||
|
@ -331,6 +329,9 @@ namespace swrenderer
|
||||||
|
|
||||||
RenderPortal *renderportal = RenderPortal::Instance();
|
RenderPortal *renderportal = RenderPortal::Instance();
|
||||||
|
|
||||||
|
DrawSegment *draw_segment = RenderMemory::NewObject<DrawSegment>();
|
||||||
|
DrawSegmentList::Instance()->Push(draw_segment);
|
||||||
|
|
||||||
draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||||
draw_segment->sx1 = WallC.sx1;
|
draw_segment->sx1 = WallC.sx1;
|
||||||
draw_segment->sx2 = WallC.sx2;
|
draw_segment->sx2 = WallC.sx2;
|
||||||
|
@ -516,8 +517,7 @@ namespace swrenderer
|
||||||
|
|
||||||
if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr)
|
if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr)
|
||||||
{
|
{
|
||||||
size_t drawsegnum = draw_segment - DrawSegmentList::Instance()->drawsegs;
|
DrawSegmentList::Instance()->PushInteresting(draw_segment);
|
||||||
DrawSegmentList::Instance()->InterestingDrawsegs.Push(drawsegnum);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,8 +104,6 @@ namespace swrenderer
|
||||||
int savedextralight = extralight;
|
int savedextralight = extralight;
|
||||||
DVector3 savedpos = ViewPos;
|
DVector3 savedpos = ViewPos;
|
||||||
DAngle savedangle = ViewAngle;
|
DAngle savedangle = ViewAngle;
|
||||||
ptrdiff_t savedds_p = drawseglist->ds_p - drawseglist->drawsegs;
|
|
||||||
size_t savedinteresting = drawseglist->FirstInterestingDrawseg;
|
|
||||||
double savedvisibility = LightVisibility::Instance()->GetVisibility();
|
double savedvisibility = LightVisibility::Instance()->GetVisibility();
|
||||||
AActor *savedcamera = camera;
|
AActor *savedcamera = camera;
|
||||||
sector_t *savedsector = viewsector;
|
sector_t *savedsector = viewsector;
|
||||||
|
@ -188,7 +186,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a drawseg to clip sprites to the sky plane
|
// 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->CurrentPortalUniq = CurrentPortalUniq;
|
||||||
draw_segment->siz1 = INT_MAX;
|
draw_segment->siz1 = INT_MAX;
|
||||||
draw_segment->siz2 = INT_MAX;
|
draw_segment->siz2 = INT_MAX;
|
||||||
|
@ -207,13 +205,9 @@ namespace swrenderer
|
||||||
draw_segment->foggy = false;
|
draw_segment->foggy = false;
|
||||||
memcpy(draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short));
|
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));
|
memcpy(draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left) * sizeof(short));
|
||||||
|
drawseglist->Push(draw_segment);
|
||||||
|
|
||||||
drawseglist->firstdrawseg = draw_segment;
|
drawseglist->PushPortal();
|
||||||
drawseglist->FirstInterestingDrawseg = drawseglist->InterestingDrawsegs.Size();
|
|
||||||
|
|
||||||
interestingStack.Push(drawseglist->FirstInterestingDrawseg);
|
|
||||||
ptrdiff_t diffnum = drawseglist->firstdrawseg - drawseglist->drawsegs;
|
|
||||||
drawsegStack.Push(diffnum);
|
|
||||||
VisibleSpriteList::Instance()->PushPortal();
|
VisibleSpriteList::Instance()->PushPortal();
|
||||||
viewposStack.Push(ViewPos);
|
viewposStack.Push(ViewPos);
|
||||||
visplaneStack.Push(pl);
|
visplaneStack.Push(pl);
|
||||||
|
@ -229,33 +223,23 @@ namespace swrenderer
|
||||||
// Draw all the masked textures in a second pass, in the reverse order they
|
// 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
|
// were added. This must be done separately from the previous step for the
|
||||||
// sake of nested skyboxes.
|
// 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.
|
// Masked textures and planes need the view coordinates restored for proper positioning.
|
||||||
viewposStack.Pop(ViewPos);
|
viewposStack.Pop(ViewPos);
|
||||||
|
|
||||||
RenderTranslucentPass::Instance()->Render();
|
RenderTranslucentPass::Instance()->Render();
|
||||||
|
|
||||||
drawseglist->ds_p = drawseglist->firstdrawseg;
|
|
||||||
|
|
||||||
VisibleSpriteList::Instance()->PopPortal();
|
|
||||||
|
|
||||||
VisiblePlane *pl;
|
VisiblePlane *pl;
|
||||||
visplaneStack.Pop(pl);
|
visplaneStack.Pop(pl);
|
||||||
if (pl->Alpha > 0 && pl->picnum != skyflatnum)
|
if (pl->Alpha > 0 && pl->picnum != skyflatnum)
|
||||||
{
|
{
|
||||||
pl->Render(pl->Alpha, pl->Additive, true);
|
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;
|
camera = savedcamera;
|
||||||
viewsector = savedsector;
|
viewsector = savedsector;
|
||||||
|
|
|
@ -55,8 +55,6 @@ namespace swrenderer
|
||||||
void RenderLinePortal(PortalDrawseg* pds, int depth);
|
void RenderLinePortal(PortalDrawseg* pds, int depth);
|
||||||
void RenderLinePortalHighlight(PortalDrawseg* pds);
|
void RenderLinePortalHighlight(PortalDrawseg* pds);
|
||||||
|
|
||||||
TArray<size_t> interestingStack;
|
|
||||||
TArray<ptrdiff_t> drawsegStack;
|
|
||||||
TArray<DVector3> viewposStack;
|
TArray<DVector3> viewposStack;
|
||||||
TArray<VisiblePlane *> visplaneStack;
|
TArray<VisiblePlane *> visplaneStack;
|
||||||
TArray<PortalDrawseg *> WallPortals;
|
TArray<PortalDrawseg *> WallPortals;
|
||||||
|
|
|
@ -248,7 +248,6 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
RenderTranslucentPass::Instance()->Deinit();
|
RenderTranslucentPass::Instance()->Deinit();
|
||||||
Clip3DFloors::Instance()->Cleanup();
|
Clip3DFloors::Instance()->Cleanup();
|
||||||
DrawSegmentList::Instance()->Deinit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -72,8 +72,10 @@ namespace swrenderer
|
||||||
// b) skip most of the collected drawsegs which have no portal attached.
|
// b) skip most of the collected drawsegs which have no portal attached.
|
||||||
portaldrawsegs.Clear();
|
portaldrawsegs.Clear();
|
||||||
DrawSegmentList *drawseglist = DrawSegmentList::Instance();
|
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...)
|
// 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
|
// crashes at the first frame of the first map of Action2.wad
|
||||||
if (!seg->curline) continue;
|
if (!seg->curline) continue;
|
||||||
|
@ -141,9 +143,12 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
Clip3DFloors::Instance()->fake3D |= FAKE3D_REFRESHCLIP;
|
Clip3DFloors::Instance()->fake3D |= FAKE3D_REFRESHCLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawSegmentList *drawseglist = DrawSegmentList::Instance();
|
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
|
// [ZZ] the same as above
|
||||||
if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -49,40 +49,39 @@ namespace swrenderer
|
||||||
return &instance;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawSegmentList::Deinit()
|
|
||||||
{
|
|
||||||
if (drawsegs != nullptr)
|
|
||||||
{
|
|
||||||
M_Free(drawsegs);
|
|
||||||
drawsegs = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawSegmentList::Clear()
|
void DrawSegmentList::Clear()
|
||||||
{
|
{
|
||||||
if (drawsegs == nullptr)
|
Segments.Clear();
|
||||||
{
|
StartIndices.Clear();
|
||||||
MaxDrawSegs = 256; // [RH] Default. Increased as needed.
|
StartIndices.Push(0);
|
||||||
firstdrawseg = drawsegs = (DrawSegment *)M_Malloc (MaxDrawSegs * sizeof(DrawSegment));
|
|
||||||
}
|
InterestingSegments.Clear();
|
||||||
FirstInterestingDrawseg = 0;
|
StartInterestingIndices.Clear();
|
||||||
InterestingDrawsegs.Clear ();
|
StartInterestingIndices.Push(0);
|
||||||
ds_p = drawsegs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawSegment *DrawSegmentList::Add()
|
void DrawSegmentList::PushPortal()
|
||||||
{
|
{
|
||||||
if (ds_p == &drawsegs[MaxDrawSegs])
|
StartIndices.Push(Segments.Size());
|
||||||
{ // [RH] Grab some more drawsegs
|
StartInterestingIndices.Push(InterestingSegments.Size());
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
public:
|
||||||
static DrawSegmentList *Instance();
|
static DrawSegmentList *Instance();
|
||||||
|
|
||||||
DrawSegment *firstdrawseg = nullptr;
|
unsigned int BeginIndex() const { return StartIndices.Last(); }
|
||||||
DrawSegment *ds_p = nullptr;
|
unsigned int EndIndex() const { return Segments.Size(); }
|
||||||
DrawSegment *drawsegs = nullptr;
|
DrawSegment *Segment(int index) const { return Segments[Segments.Size() - 1 - index]; }
|
||||||
|
|
||||||
TArray<size_t> InterestingDrawsegs; // drawsegs that have something drawn on them
|
unsigned int BeginInterestingIndex() const { return StartInterestingIndices.Last(); }
|
||||||
size_t FirstInterestingDrawseg = 0;
|
unsigned int EndInterestingIndex() const { return InterestingSegments.Size(); }
|
||||||
|
DrawSegment *InterestingSegment(int index) const { return InterestingSegments[Segments.Size() - 1 - index]; }
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void Deinit();
|
void PushPortal();
|
||||||
|
void PopPortal();
|
||||||
DrawSegment *Add();
|
void Push(DrawSegment *segment);
|
||||||
|
void PushInteresting(DrawSegment *segment);
|
||||||
|
|
||||||
private:
|
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
|
// Draw any masked textures behind this particle so that when the
|
||||||
// particle is drawn, it will be in front of them.
|
// particle is drawn, it will be in front of them.
|
||||||
DrawSegmentList *segmentlist = DrawSegmentList::Instance();
|
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
|
// kg3D - no fake segs
|
||||||
if (ds->fake) continue;
|
if (ds->fake) continue;
|
||||||
if (ds->x1 >= x2 || ds->x2 <= x1)
|
if (ds->x1 >= x2 || ds->x2 <= x1)
|
||||||
|
|
|
@ -47,7 +47,6 @@ namespace swrenderer
|
||||||
|
|
||||||
VisibleSprite *spr = this;
|
VisibleSprite *spr = this;
|
||||||
|
|
||||||
DrawSegment *ds;
|
|
||||||
int i;
|
int i;
|
||||||
int x1, x2;
|
int x1, x2;
|
||||||
int r1, r2;
|
int r1, r2;
|
||||||
|
@ -280,15 +279,11 @@ namespace swrenderer
|
||||||
// Scan drawsegs from end to start for obscuring segs.
|
// Scan drawsegs from end to start for obscuring segs.
|
||||||
// The first drawseg that is closer than the sprite is the clip seg.
|
// 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();
|
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
|
// [ZZ] portal handling here
|
||||||
//if (ds->CurrentPortalUniq != spr->CurrentPortalUniq)
|
//if (ds->CurrentPortalUniq != spr->CurrentPortalUniq)
|
||||||
// continue;
|
// continue;
|
||||||
|
|
Loading…
Reference in a new issue