diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index 9e1afdc71b..9182c5f0a1 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -333,19 +333,12 @@ void TriangleBlock::RenderBlock(int x0, int y0, int x1, int y1) if (Mask0 == 0 && Mask1 == 0) continue; - // To do: make the stencil test use its own flag for comparison mode instead of abusing the depth test.. - if (!depthTest) - { - StencilEqualTest(); - if (Mask0 == 0 && Mask1 == 0) - continue; - } - else - { - StencilGreaterEqualTest(); - if (Mask0 == 0 && Mask1 == 0) - continue; + StencilEqualTest(); + if (Mask0 == 0 && Mask1 == 0) + continue; + if (depthTest) + { DepthTest(args); if (Mask0 == 0 && Mask1 == 0) continue; diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index f660f97644..90714c2663 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -158,17 +158,14 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) ClearBuffers(); SetSceneViewport(); - SetupPerspectiveMatrix(); - PolyPortalViewpoint mainViewpoint; - mainViewpoint.WorldToView = WorldToView; - mainViewpoint.WorldToClip = WorldToClip; + PolyPortalViewpoint mainViewpoint = SetupPerspectiveMatrix(); mainViewpoint.StencilValue = GetNextStencilValue(); mainViewpoint.PortalPlane = PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f); + Scene.CurrentViewpoint = &mainViewpoint; Scene.Render(&mainViewpoint); - Skydome.Render(Threads.MainThread(), WorldToView, WorldToClip); - Scene.RenderTranslucent(&mainViewpoint); PlayerSprites.Render(Threads.MainThread()); + Scene.CurrentViewpoint = nullptr; if (Viewpoint.camera) Viewpoint.camera->renderflags = savedflags; @@ -213,15 +210,8 @@ void PolyRenderer::SetSceneViewport() } } -void PolyRenderer::SetupPerspectiveMatrix() +PolyPortalViewpoint PolyRenderer::SetupPerspectiveMatrix() { - static bool bDidSetup = false; - - if (!bDidSetup) - { - bDidSetup = true; - } - // We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1. double radPitch = Viewpoint.Angles.Pitch.Normalized180().Radians(); double angx = cos(radPitch); @@ -232,9 +222,12 @@ void PolyRenderer::SetupPerspectiveMatrix() float ratio = Viewwindow.WidescreenRatio; float fovratio = (Viewwindow.WidescreenRatio >= 1.3f) ? 1.333333f : ratio; + float fovy = (float)(2 * DAngle::ToDegrees(atan(tan(Viewpoint.FieldOfView.Radians() / 2) / fovratio)).Degrees); - WorldToView = + PolyPortalViewpoint portalViewpoint; + + portalViewpoint.WorldToView = Mat4f::Rotate((float)Viewpoint.Angles.Roll.Radians(), 0.0f, 0.0f, 1.0f) * Mat4f::Rotate(adjustedPitch, 1.0f, 0.0f, 0.0f) * Mat4f::Rotate(adjustedViewAngle, 0.0f, -1.0f, 0.0f) * @@ -242,7 +235,9 @@ void PolyRenderer::SetupPerspectiveMatrix() Mat4f::SwapYZ() * Mat4f::Translate((float)-Viewpoint.Pos.X, (float)-Viewpoint.Pos.Y, (float)-Viewpoint.Pos.Z); - WorldToClip = Mat4f::Perspective(fovy, ratio, 5.0f, 65535.0f, Handedness::Right, ClipZRange::NegativePositiveW) * WorldToView; + portalViewpoint.WorldToClip = Mat4f::Perspective(fovy, ratio, 5.0f, 65535.0f, Handedness::Right, ClipZRange::NegativePositiveW) * portalViewpoint.WorldToView; + + return portalViewpoint; } cycle_t PolyCullCycles, PolyOpaqueCycles, PolyMaskedCycles, PolyDrawerWaitCycles; diff --git a/src/polyrenderer/poly_renderer.h b/src/polyrenderer/poly_renderer.h index f13dd0fe36..be8dc2cffb 100644 --- a/src/polyrenderer/poly_renderer.h +++ b/src/polyrenderer/poly_renderer.h @@ -30,7 +30,6 @@ #include "r_utility.h" #include "scene/poly_portal.h" #include "scene/poly_playersprite.h" -#include "scene/poly_sky.h" #include "scene/poly_light.h" #include "swrenderer/r_memory.h" #include "poly_renderthread.h" @@ -38,6 +37,7 @@ class AActor; class DCanvas; +class PolyPortalViewpoint; class DrawerCommandQueue; typedef std::shared_ptr DrawerCommandQueuePtr; @@ -54,7 +54,9 @@ public: void RenderRemainingPlayerSprites(); static PolyRenderer *Instance(); - + + PolyPortalViewpoint SetupPerspectiveMatrix(); + uint32_t GetNextStencilValue() { uint32_t value = NextStencilValue; NextStencilValue += 2; return value; } bool DontMapLines = false; @@ -67,16 +69,11 @@ public: PolyLightVisibility Light; RenderPolyScene Scene; - Mat4f WorldToView; - Mat4f WorldToClip; - private: void RenderActorView(AActor *actor, bool dontmaplines); void ClearBuffers(); void SetSceneViewport(); - void SetupPerspectiveMatrix(); - PolySkyDome Skydome; RenderPolyPlayerSprites PlayerSprites; uint32_t NextStencilValue = 0; }; diff --git a/src/polyrenderer/scene/poly_cull.cpp b/src/polyrenderer/scene/poly_cull.cpp index d53e0e1bfc..d79ca0467f 100644 --- a/src/polyrenderer/scene/poly_cull.cpp +++ b/src/polyrenderer/scene/poly_cull.cpp @@ -137,7 +137,7 @@ void PolyCull::CullSubsector(subsector_t *sub) } // Skip line if entirely behind portal clipping plane - if ((PortalClipPlane.A * line->v1->fX() + PortalClipPlane.B * line->v1->fY() + PortalClipPlane.D <= 0.0) || + 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[NextPvsLineStart++] = false; diff --git a/src/polyrenderer/scene/poly_model.cpp b/src/polyrenderer/scene/poly_model.cpp index d147f1f650..28d2f0e195 100644 --- a/src/polyrenderer/scene/poly_model.cpp +++ b/src/polyrenderer/scene/poly_model.cpp @@ -93,7 +93,7 @@ VSMatrix PolyModelRenderer::GetViewToWorldMatrix() swapYZ.Matrix[3 + 3 * 4] = 1.0f; VSMatrix worldToView; - worldToView.loadMatrix((PolyRenderer::Instance()->WorldToView * swapYZ).Matrix); + worldToView.loadMatrix((PolyRenderer::Instance()->Scene.CurrentViewpoint->WorldToView * swapYZ).Matrix); VSMatrix objectToWorld; worldToView.inverseMatrix(objectToWorld); diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index b5594cf328..a3aca5a8de 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -36,17 +36,17 @@ EXTERN_CVAR(Int, r_3dfloors) -void RenderPolyPlane::RenderPlanes(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals) +void RenderPolyPlane::RenderPlanes(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals, size_t sectorPortalsStart) { if (fakeflat.FrontSector->CenterFloor() == fakeflat.FrontSector->CenterCeiling()) return; RenderPolyPlane plane; - plane.Render(thread, clipPlane, fakeflat, stencilValue, true, skyCeilingHeight, sectorPortals); - plane.Render(thread, clipPlane, fakeflat, stencilValue, false, skyFloorHeight, sectorPortals); + plane.Render(thread, clipPlane, fakeflat, stencilValue, true, skyCeilingHeight, sectorPortals, sectorPortalsStart); + plane.Render(thread, clipPlane, fakeflat, stencilValue, false, skyFloorHeight, sectorPortals, sectorPortalsStart); } -void RenderPolyPlane::Render(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector> §orPortals) +void RenderPolyPlane::Render(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector> §orPortals, size_t sectorPortalsStart) { FSectorPortal *portal = fakeflat.FrontSector->ValidatePortal(ceiling ? sector_t::ceiling : sector_t::floor); if (!portal || (portal->mFlags & PORTSF_INSKYBOX) == PORTSF_INSKYBOX) // Do not recurse into portals we already recursed into @@ -55,7 +55,7 @@ void RenderPolyPlane::Render(PolyRenderThread *thread, const PolyClipPlane &clip } else { - RenderPortal(thread, clipPlane, fakeflat, stencilValue, ceiling, skyHeight, portal, sectorPortals); + RenderPortal(thread, clipPlane, fakeflat, stencilValue, ceiling, skyHeight, portal, sectorPortals, sectorPortalsStart); } } @@ -99,7 +99,7 @@ void RenderPolyPlane::RenderNormal(PolyRenderThread *thread, const PolyClipPlane } } -void RenderPolyPlane::RenderPortal(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight, FSectorPortal *portal, std::vector> §orPortals) +void RenderPolyPlane::RenderPortal(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight, FSectorPortal *portal, std::vector> §orPortals, size_t sectorPortalsStart) { const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; @@ -113,11 +113,11 @@ void RenderPolyPlane::RenderPortal(PolyRenderThread *thread, const PolyClipPlane return; } - for (auto &p : sectorPortals) + for (size_t i = sectorPortalsStart; i < sectorPortals.size(); i++) { - if (p->Portal == portal) // To do: what other criteria do we need to check for? + if (sectorPortals[i]->Portal == portal) // To do: what other criteria do we need to check for? { - polyportal = p.get(); + polyportal = sectorPortals[i].get(); break; } } diff --git a/src/polyrenderer/scene/poly_plane.h b/src/polyrenderer/scene/poly_plane.h index 9895f5b2fe..e5d0c9806e 100644 --- a/src/polyrenderer/scene/poly_plane.h +++ b/src/polyrenderer/scene/poly_plane.h @@ -57,12 +57,12 @@ private: class RenderPolyPlane { public: - static void RenderPlanes(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals); + static void RenderPlanes(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals, size_t sectorPortalsStart); private: - void Render(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector> §orPortals); + void Render(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector> §orPortals, size_t sectorPortalsStart); - void RenderPortal(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight, FSectorPortal *portal, std::vector> §orPortals); + void RenderPortal(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight, FSectorPortal *portal, std::vector> §orPortals, size_t sectorPortalsStart); void RenderNormal(PolyRenderThread *thread, const PolyClipPlane &clipPlane, const PolyTransferHeights &fakeflat, uint32_t stencilValue, bool ceiling, double skyHeight); void RenderSkyWalls(PolyRenderThread *thread, PolyDrawArgs &args, subsector_t *sub, PolyDrawSectorPortal *polyportal, bool ceiling, double skyHeight); diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index 8a387401f0..abcb861759 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -255,7 +255,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p if (renderHUDModel) { - PolyRenderHUDModel(thread, PolyRenderer::Instance()->WorldToClip, PolyClipPlane(), 1, pspr, (float)sx, (float)sy); + PolyRenderHUDModel(thread, PolyRenderer::Instance()->Scene.CurrentViewpoint->WorldToClip, PolyClipPlane(), 1, pspr, (float)sx, (float)sy); return; } diff --git a/src/polyrenderer/scene/poly_portal.cpp b/src/polyrenderer/scene/poly_portal.cpp index caf1f81453..4474eadb38 100644 --- a/src/polyrenderer/scene/poly_portal.cpp +++ b/src/polyrenderer/scene/poly_portal.cpp @@ -46,31 +46,7 @@ void PolyDrawSectorPortal::Render(int portalDepth) SaveGlobals(); - const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; - - // To do: get this information from PolyRenderer instead of duplicating the code.. - const auto &viewwindow = PolyRenderer::Instance()->Viewwindow; - double radPitch = viewpoint.Angles.Pitch.Normalized180().Radians(); - double angx = cos(radPitch); - double angy = sin(radPitch) * level.info->pixelstretch; - double alen = sqrt(angx*angx + angy*angy); - float adjustedPitch = (float)asin(angy / alen); - float adjustedViewAngle = (float)(viewpoint.Angles.Yaw - 90).Radians(); - float ratio = viewwindow.WidescreenRatio; - float fovratio = (viewwindow.WidescreenRatio >= 1.3f) ? 1.333333f : ratio; - float fovy = (float)(2 * DAngle::ToDegrees(atan(tan(viewpoint.FieldOfView.Radians() / 2) / fovratio)).Degrees); - Mat4f worldToView = - Mat4f::Rotate((float)viewpoint.Angles.Roll.Radians(), 0.0f, 0.0f, 1.0f) * - Mat4f::Rotate(adjustedPitch, 1.0f, 0.0f, 0.0f) * - Mat4f::Rotate(adjustedViewAngle, 0.0f, -1.0f, 0.0f) * - Mat4f::Scale(1.0f, level.info->pixelstretch, 1.0f) * - Mat4f::SwapYZ() * - Mat4f::Translate((float)-viewpoint.Pos.X, (float)-viewpoint.Pos.Y, (float)-viewpoint.Pos.Z); - Mat4f worldToClip = Mat4f::Perspective(fovy, ratio, 5.0f, 65535.0f, Handedness::Right, ClipZRange::NegativePositiveW) * worldToView; - - PortalViewpoint = PolyPortalViewpoint(); - PortalViewpoint.WorldToView = worldToView; - PortalViewpoint.WorldToClip = worldToClip; + PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(); PortalViewpoint.StencilValue = StencilValue; PortalViewpoint.PortalPlane = PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f); PortalViewpoint.PortalDepth = portalDepth; @@ -80,29 +56,13 @@ void PolyDrawSectorPortal::Render(int portalDepth) RestoreGlobals(); } -void PolyDrawSectorPortal::RenderTranslucent() -{ - if (Portal->mType == PORTS_HORIZON || Portal->mType == PORTS_PLANE) - return; - - SaveGlobals(); - - PolyRenderer::Instance()->Scene.RenderTranslucent(&PortalViewpoint); - - RestoreGlobals(); -} - void PolyDrawSectorPortal::SaveGlobals() { auto &viewpoint = PolyRenderer::Instance()->Viewpoint; const auto &viewwindow = PolyRenderer::Instance()->Viewwindow; - savedextralight = viewpoint.extralight; - savedpos = viewpoint.Pos; - savedangles = viewpoint.Angles; - //savedvisibility = PolyRenderer::Instance()->Light.GetVisibility(); - savedcamera = viewpoint.camera; - savedsector = viewpoint.sector; + SavedViewpoint = viewpoint; + SavedInvisibility = viewpoint.camera ? (viewpoint.camera->renderflags & RF_INVISIBLE) == RF_INVISIBLE : false; if (Portal->mType == PORTS_SKYVIEWPOINT) { @@ -111,7 +71,7 @@ void PolyDrawSectorPortal::SaveGlobals() viewpoint.extralight = 0; //PolyRenderer::Instance()->Light.SetVisibility(sky->args[0] * 0.25f); viewpoint.Pos = sky->InterpolatedPosition(viewpoint.TicFrac); - viewpoint.Angles.Yaw = savedangles.Yaw + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * viewpoint.TicFrac); + viewpoint.Angles.Yaw = SavedViewpoint.Angles.Yaw + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * viewpoint.TicFrac); } else //if (Portal->mType == PORTS_STACKEDSECTORTHING || Portal->mType == PORTS_PORTAL || Portal->mType == PORTS_LINKEDPORTAL) { @@ -137,12 +97,18 @@ void PolyDrawSectorPortal::RestoreGlobals() auto &viewpoint = PolyRenderer::Instance()->Viewpoint; const auto &viewwindow = PolyRenderer::Instance()->Viewwindow; - viewpoint.camera = savedcamera; - viewpoint.sector = savedsector; - viewpoint.Pos = savedpos; + viewpoint = SavedViewpoint; + + if (viewpoint.camera) + { + if (SavedInvisibility) + viewpoint.camera->renderflags |= RF_INVISIBLE; + else + viewpoint.camera->renderflags &= ~RF_INVISIBLE; + } + //PolyRenderer::Instance()->Light.SetVisibility(savedvisibility); - viewpoint.extralight = savedextralight; - viewpoint.Angles = savedangles; + R_SetViewAngle(viewpoint, viewwindow); } @@ -162,33 +128,10 @@ void PolyDrawLinePortal::Render(int portalDepth) { SaveGlobals(); - // To do: get this information from PolyRenderer instead of duplicating the code.. - const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; - const auto &viewwindow = PolyRenderer::Instance()->Viewwindow; - double radPitch = viewpoint.Angles.Pitch.Normalized180().Radians(); - double angx = cos(radPitch); - double angy = sin(radPitch) * level.info->pixelstretch; - double alen = sqrt(angx*angx + angy*angy); - float adjustedPitch = (float)asin(angy / alen); - float adjustedViewAngle = (float)(viewpoint.Angles.Yaw - 90).Radians(); - float ratio = viewwindow.WidescreenRatio; - float fovratio = (viewwindow.WidescreenRatio >= 1.3f) ? 1.333333f : ratio; - float fovy = (float)(2 * DAngle::ToDegrees(atan(tan(viewpoint.FieldOfView.Radians() / 2) / fovratio)).Degrees); - Mat4f worldToView = - Mat4f::Rotate((float)viewpoint.Angles.Roll.Radians(), 0.0f, 0.0f, 1.0f) * - Mat4f::Rotate(adjustedPitch, 1.0f, 0.0f, 0.0f) * - Mat4f::Rotate(adjustedViewAngle, 0.0f, -1.0f, 0.0f) * - Mat4f::Scale(1.0f, level.info->pixelstretch, 1.0f) * - Mat4f::SwapYZ() * - Mat4f::Translate((float)-viewpoint.Pos.X, (float)-viewpoint.Pos.Y, (float)-viewpoint.Pos.Z); - if (Mirror) - worldToView = Mat4f::Scale(-1.0f, 1.0f, 1.0f) * worldToView; - Mat4f worldToClip = Mat4f::Perspective(fovy, ratio, 5.0f, 65535.0f, Handedness::Right, ClipZRange::NegativePositiveW) * worldToView; - // Find portal destination line and make sure it faces the right way line_t *clipLine = Portal ? Portal->mDestination : Mirror; - DVector2 pt1 = clipLine->v1->fPos() - viewpoint.Pos; - DVector2 pt2 = clipLine->v2->fPos() - viewpoint.Pos; + DVector2 pt1 = clipLine->v1->fPos() - PolyRenderer::Instance()->Viewpoint.Pos; + DVector2 pt2 = clipLine->v2->fPos() - PolyRenderer::Instance()->Viewpoint.Pos; bool backfacing = (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0); vertex_t *v1 = backfacing ? clipLine->v1 : clipLine->v2; vertex_t *v2 = backfacing ? clipLine->v2 : clipLine->v1; @@ -207,39 +150,24 @@ void PolyDrawLinePortal::Render(int portalDepth) Segments.clear(); Segments.push_back({ angle1, angle2 });*/ - PortalViewpoint = PolyPortalViewpoint(); - PortalViewpoint.WorldToView = worldToView; - PortalViewpoint.WorldToClip = worldToClip; + PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(); PortalViewpoint.StencilValue = StencilValue; PortalViewpoint.PortalPlane = portalPlane; PortalViewpoint.PortalDepth = portalDepth; - PortalViewpoint.LastPortalLine = clipLine; + PortalViewpoint.PortalEnterLine = clipLine; PolyRenderer::Instance()->Scene.Render(&PortalViewpoint); RestoreGlobals(); } -void PolyDrawLinePortal::RenderTranslucent() -{ - SaveGlobals(); - PolyRenderer::Instance()->Scene.RenderTranslucent(&PortalViewpoint); - RestoreGlobals(); -} - void PolyDrawLinePortal::SaveGlobals() { auto &viewpoint = PolyRenderer::Instance()->Viewpoint; const auto &viewwindow = PolyRenderer::Instance()->Viewwindow; - savedextralight = viewpoint.extralight; - savedpos = viewpoint.Pos; - savedangles = viewpoint.Angles; - savedcamera = viewpoint.camera; - savedsector = viewpoint.sector; - savedinvisibility = viewpoint.camera ? (viewpoint.camera->renderflags & RF_INVISIBLE) == RF_INVISIBLE : false; - savedViewPath[0] = viewpoint.Path[0]; - savedViewPath[1] = viewpoint.Path[1]; + SavedViewpoint = viewpoint; + SavedInvisibility = viewpoint.camera ? (viewpoint.camera->renderflags & RF_INVISIBLE) == RF_INVISIBLE : false; if (Mirror) { @@ -290,27 +218,35 @@ void PolyDrawLinePortal::SaveGlobals() P_TranslatePortalXY(src, viewpoint.Path[0].X, viewpoint.Path[0].Y); P_TranslatePortalXY(src, viewpoint.Path[1].X, viewpoint.Path[1].Y); + if (viewpoint.camera && !viewpoint.showviewer) + viewpoint.camera->renderflags |= RF_INVISIBLE; + + /* What is this code trying to do? if (viewpoint.camera) + { viewpoint.camera->renderflags &= ~RF_INVISIBLE; - if (!viewpoint.showviewer && viewpoint.camera && P_PointOnLineSidePrecise(viewpoint.Path[0], dst) != P_PointOnLineSidePrecise(viewpoint.Path[1], dst)) - { - double distp = (viewpoint.Path[0] - viewpoint.Path[1]).Length(); - if (distp > EQUAL_EPSILON) + if (!viewpoint.showviewer && P_PointOnLineSidePrecise(viewpoint.Path[0], dst) != P_PointOnLineSidePrecise(viewpoint.Path[1], dst)) { - double dist1 = (viewpoint.Pos - viewpoint.Path[0]).Length(); - double dist2 = (viewpoint.Pos - viewpoint.Path[1]).Length(); - - if (dist1 + dist2 < distp + 1) + double distp = (viewpoint.Path[0] - viewpoint.Path[1]).Length(); + if (distp > EQUAL_EPSILON) { - viewpoint.camera->renderflags |= RF_INVISIBLE; + double dist1 = (viewpoint.Pos - viewpoint.Path[0]).Length(); + double dist2 = (viewpoint.Pos - viewpoint.Path[1]).Length(); + + if (dist1 + dist2 < distp + 1) + { + viewpoint.camera->renderflags |= RF_INVISIBLE; + } } } } + */ } viewpoint.camera = nullptr; viewpoint.sector = R_PointInSubsector(viewpoint.Pos)->sector; + R_SetViewAngle(viewpoint, viewwindow); if (Mirror) @@ -321,20 +257,17 @@ void PolyDrawLinePortal::RestoreGlobals() { auto &viewpoint = PolyRenderer::Instance()->Viewpoint; const auto &viewwindow = PolyRenderer::Instance()->Viewwindow; + + viewpoint = SavedViewpoint; + if (viewpoint.camera) { - if (savedinvisibility) + if (SavedInvisibility) viewpoint.camera->renderflags |= RF_INVISIBLE; else viewpoint.camera->renderflags &= ~RF_INVISIBLE; } - viewpoint.camera = savedcamera; - viewpoint.sector = savedsector; - viewpoint.Pos = savedpos; - viewpoint.extralight = savedextralight; - viewpoint.Angles = savedangles; - viewpoint.Path[0] = savedViewPath[0]; - viewpoint.Path[1] = savedViewPath[1]; + R_SetViewAngle(viewpoint, viewwindow); if (Mirror) diff --git a/src/polyrenderer/scene/poly_portal.h b/src/polyrenderer/scene/poly_portal.h index 6c58128e79..d9ad8f1ec8 100644 --- a/src/polyrenderer/scene/poly_portal.h +++ b/src/polyrenderer/scene/poly_portal.h @@ -44,7 +44,6 @@ public: PolyDrawSectorPortal(FSectorPortal *portal, bool ceiling); void Render(int portalDepth); - void RenderTranslucent(); FSectorPortal *Portal = nullptr; uint32_t StencilValue = 0; @@ -58,12 +57,8 @@ private: bool Ceiling; PolyPortalViewpoint PortalViewpoint; - int savedextralight; - DVector3 savedpos; - DRotator savedangles; - //double savedvisibility; - AActor *savedcamera; - sector_t *savedsector; + FRenderViewpoint SavedViewpoint; + bool SavedInvisibility; }; class PolyDrawLinePortal @@ -73,7 +68,6 @@ public: PolyDrawLinePortal(line_t *mirror); void Render(int portalDepth); - void RenderTranslucent(); FLinePortal *Portal = nullptr; line_t *Mirror = nullptr; @@ -87,11 +81,6 @@ private: PolyPortalViewpoint PortalViewpoint; - int savedextralight; - DVector3 savedpos; - DRotator savedangles; - AActor *savedcamera; - sector_t *savedsector; - bool savedinvisibility; - DVector3 savedViewPath[2]; + FRenderViewpoint SavedViewpoint; + bool SavedInvisibility; }; diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index b84608a4ad..2b62da6c89 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -84,7 +84,10 @@ void RenderPolyScene::Render(PolyPortalViewpoint *viewpoint) CurrentViewpoint->SectorPortalsEnd = thread->SectorPortals.size(); CurrentViewpoint->LinePortalsEnd = thread->LinePortals.size(); + Skydome.Render(thread, CurrentViewpoint->WorldToView, CurrentViewpoint->WorldToClip); + RenderPortals(); + RenderTranslucent(); CurrentViewpoint = oldviewpoint; } @@ -155,14 +158,14 @@ void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub } Render3DFloorPlane::RenderPlanes(thread, CurrentViewpoint->PortalPlane, sub, CurrentViewpoint->StencilValue, subsectorDepth, thread->TranslucentObjects); - RenderPolyPlane::RenderPlanes(thread, CurrentViewpoint->PortalPlane, sub, CurrentViewpoint->StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, thread->SectorPortals); + RenderPolyPlane::RenderPlanes(thread, CurrentViewpoint->PortalPlane, sub, CurrentViewpoint->StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, thread->SectorPortals, CurrentViewpoint->SectorPortalsStart); } else { PolyTransferHeights fakeflat(sub); Render3DFloorPlane::RenderPlanes(thread, CurrentViewpoint->PortalPlane, sub, CurrentViewpoint->StencilValue, subsectorDepth, thread->TranslucentObjects); - RenderPolyPlane::RenderPlanes(thread, CurrentViewpoint->PortalPlane, fakeflat, CurrentViewpoint->StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, thread->SectorPortals); + RenderPolyPlane::RenderPlanes(thread, CurrentViewpoint->PortalPlane, fakeflat, CurrentViewpoint->StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, thread->SectorPortals, CurrentViewpoint->SectorPortalsStart); for (uint32_t i = 0; i < sub->numlines; i++) { @@ -233,7 +236,7 @@ void RenderPolyScene::RenderPolySubsector(PolyRenderThread *thread, subsector_t sub->flags |= SSECF_DRAWN; } - RenderPolyWall::RenderLine(thread, CurrentViewpoint->PortalPlane, line, frontsector, subsectorDepth, CurrentViewpoint->StencilValue, thread->TranslucentObjects, thread->LinePortals, CurrentViewpoint->LastPortalLine); + RenderPolyWall::RenderLine(thread, CurrentViewpoint->PortalPlane, line, frontsector, subsectorDepth, CurrentViewpoint->StencilValue, thread->TranslucentObjects, thread->LinePortals, CurrentViewpoint->LinePortalsStart, CurrentViewpoint->PortalEnterLine); } } } @@ -312,15 +315,16 @@ void RenderPolyScene::RenderLine(PolyRenderThread *thread, subsector_t *sub, seg } // Render wall, and update culling info if its an occlusion blocker - RenderPolyWall::RenderLine(thread, CurrentViewpoint->PortalPlane, line, frontsector, subsectorDepth, CurrentViewpoint->StencilValue, thread->TranslucentObjects, thread->LinePortals, CurrentViewpoint->LastPortalLine); + RenderPolyWall::RenderLine(thread, CurrentViewpoint->PortalPlane, line, frontsector, subsectorDepth, CurrentViewpoint->StencilValue, thread->TranslucentObjects, thread->LinePortals, CurrentViewpoint->LinePortalsStart, CurrentViewpoint->PortalEnterLine); } void RenderPolyScene::RenderPortals() { PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread(); - bool foggy = false; - if (CurrentViewpoint->PortalDepth < r_portal_recursions) + bool enterPortals = CurrentViewpoint->PortalDepth < r_portal_recursions; + + if (enterPortals) { for (size_t i = CurrentViewpoint->SectorPortalsStart; i < CurrentViewpoint->SectorPortalsEnd; i++) thread->SectorPortals[i]->Render(CurrentViewpoint->PortalDepth + 1); @@ -328,86 +332,51 @@ void RenderPolyScene::RenderPortals() for (size_t i = CurrentViewpoint->LinePortalsStart; i < CurrentViewpoint->LinePortalsEnd; i++) thread->LinePortals[i]->Render(CurrentViewpoint->PortalDepth + 1); } - else // Fill with black + + Mat4f *transform = thread->FrameMemory->NewObject(CurrentViewpoint->WorldToClip); + PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); + + PolyDrawArgs args; + args.SetClipPlane(0, CurrentViewpoint->PortalPlane); + args.SetWriteColor(!enterPortals); + args.SetDepthTest(false); + + if (!enterPortals) // Fill with black { - PolyDrawArgs args; + bool foggy = false; args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(foggy), true); - args.SetColor(0, 0); - args.SetClipPlane(0, CurrentViewpoint->PortalPlane); args.SetStyle(TriBlendMode::FillOpaque); + args.SetColor(0, 0); + } - for (size_t i = CurrentViewpoint->SectorPortalsStart; i < CurrentViewpoint->SectorPortalsEnd; i++) + for (size_t i = CurrentViewpoint->SectorPortalsStart; i < CurrentViewpoint->SectorPortalsEnd; i++) + { + const auto &portal = thread->SectorPortals[i]; + args.SetStencilTestValue(enterPortals ? portal->StencilValue + 1 : portal->StencilValue); + args.SetWriteStencil(true, CurrentViewpoint->StencilValue + 1); + for (const auto &verts : portal->Shape) { - const auto &portal = thread->SectorPortals[i]; - args.SetStencilTestValue(portal->StencilValue); - args.SetWriteStencil(true, portal->StencilValue + 1); - for (const auto &verts : portal->Shape) - { - args.DrawArray(thread->DrawQueue, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); - } + args.DrawArray(thread->DrawQueue, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); } + } - for (size_t i = CurrentViewpoint->LinePortalsStart; i < CurrentViewpoint->LinePortalsEnd; i++) + for (size_t i = CurrentViewpoint->LinePortalsStart; i < CurrentViewpoint->LinePortalsEnd; i++) + { + const auto &portal = thread->LinePortals[i]; + args.SetStencilTestValue(enterPortals ? portal->StencilValue + 1 : portal->StencilValue); + args.SetWriteStencil(true, CurrentViewpoint->StencilValue + 1); + for (const auto &verts : portal->Shape) { - const auto &portal = thread->LinePortals[i]; - args.SetStencilTestValue(portal->StencilValue); - args.SetWriteStencil(true, portal->StencilValue + 1); - for (const auto &verts : portal->Shape) - { - args.DrawArray(thread->DrawQueue, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); - } + args.DrawArray(thread->DrawQueue, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); } } } -void RenderPolyScene::RenderTranslucent(PolyPortalViewpoint *viewpoint) +void RenderPolyScene::RenderTranslucent() { - PolyPortalViewpoint *oldviewpoint = CurrentViewpoint; - CurrentViewpoint = viewpoint; - PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread(); Mat4f *transform = thread->FrameMemory->NewObject(CurrentViewpoint->WorldToClip); - - if (CurrentViewpoint->PortalDepth < r_portal_recursions) - { - for (size_t i = CurrentViewpoint->SectorPortalsEnd; i > CurrentViewpoint->SectorPortalsStart; i--) - { - auto &portal = thread->SectorPortals[i - 1]; - portal->RenderTranslucent(); - - PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); - - PolyDrawArgs args; - args.SetStencilTestValue(portal->StencilValue + 1); - args.SetWriteStencil(true, CurrentViewpoint->StencilValue + 1); - args.SetClipPlane(0, CurrentViewpoint->PortalPlane); - for (const auto &verts : portal->Shape) - { - args.SetWriteColor(false); - args.DrawArray(thread->DrawQueue, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); - } - } - - for (size_t i = CurrentViewpoint->LinePortalsEnd; i > CurrentViewpoint->LinePortalsStart; i--) - { - auto &portal = thread->LinePortals[i - 1]; - portal->RenderTranslucent(); - - PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); - - PolyDrawArgs args; - args.SetStencilTestValue(portal->StencilValue + 1); - args.SetWriteStencil(true, CurrentViewpoint->StencilValue + 1); - args.SetClipPlane(0, CurrentViewpoint->PortalPlane); - for (const auto &verts : portal->Shape) - { - args.SetWriteColor(false); - args.DrawArray(thread->DrawQueue, verts.Vertices, verts.Count, PolyDrawMode::TriangleFan); - } - } - } - PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); PolyMaskedCycles.Clock(); @@ -427,8 +396,6 @@ void RenderPolyScene::RenderTranslucent(PolyPortalViewpoint *viewpoint) } PolyMaskedCycles.Unclock(); - - CurrentViewpoint = oldviewpoint; } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/polyrenderer/scene/poly_scene.h b/src/polyrenderer/scene/poly_scene.h index 3d1178f60d..9642e15f63 100644 --- a/src/polyrenderer/scene/poly_scene.h +++ b/src/polyrenderer/scene/poly_scene.h @@ -32,6 +32,7 @@ #include "polyrenderer/math/gpu_types.h" #include "poly_playersprite.h" #include "poly_cull.h" +#include "poly_sky.h" class PolyTranslucentObject { @@ -63,7 +64,7 @@ public: uint32_t StencilValue = 0; int PortalDepth = 0; - line_t *LastPortalLine = nullptr; + line_t *PortalEnterLine = nullptr; size_t ObjectsStart = 0; size_t ObjectsEnd = 0; @@ -81,7 +82,6 @@ public: ~RenderPolyScene(); void Render(PolyPortalViewpoint *viewpoint); - void RenderTranslucent(PolyPortalViewpoint *viewpoint); static const uint32_t SkySubsectorDepth = 0x7fffffff; @@ -89,6 +89,7 @@ public: private: void RenderPortals(); + void RenderTranslucent(); void RenderSectors(); void RenderSubsector(PolyRenderThread *thread, subsector_t *sub, uint32_t subsectorDepth); void RenderLine(PolyRenderThread *thread, subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth); @@ -100,6 +101,7 @@ private: static int PointOnSide(const DVector2 &pos, const node_t *node); PolyCull Cull; + PolySkyDome Skydome; }; enum class PolyWaterFakeSide diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 00641a7e52..fdbb2fa925 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -83,7 +83,7 @@ void RenderPolySprite::Render(PolyRenderThread *thread, const PolyClipPlane &cli { const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac); - PolyRenderModel(thread, PolyRenderer::Instance()->WorldToClip, clipPlane, stencilValue, (float)pos.X, (float)pos.Y, (float)pos.Z, modelframe, thing); + PolyRenderModel(thread, PolyRenderer::Instance()->Scene.CurrentViewpoint->WorldToClip, clipPlane, stencilValue, (float)pos.X, (float)pos.Y, (float)pos.Z, modelframe, thing); return; } } diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index 1360077023..0a219b7d57 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -40,7 +40,7 @@ EXTERN_CVAR(Bool, r_drawmirrors) EXTERN_CVAR(Bool, r_fogboundary) -bool RenderPolyWall::RenderLine(PolyRenderThread *thread, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector &translucentWallsOutput, std::vector> &linePortals, line_t *lastPortalLine) +bool RenderPolyWall::RenderLine(PolyRenderThread *thread, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector &translucentWallsOutput, std::vector> &linePortals, size_t linePortalsStart, line_t *portalEnterLine) { double frontceilz1 = frontsector->ceilingplane.ZatPoint(line->v1); double frontfloorz1 = frontsector->floorplane.ZatPoint(line->v1); @@ -52,7 +52,7 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, const PolyClipPlane &c PolyDrawLinePortal *polyportal = nullptr; if (line->backsector == nullptr && line->linedef && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors)) { - if (lastPortalLine == line->linedef || + if (portalEnterLine == line->linedef || (line->linedef->v1->fX() * clipPlane.A + line->linedef->v1->fY() * clipPlane.B + clipPlane.D <= 0.0f) || (line->linedef->v2->fX() * clipPlane.A + line->linedef->v2->fY() * clipPlane.B + clipPlane.D <= 0.0f)) { @@ -64,7 +64,7 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, const PolyClipPlane &c } else if (line->linedef && line->linedef->isVisualPortal()) { - if (lastPortalLine == line->linedef || + if (portalEnterLine == line->linedef || (line->linedef->v1->fX() * clipPlane.A + line->linedef->v1->fY() * clipPlane.B + clipPlane.D <= 0.0f) || (line->linedef->v2->fX() * clipPlane.A + line->linedef->v2->fY() * clipPlane.B + clipPlane.D <= 0.0f)) { @@ -72,11 +72,11 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, const PolyClipPlane &c } FLinePortal *portal = line->linedef->getPortal(); - for (auto &p : linePortals) + for (size_t i = linePortalsStart; i < linePortals.size(); i++) { - if (p->Portal == portal) // To do: what other criterias do we need to check for? + if (linePortals[i]->Portal == portal) // To do: what other criteria do we need to check for? { - polyportal = p.get(); + polyportal = linePortals[i].get(); break; } } @@ -322,7 +322,6 @@ void RenderPolyWall::Render(PolyRenderThread *thread, const PolyClipPlane &clipP PolyDrawArgs args; args.SetLight(Colormap, GetLightLevel(), PolyRenderer::Instance()->Light.WallGlobVis(foggy), false); - args.SetStencilTestValue(StencilValue); if (Texture && !Polyportal) args.SetTexture(Texture, DefaultRenderStyle()); args.SetClipPlane(0, clipPlane); @@ -331,6 +330,7 @@ void RenderPolyWall::Render(PolyRenderThread *thread, const PolyClipPlane &clipP if (FogBoundary) { + args.SetStencilTestValue(StencilValue + 1); args.SetStyle(TriBlendMode::FogBoundary); args.SetColor(0xffffffff, 254); args.SetDepthTest(true); @@ -343,6 +343,7 @@ void RenderPolyWall::Render(PolyRenderThread *thread, const PolyClipPlane &clipP if (Polyportal) { + args.SetStencilTestValue(StencilValue); args.SetWriteStencil(true, Polyportal->StencilValue); args.SetWriteColor(false); args.SetWriteDepth(false); @@ -351,6 +352,7 @@ void RenderPolyWall::Render(PolyRenderThread *thread, const PolyClipPlane &clipP } else if (!Masked) { + args.SetStencilTestValue(StencilValue); args.SetWriteStencil(true, StencilValue + 1); args.SetStyle(TriBlendMode::TextureOpaque); DrawStripes(thread, args, vertices); @@ -360,13 +362,14 @@ void RenderPolyWall::Render(PolyRenderThread *thread, const PolyClipPlane &clipP double srcalpha = MIN(Alpha, 1.0); double destalpha = Additive ? 1.0 : 1.0 - srcalpha; args.SetStyle(TriBlendMode::TextureAdd, srcalpha, destalpha); + args.SetStencilTestValue(StencilValue + 1); args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); DrawStripes(thread, args, vertices); } - RenderPolyDecal::RenderWallDecals(thread, clipPlane, LineSeg, StencilValue); + RenderPolyDecal::RenderWallDecals(thread, clipPlane, LineSeg, StencilValue + 1); } void RenderPolyWall::SetDynLights(PolyRenderThread *thread, PolyDrawArgs &args) diff --git a/src/polyrenderer/scene/poly_wall.h b/src/polyrenderer/scene/poly_wall.h index f4e0d11f09..c74156890a 100644 --- a/src/polyrenderer/scene/poly_wall.h +++ b/src/polyrenderer/scene/poly_wall.h @@ -31,7 +31,7 @@ class PolyCull; class RenderPolyWall { public: - static bool RenderLine(PolyRenderThread *thread, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector &translucentWallsOutput, std::vector> &linePortals, line_t *lastPortalLine); + static bool RenderLine(PolyRenderThread *thread, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector &translucentWallsOutput, std::vector> &linePortals, size_t linePortalsStart, line_t *portalEnterLine); static void Render3DFloorLine(PolyRenderThread *thread, const PolyClipPlane &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector &translucentWallsOutput); void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2);