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

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

Moved setting of TexturePoolSize? into State.

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