From 864358389e5face04f25e00b87dc49b8012065ff Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 25 Nov 2016 18:15:48 +0100 Subject: [PATCH] Implement portal recursion limit --- src/r_poly.cpp | 4 +- src/r_poly_portal.cpp | 112 ++++++++++++++++++++---------------------- src/r_poly_portal.h | 12 ++--- 3 files changed, 60 insertions(+), 68 deletions(-) diff --git a/src/r_poly.cpp b/src/r_poly.cpp index 13ecd2625..729774174 100644 --- a/src/r_poly.cpp +++ b/src/r_poly.cpp @@ -45,9 +45,9 @@ void RenderPolyScene::Render() SetSceneViewport(); SetupPerspectiveMatrix(); MainPortal.SetViewpoint(WorldToClip, GetNextStencilValue()); - MainPortal.Render(); + MainPortal.Render(0); Skydome.Render(WorldToClip); - MainPortal.RenderTranslucent(); + MainPortal.RenderTranslucent(0); PlayerSprites.Render(); DrawerCommandQueue::WaitForWorkers(); diff --git a/src/r_poly_portal.cpp b/src/r_poly_portal.cpp index 4f42ab77e..0346a9d7d 100644 --- a/src/r_poly_portal.cpp +++ b/src/r_poly_portal.cpp @@ -48,15 +48,18 @@ void RenderPolyPortal::SetViewpoint(const TriMatrix &worldToClip, uint32_t stenc StencilValue = stencilValue; } -void RenderPolyPortal::Render() +void RenderPolyPortal::Render(int portalDepth) { ClearBuffers(); Cull.CullScene(WorldToClip); RenderSectors(); - for (auto &portal : SectorPortals) - portal->Render(); - for (auto &portal : LinePortals) - portal->Render(); + if (portalDepth < r_portal_recursions) + { + for (auto &portal : SectorPortals) + portal->Render(portalDepth + 1); + for (auto &portal : LinePortals) + portal->Render(portalDepth + 1); + } } void RenderPolyPortal::ClearBuffers() @@ -189,45 +192,48 @@ void RenderPolyPortal::RenderLine(subsector_t *sub, seg_t *line, sector_t *front } } -void RenderPolyPortal::RenderTranslucent() +void RenderPolyPortal::RenderTranslucent(int portalDepth) { - for (auto it = SectorPortals.rbegin(); it != SectorPortals.rend(); ++it) + if (portalDepth < r_portal_recursions) { - auto &portal = *it; - portal->RenderTranslucent(); - - PolyDrawArgs args; - args.objectToClip = &WorldToClip; - args.mode = TriangleDrawMode::Fan; - args.stenciltestvalue = portal->StencilValue + 1; - args.stencilwritevalue = StencilValue; - for (const auto &verts : portal->Shape) + for (auto it = SectorPortals.rbegin(); it != SectorPortals.rend(); ++it) { - args.vinput = verts.Vertices; - args.vcount = verts.Count; - args.ccw = verts.Ccw; - args.uniforms.subsectorDepth = verts.SubsectorDepth; - PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy); + auto &portal = *it; + portal->RenderTranslucent(portalDepth + 1); + + PolyDrawArgs args; + args.objectToClip = &WorldToClip; + args.mode = TriangleDrawMode::Fan; + args.stenciltestvalue = portal->StencilValue + 1; + args.stencilwritevalue = StencilValue; + for (const auto &verts : portal->Shape) + { + args.vinput = verts.Vertices; + args.vcount = verts.Count; + args.ccw = verts.Ccw; + args.uniforms.subsectorDepth = verts.SubsectorDepth; + PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy); + } } - } - for (auto it = LinePortals.rbegin(); it != LinePortals.rend(); ++it) - { - auto &portal = *it; - portal->RenderTranslucent(); - - PolyDrawArgs args; - args.objectToClip = &WorldToClip; - args.mode = TriangleDrawMode::Fan; - args.stenciltestvalue = portal->StencilValue + 1; - args.stencilwritevalue = StencilValue; - for (const auto &verts : portal->Shape) + for (auto it = LinePortals.rbegin(); it != LinePortals.rend(); ++it) { - args.vinput = verts.Vertices; - args.vcount = verts.Count; - args.ccw = verts.Ccw; - args.uniforms.subsectorDepth = verts.SubsectorDepth; - PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy); + auto &portal = *it; + portal->RenderTranslucent(portalDepth + 1); + + PolyDrawArgs args; + args.objectToClip = &WorldToClip; + args.mode = TriangleDrawMode::Fan; + args.stenciltestvalue = portal->StencilValue + 1; + args.stencilwritevalue = StencilValue; + for (const auto &verts : portal->Shape) + { + args.vinput = verts.Vertices; + args.vcount = verts.Count; + args.ccw = verts.Ccw; + args.uniforms.subsectorDepth = verts.SubsectorDepth; + PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy); + } } } @@ -263,16 +269,11 @@ PolyDrawSectorPortal::PolyDrawSectorPortal(FSectorPortal *portal, bool ceiling) StencilValue = RenderPolyScene::Instance()->GetNextStencilValue(); } -void PolyDrawSectorPortal::Render() +void PolyDrawSectorPortal::Render(int portalDepth) { if (Portal->mType != PORTS_SKYVIEWPOINT) return; - static int recursion = 0; - if (recursion >= 1/*r_portal_recursions*/) - return; - recursion++; - SaveGlobals(); // To do: get this information from RenderPolyScene instead of duplicating the code.. @@ -294,26 +295,17 @@ void PolyDrawSectorPortal::Render() TriMatrix worldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView; RenderPortal.SetViewpoint(worldToClip, StencilValue); - RenderPortal.Render(); + RenderPortal.Render(portalDepth); RestoreGlobals(); - - recursion--; } -void PolyDrawSectorPortal::RenderTranslucent() +void PolyDrawSectorPortal::RenderTranslucent(int portalDepth) { if (Portal->mType != PORTS_SKYVIEWPOINT) return; - static int recursion = 0; - if (recursion >= 1/*r_portal_recursions*/) - return; - recursion++; - - RenderPortal.RenderTranslucent(); - - recursion--; + RenderPortal.RenderTranslucent(portalDepth); } void PolyDrawSectorPortal::SaveGlobals() @@ -357,12 +349,12 @@ PolyDrawLinePortal::PolyDrawLinePortal(line_t *src, line_t *dest, bool mirror) : StencilValue = RenderPolyScene::Instance()->GetNextStencilValue(); } -void PolyDrawLinePortal::Render() +void PolyDrawLinePortal::Render(int portalDepth) { - RenderPortal.Render(); + RenderPortal.Render(portalDepth); } -void PolyDrawLinePortal::RenderTranslucent() +void PolyDrawLinePortal::RenderTranslucent(int portalDepth) { - RenderPortal.RenderTranslucent(); + RenderPortal.RenderTranslucent(portalDepth); } diff --git a/src/r_poly_portal.h b/src/r_poly_portal.h index b910034a2..a53a185e3 100644 --- a/src/r_poly_portal.h +++ b/src/r_poly_portal.h @@ -84,8 +84,8 @@ public: RenderPolyPortal(); ~RenderPolyPortal(); void SetViewpoint(const TriMatrix &worldToClip, uint32_t stencilValue); - void Render(); - void RenderTranslucent(); + void Render(int portalDepth); + void RenderTranslucent(int portalDepth); static const uint32_t SkySubsectorDepth = 0x7fffffff; @@ -124,8 +124,8 @@ class PolyDrawSectorPortal public: PolyDrawSectorPortal(FSectorPortal *portal, bool ceiling); - void Render(); - void RenderTranslucent(); + void Render(int portalDepth); + void RenderTranslucent(int portalDepth); FSectorPortal *Portal; uint32_t StencilValue = 0; @@ -151,8 +151,8 @@ class PolyDrawLinePortal public: PolyDrawLinePortal(line_t *src, line_t *dest, bool mirror); - void Render(); - void RenderTranslucent(); + void Render(int portalDepth); + void RenderTranslucent(int portalDepth); uint32_t StencilValue = 0; std::vector Shape;