- Switch sprite drawing to use the interesting draw segments list

- Stop adding 3D floor "fake" draw segments to the interesting segments list
- Rename InterestingSegments list to TranslucentSegments
This commit is contained in:
Magnus Norddahl 2017-07-01 23:55:41 +02:00
parent 5a761dd3c3
commit e19c8eba62
6 changed files with 56 additions and 78 deletions

View file

@ -508,9 +508,9 @@ namespace swrenderer
draw_segment->shade = LightVisibility::LightLevelToShade(mLineSegment->sidedef->GetLightLevel(foggy, mLineSegment->frontsector->lightlevel) + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy);
}
if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr)
if ((draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr) && !draw_segment->fake)
{
Thread->DrawSegments->PushInteresting(draw_segment);
Thread->DrawSegments->PushTranslucent(draw_segment);
}
}
}

View file

@ -136,37 +136,11 @@ namespace swrenderer
RenderPortal *renderportal = Thread->Portal.get();
DrawSegmentList *drawseglist = Thread->DrawSegments.get();
int numGroups = drawseglist->SegmentGroups.Size();
for (int j = 0; j < numGroups; j++)
drawseglist->SegmentGroups[j].GroupDrawn = false;
auto &sortedSprites = Thread->SpriteList->SortedSprites;
for (int i = sortedSprites.Size(); i > 0; i--)
{
VisibleSprite *sprite = sortedSprites[i - 1];
// Draw the draw segments known to be behind us now.
for (int j = numGroups; j > 0; j--)
{
auto &group = drawseglist->SegmentGroups[j - 1];
if (!group.GroupDrawn && group.neardepth > sprite->DrawSegDepth())
{
for (unsigned int index = group.BeginIndex; index != group.EndIndex; index++)
{
DrawSegment *ds = drawseglist->Segment(index);
if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq) continue;
if (ds->fake) continue;
if (ds->maskedtexturecol != nullptr || ds->bFogBoundary)
{
RenderDrawSegment renderer(Thread);
renderer.Render(ds, ds->x1, ds->x2);
}
}
group.GroupDrawn = true;
}
}
if (sprite->IsCurrentPortalUniq(renderportal->CurrentPortalUniq))
{
sprite->Render(Thread);

View file

@ -63,15 +63,15 @@ namespace swrenderer
StartIndices.Clear();
StartIndices.Push(0);
InterestingSegments.Clear();
StartInterestingIndices.Clear();
StartInterestingIndices.Push(0);
TranslucentSegments.Clear();
StartTranslucentIndices.Clear();
StartTranslucentIndices.Push(0);
}
void DrawSegmentList::PushPortal()
{
StartIndices.Push(Segments.Size());
StartInterestingIndices.Push(InterestingSegments.Size());
StartTranslucentIndices.Push(TranslucentSegments.Size());
}
void DrawSegmentList::PopPortal()
@ -79,8 +79,8 @@ namespace swrenderer
Segments.Resize(StartIndices.Last());
StartIndices.Pop();
InterestingSegments.Resize(StartInterestingIndices.Last());
StartInterestingIndices.Pop();
TranslucentSegments.Resize(StartTranslucentIndices.Last());
StartTranslucentIndices.Pop();
}
void DrawSegmentList::Push(DrawSegment *segment)
@ -88,9 +88,9 @@ namespace swrenderer
Segments.Push(segment);
}
void DrawSegmentList::PushInteresting(DrawSegment *segment)
void DrawSegmentList::PushTranslucent(DrawSegment *segment)
{
InterestingSegments.Push(segment);
TranslucentSegments.Push(segment);
}
void DrawSegmentList::BuildSegmentGroups()

View file

@ -63,7 +63,6 @@ namespace swrenderer
short *sprbottomclip;
unsigned int BeginIndex;
unsigned int EndIndex;
bool GroupDrawn;
};
class DrawSegmentList
@ -76,14 +75,14 @@ namespace swrenderer
unsigned int SegmentsCount() const { return Segments.Size() - StartIndices.Last(); }
DrawSegment *Segment(unsigned int index) const { return Segments[Segments.Size() - 1 - index]; }
unsigned int InterestingSegmentsCount() const { return InterestingSegments.Size() - StartInterestingIndices.Last(); }
DrawSegment *InterestingSegment(unsigned int index) const { return InterestingSegments[InterestingSegments.Size() - 1 - index]; }
unsigned int TranslucentSegmentsCount() const { return TranslucentSegments.Size() - StartTranslucentIndices.Last(); }
DrawSegment *TranslucentSegment(unsigned int index) const { return TranslucentSegments[TranslucentSegments.Size() - 1 - index]; }
void Clear();
void PushPortal();
void PopPortal();
void Push(DrawSegment *segment);
void PushInteresting(DrawSegment *segment);
void PushTranslucent(DrawSegment *segment);
void BuildSegmentGroups();
@ -93,8 +92,8 @@ namespace swrenderer
TArray<DrawSegment *> Segments;
TArray<unsigned int> StartIndices;
TArray<DrawSegment *> InterestingSegments; // drawsegs that have something drawn on them
TArray<unsigned int> StartInterestingIndices;
TArray<DrawSegment *> TranslucentSegments; // drawsegs that have something drawn on them
TArray<unsigned int> StartTranslucentIndices;
// For building segment groups
short cliptop[MAXWIDTH];

