From 4d671fb6184bbe83aa51977ac67756a5ed17d694 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 10 Sep 2017 16:29:57 +0200 Subject: [PATCH] - Improve softpoly culling performance --- src/polyrenderer/scene/poly_cull.cpp | 33 +++++++++++++++++++-------- src/polyrenderer/scene/poly_cull.h | 6 +++-- src/polyrenderer/scene/poly_scene.cpp | 10 ++++---- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/polyrenderer/scene/poly_cull.cpp b/src/polyrenderer/scene/poly_cull.cpp index 93041650d..c39eb66cc 100644 --- a/src/polyrenderer/scene/poly_cull.cpp +++ b/src/polyrenderer/scene/poly_cull.cpp @@ -33,11 +33,21 @@ void PolyCull::CullScene(const TriMatrix &worldToClip, const PolyClipPlane &port ClearSolidSegments(); MarkViewFrustum(); + for (const auto &sub : PvsSectors) + SubsectorDepths[sub->Index()] = 0xffffffff; + SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff); + + for (const auto §or : SeenSectors) + SectorSeen[sector->Index()] = false; + SectorSeen.resize(level.sectors.Size()); + PvsSectors.clear(); - PvsLineStart.clear(); - PvsLineVisible.clear(); SeenSectors.clear(); - SubsectorDepths.clear(); + + NextPvsLineStart = 0; + PvsLineStart.clear(); + PvsLineVisible.resize(level.segs.Size()); + PortalClipPlane = portalClipPlane; // Cull front to back @@ -108,7 +118,7 @@ void PolyCull::CullSubsector(subsector_t *sub) // Mark that we need to render this PvsSectors.push_back(sub); - PvsLineStart.push_back((uint32_t)PvsLineVisible.size()); + PvsLineStart.push_back(NextPvsLineStart); DVector3 viewpos = PolyRenderer::Instance()->Viewpoint.Pos; @@ -122,7 +132,7 @@ void PolyCull::CullSubsector(subsector_t *sub) DVector2 pt2 = line->v2->fPos() - viewpos; if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0) { - PvsLineVisible.push_back(false); + PvsLineVisible[NextPvsLineStart++] = false; continue; } @@ -130,7 +140,7 @@ void PolyCull::CullSubsector(subsector_t *sub) if ((PortalClipPlane.A * line->v1->fX() + PortalClipPlane.B * line->v1->fY() + PortalClipPlane.D <= 0.0) || (PortalClipPlane.A * line->v2->fX() + PortalClipPlane.B * line->v2->fY() + PortalClipPlane.D <= 0.0)) { - PvsLineVisible.push_back(false); + PvsLineVisible[NextPvsLineStart++] = false; continue; } @@ -142,11 +152,16 @@ void PolyCull::CullSubsector(subsector_t *sub) } // Mark if this line was visible - PvsLineVisible.push_back(lineVisible); + PvsLineVisible[NextPvsLineStart++] = lineVisible; } - SeenSectors.insert(sub->sector); - SubsectorDepths[sub] = subsectorDepth; + if (!SectorSeen[sub->sector->Index()]) + { + SectorSeen[sub->sector->Index()] = true; + SeenSectors.push_back(sub->sector); + } + + SubsectorDepths[sub->Index()] = subsectorDepth; } void PolyCull::ClearSolidSegments() diff --git a/src/polyrenderer/scene/poly_cull.h b/src/polyrenderer/scene/poly_cull.h index 29c47134d..549f4c375 100644 --- a/src/polyrenderer/scene/poly_cull.h +++ b/src/polyrenderer/scene/poly_cull.h @@ -40,8 +40,9 @@ public: double MaxCeilingHeight = 0.0; double MinFloorHeight = 0.0; - std::set SeenSectors; - std::unordered_map SubsectorDepths; + std::vector SeenSectors; + std::vector SectorSeen; + std::vector SubsectorDepths; static angle_t PointToPseudoAngle(double x, double y); @@ -78,6 +79,7 @@ private: std::vector PvsLineStart; std::vector PvsLineVisible; + uint32_t NextPvsLineStart = 0; static angle_t AngleToPseudo(angle_t ang); }; diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index d315a02e5..6f84c2d4f 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -213,9 +213,8 @@ void RenderPolyScene::RenderSprite(PolyRenderThread *thread, AActor *thing, doub if (level.nodes.Size() == 0) { subsector_t *sub = &level.subsectors[0]; - auto it = Cull.SubsectorDepths.find(sub); - if (it != Cull.SubsectorDepths.end()) - TranslucentObjects[thread->ThreadIndex].push_back(thread->FrameMemory->NewObject(thing, sub, it->second, sortDistance, 0.0f, 1.0f, StencilValue)); + if (Cull.SubsectorDepths[sub->Index()] != 0xffffffff) + TranslucentObjects[thread->ThreadIndex].push_back(thread->FrameMemory->NewObject(thing, sub, Cull.SubsectorDepths[sub->Index()], sortDistance, 0.0f, 1.0f, StencilValue)); } else { @@ -254,9 +253,8 @@ void RenderPolyScene::RenderSprite(PolyRenderThread *thread, AActor *thing, doub subsector_t *sub = (subsector_t *)((uint8_t *)node - 1); - auto it = Cull.SubsectorDepths.find(sub); - if (it != Cull.SubsectorDepths.end()) - TranslucentObjects[thread->ThreadIndex].push_back(thread->FrameMemory->NewObject(thing, sub, it->second, sortDistance, (float)t1, (float)t2, StencilValue)); + if (Cull.SubsectorDepths[sub->Index()] != 0xffffffff) + TranslucentObjects[thread->ThreadIndex].push_back(thread->FrameMemory->NewObject(thing, sub, Cull.SubsectorDepths[sub->Index()], sortDistance, (float)t1, (float)t2, StencilValue)); } void RenderPolyScene::RenderLine(PolyRenderThread *thread, subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth)