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

Revision 9469, 30.1 kB (checked in by robert, 4 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
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13#include <osg/State>
14#include <osg/Notify>
15#include <osg/GLU>
16#include <osg/GLExtensions>
17#include <osg/ApplicationUsage>
18
19#ifndef GL_MAX_TEXTURE_COORDS
20#define GL_MAX_TEXTURE_COORDS 0x8871
21#endif
22
23#ifndef GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
24#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
25#endif
26
27#ifndef GL_MAX_TEXTURE_UNITS
28#define GL_MAX_TEXTURE_UNITS 0x84E2
29#endif
30
31using namespace std;
32using namespace osg;
33
34static ApplicationUsageProxy State_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_GL_ERROR_CHECKING <type>","ONCE_PER_ATTRIBUTE | ON | on enables fine grained checking,  ONCE_PER_FRAME enables coarse grained checking");
35
36State::State():
37    Referenced(true)
38{
39    _graphicsContext = 0;
40    _contextID = 0;
41    _identity = new osg::RefMatrix(); // default RefMatrix constructs to identity.
42    _initialViewMatrix = _identity;
43    _projection = _identity;
44    _modelView = _identity;
45
46    _abortRenderingPtr = false;   
47
48    _checkGLErrors = ONCE_PER_FRAME;
49
50    const char* str = getenv("OSG_GL_ERROR_CHECKING");
51    if (str && (strcmp(str,"ONCE_PER_ATTRIBUTE")==0 || strcmp(str,"ON")==0 || strcmp(str,"on")==0))
52    {
53        _checkGLErrors = ONCE_PER_ATTRIBUTE;
54    }
55
56    _currentActiveTextureUnit=0;
57    _currentClientActiveTextureUnit=0;
58
59    _currentVBO = 0;
60    _currentEBO = 0;
61    _currentPBO = 0;
62
63    _isSecondaryColorSupportResolved = false;
64    _isSecondaryColorSupported = false;
65
66    _isFogCoordSupportResolved = false;
67    _isFogCoordSupported = false;
68
69    _isVertexBufferObjectSupportResolved = false;
70    _isVertexBufferObjectSupported = false;
71   
72    _lastAppliedProgramObject = 0;
73
74    _extensionProcsInitialized = false;
75    _glClientActiveTexture = 0;
76    _glActiveTexture = 0;
77    _glFogCoordPointer = 0;
78    _glSecondaryColorPointer = 0;
79    _glVertexAttribPointer = 0;
80    _glEnableVertexAttribArray = 0;
81    _glDisableVertexAttribArray = 0;
82    _glDrawArraysInstanced = 0;
83    _glDrawElementsInstanced = 0;
84
85    _dynamicObjectCount  = 0;
86
87    _glMaxTextureCoords = 1;
88    _glMaxTextureUnits = 1;
89}
90
91State::~State()
92{
93}
94
95void State::reset()
96{
97
98#if 1
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    }       
108#else
109    _modeMap.clear();
110#endif
111
112    _modeMap[GL_DEPTH_TEST].global_default_value = true;
113    _modeMap[GL_DEPTH_TEST].changed = true;
114   
115    // go through all active StateAttribute's, setting to change to force update,
116    // the idea is to leave only the global defaults left.
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;
125    }
126   
127    // we can do a straight clear, we arn't interested in GL_DEPTH_TEST defaults in texture modes.
128    for(TextureModeMapList::iterator tmmItr=_textureModeMapList.begin();
129        tmmItr!=_textureModeMapList.end();
130        ++tmmItr)
131    {
132        tmmItr->clear();
133    }
134
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    }
152
153    _stateStateStack.clear();
154   
155    _modelView = _identity;
156    _projection = _identity;
157   
158    dirtyAllVertexArrays();
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
164    // is preferred.
165    setActiveTextureUnit(0);
166#else
167    // reset active texture unit values without calling OpenGL
168    _currentActiveTextureUnit = 0;
169    _currentClientActiveTextureUnit = 0;
170#endif
171   
172    _lastAppliedProgramObject = 0;
173
174    for(AppliedProgramObjectSet::iterator apitr=_appliedProgramObjectSet.begin();
175        apitr!=_appliedProgramObjectSet.end();
176        ++apitr)
177    {
178        (*apitr)->resetAppliedUniforms();
179    }
180   
181    _appliedProgramObjectSet.clear();
182   
183   
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
195}
196
197void State::setInitialViewMatrix(const osg::RefMatrix* matrix)
198{
199    if (matrix) _initialViewMatrix = matrix;
200    else _initialViewMatrix = _identity;
201
202    _initialInverseViewMatrix.invert(*_initialViewMatrix);
203}
204
205void State::pushStateSet(const StateSet* dstate)
206{
207
208    _stateStateStack.push_back(dstate);
209    if (dstate)
210    {
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)
218        {
219            pushModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
220        }
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)
227        {
228            pushAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
229        }
230
231        pushUniformList(_uniformMap,dstate->getUniformList());
232    }
233
234    // osg::notify(osg::NOTICE)<<"State::pushStateSet()"<<_stateStateStack.size()<<std::endl;
235}
236
237void State::popAllStateSets()
238{
239    // osg::notify(osg::NOTICE)<<"State::popAllStateSets()"<<_stateStateStack.size()<<std::endl;
240
241    while (!_stateStateStack.empty()) popStateSet();
242   
243    applyProjectionMatrix(0);
244    applyModelViewMatrix(0);
245   
246    _lastAppliedProgramObject = 0;
247}
248
249void State::popStateSet()
250{
251    // osg::notify(osg::NOTICE)<<"State::popStateSet()"<<_stateStateStack.size()<<std::endl;
252
253    if (_stateStateStack.empty()) return;
254   
255   
256    const StateSet* dstate = _stateStateStack.back();
257
258    if (dstate)
259    {
260
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)
267        {
268            popModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
269        }
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)
276        {
277            popAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
278        }
279
280        popUniformList(_uniformMap,dstate->getUniformList());
281
282    }
283   
284    // remove the top draw state from the stack.
285    _stateStateStack.pop_back();
286}
287
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
340void State::captureCurrentState(StateSet& stateset) const
341{
342    // empty the stateset first.
343    stateset.clear();
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
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
368}
369
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..
372// template<class T>
373// T mymax(const T& a,const T& b)
374// {
375//     return (((a) > (b)) ? (a) : (b));
376// }
377
378void State::apply(const StateSet* dstate)
379{
380    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply(StateSet*)");
381
382    // equivalent to:
383    //pushStateSet(dstate);
384    //apply();
385    //popStateSet();
386    //return;
387   
388    if (dstate)
389    {
390
391        applyModeList(_modeMap,dstate->getModeList());
392        applyAttributeList(_attributeMap,dstate->getAttributeList());
393
394        const StateSet::TextureModeList& ds_textureModeList = dstate->getTextureModeList();
395        const StateSet::TextureAttributeList& ds_textureAttributeList = dstate->getTextureAttributeList();
396
397        unsigned int unit;
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()));
401        for(unit=0;unit<unitMax;++unit)
402        {
403            if (setActiveTextureUnit(unit))
404            {
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]);
410            }
411        }
412       
413#if 1       
414        applyUniformList(_uniformMap,dstate->getUniformList());
415#else               
416        if (_lastAppliedProgramObject)
417        {
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
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            }
439        }
440#endif
441
442    }
443    else
444    {
445        // no incoming stateset, so simply apply state.
446        apply();
447    }
448
449    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply(StateSet*)");
450}
451
452void State::apply()
453{
454
455    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply()");
456
457    // go through all active OpenGL modes, enabling/disable where
458    // appropriate.
459    applyModeMap(_modeMap);
460
461    // go through all active StateAttribute's, applying where appropriate.
462    applyAttributeMap(_attributeMap);
463       
464    unsigned int unit;
465    unsigned int unitMax = maximum(_textureModeMapList.size(),_textureAttributeMapList.size());
466    for(unit=0;unit<unitMax;++unit)
467    {
468        if (setActiveTextureUnit(unit))
469        {
470            if (unit<_textureModeMapList.size()) applyModeMap(_textureModeMapList[unit]);
471            if (unit<_textureAttributeMapList.size()) applyAttributeMap(_textureAttributeMapList[unit]);
472        }
473    }
474
475#if 1       
476    applyUniformMap(_uniformMap);
477#else       
478    if (_lastAppliedProgramObject && !_stateStateStack.empty())
479    {
480        for(StateSetStack::iterator sitr=_stateStateStack.begin();
481            sitr!=_stateStateStack.end();
482            ++sitr)
483        {
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            }
492        }
493    }
494#endif
495
496
497    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply()");
498}
499
500void State::haveAppliedMode(StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
501{
502    haveAppliedMode(_modeMap,mode,value);
503}
504
505void State::haveAppliedMode(StateAttribute::GLMode mode)
506{
507    haveAppliedMode(_modeMap,mode);
508}
509
510void State::haveAppliedAttribute(const StateAttribute* attribute)
511{
512    haveAppliedAttribute(_attributeMap,attribute);
513}
514
515void State::haveAppliedAttribute(StateAttribute::Type type, unsigned int member)
516{
517    haveAppliedAttribute(_attributeMap,type,member);
518}
519
520bool State::getLastAppliedMode(StateAttribute::GLMode mode) const
521{
522    return getLastAppliedMode(_modeMap,mode);
523}
524
525const StateAttribute* State::getLastAppliedAttribute(StateAttribute::Type type, unsigned int member) const
526{
527    return getLastAppliedAttribute(_attributeMap,type,member);
528}
529
530
531void State::haveAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
532{
533    haveAppliedMode(getOrCreateTextureModeMap(unit),mode,value);
534}
535
536void State::haveAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode)
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
546void State::haveAppliedTextureAttribute(unsigned int unit,StateAttribute::Type type, unsigned int member)
547{
548    haveAppliedAttribute(getOrCreateTextureAttributeMap(unit),type,member);
549}
550
551bool State::getLastAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode) const
552{
553    if (unit>=_textureModeMapList.size()) return false;
554    return getLastAppliedMode(_textureModeMapList[unit],mode);
555}
556
557const StateAttribute* State::getLastAppliedTextureAttribute(unsigned int unit,StateAttribute::Type type, unsigned int member) const
558{
559    if (unit>=_textureAttributeMapList.size()) return false;
560    return getLastAppliedAttribute(_textureAttributeMapList[unit],type,member);
561}
562
563
564void State::haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
565{
566    ModeStack& ms = modeMap[mode];
567
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
574/** mode has been set externally, update state to reflect this setting.*/
575void State::haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode)
576{
577    ModeStack& ms = modeMap[mode];
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
587/** attribute has been applied externally, update state to reflect this setting.*/
588void State::haveAppliedAttribute(AttributeMap& attributeMap,const StateAttribute* attribute)
589{
590    if (attribute)
591    {
592        AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
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
601void State::haveAppliedAttribute(AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member)
602{
603   
604    AttributeMap::iterator itr = attributeMap.find(StateAttribute::TypeMemberPair(type,member));
605    if (itr!=attributeMap.end())
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}
614
615bool State::getLastAppliedMode(const ModeMap& modeMap,StateAttribute::GLMode mode) const
616{
617    ModeMap::const_iterator itr = modeMap.find(mode);
618    if (itr!=modeMap.end())
619    {
620        const ModeStack& ms = itr->second;
621        return ms.last_applied_value;
622    }
623    else
624    {
625        return false;
626    }
627}
628
629const StateAttribute* State::getLastAppliedAttribute(const AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member) const
630{
631    AttributeMap::const_iterator itr = attributeMap.find(StateAttribute::TypeMemberPair(type,member));
632    if (itr!=attributeMap.end())
633    {
634        const AttributeStack& as = itr->second;
635        return as.last_applied_attribute;
636    }
637    else
638    {
639        return NULL;
640    }
641}
642
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
701Polytope State::getViewFrustum() const
702{
703    Polytope cv;
704    cv.setToUnitFrustum();
705    cv.transformProvidingInverse((*_modelView)*(*_projection));
706    return cv;
707}
708
709
710
711void State::disableAllVertexArrays()
712{
713    disableVertexPointer();
714    disableTexCoordPointersAboveAndIncluding(0);
715    disableVertexAttribPointersAboveAndIncluding(0);
716    disableColorPointer();
717    disableFogCoordPointer();
718    disableIndexPointer();
719    disableNormalPointer();
720    disableSecondaryColorPointer();
721}
722
723void State::dirtyAllVertexArrays()
724{
725    dirtyVertexPointer();
726    dirtyTexCoordPointersAboveAndIncluding(0);
727    dirtyVertexAttribPointersAboveAndIncluding(0);
728    dirtyColorPointer();
729    dirtyFogCoordPointer();
730    dirtyIndexPointer();
731    dirtyNormalPointer();
732    dirtySecondaryColorPointer();
733}
734
735void State::setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer)
736{
737    disableAllVertexArrays();
738
739    glInterleavedArrays( format, stride, pointer);
740
741    // the crude way, assume that all arrays have been effected so dirty them and
742    // disable them...
743    dirtyAllVertexArrays();
744}
745
746void State::initializeExtensionProcs()
747{
748    if (_extensionProcsInitialized) return;
749
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");
758
759    setGLExtensionFuncPtr(_glDrawArraysInstanced, "glDrawArraysInstanced","glDrawArraysInstancedARB","glDrawArraysInstancedEXT");
760    setGLExtensionFuncPtr(_glDrawElementsInstanced, "glDrawElementsInstanced","glDrawElementsInstancedARB","glDrawElementsInstancedEXT");
761
762    if ( osg::getGLVersionNumber() >= 2.0 || osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_shader") )
763    {
764        glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,&_glMaxTextureUnits);
765        glGetIntegerv(GL_MAX_TEXTURE_COORDS,&_glMaxTextureCoords);
766    }
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    }
776    else
777    {
778        _glMaxTextureUnits = 1;
779        _glMaxTextureCoords = 1;
780    }
781
782    _extensionProcsInitialized = true;
783}
784
785bool State::setClientActiveTextureUnit( unsigned int unit )
786{
787    if (unit!=_currentClientActiveTextureUnit)
788    {
789        if (_glClientActiveTexture && unit < (unsigned int)_glMaxTextureCoords)
790        {
791            _glClientActiveTexture(GL_TEXTURE0+unit);
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    {
809        if (_glActiveTexture && unit < (unsigned int)(maximum(_glMaxTextureCoords,_glMaxTextureUnits)) )
810        {
811            _glActiveTexture(GL_TEXTURE0+unit);
812            _currentActiveTextureUnit = unit;
813        }
814        else
815        {
816            return unit==0;
817        }
818    }
819    return true;
820}
821
822void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
823{
824    if (_glFogCoordPointer)
825    {
826
827        if (!_fogArray._enabled || _fogArray._dirty)
828        {
829            _fogArray._enabled = true;
830            glEnableClientState(GL_FOG_COORDINATE_ARRAY);
831        }
832        //if (_fogArray._pointer!=ptr || _fogArray._dirty)
833        {
834            _fogArray._pointer=ptr;
835            _glFogCoordPointer( type, stride, ptr );
836        }
837        _fogArray._dirty = false;
838    }
839   
840}
841
842void State::setSecondaryColorPointer( GLint size, GLenum type,
843                                      GLsizei stride, const GLvoid *ptr )
844{
845    if (_glSecondaryColorPointer)
846    {
847        if (!_secondaryColorArray._enabled || _secondaryColorArray._dirty)
848        {
849            _secondaryColorArray._enabled = true;
850            glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
851        }
852        //if (_secondaryColorArray._pointer!=ptr || _secondaryColorArray._dirty)
853        {
854            _secondaryColorArray._pointer=ptr;
855            _glSecondaryColorPointer( size, type, stride, ptr );
856        }
857        _secondaryColorArray._dirty = false;
858    }
859}
860
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{
867    if (_glVertexAttribPointer)
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;
875            _glEnableVertexAttribArray( index );
876        }
877        //if (eap._pointer != ptr || eap._normalized!=normalized || eap._dirty)
878        {
879            _glVertexAttribPointer( index, size, type, normalized, stride, ptr );
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{
891    if (_glDisableVertexAttribArray)
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;
900            _glDisableVertexAttribArray( index );
901        }
902    }
903}       
904
905void State::disableVertexAttribPointersAboveAndIncluding( unsigned int index )
906{
907    if (_glDisableVertexAttribArray)
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;
916                _glDisableVertexAttribArray( index );
917            }
918            ++index;
919        }
920    }
921}
922
923bool State::computeSecondaryColorSupported() const
924{
925    _isSecondaryColorSupportResolved = true;
926    _isSecondaryColorSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_secondary_color");
927    return _isSecondaryColorSupported;
928}
929
930bool State::computeFogCoordSupported() const
931{
932    _isFogCoordSupportResolved = true;
933    _isFogCoordSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_fog_coord");
934    return _isFogCoordSupported;
935}
936
937bool State::computeVertexBufferObjectSupported() const
938{
939    _isVertexBufferObjectSupportResolved = true;
940    _isVertexBufferObjectSupported = osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_buffer_object");
941    return _isVertexBufferObjectSupported;
942}
943
944bool State::checkGLErrors(const char* str) const
945{
946    GLenum errorNo = glGetError();
947    if (errorNo!=GL_NO_ERROR)
948    {
949        const char* error = (char*)gluErrorString(errorNo);
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;
952
953        if (str) osg::notify(WARN)<<" at "<<str<< std::endl;
954        else     osg::notify(WARN)<<" in osg::State."<< std::endl;
955
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    {
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;
968        else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
969
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    {
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;
982        else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying attribute "<<attribute->className()<<" "<<attribute<< std::endl;
983
984        return true;
985    }
986    return false;
987}
988
Note: See TracBrowser for help on using the browser.