From 83c0ec8b15b3622b2b3a243c33310bc76e2d4820 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 22 Apr 2018 23:29:39 +0200 Subject: [PATCH] - fix softpoly mirrors (cherry picked from commit 6e77cb49065e1cfefaad4bb2c097025cfd43842b) --- src/polyrenderer/drawers/poly_triangle.cpp | 26 +++++++++++++--------- src/polyrenderer/drawers/poly_triangle.h | 15 ++++++++----- src/polyrenderer/poly_renderer.cpp | 7 +++++- src/polyrenderer/poly_renderer.h | 2 +- src/polyrenderer/scene/poly_portal.cpp | 8 +------ src/polyrenderer/scene/poly_scene.cpp | 3 +++ src/polyrenderer/scene/poly_scene.h | 1 + 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index df8b2896a..f0ddaf3be 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -74,9 +74,9 @@ void PolyTriangleDrawer::SetTransform(const DrawerCommandQueuePtr &queue, const queue->Push(objectToClip); } -void PolyTriangleDrawer::ToggleMirror(const DrawerCommandQueuePtr &queue) +void PolyTriangleDrawer::SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw) { - queue->Push(); + queue->Push(ccw); } ///////////////////////////////////////////////////////////////////////////// @@ -93,7 +93,7 @@ void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, ui dest_pitch = new_dest_pitch; dest_bgra = new_dest_bgra; span_drawers = new_span_drawers; - mirror = false; + ccw = true; } void PolyTriangleThreadData::SetTransform(const Mat4f *newObjectToClip) @@ -118,7 +118,6 @@ void PolyTriangleThreadData::DrawElements(const PolyDrawArgs &drawargs) args.stencilMasks = PolyStencilBuffer::Instance()->Masks(); args.zbuffer = PolyZBuffer::Instance()->Values(); - bool ccw = !mirror; const TriVertex *vinput = drawargs.Vertices(); const unsigned int *elements = drawargs.Elements(); int vcount = drawargs.VertexCount(); @@ -146,15 +145,16 @@ void PolyTriangleThreadData::DrawElements(const PolyDrawArgs &drawargs) } else // TriangleDrawMode::TriangleStrip { + bool toggleccw = ccw; vert[0] = ShadeVertex(drawargs, vinput[*(elements++)]); vert[1] = ShadeVertex(drawargs, vinput[*(elements++)]); for (int i = 2; i < vcount; i++) { vert[2] = ShadeVertex(drawargs, vinput[*(elements++)]); - DrawShadedTriangle(vert, ccw, &args); + DrawShadedTriangle(vert, toggleccw, &args); vert[0] = vert[1]; vert[1] = vert[2]; - ccw = !ccw; + toggleccw = !toggleccw; } } } @@ -176,7 +176,6 @@ void PolyTriangleThreadData::DrawArrays(const PolyDrawArgs &drawargs) args.stencilMasks = PolyStencilBuffer::Instance()->Masks(); args.zbuffer = PolyZBuffer::Instance()->Values(); - bool ccw = !mirror; const TriVertex *vinput = drawargs.Vertices(); int vcount = drawargs.VertexCount(); @@ -203,15 +202,16 @@ void PolyTriangleThreadData::DrawArrays(const PolyDrawArgs &drawargs) } else // TriangleDrawMode::TriangleStrip { + bool toggleccw = ccw; vert[0] = ShadeVertex(drawargs, *(vinput++)); vert[1] = ShadeVertex(drawargs, *(vinput++)); for (int i = 2; i < vcount; i++) { vert[2] = ShadeVertex(drawargs, *(vinput++)); - DrawShadedTriangle(vert, ccw, &args); + DrawShadedTriangle(vert, toggleccw, &args); vert[0] = vert[1]; vert[1] = vert[2]; - ccw = !ccw; + toggleccw = !toggleccw; } } } @@ -569,9 +569,13 @@ void PolySetTransformCommand::Execute(DrawerThread *thread) ///////////////////////////////////////////////////////////////////////////// -void PolyToggleMirrorCommand::Execute(DrawerThread *thread) +PolySetCullCCWCommand::PolySetCullCCWCommand(bool ccw) : ccw(ccw) { - PolyTriangleThreadData::Get(thread)->ToggleMirror(); +} + +void PolySetCullCCWCommand::Execute(DrawerThread *thread) +{ + PolyTriangleThreadData::Get(thread)->SetCullCCW(ccw); } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index 7c520ed6f..bd147efb5 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -34,7 +34,7 @@ class PolyTriangleDrawer public: static void ClearBuffers(DCanvas *canvas); static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers); - static void ToggleMirror(const DrawerCommandQueuePtr &queue); + static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw); static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip); }; @@ -45,7 +45,7 @@ public: void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers); void SetTransform(const Mat4f *objectToClip); - void ToggleMirror() { mirror = !mirror; } + void SetCullCCW(bool value) { ccw = value; } void DrawElements(const PolyDrawArgs &args); void DrawArrays(const PolyDrawArgs &args); @@ -78,7 +78,7 @@ private: int dest_height = 0; bool dest_bgra = false; uint8_t *dest = nullptr; - bool mirror = false; + bool ccw = true; const Mat4f *objectToClip = nullptr; bool span_drawers = false; @@ -97,11 +97,16 @@ private: const Mat4f *objectToClip; }; -class PolyToggleMirrorCommand : public DrawerCommand +class PolySetCullCCWCommand : public DrawerCommand { public: + PolySetCullCCWCommand(bool ccw); + void Execute(DrawerThread *thread) override; - FString DebugInfo() override { return "PolyToggleMirror"; } + FString DebugInfo() override { return "PolySetCullCCWCommand"; } + +private: + bool ccw; }; class PolySetViewportCommand : public DrawerCommand diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index 372c2bc78..753d94d61 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -213,7 +213,7 @@ void PolyRenderer::SetSceneViewport() } } -PolyPortalViewpoint PolyRenderer::SetupPerspectiveMatrix() +PolyPortalViewpoint PolyRenderer::SetupPerspectiveMatrix(bool mirror) { static bool bDidSetup = false; @@ -246,6 +246,11 @@ PolyPortalViewpoint PolyRenderer::SetupPerspectiveMatrix() Mat4f::SwapYZ() * Mat4f::Translate((float)-Viewpoint.Pos.X, (float)-Viewpoint.Pos.Y, (float)-Viewpoint.Pos.Z); + portalViewpoint.Mirror = mirror; + + if (mirror) + portalViewpoint.WorldToView = Mat4f::Scale(-1.0f, 1.0f, 1.0f) * portalViewpoint.WorldToView; + portalViewpoint.WorldToClip = Mat4f::Perspective(fovy, ratio, 5.0f, 65535.0f, Handedness::Right, ClipZRange::NegativePositiveW) * portalViewpoint.WorldToView; return portalViewpoint; diff --git a/src/polyrenderer/poly_renderer.h b/src/polyrenderer/poly_renderer.h index b6c4bebf4..173cbc441 100644 --- a/src/polyrenderer/poly_renderer.h +++ b/src/polyrenderer/poly_renderer.h @@ -55,7 +55,7 @@ public: static PolyRenderer *Instance(); - PolyPortalViewpoint SetupPerspectiveMatrix(); + PolyPortalViewpoint SetupPerspectiveMatrix(bool mirror = false); uint32_t GetNextStencilValue() { uint32_t value = NextStencilValue; NextStencilValue += 2; return value; } diff --git a/src/polyrenderer/scene/poly_portal.cpp b/src/polyrenderer/scene/poly_portal.cpp index 4474eadb3..afed60f0b 100644 --- a/src/polyrenderer/scene/poly_portal.cpp +++ b/src/polyrenderer/scene/poly_portal.cpp @@ -150,7 +150,7 @@ void PolyDrawLinePortal::Render(int portalDepth) Segments.clear(); Segments.push_back({ angle1, angle2 });*/ - PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(); + PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(Mirror); PortalViewpoint.StencilValue = StencilValue; PortalViewpoint.PortalPlane = portalPlane; PortalViewpoint.PortalDepth = portalDepth; @@ -248,9 +248,6 @@ void PolyDrawLinePortal::SaveGlobals() viewpoint.sector = R_PointInSubsector(viewpoint.Pos)->sector; R_SetViewAngle(viewpoint, viewwindow); - - if (Mirror) - PolyTriangleDrawer::ToggleMirror(PolyRenderer::Instance()->Threads.MainThread()->DrawQueue); } void PolyDrawLinePortal::RestoreGlobals() @@ -269,7 +266,4 @@ void PolyDrawLinePortal::RestoreGlobals() } R_SetViewAngle(viewpoint, viewwindow); - - if (Mirror) - PolyTriangleDrawer::ToggleMirror(PolyRenderer::Instance()->Threads.MainThread()->DrawQueue); } diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index 2b62da6c8..2f1b92906 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -103,6 +103,7 @@ void RenderPolyScene::RenderSectors() PolyRenderer::Instance()->Threads.RenderThreadSlices(totalcount, [&](PolyRenderThread *thread) { + PolyTriangleDrawer::SetCullCCW(thread->DrawQueue, !CurrentViewpoint->Mirror); PolyTriangleDrawer::SetTransform(thread->DrawQueue, thread->FrameMemory->NewObject(CurrentViewpoint->WorldToClip)); if (thread != mainthread) @@ -334,6 +335,7 @@ void RenderPolyScene::RenderPortals() } Mat4f *transform = thread->FrameMemory->NewObject(CurrentViewpoint->WorldToClip); + PolyTriangleDrawer::SetCullCCW(thread->DrawQueue, !CurrentViewpoint->Mirror); PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); PolyDrawArgs args; @@ -377,6 +379,7 @@ void RenderPolyScene::RenderTranslucent() PolyRenderThread *thread = PolyRenderer::Instance()->Threads.MainThread(); Mat4f *transform = thread->FrameMemory->NewObject(CurrentViewpoint->WorldToClip); + PolyTriangleDrawer::SetCullCCW(thread->DrawQueue, !CurrentViewpoint->Mirror); PolyTriangleDrawer::SetTransform(thread->DrawQueue, transform); PolyMaskedCycles.Clock(); diff --git a/src/polyrenderer/scene/poly_scene.h b/src/polyrenderer/scene/poly_scene.h index 9642e15f6..de9619bee 100644 --- a/src/polyrenderer/scene/poly_scene.h +++ b/src/polyrenderer/scene/poly_scene.h @@ -63,6 +63,7 @@ public: PolyClipPlane PortalPlane; uint32_t StencilValue = 0; int PortalDepth = 0; + bool Mirror = false; line_t *PortalEnterLine = nullptr;