How to clean up Stencil Buffer between two nodes in OSG

20 views
Skip to first unread message

te lee

unread,
May 19, 2020, 2:10:39 AM5/19/20
to vsg-users : VulkanSceneGraph Developer Discussion Group
             
            I'm very sorry to ask you this question, because I encountered a very difficult problem in the process of OSG development, which bothered me for three weeks.

         The problem is that I plan to use OSG to implement similar functions.  Open multiple sectioning at the same time and cover with cover.


1.png

              
                                                    

         1. First of all, refer to this algorithm, and use the Stencil to test the building cover, which can achieve the following results.
                        void CappingTechnique::redefine_passes(int openedClipNum)
{
if (_openedClipNum != openedClipNum)
{
this->dirtyPasses();
{
osg::ref_ptr<osg::StateSet> ss = new osg::StateSet;
osg::ColorMask* colorMask = new osg::ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
ss->setAttribute(colorMask);

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);

ss->setMode(GL_CLIP_PLANE0, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
ss->setMode(GL_CLIP_PLANE1, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
ss->setMode(GL_CLIP_PLANE2, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
ss->setMode(GL_CLIP_PLANE3, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
ss->setMode(GL_CLIP_PLANE4, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);

if (openedClipNum >= 0)
{
ss->setMode(GL_CLIP_PLANE0 + openedClipNum, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
}

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);

ss->setMode(GL_CLIP_PLANE0, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
ss->setMode(GL_CLIP_PLANE1, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
ss->setMode(GL_CLIP_PLANE2, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
ss->setMode(GL_CLIP_PLANE3, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
ss->setMode(GL_CLIP_PLANE4, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

if (openedClipNum >= 0)
{
ss->setMode(GL_CLIP_PLANE0 + openedClipNum, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
}
 
addPass(ss.get());
}
}
                                      
         2. here, create and display the cover hanging under the relatively independent node.when opening a section, the cover surface can be created and displayed correctly. 

2.png

                              
       3 However, when opening multiple cover surfaces at the same time, the following error will appear, which seems to be caused by the incorrect cleaning of the stencil buffer.

3.png

                             

        4. Searching data through Google did not find out how to clean the stencil buffer when drawing between two nodes.

                          

Robert Osfield

unread,
May 19, 2020, 4:07:19 AM5/19/20
to OpenSceneGraph Users
I have moved this posted from vsg-users to osg-users as this is the correct forum for OSG support.

In the OSG to do multi-pass effect that require clearing of the depth/color/stencil buffers you use an osg::Camera.  The osghud example has a code path that illustrates the use of osg::Camera to clear the depth buffer only.  The part that controls the clearing is the line:

    // only clear the depth buffer
    camera->setClearMask(GL_DEPTH_BUFFER_BIT);

For you needs you'd use the GL_STENCIL_BUFFER_BIT.

te lee

unread,
Jun 19, 2020, 12:07:32 AM6/19/20
to OpenSceneGraph Users
Thank you very much. The code above works
Reply all
Reply to author
Forward
0 new messages