From b6e92c9c6deedfb9c4a4acfd106d57eb3e1628e8 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 20 Jan 2021 23:37:19 +0000 Subject: [PATCH] Use ShaderVisitor to skip translucent framebuffer specific stuff --- apps/openmw/mwrender/characterpreview.cpp | 3 +++ apps/openmw/mwrender/renderingmanager.cpp | 1 - components/resource/scenemanager.cpp | 7 ++++--- components/resource/scenemanager.hpp | 4 ++-- components/shader/shadervisitor.cpp | 10 +++++++++- components/shader/shadervisitor.hpp | 4 ++++ files/shaders/objects_fragment.glsl | 3 +++ 7 files changed, 25 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index f21e667eb0..14735050ce 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include @@ -249,6 +251,7 @@ namespace MWRender void CharacterPreview::setBlendMode() { + mResourceSystem->getSceneManager()->recreateShaders(mNode, "objects", true); SetUpBlendVisitor visitor; mNode->accept(visitor); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index e1f6f0dd96..6ce431d2e2 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -370,7 +370,6 @@ namespace MWRender mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("near", mNearClip)); mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("far", mViewDistance)); mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("simpleWater", false)); - mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("noAlpha", false)); mUniformNear = mRootNode->getOrCreateStateSet()->getUniform("near"); mUniformFar = mRootNode->getOrCreateStateSet()->getUniform("far"); diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index e75fa4f74e..d937b992b1 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -247,9 +247,9 @@ namespace Resource return mForceShaders; } - void SceneManager::recreateShaders(osg::ref_ptr node, const std::string& shaderPrefix) + void SceneManager::recreateShaders(osg::ref_ptr node, const std::string& shaderPrefix, bool translucentFramebuffer) { - osg::ref_ptr shaderVisitor(createShaderVisitor(shaderPrefix)); + osg::ref_ptr shaderVisitor(createShaderVisitor(shaderPrefix, translucentFramebuffer)); shaderVisitor->setAllowedToModifyStateSets(false); node->accept(*shaderVisitor); } @@ -749,7 +749,7 @@ namespace Resource stats->setAttribute(frameNumber, "Node Instance", mInstanceCache->getCacheSize()); } - Shader::ShaderVisitor *SceneManager::createShaderVisitor(const std::string& shaderPrefix) + Shader::ShaderVisitor *SceneManager::createShaderVisitor(const std::string& shaderPrefix, bool translucentFramebuffer) { Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, shaderPrefix+"_vertex.glsl", shaderPrefix+"_fragment.glsl"); shaderVisitor->setForceShaders(mForceShaders); @@ -759,6 +759,7 @@ namespace Resource shaderVisitor->setAutoUseSpecularMaps(mAutoUseSpecularMaps); shaderVisitor->setSpecularMapPattern(mSpecularMapPattern); shaderVisitor->setApplyLightingToEnvMaps(mApplyLightingToEnvMaps); + shaderVisitor->setTranslucentFramebuffer(translucentFramebuffer); return shaderVisitor; } diff --git a/components/resource/scenemanager.hpp b/components/resource/scenemanager.hpp index e897566a8b..a815a324f2 100644 --- a/components/resource/scenemanager.hpp +++ b/components/resource/scenemanager.hpp @@ -76,7 +76,7 @@ namespace Resource Shader::ShaderManager& getShaderManager(); /// Re-create shaders for this node, need to call this if texture stages or vertex color mode have changed. - void recreateShaders(osg::ref_ptr node, const std::string& shaderPrefix = "objects"); + void recreateShaders(osg::ref_ptr node, const std::string& shaderPrefix = "objects", bool translucentFramebuffer = false); /// @see ShaderVisitor::setForceShaders void setForceShaders(bool force); @@ -173,7 +173,7 @@ namespace Resource private: - Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects"); + Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects", bool translucentFramebuffer = false); std::unique_ptr mShaderManager; bool mForceShaders; diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index e908b6aaa8..9dec5522ca 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -40,6 +40,7 @@ namespace Shader , mAutoUseNormalMaps(false) , mAutoUseSpecularMaps(false) , mApplyLightingToEnvMaps(false) + , mTranslucentFramebuffer(false) , mShaderManager(shaderManager) , mImageManager(imageManager) , mDefaultVsTemplate(defaultVsTemplate) @@ -146,7 +147,7 @@ namespace Shader mRequirements.back().mShaderRequired = true; } } - else + else if (!mTranslucentFramebuffer) Log(Debug::Error) << "ShaderVisitor encountered unknown texture " << texture; } } @@ -322,6 +323,8 @@ namespace Shader writableStateSet->addUniform(new osg::Uniform("colorMode", reqs.mColorMode)); + defineMap["translucentFramebuffer"] = mTranslucentFramebuffer ? "1" : "0"; + osg::ref_ptr vertexShader (mShaderManager.getShader(mDefaultVsTemplate, defineMap, osg::Shader::VERTEX)); osg::ref_ptr fragmentShader (mShaderManager.getShader(mDefaultFsTemplate, defineMap, osg::Shader::FRAGMENT)); @@ -474,4 +477,9 @@ namespace Shader mApplyLightingToEnvMaps = apply; } + void ShaderVisitor::setTranslucentFramebuffer(bool translucent) + { + mTranslucentFramebuffer = translucent; + } + } diff --git a/components/shader/shadervisitor.hpp b/components/shader/shadervisitor.hpp index 6031dbfe6c..11b37c9230 100644 --- a/components/shader/shadervisitor.hpp +++ b/components/shader/shadervisitor.hpp @@ -40,6 +40,8 @@ namespace Shader void setApplyLightingToEnvMaps(bool apply); + void setTranslucentFramebuffer(bool translucent); + void apply(osg::Node& node) override; void apply(osg::Drawable& drawable) override; @@ -63,6 +65,8 @@ namespace Shader bool mApplyLightingToEnvMaps; + bool mTranslucentFramebuffer; + ShaderManager& mShaderManager; Resource::ImageManager& mImageManager; diff --git a/files/shaders/objects_fragment.glsl b/files/shaders/objects_fragment.glsl index bd2bd5909f..50bb77145a 100644 --- a/files/shaders/objects_fragment.glsl +++ b/files/shaders/objects_fragment.glsl @@ -209,8 +209,11 @@ void main() #endif gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue); +#if @translucentFramebuffer + // having testing & blending isn't enough - we need to write an opaque pixel to be opaque if (noAlpha) gl_FragData[0].a = 1.0; +#endif applyShadowDebugOverlay(); }