GFX3D: Also treat wireframe polygons using A3I5/A5I3 textures as opaque if the polygon is a Decal or Shadow polygon.
- Also do a few readability improvements in the OpenGL renderer.
This commit is contained in:
parent
4fb55bddb9
commit
65c5cdd712
|
@ -2903,17 +2903,18 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
|
|||
|
||||
// Render the polygons
|
||||
this->SetPolygonIndex(i);
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
|
||||
if ( ((thePoly.getTexParamTexFormat() == TEXMODE_A3I5) || (thePoly.getTexParamTexFormat() == TEXMODE_A5I3)) && (thePoly.getAttributePolygonMode() != POLYGON_MODE_SHADOW) && (thePoly.isOpaque() || thePoly.isWireframe()) )
|
||||
if (thePoly.getAttributePolygonMode() == POLYGON_MODE_SHADOW)
|
||||
{
|
||||
const GLboolean enableDepthWrite = ( (thePoly.getAttributePolygonMode() == POLYGON_MODE_DECAL && thePoly.isOpaque()) || thePoly.getAttributeEnableAlphaDepthWrite() ) ? GL_TRUE : GL_FALSE;
|
||||
this->DrawAlphaTextureOpaqueFragments(polyPrimitive, vertIndexCount, indexBufferPtr, enableDepthWrite);
|
||||
this->DrawShadowPolygon(polyPrimitive, vertIndexCount, indexBufferPtr, thePoly.getAttributeEnableAlphaDepthWrite(), thePoly.isTranslucent(), thePoly.getAttributePolygonID());
|
||||
}
|
||||
else if ( (thePoly.getAttributePolygonMode() == POLYGON_MODE_SHADOW) && (thePoly.getAttributePolygonID() != 0) )
|
||||
else if ( (thePoly.getTexParamTexFormat() == TEXMODE_A3I5) || (thePoly.getTexParamTexFormat() == TEXMODE_A5I3) )
|
||||
{
|
||||
const GLboolean enableDepthWrite = ( thePoly.isOpaque() || thePoly.getAttributeEnableAlphaDepthWrite() ) ? GL_TRUE : GL_FALSE;
|
||||
this->DrawShadowPolygon(polyPrimitive, vertIndexCount, indexBufferPtr, enableDepthWrite, (thePoly.isOpaque()) ? thePoly.getAttributePolygonID() : 0);
|
||||
this->DrawAlphaTexturePolygon(polyPrimitive, vertIndexCount, indexBufferPtr, thePoly.getAttributeEnableAlphaDepthWrite(), thePoly.isTranslucent(), thePoly.isWireframe() || thePoly.isOpaque());
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
}
|
||||
|
||||
indexBufferPtr += vertIndexCount;
|
||||
|
@ -3248,34 +3249,51 @@ Render3DError OpenGLRenderer_1_2::SetupViewport(const u32 viewportValue)
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::DrawAlphaTextureOpaqueFragments(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const GLboolean enableDepthWrite)
|
||||
Render3DError OpenGLRenderer_1_2::DrawAlphaTexturePolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const bool canHaveOpaqueFragments)
|
||||
{
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
if (this->isShaderSupported)
|
||||
{
|
||||
const OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glUniform1i(OGLRef.uniformTexDrawOpaque, GL_TRUE);
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
glUniform1i(OGLRef.uniformTexDrawOpaque, GL_FALSE);
|
||||
if (isTranslucent)
|
||||
{
|
||||
// Draw the translucent fragments.
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
|
||||
// Draw the opaque fragments if they might exist.
|
||||
if (canHaveOpaqueFragments)
|
||||
{
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
glUniform1i(OGLRef.uniformTexDrawOpaque, GL_TRUE);
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
glUniform1i(OGLRef.uniformTexDrawOpaque, GL_FALSE);
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glDepthMask((enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the polygon as completely opaque.
|
||||
glUniform1i(OGLRef.uniformTexDrawOpaque, GL_TRUE);
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
glUniform1i(OGLRef.uniformTexDrawOpaque, GL_FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
}
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glDepthMask(enableDepthWrite);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::DrawShadowPolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const GLboolean enableDepthWrite, const u8 opaquePolyID)
|
||||
Render3DError OpenGLRenderer_1_2::DrawShadowPolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const u8 opaquePolyID)
|
||||
{
|
||||
// Shadow polygons are actually drawn over the course of multiple passes.
|
||||
// Note that the 1st and 2nd passes are performed in SetupPolygon().
|
||||
// Note that the 1st and 2nd passes are performed using states from SetupPolygon().
|
||||
//
|
||||
// 1st pass (NDS driven): The NDS creates the shadow volume and updates only the
|
||||
// stencil buffer, writing to bit 0x40. Color and depth writes are disabled for this
|
||||
|
@ -3299,6 +3317,16 @@ Render3DError OpenGLRenderer_1_2::DrawShadowPolygon(const GLenum polyPrimitive,
|
|||
// Since opaque polygons need to update their polygon IDs, we update only the stencil
|
||||
// buffer with the polygon ID. Color and depth values are disabled for this pass.
|
||||
|
||||
// 1st pass: Create the shadow volume.
|
||||
if (opaquePolyID == 0)
|
||||
{
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
// 2nd pass: Do the polygon ID check.
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
|
||||
// 3rd pass: Draw the shadow polygon.
|
||||
glStencilFunc(GL_EQUAL, 0xC0, 0xC0);
|
||||
// Technically, a depth-fail result should also reset the stencil buffer bits, but
|
||||
|
@ -3307,7 +3335,7 @@ Render3DError OpenGLRenderer_1_2::DrawShadowPolygon(const GLenum polyPrimitive,
|
|||
glStencilOp(GL_ZERO, GL_KEEP, GL_ZERO);
|
||||
glStencilMask(0xC0);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDepthMask(enableDepthWrite);
|
||||
glDepthMask((!isTranslucent || enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE);
|
||||
|
||||
if (this->isShaderSupported)
|
||||
{
|
||||
|
@ -3328,7 +3356,7 @@ Render3DError OpenGLRenderer_1_2::DrawShadowPolygon(const GLenum polyPrimitive,
|
|||
glDepthMask(GL_FALSE);
|
||||
|
||||
// 4th pass: Update the polygon IDs in the stencil buffer if the shadow polygons are opaque.
|
||||
if (opaquePolyID != 0)
|
||||
if (!isTranslucent)
|
||||
{
|
||||
glStencilFunc(GL_ALWAYS, opaquePolyID, 0x3F);
|
||||
glStencilMask(0x3F);
|
||||
|
|
|
@ -669,8 +669,8 @@ protected:
|
|||
virtual Render3DError DownsampleFBO() = 0;
|
||||
virtual Render3DError ReadBackPixels() = 0;
|
||||
|
||||
virtual Render3DError DrawAlphaTextureOpaqueFragments(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const GLboolean enableDepthWrite) = 0;
|
||||
virtual Render3DError DrawShadowPolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const GLboolean enableDepthWrite, const u8 opaquePolyID) = 0;
|
||||
virtual Render3DError DrawAlphaTexturePolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const bool canHaveOpaqueFragments) = 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;
|
||||
|
||||
public:
|
||||
|
@ -752,8 +752,8 @@ protected:
|
|||
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
|
||||
virtual Render3DError SetupViewport(const u32 viewportValue);
|
||||
|
||||
virtual Render3DError DrawAlphaTextureOpaqueFragments(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const GLboolean enableDepthWrite);
|
||||
virtual Render3DError DrawShadowPolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const GLboolean enableDepthWrite, const u8 opaquePolyID);
|
||||
virtual Render3DError DrawAlphaTexturePolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const bool canHaveOpaqueFragments);
|
||||
virtual Render3DError DrawShadowPolygon(const GLenum polyPrimitive, const GLsizei vertIndexCount, const GLushort *indexBufferPtr, const bool enableAlphaDepthWrite, const bool isTranslucent, const u8 opaquePolyID);
|
||||
|
||||
public:
|
||||
~OpenGLRenderer_1_2();
|
||||
|
|
|
@ -452,11 +452,9 @@ struct POLY {
|
|||
|
||||
bool isTranslucent() const
|
||||
{
|
||||
const bool isOpaque = this->isOpaque();
|
||||
|
||||
// First, check if the polygon is wireframe or opaque.
|
||||
// If neither, then it must be translucent.
|
||||
if (!this->isWireframe() && !isOpaque)
|
||||
if (!this->isWireframe() && !this->isOpaque())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -466,7 +464,7 @@ struct POLY {
|
|||
const PolygonMode mode = this->getAttributePolygonMode();
|
||||
|
||||
//a5i3 or a3i5 -> translucent
|
||||
if ( (texFormat == TEXMODE_A3I5 || texFormat == TEXMODE_A5I3) && !(isOpaque && (mode == POLYGON_MODE_DECAL || mode == POLYGON_MODE_SHADOW)) )
|
||||
if ( (texFormat == TEXMODE_A3I5 || texFormat == TEXMODE_A5I3) && (mode != POLYGON_MODE_DECAL && mode != POLYGON_MODE_SHADOW) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue