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;
|
||||
}
|
||||
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.alphaTestMethod = test.nAlphaMethod;
|
||||
shaderCaps.alphaTestFailMethod = test.nAlphaFail;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -85,10 +85,11 @@ private:
|
|||
unsigned int hasFog : 1;
|
||||
unsigned int hasAlphaTest : 1;
|
||||
unsigned int alphaTestMethod : 3;
|
||||
unsigned int alphaTestFailMethod : 2;
|
||||
unsigned int hasDestAlphaTest : 1;
|
||||
unsigned int destAlphaTestRef : 1;
|
||||
unsigned int colorOutputWhite : 1;
|
||||
unsigned int padding : 10;
|
||||
unsigned int padding : 8;
|
||||
|
||||
bool isIndexedTextureSource() const
|
||||
{
|
||||
|
@ -316,7 +317,7 @@ private:
|
|||
Framework::OpenGl::CShader GenerateVertexShader(const SHADERCAPS&);
|
||||
Framework::OpenGl::CShader GenerateFragmentShader(const SHADERCAPS&);
|
||||
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::CBuffer GeneratePresentVertexBuffer();
|
||||
|
@ -462,4 +463,5 @@ private:
|
|||
VertexBuffer m_vertexBuffer;
|
||||
|
||||
bool m_hasFramebufferFetchExtension = false;
|
||||
bool m_hasFramebufferDepthFetchExtension = false;
|
||||
};
|
||||
|
|
|
@ -137,8 +137,35 @@ Framework::OpenGl::CShader CGSH_OpenGL::GenerateFragmentShader(const SHADERCAPS&
|
|||
{
|
||||
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 useFramebufferFetch = writeDestAlphaTest;
|
||||
useFramebufferFetch |= writeDestAlphaTest;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if(useFramebufferDepthFetch)
|
||||
{
|
||||
shaderBuilder << "#extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require" << std::endl;
|
||||
}
|
||||
|
||||
shaderBuilder << "precision mediump float;" << 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 << " texCoord.st /= texCoord.p;" << std::endl;
|
||||
|
||||
|
@ -348,7 +382,7 @@ Framework::OpenGl::CShader CGSH_OpenGL::GenerateFragmentShader(const SHADERCAPS&
|
|||
|
||||
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)
|
||||
|
@ -374,7 +408,7 @@ Framework::OpenGl::CShader CGSH_OpenGL::GenerateFragmentShader(const SHADERCAPS&
|
|||
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;
|
||||
|
||||
|
@ -418,7 +452,7 @@ std::string CGSH_OpenGL::GenerateTexCoordClampingSection(TEXTURE_CLAMP_MODE clam
|
|||
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;
|
||||
|
||||
|
@ -456,10 +490,25 @@ std::string CGSH_OpenGL::GenerateAlphaTestSection(ALPHA_TEST_METHOD testMethod)
|
|||
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 << test << std::endl;
|
||||
shaderBuilder << "{" << std::endl;
|
||||
shaderBuilder << " discard;" << std::endl;
|
||||
shaderBuilder << testFailOp << std::endl;
|
||||
shaderBuilder << "}" << std::endl;
|
||||
|
||||
std::string shaderSource = shaderBuilder.str();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue