root/OpenSceneGraph/trunk/src/osgPlugins/geo/ClipRegion.cpp @ 13041

Revision 13041, 5.4 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// clip region
2// GEO version, Nov 2003
3// may be replaced when clipRegion accepted into OSG proper.
4// i) a clipregion is class derived from Group, with a Geode and any children of the group
5// ii) a special draw is made that:
6//    sets stencil bits by drawing the clip Geode
7//    draws the children of group clipped by the stencil region.
8// partly derived fromt he stencil code in osgreflect example.
9
10#include "ClipRegion.h"
11#include <osg/ColorMask>
12#include <osg/Geode>
13#include <osg/Depth>
14#include <osg/BlendFunc>
15#include <osgUtil/CullVisitor>
16
17using namespace osg;
18
19//=====
20GeoClipRegion::GeoClipRegion(int bin)
21{
22    stencilbin=bin;
23}
24
25GeoClipRegion::~GeoClipRegion()
26{
27}
28
29GeoClipRegion::GeoClipRegion(const GeoClipRegion& clr,const osg::CopyOp& copyop): osg::Group(clr,copyop)
30{    //_clipNodes=clr._clipNodes;
31}
32
33void GeoClipRegion::addClipNode(osg::Node *gd) {
34
35    osg::StateSet *state=gd->getOrCreateStateSet();
36    // add clip node(s) to set stencil bit marking the clip area.
37    // stencil op so that the stencil buffer get set at the clip pixels
38    osg::Stencil* stencil = new osg::Stencil;
39    stencil->setFunction(osg::Stencil::ALWAYS,1,~0u);
40    stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::REPLACE);
41    state->setAttributeAndModes(stencil,osg::StateAttribute::ON);
42
43    // switch off the writing to the color bit planes. (Dont show the clip area)
44    osg::ColorMask* colorMask = new osg::ColorMask;
45    colorMask->setMask(false,false,false,false);
46
47    state->setRenderBinDetails(stencilbin,"RenderBin");
48    state->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
49    state->setAttribute(colorMask);
50        // set up depth so all writing to depth goes to maximum depth. (dont want to z-clip the cull stencil)
51    osg::Depth* depth = new osg::Depth;
52    depth->setFunction(osg::Depth::ALWAYS);
53    depth->setRange(1.0,1.0);
54    state->setAttribute(depth);
55    Group::addChild(gd);
56}
57
58bool GeoClipRegion::addChild( osg::Node *child )
59{
60    // bin the last - draw 'real' scenery last, using Z buffer to clip against any clip region...
61
62        osg::StateSet* statesetBin2 = child->getOrCreateStateSet();
63        statesetBin2->setRenderBinDetails(stencilbin+3,"RenderBin");
64    /*   osg::Stencil* stencil = new osg::Stencil;
65        stencil->setFunction(osg::Stencil::ALWAYS,0,~0);
66        stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::REPLACE);
67        statesetBin2->setAttributeAndModes(stencil,osg::StateAttribute::ON);*/
68        return Group::addChild(child);
69}
70
71bool GeoClipRegion::addClippedChild( osg::Node *child )
72{
73// these children of this clipregion are drawn in stencilBin+2, clipped at the edges of the clip region
74    osg::StateSet *state=child->getOrCreateStateSet();
75    // state tests pixels against the set stencil.
76    osg::Stencil* stenciltest = new osg::Stencil;
77    stenciltest->setFunction(osg::Stencil::EQUAL,1,~0u);
78    stenciltest->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP);
79    state->setAttributeAndModes(stenciltest,osg::StateAttribute::ON);
80
81    osg::ColorMask* cMask = new osg::ColorMask;
82    cMask->setMask(true,true,true,true);
83    state->setAttribute(cMask);
84
85    state->setRenderBinDetails(stencilbin+1,"RenderBin");
86    // use depth for rest of the scene unless overriden.
87    osg::Depth* rootDepth = new osg::Depth;
88    rootDepth->setFunction(osg::Depth::LESS);
89    rootDepth->setRange(0.0,1.0);
90    state->setAttribute(rootDepth);
91
92    return   Group::addChild(child);
93}
94bool GeoClipRegion::addObscuredChild( osg::Node *child )
95{
96// other children of this node are drawn in stencilBin+2 outside the clip, hidden by the clip region
97    osg::StateSet *state=child->getOrCreateStateSet();
98    // state tests pixels against the set stencil.
99    osg::Stencil* stenciltest = new osg::Stencil;
100    stenciltest->setFunction(osg::Stencil::NOTEQUAL,1,~0u);
101    stenciltest->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP);
102    state->setAttributeAndModes(stenciltest,osg::StateAttribute::ON);
103
104    osg::ColorMask* cMask = new osg::ColorMask;
105    cMask->setMask(true,true,true,true);
106    state->setAttribute(cMask);
107
108    state->setRenderBinDetails(stencilbin+1,"RenderBin");
109    // use depth for rest of the scene unless overriden.
110    osg::Depth* rootDepth = new osg::Depth;
111    rootDepth->setFunction(osg::Depth::LESS);
112    rootDepth->setRange(0.0,1.0);
113    state->setAttribute(rootDepth);
114    return Group::addChild(child);
115}
116
117void GeoClipRegion::addDrawClipNode(osg::Node *ndclip)
118{
119    osg::StateSet *state=ndclip->getOrCreateStateSet();
120    // last bin  - draw clip area and blend it with the clipped, visible geometry.
121
122    // set up depth so all writing to depth goes to maximum depth.
123    osg::Depth* depth = new osg::Depth;
124    depth->setFunction(osg::Depth::ALWAYS);
125
126    osg::Stencil* stencil = new osg::Stencil;
127    stencil->setFunction(osg::Stencil::EQUAL,1,~0u);
128    stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::ZERO);
129
130    // set up additive blending.
131    osg::BlendFunc* trans = new osg::BlendFunc;
132    trans->setFunction(osg::BlendFunc::ONE,osg::BlendFunc::ONE);
133
134    state->setRenderBinDetails(stencilbin+2,"RenderBin");
135    state->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
136    state->setAttributeAndModes(stencil,osg::StateAttribute::ON);
137    state->setAttributeAndModes(trans,osg::StateAttribute::ON);
138    state->setAttribute(depth);
139    Group::addChild(ndclip);
140}
Note: See TracBrowser for help on using the browser.