mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 13:47:57 +03:00
Implement a specific case of alpha testing (depth discard) using extensions.
This commit is contained in:
parent
8f201ab7c2
commit
3fddb1fe69
3 changed files with 63 additions and 7 deletions
|
@ -313,6 +313,10 @@ void CGSH_OpenGL::CheckExtensions()
|
||||||
{
|
{
|
||||||
m_hasFramebufferFetchExtension = true;
|
m_hasFramebufferFetchExtension = true;
|
||||||
}
|
}
|
||||||
|
else if(!strcmp(extensionName, "GL_ARM_shader_framebuffer_fetch_depth_stencil"))
|
||||||
|
{
|
||||||
|
m_hasFramebufferDepthFetchExtension = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1125,6 +1129,7 @@ void CGSH_OpenGL::FillShaderCapsFromTest(SHADERCAPS& shaderCaps, const uint64& t
|
||||||
{
|
{
|
||||||
shaderCaps.hasAlphaTest = m_alphaTestingEnabled ? 1 : 0;
|
shaderCaps.hasAlphaTest = m_alphaTestingEnabled ? 1 : 0;
|
||||||
shaderCaps.alphaTestMethod = test.nAlphaMethod;
|
shaderCaps.alphaTestMethod = test.nAlphaMethod;
|
||||||
|
shaderCaps.alphaTestFailMethod = test.nAlphaFail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -85,10 +85,11 @@ private:
|
||||||
unsigned int hasFog : 1;
|
unsigned int hasFog : 1;
|
||||||
unsigned int hasAlphaTest : 1;
|
unsigned int hasAlphaTest : 1;
|
||||||
unsigned int alphaTestMethod : 3;
|
unsigned int alphaTestMethod : 3;
|
||||||
|
unsigned int alphaTestFailMethod : 2;
|
||||||
unsigned int hasDestAlphaTest : 1;
|
unsigned int hasDestAlphaTest : 1;
|
||||||
unsigned int destAlphaTestRef : 1;
|
unsigned int destAlphaTestRef : 1;
|
||||||
unsigned int colorOutputWhite : 1;
|
unsigned int colorOutputWhite : 1;
|
||||||
unsigned int padding : 10;
|
unsigned int padding : 8;
|
||||||
|
|
||||||
bool isIndexedTextureSource() const
|
bool isIndexedTextureSource() const
|
||||||
{
|
{
|
||||||
|
@ -316,7 +317,7 @@ private:
|
||||||
Framework::OpenGl::CShader GenerateVertexShader(const SHADERCAPS&);
|
Framework::OpenGl::CShader GenerateVertexShader(const SHADERCAPS&);
|
||||||
Framework::OpenGl::CShader GenerateFragmentShader(const SHADERCAPS&);
|
Framework::OpenGl::CShader GenerateFragmentShader(const SHADERCAPS&);
|
||||||
std::string GenerateTexCoordClampingSection(TEXTURE_CLAMP_MODE, const char*);
|
std::string GenerateTexCoordClampingSection(TEXTURE_CLAMP_MODE, const char*);
|
||||||
std::string GenerateAlphaTestSection(ALPHA_TEST_METHOD);
|
std::string GenerateAlphaTestSection(ALPHA_TEST_METHOD, ALPHA_TEST_FAIL_METHOD);
|
||||||
|
|
||||||
Framework::OpenGl::ProgramPtr GeneratePresentProgram();
|
Framework::OpenGl::ProgramPtr GeneratePresentProgram();
|
||||||
Framework::OpenGl::CBuffer GeneratePresentVertexBuffer();
|
Framework::OpenGl::CBuffer GeneratePresentVertexBuffer();
|
||||||
|
@ -462,4 +463,5 @@ private:
|
||||||
VertexBuffer m_vertexBuffer;
|
VertexBuffer m_vertexBuffer;
|
||||||
|
|
||||||
bool m_hasFramebufferFetchExtension = false;
|
bool m_hasFramebufferFetchExtension = false;
|
||||||
|
bool m_hasFramebufferDepthFetchExtension = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -137,8 +137,35 @@ Framework::OpenGl::CShader CGSH_OpenGL::GenerateFragmentShader(const SHADERCAPS&
|
||||||
{
|
{
|
||||||
std::stringstream shaderBuilder;
|
std::stringstream shaderBuilder;
|
||||||
|
|
||||||
|
bool useFramebufferFetch = false;
|
||||||
|
bool useFramebufferDepthFetch = false;
|
||||||
|
|
||||||
|
auto alphaTestFailMethod = static_cast<ALPHA_TEST_FAIL_METHOD>(caps.alphaTestFailMethod);
|
||||||
|
if(caps.hasAlphaTest)
|
||||||
|
{
|
||||||
|
switch(alphaTestFailMethod)
|
||||||
|
{
|
||||||
|
case ALPHA_TEST_FAIL_KEEP:
|
||||||
|
case ALPHA_TEST_FAIL_RGBONLY:
|
||||||
|
case ALPHA_TEST_FAIL_ZBONLY:
|
||||||
|
//TODO: Check how we can implement these correctly
|
||||||
|
alphaTestFailMethod = ALPHA_TEST_FAIL_KEEP;
|
||||||
|
break;
|
||||||
|
case ALPHA_TEST_FAIL_FBONLY:
|
||||||
|
if(!m_hasFramebufferDepthFetchExtension)
|
||||||
|
{
|
||||||
|
alphaTestFailMethod = ALPHA_TEST_FAIL_KEEP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
useFramebufferDepthFetch |= true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool writeDestAlphaTest = caps.hasDestAlphaTest && m_hasFramebufferFetchExtension;
|
bool writeDestAlphaTest = caps.hasDestAlphaTest && m_hasFramebufferFetchExtension;
|
||||||
bool useFramebufferFetch = writeDestAlphaTest;
|
useFramebufferFetch |= writeDestAlphaTest;
|
||||||
|
|
||||||
shaderBuilder << GLSL_VERSION << std::endl;
|
shaderBuilder << GLSL_VERSION << std::endl;
|
||||||
|
|
||||||
|
@ -147,6 +174,11 @@ Framework::OpenGl::CShader CGSH_OpenGL::GenerateFragmentShader(const SHADERCAPS&
|
||||||
shaderBuilder << "#extension GL_EXT_shader_framebuffer_fetch : require" << std::endl;
|
shaderBuilder << "#extension GL_EXT_shader_framebuffer_fetch : require" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(useFramebufferDepthFetch)
|
||||||
|
{
|
||||||
|
shaderBuilder << "#extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
shaderBuilder << "precision mediump float;" << std::endl;
|
shaderBuilder << "precision mediump float;" << std::endl;
|
||||||
|
|
||||||
shaderBuilder << "in highp float v_depth;" << std::endl;
|
shaderBuilder << "in highp float v_depth;" << std::endl;
|
||||||
|
@ -233,6 +265,8 @@ Framework::OpenGl::CShader CGSH_OpenGL::GenerateFragmentShader(const SHADERCAPS&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shaderBuilder << " highp float fragDepth = v_depth;" << std::endl;
|
||||||
|
|
||||||
shaderBuilder << " highp vec3 texCoord = v_texCoord;" << std::endl;
|
shaderBuilder << " highp vec3 texCoord = v_texCoord;" << std::endl;
|
||||||
shaderBuilder << " texCoord.st /= texCoord.p;" << std::endl;
|
shaderBuilder << " texCoord.st /= texCoord.p;" << std::endl;
|
||||||
|
|
||||||
|
@ -348,7 +382,7 @@ Framework::OpenGl::CShader CGSH_OpenGL::GenerateFragmentShader(const SHADERCAPS&
|
||||||
|
|
||||||
if(caps.hasAlphaTest)
|
if(caps.hasAlphaTest)
|
||||||
{
|
{
|
||||||
shaderBuilder << GenerateAlphaTestSection(static_cast<ALPHA_TEST_METHOD>(caps.alphaTestMethod));
|
shaderBuilder << GenerateAlphaTestSection(static_cast<ALPHA_TEST_METHOD>(caps.alphaTestMethod), alphaTestFailMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(caps.hasFog)
|
if(caps.hasFog)
|
||||||
|
@ -374,7 +408,7 @@ Framework::OpenGl::CShader CGSH_OpenGL::GenerateFragmentShader(const SHADERCAPS&
|
||||||
shaderBuilder << " fragColor.xyz = vec3(1, 1, 1);" << std::endl;
|
shaderBuilder << " fragColor.xyz = vec3(1, 1, 1);" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderBuilder << " gl_FragDepth = v_depth;" << std::endl;
|
shaderBuilder << " gl_FragDepth = fragDepth;" << std::endl;
|
||||||
|
|
||||||
shaderBuilder << "}" << std::endl;
|
shaderBuilder << "}" << std::endl;
|
||||||
|
|
||||||
|
@ -418,7 +452,7 @@ std::string CGSH_OpenGL::GenerateTexCoordClampingSection(TEXTURE_CLAMP_MODE clam
|
||||||
return shaderSource;
|
return shaderSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CGSH_OpenGL::GenerateAlphaTestSection(ALPHA_TEST_METHOD testMethod)
|
std::string CGSH_OpenGL::GenerateAlphaTestSection(ALPHA_TEST_METHOD testMethod, ALPHA_TEST_FAIL_METHOD testFailMethod)
|
||||||
{
|
{
|
||||||
std::stringstream shaderBuilder;
|
std::stringstream shaderBuilder;
|
||||||
|
|
||||||
|
@ -456,10 +490,25 @@ std::string CGSH_OpenGL::GenerateAlphaTestSection(ALPHA_TEST_METHOD testMethod)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* testFailOp = " discard;";
|
||||||
|
switch(testFailMethod)
|
||||||
|
{
|
||||||
|
case CGSHandler::ALPHA_TEST_FAIL_KEEP:
|
||||||
|
testFailOp = " discard;";
|
||||||
|
break;
|
||||||
|
case CGSHandler::ALPHA_TEST_FAIL_FBONLY:
|
||||||
|
//Depth is discarded
|
||||||
|
testFailOp = " fragDepth = gl_LastFragDepthARM;";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
shaderBuilder << "uint textureColorAlphaInt = uint(textureColor.a * 255.0);" << std::endl;
|
shaderBuilder << "uint textureColorAlphaInt = uint(textureColor.a * 255.0);" << std::endl;
|
||||||
shaderBuilder << test << std::endl;
|
shaderBuilder << test << std::endl;
|
||||||
shaderBuilder << "{" << std::endl;
|
shaderBuilder << "{" << std::endl;
|
||||||
shaderBuilder << " discard;" << std::endl;
|
shaderBuilder << testFailOp << std::endl;
|
||||||
shaderBuilder << "}" << std::endl;
|
shaderBuilder << "}" << std::endl;
|
||||||
|
|
||||||
std::string shaderSource = shaderBuilder.str();
|
std::string shaderSource = shaderBuilder.str();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue