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

Revision 10601, 31.4 kB (checked in by robert, 5 years ago)

Introduced new GLBufferObject pool for managing the memory footprint taken up by VertexBufferObejct?, ElementBufferObject? and PixelBufferObject?.

  • 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>
[10590]14#include <osg/Texture>
[10]15#include <osg/Notify>
[45]16#include <osg/GLU>
[1944]17#include <osg/GLExtensions>
[8135]18#include <osg/ApplicationUsage>
[10]19
[6671]20#ifndef GL_MAX_TEXTURE_COORDS
21#define GL_MAX_TEXTURE_COORDS 0x8871
22#endif
[1944]23
[6671]24#ifndef GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
25#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
26#endif
27
[7796]28#ifndef GL_MAX_TEXTURE_UNITS
29#define GL_MAX_TEXTURE_UNITS 0x84E2
30#endif
31
[1983]32using namespace std;
[10]33using namespace osg;
34
[8135]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
[7257]37State::State():
38    Referenced(true)
[10]39{
[4400]40    _graphicsContext = 0;
[10]41    _contextID = 0;
[1463]42    _identity = new osg::RefMatrix(); // default RefMatrix constructs to identity.
[2073]43    _initialViewMatrix = _identity;
[950]44    _projection = _identity;
[489]45    _modelView = _identity;
[1677]46
47    _abortRenderingPtr = false;   
[6250]48
[4127]49    _checkGLErrors = ONCE_PER_FRAME;
[950]50
[8135]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
[950]57    _currentActiveTextureUnit=0;
58    _currentClientActiveTextureUnit=0;
[1313]59
[6578]60    _currentVBO = 0;
61    _currentEBO = 0;
62    _currentPBO = 0;
63
[2000]64    _isSecondaryColorSupportResolved = false;
65    _isSecondaryColorSupported = false;
[1313]66
67    _isFogCoordSupportResolved = false;
68    _isFogCoordSupported = false;
[2000]69
70    _isVertexBufferObjectSupportResolved = false;
71    _isVertexBufferObjectSupported = false;
[4027]72   
73    _lastAppliedProgramObject = 0;
[5380]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;
[9447]83    _glDrawArraysInstanced = 0;
84    _glDrawElementsInstanced = 0;
[6069]85
86    _dynamicObjectCount  = 0;
[7917]87
88    _glMaxTextureCoords = 1;
89    _glMaxTextureUnits = 1;
[10588]90
91    _maxTexturePoolSize = 0;
[10601]92    _maxBufferObjectPoolSize = 0;
[10]93}
94
95State::~State()
96{
[9549]97    for(AppliedProgramObjectSet::iterator itr = _appliedProgramObjectSet.begin();
98        itr != _appliedProgramObjectSet.end();
99        ++itr)
100    {
101        (*itr)->removeObserver(this);
102    }
[10]103}
104
[9549]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    {
[9553]111        // osg::notify(osg::NOTICE)<<"Removing _appliedProgramObjectSet entry "<<ppcp<<std::endl;
[9549]112        _appliedProgramObjectSet.erase(itr);
113    }
114}
115
[10]116void State::reset()
117{
[4149]118
[5001]119#if 1
[97]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    }       
[5001]129#else
130    _modeMap.clear();
131#endif
[97]132
133    _modeMap[GL_DEPTH_TEST].global_default_value = true;
[609]134    _modeMap[GL_DEPTH_TEST].changed = true;
135   
[836]136    // go through all active StateAttribute's, setting to change to force update,
137    // the idea is to leave only the global defaults left.
[97]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;
[836]146    }
147   
[7648]148    // we can do a straight clear, we arn't interested in GL_DEPTH_TEST defaults in texture modes.
[836]149    for(TextureModeMapList::iterator tmmItr=_textureModeMapList.begin();
150        tmmItr!=_textureModeMapList.end();
151        ++tmmItr)
152    {
153        tmmItr->clear();
154    }
[97]155
[836]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    }
[97]173
[4027]174    _stateStateStack.clear();
[489]175   
176    _modelView = _identity;
177    _projection = _identity;
[1178]178   
179    dirtyAllVertexArrays();
[5736]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
[7648]185    // is preferred.
[1184]186    setActiveTextureUnit(0);
[5736]187#else
188    // reset active texture unit values without calling OpenGL
189    _currentActiveTextureUnit = 0;
190    _currentClientActiveTextureUnit = 0;
191#endif
[4027]192   
193    _lastAppliedProgramObject = 0;
[4149]194
195    for(AppliedProgramObjectSet::iterator apitr=_appliedProgramObjectSet.begin();
196        apitr!=_appliedProgramObjectSet.end();
197        ++apitr)
198    {
[4163]199        (*apitr)->resetAppliedUniforms();
[9798]200        (*apitr)->removeObserver(this);
[4149]201    }
[4027]202   
[4149]203    _appliedProgramObjectSet.clear();
204   
205   
[4027]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
[10]217}
218
[2176]219void State::setInitialViewMatrix(const osg::RefMatrix* matrix)
220{
221    if (matrix) _initialViewMatrix = matrix;
222    else _initialViewMatrix = _identity;
223
224    _initialInverseViewMatrix.invert(*_initialViewMatrix);
225}
226
[10588]227void State::setMaxTexturePoolSize(unsigned int size)
228{
229    _maxTexturePoolSize = size;
[10590]230    osg::Texture::getTextureObjectManager(getContextID())->setMaxTexturePoolSize(size);
[10588]231    osg::notify(osg::NOTICE)<<"_maxTexturePoolSize="<<_maxTexturePoolSize<<std::endl;
232}
233
[10601]234void State::setMaxBufferObjectPoolSize(unsigned int size)
[10588]235{
[10601]236    _maxBufferObjectPoolSize = size;
237    osg::GLBufferObjectManager::getGLBufferObjectManager(getContextID())->setMaxGLBufferObjectPoolSize(_maxBufferObjectPoolSize);
238    osg::notify(osg::NOTICE)<<"_maxBufferObjectPoolSize="<<_maxBufferObjectPoolSize<<std::endl;
[10588]239}
240
[10]241void State::pushStateSet(const StateSet* dstate)
242{
[6504]243
[4027]244    _stateStateStack.push_back(dstate);
[10]245    if (dstate)
246    {
[836]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)
[319]254        {
[836]255            pushModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
[319]256        }
[836]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)
[10]263        {
[836]264            pushAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
[10]265        }
266
[4180]267        pushUniformList(_uniformMap,dstate->getUniformList());
[319]268    }
[6504]269
270    // osg::notify(osg::NOTICE)<<"State::pushStateSet()"<<_stateStateStack.size()<<std::endl;
[319]271}
272
[2259]273void State::popAllStateSets()
274{
[6504]275    // osg::notify(osg::NOTICE)<<"State::popAllStateSets()"<<_stateStateStack.size()<<std::endl;
276
[4027]277    while (!_stateStateStack.empty()) popStateSet();
[2262]278   
279    applyProjectionMatrix(0);
280    applyModelViewMatrix(0);
[4200]281   
282    _lastAppliedProgramObject = 0;
[2259]283}
284
[319]285void State::popStateSet()
286{
[6504]287    // osg::notify(osg::NOTICE)<<"State::popStateSet()"<<_stateStateStack.size()<<std::endl;
288
[4027]289    if (_stateStateStack.empty()) return;
[319]290   
[6504]291   
[4027]292    const StateSet* dstate = _stateStateStack.back();
[319]293
294    if (dstate)
295    {
296
[836]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)
[10]303        {
[836]304            popModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
[10]305        }
[836]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)
[10]312        {
[836]313            popAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
[10]314        }
[4180]315
316        popUniformList(_uniformMap,dstate->getUniformList());
317
[10]318    }
319   
320    // remove the top draw state from the stack.
[4027]321    _stateStateStack.pop_back();
[10]322}
323
[6504]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
[121]376void State::captureCurrentState(StateSet& stateset) const
377{
378    // empty the stateset first.
[3480]379    stateset.clear();
[121]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
[319]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
[121]404}
405
[1623]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..
[1620]408// template<class T>
409// T mymax(const T& a,const T& b)
410// {
[1940]411//     return (((a) > (b)) ? (a) : (b));
[1620]412// }
[121]413
[10]414void State::apply(const StateSet* dstate)
415{
[4127]416    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply(StateSet*)");
[1529]417
[7648]418    // equivalent to:
[10]419    //pushStateSet(dstate);
420    //apply();
421    //popStateSet();
[1676]422    //return;
423   
[10]424    if (dstate)
425    {
426
[836]427        applyModeList(_modeMap,dstate->getModeList());
428        applyAttributeList(_attributeMap,dstate->getAttributeList());
[10]429
[836]430        const StateSet::TextureModeList& ds_textureModeList = dstate->getTextureModeList();
431        const StateSet::TextureAttributeList& ds_textureAttributeList = dstate->getTextureAttributeList();
[10]432
[836]433        unsigned int unit;
[1623]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()));
[836]437        for(unit=0;unit<unitMax;++unit)
[10]438        {
[836]439            if (setActiveTextureUnit(unit))
[10]440            {
[836]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]);
[10]446            }
447        }
[4027]448       
[4180]449#if 1       
450        applyUniformList(_uniformMap,dstate->getUniformList());
451#else               
[4027]452        if (_lastAppliedProgramObject)
453        {
[4029]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
[4028]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            }
[4027]475        }
[4180]476#endif
477
[10]478    }
479    else
480    {
[7648]481        // no incoming stateset, so simply apply state.
[10]482        apply();
483    }
484
[4127]485    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply(StateSet*)");
[10]486}
487
488void State::apply()
489{
490
[4127]491    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply()");
[1529]492
[10]493    // go through all active OpenGL modes, enabling/disable where
494    // appropriate.
[836]495    applyModeMap(_modeMap);
[10]496
[319]497    // go through all active StateAttribute's, applying where appropriate.
[836]498    applyAttributeMap(_attributeMap);
499       
500    unsigned int unit;
[1623]501    unsigned int unitMax = maximum(_textureModeMapList.size(),_textureAttributeMapList.size());
[836]502    for(unit=0;unit<unitMax;++unit)
[319]503    {
[836]504        if (setActiveTextureUnit(unit))
[319]505        {
[836]506            if (unit<_textureModeMapList.size()) applyModeMap(_textureModeMapList[unit]);
507            if (unit<_textureAttributeMapList.size()) applyAttributeMap(_textureAttributeMapList[unit]);
[319]508        }
[836]509    }
[1903]510
[4180]511#if 1       
512    applyUniformMap(_uniformMap);
513#else       
[4028]514    if (_lastAppliedProgramObject && !_stateStateStack.empty())
[4027]515    {
[4029]516        for(StateSetStack::iterator sitr=_stateStateStack.begin();
517            sitr!=_stateStateStack.end();
518            ++sitr)
[4028]519        {
[4029]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            }
[4028]528        }
[4027]529    }
[4180]530#endif
[4027]531
[4180]532
[4127]533    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply()");
[10]534}
535
[1133]536void State::haveAppliedMode(StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
[10]537{
[836]538    haveAppliedMode(_modeMap,mode,value);
539}
[10]540
[1133]541void State::haveAppliedMode(StateAttribute::GLMode mode)
[836]542{
543    haveAppliedMode(_modeMap,mode);
544}
545
546void State::haveAppliedAttribute(const StateAttribute* attribute)
547{
548    haveAppliedAttribute(_attributeMap,attribute);
549}
550
[3488]551void State::haveAppliedAttribute(StateAttribute::Type type, unsigned int member)
[836]552{
[3488]553    haveAppliedAttribute(_attributeMap,type,member);
[836]554}
555
[1133]556bool State::getLastAppliedMode(StateAttribute::GLMode mode) const
[836]557{
558    return getLastAppliedMode(_modeMap,mode);
559}
560
[3488]561const StateAttribute* State::getLastAppliedAttribute(StateAttribute::Type type, unsigned int member) const
[836]562{
[3488]563    return getLastAppliedAttribute(_attributeMap,type,member);
[836]564}
565
566
[1133]567void State::haveAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
[836]568{
569    haveAppliedMode(getOrCreateTextureModeMap(unit),mode,value);
570}
571
[1133]572void State::haveAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode)
[836]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
[3488]582void State::haveAppliedTextureAttribute(unsigned int unit,StateAttribute::Type type, unsigned int member)
[836]583{
[3488]584    haveAppliedAttribute(getOrCreateTextureAttributeMap(unit),type,member);
[836]585}
586
[1133]587bool State::getLastAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode) const
[836]588{
589    if (unit>=_textureModeMapList.size()) return false;
590    return getLastAppliedMode(_textureModeMapList[unit],mode);
591}
592
[3488]593const StateAttribute* State::getLastAppliedTextureAttribute(unsigned int unit,StateAttribute::Type type, unsigned int member) const
[836]594{
595    if (unit>=_textureAttributeMapList.size()) return false;
[3488]596    return getLastAppliedAttribute(_textureAttributeMapList[unit],type,member);
[836]597}
598
599
[1133]600void State::haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
[836]601{
602    ModeStack& ms = modeMap[mode];
603
[10]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
[464]610/** mode has been set externally, update state to reflect this setting.*/
[1133]611void State::haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode)
[464]612{
[836]613    ModeStack& ms = modeMap[mode];
[464]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
[10]623/** attribute has been applied externally, update state to reflect this setting.*/
[836]624void State::haveAppliedAttribute(AttributeMap& attributeMap,const StateAttribute* attribute)
[10]625{
626    if (attribute)
627    {
[3488]628        AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
[10]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
[3488]637void State::haveAppliedAttribute(AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member)
[464]638{
639   
[3488]640    AttributeMap::iterator itr = attributeMap.find(StateAttribute::TypeMemberPair(type,member));
[836]641    if (itr!=attributeMap.end())
[464]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}
[493]650
[1133]651bool State::getLastAppliedMode(const ModeMap& modeMap,StateAttribute::GLMode mode) const
[698]652{
[836]653    ModeMap::const_iterator itr = modeMap.find(mode);
654    if (itr!=modeMap.end())
[698]655    {
656        const ModeStack& ms = itr->second;
657        return ms.last_applied_value;
658    }
659    else
660    {
661        return false;
662    }
663}
664
[3488]665const StateAttribute* State::getLastAppliedAttribute(const AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member) const
[698]666{
[3488]667    AttributeMap::const_iterator itr = attributeMap.find(StateAttribute::TypeMemberPair(type,member));
[836]668    if (itr!=attributeMap.end())
[698]669    {
670        const AttributeStack& as = itr->second;
671        return as.last_applied_attribute;
672    }
673    else
674    {
675        return NULL;
676    }
677}
678
[1508]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
[724]737Polytope State::getViewFrustum() const
[493]738{
[724]739    Polytope cv;
[493]740    cv.setToUnitFrustum();
741    cv.transformProvidingInverse((*_modelView)*(*_projection));
742    return cv;
743}
[861]744
[1508]745
746
[1152]747void State::disableAllVertexArrays()
748{
749    disableVertexPointer();
750    disableTexCoordPointersAboveAndIncluding(0);
[1940]751    disableVertexAttribPointersAboveAndIncluding(0);
[1152]752    disableColorPointer();
753    disableFogCoordPointer();
754    disableIndexPointer();
755    disableNormalPointer();
756    disableSecondaryColorPointer();
757}
758
759void State::dirtyAllVertexArrays()
760{
761    dirtyVertexPointer();
762    dirtyTexCoordPointersAboveAndIncluding(0);
[1940]763    dirtyVertexAttribPointersAboveAndIncluding(0);
[1152]764    dirtyColorPointer();
765    dirtyFogCoordPointer();
766    dirtyIndexPointer();
767    dirtyNormalPointer();
768    dirtySecondaryColorPointer();
769}
770
[1655]771void State::setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer)
[1320]772{
[1659]773    disableAllVertexArrays();
774
[1320]775    glInterleavedArrays( format, stride, pointer);
[1659]776
[1320]777    // the crude way, assume that all arrays have been effected so dirty them and
778    // disable them...
779    dirtyAllVertexArrays();
780}
781
[5380]782void State::initializeExtensionProcs()
783{
784    if (_extensionProcsInitialized) return;
[1320]785
[9380]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");
[861]794
[9469]795    setGLExtensionFuncPtr(_glDrawArraysInstanced, "glDrawArraysInstanced","glDrawArraysInstancedARB","glDrawArraysInstancedEXT");
796    setGLExtensionFuncPtr(_glDrawElementsInstanced, "glDrawElementsInstanced","glDrawElementsInstancedARB","glDrawElementsInstancedEXT");
[9447]797
[7796]798    if ( osg::getGLVersionNumber() >= 2.0 || osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_shader") )
[7661]799    {
[7796]800        glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,&_glMaxTextureUnits);
801        glGetIntegerv(GL_MAX_TEXTURE_COORDS,&_glMaxTextureCoords);
[7661]802    }
[7796]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    }
[7661]812    else
813    {
[7796]814        _glMaxTextureUnits = 1;
815        _glMaxTextureCoords = 1;
[7661]816    }
817
[5380]818    _extensionProcsInitialized = true;
819}
820
[861]821bool State::setClientActiveTextureUnit( unsigned int unit )
822{
823    if (unit!=_currentClientActiveTextureUnit)
824    {
[6671]825        if (_glClientActiveTexture && unit < (unsigned int)_glMaxTextureCoords)
[861]826        {
[5380]827            _glClientActiveTexture(GL_TEXTURE0+unit);
[861]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    {
[7796]845        if (_glActiveTexture && unit < (unsigned int)(maximum(_glMaxTextureCoords,_glMaxTextureUnits)) )
[861]846        {
[5380]847            _glActiveTexture(GL_TEXTURE0+unit);
[861]848            _currentActiveTextureUnit = unit;
849        }
850        else
851        {
852            return unit==0;
853        }
854    }
855    return true;
856}
[1045]857
858void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
859{
[5380]860    if (_glFogCoordPointer)
[1045]861    {
862
[1152]863        if (!_fogArray._enabled || _fogArray._dirty)
[1045]864        {
865            _fogArray._enabled = true;
866            glEnableClientState(GL_FOG_COORDINATE_ARRAY);
867        }
[2000]868        //if (_fogArray._pointer!=ptr || _fogArray._dirty)
[1045]869        {
870            _fogArray._pointer=ptr;
[5380]871            _glFogCoordPointer( type, stride, ptr );
[1045]872        }
[1152]873        _fogArray._dirty = false;
[1045]874    }
875   
876}
877
878void State::setSecondaryColorPointer( GLint size, GLenum type,
879                                      GLsizei stride, const GLvoid *ptr )
880{
[5380]881    if (_glSecondaryColorPointer)
[1045]882    {
[1152]883        if (!_secondaryColorArray._enabled || _secondaryColorArray._dirty)
[1045]884        {
885            _secondaryColorArray._enabled = true;
886            glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
887        }
[2000]888        //if (_secondaryColorArray._pointer!=ptr || _secondaryColorArray._dirty)
[1045]889        {
890            _secondaryColorArray._pointer=ptr;
[5380]891            _glSecondaryColorPointer( size, type, stride, ptr );
[1045]892        }
[1152]893        _secondaryColorArray._dirty = false;
[1045]894    }
895}
[1313]896
[1944]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{
[5380]903    if (_glVertexAttribPointer)
[1944]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;
[5380]911            _glEnableVertexAttribArray( index );
[1944]912        }
[2000]913        //if (eap._pointer != ptr || eap._normalized!=normalized || eap._dirty)
[1944]914        {
[5380]915            _glVertexAttribPointer( index, size, type, normalized, stride, ptr );
[1944]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{
[5380]927    if (_glDisableVertexAttribArray)
[1944]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;
[5380]936            _glDisableVertexAttribArray( index );
[1944]937        }
938    }
939}       
940
941void State::disableVertexAttribPointersAboveAndIncluding( unsigned int index )
942{
[5380]943    if (_glDisableVertexAttribArray)
[1944]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;
[5380]952                _glDisableVertexAttribArray( index );
[1944]953            }
954            ++index;
955        }
956    }
957}
958
[1313]959bool State::computeSecondaryColorSupported() const
960{
[2000]961    _isSecondaryColorSupportResolved = true;
[4102]962    _isSecondaryColorSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_secondary_color");
[2000]963    return _isSecondaryColorSupported;
[1313]964}
965
966bool State::computeFogCoordSupported() const
967{
968    _isFogCoordSupportResolved = true;
[4102]969    _isFogCoordSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_fog_coord");
[1313]970    return _isFogCoordSupported;
971}
[1529]972
[2000]973bool State::computeVertexBufferObjectSupported() const
974{
975    _isVertexBufferObjectSupportResolved = true;
[4102]976    _isVertexBufferObjectSupported = osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_buffer_object");
[2000]977    return _isVertexBufferObjectSupported;
978}
979
[1529]980bool State::checkGLErrors(const char* str) const
981{
982    GLenum errorNo = glGetError();
983    if (errorNo!=GL_NO_ERROR)
984    {
[4644]985        const char* error = (char*)gluErrorString(errorNo);
[4650]986        if (error) osg::notify(WARN)<<"Warning: detected OpenGL error '" << error<<"'";
[9682]987        else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x" << std::hex << errorNo << std::dec;
[4644]988
[4650]989        if (str) osg::notify(WARN)<<" at "<<str<< std::endl;
990        else     osg::notify(WARN)<<" in osg::State."<< std::endl;
[4644]991
[1529]992        return true;
993    }
994    return false;
995}
996
997bool State::checkGLErrors(StateAttribute::GLMode mode) const
998{
999    GLenum errorNo = glGetError();
1000    if (errorNo!=GL_NO_ERROR)
1001    {
[4644]1002        const char* error = (char*)gluErrorString(errorNo);
1003        if (error) osg::notify(WARN)<<"Warning: detected OpenGL error '"<< error <<"' after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
[4650]1004        else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
[4644]1005
[1529]1006        return true;
1007    }
1008    return false;
1009}
1010
1011bool State::checkGLErrors(const StateAttribute* attribute) const
1012{
1013    GLenum errorNo = glGetError();
1014    if (errorNo!=GL_NO_ERROR)
1015    {
[4644]1016        const char* error = (char*)gluErrorString(errorNo);
1017        if (error) osg::notify(WARN)<<"Warning: detected OpenGL error '"<< error <<"' after applying attribute "<<attribute->className()<<" "<<attribute<< std::endl;
[9682]1018        else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying attribute "<<attribute->className()<<" "<<attribute<< std::dec << std::endl;
[4644]1019
[1529]1020        return true;
1021    }
1022    return false;
1023}
1024
Note: See TracBrowser for help on using the browser.