From 8944328f80df03899e54b29f2cb6614b2a8f74b6 Mon Sep 17 00:00:00 2001 From: rogerman Date: Wed, 31 Oct 2018 13:44:20 -0700 Subject: [PATCH] OpenGL Renderer: Partially fix rendering in the Customize screen of Sands of Destruction. - This fix properly emulates the less-than-or-equal depth test rendering for front-facing polygons drawn on top of opaque back-facing fragments, but only if the front-facing polygon is opaque. Translucent front-facing polygons are not supported at this time due to requiring extensive changes to the rendering logic and shaders in order to emulate this extremely rare and niche NDS feature. (If you require the proper rendering of translucent front-facing polygons on top of back-facing fragments, then you must use SoftRasterizer.) --- desmume/src/OGLRender.cpp | 60 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index d4dc510a9..a8e48584b 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -1874,7 +1874,35 @@ Render3DError OpenGLRenderer::DrawAlphaTexturePolygon(const GLenum polyPrimitive else // Draw the polygon as completely opaque. { glUniform1i(OGLRef.uniformTexDrawOpaque, GL_TRUE); - glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr); + + if (isPolyFrontFacing) + { + glDepthFunc(GL_EQUAL); + glStencilFunc(GL_EQUAL, 0x40 | opaquePolyID, 0x40); + glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr); + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glStencilMask(0x40); + glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); + glStencilFunc(GL_ALWAYS, opaquePolyID, 0x3F); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0xFF); + glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr); + } + else + { + glStencilFunc(GL_ALWAYS, 0x40 | opaquePolyID, 0x40); + glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr); + + glStencilFunc(GL_ALWAYS, opaquePolyID, 0x3F); + } + glUniform1i(OGLRef.uniformTexDrawOpaque, GL_FALSE); } } @@ -1965,6 +1993,36 @@ Render3DError OpenGLRenderer::DrawOtherPolygon(const GLenum polyPrimitive, glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(((DRAWMODE == OGLPolyDrawMode_DrawOpaquePolys) || enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE); } + else if (DRAWMODE == OGLPolyDrawMode_DrawOpaquePolys) + { + if (isPolyFrontFacing) + { + glDepthFunc(GL_EQUAL); + glStencilFunc(GL_EQUAL, 0x40 | opaquePolyID, 0x40); + glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr); + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDepthMask(GL_FALSE); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glStencilMask(0x40); + glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); + glStencilFunc(GL_ALWAYS, opaquePolyID, 0x3F); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0xFF); + glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr); + } + else + { + glStencilFunc(GL_ALWAYS, 0x40 | opaquePolyID, 0x40); + glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr); + + glStencilFunc(GL_ALWAYS, opaquePolyID, 0x3F); + } + } else { glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);