OpenGL Renderer: Be a little more precise when doing polygon comparisons between opaque and translucent drawing modes. (Related to commit 5aeed21.)

This commit is contained in:
rogerman 2017-08-04 11:25:06 -07:00
parent f8ab45fc4b
commit eea54a753c
4 changed files with 39 additions and 27 deletions

View File

@ -1488,7 +1488,7 @@ OpenGLTexture* OpenGLRenderer::GetLoadedTextureFromPolygon(const POLY &thePoly,
} }
template <OGLPolyDrawMode DRAWMODE> template <OGLPolyDrawMode DRAWMODE>
size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, u32 &lastPolyAttr, u32 &lastTexParams, u32 &lastTexPalette, u32 &lastViewport) size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent)
{ {
OGLRenderRef &OGLRef = *this->ref; OGLRenderRef &OGLRef = *this->ref;
@ -1513,10 +1513,21 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const
static const GLsizei indexIncrementLUT[] = {3, 6, 3, 6, 3, 4, 3, 4}; static const GLsizei indexIncrementLUT[] = {3, 6, 3, 6, 3, 4, 3, 4};
// 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);
// Enumerate through all polygons and render
GLsizei vertIndexCount = 0; GLsizei vertIndexCount = 0;
GLushort *indexBufferPtr = OGLRef.vertIndexBuffer + indexOffset; GLushort *indexBufferPtr = OGLRef.vertIndexBuffer + indexOffset;
// Enumerate through all polygons and render
for (size_t i = firstIndex; i <= lastIndex; i++) for (size_t i = firstIndex; i <= lastIndex; i++)
{ {
const POLY &thePoly = polyList->list[indexList->list[i]]; const POLY &thePoly = polyList->list[indexList->list[i]];
@ -1525,7 +1536,8 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const
if (lastPolyAttr != thePoly.polyAttr) if (lastPolyAttr != thePoly.polyAttr)
{ {
lastPolyAttr = thePoly.polyAttr; lastPolyAttr = thePoly.polyAttr;
this->SetupPolygon(thePoly, (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass)); lastPolyTreatedAsTranslucent = thePoly.isTranslucent();
this->SetupPolygon(thePoly, lastPolyTreatedAsTranslucent, (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass));
} }
// Set up the texture if it changed // Set up the texture if it changed
@ -1749,6 +1761,7 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
std::string framebufferOutputVtxShaderString = std::string(FramebufferOutputVtxShader_100); std::string framebufferOutputVtxShaderString = std::string(FramebufferOutputVtxShader_100);
std::string framebufferOutputRGBA6665FragShaderString = std::string(FramebufferOutputRGBA6665FragShader_100); std::string framebufferOutputRGBA6665FragShaderString = std::string(FramebufferOutputRGBA6665FragShader_100);
std::string framebufferOutputRGBA8888FragShaderString = std::string(FramebufferOutputRGBA8888FragShader_100); std::string framebufferOutputRGBA8888FragShaderString = std::string(FramebufferOutputRGBA8888FragShader_100);
error = this->InitPostprocessingPrograms(zeroAlphaPixelMaskVtxShaderString, error = this->InitPostprocessingPrograms(zeroAlphaPixelMaskVtxShaderString,
zeroAlphaPixelMaskFragShaderString, zeroAlphaPixelMaskFragShaderString,
edgeMarkVtxShaderString, edgeMarkVtxShaderString,
@ -2131,7 +2144,6 @@ void OpenGLRenderer_1_2::DestroyGeometryProgram()
glDetachShader(OGLRef.programGeometryID, OGLRef.vertexGeometryShaderID); glDetachShader(OGLRef.programGeometryID, OGLRef.vertexGeometryShaderID);
glDetachShader(OGLRef.programGeometryID, OGLRef.fragmentGeometryShaderID); glDetachShader(OGLRef.programGeometryID, OGLRef.fragmentGeometryShaderID);
glDeleteProgram(OGLRef.programGeometryID); glDeleteProgram(OGLRef.programGeometryID);
glDeleteShader(OGLRef.vertexGeometryShaderID); glDeleteShader(OGLRef.vertexGeometryShaderID);
glDeleteShader(OGLRef.fragmentGeometryShaderID); glDeleteShader(OGLRef.fragmentGeometryShaderID);
@ -3506,7 +3518,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
if(renderState.enableAlphaBlending) if (renderState.enableAlphaBlending)
{ {
glEnable(GL_BLEND); glEnable(GL_BLEND);
} }
@ -3520,21 +3532,17 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
this->EnableVertexAttributes(); this->EnableVertexAttributes();
const POLY &firstPoly = polyList->list[indexList->list[0]]; const POLY &firstPoly = polyList->list[indexList->list[0]];
u32 lastPolyAttr = firstPoly.polyAttr; bool lastPolyTreatedAsTranslucent = firstPoly.isTranslucent();
u32 lastTexParams = firstPoly.texParam;
u32 lastTexPalette = firstPoly.texPalette;
u32 lastViewport = firstPoly.viewport;
size_t indexOffset = 0; size_t indexOffset = 0;
this->SetupPolygon(firstPoly, true); if (polyList->opaqueCount > 0)
this->SetupTexture(firstPoly, 0); {
this->SetupViewport(firstPoly.viewport); this->DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawOpaquePolys>(polyList, indexList, 0, polyList->opaqueCount - 1, indexOffset, lastPolyTreatedAsTranslucent);
}
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawOpaquePolys>(polyList, indexList, 0, polyList->opaqueCount - 1, indexOffset, lastPolyAttr, lastTexParams, lastTexPalette, lastViewport);
if (polyList->opaqueCount != polyList->count) if (polyList->opaqueCount != polyList->count)
{ {
this->DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawTranslucentPolys>(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyAttr, lastTexParams, lastTexPalette, lastViewport); this->DrawPolygonsForIndexRange<OGLPolyDrawMode_DrawTranslucentPolys>(polyList, indexList, polyList->opaqueCount, polyList->count - 1, indexOffset, lastPolyTreatedAsTranslucent);
} }
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@ -3891,7 +3899,7 @@ void OpenGLRenderer_1_2::SetPolygonIndex(const size_t index)
this->_currentPolyIndex = index; this->_currentPolyIndex = index;
} }
Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool willChangeStencilBuffer) Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer)
{ {
const PolygonAttributes attr = thePoly.getAttributes(); const PolygonAttributes attr = thePoly.getAttributes();
@ -3946,11 +3954,11 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool willCha
else else
{ {
glStencilFunc(GL_ALWAYS, attr.polygonID, 0x3F); glStencilFunc(GL_ALWAYS, attr.polygonID, 0x3F);
glStencilOp(GL_KEEP, GL_KEEP, (attr.isTranslucent) ? GL_KEEP : GL_REPLACE); glStencilOp(GL_KEEP, GL_KEEP, (treatAsTranslucent) ? GL_KEEP : GL_REPLACE);
glStencilMask(0xFF); // Drawing non-shadow polygons will implicitly reset the stencil buffer bits glStencilMask(0xFF); // Drawing non-shadow polygons will implicitly reset the stencil buffer bits
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask((!attr.isTranslucent || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE); glDepthMask((!treatAsTranslucent || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
} }
} }
@ -4527,3 +4535,7 @@ Render3DError OpenGLRenderer_2_1::RenderFlush(bool willFlushBuffer32, bool willF
return RENDER3DERROR_NOERR; 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);

View File

@ -631,7 +631,7 @@ protected:
Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16); Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16);
OpenGLTexture* GetLoadedTextureFromPolygon(const POLY &thePoly, bool enableTexturing); 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, u32 &lastPolyAttr, u32 &lastTexParams, u32 &lastTexPalette, u32 &lastViewport); template<OGLPolyDrawMode DRAWMODE> size_t DrawPolygonsForIndexRange(const POLYLIST *polyList, const INDEXLIST *indexList, size_t firstIndex, size_t lastIndex, size_t &indexOffset, bool &lastPolyTreatedAsTranslucent);
template<bool WILLUPDATESTENCILBUFFER> Render3DError DrawAlphaTexturePolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const bool canHaveOpaqueFragments); 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 // OpenGL-specific methods
@ -683,7 +683,7 @@ protected:
virtual Render3DError DrawShadowPolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const u8 opaquePolyID) = 0; virtual Render3DError DrawShadowPolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const u8 opaquePolyID) = 0;
virtual void SetPolygonIndex(const size_t index) = 0; virtual void SetPolygonIndex(const size_t index) = 0;
virtual Render3DError SetupPolygon(const POLY &thePoly, bool willChangeStencilBuffer) = 0; virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer) = 0;
public: public:
OpenGLRenderer(); OpenGLRenderer();
@ -762,7 +762,7 @@ protected:
virtual Render3DError ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes) const; virtual Render3DError ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes) const;
virtual void SetPolygonIndex(const size_t index); virtual void SetPolygonIndex(const size_t index);
virtual Render3DError SetupPolygon(const POLY &thePoly, bool willChangeStencilBuffer); virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer);
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex); virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
virtual Render3DError SetupViewport(const u32 viewportValue); virtual Render3DError SetupViewport(const u32 viewportValue);

