From d823ae255e90d266aefe0f0e948b332d41db233f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 6 Apr 2021 19:25:40 +0200 Subject: [PATCH] - fixed view clipping for portal sectors. All lines within the portal must neither be added to the clipper nor checked for obstruction by other parts of the map. --- .../core/rendering/scene/hw_bunchdrawer.cpp | 21 ++++++++++--------- source/core/rendering/scene/hw_bunchdrawer.h | 9 ++++---- source/core/rendering/scene/hw_drawinfo.cpp | 16 +++++++------- source/core/rendering/scene/hw_drawinfo.h | 4 ++-- source/core/rendering/scene/hw_portal.cpp | 7 ++++--- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/source/core/rendering/scene/hw_bunchdrawer.cpp b/source/core/rendering/scene/hw_bunchdrawer.cpp index 5f2572849..6c84a911c 100644 --- a/source/core/rendering/scene/hw_bunchdrawer.cpp +++ b/source/core/rendering/scene/hw_bunchdrawer.cpp @@ -91,7 +91,7 @@ void BunchDrawer::StartScene() // //========================================================================== -void BunchDrawer::StartBunch(int sectnum, int linenum, binangle startan, binangle endan) +void BunchDrawer::StartBunch(int sectnum, int linenum, binangle startan, binangle endan, bool portal) { FBunch* bunch = &Bunches[LastBunch = Bunches.Reserve(1)]; @@ -99,6 +99,7 @@ void BunchDrawer::StartBunch(int sectnum, int linenum, binangle startan, binangl bunch->startline = bunch->endline = linenum; bunch->startangle = startan; bunch->endangle = endan; + bunch->portal = portal; } //========================================================================== @@ -182,7 +183,7 @@ bool BunchDrawer::CheckClip(walltype* wal) // //========================================================================== -int BunchDrawer::ClipLine(int line) +int BunchDrawer::ClipLine(int line, bool portal) { auto wal = &wall[line]; @@ -195,7 +196,7 @@ int BunchDrawer::ClipLine(int line) return CL_Skip; } - if (!clipper->SafeCheckRange(startAngle, endAngle)) + if (!portal && !clipper->SafeCheckRange(startAngle, endAngle)) { return CL_Skip; } @@ -203,7 +204,7 @@ int BunchDrawer::ClipLine(int line) if (wal->nextwall == -1 || (wal->cstat & CSTAT_WALL_1WAY) || CheckClip(wal)) { // one-sided - clipper->SafeAddClipRange(startAngle, endAngle); + if (!portal) clipper->SafeAddClipRange(startAngle, endAngle); return CL_Draw; } else @@ -225,7 +226,7 @@ void BunchDrawer::ProcessBunch(int bnch) ClipWall.Clock(); for (int i = bunch->startline; i <= bunch->endline; i++) { - int clipped = ClipLine(i); + int clipped = ClipLine(i, bunch->portal); if (clipped & CL_Draw) { @@ -250,7 +251,7 @@ void BunchDrawer::ProcessBunch(int bnch) if (clipped & CL_Pass) { ClipWall.Unclock(); - ProcessSector(wall[i].nextsector); + ProcessSector(wall[i].nextsector, false); ClipWall.Clock(); } } @@ -425,7 +426,7 @@ int BunchDrawer::FindClosestBunch() // //========================================================================== -void BunchDrawer::ProcessSector(int sectnum) +void BunchDrawer::ProcessSector(int sectnum, bool portal) { if (gotsector[sectnum]) return; gotsector.Set(sectnum); @@ -503,7 +504,7 @@ void BunchDrawer::ProcessSector(int sectnum) // situation where 2 bunches may overlap at both ends. startangle = ang1; - StartBunch(sectnum, sect->wallptr + i, ang1, ang2); + StartBunch(sectnum, sect->wallptr + i, ang1, ang2, portal); inbunch = true; } else @@ -520,11 +521,11 @@ void BunchDrawer::ProcessSector(int sectnum) // //========================================================================== -void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount) +void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount, bool portal) { Bsp.Clock(); for(unsigned i=0;i 0) { int closest = FindClosestBunch(); diff --git a/source/core/rendering/scene/hw_bunchdrawer.h b/source/core/rendering/scene/hw_bunchdrawer.h index dbf5329eb..ae030bf3a 100644 --- a/source/core/rendering/scene/hw_bunchdrawer.h +++ b/source/core/rendering/scene/hw_bunchdrawer.h @@ -11,6 +11,7 @@ struct FBunch int sectnum; int startline; int endline; + bool portal; binangle startangle; // in pseudo angles for the clipper binangle endangle; }; @@ -38,19 +39,19 @@ private: }; void StartScene(); - void StartBunch(int sectnum, int linenum, binangle startan, binangle endan); + void StartBunch(int sectnum, int linenum, binangle startan, binangle endan, bool portal); void AddLineToBunch(int line, binangle newan); void DeleteBunch(int index); bool CheckClip(walltype* wal); - int ClipLine(int line); + int ClipLine(int line, bool portal); void ProcessBunch(int bnch); int WallInFront(int wall1, int wall2); int BunchInFront(FBunch* b1, FBunch* b2); int FindClosestBunch(); - void ProcessSector(int sectnum); + void ProcessSector(int sectnum, bool portal); public: void Init(HWDrawInfo* _di, Clipper* c, vec2_t& view); - void RenderScene(const int* viewsectors, unsigned sectcount); + void RenderScene(const int* viewsectors, unsigned sectcount, bool portal); const FixedBitArray& GotSector() const { return gotsector; } }; diff --git a/source/core/rendering/scene/hw_drawinfo.cpp b/source/core/rendering/scene/hw_drawinfo.cpp index 7f4a8d328..be7841bc0 100644 --- a/source/core/rendering/scene/hw_drawinfo.cpp +++ b/source/core/rendering/scene/hw_drawinfo.cpp @@ -364,7 +364,7 @@ void HWDrawInfo::DispatchSprites() // //----------------------------------------------------------------------------- -void HWDrawInfo::CreateScene() +void HWDrawInfo::CreateScene(bool portal) { const auto& vp = Viewpoint; @@ -387,9 +387,9 @@ void HWDrawInfo::CreateScene() vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) }; mDrawer.Init(this, mClipper, view); if (vp.SectNums) - mDrawer.RenderScene(vp.SectNums, vp.SectCount); + mDrawer.RenderScene(vp.SectNums, vp.SectCount, portal); else - mDrawer.RenderScene(&vp.SectCount, 1); + mDrawer.RenderScene(&vp.SectCount, 1, portal); SetupSprite.Clock(); gi->processSprites(tsprite, spritesortcnt, view.x, view.y, vp.Pos.Z * -256, bamang(vp.RotAngle), vp.TicFrac * 65536); @@ -422,7 +422,7 @@ void HWDrawInfo::CreateScene() mClipper->Clear(); mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1)); mDrawer.Init(this, mClipper, view); - mDrawer.RenderScene(&drawsect, 1); + mDrawer.RenderScene(&drawsect, 1, false); for (int i = 0; i < eff.geocnt; i++) { @@ -453,7 +453,7 @@ void HWDrawInfo::CreateScene() mClipper->Clear(); mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1)); mDrawer.Init(this, mClipper, view); - mDrawer.RenderScene(&drawsect, 1); + mDrawer.RenderScene(&drawsect, 1, false); for (int i = 0; i < eff.geocnt; i++) { @@ -670,7 +670,7 @@ void HWDrawInfo::Set3DViewport(FRenderState &state) // //----------------------------------------------------------------------------- -void HWDrawInfo::DrawScene(int drawmode) +void HWDrawInfo::DrawScene(int drawmode, bool portal) { static int recursion = 0; static int ssao_portals_available = 0; @@ -692,7 +692,7 @@ void HWDrawInfo::DrawScene(int drawmode) ssao_portals_available--; } - CreateScene(); + CreateScene(portal); auto& RenderState = *screen->RenderState(); RenderState.SetDepthMask(true); @@ -725,7 +725,7 @@ void HWDrawInfo::DrawScene(int drawmode) void HWDrawInfo::ProcessScene(bool toscreen) { portalState.BeginScene(); - DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN); + DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN, false); if (toscreen && isBlood()) { gotsector = mDrawer.GotSector(); // Blood needs this to implement some lighting effect hacks. Needs to be refactored to use better info. diff --git a/source/core/rendering/scene/hw_drawinfo.h b/source/core/rendering/scene/hw_drawinfo.h index dc223ed21..9e7995f0a 100644 --- a/source/core/rendering/scene/hw_drawinfo.h +++ b/source/core/rendering/scene/hw_drawinfo.h @@ -158,8 +158,8 @@ public: void ClearBuffers(); HWDrawInfo *EndDrawInfo(); - void DrawScene(int drawmode); - void CreateScene(); + void DrawScene(int drawmode, bool portal); + void CreateScene(bool portal); void DispatchSprites(); void RenderScene(FRenderState &state); void RenderTranslucent(FRenderState &state); diff --git a/source/core/rendering/scene/hw_portal.cpp b/source/core/rendering/scene/hw_portal.cpp index 5d97679ba..016725636 100644 --- a/source/core/rendering/scene/hw_portal.cpp +++ b/source/core/rendering/scene/hw_portal.cpp @@ -400,9 +400,10 @@ void HWScenePortalBase::DrawContents(HWDrawInfo* di, FRenderState& state) { if (Setup(di, state, di->mClipper)) { - gi->EnterPortal(di->Viewpoint.CameraSprite, GetType()); - di->DrawScene(DM_PORTAL); - gi->LeavePortal(di->Viewpoint.CameraSprite, GetType()); + auto type = GetType(); + gi->EnterPortal(di->Viewpoint.CameraSprite, type); + di->DrawScene(DM_PORTAL, type == PORTAL_SECTOR_CEILING); + gi->LeavePortal(di->Viewpoint.CameraSprite, type); Shutdown(di, state); } else state.ClearScreen();