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





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to