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

Revision 9553, 30.7 kB (checked in by robert, 6 years ago)

Commented out debug message

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