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

Revision 9469, 30.1 kB (checked in by robert, 5 years ago)

Added checked from the ARG version of glDraw*Instanced().

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