[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