From e19c8eba62b10b76cbf5d038109f6ff1044a9ac2 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 1 Jul 2017 23:55:41 +0200 Subject: [PATCH] - 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 --- src/swrenderer/line/r_line.cpp | 4 +- src/swrenderer/scene/r_translucent_pass.cpp | 26 -------- src/swrenderer/segments/r_drawsegment.cpp | 16 ++--- src/swrenderer/segments/r_drawsegment.h | 11 ++-- src/swrenderer/things/r_particle.cpp | 6 +- src/swrenderer/things/r_visiblesprite.cpp | 71 +++++++++++---------- 6 files changed, 56 insertions(+), 78 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 5c3d2c124..2c810572e 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -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); } } } diff --git a/src/swrenderer/scene/r_translucent_pass.cpp b/src/swrenderer/scene/r_translucent_pass.cpp index b395e0b6d..19718dafa 100644 --- a/src/swrenderer/scene/r_translucent_pass.cpp +++ b/src/swrenderer/scene/r_translucent_pass.cpp @@ -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); diff --git a/src/swrenderer/segments/r_drawsegment.cpp b/src/swrenderer/segments/r_drawsegment.cpp index 6d8d50707..72abbc343 100644 --- a/src/swrenderer/segments/r_drawsegment.cpp +++ b/src/swrenderer/segments/r_drawsegment.cpp @@ -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() diff --git a/src/swrenderer/segments/r_drawsegment.h b/src/swrenderer/segments/r_drawsegment.h index 2c6fcdaa7..7c685f080 100644 --- a/src/swrenderer/segments/r_drawsegment.h +++ b/src/swrenderer/segments/r_drawsegment.h @@ -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 Segments; TArray StartIndices; - TArray InterestingSegments; // drawsegs that have something drawn on them - TArray StartInterestingIndices; + TArray TranslucentSegments; // drawsegs that have something drawn on them + TArray StartTranslucentIndices; // For building segment groups short cliptop[MAXWIDTH]; diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index fee9a39c0..33d2a6d09 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -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; diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index f7ae8547b..08e99b637 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -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(ds->x1, x1); + int r2 = MIN(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(group.x1, x1); - r2 = MIN(group.x2, x2); + int r1 = MAX(group.x1, x1); + int r2 = MIN(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(ds->x1, x1); - r2 = MIN(ds->x2, x2); + int r1 = MAX(ds->x1, x1); + int r2 = MIN(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; }