osgEarth 2.1.1
|
Public Member Functions | |
StencilVolumeNode (bool preRenderChildrenToDepthBuffer=false, bool inverted=false) | |
StencilVolumeNode (const StencilVolumeNode &rhs, const osg::CopyOp &op=osg::CopyOp::DEEP_COPY_ALL) | |
META_Node (osgEarth::Features, StencilVolumeNode) | |
virtual void | traverse (osg::NodeVisitor &nv) |
int | setBaseRenderBin (int bin) |
void | addVolumes (osg::Node *node) |
virtual bool | addChild (Node *child) |
virtual bool | insertChild (unsigned int index, Node *child) |
virtual bool | removeChildren (unsigned int pos, unsigned int numChildrenToRemove) |
virtual bool | replaceChild (Node *origChild, Node *newChild) |
virtual bool | setChild (unsigned int i, Node *node) |
virtual osg::BoundingSphere | computeBound () const |
Protected Member Functions | |
void | init () |
Protected Attributes | |
osg::ref_ptr< osg::Group > | _root |
osg::Group * | _stencilGroup1 |
osg::Group * | _stencilGroup2 |
osg::Group * | _depthPass |
osg::Group * | _renderPass |
bool | _inverted |
bool | _preRenderChildrenToDepthBuffer |
Definition at line 31 of file StencilVolumeNode.
StencilVolumeNode::StencilVolumeNode | ( | bool | preRenderChildrenToDepthBuffer = false , |
bool | inverted = false |
||
) |
Constructs a stencil masking node.
preRenderChildrenToDepthBuffer | Normally, this node will render the stencil volumes first and then render the children (which will be masked by the stencil). If you need to pre-render the children to the depth buffer, set this to TRUE. You need to do this is you are creating a straight render mask. |
inverted | Inverts the stencil buffer, masking the opposite pixels that would normally be masked. |
Definition at line 41 of file StencilVolumeNode.cpp.
: osgEarth::MaskNode(), _preRenderChildrenToDepthBuffer( preRenderChildrenToDepthBuffer ), _inverted( inverted ), _stencilGroup1( 0L ), _stencilGroup2( 0L ), _depthPass( 0L ), _renderPass( 0L ) { init(); }
StencilVolumeNode::StencilVolumeNode | ( | const StencilVolumeNode & | rhs, |
const osg::CopyOp & | op = osg::CopyOp::DEEP_COPY_ALL |
||
) |
Definition at line 47 of file StencilUtils.cpp.
: osg::Group( rhs, op ), _stencilGroup1( rhs._stencilGroup1 ), _stencilGroup2( rhs._stencilGroup2 ), _maskGroup( rhs._maskGroup ), _maskColorArray( rhs._maskColorArray ) { //nop }
bool StencilVolumeNode::addChild | ( | Node * | child | ) | [virtual] |
Override all the osg::Group methods:
Definition at line 101 of file StencilVolumeNode.cpp.
{ if ( !child ) return false; dirtyBound(); if ( _depthPass ) _depthPass->addChild( child ); return _renderPass->addChild( child ); }
void StencilVolumeNode::addVolumes | ( | osg::Node * | node | ) |
Definition at line 84 of file StencilUtils.cpp.
{ if ( _stencilGroup1 ) _stencilGroup1->addChild( node ); if ( _stencilGroup2 ) _stencilGroup2->addChild( node ); }
osg::BoundingSphere StencilVolumeNode::computeBound | ( | ) | const [virtual] |
Definition at line 134 of file StencilVolumeNode.cpp.
{ if ( _depthPass ) return _depthPass->computeBound(); else return _renderPass->computeBound(); }
void StencilVolumeNode::init | ( | ) | [protected] |
Definition at line 93 of file StencilUtils.cpp.
{ // FIRST create the stenciled geometry pass: // For now we are hard-coding these to what are hopefully "safe" values. // In the future we hope to rewrite this as a custom StencilVolumeNode that // will automatically detect extension availability at draw time and choose // the optimal GL rendering path. static bool s_EXT_stencil_wrap = true; //osg::isGLExtensionSupported(0, "GL_EXT_stencil_wrap"); static bool s_EXT_stencil_two_side = false; //osg::isGLExtensionSupported(0, "GL_EXT_stencil_two_side"); // zFail=true if more compute intensive, but lets you get inside the volume. // Again, a custom node will give us a better opportunity to choose between zFail and zPass based on // the eye location (you only need zFail if you camera is inside the volume). bool zFail = true; int baseBin = 100; osg::notify(osg::INFO) << "[osgEarth] Stencil buffer wrap = " << s_EXT_stencil_wrap << std::endl; if ( s_EXT_stencil_two_side ) { osg::notify(osg::INFO) << "[osgEarth] Two-sided stenciling" << std::endl; osg::StencilTwoSided::Operation incrOp = s_EXT_stencil_wrap ? osg::StencilTwoSided::INCR_WRAP : osg::StencilTwoSided::INCR; osg::StencilTwoSided::Operation decrOp = s_EXT_stencil_wrap ? osg::StencilTwoSided::DECR_WRAP : osg::StencilTwoSided::DECR; _stencilGroup1 = new osg::Group(); //osg::Group* stencil_group = new osg::Group(); osg::StateSet* ss = _stencilGroup1->getOrCreateStateSet(); ss->setRenderBinDetails( baseBin++, "RenderBin" ); if ( zFail ) { osg::StencilTwoSided* stencil = new osg::StencilTwoSided(); stencil->setFunction(osg::StencilTwoSided::BACK, osg::StencilTwoSided::ALWAYS, 1, ~0u); stencil->setOperation(osg::StencilTwoSided::BACK, osg::StencilTwoSided::KEEP, incrOp, osg::StencilTwoSided::KEEP); stencil->setFunction(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::ALWAYS, 1, ~0u); stencil->setOperation(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::KEEP, decrOp, osg::StencilTwoSided::KEEP); ss->setAttributeAndModes( stencil, ON_AND_PROTECTED ); } else { osg::StencilTwoSided* stencil = new osg::StencilTwoSided(); stencil->setFunction(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::ALWAYS, 1, ~0u); stencil->setOperation(osg::StencilTwoSided::FRONT, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, incrOp); stencil->setFunction(osg::StencilTwoSided::BACK, osg::StencilTwoSided::ALWAYS, 1, ~0u); stencil->setOperation(osg::StencilTwoSided::BACK, osg::StencilTwoSided::KEEP, osg::StencilTwoSided::KEEP, decrOp); ss->setAttributeAndModes( stencil, ON_AND_PROTECTED ); } ss->setAttributeAndModes(new osg::ColorMask(false,false,false,false), ON_AND_PROTECTED); ss->setAttributeAndModes(new osg::Depth(osg::Depth::LESS,0,1,false), ON_AND_PROTECTED); //stencil_group->addChild( geometry ); this->addChild( _stencilGroup1 ); //root->addChild( stencil_group ); } else { osg::notify(osg::INFO) << "[osgEarth] One-sided stenciling" << std::endl; if ( !zFail ) // Z-Pass { _stencilGroup1 = new osg::Group(); osg::StateSet* front_ss = _stencilGroup1->getOrCreateStateSet(); front_ss->setRenderBinDetails( baseBin++, "RenderBin" ); // incrementing stencil op for front faces: osg::Stencil* front_stencil = new osg::Stencil(); front_stencil->setFunction( osg::Stencil::ALWAYS, 1, ~0u ); osg::Stencil::Operation incrOp = s_EXT_stencil_wrap ? osg::Stencil::INCR_WRAP : osg::Stencil::INCR; front_stencil->setOperation( osg::Stencil::KEEP, osg::Stencil::KEEP, incrOp ); front_ss->setAttributeAndModes( front_stencil, ON_AND_PROTECTED ); front_ss->setAttributeAndModes( new osg::ColorMask(false,false,false,false), ON_AND_PROTECTED); front_ss->setAttributeAndModes( new osg::CullFace(osg::CullFace::BACK), ON_AND_PROTECTED); front_ss->setAttributeAndModes( new osg::Depth(osg::Depth::LESS,0,1,false), ON_AND_PROTECTED); //front_group->addChild( geometry ); this->addChild( _stencilGroup1 ); //root->addChild( front_group ); // decrementing stencil op for back faces: _stencilGroup2 = new osg::Group(); osg::StateSet* back_ss = _stencilGroup2->getOrCreateStateSet(); back_ss->setRenderBinDetails( baseBin++, "RenderBin" ); osg::Stencil* back_stencil = new osg::Stencil(); back_stencil->setFunction( osg::Stencil::ALWAYS, 1, ~0u ); osg::Stencil::Operation decrOp = s_EXT_stencil_wrap ? osg::Stencil::DECR_WRAP : osg::Stencil::DECR; back_stencil->setOperation( osg::Stencil::KEEP, osg::Stencil::KEEP, decrOp ); back_ss->setAttributeAndModes( back_stencil, ON_AND_PROTECTED ); back_ss->setAttributeAndModes( new osg::ColorMask(false,false,false,false), ON_AND_PROTECTED); back_ss->setAttributeAndModes( new osg::CullFace(osg::CullFace::FRONT), ON_AND_PROTECTED); back_ss->setAttributeAndModes( new osg::Depth(osg::Depth::LESS,0,1,false), ON_AND_PROTECTED); //back_group->addChild( geometry ); this->addChild( _stencilGroup2 ); //root->addChild( back_group ); } else { // incrementing stencil op for back faces: { _stencilGroup1 = new osg::Group(); osg::StateSet* front_ss = _stencilGroup1->getOrCreateStateSet(); front_ss->setRenderBinDetails( baseBin++, "RenderBin" ); osg::Stencil* front_stencil = new osg::Stencil(); front_stencil->setFunction( osg::Stencil::ALWAYS ); //, 1, ~0u ); osg::Stencil::Operation incrOp = s_EXT_stencil_wrap ? osg::Stencil::INCR_WRAP : osg::Stencil::INCR; front_stencil->setOperation( osg::Stencil::KEEP, incrOp, osg::Stencil::KEEP ); front_ss->setAttributeAndModes( front_stencil, ON_AND_PROTECTED ); front_ss->setAttributeAndModes( new osg::ColorMask(false,false,false,false), ON_AND_PROTECTED); front_ss->setAttributeAndModes( new osg::CullFace(osg::CullFace::FRONT), ON_AND_PROTECTED); front_ss->setAttributeAndModes( new osg::Depth(osg::Depth::LESS,0,1,false), ON_AND_PROTECTED); //front_group->addChild( geometry ); this->addChild( _stencilGroup1 ); //root->addChild( front_group ); } // decrementing stencil buf for front faces { _stencilGroup2 = new osg::Group(); osg::StateSet* back_ss = _stencilGroup2->getOrCreateStateSet(); back_ss->setRenderBinDetails( baseBin++, "RenderBin" ); osg::Stencil* back_stencil = new osg::Stencil(); back_stencil->setFunction( osg::Stencil::ALWAYS ); //, 1, ~0u ); osg::Stencil::Operation decrOp = s_EXT_stencil_wrap ? osg::Stencil::DECR_WRAP : osg::Stencil::DECR; back_stencil->setOperation( osg::Stencil::KEEP, decrOp, osg::Stencil::KEEP ); back_ss->setAttributeAndModes( back_stencil, ON_AND_PROTECTED ); back_ss->setAttributeAndModes( new osg::ColorMask(false,false,false,false), ON_AND_PROTECTED); back_ss->setAttributeAndModes( new osg::CullFace(osg::CullFace::BACK), ON_AND_PROTECTED); back_ss->setAttributeAndModes( new osg::Depth(osg::Depth::LESS,0,1,false), ON_AND_PROTECTED); //back_group->addChild( geometry ); this->addChild( _stencilGroup2 ); //root->addChild( back_group ); } } } // NOW built the full-screen quad mask that will paint the volume: _maskGroup = new osg::Group(); // make a full screen quad: osg::Geometry* quad = new osg::Geometry(); osg::Vec3Array* verts = new osg::Vec3Array(4); (*verts)[0].set( 0, 1, 0 ); (*verts)[1].set( 0, 0, 0 ); (*verts)[2].set( 1, 0, 0 ); (*verts)[3].set( 1, 1, 0 ); quad->setVertexArray( verts ); quad->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) ); _maskColorArray = new osg::Vec4Array(1); (*_maskColorArray)[0] = osg::Vec4f(1,1,1,1); quad->setColorArray( _maskColorArray ); quad->setColorBinding( osg::Geometry::BIND_OVERALL ); osg::Geode* quad_geode = new osg::Geode(); quad_geode->addDrawable( quad ); osg::StateSet* quad_ss = quad->getOrCreateStateSet(); quad_ss->setMode( GL_CULL_FACE, OFF_AND_PROTECTED ); quad_ss->setMode( GL_DEPTH_TEST, OFF_AND_PROTECTED ); quad_ss->setMode( GL_LIGHTING, OFF_AND_PROTECTED ); osg::Stencil* quad_stencil = new osg::Stencil(); quad_stencil->setFunction( osg::Stencil::NOTEQUAL, 128, (unsigned int)~0 ); // this will conveniently re-clear the stencil buffer in prep for the next pass: quad_stencil->setOperation( osg::Stencil::REPLACE, osg::Stencil::REPLACE, osg::Stencil::REPLACE ); quad_ss->setAttributeAndModes( quad_stencil, ON_AND_PROTECTED ); osg::MatrixTransform* abs = new osg::MatrixTransform(); abs->setReferenceFrame( osg::Transform::ABSOLUTE_RF ); abs->setMatrix( osg::Matrix::identity() ); abs->addChild( quad_geode ); osg::Projection* proj = new osg::Projection(); proj->setMatrix( osg::Matrix::ortho(0, 1, 0, 1, 0, -1) ); proj->addChild( abs ); _maskGroup->addChild( proj ); _maskGroup->getOrCreateStateSet()->setMode( GL_BLEND, 1 ); _maskGroup->getOrCreateStateSet()->setRenderBinDetails( baseBin++, "RenderBin" ); this->addChild( _maskGroup ); }
bool StencilVolumeNode::insertChild | ( | unsigned int | index, |
Node * | child | ||
) | [virtual] |
Definition at line 108 of file StencilVolumeNode.cpp.
{ if ( !child ) return false; dirtyBound(); if ( _depthPass ) _depthPass->insertChild( index, child ); return _renderPass->insertChild( index, child ); }
osgEarth::Features::StencilVolumeNode::META_Node | ( | osgEarth::Features | , |
StencilVolumeNode | |||
) |
bool StencilVolumeNode::removeChildren | ( | unsigned int | pos, |
unsigned int | numChildrenToRemove | ||
) | [virtual] |
Definition at line 115 of file StencilVolumeNode.cpp.
{ dirtyBound(); if ( _depthPass ) _depthPass->removeChildren( pos, numChildrenToRemove ); return _renderPass->removeChildren( pos, numChildrenToRemove ); }
bool StencilVolumeNode::replaceChild | ( | Node * | origChild, |
Node * | newChild | ||
) | [virtual] |
Definition at line 121 of file StencilVolumeNode.cpp.
{ dirtyBound(); if ( _depthPass ) _depthPass->replaceChild( origChild, newChild ); return _renderPass->replaceChild( origChild, newChild ); }
int StencilVolumeNode::setBaseRenderBin | ( | int | bin | ) |
Definition at line 59 of file StencilUtils.cpp.
{ if ( _stencilGroup1 ) { _stencilGroup1->getOrCreateStateSet()->setRenderBinDetails( bin++, "RenderBin" ); } if ( _stencilGroup2 ) { _stencilGroup2->getOrCreateStateSet()->setRenderBinDetails( bin++, "RenderBin" ); } if ( _maskGroup ) { _maskGroup->getOrCreateStateSet()->setRenderBinDetails( bin++, "RenderBin" ); } return bin; }
bool StencilVolumeNode::setChild | ( | unsigned int | i, |
Node * | node | ||
) | [virtual] |
Definition at line 127 of file StencilVolumeNode.cpp.
{ dirtyBound(); if ( _depthPass ) _depthPass->setChild( i, node ); return _renderPass->setChild( i, node ); }
void StencilVolumeNode::traverse | ( | osg::NodeVisitor & | nv | ) | [virtual] |
Definition at line 141 of file StencilVolumeNode.cpp.
{ _root->accept( nv ); }
osg::Group* osgEarth::Features::StencilVolumeNode::_depthPass [protected] |
Definition at line 83 of file StencilVolumeNode.
bool osgEarth::Features::StencilVolumeNode::_inverted [protected] |
Definition at line 85 of file StencilVolumeNode.
Definition at line 86 of file StencilVolumeNode.
osg::Group* osgEarth::Features::StencilVolumeNode::_renderPass [protected] |
Definition at line 84 of file StencilVolumeNode.
osg::ref_ptr<osg::Group> osgEarth::Features::StencilVolumeNode::_root [protected] |
Definition at line 80 of file StencilVolumeNode.
osg::Group* osgEarth::Features::StencilVolumeNode::_stencilGroup1 [protected] |
Definition at line 81 of file StencilVolumeNode.
osg::Group* osgEarth::Features::StencilVolumeNode::_stencilGroup2 [protected] |
Definition at line 82 of file StencilVolumeNode.