From 613068d7a437972f1f2a991165fab6f15968aabe Mon Sep 17 00:00:00 2001 From: codereader Date: Fri, 9 Apr 2021 13:43:33 +0200 Subject: [PATCH] #5566: Add alphatest support to the z-fill program (WIP) --- install/gl/zfill_alpha_fp.glsl | 40 ++++++++--------- install/gl/zfill_vp.glsl | 4 +- .../rendersystem/backend/OpenGLShader.cpp | 26 ++++++++++- .../rendersystem/backend/OpenGLShaderPass.cpp | 16 +++++++ .../backend/glprogram/GLSLBumpProgram.h | 4 +- .../glprogram/GLSLDepthFillAlphaProgram.cpp | 43 +++++++++++++++++++ .../glprogram/GLSLDepthFillAlphaProgram.h | 7 +++ 7 files changed, 114 insertions(+), 26 deletions(-) diff --git a/install/gl/zfill_alpha_fp.glsl b/install/gl/zfill_alpha_fp.glsl index b2fa90da6e..a9743a1866 100644 --- a/install/gl/zfill_alpha_fp.glsl +++ b/install/gl/zfill_alpha_fp.glsl @@ -1,27 +1,25 @@ -/// ============================================================================ -/* -Copyright (C) 2004 Robert Beckebans -Please see the file "CONTRIBUTORS" for a list of contributors -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. +uniform sampler2D u_diffuse; +uniform float u_alpha_test; -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +varying vec2 var_tex_diffuse; -See the GNU Lesser General Public License for more details. +void main() +{ + if (u_alpha_test < 0) + { + gl_FragColor.a = 1.0; + gl_FragColor.rgb = vec3(1.0, 1.0, 0.0); + } + else + { + vec4 tex = texture2D(u_diffuse, var_tex_diffuse); -You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -/// ============================================================================ + if (tex.a <= u_alpha_test) + { + discard; + } -void main() -{ - gl_FragColor.a = 1.0; - gl_FragColor.rgb = vec3(1.0, 1.0, 0.0); + gl_FragColor = tex; + } } diff --git a/install/gl/zfill_vp.glsl b/install/gl/zfill_vp.glsl index 573e100ddc..a485475a07 100644 --- a/install/gl/zfill_vp.glsl +++ b/install/gl/zfill_vp.glsl @@ -22,13 +22,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. attribute vec4 attr_TexCoord0; +varying vec2 var_tex_diffuse; + void main() { // transform vertex position into homogenous clip-space gl_Position = ftransform(); // transform texcoords - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + var_tex_diffuse = (gl_TextureMatrix[0] * attr_TexCoord0).st; // assign color gl_FrontColor = gl_Color; diff --git a/radiantcore/rendersystem/backend/OpenGLShader.cpp b/radiantcore/rendersystem/backend/OpenGLShader.cpp index 2d805ef555..b7981dbba6 100644 --- a/radiantcore/rendersystem/backend/OpenGLShader.cpp +++ b/radiantcore/rendersystem/backend/OpenGLShader.cpp @@ -312,6 +312,7 @@ void OpenGLShader::appendInteractionLayer(const DBSTriplet& triplet) alphaTest = triplet.diffuse->getAlphaTest(); } +#if 0 // Append a depthfill shader pass if requested (not applicable for // alpha-test materials) if (triplet.needDepthFill && alphaTest <= 0.0) @@ -329,7 +330,30 @@ void OpenGLShader::appendInteractionLayer(const DBSTriplet& triplet) zPass.glProgram = _renderSystem.getGLProgramFactory().getBuiltInProgram("depthFill"); } + else +#else + if (triplet.needDepthFill && triplet.diffuse) + { + // Create depth-buffer fill pass with alpha test + OpenGLState& zPass = appendDefaultPass(); + zPass.setRenderFlag(RENDER_MASKCOLOUR); + zPass.setRenderFlag(RENDER_FILL); + zPass.setRenderFlag(RENDER_CULLFACE); + zPass.setRenderFlag(RENDER_DEPTHTEST); + zPass.setRenderFlag(RENDER_DEPTHWRITE); + zPass.setRenderFlag(RENDER_PROGRAM); + zPass.setRenderFlag(RENDER_ALPHATEST); + zPass.setRenderFlag(RENDER_TEXTURE_2D); + zPass.setRenderFlag(RENDER_BUMP); + zPass.alphaThreshold = static_cast(alphaTest); + zPass.setSortPosition(OpenGLState::SORT_ZFILL); + zPass.stage0 = triplet.diffuse; + zPass.texture0 = getTextureOrInteractionDefault(triplet.diffuse)->getGLTexNum(); + + zPass.glProgram = _renderSystem.getGLProgramFactory().getBuiltInProgram("depthFillAlpha"); + } +#endif // Add the DBS pass OpenGLState& dbsPass = appendDefaultPass(); @@ -337,7 +361,7 @@ void OpenGLShader::appendInteractionLayer(const DBSTriplet& triplet) setGLTexturesFromTriplet(dbsPass, triplet); // Set render flags - dbsPass.setRenderFlag(RENDER_BLEND); + //dbsPass.setRenderFlag(RENDER_BLEND); dbsPass.setRenderFlag(RENDER_FILL); dbsPass.setRenderFlag(RENDER_TEXTURE_2D); dbsPass.setRenderFlag(RENDER_CULLFACE); diff --git a/radiantcore/rendersystem/backend/OpenGLShaderPass.cpp b/radiantcore/rendersystem/backend/OpenGLShaderPass.cpp index fa5a0b4710..f7ae61a112 100644 --- a/radiantcore/rendersystem/backend/OpenGLShaderPass.cpp +++ b/radiantcore/rendersystem/backend/OpenGLShaderPass.cpp @@ -11,6 +11,8 @@ #include "debugging/render.h" #include "debugging/gl.h" +#include "glprogram/GLSLDepthFillAlphaProgram.h" + namespace render { @@ -303,6 +305,20 @@ void OpenGLShaderPass::applyState(OpenGLState& current, { current.glProgram->enable(); } + + // Check if we need to set the alpha test value + if ((requiredState & (RENDER_ALPHATEST | RENDER_FILL)) == (RENDER_ALPHATEST | RENDER_FILL)) + { + auto zFillAlphaProgram = dynamic_cast(current.glProgram); + + if (zFillAlphaProgram != nullptr) + { + zFillAlphaProgram->applyAlphaTest(_glState.alphaThreshold); + + setTextureState(current.texture0, _glState.texture0, GL_TEXTURE0, GL_TEXTURE_2D); + setupTextureMatrix(GL_TEXTURE0, _glState.stage0); + } + } } // State changes. Only perform these if changingBitsMask > 0, since if there are diff --git a/radiantcore/rendersystem/backend/glprogram/GLSLBumpProgram.h b/radiantcore/rendersystem/backend/glprogram/GLSLBumpProgram.h index 6b76b55578..a3ec5a647e 100644 --- a/radiantcore/rendersystem/backend/glprogram/GLSLBumpProgram.h +++ b/radiantcore/rendersystem/backend/glprogram/GLSLBumpProgram.h @@ -9,6 +9,7 @@ namespace render class GLSLBumpProgram : public GLSLProgramBase { +private: // The value all lights should be scaled by, obtained from the game description float _lightScale; @@ -20,9 +21,6 @@ class GLSLBumpProgram : int _locAmbientLight; int _locInvertVCol; - // Program object identifier - GLuint _programObj; - public: /* GLProgram implementation */ diff --git a/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.cpp b/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.cpp index b7f6760b75..2078b80d1f 100644 --- a/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.cpp +++ b/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.cpp @@ -23,6 +23,49 @@ void GLSLDepthFillAlphaProgram::create() DEPTHFILL_ALPHA_VP_FILENAME, DEPTHFILL_ALPHA_FP_FILENAME ); + glBindAttribLocation(_programObj, ATTR_TEXCOORD, "attr_TexCoord0"); + + glLinkProgram(_programObj); + + debug::assertNoGlErrors(); + + _locAlphaTest = glGetUniformLocation(_programObj, "u_alpha_test"); + + glUseProgram(_programObj); + debug::assertNoGlErrors(); + + GLint samplerLoc = glGetUniformLocation(_programObj, "u_diffuse"); + glUniform1i(samplerLoc, 0); + + debug::assertNoGlErrors(); +} + +void GLSLDepthFillAlphaProgram::enable() +{ + GLSLProgramBase::enable(); + + glEnableVertexAttribArrayARB(ATTR_TEXCOORD); +} + +void GLSLDepthFillAlphaProgram::disable() +{ + GLSLProgramBase::disable(); + + glDisableVertexAttribArrayARB(ATTR_TEXCOORD); +} + +void GLSLDepthFillAlphaProgram::applyAlphaTest(float alphaTest) +{ + glUniform1f(_locAlphaTest, alphaTest); + + debug::assertNoGlErrors(); + + glActiveTexture(GL_TEXTURE0); + glClientActiveTexture(GL_TEXTURE0); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + debug::assertNoGlErrors(); } diff --git a/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.h b/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.h index 105c4ea490..5fec400e59 100644 --- a/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.h +++ b/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.h @@ -8,8 +8,15 @@ namespace render class GLSLDepthFillAlphaProgram : public GLSLProgramBase { +private: + GLint _locAlphaTest; + public: void create() override; + void enable() override; + void disable() override; + + void applyAlphaTest(float alphaTest); }; }