root/OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osg/State.cpp @ 11208

Revision 11208, 30.8 kB (checked in by paulmartz, 4 years ago)

Merge 10664 to 2.8 branch (MSFBO workaround for OS X).

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