OpenSceneGraph/src/osgFX/Technique.cpp
2003-08-26 21:17:22 +00:00

80 lines
2.0 KiB
C++

#include <osgFX/Technique>
#include <osg/GLExtensions>
using namespace osgFX;
Technique::Technique()
: osg::Referenced(),
passes_defined_(false),
control_node_(new osg::Group)
{
}
void Technique::addPass(osg::StateSet *ss)
{
osg::ref_ptr<osg::Group> pass = new osg::Group;
control_node_->addChild(pass.get());
if (ss) {
ss->setRenderBinDetails(static_cast<int>(control_node_->getNumChildren()), "RenderBin");
pass->setStateSet(ss);
}
}
void Technique::addPass(osg::Group *pass)
{
control_node_->addChild(pass);
}
bool Technique::validate(osg::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(i->c_str())) return false;
}
return true;
}
void Technique::accept(osg::NodeVisitor &nv, osg::Node *child)
{
// define passes if necessary
if (!passes_defined_) {
// clear existing pass nodes
if (control_node_->getNumChildren() > 0) {
control_node_->removeChild(0, control_node_->getNumChildren());
}
define_passes();
passes_defined_ = true;
}
// update pass children if necessary
if (child != prev_child_.get()) {
for (unsigned i=0; i<control_node_->getNumChildren(); ++i) {
osg::Group *pass = dynamic_cast<osg::Group *>(control_node_->getChild(i));
if (pass) {
if (pass->getNumChildren() > 0) {
pass->removeChild(0, pass->getNumChildren());
}
osg::Node *oc = getOverrideChild(i);
if (oc) {
pass->addChild(oc);
} else {
pass->addChild(child);
}
}
}
prev_child_ = child;
}
// traverse the control node
control_node_->accept(nv);
}