- 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); 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(); RenderPortal *renderportal = Thread->Portal.get();
DrawSegmentList *drawseglist = Thread->DrawSegments.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; auto &sortedSprites = Thread->SpriteList->SortedSprites;
for (int i = sortedSprites.Size(); i > 0; i--) for (int i = sortedSprites.Size(); i > 0; i--)
{ {
VisibleSprite *sprite = sortedSprites[i - 1]; 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)) if (sprite->IsCurrentPortalUniq(renderportal->CurrentPortalUniq))
{ {
sprite->Render(Thread); sprite->Render(Thread);

View File

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

View File

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

View File

@ -275,12 +275,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 = thread->DrawSegments.get(); 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) if (ds->x1 >= x2 || ds->x2 <= x1)
{ {
continue; continue;

View File

@ -58,7 +58,6 @@ namespace swrenderer
int i; int i;
int x1, x2; int x1, x2;
int r1, r2;
short topclip, botclip; short topclip, botclip;
short *clip1, *clip2; short *clip1, *clip2;
FSWColormap *colormap = spr->Light.BaseColormap; FSWColormap *colormap = spr->Light.BaseColormap;
@ -293,16 +292,48 @@ namespace swrenderer
// 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.
DrawSegmentList *segmentlist = thread->DrawSegments.get(); 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++) for (unsigned int groupIndex = 0; groupIndex < segmentlist->SegmentGroups.Size(); groupIndex++)
{ {
auto &group = segmentlist->SegmentGroups[groupIndex]; auto &group = segmentlist->SegmentGroups[groupIndex];
if (group.x1 >= x2 || group.x2 <= x1 || group.neardepth > spr->depth) if (group.x1 >= x2 || group.x2 <= x1 || group.neardepth > spr->depth)
continue; continue;
if (group.fardepth < spr->depth) if (group.fardepth < spr->depth)
{ {
r1 = MAX<int>(group.x1, x1); int r1 = MAX<int>(group.x1, x1);
r2 = MIN<int>(group.x2, x2); int r2 = MIN<int>(group.x2, x2);
// Clip bottom // Clip bottom
clip1 = clipbot + r1; clip1 = clipbot + r1;
@ -330,7 +361,6 @@ namespace swrenderer
} }
else else
{ {
//for (unsigned int index = segmentlist->BeginIndex(); index != segmentlist->EndIndex(); index++)
for (unsigned int index = group.BeginIndex; index != group.EndIndex; index++) for (unsigned int index = group.BeginIndex; index != group.EndIndex; index++)
{ {
DrawSegment *ds = segmentlist->Segment(index); DrawSegment *ds = segmentlist->Segment(index);
@ -346,41 +376,18 @@ namespace swrenderer
continue; continue;
} }
r1 = MAX<int>(ds->x1, x1); int r1 = MAX<int>(ds->x1, x1);
r2 = MIN<int>(ds->x2, x2); int r2 = MIN<int>(ds->x2, x2);
float neardepth, fardepth; float neardepth = MIN(ds->sz1, ds->sz2);
if (!spr->IsWallSprite()) float fardepth = MAX(ds->sz1, ds->sz2);
{
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;
}
// Check if sprite is in front of draw seg: // Check if sprite is in front of draw seg:
if ((!spr->IsWallSprite() && neardepth > spr->depth) || ((spr->IsWallSprite() || fardepth > spr->depth) && 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.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)) (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
// 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);
}
continue; continue;
} }