From f62e2f9ba3f4617f77f98ebfa8dce7ca4dfcc7c6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jul 2018 19:16:12 +0200 Subject: [PATCH] - fixed: The stencil cap may never write to the depth buffer. Due to the way nested portals work this will block rendering of the nested cap entriely and cause some visual glitches when looking straight up or down in such a sector. --- src/gl/scene/gl_portal.cpp | 17 ++++++++++------- src/gl/scene/gl_portal.h | 10 +++++++++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 9d1a85ae7..62c2d21c7 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -86,7 +86,7 @@ void GLPortal::ClearScreen(HWDrawInfo *di) // DrawPortalStencil // //----------------------------------------------------------------------------- -void GLPortal::DrawPortalStencil() +void GLPortal::DrawPortalStencil(int pass) { if (mPrimIndices.Size() == 0) { @@ -105,8 +105,11 @@ void GLPortal::DrawPortalStencil() } if (NeedCap() && lines.Size() > 1) { + if (pass == STP_AllInOne) glDepthMask(false); + else if (pass == STP_DepthRestore) glDepthRange(1, 1); GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILTOP_INDEX, 4); GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILBOTTOM_INDEX, 4); + if (pass == STP_DepthRestore) glDepthRange(0, 1); } } @@ -150,7 +153,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, HWDrawInfo *outer_di, HWDraw // Use occlusion query to avoid rendering portals that aren't visible if (doquery) glBeginQuery(GL_SAMPLES_PASSED, GLRenderer->PortalQueryObject); - DrawPortalStencil(); + DrawPortalStencil(STP_Stencil); if (doquery) glEndQuery(GL_SAMPLES_PASSED); @@ -160,7 +163,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, HWDrawInfo *outer_di, HWDraw glDepthMask(true); // enable z-buffer again glDepthRange(1, 1); glDepthFunc(GL_ALWAYS); - DrawPortalStencil(); + DrawPortalStencil(STP_DepthClear); // set normal drawing mode gl_RenderState.EnableTexture(true); @@ -189,7 +192,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, HWDrawInfo *outer_di, HWDraw // Note: We must draw the stencil with z-write enabled here because there is no second pass! glDepthMask(true); - DrawPortalStencil(); + DrawPortalStencil(STP_AllInOne); glStencilFunc(GL_EQUAL, mState->recursion + 1, ~0); // draw sky into stencil glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil gl_RenderState.EnableTexture(true); @@ -252,7 +255,7 @@ void GLPortal::End(HWDrawInfo *di, bool usestencil) // first step: reset the depth buffer to max. depth glDepthRange(1, 1); // always glDepthFunc(GL_ALWAYS); // write the farthest depth value - DrawPortalStencil(); + DrawPortalStencil(STP_DepthClear); } else { @@ -264,7 +267,7 @@ void GLPortal::End(HWDrawInfo *di, bool usestencil) glDepthRange(0, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); glStencilFunc(GL_EQUAL, mState->recursion, ~0); // draw sky into stencil - DrawPortalStencil(); + DrawPortalStencil(STP_DepthRestore); glDepthFunc(GL_LESS); @@ -306,7 +309,7 @@ void GLPortal::End(HWDrawInfo *di, bool usestencil) gl_RenderState.BlendFunc(GL_ONE, GL_ZERO); gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.Apply(); - DrawPortalStencil(); + DrawPortalStencil(STP_DepthRestore); gl_RenderState.SetEffect(EFF_NONE); gl_RenderState.EnableTexture(true); glColorMask(1, 1, 1, 1); // mark portal in alpha channel but don't touch color diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 4282f3d0b..8e9900e24 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -50,7 +50,15 @@ class GLPortal : public IPortal { private: - void DrawPortalStencil(); + + enum + { + STP_Stencil, + STP_DepthClear, + STP_DepthRestore, + STP_AllInOne + }; + void DrawPortalStencil(int pass); ActorRenderFlags savedvisibility; TArray mPrimIndices;