From d8b808576fbe3b13d5d83380ba848ce28ced44f7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 3 May 2021 00:52:17 +0200 Subject: [PATCH] - restrict the sky portal shortcut to skies in scenes where there are no other portals. This entire setup does not work with sector portals, causing various render glitches in Shadow Warrior's portals. This also applies to skies within portals so it is now restricted to single sky setups. --- source/core/rendering/scene/hw_portal.cpp | 48 ++++------------------- source/core/rendering/scene/hw_portal.h | 1 - 2 files changed, 8 insertions(+), 41 deletions(-) diff --git a/source/core/rendering/scene/hw_portal.cpp b/source/core/rendering/scene/hw_portal.cpp index c4ea20cf002..1bce5d4e6c3 100644 --- a/source/core/rendering/scene/hw_portal.cpp +++ b/source/core/rendering/scene/hw_portal.cpp @@ -110,53 +110,21 @@ void FPortalSceneState::EndFrame(HWDrawInfo *di, FRenderState &state) //----------------------------------------------------------------------------- // -// Renders one sky portal without a stencil. -// In more complex scenes using a stencil for skies can severely stall -// the GPU and there's rarely more than one sky visible at a time. +// Renders one sky portal without a stencil. Only useful if this is the only portal in view. // //----------------------------------------------------------------------------- bool FPortalSceneState::RenderFirstSkyPortal(int recursion, HWDrawInfo *outer_di, FRenderState &state) { - HWPortal * p; - HWPortal * best = nullptr; + HWPortal* best = nullptr; unsigned bestindex = 0; - // Find the one with the highest amount of lines. - // Normally this is also the one that saves the largest amount - // of time by drawing it before the scene itself. - auto &portals = outer_di->Portals; - for (int i = portals.Size() - 1; i >= 0; --i) - { - p = portals[i]; - if (p->lines.Size() > 0 && p->IsSky()) - { - // Cannot clear the depth buffer inside a portal recursion - if (recursion && p->NeedDepthBuffer()) continue; - - if (!best || p->lines.Size() > best->lines.Size()) - { - best = p; - bestindex = i; - } + if (recursion > 0 || outer_di->Portals.Size() != 1 || !outer_di->Portals[0]->IsSky()) return false; - // If the portal area contains the current camera viewpoint, let's always use it because it's likely to give the largest area. - if (p->boundingBox.contains(outer_di->Viewpoint.Pos)) - { - best = p; - bestindex = i; - break; - } - } - } - - if (best) - { - portals.Delete(bestindex); - RenderPortal(best, state, false, outer_di); - delete best; - return true; - } - return false; + best = outer_di->Portals[0]; + outer_di->Portals.Clear(); + RenderPortal(best, state, false, outer_di); + delete best; + return true; } diff --git a/source/core/rendering/scene/hw_portal.h b/source/core/rendering/scene/hw_portal.h index b73632af515..77278edfbb4 100644 --- a/source/core/rendering/scene/hw_portal.h +++ b/source/core/rendering/scene/hw_portal.h @@ -352,7 +352,6 @@ struct HWSectorStackPortal : public HWScenePortalBase bool Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper) override; void Shutdown(HWDrawInfo *di, FRenderState &rstate) override; virtual void * GetSource() const { return origin; } - virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one. virtual const char *GetName(); virtual int GetType() { return PORTAL_SECTOR_CEILING; } PortalDesc *origin;