root/OpenSceneGraph/trunk/src/osgGA/StateSetManipulator.cpp @ 10946

Revision 10946, 7.9 kB (checked in by robert, 5 years ago)

From Sukender, warning fix.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osgGA/StateSetManipulator>
2
3#include <osg/PolygonMode>
4#include <osg/ref_ptr>
5#include <osg/Texture>
6#include <osg/Texture2D>
7#include <osg/TextureRectangle>
8#include <osg/TextureCubeMap>
9
10
11// #define COMPILE_TEXENVFILTER_USAGE
12#if COMPILE_TEXENVFILTER_USAGE
13    #include <osg/TexEnvFilter>
14#endif
15
16using namespace osg;
17using namespace osgGA;
18
19StateSetManipulator::StateSetManipulator(osg::StateSet* stateset):
20    _initialized(false),
21    _backface(false),
22    _lighting(false),
23    _texture(false),
24    _maxNumOfTextureUnits(4),
25    _keyEventToggleBackfaceCulling('b'),
26    _keyEventToggleLighting('l'),
27    _keyEventToggleTexturing('t'),
28    _keyEventCyclePolygonMode('w')
29{
30    setStateSet(stateset);
31}
32
33StateSetManipulator::~StateSetManipulator()
34{
35}
36
37void StateSetManipulator::setStateSet(StateSet *stateset)
38{
39    _stateset = stateset;
40#if 0
41    // specify that this stateset is dynamic so it prevents
42    // the draw and update phase from overlapping - good for
43    // stability but breaks all the performance advantage of
44    // DrawThreadPerContex.
45    _stateset->setDataVariance(osg::Object::DYNAMIC);
46#endif
47}
48
49StateSet *StateSetManipulator::getStateSet()
50{
51    return _stateset.get();
52}
53
54const StateSet *StateSetManipulator::getStateSet() const
55{
56    return _stateset.get();
57}
58
59void StateSetManipulator::clone()
60{
61    if (!_stateset) return;
62   
63    // we clone the StateSet so that any draw traversals that might be running at the time of the
64    // event traversal won't change the same StateSet that is being read.  One could just set the
65    // DataVariance to DYNAMIC to avoid this overlap, but this would introduce a performance penalty.
66   
67    StateSet::ParentList parents = _stateset->getParents();
68    osg::ref_ptr<osg::StateSet> newStateSet = dynamic_cast<osg::StateSet*>(_stateset->clone(osg::CopyOp::SHALLOW_COPY));
69
70    // change the parents of the original StateSet to point to the new stateset
71    for(StateSet::ParentList::iterator itr = parents.begin();
72        itr !=  parents.end();
73        ++itr)
74    {
75        osg::Object* object = *itr;
76        osg::Node* node = dynamic_cast<osg::Node*>(object);
77        if (node) node->setStateSet(newStateSet.get());
78        else
79        {
80            osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(object);
81            if (drawable) drawable->setStateSet(newStateSet.get());
82        }
83    }
84   
85    _stateset = newStateSet;
86}
87
88bool StateSetManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& aa)
89{
90    if(!_stateset.valid()) return false;
91
92    if (!_initialized)
93    {
94        _initialized = true;
95        _backface = (_stateset->getMode(GL_CULL_FACE)&osg::StateAttribute::ON);
96        _lighting =(_stateset->getMode(GL_LIGHTING)&osg::StateAttribute::ON);
97
98        unsigned int mode = osg::StateAttribute::INHERIT|osg::StateAttribute::ON;
99
100        _texture = (_stateset->getTextureMode(0,GL_TEXTURE_2D)&mode)!=0 ||
101                   (_stateset->getTextureMode(0,GL_TEXTURE_3D)&mode)!=0 ||
102                   (_stateset->getTextureMode(0,GL_TEXTURE_RECTANGLE)&mode)!=0 ||
103                   (_stateset->getTextureMode(0,GL_TEXTURE_CUBE_MAP)&mode)!=0;
104                   
105        #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE)
106            _texture |= ((_stateset->getTextureMode(0,GL_TEXTURE_1D)&mode)!=0);
107        #endif
108    }
109
110    if (ea.getHandled()) return false;
111
112    if (ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN)
113    {
114
115        if ( ea.getKey() == _keyEventToggleBackfaceCulling )
116        {
117            setBackfaceEnabled(!getBackfaceEnabled());
118            aa.requestRedraw();
119            return true;
120        }
121        if ( ea.getKey() == _keyEventToggleLighting )
122        {
123                setLightingEnabled(!getLightingEnabled());
124                aa.requestRedraw();
125                return true;
126        }
127        if ( ea.getKey() == _keyEventToggleTexturing )
128        {
129                setTextureEnabled(!getTextureEnabled());
130                aa.requestRedraw();
131                return true;
132        }
133        if ( ea.getKey() == _keyEventCyclePolygonMode )
134        {
135                cyclePolygonMode();
136                aa.requestRedraw();
137                return true;
138        }
139    }
140
141    return false;
142}
143
144void StateSetManipulator::getUsage(osg::ApplicationUsage& usage) const
145{
146    usage.addKeyboardMouseBinding(reinterpret_cast<const char*>(&_keyEventToggleBackfaceCulling),"Toggle backface culling");
147    usage.addKeyboardMouseBinding(reinterpret_cast<const char*>(&_keyEventToggleLighting),"Toggle lighting");
148    usage.addKeyboardMouseBinding(reinterpret_cast<const char*>(&_keyEventToggleTexturing),"Toggle texturing");
149    usage.addKeyboardMouseBinding(reinterpret_cast<const char*>(&_keyEventCyclePolygonMode),"Toggle polygon fill mode between fill, line (wire frame) and points");
150}
151
152
153void StateSetManipulator::setBackfaceEnabled(bool newbackface)
154{
155    if (_backface == newbackface) return;
156   
157    clone();
158   
159    _backface = newbackface;
160    if( _backface ) _stateset->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
161    else _stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
162}
163
164void StateSetManipulator::setLightingEnabled(bool newlighting)
165{
166    if (_lighting == newlighting) return;
167   
168    clone();
169
170    _lighting = newlighting;
171    if( _lighting ) _stateset->setMode(GL_LIGHTING,osg::StateAttribute::ON);
172    else _stateset->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
173}
174
175void StateSetManipulator::setTextureEnabled(bool newtexture)
176{
177    if (_texture==newtexture) return;
178   
179    clone();
180
181    _texture = newtexture;
182//    osg::ref_ptr< osg::Texture > tex = dynamic_cast<osg::Texture*>
183//        ( _stateset->getAttribute( osg::StateAttribute::TEXTURE ) );
184//    cout << tex->numTextureUnits() << endl;
185
186    unsigned int mode = osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF;
187    if ( _texture ) mode = osg::StateAttribute::INHERIT|osg::StateAttribute::ON;
188    for( unsigned int ii=0; ii<_maxNumOfTextureUnits; ii++ )
189    {
190        #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE)
191            _stateset->setTextureMode( ii, GL_TEXTURE_1D, mode );
192        #endif
193        _stateset->setTextureMode( ii, GL_TEXTURE_2D, mode );
194        _stateset->setTextureMode( ii, GL_TEXTURE_3D, mode );
195        _stateset->setTextureMode( ii, GL_TEXTURE_RECTANGLE, mode );
196        _stateset->setTextureMode( ii, GL_TEXTURE_CUBE_MAP, mode);
197    }
198}
199
200void StateSetManipulator::setPolygonMode(osg::PolygonMode::Mode newpolygonmode)
201{
202    clone();
203
204    osg::PolygonMode* polyModeObj = getOrCreatePolygonMode();
205
206    polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,newpolygonmode);
207}
208
209void StateSetManipulator::cyclePolygonMode()
210{
211    clone();
212
213    osg::PolygonMode* polyModeObj = getOrCreatePolygonMode();
214
215    osg::PolygonMode::Mode currentMode = getPolygonMode();
216    // cycle through the available modes. 
217    switch(currentMode)
218    {
219        case osg::PolygonMode::FILL : polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE); break;
220        case osg::PolygonMode::LINE : polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::POINT); break;
221        case osg::PolygonMode::POINT : polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::FILL); break;
222    }
223}
224
225osg::PolygonMode::Mode StateSetManipulator::getPolygonMode() const
226{
227    osg::PolygonMode* polyModeObj = dynamic_cast<osg::PolygonMode*>(_stateset->getAttribute(osg::StateAttribute::POLYGONMODE));
228    if (polyModeObj) return polyModeObj->getMode(osg::PolygonMode::FRONT_AND_BACK);
229    else return osg::PolygonMode::FILL;
230}
231
232osg::PolygonMode* StateSetManipulator::getOrCreatePolygonMode()
233{
234    osg::PolygonMode* polyModeObj = dynamic_cast<osg::PolygonMode*>(_stateset->getAttribute(osg::StateAttribute::POLYGONMODE));
235    if (!polyModeObj)
236    {
237        polyModeObj = new osg::PolygonMode;
238        _stateset->setAttribute(polyModeObj);
239    }
240    return polyModeObj;
241}
Note: See TracBrowser for help on using the browser.