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

Revision 10743, 47.4 kB (checked in by robert, 5 years ago)

Introduced new State::drawQuads(..) convinience method to help out with mapping GL 1.x style calls to GLES2.0 compatible calls.

  • 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/Texture>
15#include <osg/Notify>
16#include <osg/GLU>
17#include <osg/GLExtensions>
18#include <osg/ApplicationUsage>
19
20#include <sstream>
21
22#ifndef GL_MAX_TEXTURE_COORDS
23#define GL_MAX_TEXTURE_COORDS 0x8871
24#endif
25
26#ifndef GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
27#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
28#endif
29
30#ifndef GL_MAX_TEXTURE_UNITS
31#define GL_MAX_TEXTURE_UNITS 0x84E2
32#endif
33
34using namespace std;
35using namespace osg;
36
37static 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");
38
39State::State():
40    Referenced(true)
41{
42    _graphicsContext = 0;
43    _contextID = 0;
44    _identity = new osg::RefMatrix(); // default RefMatrix constructs to identity.
45    _initialViewMatrix = _identity;
46    _projection = _identity;
47    _modelView = _identity;
48
49    #if defined(OSG_GLES2_AVAILABLE) || defined(OSG_GL3_AVAILABLE)   
50        _useModelViewAndProjectionUniforms = true;
51        _useVertexAttributeAliasing = true;
52    #else   
53        _useModelViewAndProjectionUniforms = false;
54        _useVertexAttributeAliasing = false;
55    #endif
56   
57    _modelViewMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ModelViewMatrix");
58    _projectionMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ProjectionMatrix");
59    _modelViewProjectionMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ModelViewProjectionMatrix");
60    _normalMatrixUniform = new Uniform(Uniform::FLOAT_MAT3,"osg_NormalMatrix");
61
62    bool compactAliasing = true;
63    if (compactAliasing)
64    {
65        setUpVertexAttribAlias(_vertexAlias,0, "gl_Vertex","osg_Vertex","attribute vec4 ");
66        setUpVertexAttribAlias(_normalAlias, 1, "gl_Normal","osg_Normal","attribute vec3 ");
67        setUpVertexAttribAlias(_colorAlias, 2, "gl_Color","osg_Color","attribute vec4 ");
68
69        _texCoordAliasList.resize(5);
70        for(unsigned int i=0; i<_texCoordAliasList.size(); i++)
71        {
72            std::stringstream gl_MultiTexCoord;
73            std::stringstream osg_MultiTexCoord;
74            gl_MultiTexCoord<<"gl_MultiTexCoord"<<i;
75            osg_MultiTexCoord<<"osg_MultiTexCoord"<<i;
76
77            setUpVertexAttribAlias(_texCoordAliasList[i], 3+i, gl_MultiTexCoord.str(), osg_MultiTexCoord.str(), "attribute vec4 ");
78        }
79
80        setUpVertexAttribAlias(_secondaryColorAlias, 6, "gl_SecondaryColor","osg_SecondaryColor","attribute vec4 ");
81        setUpVertexAttribAlias(_fogCoordAlias, 7, "gl_FogCoord","osg_FogCoord","attribute float ");
82
83    }
84    else
85    {
86        setUpVertexAttribAlias(_vertexAlias,0, "gl_Vertex","osg_Vertex","attribute vec4 ");
87        setUpVertexAttribAlias(_normalAlias, 2, "gl_Normal","osg_Normal","attribute vec3 ");
88        setUpVertexAttribAlias(_colorAlias, 3, "gl_Color","osg_Color","attribute vec4 ");
89        setUpVertexAttribAlias(_secondaryColorAlias, 4, "gl_SecondaryColor","osg_SecondaryColor","attribute vec4 ");
90        setUpVertexAttribAlias(_fogCoordAlias, 5, "gl_FogCoord","osg_FogCoord","attribute float ");
91
92        _texCoordAliasList.resize(8);
93        for(unsigned int i=0; i<_texCoordAliasList.size(); i++)
94        {
95            std::stringstream gl_MultiTexCoord;
96            std::stringstream osg_MultiTexCoord;
97            gl_MultiTexCoord<<"gl_MultiTexCoord"<<i;
98            osg_MultiTexCoord<<"osg_MultiTexCoord"<<i;
99
100            setUpVertexAttribAlias(_texCoordAliasList[i], 8+i, gl_MultiTexCoord.str(), osg_MultiTexCoord.str(), "attribute vec4 ");
101        }
102    }
103
104    _abortRenderingPtr = false;   
105
106    _checkGLErrors = ONCE_PER_FRAME;
107
108    const char* str = getenv("OSG_GL_ERROR_CHECKING");
109    if (str && (strcmp(str,"ONCE_PER_ATTRIBUTE")==0 || strcmp(str,"ON")==0 || strcmp(str,"on")==0))
110    {
111        _checkGLErrors = ONCE_PER_ATTRIBUTE;
112    }
113
114    _currentActiveTextureUnit=0;
115    _currentClientActiveTextureUnit=0;
116
117    _currentVBO = 0;
118    _currentEBO = 0;
119    _currentPBO = 0;
120
121    _isSecondaryColorSupportResolved = false;
122    _isSecondaryColorSupported = false;
123
124    _isFogCoordSupportResolved = false;
125    _isFogCoordSupported = false;
126
127    _isVertexBufferObjectSupportResolved = false;
128    _isVertexBufferObjectSupported = false;
129   
130    _lastAppliedProgramObject = 0;
131
132    _extensionProcsInitialized = false;
133    _glClientActiveTexture = 0;
134    _glActiveTexture = 0;
135    _glFogCoordPointer = 0;
136    _glSecondaryColorPointer = 0;
137    _glVertexAttribPointer = 0;
138    _glEnableVertexAttribArray = 0;
139    _glDisableVertexAttribArray = 0;
140    _glDrawArraysInstanced = 0;
141    _glDrawElementsInstanced = 0;
142
143    _dynamicObjectCount  = 0;
144
145    _glMaxTextureCoords = 1;
146    _glMaxTextureUnits = 1;
147
148    _maxTexturePoolSize = 0;
149    _maxBufferObjectPoolSize = 0;
150
151    _glBeginEndAdapter.setState(this);
152    _arrayDispatchers.setState(this);
153}
154
155State::~State()
156{
157    //_texCoordArrayList.clear();
158
159    //_vertexAttribArrayList.clear();
160
161    // osg::notify(osg::NOTICE)<<"State::~State()"<<this<<std::endl;
162    for(AppliedProgramObjectSet::iterator itr = _appliedProgramObjectSet.begin();
163        itr != _appliedProgramObjectSet.end();
164        ++itr)
165    {
166        (*itr)->removeObserver(this);
167    }
168}
169
170void State::objectDeleted(void* object)
171{
172    const Program::PerContextProgram* ppcp = reinterpret_cast<const Program::PerContextProgram*>(object);
173    AppliedProgramObjectSet::iterator itr = _appliedProgramObjectSet.find(ppcp);
174    if (itr != _appliedProgramObjectSet.end())
175    {
176        // osg::notify(osg::NOTICE)<<"Removing _appliedProgramObjectSet entry "<<ppcp<<std::endl;
177        _appliedProgramObjectSet.erase(itr);
178    }
179}
180
181void State::reset()
182{
183
184#if 1
185    for(ModeMap::iterator mitr=_modeMap.begin();
186        mitr!=_modeMap.end();
187        ++mitr)
188    {
189        ModeStack& ms = mitr->second;
190        ms.valueVec.clear();
191        ms.last_applied_value = !ms.global_default_value;
192        ms.changed = true;
193    }       
194#else
195    _modeMap.clear();
196#endif
197
198    _modeMap[GL_DEPTH_TEST].global_default_value = true;
199    _modeMap[GL_DEPTH_TEST].changed = true;
200   
201    // go through all active StateAttribute's, setting to change to force update,
202    // the idea is to leave only the global defaults left.
203    for(AttributeMap::iterator aitr=_attributeMap.begin();
204        aitr!=_attributeMap.end();
205        ++aitr)
206    {
207        AttributeStack& as = aitr->second;
208        as.attributeVec.clear();
209        as.last_applied_attribute = NULL;
210        as.changed = true;
211    }
212   
213    // we can do a straight clear, we arn't interested in GL_DEPTH_TEST defaults in texture modes.
214    for(TextureModeMapList::iterator tmmItr=_textureModeMapList.begin();
215        tmmItr!=_textureModeMapList.end();
216        ++tmmItr)
217    {
218        tmmItr->clear();
219    }
220
221    // empty all the texture attributes as per normal attributes, leaving only the global defaults left.
222    for(TextureAttributeMapList::iterator tamItr=_textureAttributeMapList.begin();
223        tamItr!=_textureAttributeMapList.end();
224        ++tamItr)
225    {
226        AttributeMap& attributeMap = *tamItr;
227        // go through all active StateAttribute's, setting to change to force update.
228        for(AttributeMap::iterator aitr=attributeMap.begin();
229            aitr!=attributeMap.end();
230            ++aitr)
231        {
232            AttributeStack& as = aitr->second;
233            as.attributeVec.clear();
234            as.last_applied_attribute = NULL;
235            as.changed = true;
236        }
237    }
238
239    _stateStateStack.clear();
240   
241    _modelView = _identity;
242    _projection = _identity;
243   
244    dirtyAllVertexArrays();
245   
246#if 0
247    // reset active texture unit values and call OpenGL
248    // note, this OpenGL op precludes the use of State::reset() without a
249    // valid graphics context, therefore the new implementation below
250    // is preferred.
251    setActiveTextureUnit(0);
252#else
253    // reset active texture unit values without calling OpenGL
254    _currentActiveTextureUnit = 0;
255    _currentClientActiveTextureUnit = 0;
256#endif
257   
258    _lastAppliedProgramObject = 0;
259
260    for(AppliedProgramObjectSet::iterator apitr=_appliedProgramObjectSet.begin();
261        apitr!=_appliedProgramObjectSet.end();
262        ++apitr)
263    {
264        (*apitr)->resetAppliedUniforms();
265        (*apitr)->removeObserver(this);
266    }
267   
268    _appliedProgramObjectSet.clear();
269   
270   
271    // what about uniforms??? need to clear them too...
272    // go through all active Unfirom's, setting to change to force update,
273    // the idea is to leave only the global defaults left.
274    for(UniformMap::iterator uitr=_uniformMap.begin();
275        uitr!=_uniformMap.end();
276        ++uitr)
277    {
278        UniformStack& us = uitr->second;
279        us.uniformVec.clear();
280    }
281
282}
283
284void State::setInitialViewMatrix(const osg::RefMatrix* matrix)
285{
286    if (matrix) _initialViewMatrix = matrix;
287    else _initialViewMatrix = _identity;
288
289    _initialInverseViewMatrix.invert(*_initialViewMatrix);
290}
291
292void State::setMaxTexturePoolSize(unsigned int size)
293{
294    _maxTexturePoolSize = size;
295    osg::Texture::getTextureObjectManager(getContextID())->setMaxTexturePoolSize(size);
296    osg::notify(osg::INFO)<<"osg::State::_maxTexturePoolSize="<<_maxTexturePoolSize<<std::endl;
297}
298
299void State::setMaxBufferObjectPoolSize(unsigned int size)
300{
301    _maxBufferObjectPoolSize = size;
302    osg::GLBufferObjectManager::getGLBufferObjectManager(getContextID())->setMaxGLBufferObjectPoolSize(_maxBufferObjectPoolSize);
303    osg::notify(osg::INFO)<<"osg::State::_maxBufferObjectPoolSize="<<_maxBufferObjectPoolSize<<std::endl;
304}
305
306void State::pushStateSet(const StateSet* dstate)
307{
308
309    _stateStateStack.push_back(dstate);
310    if (dstate)
311    {
312
313        pushModeList(_modeMap,dstate->getModeList());
314
315        // iterator through texture modes.       
316        unsigned int unit;
317        const StateSet::TextureModeList& ds_textureModeList = dstate->getTextureModeList();
318        for(unit=0;unit<ds_textureModeList.size();++unit)
319        {
320            pushModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
321        }
322
323        pushAttributeList(_attributeMap,dstate->getAttributeList());
324
325        // iterator through texture attributes.
326        const StateSet::TextureAttributeList& ds_textureAttributeList = dstate->getTextureAttributeList();
327        for(unit=0;unit<ds_textureAttributeList.size();++unit)
328        {
329            pushAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
330        }
331
332        pushUniformList(_uniformMap,dstate->getUniformList());
333    }
334
335    // osg::notify(osg::NOTICE)<<"State::pushStateSet()"<<_stateStateStack.size()<<std::endl;
336}
337
338void State::popAllStateSets()
339{
340    // osg::notify(osg::NOTICE)<<"State::popAllStateSets()"<<_stateStateStack.size()<<std::endl;
341
342    while (!_stateStateStack.empty()) popStateSet();
343   
344    applyProjectionMatrix(0);
345    applyModelViewMatrix(0);
346   
347    _lastAppliedProgramObject = 0;
348}
349
350void State::popStateSet()
351{
352    // osg::notify(osg::NOTICE)<<"State::popStateSet()"<<_stateStateStack.size()<<std::endl;
353
354    if (_stateStateStack.empty()) return;
355   
356   
357    const StateSet* dstate = _stateStateStack.back();
358
359    if (dstate)
360    {
361
362        popModeList(_modeMap,dstate->getModeList());
363
364        // iterator through texture modes.       
365        unsigned int unit;
366        const StateSet::TextureModeList& ds_textureModeList = dstate->getTextureModeList();
367        for(unit=0;unit<ds_textureModeList.size();++unit)
368        {
369            popModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
370        }
371
372        popAttributeList(_attributeMap,dstate->getAttributeList());
373
374        // iterator through texture attributes.
375        const StateSet::TextureAttributeList& ds_textureAttributeList = dstate->getTextureAttributeList();
376        for(unit=0;unit<ds_textureAttributeList.size();++unit)
377        {
378            popAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
379        }
380
381        popUniformList(_uniformMap,dstate->getUniformList());
382
383    }
384   
385    // remove the top draw state from the stack.
386    _stateStateStack.pop_back();
387}
388
389void State::insertStateSet(unsigned int pos,const StateSet* dstate)
390{
391    StateSetStack tempStack;
392   
393    // first pop the StateSet above the position we need to insert at
394    while (_stateStateStack.size()>pos)
395    {
396        tempStack.push_back(_stateStateStack.back());
397        popStateSet();
398    }
399
400    // push our new stateset
401    pushStateSet(dstate);
402   
403    // push back the original ones
404    for(StateSetStack::reverse_iterator itr = tempStack.rbegin();
405        itr != tempStack.rend();
406        ++itr)
407    {
408        pushStateSet(*itr);
409    }
410
411}
412
413void State::removeStateSet(unsigned int pos)
414{
415    if (pos >= _stateStateStack.size())
416    {
417        osg::notify(osg::NOTICE)<<"Warning: State::removeStateSet("<<pos<<") out of range"<<std::endl;
418        return;
419    }
420   
421    // record the StateSet above the one we intend to remove
422    StateSetStack tempStack;
423    while (_stateStateStack.size()-1>pos)
424    {
425        tempStack.push_back(_stateStateStack.back());
426        popStateSet();
427    }
428
429    // remove the intended StateSet as well   
430    popStateSet();
431
432    // push back the original ones that were above the remove StateSet
433    for(StateSetStack::reverse_iterator itr = tempStack.rbegin();
434        itr != tempStack.rend();
435        ++itr)
436    {
437        pushStateSet(*itr);
438    }
439}
440
441void State::captureCurrentState(StateSet& stateset) const
442{
443    // empty the stateset first.
444    stateset.clear();
445   
446    for(ModeMap::const_iterator mitr=_modeMap.begin();
447        mitr!=_modeMap.end();
448        ++mitr)
449    {
450        // note GLMode = mitr->first
451        const ModeStack& ms = mitr->second;
452        if (!ms.valueVec.empty())
453        {
454            stateset.setMode(mitr->first,ms.valueVec.back());
455        }
456    }       
457
458    for(AttributeMap::const_iterator aitr=_attributeMap.begin();
459        aitr!=_attributeMap.end();
460        ++aitr)
461    {
462        const AttributeStack& as = aitr->second;
463        if (!as.attributeVec.empty())
464        {
465            stateset.setAttribute(const_cast<StateAttribute*>(as.attributeVec.back().first));
466        }
467    }       
468
469}
470
471// revert to using maximum for consistency, maximum should be defined by STLport on VS.
472// // visual studio 6.0 doesn't appear to define maximum?!? So do our own here..
473// template<class T>
474// T mymax(const T& a,const T& b)
475// {
476//     return (((a) > (b)) ? (a) : (b));
477// }
478
479void State::apply(const StateSet* dstate)
480{
481    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply(StateSet*)");
482
483    // equivalent to:
484    //pushStateSet(dstate);
485    //apply();
486    //popStateSet();
487    //return;
488
489    if (dstate)
490    {
491
492        applyModeList(_modeMap,dstate->getModeList());
493        applyAttributeList(_attributeMap,dstate->getAttributeList());
494
495        const StateSet::TextureModeList& ds_textureModeList = dstate->getTextureModeList();
496        const StateSet::TextureAttributeList& ds_textureAttributeList = dstate->getTextureAttributeList();
497
498        unsigned int unit;
499        unsigned int unitMax = maximum(static_cast<unsigned int>(ds_textureModeList.size()),static_cast<unsigned int>(ds_textureAttributeList.size()));
500        unitMax = maximum(static_cast<unsigned int>(unitMax),static_cast<unsigned int>(_textureModeMapList.size()));
501        unitMax = maximum(static_cast<unsigned int>(unitMax),static_cast<unsigned int>(_textureAttributeMapList.size()));
502        for(unit=0;unit<unitMax;++unit)
503        {
504            if (setActiveTextureUnit(unit))
505            {
506                if (unit<ds_textureModeList.size()) applyModeList(getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
507                else if (unit<_textureModeMapList.size()) applyModeMap(_textureModeMapList[unit]);
508
509                if (unit<ds_textureAttributeList.size()) applyAttributeList(getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
510                else if (unit<_textureAttributeMapList.size()) applyAttributeMap(_textureAttributeMapList[unit]);
511            }
512        }
513
514        applyUniformList(_uniformMap,dstate->getUniformList());
515    }
516    else
517    {
518        // no incoming stateset, so simply apply state.
519        apply();
520    }
521
522    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply(StateSet*)");
523}
524
525void State::apply()
526{
527
528    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::apply()");
529
530    // go through all active OpenGL modes, enabling/disable where
531    // appropriate.
532    applyModeMap(_modeMap);
533
534    // go through all active StateAttribute's, applying where appropriate.
535    applyAttributeMap(_attributeMap);
536       
537    unsigned int unit;
538    unsigned int unitMax = maximum(_textureModeMapList.size(),_textureAttributeMapList.size());
539    for(unit=0;unit<unitMax;++unit)
540    {
541        if (setActiveTextureUnit(unit))
542        {
543            if (unit<_textureModeMapList.size()) applyModeMap(_textureModeMapList[unit]);
544            if (unit<_textureAttributeMapList.size()) applyAttributeMap(_textureAttributeMapList[unit]);
545        }
546    }
547
548    applyUniformMap(_uniformMap);
549
550    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply()");
551}
552
553void State::haveAppliedMode(StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
554{
555    haveAppliedMode(_modeMap,mode,value);
556}
557
558void State::haveAppliedMode(StateAttribute::GLMode mode)
559{
560    haveAppliedMode(_modeMap,mode);
561}
562
563void State::haveAppliedAttribute(const StateAttribute* attribute)
564{
565    haveAppliedAttribute(_attributeMap,attribute);
566}
567
568void State::haveAppliedAttribute(StateAttribute::Type type, unsigned int member)
569{
570    haveAppliedAttribute(_attributeMap,type,member);
571}
572
573bool State::getLastAppliedMode(StateAttribute::GLMode mode) const
574{
575    return getLastAppliedMode(_modeMap,mode);
576}
577
578const StateAttribute* State::getLastAppliedAttribute(StateAttribute::Type type, unsigned int member) const
579{
580    return getLastAppliedAttribute(_attributeMap,type,member);
581}
582
583
584void State::haveAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
585{
586    haveAppliedMode(getOrCreateTextureModeMap(unit),mode,value);
587}
588
589void State::haveAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode)
590{
591    haveAppliedMode(getOrCreateTextureModeMap(unit),mode);
592}
593
594void State::haveAppliedTextureAttribute(unsigned int unit,const StateAttribute* attribute)
595{
596    haveAppliedAttribute(getOrCreateTextureAttributeMap(unit),attribute);
597}
598
599void State::haveAppliedTextureAttribute(unsigned int unit,StateAttribute::Type type, unsigned int member)
600{
601    haveAppliedAttribute(getOrCreateTextureAttributeMap(unit),type,member);
602}
603
604bool State::getLastAppliedTextureMode(unsigned int unit,StateAttribute::GLMode mode) const
605{
606    if (unit>=_textureModeMapList.size()) return false;
607    return getLastAppliedMode(_textureModeMapList[unit],mode);
608}
609
610const StateAttribute* State::getLastAppliedTextureAttribute(unsigned int unit,StateAttribute::Type type, unsigned int member) const
611{
612    if (unit>=_textureAttributeMapList.size()) return false;
613    return getLastAppliedAttribute(_textureAttributeMapList[unit],type,member);
614}
615
616
617void State::haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode,StateAttribute::GLModeValue value)
618{
619    ModeStack& ms = modeMap[mode];
620
621    ms.last_applied_value = value & StateAttribute::ON;
622
623    // will need to disable this mode on next apply so set it to changed.
624    ms.changed = true;   
625}
626
627/** mode has been set externally, update state to reflect this setting.*/
628void State::haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode)
629{
630    ModeStack& ms = modeMap[mode];
631
632    // don't know what last applied value is can't apply it.
633    // assume that it has changed by toggle the value of last_applied_value.
634    ms.last_applied_value = !ms.last_applied_value;
635
636    // will need to disable this mode on next apply so set it to changed.
637    ms.changed = true;   
638}
639
640/** attribute has been applied externally, update state to reflect this setting.*/
641void State::haveAppliedAttribute(AttributeMap& attributeMap,const StateAttribute* attribute)
642{
643    if (attribute)
644    {
645        AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
646
647        as.last_applied_attribute = attribute;
648
649        // will need to update this attribute on next apply so set it to changed.
650        as.changed = true;
651    }
652}
653
654void State::haveAppliedAttribute(AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member)
655{
656   
657    AttributeMap::iterator itr = attributeMap.find(StateAttribute::TypeMemberPair(type,member));
658    if (itr!=attributeMap.end())
659    {
660        AttributeStack& as = itr->second;
661        as.last_applied_attribute = 0L;
662
663        // will need to update this attribute on next apply so set it to changed.
664        as.changed = true;
665    }
666}
667
668bool State::getLastAppliedMode(const ModeMap& modeMap,StateAttribute::GLMode mode) const
669{
670    ModeMap::const_iterator itr = modeMap.find(mode);
671    if (itr!=modeMap.end())
672    {
673        const ModeStack& ms = itr->second;
674        return ms.last_applied_value;
675    }
676    else
677    {
678        return false;
679    }
680}
681
682const StateAttribute* State::getLastAppliedAttribute(const AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member) const
683{
684    AttributeMap::const_iterator itr = attributeMap.find(StateAttribute::TypeMemberPair(type,member));
685    if (itr!=attributeMap.end())
686    {
687        const AttributeStack& as = itr->second;
688        return as.last_applied_attribute;
689    }
690    else
691    {
692        return NULL;
693    }
694}
695
696void State::dirtyAllModes()
697{
698    for(ModeMap::iterator mitr=_modeMap.begin();
699        mitr!=_modeMap.end();
700        ++mitr)
701    {
702        ModeStack& ms = mitr->second;
703        ms.last_applied_value = !ms.last_applied_value;
704        ms.changed = true;   
705
706    }       
707
708    for(TextureModeMapList::iterator tmmItr=_textureModeMapList.begin();
709        tmmItr!=_textureModeMapList.end();
710        ++tmmItr)
711    {
712        for(ModeMap::iterator mitr=tmmItr->begin();
713            mitr!=tmmItr->end();
714            ++mitr)
715        {
716            ModeStack& ms = mitr->second;
717            ms.last_applied_value = !ms.last_applied_value;
718            ms.changed = true;   
719
720        }       
721    }
722}
723
724void State::dirtyAllAttributes()
725{
726    for(AttributeMap::iterator aitr=_attributeMap.begin();
727        aitr!=_attributeMap.end();
728        ++aitr)
729    {
730        AttributeStack& as = aitr->second;
731        as.last_applied_attribute = 0;
732        as.changed = true;
733    }
734   
735
736    for(TextureAttributeMapList::iterator tamItr=_textureAttributeMapList.begin();
737        tamItr!=_textureAttributeMapList.end();
738        ++tamItr)
739    {
740        AttributeMap& attributeMap = *tamItr;
741        for(AttributeMap::iterator aitr=attributeMap.begin();
742            aitr!=attributeMap.end();
743            ++aitr)
744        {
745            AttributeStack& as = aitr->second;
746            as.last_applied_attribute = 0;
747            as.changed = true;
748        }
749    }
750
751}
752
753
754Polytope State::getViewFrustum() const
755{
756    Polytope cv;
757    cv.setToUnitFrustum();
758    cv.transformProvidingInverse((*_modelView)*(*_projection));
759    return cv;
760}
761
762
763
764void State::disableAllVertexArrays()
765{
766    disableVertexPointer();
767    disableTexCoordPointersAboveAndIncluding(0);
768    disableVertexAttribPointersAboveAndIncluding(0);
769    disableColorPointer();
770    disableFogCoordPointer();
771    disableNormalPointer();
772    disableSecondaryColorPointer();
773}
774
775void State::dirtyAllVertexArrays()
776{
777    dirtyVertexPointer();
778    dirtyTexCoordPointersAboveAndIncluding(0);
779    dirtyVertexAttribPointersAboveAndIncluding(0);
780    dirtyColorPointer();
781    dirtyFogCoordPointer();
782    dirtyNormalPointer();
783    dirtySecondaryColorPointer();
784}
785
786void State::setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer)
787{
788    disableAllVertexArrays();
789
790#if defined(OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE) && !defined(OSG_GLES1_AVAILABLE)
791    glInterleavedArrays( format, stride, pointer);
792#else
793    osg::notify(osg::NOTICE)<<"Warning: State::setInterleavedArrays(..) not implemented."<<std::endl;   
794#endif
795
796    // the crude way, assume that all arrays have been effected so dirty them and
797    // disable them...
798    dirtyAllVertexArrays();
799}
800
801void State::initializeExtensionProcs()
802{
803    if (_extensionProcsInitialized) return;
804
805    setGLExtensionFuncPtr(_glClientActiveTexture,"glClientActiveTexture","glClientActiveTextureARB");
806    setGLExtensionFuncPtr(_glActiveTexture, "glActiveTexture","glActiveTextureARB");
807    setGLExtensionFuncPtr(_glFogCoordPointer, "glFogCoordPointer","glFogCoordPointerEXT");
808    setGLExtensionFuncPtr(_glSecondaryColorPointer, "glSecondaryColorPointer","glSecondaryColorPointerEXT");
809    setGLExtensionFuncPtr(_glVertexAttribPointer, "glVertexAttribPointer","glVertexAttribPointerARB");
810    setGLExtensionFuncPtr(_glEnableVertexAttribArray, "glEnableVertexAttribArray","glEnableVertexAttribArrayARB");
811    setGLExtensionFuncPtr(_glMultiTexCoord4f, "glMultiTexCoord4f","glMultiTexCoord4fARB");
812    setGLExtensionFuncPtr(_glVertexAttrib4f, "glVertexAttrib4f");
813    setGLExtensionFuncPtr(_glVertexAttrib4fv, "glVertexAttrib4fv");
814    setGLExtensionFuncPtr(_glDisableVertexAttribArray, "glDisableVertexAttribArray","glDisableVertexAttribArrayARB");
815    setGLExtensionFuncPtr(_glBindBuffer, "glBindBuffer","glBindBufferARB");
816
817    setGLExtensionFuncPtr(_glDrawArraysInstanced, "glDrawArraysInstanced","glDrawArraysInstancedARB","glDrawArraysInstancedEXT");
818    setGLExtensionFuncPtr(_glDrawElementsInstanced, "glDrawElementsInstanced","glDrawElementsInstancedARB","glDrawElementsInstancedEXT");
819
820    if ( osg::getGLVersionNumber() >= 2.0 || osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_shader") )
821    {
822        glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,&_glMaxTextureUnits);
823        glGetIntegerv(GL_MAX_TEXTURE_COORDS,&_glMaxTextureCoords);
824    }
825    else if ( osg::getGLVersionNumber() >= 1.3 ||
826                                 osg::isGLExtensionSupported(_contextID,"GL_ARB_multitexture") ||
827                                 osg::isGLExtensionSupported(_contextID,"GL_EXT_multitexture") )
828    {
829        GLint maxTextureUnits;
830        glGetIntegerv(GL_MAX_TEXTURE_UNITS,&maxTextureUnits);
831        _glMaxTextureUnits = maxTextureUnits;
832        _glMaxTextureCoords = maxTextureUnits;
833    }
834    else
835    {
836        _glMaxTextureUnits = 1;
837        _glMaxTextureCoords = 1;
838    }
839
840    _extensionProcsInitialized = true;
841}
842
843bool State::setClientActiveTextureUnit( unsigned int unit )
844{
845    if (unit!=_currentClientActiveTextureUnit)
846    {
847        if (_glClientActiveTexture && unit < (unsigned int)_glMaxTextureCoords)
848        {
849            _glClientActiveTexture(GL_TEXTURE0+unit);
850            _currentClientActiveTextureUnit = unit;
851        }
852        else
853        {
854            return unit==0;
855        }
856    }
857    return true;
858}
859
860
861/** set the current texture unit, return true if selected, false if selection failed such as when multitexturing is not supported.
862  * note, only updates values that change.*/
863bool State::setActiveTextureUnit( unsigned int unit )
864{
865    if (unit!=_currentActiveTextureUnit)
866    {
867        if (_glActiveTexture && unit < (unsigned int)(maximum(_glMaxTextureCoords,_glMaxTextureUnits)) )
868        {
869            _glActiveTexture(GL_TEXTURE0+unit);
870            _currentActiveTextureUnit = unit;
871        }
872        else
873        {
874            return unit==0;
875        }
876    }
877    return true;
878}
879
880void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
881{
882#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
883    if (_useVertexAttributeAliasing)
884    {
885        setVertexAttribPointer(_fogCoordAlias._location, 1, type, GL_FALSE, stride, ptr);
886    }
887    else
888    {
889        if (_glFogCoordPointer)
890        {
891
892            if (!_fogArray._enabled || _fogArray._dirty)
893            {
894                _fogArray._enabled = true;
895                glEnableClientState(GL_FOG_COORDINATE_ARRAY);
896            }
897            //if (_fogArray._pointer!=ptr || _fogArray._dirty)
898            {
899                _fogArray._pointer=ptr;
900                _glFogCoordPointer( type, stride, ptr );
901            }
902            _fogArray._lazy_disable = false;
903            _fogArray._dirty = false;
904        }
905    }
906#else
907        setVertexAttribPointer(_fogCoordAlias._location, 1, type, GL_FALSE, stride, ptr);
908#endif
909}
910
911void State::setSecondaryColorPointer( GLint size, GLenum type,
912                                      GLsizei stride, const GLvoid *ptr )
913{
914#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
915    if (_useVertexAttributeAliasing)
916    {
917        setVertexAttribPointer(_secondaryColorAlias._location, size, type, GL_FALSE, stride, ptr);
918    }
919    else
920    {
921        if (_glSecondaryColorPointer)
922        {
923            if (!_secondaryColorArray._enabled || _secondaryColorArray._dirty)
924            {
925                _secondaryColorArray._enabled = true;
926                glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
927            }
928            //if (_secondaryColorArray._pointer!=ptr || _secondaryColorArray._dirty)
929            {
930                _secondaryColorArray._pointer=ptr;
931                _glSecondaryColorPointer( size, type, stride, ptr );
932            }
933            _secondaryColorArray._lazy_disable = false;
934            _secondaryColorArray._dirty = false;
935        }
936    }
937#else
938        setVertexAttribPointer(_secondaryColorAlias._location, size, type, GL_FALSE, stride, ptr);
939#endif
940}
941
942/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
943* note, only updates values that change.*/
944void State::setVertexAttribPointer( unsigned int index,
945                                      GLint size, GLenum type, GLboolean normalized,
946                                    GLsizei stride, const GLvoid *ptr )
947{
948    if (_glVertexAttribPointer)
949    {
950        // osg::notify(osg::NOTICE)<<"State::setVertexAttribPointer("<<index<<",...)"<<std::endl;
951
952        if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1);
953        EnabledArrayPair& eap = _vertexAttribArrayList[index];
954
955        if (!eap._enabled || eap._dirty)
956        {
957            eap._enabled = true;
958            // osg::notify(osg::NOTICE)<<"    _glEnableVertexAttribArray( "<<index<<" )"<<std::endl;
959            _glEnableVertexAttribArray( index );
960        }
961        //if (eap._pointer != ptr || eap._normalized!=normalized || eap._dirty)
962        {
963            // osg::notify(osg::NOTICE)<<"    _glVertexAttribPointer( "<<index<<" )"<<std::endl;
964            _glVertexAttribPointer( index, size, type, normalized, stride, ptr );
965            eap._pointer = ptr;
966            eap._normalized = normalized;
967        }
968        eap._lazy_disable = false;
969        eap._dirty = false;
970    }
971}     
972
973/** wrapper around DisableVertexAttribArrayARB(index);
974* note, only updates values that change.*/
975void State::disableVertexAttribPointer( unsigned int index )
976{
977    if (_glDisableVertexAttribArray)
978    {
979        if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1);
980        EnabledArrayPair& eap = _vertexAttribArrayList[index];
981
982        if (eap._enabled || eap._dirty)
983        {
984            eap._enabled = false;
985            eap._dirty = false;
986            // osg::notify(osg::NOTICE)<<"    _glDisableVertexAttribArray( "<<index<<" )"<<std::endl;
987            _glDisableVertexAttribArray( index );
988        }
989    }
990}       
991
992void State::disableVertexAttribPointersAboveAndIncluding( unsigned int index )
993{
994    if (_glDisableVertexAttribArray)
995    {
996        while (index<_vertexAttribArrayList.size())
997        {
998            EnabledArrayPair& eap = _vertexAttribArrayList[index];
999            if (eap._enabled || eap._dirty)
1000            {
1001                eap._enabled = false;
1002                eap._dirty = false;
1003                // osg::notify(osg::NOTICE)<<"    State::disableVertexAttribPointersAboveAndIncluding(): _glDisableVertexAttribArray( "<<index<<" )"<<std::endl;
1004                _glDisableVertexAttribArray( index );
1005            }
1006            ++index;
1007        }
1008    }
1009}
1010
1011void State::lazyDisablingOfVertexAttributes()
1012{
1013    // osg::notify(osg::NOTICE)<<"lazyDisablingOfVertexAttributes()"<<std::endl;
1014    if (!_useVertexAttributeAliasing)
1015    {
1016        _vertexArray._lazy_disable = true;
1017        _normalArray._lazy_disable = true;
1018        _colorArray._lazy_disable = true;
1019        _secondaryColorArray._lazy_disable = true;
1020        _fogArray._lazy_disable = true;
1021        for(EnabledTexCoordArrayList::iterator itr = _texCoordArrayList.begin();
1022            itr != _texCoordArrayList.end();
1023            ++itr)
1024        {
1025            itr->_lazy_disable = true;
1026        }
1027    }
1028
1029    for(EnabledVertexAttribArrayList::iterator itr = _vertexAttribArrayList.begin();
1030        itr != _vertexAttribArrayList.end();
1031        ++itr)
1032    {
1033        itr->_lazy_disable = true;
1034    }
1035}
1036
1037void State::applyDisablingOfVertexAttributes()
1038{
1039    //osg::notify(osg::NOTICE)<<"start of applyDisablingOfVertexAttributes()"<<std::endl;
1040    if (!_useVertexAttributeAliasing)
1041    {
1042        if (_vertexArray._lazy_disable) disableVertexPointer();
1043        if (_normalArray._lazy_disable) disableNormalPointer();
1044        if (_colorArray._lazy_disable) disableColorPointer();
1045        if (_secondaryColorArray._lazy_disable) disableSecondaryColorPointer();
1046        if (_fogArray._lazy_disable) disableFogCoordPointer();
1047        for(unsigned int i=0; i<_texCoordArrayList.size(); ++i)
1048        {
1049            if (_texCoordArrayList[i]._lazy_disable) disableTexCoordPointer(i);
1050        }
1051    }
1052    for(unsigned int i=0; i<_vertexAttribArrayList.size(); ++i)
1053    {
1054        if (_vertexAttribArrayList[i]._lazy_disable) disableVertexAttribPointer(i);
1055    }
1056    // osg::notify(osg::NOTICE)<<"end of applyDisablingOfVertexAttributes()"<<std::endl;
1057}
1058
1059
1060bool State::computeSecondaryColorSupported() const
1061{
1062    _isSecondaryColorSupportResolved = true;
1063    _isSecondaryColorSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_secondary_color");
1064    return _isSecondaryColorSupported;
1065}
1066
1067bool State::computeFogCoordSupported() const
1068{
1069    _isFogCoordSupportResolved = true;
1070    _isFogCoordSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_fog_coord");
1071    return _isFogCoordSupported;
1072}
1073
1074bool State::computeVertexBufferObjectSupported() const
1075{
1076    _isVertexBufferObjectSupportResolved = true;
1077    _isVertexBufferObjectSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES || osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_buffer_object");
1078    return _isVertexBufferObjectSupported;
1079}
1080
1081bool State::checkGLErrors(const char* str) const
1082{
1083    GLenum errorNo = glGetError();
1084    if (errorNo!=GL_NO_ERROR)
1085    {
1086#ifdef OSG_GLU_AVAILABLE
1087        const char* error = (char*)gluErrorString(errorNo);
1088        if (error) osg::notify(WARN)<<"Warning: detected OpenGL error '" << error<<"'";
1089        else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x" << std::hex << errorNo << std::dec;
1090#else
1091            switch(errorNo)
1092            {
1093                case(GL_INVALID_ENUM):
1094                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_INVALID_ENUM";
1095                    break;
1096                case(GL_INVALID_VALUE):
1097                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_INVALID_VALUE";
1098                    break;
1099                case(GL_INVALID_OPERATION):
1100                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_INVALID_OPERATION";
1101                    break;
1102                case(GL_OUT_OF_MEMORY):
1103                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_OUT_OF_MEMORY";
1104                    break;
1105                default:
1106                    osg::notify(WARN)<<"Warning: detected OpenGL error number 0x" << std::hex << errorNo << std::dec;
1107                    break;
1108            }
1109#endif
1110        if (str) osg::notify(WARN)<<" at "<<str<< std::endl;
1111        else     osg::notify(WARN)<<" in osg::State."<< std::endl;
1112
1113        return true;
1114    }
1115    return false;
1116}
1117
1118bool State::checkGLErrors(StateAttribute::GLMode mode) const
1119{
1120    GLenum errorNo = glGetError();
1121    if (errorNo!=GL_NO_ERROR)
1122    {
1123        #ifdef OSG_GLU_AVAILABLE
1124            const char* error = (char*)gluErrorString(errorNo);
1125            if (error) osg::notify(WARN)<<"Warning: detected OpenGL error '"<< error <<"' after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
1126            else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
1127        #else
1128            switch(errorNo)
1129            {
1130                case(GL_INVALID_ENUM):
1131                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_INVALID_ENUM after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
1132                    break;
1133                case(GL_INVALID_VALUE):
1134                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_INVALID_VALUE after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
1135                    break;
1136                case(GL_INVALID_OPERATION):
1137                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_INVALID_OPERATION after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
1138                    break;
1139                case(GL_OUT_OF_MEMORY):
1140                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_OUT_OF_MEMORY after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
1141                    break;
1142                default:
1143                    osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying GLMode 0x"<<hex<<mode<<dec<< std::endl;
1144                    break;
1145            }
1146        #endif
1147        return true;
1148    }
1149    return false;
1150}
1151
1152bool State::checkGLErrors(const StateAttribute* attribute) const
1153{
1154    GLenum errorNo = glGetError();
1155    if (errorNo!=GL_NO_ERROR)
1156    {
1157        #ifdef OSG_GLU_AVAILABLE
1158            const char* error = (char*)gluErrorString(errorNo);
1159            if (error) osg::notify(WARN)<<"Warning: detected OpenGL error '"<< error <<"' after applying attribute "<<attribute->className()<<" "<<attribute<< std::endl;
1160            else       osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying attribute "<<attribute->className()<<" "<<attribute<< std::dec << std::endl;
1161        #else
1162            switch(errorNo)
1163            {
1164                case(GL_INVALID_ENUM):
1165                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_INVALID_ENUM after applying attribute "<<attribute->className()<<" "<<attribute<< std::dec << std::endl;
1166                    break;
1167                case(GL_INVALID_VALUE):
1168                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_INVALID_VALUE after applying attribute "<<attribute->className()<<" "<<attribute<< std::dec << std::endl;
1169                    break;
1170                case(GL_INVALID_OPERATION):
1171                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_INVALID_OPERATION after applying attribute "<<attribute->className()<<" "<<attribute<< std::dec << std::endl;
1172                    break;
1173                case(GL_OUT_OF_MEMORY):
1174                    osg::notify(WARN)<<"Warning: detected OpenGL error GL_OUT_OF_MEMORY after applying attribute "<<attribute->className()<<" "<<attribute<< std::dec << std::endl;
1175                    break;
1176                default:
1177                    osg::notify(WARN)<<"Warning: detected OpenGL error number 0x"<< std::hex << errorNo <<" after applying attribute "<<attribute->className()<<" "<<attribute<< std::dec << std::endl;
1178                    break;
1179            }
1180        #endif
1181
1182        return true;
1183    }
1184    return false;
1185}
1186
1187
1188void State::applyModelViewAndProjectionUniformsIfRequired()
1189{
1190    if (!_lastAppliedProgramObject) return;
1191
1192    if (_modelViewMatrixUniform.valid()) _lastAppliedProgramObject->apply(*_modelViewMatrixUniform);
1193    if (_projectionMatrixUniform) _lastAppliedProgramObject->apply(*_projectionMatrixUniform);
1194    if (_modelViewProjectionMatrixUniform) _lastAppliedProgramObject->apply(*_modelViewProjectionMatrixUniform);
1195    if (_normalMatrixUniform) _lastAppliedProgramObject->apply(*_normalMatrixUniform);
1196}
1197
1198namespace State_Utils
1199{
1200    bool replace(std::string& str, const std::string& original_phrase, const std::string& new_phrase)
1201    {
1202        bool replacedStr = false;
1203        std::string::size_type pos = 0;
1204        while((pos=str.find(original_phrase, pos))!=std::string::npos)
1205        {
1206            std::string::size_type endOfPhrasePos = pos+original_phrase.size();
1207            if (endOfPhrasePos<str.size())
1208            {
1209                char c = str[endOfPhrasePos];
1210                if ((c>='0' && c<='9') ||
1211                    (c>='a' && c<='z') ||
1212                    (c>='A' && c<='Z'))
1213                {
1214                    pos = endOfPhrasePos;
1215                    continue;
1216                }
1217            }
1218
1219            replacedStr = true;
1220            str.replace(pos, original_phrase.size(), new_phrase);
1221        }
1222        return replacedStr;
1223    }
1224
1225    void replaceAndInsertDeclaration(std::string& source, const std::string& originalStr, const std::string& newStr, const std::string& declarationPrefix)
1226    {
1227        if (replace(source, originalStr, newStr))
1228        {
1229            source.insert(0, declarationPrefix + newStr + std::string(";\n"));
1230        }
1231    }
1232}
1233
1234bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const
1235{
1236    osg::notify(osg::NOTICE)<<"State::convertShaderSourceToOsgBuiltIns()"<<std::endl;
1237
1238    osg::notify(osg::NOTICE)<<"++Before Converted source "<<std::endl<<source<<std::endl<<"++++++++"<<std::endl;
1239
1240    // replace ftransform as it only works with built-ins
1241    State_Utils::replace(source, "ftransform()", "gl_ModelViewProjectionMatrix * gl_Vertex");
1242
1243    State_Utils::replaceAndInsertDeclaration(source, "gl_Normal", "osg_Normal", "attribute vec3 ");
1244    State_Utils::replaceAndInsertDeclaration(source, "gl_Vertex", "osg_Vertex", "attribute vec4 ");
1245    State_Utils::replaceAndInsertDeclaration(source, "gl_Color", "osg_Color", "attribute vec4 ");
1246    State_Utils::replaceAndInsertDeclaration(source, "gl_SecondaryColor", "osg_SecondaryColor", "attribute vec4 ");
1247    State_Utils::replaceAndInsertDeclaration(source, "gl_FogCoord", "osg_FogCoord", "attribute float ");
1248
1249    State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord0", "osg_MultiTexCoord0", "attribute vec4 ");
1250    State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord1", "osg_MultiTexCoord1", "attribute vec4 ");
1251    State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord2", "osg_MultiTexCoord2", "attribute vec4 ");
1252    State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord3", "osg_MultiTexCoord3", "attribute vec4 ");
1253    State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord4", "osg_MultiTexCoord4", "attribute vec4 ");
1254    State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord5", "osg_MultiTexCoord5", "attribute vec4 ");
1255    State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord6", "osg_MultiTexCoord6", "attribute vec4 ");
1256    State_Utils::replaceAndInsertDeclaration(source, "gl_MultiTexCoord7", "osg_MultiTexCoord7", "attribute vec4 ");
1257
1258    // replace built in uniform
1259    State_Utils::replaceAndInsertDeclaration(source, "gl_ModelViewMatrix", "osg_ModelViewMatrix", "uniform mat4 ");
1260    State_Utils::replaceAndInsertDeclaration(source, "gl_ModelViewProjectionMatrix", "osg_ModelViewProjectionMatrix", "uniform mat4 ");
1261    State_Utils::replaceAndInsertDeclaration(source, "gl_ProjectionMatrix", "osg_ProjectionMatrix", "uniform mat4 ");
1262    State_Utils::replaceAndInsertDeclaration(source, "gl_NormalMatrix", "osg_NormalMatrix", "uniform mat3 ");
1263
1264    osg::notify(osg::NOTICE)<<"-------- Converted source "<<std::endl<<source<<std::endl<<"----------------"<<std::endl;
1265
1266    return true;
1267}
1268
1269void State::setUpVertexAttribAlias(VertexAttribAlias& alias, GLuint location, const std::string glName, const std::string osgName, const std::string& declaration)
1270{
1271    alias = VertexAttribAlias(location, glName, osgName, declaration);
1272    _attributeBindingList[osgName] = location;
1273}
1274
1275void State::applyProjectionMatrix(const osg::RefMatrix* matrix)
1276{
1277    if (_projection!=matrix)
1278    {
1279        if (matrix)
1280        {
1281            _projection=matrix;
1282        }
1283        else
1284        {
1285            _projection=_identity;
1286        }
1287
1288        if (_useModelViewAndProjectionUniforms)
1289        {
1290            if (_projectionMatrixUniform.valid()) _projectionMatrixUniform->set(*_projection);
1291            updateModelViewAndProjectionMatrixUniforms();
1292        }
1293#ifdef OSG_GL_MATRICES_AVAILABLE
1294        glMatrixMode( GL_PROJECTION );
1295            glLoadMatrix(_projection->ptr());
1296        glMatrixMode( GL_MODELVIEW );
1297#endif
1298    }
1299}
1300
1301void State::applyModelViewMatrix(const osg::RefMatrix* matrix)
1302{
1303    if (_modelView!=matrix)
1304    {
1305        if (matrix)
1306        {
1307            _modelView=matrix;
1308        }
1309        else
1310        {
1311            _modelView=_identity;
1312        }
1313
1314        if (_useModelViewAndProjectionUniforms)
1315        {
1316            if (_modelViewMatrixUniform.valid()) _modelViewMatrixUniform->set(*_modelView);
1317            updateModelViewAndProjectionMatrixUniforms();
1318        }
1319
1320#ifdef OSG_GL_MATRICES_AVAILABLE
1321        glLoadMatrix(_modelView->ptr());
1322#endif
1323    }
1324}
1325
1326#include <osg/io_utils>
1327
1328void State::updateModelViewAndProjectionMatrixUniforms()
1329{
1330    if (_modelViewProjectionMatrixUniform.valid()) _modelViewProjectionMatrixUniform->set((*_modelView) * (*_projection));
1331    if (_normalMatrixUniform.valid())
1332    {
1333        Matrix mv(*_modelView);
1334        mv.setTrans(0.0, 0.0, 0.0);
1335
1336        Matrix matrix;
1337        matrix.invert(mv);
1338
1339        Matrix3 normalMatrix(matrix(0,0), matrix(1,0), matrix(2,0),
1340                             matrix(0,1), matrix(1,1), matrix(2,1),
1341                             matrix(0,2), matrix(1,2), matrix(2,2));
1342
1343        _normalMatrixUniform->set(normalMatrix);
1344    }
1345}
1346
1347void State::drawQuads(GLint first, GLsizei count, GLsizei primCount)
1348{
1349    // osg::notify(osg::NOTICE)<<"State::drawQuads("<<first<<", "<<count<<")"<<std::endl;
1350   
1351    unsigned int array = first % 4;
1352    unsigned int offsetFirst = ((first-array) / 4) * 6;
1353    unsigned int numQuads = (count/4);
1354    unsigned int numIndices = numQuads * 6;
1355    unsigned int endOfIndices = offsetFirst+numIndices;
1356    Indices& indices = _quadIndices[array];
1357    if (endOfIndices>65536)
1358    {
1359        osg::notify(osg::NOTICE)<<"Warning: State::drawQuads("<<first<<", "<<count<<") too large handle in remapping to ushort glDrawElements."<<std::endl;
1360        endOfIndices = 65536;
1361    }
1362   
1363    if (endOfIndices >= indices.size())
1364    {
1365        // we need to expand the _indexArray to be big enough to cope with all the quads required.
1366        unsigned int numExistingQuads = indices.size()/6;
1367        unsigned int numRequiredQuads = endOfIndices/6;
1368        indices.reserve(endOfIndices);
1369        for(unsigned int i=numExistingQuads; i<numRequiredQuads; ++i)
1370        {
1371            unsigned int base = i*4 + array;
1372            indices.push_back(base);
1373            indices.push_back(base+1);
1374            indices.push_back(base+3);
1375           
1376            indices.push_back(base+1);
1377            indices.push_back(base+2);
1378            indices.push_back(base+3);
1379           
1380            // osg::notify(osg::NOTICE)<<"   adding quad indices ("<<base<<")"<<std::endl;
1381        }
1382    }
1383
1384    // if (array!=0) return;
1385
1386    // osg::notify(osg::NOTICE)<<"  glDrawElements(GL_TRIANGLES, "<<numIndices<<", GL_UNSIGNED_SHORT, "<<&(indices[base])<<")"<<std::endl;
1387    glDrawElementsInstanced(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, &(indices[offsetFirst]), primCount);
1388}
Note: See TracBrowser for help on using the browser.