From 42fedd0f4c00bd30075d9a992a5790c6b99834b7 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 1 Jul 2017 03:31:06 +0200 Subject: [PATCH] - Improve sprite performance when there are many draw segments --- src/swrenderer/scene/r_translucent_pass.cpp | 34 +++++++++++++++++++-- src/swrenderer/segments/r_drawsegment.h | 1 + src/swrenderer/things/r_visiblesprite.cpp | 10 ++---- src/swrenderer/things/r_visiblesprite.h | 2 ++ 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/swrenderer/scene/r_translucent_pass.cpp b/src/swrenderer/scene/r_translucent_pass.cpp index 905974571..b395e0b6d 100644 --- a/src/swrenderer/scene/r_translucent_pass.cpp +++ b/src/swrenderer/scene/r_translucent_pass.cpp @@ -134,13 +134,42 @@ namespace swrenderer void RenderTranslucentPass::DrawMaskedSingle(bool renew) { 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--) { - if (sortedSprites[i - 1]->IsCurrentPortalUniq(renderportal->CurrentPortalUniq)) + VisibleSprite *sprite = sortedSprites[i - 1]; + + // Draw the draw segments known to be behind us now. + for (int j = numGroups; j > 0; j--) { - sortedSprites[i - 1]->Render(Thread); + 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); } } @@ -151,7 +180,6 @@ namespace swrenderer Thread->Clip3D->fake3D |= FAKE3D_REFRESHCLIP; } - DrawSegmentList *drawseglist = Thread->DrawSegments.get(); for (unsigned int index = 0; index != drawseglist->SegmentsCount(); index++) { DrawSegment *ds = drawseglist->Segment(index); diff --git a/src/swrenderer/segments/r_drawsegment.h b/src/swrenderer/segments/r_drawsegment.h index 5480ac4f2..2c6fcdaa7 100644 --- a/src/swrenderer/segments/r_drawsegment.h +++ b/src/swrenderer/segments/r_drawsegment.h @@ -63,6 +63,7 @@ namespace swrenderer short *sprbottomclip; unsigned int BeginIndex; unsigned int EndIndex; + bool GroupDrawn; }; class DrawSegmentList diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index 26a5d76be..f7ae8547b 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -296,7 +296,7 @@ namespace swrenderer for (unsigned int groupIndex = 0; groupIndex < segmentlist->SegmentGroups.Size(); groupIndex++) { auto &group = segmentlist->SegmentGroups[groupIndex]; - if (group.x1 >= x2 || group.x2 <= x1) + if (group.x1 >= x2 || group.x2 <= x1 || group.neardepth > spr->depth) continue; if (group.fardepth < spr->depth) @@ -335,11 +335,6 @@ namespace swrenderer { DrawSegment *ds = segmentlist->Segment(index); - // [ZZ] portal handling here - //if (ds->CurrentPortalUniq != spr->CurrentPortalUniq) - // continue; - // [ZZ] WARNING: uncommenting the two above lines, totally breaks sprite clipping - // kg3D - no clipping on fake segs if (ds->fake) continue; // determine if the drawseg obscures the sprite @@ -380,8 +375,7 @@ namespace swrenderer RenderPortal *renderportal = thread->Portal.get(); // seg is behind sprite, so draw the mid texture if it has one - if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here - (ds->maskedtexturecol != nullptr || ds->bFogBoundary)) + if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && (ds->maskedtexturecol != nullptr || ds->bFogBoundary)) { RenderDrawSegment renderer(thread); renderer.Render(ds, r1, r2); diff --git a/src/swrenderer/things/r_visiblesprite.h b/src/swrenderer/things/r_visiblesprite.h index f9490472c..f31d08b58 100644 --- a/src/swrenderer/things/r_visiblesprite.h +++ b/src/swrenderer/things/r_visiblesprite.h @@ -46,6 +46,8 @@ namespace swrenderer double SortDist2D() const { return DVector2(deltax, deltay).LengthSquared(); } float SortDist() const { return idepth; } + float DrawSegDepth() const { return depth; } + protected: virtual bool IsParticle() const { return false; } virtual bool IsVoxel() const { return false; }