mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-31 15:45:35 +00:00
Merge branch 'colladaalphatest' into 'master'
Collada alpha testing See merge request OpenMW/openmw!1177
This commit is contained in:
commit
aa11238be1
2 changed files with 89 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <osg/AlphaFunc>
|
||||
#include <osg/Node>
|
||||
#include <osg/UserDataContainer>
|
||||
|
||||
|
@ -217,7 +218,82 @@ 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::Warning) << "Unexpected alpha testing mode: " << mode;
|
||||
return osg::AlphaFunc::LEQUAL;
|
||||
}
|
||||
|
||||
void apply(osg::Node& node) override
|
||||
{
|
||||
if (node.getOrCreateStateSet()->getRenderingHint() == osg::StateSet::TRANSPARENT_BIN)
|
||||
{
|
||||
osg::ref_ptr<osg::Depth> depth = SceneUtil::createDepth();
|
||||
depth->setWriteMask(false);
|
||||
|
||||
node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON);
|
||||
}
|
||||
else if (node.getOrCreateStateSet()->getRenderingHint() == osg::StateSet::OPAQUE_BIN)
|
||||
{
|
||||
osg::ref_ptr<osg::Depth> depth = SceneUtil::createDepth();
|
||||
depth->setWriteMask(true);
|
||||
|
||||
node.getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
/* Check if the <node> has <extra type="Node"> <technique profile="OpenSceneGraph"> <Descriptions> <Description>
|
||||
correct format for OpenMW: <Description>alphatest mode value MaterialName</Description>
|
||||
e.g <Description>alphatest GEQUAL 0.8 MyAlphaTestedMaterial</Description> */
|
||||
std::vector<std::string> descriptions = node.getDescriptions();
|
||||
for (auto description : descriptions)
|
||||
{
|
||||
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<std::string> descriptionParts;
|
||||
std::istringstream descriptionStringStream(description);
|
||||
for (std::string part; std::getline(descriptionStringStream, part, ' ');)
|
||||
{
|
||||
descriptionParts.emplace_back(part);
|
||||
}
|
||||
|
||||
if (descriptionParts.size() > (3) && descriptionParts.at(3) == node.getOrCreateStateSet()->getName())
|
||||
{
|
||||
if (descriptionParts.at(0) == "alphatest")
|
||||
{
|
||||
osg::AlphaFunc::ComparisonFunction mode = getTestMode(descriptionParts.at(1));
|
||||
osg::ref_ptr<osg::AlphaFunc> alphaFunc (new osg::AlphaFunc(mode, std::stod(descriptionParts.at(2))));
|
||||
node.getOrCreateStateSet()->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
private:
|
||||
std::vector<std::string> mDescriptions;
|
||||
};
|
||||
|
||||
SceneManager::SceneManager(const VFS::Manager *vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager)
|
||||
: ResourceManager(vfs)
|
||||
|
@ -424,6 +500,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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue