Files
OpenSceneGraph/src/osgFX/Technique.cpp
Robert Osfield 33b838e437 From Jannik Heller, "This submission makes the osgFX::Technique traverse as a normal Group if the visitor is not a cull visitor.
As for motivation behind the change, I think it makes more sense that way because only the CullVisitor cares about rendering. Say an intersection visitor or update visitor only needs to traverse the subgraph once, not once for each pass. For these visitors there is no point in traversing the subgraph more than once, since it's exactly the same graph. Another motivation is the performance improvement had when an intersection visitor tests against a multipass Technique."

 Note about mods by Robert Osfield, "Changed dyanmic_cast<> and check against getTraversalType() to utilize the new asCullVisitor() instead to improve efficiency."
2016-03-01 11:57:02 +00:00

72 lines
1.7 KiB
C++

#include <osgFX/Technique>
#include <osgFX/Effect>
#include <osg/GLExtensions>
#include <osgUtil/CullVisitor>
using namespace osgFX;
Technique::Technique()
: osg::Referenced()
{
}
void Technique::addPass(osg::StateSet* ss)
{
if (ss) {
_passes.push_back(ss);
ss->setRenderBinDetails(static_cast<int>(_passes.size()), "RenderBin");
}
}
bool Technique::validate(osg::State& state) const
{
typedef std::vector<std::string> String_list;
String_list extensions;
getRequiredExtensions(extensions);
for (String_list::const_iterator i=extensions.begin(); i!=extensions.end(); ++i) {
if (!osg::isGLExtensionSupported(state.getContextID(),i->c_str())) return false;
}
return true;
}
void Technique::traverse_implementation(osg::NodeVisitor& nv, Effect* fx)
{
// define passes if necessary
if (_passes.empty()) {
define_passes();
}
// special actions must be taken if the node visitor is actually a CullVisitor
osgUtil::CullVisitor* cv = nv.asCullVisitor();
if (cv)
{
// traverse all passes
for (int i=0; i<getNumPasses(); ++i)
{
// push the i-th pass' StateSet
cv->pushStateSet(_passes[i].get());
// traverse the override node if defined, otherwise
// traverse children as a Group would do
osg::Node *override = getOverrideChild(i);
if (override) {
override->accept(nv);
} else {
fx->inherited_traverse(nv);
}
// pop the StateSet
cv->popStateSet();
}
}
else
{
fx->inherited_traverse(nv);
}
}