diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index 88ae14e10..ad471b4f0 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -33,7 +33,7 @@ EXTERN_CVAR(Int, r_3dfloors) -void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals) +void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t ceilingSubsectorDepth, uint32_t floorSubsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals) { RenderPolyPlane plane; @@ -61,7 +61,7 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipP double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot); if (fakeHeight < viewpoint.Pos.Z && fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot)) { - plane.Render3DFloor(worldToClip, clipPlane, sub, subsectorDepth, stencilValue, false, fakeFloor); + plane.Render3DFloor(worldToClip, clipPlane, sub, floorSubsectorDepth, stencilValue, false, fakeFloor); } } @@ -82,13 +82,13 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipP double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot); if (fakeHeight > viewpoint.Pos.Z && fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot)) { - plane.Render3DFloor(worldToClip, clipPlane, sub, subsectorDepth, stencilValue, true, fakeFloor); + plane.Render3DFloor(worldToClip, clipPlane, sub, ceilingSubsectorDepth, stencilValue, true, fakeFloor); } } } - plane.Render(worldToClip, clipPlane, cull, sub, subsectorDepth, stencilValue, true, skyCeilingHeight, sectorPortals); - plane.Render(worldToClip, clipPlane, cull, sub, subsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals); + plane.Render(worldToClip, clipPlane, cull, sub, ceilingSubsectorDepth, stencilValue, true, skyCeilingHeight, sectorPortals); + plane.Render(worldToClip, clipPlane, cull, sub, floorSubsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals); } void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor) diff --git a/src/polyrenderer/scene/poly_plane.h b/src/polyrenderer/scene/poly_plane.h index ce2192594..bb022aea9 100644 --- a/src/polyrenderer/scene/poly_plane.h +++ b/src/polyrenderer/scene/poly_plane.h @@ -30,7 +30,7 @@ class PolyCull; class RenderPolyPlane { public: - static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals); + static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t ceilingSubsectorDepth, uint32_t floorSubsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector> §orPortals); private: struct UVTransform diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index ad0d88d34..2e5b04840 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -30,7 +30,6 @@ #include "polyrenderer/poly_renderer.h" #include "polyrenderer/scene/poly_light.h" -CVAR(Bool, r_debug_cull, 0, 0) EXTERN_CVAR(Int, r_portal_recursions) ///////////////////////////////////////////////////////////////////////////// @@ -92,19 +91,52 @@ void RenderPolyScene::ClearBuffers() void RenderPolyScene::RenderSectors() { - if (r_debug_cull) + int count = (int)Cull.PvsSectors.size(); + auto subsectors = Cull.PvsSectors.data(); + + int nextCeilingZChange = 0; + int nextFloorZChange = 0; + uint32_t ceilingSubsectorDepth = 0; + uint32_t floorSubsectorDepth = 0; + + for (int i = 0; i < count; i++) { - for (auto it = Cull.PvsSectors.rbegin(); it != Cull.PvsSectors.rend(); ++it) - RenderSubsector(*it); - } - else - { - for (auto it = Cull.PvsSectors.begin(); it != Cull.PvsSectors.end(); ++it) - RenderSubsector(*it); + // The software renderer only updates the clipping if the sector height changes. + // Find the subsector depths for when that happens. + if (i == nextCeilingZChange) + { + double z = subsectors[i]->sector->ceilingplane.Zat0(); + nextCeilingZChange++; + while (nextCeilingZChange < count) + { + double nextZ = subsectors[nextCeilingZChange]->sector->ceilingplane.Zat0(); + if (nextZ > z) + break; + z = nextZ; + nextCeilingZChange++; + } + ceilingSubsectorDepth = NextSubsectorDepth + nextCeilingZChange - i - 1; + } + if (i == nextFloorZChange) + { + double z = subsectors[i]->sector->floorplane.Zat0(); + nextFloorZChange++; + while (nextFloorZChange < count) + { + double nextZ = subsectors[nextFloorZChange]->sector->floorplane.Zat0(); + if (nextZ < z) + break; + z = nextZ; + nextFloorZChange++; + } + floorSubsectorDepth = NextSubsectorDepth + nextFloorZChange - i - 1; + } + + RenderSubsector(subsectors[i], ceilingSubsectorDepth, floorSubsectorDepth); } } -void RenderPolyScene::RenderSubsector(subsector_t *sub) +void RenderPolyScene::RenderSubsector(subsector_t *sub, uint32_t ceilingSubsectorDepth, uint32_t floorSubsectorDepth) { sector_t *frontsector = sub->sector; frontsector->MoreFlags |= SECF_DRAWN; @@ -147,7 +179,7 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub) if (sub->sector->CenterFloor() != sub->sector->CenterCeiling()) { - RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, subsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals); + RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, ceilingSubsectorDepth, floorSubsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals); } if (mainBSP) diff --git a/src/polyrenderer/scene/poly_scene.h b/src/polyrenderer/scene/poly_scene.h index 8dafc949b..e4a1dff4f 100644 --- a/src/polyrenderer/scene/poly_scene.h +++ b/src/polyrenderer/scene/poly_scene.h @@ -86,7 +86,7 @@ private: void ClearBuffers(); void RenderPortals(int portalDepth); void RenderSectors(); - void RenderSubsector(subsector_t *sub); + void RenderSubsector(subsector_t *sub, uint32_t ceilingSubsectorDepth, uint32_t floorSubsectorDepth); void RenderLine(subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth); void RenderSprite(AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right); void RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node);