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."
72 lines
1.7 KiB
C++
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);
|
|
}
|
|
}
|