root/OpenSceneGraph/trunk/src/osg/State.cpp @ 10590

Revision 10590, 31.5 kB (checked in by robert, 4 years ago)

Moved setting of TexturePoolSize? into State.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13#include <osg/State>
14#include <osg/Texture>
15#include <osg/Notify>
16#include <osg/GLU>
17#include <osg/GLExtensions>
18#include <osg/ApplicationUsage>
19
20#ifndef GL_MAX_TEXTURE_COORDS
21#define GL_MAX_TEXTURE_COORDS 0x8871
22#endif
23
24#ifndef GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
25#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
26#endif
27
28#ifndef GL_MAX_TEXTURE_UNITS
29#define GL_MAX_TEXTURE_UNITS 0x84E2
30#endif
31
32using namespace std;
33using namespace osg;
34
35static ApplicationUsageProxy State_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_GL_ERROR_CHECKING <type>","ONCE_PER_ATTRIBUTE | ON | on enables fine grained checking,  ONCE_PER_FRAME enables coarse grained checking");
36
37State::State():
38    Referenced(true)
39{
40    _graphicsContext = 0;
41    _contextID = 0;
42    _identity = new osg::RefMatrix(); // default RefMatrix constructs to identity.
43    _initialViewMatrix = _identity;
44    _projection = _identity;
45    _modelView = _identity;
46
47    _abortRenderingPtr = false;   
48
49    _checkGLErrors = ONCE_PER_FRAME;
50
51    const char* str = getenv("OSG_GL_ERROR_CHECKING");
52    if (str && (strcmp(str,"ONCE_PER_ATTRIBUTE")==0 || strcmp(str,"ON")==0 || strcmp(str,"on")==0))
53    {
54        _checkGLErrors = ONCE_PER_ATTRIBUTE;
55    }
56
57    _currentActiveTextureUnit=0;
58    _currentClientActiveTextureUnit=0;
59
60    _currentVBO = 0;
61    _currentEBO = 0;
62    _currentPBO = 0;
63
64    _isSecondaryColorSupportResolved = false;
65    _isSecondaryColorSupported = false;
66
67    _isFogCoordSupportResolved = false;
68    _isFogCoordSupported = false;
69
70    _isVertexBufferObjectSupportResolved = false;
71    _isVertexBufferObjectSupported = false;
72   
73    _lastAppliedProgramObject = 0;
74
75    _extensionProcsInitialized = false;
76    _glClientActiveTexture = 0;
77    _glActiveTexture = 0;
78    _glFogCoordPointer = 0;
79    _glSecondaryColorPointer = 0;
80    _glVertexAttribPointer = 0;
81    _glEnableVertexAttribArray = 0;
82    _glDisableVertexAttribArray = 0;
83    _glDrawArraysInstanced = 0;
84    _glDrawElementsInstanced = 0;
85
86    _dynamicObjectCount  = 0;
87
88    _glMaxTextureCoords = 1;
89    _glMaxTextureUnits = 1;
90
91    _maxTexturePoolSize = 0;
92    _maxVBOPoolSize = 0;
93    _maxFBOPoolSize = 0;
94}
95
96State::~State()
97{
98    for(AppliedProgramObjectSet::iterator itr = _appliedProgramObjectSet.begin();
99        itr != _appliedProgramObjectSet.end();
100        ++itr)
101    {
102        (*itr)->removeObserver(this);
103    }
104}
105
106void State::objectDeleted(void* object)
107{
108    const Program::PerContextProgram* ppcp = reinterpret_cast<const Program::PerContextProgram*>(object);
109    AppliedProgramObjectSet::iterator itr = _appliedProgramObjectSet.find(ppcp);
110    if (itr != _appliedProgramObjectSet.end())
111    {
112        // osg::notify(osg::NOTICE)<<"Removing _appliedProgramObjectSet entry "<<ppcp<<std::endl;
113        _appliedProgramObjectSet.erase(itr);
114    }
115}
116
117void State::reset()
118{
119
120#if 1
121    for(ModeMap::iterator mitr=_modeMap.begin();
122        mitr!=_modeMap.end();
123        ++mitr)
124    {
125        ModeStack& ms = mitr->second;
126        ms.valueVec.clear();
127        ms.last_applied_value = !ms.global_default_value;
128        ms.changed = true;
129    }       
130#else
131    _modeMap.clear();
132#endif
133
134    _modeMap[GL_DEPTH_TEST].global_default_value = true;
135    _modeMap[GL_DEPTH_TEST].changed = true;
136   
137    // go through all active StateAttribute's, setting to change to force update,
138    // the idea is to leave only the global defaults left.
139    for(AttributeMap::iterator aitr=_attributeMap.begin();
140        aitr!=_attributeMap.end();
141        ++aitr)
142    {
143        AttributeStack& as = aitr->second;
144        as.attributeVec.clear();
145        as.last_applied_attribute = NULL;
146        as.changed = true;
147    }
148   
149    // we can do a straight clear, we arn't interested in GL_DEPTH_TEST defaults in texture modes.
150    for(TextureModeMapList::iterator tmmItr=_textureModeMapList.begin();
151        tmmItr!=_textureModeMapList.end();
152        ++tmmItr)
153    {
154        tmmItr->clear();
155    }
156
157    // empty all the texture attributes as per normal attributes, leaving only the global defaults left.
158    for(TextureAttributeMapList::iterator tamItr=_textureAttributeMapList.begin();
159        tamItr!=_textureAttributeMapList.end();
160        ++tamItr)
161    {
162        AttributeMap& attributeMap = *tamItr;
163        // go through all active StateAttribute's, setting to change to force update.
164        for(AttributeMap::iterator aitr=attributeMap.begin();
165            aitr!=attributeMap.end();
166            ++aitr)
167        {
168            AttributeStack& as = aitr->second;
169            as.attributeVec.clear();
170            as.last_applied_attribute = NULL;
171            as.changed = true;
172        }
173    }
174
175    _stateStateStack.clear();
176   
177    _modelView = _identity;
178    _projection = _identity;
179   
180    dirtyAllVertexArrays();
181   
182#if 0
183    // reset active texture unit values and call OpenGL
184    // note, this OpenGL op precludes the use of State::reset() without a
185    // valid graphics context, therefore the new implementation below
186    // is preferred.
187    setActiveTextureUnit(0);
188#else
189    // reset active texture unit values without calling OpenGL
190    _currentActiveTextureUnit = 0;
191    _currentClientActiveTextureUnit = 0;
192#endif
193   
194    _lastAppliedProgramObject = 0;
195
196    for(AppliedProgramObjectSet::iterator apitr=_appliedProgramObjectSet.begin();
197        apitr!=_appliedProgramObjectSet.end();
198        ++apitr)
199    {
200        (*apitr)->resetAppliedUniforms();
201        (*apitr)->removeObserver(this);
202    }
203   
204    _appliedProgramObjectSet.clear();
205   
206   
207    // what about uniforms??? need to clear them too...
208    // go through all active Unfirom's, setting to change to force update,
209    // the idea is to leave only the global defaults left.
210    for(UniformMap::iterator uitr=_uniformMap.begin();
211        uitr!=_uniformMap.end();
212        ++uitr)
213    {
214        UniformStack& us = uitr->second;
215        us.uniformVec.clear();
216    }
217
218}
219
220void State::setInitialViewMatrix(const osg::RefMatrix* matrix)
221{
222    if (matrix) _initialViewMatrix = matrix;
223    else _initialViewMatrix = _identity;
224
225    _initialInverseViewMatrix.invert(*_initialViewMatrix);
226}
227
228void State::setMaxTexturePoolSize(unsigned int size)
229{
230    _maxTexturePoolSize = size;
231    osg::Texture::getTextureObjectManager(getContextID())->setMaxTexturePoolSize(size);
232    osg::notify(osg::NOTICE)<<"_maxTexturePoolSize="<<_maxTexturePoolSize<<std::endl;
233}
234
235void State::setMaxVBOPoolSize(unsigned int size)
236{
237    _maxVBOPoolSize = size;
238    osg::notify(osg::NOTICE)<<"_maxVBOPoolSize="<<_maxVBOPoolSize<<std::endl;
239}
240
241void State::setMaxFBOPoolSize(unsigned int size)
242{
243    _maxFBOPoolSize = size;
244    osg::notify(osg::NOTICE)<<"_maxFBOPoolSize="<<_maxFBOPoolSize<<std::endl;
245}
246
247void State::pushStateSet(const StateSet* dstate)
248{
249
250    _stateStateStack.push_back(dstate);
251    if (dstate)
252    {
253
254        pushModeList(_modeMap,dstate->getModeList());
255
256        // iterator through texture modes.       
257        unsigned int unit;
258        const StateSet::TextureModeList& ds_textureModeList = dstate->getTextureModeList();
259        for(unit=0;unit<ds_textureModeList.size();++unit)
260        {
261            pushModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
262        }
263
264        pushAttributeList(_attributeMap,dstate->getAttributeList());
265
266        // iterator through texture attributes.
267        const StateSet::TextureAttributeList& ds_textureAttributeList = dstate->getTextureAttributeList();
268        for(unit=0;unit<ds_textureAttributeList.size();++unit)
269        {
270            pushAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
271        }
272
273        pushUniformList(_uniformMap,dstate->getUniformList());
274    }
275
276    // osg::notify(osg::NOTICE)<<"State::pushStateSet()"<<_stateStateStack.size()<<std::endl;
277}
278
279void State::popAllStateSets()
280{
281    // osg::notify(osg::NOTICE)<<"State::popAllStateSets()"<<_stateStateStack.size()<<std::endl;
282
283    while (!_stateStateStack.empty()) popStateSet();
284   
285    applyProjectionMatrix(0);
286    applyModelViewMatrix(0);
287   
288    _lastAppliedProgramObject = 0;
289}
290
291void State::popStateSet()
292{
293    // osg::notify(osg::NOTICE)<<"State::popStateSet()"<<_stateStateStack.size()<<std::endl;
294
295    if (_stateStateStack.empty()) return;
296   
297   
298    const StateSet* dstate = _stateStateStack.back();
299
300    if (dstate)
301    {
302
303        popModeList(_modeMap,dstate->getModeList());
304
305        // iterator through texture modes.       
306        unsigned int unit;
307        const StateSet::TextureModeList& ds_textureModeList = dstate->getTextureModeList();
308        for(unit=0;unit<ds_textureModeList.size();++unit)
309        {
310            popModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
311        }
312
313        popAttributeList(_attributeMap,dstate->getAttributeList());
314
315        // iterator through texture attributes.
316        const StateSet::TextureAttributeList& ds_textureAttributeList = dstate->getTextureAttributeList();
317        for(unit=0;unit<ds_textureAttributeList.size();++unit)
318        {
319            popAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
320        }
321
322        popUniformList(_uniformMap,dstate->getUniformList());
323
324    }
325   
326    // remove the top draw state from the stack.
327    _stateStateStack.pop_back();
328}
329
330void State::insertStateSet(unsigned int pos,const StateSet* dstate)
331{
332    StateSetStack tempStack;
333   
334    // first pop the StateSet above the position we need to insert at
335    while (_stateStateStack.size()>pos)
336    {
337        tempStack.push_back(_stateStateStack.back());
338        popStateSet();
339    }
340
341    // push our new stateset
342    pushStateSet(dstate);
343   
344    // push back the original ones
345    for(StateSetStack::reverse_iterator itr = tempStack.rbegin();
346        itr != tempStack.rend();
347        ++itr)
348    {
349        pushStateSet(*itr);
350    }
351
352}
353
354void State::removeStateSet(unsigned int pos)
355{
356    if (pos >= _stateStateStack.size())
357    {
358        osg::notify(osg::NOTICE)<<"Warning: State::removeStateSet("<<pos<<") out of range"<<std::endl;
359        return;
360    }
361   
362    // record the StateSet above the one we intend to remove
363    StateSetStack tempStack;
364    while (_stateStateStack.size()-1>pos)
365    {
366        tempStack.push_back(_stateStateStack.back());
367        popStateSet();
368    }
369
370    // remove the intended StateSet as well   
371    popStateSet();
372
373    // push back the original ones that were above the remove StateSet
374    for(StateSetStack::reverse_iterator itr = tempStack.rbegin();
375        itr != tempStack.rend();
376        ++itr)
377    {
378        pushStateSet(*itr);
379    }
380}
381
382void State::captureCurrentState(StateSet& stateset) const
383{
384    // empty the stateset first.
385    stateset.clear();
386   
387    for(ModeMap::const_iterator mitr=_modeMap.begin();
388        mitr!=_modeMap.end();
389        ++mitr)
390    {
391        // note GLMode = mitr->first
392        const ModeStack& ms = mitr->second;
393        if (!ms.valueVec.empty())
394        {
395            stateset.setMode(mitr->first,ms.valueVec.back());
396        }
397    }       
398
399    for(AttributeMap::const_iterator aitr=_attributeMap.begin();
400        aitr!=_attributeMap.end();
401        ++aitr)
402    {
403        const AttributeStack& as = aitr->second;
404        if (!as.attributeVec.empty())
405        {
406            stateset.setAttribute(const_cast<StateAttribute*>(as.attributeVec.back().first));
407        }
408    }       
409
410}
411
412// revert to using maximum for consistency, maximum should be defined by STLport on VS.
413// // visual studio 6.0 doesn't appear to define maximum?!? So do our own here..
414// template<class T>
415// T mymax(const T& a,const T& b)
416// {
417//     return (((a) > (b)) ? (a) : (b));
418// }
419
420void State::apply(const StateSet* dstate)
421{
422    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply(StateSet*)");
423
424    // equivalent to:
425    //pushStateSet(dstate);
426    //apply();
427    //popStateSet();
428    //return;
429   
430    if (dstate)
431    {
432
433        applyModeList(_modeMap,dstate->getModeList());
434        applyAttributeList(_attributeMap,dstate->getAttributeList());
435
436        const StateSet::TextureModeList& ds_textureModeList = dstate->getTextureModeList();
437        const StateSet::TextureAttributeList& ds_textureAttributeList = dstate->getTextureAttributeList();
438
439        unsigned int unit;
440        unsigned int unitMax = maximum(static_cast<unsigned int>(ds_textureModeList.size()),static_cast<unsigned int>(ds_textureAttributeList.size()));
441        unitMax = maximum(static_cast<unsigned int>(unitMax),static_cast<unsigned int>(_textureModeMapList.size()));
442        unitMax = maximum(static_cast<unsigned int>(unitMax),static_cast<unsigned int>(_textureAttributeMapList.size()));
443        for(unit=0;unit<unitMax;++unit)
444        {
445            if (setActiveTextureUnit(unit))
446            {
447                if (unit<ds_textureModeList.size()) applyModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
448                else if (unit<_textureModeMapList.size()) applyModeMap(_textureModeMapList[unit]);
449               
450                if (unit<ds_textureAttributeList.size()) applyAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
451                else if (unit<_textureAttributeMapList.size()) applyAttributeMap(_textureAttributeMapList[unit]);
452            }
453        }
454       
455#if 1       
456        applyUniformList(_uniformMap,dstate->getUniformList());
457#else               
458        if (_lastAppliedProgramObject)
459        {
460            for(StateSetStack::iterator sitr=_stateStateStack.begin();
461                sitr!=_stateStateStack.end();
462                ++sitr)
463            {
464                const StateSet* stateset = *sitr;
465                const StateSet::UniformList& uniformList = stateset->getUniformList();
466                for(StateSet::UniformList::const_iterator itr=uniformList.begin();
467                    itr!=uniformList.end();
468                    ++itr)
469                {
470                    _lastAppliedProgramObject->apply(*(itr->second.first));
471                }
472            }
473
474            const StateSet::UniformList& uniformList = dstate->getUniformList();
475            for(StateSet::UniformList::const_iterator itr=uniformList.begin();
476                itr!=uniformList.end();
477                ++itr)
478            {
479                _lastAppliedProgramObject->apply(*(itr->second.first));
480            }
481        }
482#endif
483
484    }
485    else
486    {
487        // no incoming stateset, so simply apply state.
488        apply();
489    }
490
491    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply(StateSet*)");
492}
493
494void State::apply()
495{
496
497    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply()");
498
499    // go through all active OpenGL modes, enabling/disable where
500    // appropriate.
501    applyModeMap(_modeMap);
502
503    // go through all active StateAttribute's, applying where appropriate.
504    applyAttributeMap(_attributeMap);
505       
506    unsigned int unit;
507    unsigned int unitMax = maximum(_textureModeMapList.size(),_textureAttributeMapList.size());
508    for(unit=0;unit<unitMax;++unit)
509    {
510        if (setActiveTextureUnit(unit))
511        {
512            if (unit<_textureModeMapList.size()) applyModeMap(_textureModeMapList[unit]);
513            if (unit<_textureAttributeMapList.size()) applyAttributeMap(_textureAttributeMapList[unit]);
514        }
515    }
516
517#if 1       
518    applyUniformMap(_uniformMap);
519#else       
520    if (_lastAppliedProgramObject && !_stateStateStack.empty())
521    {
522        for(StateSetStack::iterator sitr=_stateStateStack.begin();
523            sitr!=_stateStateStack.end();
524            ++sitr)
525        {
526            const StateSet* stateset = *sitr;
527            const StateSet::UniformList& uniformList = stateset->getUniformList();
528            for(StateSet::UniformList::const_iterator itr=uniformList.begin();
529                itr!=uniformList.end();
530                ++itr)
531            {
532                _lastAppliedProgramObject->apply(*(itr->second.first));
533            }
534        }
535    }
536#endif
537
538
539    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply()");
540}
541
542void State::haveAppliedMode(StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
543{
544    haveAppliedMode(_modeMap,mode,value);
545}
546
547void State::haveAppliedMode(StateAttribute::GLMode mode)
548{
549    haveAppliedMode(_modeMap,mode);
550}
551
552void State::haveAppliedAttribute(const StateAttribute* attribute)
553{
554    haveAppliedAttribute(_attributeMap,attribute);
555}
556
557void State::haveAppliedAttribute(StateAttribute::Type type, unsigned int member)
558{
559    haveAppliedAttribute(_attributeMap,type,member);
560}
561
562bool State::getLastAppliedMode(StateAttribute::GLMode mode) const
563{
564    return getLastAppliedMode(_modeMap,mode);
565}
566
567const StateAttribute* State::getLastAppliedAttribute(StateAttribute::Type type, unsigned int member) const
568{
569    return getLastAppliedAttribute(_attributeMap,type,member);
570}
571
572
573void State::haveAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
574{
575    haveAppliedMode(getOrCreateTextureModeMap(unit),mode,value);
576}
577
578void State::haveAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode)
579{
580    haveAppliedMode(getOrCreateTextureModeMap(unit),mode);
581}
582
583void State::haveAppliedTextureAttribute(unsigned int unit,const StateAttribute* attribute)
584{
585    haveAppliedAttribute(getOrCreateTextureAttributeMap(unit),attribute);
586}
587
588void State::haveAppliedTextureAttribute(unsigned int unit,StateAttribute::Type type, unsigned int member)
589{
590    haveAppliedAttribute(getOrCreateTextureAttributeMap(unit),type,member);
591}
592
593bool State::getLastAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode) const
594{
595    if (unit>=_textureModeMapList.size()) return false;
596    return getLastAppliedMode(_textureModeMapList[unit],mode);
597}
598
599const StateAttribute* State::getLastAppliedTextureAttribute(unsigned int unit,StateAttribute::Type type, unsigned int member) const
600{
601    if (unit>=_textureAttributeMapList.size()) return false;
602    return getLastAppliedAttribute(_textureAttributeMapList[unit],type,member);
603}
604
605
606void State::haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
607{
608    ModeStack& ms = modeMap[mode];
609
610    ms.last_applied_value = value & StateAttribute::ON;
611
612    // will need to disable this mode on next apply so set it to changed.
613    ms.changed = true;   
614}
615
616/** mode has been set externally, update state to reflect this setting.*/
617void State::haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode)
618{
619    ModeStack& ms = modeMap[mode];
620
621    // don't know what last applied value is can't apply it.
622    // assume that it has changed by toggle the value of last_applied_value.
623    ms.last_applied_value = !ms.last_applied_value;
624
625    // will need to disable this mode on next apply so set it to changed.
626    ms.changed = true;   
627}
628
629/** attribute has been applied externally, update state to reflect this setting.*/
630void State::haveAppliedAttribute(AttributeMap& attributeMap,const StateAttribute* attribute)
631{
632    if (attribute)
633    {
634        AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
635
636        as.last_applied_attribute = attribute;
637
638        // will need to update this attribute on next apply so set it to changed.
639        as.changed = true;
640    }
641}
642
643void State::haveAppliedAttribute(AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member)
644{
645   
646    AttributeMap::iterator itr = attributeMap.find(StateAttribute::TypeMemberPair(type,member));
647    if (itr!=attributeMap.end())
648    {
649        AttributeStack& as = itr->second;
650        as.last_applied_attribute = 0L;
651
652        // will need to update this attribute on next apply so set it to changed.
653        as.changed = true;
654    }
655}
656
657bool State::getLastAppliedMode(const ModeMap& modeMap,StateAttribute::GLMode mode) const
658{
659    ModeMap::const_iterator itr = modeMap.find(mode);
660    if (itr!=modeMap.end())
661    {
662        const ModeStack& ms = itr->second;
663        return ms.last_applied_value;
664    }
665    else
666    {
667        return false;
668    }
669}
670
671const StateAttribute* State::getLastAppliedAttribute(const AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member) const
672{
673    AttributeMap::const_iterator itr = attributeMap.find(StateAttribute::TypeMemberPair(type,member));
674    if (itr!=attributeMap.end())
675    {
676        const AttributeStack& as = itr->second;
677        return as.last_applied_attribute;
678    }
679    else
680    {
681        return NULL;
682    }
683}
684
685void State::dirtyAllModes()
686{
687    for(ModeMap::iterator mitr=_modeMap.begin();
688        mitr!=_modeMap.end();
689        ++mitr)
690    {
691        ModeStack& ms = mitr->second;
692        ms.last_applied_value = !ms.last_applied_value;
693        ms.changed = true;   
694
695    }       
696
697    for(TextureModeMapList::iterator tmmItr=_textureModeMapList.begin();
698        tmmItr!=_textureModeMapList.end();
699        ++tmmItr)
700    {
701        for(ModeMap::iterator mitr=tmmItr->begin();
702            mitr!=tmmItr->end();
703            ++mitr)
704        {
705            ModeStack& ms = mitr->second;
706            ms.last_applied_value = !ms.last_applied_value;
707            ms.changed = true;   
708
709        }       
710    }
711}
712
713void State::dirtyAllAttributes()
714{
715    for(AttributeMap::iterator aitr=_attributeMap.begin();
716        aitr!=_attributeMap.end();
717        ++aitr)
718    {
719        AttributeStack& as = aitr->second;
720        as.last_applied_attribute = 0;
721        as.changed = true;
722    }
723   
724
725    for(TextureAttributeMapList::iterator tamItr=_textureAttributeMapList.begin();
726        tamItr!=_textureAttributeMapList.end();
727        ++tamItr)
728    {
729        AttributeMap& attributeMap = *tamItr;
730        for(AttributeMap::iterator aitr=attributeMap.begin();
731            aitr!=attributeMap.end();
732            ++aitr)
733        {
734            AttributeStack& as = aitr->second;
735            as.last_applied_attribute = 0;
736            as.changed = true;
737        }
738    }
739
740}
741
742
743Polytope State::getViewFrustum() const
744{
745    Polytope cv;
746    cv.setToUnitFrustum();
747    cv.transformProvidingInverse((*_modelView)*(*_projection));
748    return cv;
749}
750
751
752
753void State::disableAllVertexArrays()
754{
755    disableVertexPointer();
756    disableTexCoordPointersAboveAndIncluding(0);
757    disableVertexAttribPointersAboveAndIncluding(0);
758    disableColorPointer();
759    disableFogCoordPointer();
760    disableIndexPointer();
761    disableNormalPointer();
762    disableSecondaryColorPointer();
763}
764
765void State::dirtyAllVertexArrays()
766{
767    dirtyVertexPointer();
768    dirtyTexCoordPointersAboveAndIncluding(0);
769    dirtyVertexAttribPointersAboveAndIncluding(0);
770    dirtyColorPointer();
771    dirtyFogCoordPointer();
772    dirtyIndexPointer();
773    dirtyNormalPointer();
774    dirtySecondaryColorPointer();
775}
776
777void State::setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer)
778{
779    disableAllVertexArrays();
780
781    glInterleavedArrays( format, stride, pointer);
782
783    // the crude way, assume that all arrays have been effected so dirty them and
784    // disable them...
785    dirtyAllVertexArrays();
786}
787
788void State::initializeExtensionProcs()
789{
790    if (_extensionProcsInitialized) return;
791
792    setGLExtensionFuncPtr(_glClientActiveTexture,"glClientActiveTexture","glClientActiveTextureARB");
793    setGLExtensionFuncPtr(_glActiveTexture, "glActiveTexture","glActiveTextureARB");
794    setGLExtensionFuncPtr(_glFogCoordPointer, "glFogCoordPointer","glFogCoordPointerEXT");
795    setGLExtensionFuncPtr(_glSecondaryColorPointer, "glSecondaryColorPointer","glSecondaryColorPointerEXT");
796    setGLExtensionFuncPtr(_glVertexAttribPointer, "glVertexAttribPointer","glVertexAttribPointerARB");
797    setGLExtensionFuncPtr(_glEnableVertexAttribArray, "glEnableVertexAttribArray","glEnableVertexAttribArrayARB");
798    setGLExtensionFuncPtr(_glDisableVertexAttribArray, "glDisableVertexAttribArray","glDisableVertexAttribArrayARB");
799    setGLExtensionFuncPtr(_glBindBuffer, "glBindBuffer","glBindBufferARB");
800
801    setGLExtensionFuncPtr(_glDrawArraysInstanced, "glDrawArraysInstanced","glDrawArraysInstancedARB","glDrawArraysInstancedEXT");
802    setGLExtensionFuncPtr(_glDrawElementsInstanced, "glDrawElementsInstanced","glDrawElementsInstancedARB","glDrawElementsInstancedEXT");
803
804    if ( osg::getGLVersionNumber() >= 2.0 || osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_shader") )
805    {
806        glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,&_glMaxTextureUnits);
807        glGetIntegerv(GL_MAX_TEXTURE_COORDS,&_glMaxTextureCoords);
808    }
809    else if ( osg::getGLVersionNumber() >= 1.3 ||
810                                 osg::isGLExtensionSupported(_contextID,"GL_ARB_multitexture") ||
811                                 osg::isGLExtensionSupported(_contextID,"GL_EXT_multitexture") )
812    {
813        GLint maxTextureUnits;
814        glGetIntegerv(GL_MAX_TEXTURE_UNITS,&maxTextureUnits);
815        _glMaxTextureUnits = maxTextureUnits;
816        _glMaxTextureCoords = maxTextureUnits;
817    }
818    else
819    {
820        _glMaxTextureUnits = 1;
821        _glMaxTextureCoords = 1;
822    }
823
824    _extensionProcsInitialized = true;
825}
826
827bool State::setClientActiveTextureUnit( unsigned int unit )
828{
829    if (unit!=_currentClientActiveTextureUnit)
830    {
831        if (_glClientActiveTexture && unit < (unsigned int)_glMaxTextureCoords)
832        {
833            _glClientActiveTexture(GL_TEXTURE0+unit);
834            _currentClientActiveTextureUnit = unit;
835        }
836        else
837        {
838            return unit==0;
839        }
840    }
841    return true;
842}
843
844
845/** set the current texture unit, return true if selected, false if selection failed such as when multitexturing is not supported.
846  * note, only updates values that change.*/
847bool State::setActiveTextureUnit( unsigned int unit )
848{
849    if (unit!=_currentActiveTextureUnit)
850    {
851        if (_glActiveTexture && unit < (unsigned int)(maximum(_glMaxTextureCoords,_glMaxTextureUnits)) )
852        {
853            _glActiveTexture(GL_TEXTURE0+unit);
854            _currentActiveTextureUnit = unit;
855        }
856        else
857        {
858            return unit==0;
859        }
860    }
861    return true;
862}
863
864void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
865{
866    if (_glFogCoordPointer)
867    {
868
869        if (!_fogArray._enabled || _fogArray._dirty)
870        {
871            _fogArray._enabled = true;
872            glEnableClientState(GL_FOG_COORDINATE_ARRAY);
873        }
874        //if (_fogArray._pointer!=ptr || _fogArray._dirty)
875        {
876            _fogArray._pointer=ptr;
877            _glFogCoordPointer( type, stride, ptr );
878        }
879        _fogArray._dirty = false;
880    }
881   
882}
883
884void State::setSecondaryColorPointer( GLint size, GLenum type,
885                                      GLsizei stride, const GLvoid *ptr )
886{
887    if (_glSecondaryColorPointer)
888    {
889        if (!_secondaryColorArray._enabled || _secondaryColorArray._dirty)
890        {
891            _secondaryColorArray._enabled = true;
892            glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
893        }
894        //if (_secondaryColorArray._pointer!=ptr || _secondaryColorArray._dirty)
895        {
896            _secondaryColorArray._pointer=ptr;
897            _glSecondaryColorPointer( size, type, stride, ptr );
898        }
899        _secondaryColorArray._dirty = false;
900    }
901}
902
903/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
904* note, only updates values that change.*/
905void State::setVertexAttribPointer( unsigned int index,
906                                      GLint size, GLenum type, GLboolean normalized,
907                                    GLsizei stride, const GLvoid *ptr )
908{
909    if (_glVertexAttribPointer)
910    {
911        if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1);
912        EnabledArrayPair& eap = _vertexAttribArrayList[index];
913
914        if (!eap._enabled || eap._dirty)
915        {
916            eap._enabled = true;
917            _glEnableVertexAttribArray( index );
918        }
919        //if (eap._pointer != ptr || eap._normalized!=normalized || eap._dirty)
920        {
921            _glVertexAttribPointer( index, size, type, normalized, stride, ptr );
922            eap._pointer = ptr;
923            eap._normalized = normalized;
924        }
925        eap._dirty = false;
926    }
927}     
928
929/** wrapper around DisableVertexAttribArrayARB(index);
930* note, only updates values that change.*/
931void State::disableVertexAttribPointer( unsigned int index )
932{
933    if (_glDisableVertexAttribArray)
934    {
935        if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1);
936        EnabledArrayPair& eap = _vertexAttribArrayList[index];
937
938        if (eap._enabled || eap._dirty)
939        {
940            eap._enabled = false;
941            eap._dirty = false;
942            _glDisableVertexAttribArray( index );
943        }
944    }
945}       
946
947void State::disableVertexAttribPointersAboveAndIncluding( unsigned int index )
948{
949    if (_glDisableVertexAttribArray)
950    {
951        while (index<_vertexAttribArrayList.size())
952        {
953            EnabledArrayPair& eap = _vertexAttribArrayList[index];
954            if (eap._enabled || eap._dirty)
955            {
956                eap._enabled = false;
957                eap._dirty = false;
958                _glDisableVertexAttribArray( index );
959            }
960            ++index;
961        }
962    }
963}
964
965bool State::computeSecondaryColorSupported() const
966{
967    _isSecondaryColorSupportResolved = true;
968    _isSecondaryColorSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_secondary_color");
969    return _isSecondaryColorSupported;
970}
971
972bool State::computeFogCoordSupported() const
973{
974    _isFogCoordSupportResolved = true;
975    _isFogCoordSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_fog_coord");
976    return _isFogCoordSupported;
977}
978
979bool State::computeVertexBufferObjectSupported() const
980{
981    _isVertexBufferObjectSupportResolved = true;
982    _isVertexBufferObjectSupported = osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_buffer_object");
983    return _isVertexBufferObjectSupported;
984}
985
986bool State::checkGLErrors(const char* str) const
987{
988    GLenum errorNo = glGetError();
989    if (errorNo!=GL_NO_ERROR)
990    {
991        const char* error = (char*)gluErrorString(errorNo);
992        if (error) osg::notify(WARN)<<"Warning: detected OpenGL error '" << error<<"'";
993        else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x" << std::hex << errorNo << std::dec;
994
995        if (str) osg::notify(WARN)<<" at "<<str<< std::endl;
996        else     osg::notify(WARN)<<" in osg::State."<< std::endl;
997
998        return true;
999    }
1000    return false;
1001}
1002
1003bool State::checkGLErrors(StateAttribute::GLMode mode) const
1004{
1005    GLenum errorNo = glGetError();
1006    if (errorNo!=GL_NO_ERROR)
1007    {
1008        const char* error = (char*)gluErrorString(errorNo);
1009        if (error) osg::notify(WARN)<<"Warning: detected OpenGL error '"<< error <<"' after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
1010        else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
1011
1012        return true;
1013    }
1014    return false;
1015}
1016
1017bool State::checkGLErrors(const StateAttribute* attribute) const
1018{
1019    GLenum errorNo = glGetError();
1020    if (errorNo!=GL_NO_ERROR)
1021    {
1022        const char* error = (char*)gluErrorString(errorNo);
1023        if (error) osg::notify(WARN)<<"Warning: detected OpenGL error '"<< error <<"' after applying attribute "<<attribute->className()<<" "<<attribute<< std::endl;
1024        else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying attribute "<<attribute->className()<<" "<<attribute<< std::dec << std::endl;
1025
1026        return true;
1027    }
1028    return false;
1029}
1030
Note: See TracBrowser for help on using the browser.