From 8a6be0b037bb522dd35a744a476298c69671690f Mon Sep 17 00:00:00 2001 From: codereader Date: Fri, 25 Mar 2022 16:19:50 +0100 Subject: [PATCH] #219: Refactoring to reduce code duplication --- include/iglprogram.h | 13 +++ .../backend/LightInteractions.cpp | 93 +++++++------------ .../rendersystem/backend/LightInteractions.h | 4 + .../glprogram/GLSLDepthFillAlphaProgram.h | 7 +- .../backend/glprogram/ShadowMapProgram.h | 7 +- 5 files changed, 61 insertions(+), 63 deletions(-) diff --git a/include/iglprogram.h b/include/iglprogram.h index 5758e63831..1128896a08 100644 --- a/include/iglprogram.h +++ b/include/iglprogram.h @@ -93,3 +93,16 @@ class GLProgram const Params& lightParms) { } }; + +// Interface implemented by GLSL programs supporting alpha test +class ISupportsAlphaTest +{ +public: + virtual ~ISupportsAlphaTest() {} + + // Set the alpha test value uniform + virtual void setAlphaTest(float alphaTest) = 0; + + // Set the diffuse texture matrix needed to look up the texel for the alpha test + virtual void setDiffuseTextureTransform(const Matrix4& transform) = 0; +}; diff --git a/radiantcore/rendersystem/backend/LightInteractions.cpp b/radiantcore/rendersystem/backend/LightInteractions.cpp index 5dbc00e718..3bda16081d 100644 --- a/radiantcore/rendersystem/backend/LightInteractions.cpp +++ b/radiantcore/rendersystem/backend/LightInteractions.cpp @@ -95,41 +95,14 @@ void LightInteractions::fillDepthBuffer(OpenGLState& state, GLSLDepthFillAlphaPr if (!depthFillPass) continue; - const auto& material = shader->getMaterial(); - assert(material); - - auto coverage = material->getCoverage(); - - // Skip translucent materials - if (coverage == Material::MC_TRANSLUCENT) continue; - - if (coverage == Material::MC_PERFORATED) - { - // Evaluate the shader stages of this material - depthFillPass->evaluateShaderStages(renderTime, entity); - - // Apply the alpha test value, it might be affected by time and entity parms - program.setAlphaTest(depthFillPass->getAlphaTestValue()); - - // If there's a diffuse stage, apply the correct texture - OpenGLState::SetTextureState(state.texture0, depthFillPass->state().texture0, GL_TEXTURE0, GL_TEXTURE_2D); - - // Set evaluated stage texture transformation matrix to the GLSL uniform - program.setDiffuseTextureTransform(depthFillPass->getDiffuseTextureTransform()); - } - else - { - // No alpha test on this material, pass -1 to deactivate texture sampling - // in the GLSL program - program.setAlphaTest(-1); - } + setupAlphaTest(state, shader, depthFillPass, program, renderTime, entity); for (const auto& object : objects) { // We submit all objects with an identity matrix in a single multi draw call if (!object.get().isOriented()) { - if (coverage == Material::MC_PERFORATED) + if (shader->getMaterial()->getCoverage() == Material::MC_PERFORATED) { untransformedObjects.push_back(object.get().getStorageLocation()); } @@ -186,34 +159,7 @@ void LightInteractions::drawShadowMap(OpenGLState& state, const Rectangle& recta if (!depthFillPass) continue; - const auto& material = shader->getMaterial(); - assert(material); - - auto coverage = material->getCoverage(); - - // Skip translucent materials - if (coverage == Material::MC_TRANSLUCENT) continue; - - if (coverage == Material::MC_PERFORATED) - { - // Evaluate the shader stages of this material - depthFillPass->evaluateShaderStages(renderTime, entity); - - // Apply the alpha test value, it might be affected by time and entity parms - program.setAlphaTest(depthFillPass->getAlphaTestValue()); - - // If there's a diffuse stage, apply the correct texture - OpenGLState::SetTextureState(state.texture0, depthFillPass->state().texture0, GL_TEXTURE0, GL_TEXTURE_2D); - - // Set evaluated stage texture transformation matrix to the GLSL uniform - program.setDiffuseTextureTransform(depthFillPass->getDiffuseTextureTransform()); - } - else - { - // No alpha test on this material, pass -1 to deactivate texture sampling - // in the GLSL program - program.setAlphaTest(-1); - } + setupAlphaTest(state, shader, depthFillPass, program, renderTime, entity); for (const auto& object : objects) { @@ -334,4 +280,37 @@ void LightInteractions::drawInteractions(OpenGLState& state, GLSLBumpProgram& pr OpenGLState::SetTextureState(state.texture4, 0, GL_TEXTURE4, GL_TEXTURE_2D); } +void LightInteractions::setupAlphaTest(OpenGLState& state, OpenGLShader* shader, DepthFillPass* depthFillPass, + ISupportsAlphaTest& program, std::size_t renderTime, IRenderEntity* entity) +{ + const auto& material = shader->getMaterial(); + assert(material); + + auto coverage = material->getCoverage(); + + // Skip translucent materials + if (coverage == Material::MC_TRANSLUCENT) return; + + if (coverage == Material::MC_PERFORATED) + { + // Evaluate the shader stages of this material + depthFillPass->evaluateShaderStages(renderTime, entity); + + // Apply the alpha test value, it might be affected by time and entity parms + program.setAlphaTest(depthFillPass->getAlphaTestValue()); + + // If there's a diffuse stage, apply the correct texture + OpenGLState::SetTextureState(state.texture0, depthFillPass->state().texture0, GL_TEXTURE0, GL_TEXTURE_2D); + + // Set evaluated stage texture transformation matrix to the GLSL uniform + program.setDiffuseTextureTransform(depthFillPass->getDiffuseTextureTransform()); + } + else + { + // No alpha test on this material, pass -1 to deactivate texture sampling + // in the GLSL program + program.setAlphaTest(-1); + } +} + } diff --git a/radiantcore/rendersystem/backend/LightInteractions.h b/radiantcore/rendersystem/backend/LightInteractions.h index 38537fc850..1889c1eb9f 100644 --- a/radiantcore/rendersystem/backend/LightInteractions.h +++ b/radiantcore/rendersystem/backend/LightInteractions.h @@ -17,6 +17,7 @@ class OpenGLShader; class GLSLDepthFillAlphaProgram; class GLSLBumpProgram; class ShadowMapProgram; +class DepthFillPass; /** * Defines interactions between a light and one or more entity renderables @@ -96,6 +97,9 @@ class LightInteractions void drawShadowMap(OpenGLState& state, const Rectangle& rectangle, ShadowMapProgram& program, std::size_t renderTime); void drawInteractions(OpenGLState& state, GLSLBumpProgram& program, const IRenderView& view, std::size_t renderTime); + + void setupAlphaTest(OpenGLState& state, OpenGLShader* shader, DepthFillPass* depthFillPass, + ISupportsAlphaTest& alphaTestProgram, std::size_t renderTime, IRenderEntity* entity); }; } diff --git a/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.h b/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.h index fa6a3fa033..4a723c31a6 100644 --- a/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.h +++ b/radiantcore/rendersystem/backend/glprogram/GLSLDepthFillAlphaProgram.h @@ -6,7 +6,8 @@ namespace render { class GLSLDepthFillAlphaProgram : - public GLSLProgramBase + public GLSLProgramBase, + public ISupportsAlphaTest { private: GLint _locAlphaTest; @@ -21,9 +22,9 @@ class GLSLDepthFillAlphaProgram : void setModelViewProjection(const Matrix4& modelViewProjection); void setObjectTransform(const Matrix4& transform); - void setDiffuseTextureTransform(const Matrix4& transform); - void setAlphaTest(float alphaTest); + void setAlphaTest(float alphaTest) override; + void setDiffuseTextureTransform(const Matrix4& transform) override; }; } diff --git a/radiantcore/rendersystem/backend/glprogram/ShadowMapProgram.h b/radiantcore/rendersystem/backend/glprogram/ShadowMapProgram.h index 216239b65c..02415fb0ca 100644 --- a/radiantcore/rendersystem/backend/glprogram/ShadowMapProgram.h +++ b/radiantcore/rendersystem/backend/glprogram/ShadowMapProgram.h @@ -6,7 +6,8 @@ namespace render { class ShadowMapProgram : - public GLSLProgramBase + public GLSLProgramBase, + public ISupportsAlphaTest { private: GLint _locAlphaTest; @@ -21,8 +22,8 @@ class ShadowMapProgram : void setObjectTransform(const Matrix4& transform); - void setDiffuseTextureTransform(const Matrix4& transform); - void setAlphaTest(float alphaTest); + void setDiffuseTextureTransform(const Matrix4& transform) override; + void setAlphaTest(float alphaTest) override; void setLightOrigin(const Vector3& lightOrigin); };