Just for the record, in case someone need to implement it or something
similar, the code below is what has worked for me.
The capping geometry in _capPlane is just a plane covering the whole
screen, just for testing the effect. It should fit the clipping plane(s) to
see it correctly.
Thank you very much for your help, Robert.
-----------------------8<-------------8<-------------8<-------------8<-------------8<-------------
class CappingTechnique : public osgFX::Technique {
private:
osg::Node *_capPlane;
public:
//virtual bool validate(osg::State&) const
//{ return true; }
/// 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;
}
}
};
-----------------------8<-------------8<-------------8<-------------8<-------------8<-------------
On Thu, Sep 2, 2010 at 5:19 PM, Robert Milharcic <
[email protected]> wrote:
>
>
> You can use osgFX node kit framework to implement described capping
> tehnique. You do that by inheriting osgFX::Effect class. In your derived
> class you have to override/implement virtual bool define_techniques()
> member of the osgFX::Effect class like this:
>
>
>
> bool CappingEffect::define_techniques()
>
> {
>
> CappingTechnique* technique = new CappingTechnique(this);
>
> addTechnique(technique);
>
> return true;
>
> }
>
>
>
> CappingTechnique must inherit from osgFX::Technique. In the derived class
> you will have to implement virtual bool validate(osg::State&) const,
> virtual void define_passes() and optionally virtual osg::Node*
> getOverrideChild(int pass) like this:
>
>
>
> bool CappingTechnique::validate(osg::State&) const
>
> {
>
> return true;
>
> }
>
>
>
> bool CappingTechnique:: define_passes()
>
> {
>
> // pass #1
>
> {
>
> osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
>
> ... setup states for stencil operation
>
> addPass(ss.get());
>
> }
>
> // implement pass #2
>
> {
>
> osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
>
> ... setup states for solid color draw
>
> addPass(ss.get());
>
> }
>
> }
>
>
>
> You can optionally implement getOverrideChild (int pass) to supply some
> other graph for a particlular pass. You then add your group to the
> CappingEffect (the osgFX::Effect inherits from osg::Group node) and
> CappingEffect to the camera.
>
>
>
> Robert Milharcic
>
>
>
> *From:* [email protected] [mailto:
> [email protected]] *On Behalf Of *Javier Taibo
> *Sent:* Thursday, September 02, 2010 1:09 PM
> *To:* [email protected]
> *Subject:* [osg-users] draw callbacks
>
>
>
> Hi,
>
> I have some solid geometry clipped by some clipping planes in an OSG
> application. I am trying to use the capping technique described in chapter
> 10 of the Red Book using the stencil buffer. I have successfully implemented
> this technique in raw OpenGL, but I would like to use it whithin the OSG
> application. The technique is based on storing on the stencil buffer the
> regions that are "open" and then in a later pass draw a solid color in these
> regions.
>
> I have put the clipped geometry under an osg::Camera node with the
> stencil function configured. To do the second pass (the one that draws the
> caps in the regions marked in the stencil), I am trying to use a post-draw
> callback with the OpenGL calls (saving and restoring the states to avoid
> breaking things). The problem is that I need to set the NESTED rendering
> order to see all the scene graph, and when I do it, the post-draw callback
> is not called anymore.
>
> I do not have full control over the application, so the solution I am
> looking for has to be "transparent" to the rest of the scene graph. I must
> activate this behaviour to a group in the scene graph without breaking
> anything outside this branch. What is the best way to do it? camera
> post-draw callbacks? rendering bins? any other?
>
> I am not very familiar with render passes in OSG, so the way I am trying
> is probably not the best way. I would appreciate any suggestion, advice or
> pointer to any related documentation or source code.
>
>
> Thanks in advance.
>
>
> Javier Taibo.
>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org