OpenGL Renderer: It is now possible to toggle certain accuracy-related features on and off so that users can choose where to make their accuracy-performance tradeoffs. These four emulation accuracy features are: 'Shadow polygons', 'Special zero alpha blending', 'Depth-Equals test tolerance', and 'Depth-LEqual polygon facing'.
- New Behavior: Due to the rarity of needing to emulate 'Depth-LEqual polygon facing' and its guaranteed reduction in performance in all games, this accuracy feature is now OFF by default. - Expose these new settings in the Cocoa port UI.
This commit is contained in:
parent
1e18c3fb9f
commit
6f8c060db6
|
@ -25,6 +25,7 @@
|
|||
#include "types.h"
|
||||
#include "ROMReader.h"
|
||||
#include "firmware.h"
|
||||
#include "render3D.h"
|
||||
#include "wifi.h"
|
||||
|
||||
class CFIRMWARE;
|
||||
|
@ -504,6 +505,10 @@ extern struct TCommonSettings
|
|||
, GFX3D_Renderer_TextureDeposterize(false)
|
||||
, GFX3D_Renderer_TextureSmoothing(false)
|
||||
, GFX3D_TXTHack(false)
|
||||
, OpenGL_Emulation_ShadowPolygon(true)
|
||||
, OpenGL_Emulation_SpecialZeroAlphaBlending(true)
|
||||
, OpenGL_Emulation_DepthEqualsTestTolerance(true)
|
||||
, OpenGL_Emulation_DepthLEqualPolygonFacing(false)
|
||||
, jit_max_block_size(12)
|
||||
, loadToMemory(false)
|
||||
, UseExtBIOS(false)
|
||||
|
@ -561,6 +566,11 @@ extern struct TCommonSettings
|
|||
bool GFX3D_Renderer_TextureDeposterize;
|
||||
bool GFX3D_Renderer_TextureSmoothing;
|
||||
bool GFX3D_TXTHack;
|
||||
|
||||
bool OpenGL_Emulation_ShadowPolygon;
|
||||
bool OpenGL_Emulation_SpecialZeroAlphaBlending;
|
||||
bool OpenGL_Emulation_DepthEqualsTestTolerance;
|
||||
bool OpenGL_Emulation_DepthLEqualPolygonFacing;
|
||||
|
||||
bool loadToMemory;
|
||||
|
||||
|
@ -572,7 +582,7 @@ extern struct TCommonSettings
|
|||
|
||||
bool UseExtFirmware;
|
||||
bool UseExtFirmwareSettings;
|
||||
char ExtFirmwarePath[MAX_PATH];
|
||||
char ExtFirmwarePath[MAX_PATH];
|
||||
char ExtFirmwareUserSettingsPath[MAX_PATH];
|
||||
bool BootFromFirmware;
|
||||
FirmwareConfig fwConfig;
|
||||
|
|
|
@ -1056,6 +1056,11 @@ OpenGLRenderer::OpenGLRenderer()
|
|||
willFlipAndConvertFramebufferOnGPU = false;
|
||||
willUsePerSampleZeroDstPass = false;
|
||||
|
||||
_emulateShadowPolygon = true;
|
||||
_emulateSpecialZeroAlphaBlending = true;
|
||||
_emulateDepthEqualsTestTolerance = true;
|
||||
_emulateDepthLEqualPolygonFacing = false;
|
||||
|
||||
// Init OpenGL rendering states
|
||||
ref = new OGLRenderRef;
|
||||
memset(ref, 0, sizeof(OGLRenderRef));
|
||||
|
@ -1648,7 +1653,7 @@ size_t OpenGLRenderer::DrawPolygonsForIndexRange(const POLYLIST *polyList, const
|
|||
|
||||
if (thePoly.attribute.Mode == POLYGON_MODE_SHADOW)
|
||||
{
|
||||
if (DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass)
|
||||
if ((DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass) && this->_emulateShadowPolygon)
|
||||
{
|
||||
this->DrawShadowPolygon(polyPrimitive, vertIndexCount, indexBufferPtr, thePoly.attribute.DepthEqualTest_Enable, thePoly.attribute.TranslucentDepthWrite_Enable, (DRAWMODE == OGLPolyDrawMode_DrawTranslucentPolys), thePoly.attribute.PolygonID);
|
||||
}
|
||||
|
@ -1697,7 +1702,7 @@ Render3DError OpenGLRenderer::DrawAlphaTexturePolygon(const GLenum polyPrimitive
|
|||
|
||||
if (this->isShaderSupported)
|
||||
{
|
||||
if ((DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass) && performDepthEqualTest)
|
||||
if ((DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass) && performDepthEqualTest && this->_emulateDepthEqualsTestTolerance)
|
||||
{
|
||||
if (DRAWMODE == OGLPolyDrawMode_DrawTranslucentPolys)
|
||||
{
|
||||
|
@ -1875,32 +1880,39 @@ Render3DError OpenGLRenderer::DrawAlphaTexturePolygon(const GLenum polyPrimitive
|
|||
{
|
||||
glUniform1i(OGLRef.uniformTexDrawOpaque, GL_TRUE);
|
||||
|
||||
if (isPolyFrontFacing)
|
||||
if (this->_emulateDepthLEqualPolygonFacing)
|
||||
{
|
||||
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);
|
||||
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
|
||||
{
|
||||
glStencilFunc(GL_ALWAYS, 0x40 | opaquePolyID, 0x40);
|
||||
glDrawElements(polyPrimitive, vertIndexCount, GL_UNSIGNED_SHORT, indexBufferPtr);
|
||||
|
||||
glStencilFunc(GL_ALWAYS, opaquePolyID, 0x3F);
|
||||
}
|
||||
|
||||
glUniform1i(OGLRef.uniformTexDrawOpaque, GL_FALSE);
|
||||
|
@ -1926,7 +1938,7 @@ Render3DError OpenGLRenderer::DrawOtherPolygon(const GLenum polyPrimitive,
|
|||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
if ((DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass) && performDepthEqualTest && this->isShaderSupported)
|
||||
if ((DRAWMODE != OGLPolyDrawMode_ZeroAlphaPass) && performDepthEqualTest && this->_emulateDepthEqualsTestTolerance && this->isShaderSupported)
|
||||
{
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
@ -1993,7 +2005,7 @@ 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)
|
||||
else if ((DRAWMODE == OGLPolyDrawMode_DrawOpaquePolys) && this->_emulateDepthLEqualPolygonFacing)
|
||||
{
|
||||
if (isPolyFrontFacing)
|
||||
{
|
||||
|
@ -2033,8 +2045,12 @@ Render3DError OpenGLRenderer::DrawOtherPolygon(const GLenum polyPrimitive,
|
|||
|
||||
Render3DError OpenGLRenderer::ApplyRenderingSettings(const GFX3D_State &renderState)
|
||||
{
|
||||
int oldSelectedMultisampleSize = this->_selectedMultisampleSize;
|
||||
this->_emulateShadowPolygon = CommonSettings.OpenGL_Emulation_ShadowPolygon;
|
||||
this->_emulateSpecialZeroAlphaBlending = CommonSettings.OpenGL_Emulation_SpecialZeroAlphaBlending;
|
||||
this->_emulateDepthEqualsTestTolerance = CommonSettings.OpenGL_Emulation_DepthEqualsTestTolerance;
|
||||
this->_emulateDepthLEqualPolygonFacing = CommonSettings.OpenGL_Emulation_DepthLEqualPolygonFacing;
|
||||
|
||||
int oldSelectedMultisampleSize = this->_selectedMultisampleSize;
|
||||
this->_selectedMultisampleSize = CommonSettings.GFX3D_Renderer_MultisampleSize;
|
||||
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
|
||||
|
||||
|
@ -3690,8 +3706,7 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLYLIST *polyList, con
|
|||
glDisable(GL_BLEND);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glStencilFunc(GL_ALWAYS, 0x40, 0x40);
|
||||
glDrawBuffer(GL_NONE);
|
||||
|
@ -3856,8 +3871,7 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
|
|||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboPostprocessIndexID);
|
||||
|
@ -4115,7 +4129,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
|
|||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
glStencilMask(0xFF);
|
||||
|
||||
if (this->_needsZeroDstAlphaPass)
|
||||
if (this->_needsZeroDstAlphaPass && this->_emulateSpecialZeroAlphaBlending)
|
||||
{
|
||||
if (polyList->opaqueCount == 0)
|
||||
{
|
||||
|
@ -4197,11 +4211,8 @@ Render3DError OpenGLRenderer_1_2::RenderEdgeMarking(const u16 *colorTable, const
|
|||
|
||||
// Set up the postprocessing states
|
||||
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboPostprocessIndexID);
|
||||
|
@ -4218,31 +4229,45 @@ Render3DError OpenGLRenderer_1_2::RenderEdgeMarking(const u16 *colorTable, const
|
|||
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)(sizeof(GLfloat) * 8));
|
||||
}
|
||||
|
||||
// Pass 1: Determine the pixels with zero alpha
|
||||
glDrawBuffer(GL_NONE);
|
||||
glStencilFunc(GL_ALWAYS, 0x40, 0x40);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilMask(0x40);
|
||||
glClearStencil(0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
glUseProgram(OGLRef.programGeometryZeroDstAlphaID);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Pass 2: Unblended edge mark colors to zero-alpha pixels
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glUseProgram(OGLRef.programEdgeMarkID);
|
||||
glUniform2f(OGLRef.uniformFramebufferSize, this->_framebufferWidth, this->_framebufferHeight);
|
||||
glUniform4fv(OGLRef.uniformStateEdgeColor, 8, oglColor);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
glStencilFunc(GL_NOTEQUAL, 0x40, 0x40);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Pass 3: Blended edge mark
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
if (this->_emulateSpecialZeroAlphaBlending)
|
||||
{
|
||||
// Pass 1: Determine the pixels with zero alpha
|
||||
glDrawBuffer(GL_NONE);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_ALWAYS, 0x40, 0x40);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilMask(0x40);
|
||||
glClearStencil(0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
glUseProgram(OGLRef.programGeometryZeroDstAlphaID);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Pass 2: Unblended edge mark colors to zero-alpha pixels
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glUseProgram(OGLRef.programEdgeMarkID);
|
||||
glUniform2f(OGLRef.uniformFramebufferSize, this->_framebufferWidth, this->_framebufferHeight);
|
||||
glUniform4fv(OGLRef.uniformStateEdgeColor, 8, oglColor);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
glStencilFunc(GL_NOTEQUAL, 0x40, 0x40);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Pass 3: Blended edge mark
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glUseProgram(OGLRef.programEdgeMarkID);
|
||||
glUniform2f(OGLRef.uniformFramebufferSize, this->_framebufferWidth, this->_framebufferHeight);
|
||||
glUniform4fv(OGLRef.uniformStateEdgeColor, 8, oglColor);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
|
||||
if (this->isVAOSupported)
|
||||
{
|
||||
|
@ -4296,8 +4321,7 @@ Render3DError OpenGLRenderer_1_2::RenderFog(const u8 *densityTable, const u32 co
|
|||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboPostprocessIndexID);
|
||||
|
@ -4527,29 +4551,32 @@ Render3DError OpenGLRenderer_1_2::SetupPolygon(const POLY &thePoly, bool treatAs
|
|||
// Handle drawing states for the polygon
|
||||
if (thePoly.attribute.Mode == POLYGON_MODE_SHADOW)
|
||||
{
|
||||
// Set up shadow polygon states.
|
||||
//
|
||||
// See comments in DrawShadowPolygon() for more information about
|
||||
// how this 5-pass process works in OpenGL.
|
||||
if (thePoly.attribute.PolygonID == 0)
|
||||
if (this->_emulateShadowPolygon)
|
||||
{
|
||||
// 1st pass: Use stencil buffer bit 7 (0x80) for the shadow volume mask.
|
||||
// Write only on depth-fail.
|
||||
glStencilFunc(GL_ALWAYS, 0x80, 0x80);
|
||||
glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
|
||||
glStencilMask(0x80);
|
||||
// Set up shadow polygon states.
|
||||
//
|
||||
// See comments in DrawShadowPolygon() for more information about
|
||||
// how this 5-pass process works in OpenGL.
|
||||
if (thePoly.attribute.PolygonID == 0)
|
||||
{
|
||||
// 1st pass: Use stencil buffer bit 7 (0x80) for the shadow volume mask.
|
||||
// Write only on depth-fail.
|
||||
glStencilFunc(GL_ALWAYS, 0x80, 0x80);
|
||||
glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
|
||||
glStencilMask(0x80);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2nd pass: Compare stencil buffer bits 0-5 (0x3F) with this polygon's ID. If this stencil
|
||||
// test fails, remove the fragment from the shadow volume mask by clearing bit 7.
|
||||
glStencilFunc(GL_NOTEQUAL, thePoly.attribute.PolygonID, 0x3F);
|
||||
glStencilOp(GL_ZERO, GL_KEEP, GL_KEEP);
|
||||
glStencilMask(0x80);
|
||||
}
|
||||
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2nd pass: Compare stencil buffer bits 0-5 (0x3F) with this polygon's ID. If this stencil
|
||||
// test fails, remove the fragment from the shadow volume mask by clearing bit 7.
|
||||
glStencilFunc(GL_NOTEQUAL, thePoly.attribute.PolygonID, 0x3F);
|
||||
glStencilOp(GL_ZERO, GL_KEEP, GL_KEEP);
|
||||
glStencilMask(0x80);
|
||||
}
|
||||
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -636,6 +636,11 @@ protected:
|
|||
bool willFlipAndConvertFramebufferOnGPU;
|
||||
bool willUsePerSampleZeroDstPass;
|
||||
|
||||
bool _emulateShadowPolygon;
|
||||
bool _emulateSpecialZeroAlphaBlending;
|
||||
bool _emulateDepthEqualsTestTolerance;
|
||||
bool _emulateDepthLEqualPolygonFacing;
|
||||
|
||||
FragmentColor *_mappedFramebuffer;
|
||||
FragmentColor *_workingTextureUnpackBuffer;
|
||||
bool _pixelReadNeedsFinish;
|
||||
|
|
|
@ -1385,8 +1385,7 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLYLIST *polyList, con
|
|||
glDisable(GL_BLEND);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glStencilFunc(GL_ALWAYS, 0x40, 0x40);
|
||||
glDrawBuffer(GL_NONE);
|
||||
|
@ -1503,8 +1502,7 @@ Render3DError OpenGLRenderer_3_2::ReadBackPixels()
|
|||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboPostprocessIndexID);
|
||||
|
@ -1701,39 +1699,48 @@ Render3DError OpenGLRenderer_3_2::RenderEdgeMarking(const u16 *colorTable, const
|
|||
|
||||
// Set up the postprocessing states
|
||||
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboPostprocessIndexID);
|
||||
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
|
||||
|
||||
// Pass 1: Determine the pixels with zero alpha
|
||||
glDrawBuffer(GL_NONE);
|
||||
glStencilFunc(GL_ALWAYS, 0x40, 0x40);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilMask(0x40);
|
||||
glDepthMask(GL_FALSE);
|
||||
glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
|
||||
|
||||
glUseProgram(OGLRef.programGeometryZeroDstAlphaID);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Pass 2: Unblended edge mark colors to zero-alpha pixels
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glUseProgram(OGLRef.programEdgeMarkID);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
glStencilFunc(GL_NOTEQUAL, 0x40, 0x40);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Pass 3: Blended edge mark
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
if (this->_emulateSpecialZeroAlphaBlending)
|
||||
{
|
||||
// Pass 1: Determine the pixels with zero alpha
|
||||
glDrawBuffer(GL_NONE);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_ALWAYS, 0x40, 0x40);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilMask(0x40);
|
||||
glDepthMask(GL_FALSE);
|
||||
glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
|
||||
|
||||
glUseProgram(OGLRef.programGeometryZeroDstAlphaID);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Pass 2: Unblended edge mark colors to zero-alpha pixels
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glUseProgram(OGLRef.programEdgeMarkID);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
glStencilFunc(GL_NOTEQUAL, 0x40, 0x40);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Pass 3: Blended edge mark
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glUseProgram(OGLRef.programEdgeMarkID);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
|
@ -1755,8 +1762,7 @@ Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 co
|
|||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboPostprocessVtxID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboPostprocessIndexID);
|
||||
|
@ -1900,29 +1906,32 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly, bool treatAs
|
|||
// Handle drawing states for the polygon
|
||||
if (thePoly.attribute.Mode == POLYGON_MODE_SHADOW)
|
||||
{
|
||||
// Set up shadow polygon states.
|
||||
//
|
||||
// See comments in DrawShadowPolygon() for more information about
|
||||
// how this 5-pass process works in OpenGL.
|
||||
if (thePoly.attribute.PolygonID == 0)
|
||||
if (this->_emulateShadowPolygon)
|
||||
{
|
||||
// 1st pass: Use stencil buffer bit 7 (0x80) for the shadow volume mask.
|
||||
// Write only on depth-fail.
|
||||
glStencilFunc(GL_ALWAYS, 0x80, 0x80);
|
||||
glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
|
||||
glStencilMask(0x80);
|
||||
// Set up shadow polygon states.
|
||||
//
|
||||
// See comments in DrawShadowPolygon() for more information about
|
||||
// how this 5-pass process works in OpenGL.
|
||||
if (thePoly.attribute.PolygonID == 0)
|
||||
{
|
||||
// 1st pass: Use stencil buffer bit 7 (0x80) for the shadow volume mask.
|
||||
// Write only on depth-fail.
|
||||
glStencilFunc(GL_ALWAYS, 0x80, 0x80);
|
||||
glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
|
||||
glStencilMask(0x80);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2nd pass: Compare stencil buffer bits 0-5 (0x3F) with this polygon's ID. If this stencil
|
||||
// test fails, remove the fragment from the shadow volume mask by clearing bit 7.
|
||||
glStencilFunc(GL_NOTEQUAL, thePoly.attribute.PolygonID, 0x3F);
|
||||
glStencilOp(GL_ZERO, GL_KEEP, GL_KEEP);
|
||||
glStencilMask(0x80);
|
||||
}
|
||||
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2nd pass: Compare stencil buffer bits 0-5 (0x3F) with this polygon's ID. If this stencil
|
||||
// test fails, remove the fragment from the shadow volume mask by clearing bit 7.
|
||||
glStencilFunc(GL_NOTEQUAL, thePoly.attribute.PolygonID, 0x3F);
|
||||
glStencilOp(GL_ZERO, GL_KEEP, GL_KEEP);
|
||||
glStencilMask(0x80);
|
||||
}
|
||||
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -864,6 +864,14 @@
|
|||
<false/>
|
||||
<key>Render3D_Threads</key>
|
||||
<integer>0</integer>
|
||||
<key>Render3D_OpenGL_EmulateShadowPolygon</key>
|
||||
<true/>
|
||||
<key>Render3D_OpenGL_EmulateSpecialZeroAlphaBlending</key>
|
||||
<true/>
|
||||
<key>Render3D_OpenGL_EmulateDepthEqualTestTolerance</key>
|
||||
<true/>
|
||||
<key>Render3D_OpenGL_EmulateDepthLEqualPolygonFacing</key>
|
||||
<false/>
|
||||
<key>RomInfoPanel_SectionViewState</key>
|
||||
<dict/>
|
||||
<key>AVCaptureTool_DirectoryPath</key>
|
||||
|
|
|
@ -168,6 +168,10 @@ typedef std::map<CGDirectDisplayID, int64_t> DisplayLinkFlushTimeLimitMap;
|
|||
@property (assign) BOOL render3DTextureSmoothing;
|
||||
@property (assign) NSUInteger render3DTextureScalingFactor;
|
||||
@property (assign) BOOL render3DFragmentSamplingHack;
|
||||
@property (assign) BOOL openGLEmulateShadowPolygon;
|
||||
@property (assign) BOOL openGLEmulateSpecialZeroAlphaBlending;
|
||||
@property (assign) BOOL openGLEmulateDepthEqualsTestTolerance;
|
||||
@property (assign) BOOL openGLEmulateDepthLEqualPolygonFacing;
|
||||
|
||||
#ifdef ENABLE_SHARED_FETCH_OBJECT
|
||||
@property (readonly, nonatomic) GPUClientFetchObject *fetchObject;
|
||||
|
|
|
@ -121,6 +121,10 @@ public:
|
|||
@dynamic render3DTextureSmoothing;
|
||||
@dynamic render3DTextureScalingFactor;
|
||||
@dynamic render3DFragmentSamplingHack;
|
||||
@dynamic openGLEmulateShadowPolygon;
|
||||
@dynamic openGLEmulateSpecialZeroAlphaBlending;
|
||||
@dynamic openGLEmulateDepthEqualsTestTolerance;
|
||||
@dynamic openGLEmulateDepthLEqualPolygonFacing;
|
||||
|
||||
#ifdef ENABLE_SHARED_FETCH_OBJECT
|
||||
@synthesize fetchObject;
|
||||
|
@ -719,6 +723,70 @@ public:
|
|||
return state;
|
||||
}
|
||||
|
||||
- (void) setOpenGLEmulateShadowPolygon:(BOOL)state
|
||||
{
|
||||
gpuEvent->ApplyRender3DSettingsLock();
|
||||
CommonSettings.OpenGL_Emulation_ShadowPolygon = (state) ? true : false;
|
||||
gpuEvent->ApplyRender3DSettingsUnlock();
|
||||
}
|
||||
|
||||
- (BOOL) openGLEmulateShadowPolygon
|
||||
{
|
||||
gpuEvent->ApplyRender3DSettingsLock();
|
||||
const BOOL state = (CommonSettings.OpenGL_Emulation_ShadowPolygon) ? YES : NO;
|
||||
gpuEvent->ApplyRender3DSettingsUnlock();
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setOpenGLEmulateSpecialZeroAlphaBlending:(BOOL)state
|
||||
{
|
||||
gpuEvent->ApplyRender3DSettingsLock();
|
||||
CommonSettings.OpenGL_Emulation_SpecialZeroAlphaBlending = (state) ? true : false;
|
||||
gpuEvent->ApplyRender3DSettingsUnlock();
|
||||
}
|
||||
|
||||
- (BOOL) openGLEmulateSpecialZeroAlphaBlending
|
||||
{
|
||||
gpuEvent->ApplyRender3DSettingsLock();
|
||||
const BOOL state = (CommonSettings.OpenGL_Emulation_SpecialZeroAlphaBlending) ? YES : NO;
|
||||
gpuEvent->ApplyRender3DSettingsUnlock();
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setOpenGLEmulateDepthEqualsTestTolerance:(BOOL)state
|
||||
{
|
||||
gpuEvent->ApplyRender3DSettingsLock();
|
||||
CommonSettings.OpenGL_Emulation_DepthEqualsTestTolerance = (state) ? true : false;
|
||||
gpuEvent->ApplyRender3DSettingsUnlock();
|
||||
}
|
||||
|
||||
- (BOOL) openGLEmulateDepthEqualsTestTolerance
|
||||
{
|
||||
gpuEvent->ApplyRender3DSettingsLock();
|
||||
const BOOL state = (CommonSettings.OpenGL_Emulation_DepthEqualsTestTolerance) ? YES : NO;
|
||||
gpuEvent->ApplyRender3DSettingsUnlock();
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setOpenGLEmulateDepthLEqualPolygonFacing:(BOOL)state
|
||||
{
|
||||
gpuEvent->ApplyRender3DSettingsLock();
|
||||
CommonSettings.OpenGL_Emulation_DepthLEqualPolygonFacing = (state) ? true : false;
|
||||
gpuEvent->ApplyRender3DSettingsUnlock();
|
||||
}
|
||||
|
||||
- (BOOL) openGLEmulateDepthLEqualPolygonFacing
|
||||
{
|
||||
gpuEvent->ApplyRender3DSettingsLock();
|
||||
const BOOL state = (CommonSettings.OpenGL_Emulation_DepthLEqualPolygonFacing) ? YES : NO;
|
||||
gpuEvent->ApplyRender3DSettingsUnlock();
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
- (void) setLayerMainGPU:(BOOL)gpuState
|
||||
{
|
||||
gpuEvent->ApplyGPUSettingsLock();
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -961,6 +961,11 @@
|
|||
[[NSUserDefaults standardUserDefaults] setInteger:[[cdsCore cdsGPU] gpuScale] forKey:@"Render3D_ScalingFactor"];
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:[[cdsCore cdsGPU] gpuColorFormat] forKey:@"Render3D_ColorFormat"];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setBool:[[cdsCore cdsGPU] openGLEmulateShadowPolygon] forKey:@"Render3D_OpenGL_EmulateShadowPolygon"];
|
||||
[[NSUserDefaults standardUserDefaults] setBool:[[cdsCore cdsGPU] openGLEmulateSpecialZeroAlphaBlending] forKey:@"Render3D_OpenGL_EmulateSpecialZeroAlphaBlending"];
|
||||
[[NSUserDefaults standardUserDefaults] setBool:[[cdsCore cdsGPU] openGLEmulateDepthEqualsTestTolerance] forKey:@"Render3D_OpenGL_EmulateDepthEqualTestTolerance"];
|
||||
[[NSUserDefaults standardUserDefaults] setBool:[[cdsCore cdsGPU] openGLEmulateDepthLEqualPolygonFacing] forKey:@"Render3D_OpenGL_EmulateDepthLEqualPolygonFacing"];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
|
||||
|
@ -2388,6 +2393,12 @@
|
|||
[[cdsCore cdsGPU] setRender3DFragmentSamplingHack:[[NSUserDefaults standardUserDefaults] boolForKey:@"Render3D_FragmentSamplingHack"]];
|
||||
[[cdsCore cdsGPU] setGpuScale:(NSUInteger)[[NSUserDefaults standardUserDefaults] integerForKey:@"Render3D_ScalingFactor"]];
|
||||
[[cdsCore cdsGPU] setGpuColorFormat:(NSUInteger)[[NSUserDefaults standardUserDefaults] integerForKey:@"Render3D_ColorFormat"]];
|
||||
|
||||
[[cdsCore cdsGPU] setOpenGLEmulateShadowPolygon:[[NSUserDefaults standardUserDefaults] boolForKey:@"Render3D_OpenGL_EmulateShadowPolygon"]];
|
||||
[[cdsCore cdsGPU] setOpenGLEmulateSpecialZeroAlphaBlending:[[NSUserDefaults standardUserDefaults] boolForKey:@"Render3D_OpenGL_EmulateSpecialZeroAlphaBlending"]];
|
||||
[[cdsCore cdsGPU] setOpenGLEmulateDepthEqualsTestTolerance:[[NSUserDefaults standardUserDefaults] boolForKey:@"Render3D_OpenGL_EmulateDepthEqualTestTolerance"]];
|
||||
[[cdsCore cdsGPU] setOpenGLEmulateDepthLEqualPolygonFacing:[[NSUserDefaults standardUserDefaults] boolForKey:@"Render3D_OpenGL_EmulateDepthLEqualPolygonFacing"]];
|
||||
|
||||
[[[cdsCore cdsGPU] sharedData] fetchSynchronousAtIndex:0];
|
||||
|
||||
// Set the stylus options per user preferences.
|
||||
|
|
Loading…
Reference in New Issue