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

Revision 10614, 32.0 kB (checked in by robert, 5 years ago)

Quitened down debug messages

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