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

Revision 13041, 54.9 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

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