From b3d1d106af76e748f695d50e621d57c28f0091a1 Mon Sep 17 00:00:00 2001 From: unelsson Date: Sun, 29 Aug 2021 14:26:17 +0300 Subject: [PATCH 1/7] Collada alpha testing and uniforms --- components/resource/scenemanager.cpp | 58 ++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 76e73da384..8056e6911b 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -2,6 +2,7 @@ #include +#include #include #include @@ -217,7 +218,52 @@ namespace Resource int mMaxAnisotropy; }; + // Check Collada extra descriptions + class ColladaAlphaTrickVisitor : public osg::NodeVisitor + { + public: + ColladaAlphaTrickVisitor() + : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + { + } + osg::AlphaFunc::ComparisonFunction getTestMode(std::string mode) + { + if (mode == "ALWAYS") return osg::AlphaFunc::ALWAYS; + if (mode == "LESS") return osg::AlphaFunc::LESS; + if (mode == "EQUAL") return osg::AlphaFunc::EQUAL; + if (mode == "LEQUAL") return osg::AlphaFunc::LEQUAL; + if (mode == "GREATER") return osg::AlphaFunc::GREATER; + if (mode == "NOTEQUAL") return osg::AlphaFunc::NOTEQUAL; + if (mode == "GEQUAL") return osg::AlphaFunc::GEQUAL; + if (mode == "NEVER") return osg::AlphaFunc::NEVER; + + Log(Debug::Info) << "Unexpected alpha testing mode: " << mode; + return osg::AlphaFunc::LEQUAL; + } + + void apply(osg::Node& node) override + { + std::vector descriptions = node.getDescriptions(); + for (auto description : descriptions) + { + std::vector descriptionParts; + + std::istringstream descriptionStringStream(description); + for (std::string part; std::getline(descriptionStringStream, part, ' ');) + descriptionParts.emplace_back(part); + + if (descriptionParts.at(0) == "alphatest") + { + osg::AlphaFunc::ComparisonFunction mode = getTestMode(descriptionParts.at(1)); + osg::ref_ptr alphaFunc (new osg::AlphaFunc(mode, std::stod(descriptionParts.back()))); + node.getOrCreateStateSet()->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON); + Log(Debug::Info) << "Setting collada alpha test " << description << " for " << node.getName(); + } + } + traverse(node); + } + }; SceneManager::SceneManager(const VFS::Manager *vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager) : ResourceManager(vfs) @@ -424,6 +470,18 @@ namespace Resource if (nameFinder.mFoundNode) nameFinder.mFoundNode->setNodeMask(hiddenNodeMask); + if (ext == "dae") + { + // Collada alpha testing + Resource::ColladaAlphaTrickVisitor colladaAlphaTrickVisitor; + result.getNode()->accept(colladaAlphaTrickVisitor); + + result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("emissiveMult", 1.f)); + result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("envMapColor", osg::Vec4f(1,1,1,1))); + result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("useFalloff", false)); + } + + return result.getNode(); } } From 89982eb9e333d74ed69f57a313096da486b18262 Mon Sep 17 00:00:00 2001 From: unelsson Date: Sun, 29 Aug 2021 14:31:11 +0300 Subject: [PATCH 2/7] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 917de55fe2..8a92127dca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Feature #6032: Reverse-z depth buffer Feature #6162: Refactor GUI to use shaders and to be GLES and GL3+ friendly Feature #6199: Support FBO Rendering + Feature #6249: Alpha testing support for Collada Feature #6251: OpenMW-CS: Set instance movement based on camera zoom Task #6201: Remove the "Note: No relevant classes found. No output generated" warnings Task #6264: Remove the old classes in animation.cpp From 40497d6fe55b68f708cd1063e7a36f7a75ab7389 Mon Sep 17 00:00:00 2001 From: unelsson Date: Sat, 11 Sep 2021 13:55:17 +0300 Subject: [PATCH 3/7] Set depth testing for alpha blend & test, depth writes off for blend. --- components/resource/scenemanager.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 8056e6911b..b4a26f0f35 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -244,6 +244,17 @@ namespace Resource void apply(osg::Node& node) override { + bool osgDepthCreated(false); + + if (node.getOrCreateStateSet()->getRenderingHint() == osg::StateSet::TRANSPARENT_BIN) + { + osg::ref_ptr depth = SceneUtil::createDepth(); + depth->setWriteMask(false); + osgDepthCreated = true; + + node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); + } + std::vector descriptions = node.getDescriptions(); for (auto description : descriptions) { @@ -255,6 +266,12 @@ namespace Resource if (descriptionParts.at(0) == "alphatest") { + if (!osgDepthCreated) + { + osg::ref_ptr depth = SceneUtil::createDepth(); + node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); + } + osg::AlphaFunc::ComparisonFunction mode = getTestMode(descriptionParts.at(1)); osg::ref_ptr alphaFunc (new osg::AlphaFunc(mode, std::stod(descriptionParts.back()))); node.getOrCreateStateSet()->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON); From 96f02ab32c4d2fb329f4c382499154673bb56dbb Mon Sep 17 00:00:00 2001 From: unelsson Date: Sat, 11 Sep 2021 17:03:16 +0300 Subject: [PATCH 4/7] Per-material alpha testing for collada --- components/resource/scenemanager.cpp | 42 +++++++++++++++++++--------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index b4a26f0f35..80d8f1ecdc 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -255,31 +255,47 @@ namespace Resource node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); } + /* Check if the has + correct format for OpenMW: alphatest mode value MaterialName + e.g alphatest GEQUAL 0.8 MyAlphaTestedMaterial */ std::vector descriptions = node.getDescriptions(); for (auto description : descriptions) { - std::vector descriptionParts; + mDescriptions.emplace_back(description); + } + // Iterate each description, and see if the current node uses the specified material for alpha testing + for (auto description : mDescriptions) + { + std::vector descriptionParts; std::istringstream descriptionStringStream(description); for (std::string part; std::getline(descriptionStringStream, part, ' ');) - descriptionParts.emplace_back(part); - - if (descriptionParts.at(0) == "alphatest") { - if (!osgDepthCreated) - { - osg::ref_ptr depth = SceneUtil::createDepth(); - node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); - } + descriptionParts.emplace_back(part); + } - osg::AlphaFunc::ComparisonFunction mode = getTestMode(descriptionParts.at(1)); - osg::ref_ptr alphaFunc (new osg::AlphaFunc(mode, std::stod(descriptionParts.back()))); - node.getOrCreateStateSet()->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON); - Log(Debug::Info) << "Setting collada alpha test " << description << " for " << node.getName(); + if (descriptionParts.size() > (3) && descriptionParts.at(3) == node.getOrCreateStateSet()->getName()) + { + if (descriptionParts.at(0) == "alphatest") + { + if (!osgDepthCreated) + { + osg::ref_ptr depth = SceneUtil::createDepth(); + node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); + } + + osg::AlphaFunc::ComparisonFunction mode = getTestMode(descriptionParts.at(1)); + osg::ref_ptr alphaFunc (new osg::AlphaFunc(mode, std::stod(descriptionParts.at(2)))); + node.getOrCreateStateSet()->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON); + Log(Debug::Info) << "Setting collada alpha test for " << node.getName(); + } } } + traverse(node); } + private: + std::vector mDescriptions; }; SceneManager::SceneManager(const VFS::Manager *vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager) From ec0b36d21d4035e7a4fbe7b3c222a15f04248523 Mon Sep 17 00:00:00 2001 From: unelsson Date: Sun, 12 Sep 2021 20:31:34 +0300 Subject: [PATCH 5/7] Don't make a new osg::depth to alpha tested node --- components/resource/scenemanager.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 80d8f1ecdc..b9bab66faa 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -244,13 +244,10 @@ namespace Resource void apply(osg::Node& node) override { - bool osgDepthCreated(false); - if (node.getOrCreateStateSet()->getRenderingHint() == osg::StateSet::TRANSPARENT_BIN) { osg::ref_ptr depth = SceneUtil::createDepth(); depth->setWriteMask(false); - osgDepthCreated = true; node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); } @@ -278,12 +275,6 @@ namespace Resource { if (descriptionParts.at(0) == "alphatest") { - if (!osgDepthCreated) - { - osg::ref_ptr depth = SceneUtil::createDepth(); - node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); - } - osg::AlphaFunc::ComparisonFunction mode = getTestMode(descriptionParts.at(1)); osg::ref_ptr alphaFunc (new osg::AlphaFunc(mode, std::stod(descriptionParts.at(2)))); node.getOrCreateStateSet()->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON); From f2a894024a646204c283c969b8acb33db0de255e Mon Sep 17 00:00:00 2001 From: unelsson Date: Sun, 12 Sep 2021 21:08:59 +0300 Subject: [PATCH 6/7] Change debug levels --- components/resource/scenemanager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index b9bab66faa..3112e3c837 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -238,7 +238,7 @@ namespace Resource if (mode == "GEQUAL") return osg::AlphaFunc::GEQUAL; if (mode == "NEVER") return osg::AlphaFunc::NEVER; - Log(Debug::Info) << "Unexpected alpha testing mode: " << mode; + Log(Debug::Warning) << "Unexpected alpha testing mode: " << mode; return osg::AlphaFunc::LEQUAL; } @@ -278,7 +278,6 @@ namespace Resource osg::AlphaFunc::ComparisonFunction mode = getTestMode(descriptionParts.at(1)); osg::ref_ptr alphaFunc (new osg::AlphaFunc(mode, std::stod(descriptionParts.at(2)))); node.getOrCreateStateSet()->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON); - Log(Debug::Info) << "Setting collada alpha test for " << node.getName(); } } } From 67894349a97e9949b2057055fd06933538cfa2e9 Mon Sep 17 00:00:00 2001 From: unelsson Date: Sat, 18 Sep 2021 14:02:28 +0300 Subject: [PATCH 7/7] Add a check for OPAQUE_BIN --- components/resource/scenemanager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/components/resource/scenemanager.cpp b/components/resource/scenemanager.cpp index 3112e3c837..b468b430ff 100644 --- a/components/resource/scenemanager.cpp +++ b/components/resource/scenemanager.cpp @@ -251,6 +251,13 @@ namespace Resource node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); } + else if (node.getOrCreateStateSet()->getRenderingHint() == osg::StateSet::OPAQUE_BIN) + { + osg::ref_ptr depth = SceneUtil::createDepth(); + depth->setWriteMask(true); + + node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); + } /* Check if the has correct format for OpenMW: alphatest mode value MaterialName