Hi 
Thanks alot for your comments Sergey and Chris.  

I have tried to implement the algorithm, code and comments below but it doesn't 
work as I had hoped.  

What I expected to see is the back wall of a cylinder (which intersects a box). 
 What I actually see is the whole back wall of a cylinder rendered and the 
image flickers.  

Perhaps I have approached this the wrong way regarding loading the depth buffer 
and then creating the stencil mask or have just misunderstood how to do it? Any 
comments or pointers on the code would be very welcome.

#include "stdafx.h"
#include  <osg/Geode>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osg/ShapeDrawable>

#include <osg/Depth>
#include <osg/Stencil>
#include <osg/CullFace>

#include <time.h>

osg::ref_ptr<osg::Group> root;
osg::ref_ptr<osg::Geode> myBoxGeode;
osg::ref_ptr<osg::Geode> myCylinderGeode;

void loadCylinder()
{
        
        osg::ref_ptr<osg::Cylinder> myCylinder = new 
osg::Cylinder(osg::Vec3(0,0,0),0.1,1.0);
        osg::ref_ptr<osg::ShapeDrawable> myCylinderDrawable = new 
osg::ShapeDrawable(myCylinder);
         myCylinderGeode = new osg::Geode();
        myCylinderGeode->addDrawable(myCylinderDrawable);
        root->addChild(myCylinderGeode);
        

}

void loadBox()
{
        //create a box
        osg::ref_ptr<osg::Box> myBox = new osg::Box(osg::Vec3(0,0,0),0.5);
        osg::ref_ptr<osg::ShapeDrawable> myBoxDrawable = new 
osg::ShapeDrawable(myBox);
         myBoxGeode = new osg::Geode();
        myBoxGeode->addDrawable(myBoxDrawable);
        root->addChild(myBoxGeode);

}



int _tmain(int argc, _TCHAR* argv[])
{
        root = new osg::Group;
        loadCylinder();
        loadBox();
        
        osg::StateSet* cylState = myCylinderGeode->getOrCreateStateSet();
        osg::CullFace* cfCyl = new osg::CullFace();
        cylState->setAttributeAndModes(cfCyl);

        osg::StateSet* boxState = myBoxGeode->getOrCreateStateSet();
        osg::CullFace* cfBox = new osg::CullFace();
        boxState->setAttributeAndModes(cfBox);

        osg::StateSet* state = root->getOrCreateStateSet();

        osg::ColorMask* colorMask = new osg::ColorMask();
        osg::Depth* depth = new osg::Depth();
        osg::Stencil* stencil = new osg::Stencil();

        state->setAttribute(stencil);
    state->setAttribute(colorMask);
    state->setAttribute(depth);
        

        osgViewer::Viewer viewer;
        viewer.addEventHandler(new osgViewer::StatsHandler());
        viewer.setUpViewInWindow( 50, 50, 1024, 768 );
    viewer.setSceneData( root );
        viewer.setCameraManipulator(new osgGA::TrackballManipulator());

        osg::DisplaySettings::instance()->setMinimumNumStencilBits(8);
        


        while( !viewer.done() )
    {
        /*****************************************************************
        * Turn off writing to the colour buffer, so nothing is rendered 
        * to the screen yet
        *
        *******************************************************************/
         colorMask->setMask(false, false,false,false);
        
        /*****************************************************************
        * Clear stencil buffer to O ??
        *
        *
        *******************************************************************/
         


        /*****************************************************************
        * Turn on depth testing
        * 
        *
        *******************************************************************/
        state->setAttribute(depth, osg::StateAttribute::ON );

        

        /***************************************************************
        * Render the back  face of cylinder (object a) into depth buffer
        * Ensure the box (object b ) isn't rendered
        *
        *****************************************************************/
        cfCyl->setMode(osg::CullFace::FRONT);
        cfBox->setMode(osg::CullFace::FRONT_AND_BACK);
        viewer.frame();

        /***************************************************************
        * Disable writing to the depth buffer
        *
        *
        *****************************************************************/
        depth->setWriteMask( false );
        


        /*****************************************************************
        * Set the stencil buffer to increment if the depth test passes
        *
        *
        ******************************************************************/
        //enable the stencil test
        stencil->setWriteMask(true);
        state->setAttribute( stencil, osg::StateAttribute::ON );

        //set the stencil functions
        stencil->setFunction(osg::Stencil::ALWAYS,0,0);
        
stencil->setOperation(osg::Stencil::KEEP,osg::Stencil::KEEP,osg::Stencil::INCR);

        /*****************************************************************
        * Render the front faces of the box object b
        *
        *
        ******************************************************************/
        cfCyl->setMode(osg::CullFace::FRONT_AND_BACK);
        cfBox->setMode(osg::CullFace::BACK);
        viewer.frame();


        /*****************************************************************
        * Set the stencil buffer to decrement if the depth test passes
        *
        *
        ******************************************************************/
        
stencil->setOperation(osg::Stencil::KEEP,osg::Stencil::KEEP,osg::Stencil::DECR);
        
        
/****************************************************************************
        * Render the back face of the box (object b) 
        *
        *
        
*****************************************************************************/
        cfBox->setMode(osg::CullFace::FRONT);
        viewer.frame();


        
/*******************************************************************************
        * Set the stencil buffer to pass where values aren't equal to 0
        *
        *
        
********************************************************************************/
        stencil->setFunction(osg::Stencil::NOTEQUAL,0,1);

        
/*******************************************************************************
        * Turn off writing to the stencil buffer
        *
        *
        
********************************************************************************/
        stencil->setWriteMask(false);

        
/*******************************************************************************
        * Turn on writing to the colour buffer
        *
        *
        
********************************************************************************/
        colorMask->setMask(true, true,true,true);

        
/*******************************************************************************
        * Turn off depth testing
        *
        *
        
********************************************************************************/
        state->setAttribute(depth,osg::StateAttribute::OFF);

        
/*******************************************************************************
        * Render back faces of cylinder object a
        *
        *
        
********************************************************************************/
        cfCyl->setMode(osg::CullFace::FRONT);
        cfBox->setMode(osg::CullFace::FRONT_AND_BACK);

        viewer.frame();
        
        }

        return 0;
}





Thank you!

Cheers,
Craig

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=41421#41421




Attachments: 
http://forum.openscenegraph.org//files/stencil_buffer_171.cpp


_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to