[osg-users] draw callbacks
Peter Bako
osgforum at tevs.eu
Wed Mar 30 08:01:44 PDT 2016
Hi,
I tried Javier's example, but I don't know how to modify the code, so that the
stencil plane covers the "holes" on the clipped geometry.
In this case the plane is renedered over the whole scene.
I tried to remove the transformation and projection, then the plane was rendered on the correct position but it was still a square.
I know, how should it work, but I cannot find a solution..
How should I change it? can you help me?
Thank you!
Code:
#include <osgFX/Effect>
#include <osg/Geometry>
#include <osg/Stencil>
#include <osg/Depth>
class CappingTechnique : public osgFX::Technique {
private:
osg::ref_ptr<osg::Node> _capPlane;
public:
virtual bool validate(osg::State&) const
{ return true; }
META_Technique("CappingTechnique","Pimpel capping technique");
/// Constructor
CappingTechnique()
{
// Build the plane to draw with the stencil mask
osg::Geometry *geometry = new osg::Geometry();
osg::Vec3Array *vertices = new osg::Vec3Array();
osg::Vec4Array *colors = new osg::Vec4Array();
vertices->push_back(osg::Vec3(-1.0, -1.0, 0.0));
vertices->push_back(osg::Vec3(-1.0, 1.0, 0.0));
vertices->push_back(osg::Vec3(1.0, 1.0, 0.0));
vertices->push_back(osg::Vec3(1.0, -1.0, 0.0));
geometry->setVertexArray(vertices);
colors->push_back(osg::Vec4(1.0, 0.0, 1.0, 1.0));
geometry->setColorArray(colors);
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
geometry->addPrimitiveSet(new
osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
osg::Geode *geode = new osg::Geode();
geode->addDrawable(geometry);
osg::Transform *trans = new osg::Transform();
trans->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
trans->addChild( geode );
osg::Projection *proj = new
osg::Projection(osg::Matrix::ortho2D(-1,1,-1,1));
proj->addChild( trans );
_capPlane = proj;
}
protected:
virtual void define_passes()
{
// pass #0
{
osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
osg::Stencil *stencil = new osg::Stencil;
stencil->setFunction(osg::Stencil::ALWAYS, 0x0, ~0);
stencil->setOperation(osg::Stencil::INVERT, osg::Stencil::INVERT, osg::Stencil::INVERT);
ss->setAttributeAndModes(stencil, osg::StateAttribute::ON |
osg::StateAttribute::OVERRIDE);
ss->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
addPass(ss.get());
}
// pass #1
{
osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
osg::Stencil *stencil = new osg::Stencil;
stencil->setFunction(osg::Stencil::NOTEQUAL, 0x0, ~0);
stencil->setOperation(osg::Stencil::ZERO, osg::Stencil::ZERO,osg::Stencil::ZERO);
ss->setAttributeAndModes(stencil, osg::StateAttribute::ON |
osg::StateAttribute::OVERRIDE);
osg::Depth *depth = new osg::Depth();
depth->setWriteMask(false);
ss->setAttributeAndModes( depth, osg::StateAttribute::ON );
addPass(ss.get());
}
}
virtual osg::Node *getOverrideChild(int pass){
switch(pass) {
case 1: // Second pass (pass #1) draws the cap plane
return _capPlane;
break;
default:
return NULL;
break;
}
}
};
class CappingEffect : public osgFX::Effect {
public:
CappingEffect() : osgFX::Effect() {}
CappingEffect( const CappingEffect& copy, const osg::CopyOp op=osg::CopyOp::SHALLOW_COPY )
: osgFX::Effect(copy, op) {}
META_Effect( osgFX, CappingEffect, "CappingEffect", "", "" );
protected:
virtual bool define_techniques(){
CappingTechnique* technique = new CappingTechnique();
addTechnique(technique);
return true;
}
};
int main( int argc, char** argv )
{
//load any node
osg::ref_ptr<osg::Geode> scene = new osg::Geode;
scene->addDrawable( new TeapotDrawable(1.0f) );
osg::ClipNode* clipnode = new osg::ClipNode;
osg::ref_ptr<osg::ClipPlane> clipplane = new osg::ClipPlane();
clipplane->setClipPlane(0, 0, -1, 0);
clipnode->addClipPlane(clipplane);
clipnode->addChild(scene.get());
CappingEffect* capping_effect = new CappingEffect();
capping_effect->addChild(clipnode);
osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild(capping_effect);
osgViewer::Viewer viewer;
viewer.setSceneData( root.get() );
return viewer.run();
}
Cheers,
Peter
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=66674#66674
More information about the osg-users
mailing list