View File

@ -638,6 +638,7 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
std::string fogFragShaderString = std::string(FogFragShader_150); std::string fogFragShaderString = std::string(FogFragShader_150);
std::string framebufferOutputVtxShaderString = std::string(FramebufferOutputVtxShader_150); std::string framebufferOutputVtxShaderString = std::string(FramebufferOutputVtxShader_150);
std::string framebufferOutputFragShaderString = std::string(FramebufferOutputFragShader_150); std::string framebufferOutputFragShaderString = std::string(FramebufferOutputFragShader_150);
error = this->InitPostprocessingPrograms(zeroAlphaPixelMaskVtxShaderString, error = this->InitPostprocessingPrograms(zeroAlphaPixelMaskVtxShaderString,
zeroAlphaPixelMaskFragShaderString, zeroAlphaPixelMaskFragShaderString,
edgeMarkVtxShaderString, edgeMarkVtxShaderString,
@ -1198,7 +1199,6 @@ void OpenGLRenderer_3_2::DestroyGeometryProgram()
glDetachShader(OGLRef.programGeometryID, OGLRef.vertexGeometryShaderID); glDetachShader(OGLRef.programGeometryID, OGLRef.vertexGeometryShaderID);
glDetachShader(OGLRef.programGeometryID, OGLRef.fragmentGeometryShaderID); glDetachShader(OGLRef.programGeometryID, OGLRef.fragmentGeometryShaderID);
glDeleteProgram(OGLRef.programGeometryID); glDeleteProgram(OGLRef.programGeometryID);
glDeleteShader(OGLRef.vertexGeometryShaderID); glDeleteShader(OGLRef.vertexGeometryShaderID);
glDeleteShader(OGLRef.fragmentGeometryShaderID); glDeleteShader(OGLRef.fragmentGeometryShaderID);
@ -1642,7 +1642,7 @@ void OpenGLRenderer_3_2::SetPolygonIndex(const size_t index)
glUniform1i(this->ref->uniformPolyStateIndex, index); glUniform1i(this->ref->uniformPolyStateIndex, index);
} }
Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool willChangeStencilBuffer) Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer)
{ {
const PolygonAttributes attr = thePoly.getAttributes(); const PolygonAttributes attr = thePoly.getAttributes();
@ -1697,11 +1697,11 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool willCha
else else
{ {
glStencilFunc(GL_ALWAYS, attr.polygonID, 0x3F); glStencilFunc(GL_ALWAYS, attr.polygonID, 0x3F);
glStencilOp(GL_KEEP, GL_KEEP, (attr.isTranslucent) ? GL_KEEP : GL_REPLACE); glStencilOp(GL_KEEP, GL_KEEP, (treatAsTranslucent) ? GL_KEEP : GL_REPLACE);
glStencilMask(0xFF); // Drawing non-shadow polygons will implicitly reset the stencil buffer bits glStencilMask(0xFF); // Drawing non-shadow polygons will implicitly reset the stencil buffer bits
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask((!attr.isTranslucent || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE); glDepthMask((!treatAsTranslucent || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
} }
} }

View File

@ -99,7 +99,7 @@ protected:
virtual Render3DError ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes) const; virtual Render3DError ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes) const;
virtual void SetPolygonIndex(const size_t index); virtual void SetPolygonIndex(const size_t index);
virtual Render3DError SetupPolygon(const POLY &thePoly, bool willChangeStencilBuffer); virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer);
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex); virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
virtual Render3DError SetFramebufferSize(size_t w, size_t h); virtual Render3DError SetFramebufferSize(size_t w, size_t h);