From 1742114fcd701747ebeda8434443284a3f842d67 Mon Sep 17 00:00:00 2001 From: rogerman Date: Fri, 22 Sep 2017 17:25:01 -0700 Subject: [PATCH] OpenGL Renderer: Reset the current polygon's OpenGL states to the last opaque polygon whenever the zero-destination-alpha-pass is performed. Fixes a graphical bug in MegaMan ZX Advent, where the explosions from the boss in Grey's first level will render incorrectly. (Regression from commit eea54a7.) --- desmume/src/OGLRender.cpp | 37 +++++++++++++++++++++-------------- desmume/src/OGLRender.h | 4 ++-- desmume/src/OGLRender_3_2.cpp | 4 ++-- desmume/src/OGLRender_3_2.h | 2 +- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 7bec38a94..b82bfbf5b 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -1523,7 +1523,7 @@ OpenGLTexture* OpenGLRenderer::GetLoadedTextureFromPolygon(const POLY &thePoly, } template -size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent) +size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr) { OGLRenderRef &OGLRef = *this->ref; @@ -1550,12 +1550,10 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const // Set up the initial polygon const POLY &initialPoly = polyList->list[indexList->list[firstIndex]]; - u32 lastPolyAttr = initialPoly.polyAttr; u32 lastTexParams = initialPoly.texParam; u32 lastTexPalette = initialPoly.texPalette; u32 lastViewport = initialPoly.viewport; - this->SetupPolygon(initialPoly, lastPolyTreatedAsTranslucent, (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass)); this->SetupTexture(initialPoly, firstIndex); this->SetupViewport(initialPoly.viewport); @@ -1571,8 +1569,7 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const if (lastPolyAttr != thePoly.polyAttr) { lastPolyAttr = thePoly.polyAttr; - lastPolyTreatedAsTranslucent = thePoly.isTranslucent(); - this->SetupPolygon(thePoly, lastPolyTreatedAsTranslucent, (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass)); + this->SetupPolygon(thePoly, (DRAWMODE != OGLPolyDrawMode_DrawOpaquePolys), (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass)); } // Set up the texture if it changed @@ -3268,7 +3265,7 @@ Render3DError OpenGLRenderer_1_2::DisableVertexAttributes() return OGLERROR_NOERR; } -Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, bool lastPolyTreatedAsTranslucent) +Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, u32 lastPolyAttr) { OGLRenderRef &OGLRef = *this->ref; @@ -3356,7 +3353,7 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLYLIST *polyList, con glDepthMask(GL_FALSE); glStencilFunc(GL_NOTEQUAL, 0x80, 0x80); - this->DrawPolygonsForIndexRange(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyTreatedAsTranslucent); + this->DrawPolygonsForIndexRange(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyAttr); // Restore OpenGL states back to normal. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO); @@ -3692,23 +3689,33 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState, this->EnableVertexAttributes(); - const POLY &firstPoly = polyList->list[indexList->list[0]]; - bool lastPolyTreatedAsTranslucent = firstPoly.isTranslucent(); size_t indexOffset = 0; + const POLY &firstPoly = polyList->list[indexList->list[0]]; + u32 lastPolyAttr = firstPoly.polyAttr; + this->SetupPolygon(firstPoly, false, true); + if (polyList->opaqueCount > 0) { - this->DrawPolygonsForIndexRange(polyList, indexList, 0, polyList->opaqueCount - 1, indexOffset, lastPolyTreatedAsTranslucent); + this->DrawPolygonsForIndexRange(polyList, indexList, 0, polyList->opaqueCount - 1, indexOffset, lastPolyAttr); } if (polyList->opaqueCount < polyList->count) { if (this->_needsZeroDstAlphaPass) { - this->ZeroDstAlphaPass(polyList, indexList, renderState.enableAlphaBlending, indexOffset, lastPolyTreatedAsTranslucent); + this->ZeroDstAlphaPass(polyList, indexList, renderState.enableAlphaBlending, indexOffset, lastPolyAttr); + + if (polyList->opaqueCount > 0) + { + const POLY &lastOpaquePoly = polyList->list[indexList->list[polyList->opaqueCount - 1]]; + lastPolyAttr = lastOpaquePoly.polyAttr; + this->SetupPolygon(lastOpaquePoly, false, true); + } + } - this->DrawPolygonsForIndexRange(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyTreatedAsTranslucent); + this->DrawPolygonsForIndexRange(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyAttr); } glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -4732,6 +4739,6 @@ Render3DError OpenGLRenderer_2_1::RenderFlush(bool willFlushBuffer32, bool willF return RENDER3DERROR_NOERR; } -template size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent); -template size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent); -template size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent); +template size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr); +template size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr); +template size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr); diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 8729c6db5..ea4f5511a 100755 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -658,7 +658,7 @@ protected: Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16); OpenGLTexture* GetLoadedTextureFromPolygon(const POLY &thePoly, bool enableTexturing); - template size_t DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent); + template size_t DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr); template Render3DError DrawAlphaTexturePolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const bool canHaveOpaqueFragments); // OpenGL-specific methods @@ -774,7 +774,7 @@ protected: virtual void GetExtensionSet(std::set *oglExtensionSet); virtual Render3DError EnableVertexAttributes(); virtual Render3DError DisableVertexAttributes(); - virtual Render3DError ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, bool lastPolyTreatedAsTranslucent); + virtual Render3DError ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, u32 lastPolyAttr); virtual Render3DError DownsampleFBO(); virtual Render3DError ReadBackPixels(); diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index c950e13ec..e4af95641 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -1350,7 +1350,7 @@ Render3DError OpenGLRenderer_3_2::DisableVertexAttributes() return OGLERROR_NOERR; } -Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, bool lastPolyTreatedAsTranslucent) +Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, u32 lastPolyAttr) { OGLRenderRef &OGLRef = *this->ref; @@ -1412,7 +1412,7 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLYLIST *polyList, con glDepthMask(GL_FALSE); glStencilFunc(GL_NOTEQUAL, 0x80, 0x80); - this->DrawPolygonsForIndexRange(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyTreatedAsTranslucent); + this->DrawPolygonsForIndexRange(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyAttr); // Restore OpenGL states back to normal. glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO); diff --git a/desmume/src/OGLRender_3_2.h b/desmume/src/OGLRender_3_2.h index 702180048..b2d711e6d 100644 --- a/desmume/src/OGLRender_3_2.h +++ b/desmume/src/OGLRender_3_2.h @@ -85,7 +85,7 @@ protected: virtual void GetExtensionSet(std::set *oglExtensionSet); virtual Render3DError EnableVertexAttributes(); virtual Render3DError DisableVertexAttributes(); - virtual Render3DError ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, bool lastPolyTreatedAsTranslucent); + virtual Render3DError ZeroDstAlphaPass(const POLYLIST *polyList, const INDEXLIST *indexList, bool enableAlphaBlending, size_t indexOffset, u32 lastPolyAttr); virtual Render3DError DownsampleFBO(); virtual Render3DError ReadBackPixels(); virtual Render3DError BeginRender(const GFX3D &engine);