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.)

This commit is contained in:
rogerman 2017-09-22 17:25:01 -07:00
parent f521ab1164
commit 1742114fcd
4 changed files with 27 additions and 20 deletions

View File

@ -1523,7 +1523,7 @@ OpenGLTexture* OpenGLRenderer::GetLoadedTextureFromPolygon(const POLY &thePoly,
}
template <OGLPolyDrawMode DRAWMODE>
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<OGLPolyDrawMode_ZeroAlphaPass>(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyTreatedAsTranslucent);
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(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<OGLPolyDrawMode_DrawOpaquePolys>(polyList, indexList, 0, polyList->opaqueCount - 1, indexOffset, lastPolyTreatedAsTranslucent);
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawOpaquePolys>(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<OGLPolyDrawMode_DrawTranslucentPolys>(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyTreatedAsTranslucent);
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawTranslucentPolys>(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<OGLPolyDrawMode_DrawOpaquePolys>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent);
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawTranslucentPolys>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent);
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent);
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawOpaquePolys>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr);
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawTranslucentPolys>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr);
template size_t OpenGLRenderer::DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr);

View File

@ -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<OGLPolyDrawMode DRAWMODE> size_t DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent);
template<OGLPolyDrawMode DRAWMODE> size_t DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr);
template<bool WILLUPDATESTENCILBUFFER> 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<std::string> *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();

View File

@ -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<OGLPolyDrawMode_ZeroAlphaPass>(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyTreatedAsTranslucent);
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_ZeroAlphaPass>(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyAttr);
// Restore OpenGL states back to normal.
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);

View File

@ -85,7 +85,7 @@ protected:
virtual void GetExtensionSet(std::set<std::string> *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);