View file

@ -275,12 +275,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 = thread->DrawSegments.get();
for (unsigned int index = 0; index != segmentlist->InterestingSegmentsCount(); index++)
for (unsigned int index = 0; index != segmentlist->TranslucentSegmentsCount(); index++)
{
DrawSegment *ds = segmentlist->InterestingSegment(index);
DrawSegment *ds = segmentlist->TranslucentSegment(index);
// kg3D - no fake segs
if (ds->fake) continue;
if (ds->x1 >= x2 || ds->x2 <= x1)
{
continue;

View file

@ -58,7 +58,6 @@ namespace swrenderer
int i;
int x1, x2;
int r1, r2;
short topclip, botclip;
short *clip1, *clip2;
FSWColormap *colormap = spr->Light.BaseColormap;
@ -293,16 +292,48 @@ namespace swrenderer
// The first drawseg that is closer than the sprite is the clip seg.
DrawSegmentList *segmentlist = thread->DrawSegments.get();
RenderPortal *renderportal = thread->Portal.get();
// Render draw segments behind sprite
for (unsigned int index = 0; index != segmentlist->TranslucentSegmentsCount(); index++)
{
DrawSegment *ds = segmentlist->TranslucentSegment(index);
if (ds->x1 >= x2 || ds->x2 <= x1)
{
continue;
}
float neardepth = MIN(ds->sz1, ds->sz2);
float fardepth = MAX(ds->sz1, ds->sz2);
// Check if sprite is in front of draw seg:
if ((!spr->IsWallSprite() && neardepth > spr->depth) || ((spr->IsWallSprite() || fardepth > spr->depth) &&
(spr->gpos.Y - ds->curline->v1->fY()) * (ds->curline->v2->fX() - ds->curline->v1->fX()) -
(spr->gpos.X - ds->curline->v1->fX()) * (ds->curline->v2->fY() - ds->curline->v1->fY()) <= 0))
{
if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq)
{
int r1 = MAX<int>(ds->x1, x1);
int r2 = MIN<int>(ds->x2, x2);
RenderDrawSegment renderer(thread);
renderer.Render(ds, r1, r2);
}
}
}
for (unsigned int groupIndex = 0; groupIndex < segmentlist->SegmentGroups.Size(); groupIndex++)
{
auto &group = segmentlist->SegmentGroups[groupIndex];
if (group.x1 >= x2 || group.x2 <= x1 || group.neardepth > spr->depth)
continue;
if (group.fardepth < spr->depth)
{
r1 = MAX<int>(group.x1, x1);
r2 = MIN<int>(group.x2, x2);
int r1 = MAX<int>(group.x1, x1);
int r2 = MIN<int>(group.x2, x2);
// Clip bottom
clip1 = clipbot + r1;
@ -330,7 +361,6 @@ namespace swrenderer
}
else
{
//for (unsigned int index = segmentlist->BeginIndex(); index != segmentlist->EndIndex(); index++)
for (unsigned int index = group.BeginIndex; index != group.EndIndex; index++)
{
DrawSegment *ds = segmentlist->Segment(index);
@ -346,41 +376,18 @@ namespace swrenderer
continue;
}
r1 = MAX<int>(ds->x1, x1);
r2 = MIN<int>(ds->x2, x2);
int r1 = MAX<int>(ds->x1, x1);
int r2 = MIN<int>(ds->x2, x2);
float neardepth, fardepth;
if (!spr->IsWallSprite())
{
if (ds->sz1 < ds->sz2)
{
neardepth = ds->sz1, fardepth = ds->sz2;
}
else
{
neardepth = ds->sz2, fardepth = ds->sz1;
}
}
else
{
// GCC complained about this case, is there something missing here?
fardepth = neardepth = 0;
}
float neardepth = MIN(ds->sz1, ds->sz2);
float fardepth = MAX(ds->sz1, ds->sz2);
// Check if sprite is in front of draw seg:
if ((!spr->IsWallSprite() && neardepth > spr->depth) || ((spr->IsWallSprite() || fardepth > spr->depth) &&
(spr->gpos.Y - ds->curline->v1->fY()) * (ds->curline->v2->fX() - ds->curline->v1->fX()) -
(spr->gpos.X - ds->curline->v1->fX()) * (ds->curline->v2->fY() - ds->curline->v1->fY()) <= 0))
{
RenderPortal *renderportal = thread->Portal.get();
// seg is behind sprite, so draw the mid texture if it has one
if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && (ds->maskedtexturecol != nullptr || ds->bFogBoundary))
{
RenderDrawSegment renderer(thread);
renderer.Render(ds, r1, r2);
}
// seg is behind sprite
continue;
}