1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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.
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.
18#include <osg/GLExtensions>
19#include <osg/StateSet>
22#include <osg/BufferObject>
23#include <osg/Observer>
25#include <osg/VertexArrayState>
27#include <osg/ShaderComposer>
28#include <osg/FrameStamp>
29#include <osg/DisplaySettings>
30#include <osg/Polytope>
31#include <osg/Viewport>
32#include <osg/AttributeDispatchers>
33#include <osg/GraphicsCostEstimator>
42#define GL_TEXTURE0 0x84C0
47/** macro for use with osg::StateAttribute::apply methods for detecting and
48 * reporting OpenGL error messages.*/
49#define OSG_GL_DEBUG(message) \
50 if (state.getFineGrainedErrorDetection()) \
52 GLenum errorNo = glGetError(); \
53 if (errorNo!=GL_NO_ERROR) \
55 osg::notify(WARN)<<"Warning: detected OpenGL error '"<<gluErrorString(errorNo)<<" "<<message<<endl; \
60// forward declare GraphicsContext, View and State
63/** Encapsulates the current applied OpenGL modes, attributes and vertex arrays settings,
64 * implements lazy state updating and provides accessors for querying the current state.
65 * The venerable Red Book says that "OpenGL is a state machine", and this class
66 * represents the OpenGL state in OSG. Furthermore, \c State also has other
68 * - It works as a stack of states (see \c pushStateSet() and
69 * \c popStateSet()). Manipulating this stack of OpenGL states manually is
70 * seldom needed, since OSG does this in the most common situations.
71 * - It implements lazy state updating. This means that, if one requests a
72 * state change and that particular state is already in the requested state,
73 * no OpenGL call will be made. This ensures that the OpenGL pipeline is not
74 * stalled by unnecessary state changes.
75 * - It allows to query the current OpenGL state without calls to \c glGet*(),
76 * which typically stall the graphics pipeline (see, for instance,
77 * \c captureCurrentState() and \c getModelViewMatrix()).
79class OSG_EXPORT State : public Referenced
86 /** Set the graphics context associated with that owns this State object.*/
87 void setGraphicsContext(GraphicsContext* context) { _graphicsContext = context; }
89 /** Get the graphics context associated with that owns this State object.*/
90 GraphicsContext* getGraphicsContext() { return _graphicsContext; }
92 /** Get the const graphics context associated with that owns this State object.*/
93 const GraphicsContext* getGraphicsContext() const { return _graphicsContext; }
96 /** Set the current OpenGL context uniqueID.
97 * The ContextID is used by classes like osg::StateAttribute's and osg::Drawable's to
98 * help manage separate OpenGL objects, such as display lists, vertex buffer objects
99 * and texture object for each graphics context. The ContextID simply acts as an index
100 * into arrays that these classes maintain for the purpose of storing GL object handles.
102 * Note, osgViewer::GraphicsWindow will automatically set up the ContextID for you,
103 * so you will rearely need to set this yourself.
105 * The exception is when creating your own graphics context, where you should set
106 * the ContextID uniquely for each graphics context.
108 * Typical settings for ContextID are 0,1,2,3... up to the maximum
109 * number of graphics contexts you have set up. By default contextID is 0.
111 inline void setContextID(unsigned int contextID) { _contextID=contextID; }
113 /** Get the current OpenGL context unique ID.*/
114 inline unsigned int getContextID() const { return _contextID; }
117 // ExtensionMap contains GL Extentsions objects used by StateAttribue to call OpenGL extensions/advanced features
118 typedef std::map<const std::type_info*, osg::ref_ptr<osg::Referenced> > ExtensionMap;
119 ExtensionMap _extensionMap;
121 /** Get a specific GL extensions object or GraphicsObjectManager, initialize if not already present.
122 * Note, must only be called from a the graphics context thread associated with this osg::State. */
126 const std::type_info* id(&typeid(T));
127 osg::ref_ptr<osg::Referenced>& ptr = _extensionMap[id];
130 ptr = new T(_contextID);
132 return static_cast<T*>(ptr.get());
135 /** Get a specific GL extensions object or GraphicsObjectManager if it already exists in the extension map.
136 * Note, safe to call outwith a the graphics context thread associated with this osg::State.
137 * Returns NULL if the desired extension object has not been created yet.*/
141 const std::type_info* id(&typeid(T));
142 ExtensionMap::const_iterator itr = _extensionMap.find(id);
143 if (itr==_extensionMap.end()) return 0;
144 else return itr->second.get();
147 /** Set a specific GL extensions object pr GraphicsObjectManager. */
151 const std::type_info* id(&typeid(T));
152 _extensionMap[id] = ptr;
156 void setShaderCompositionEnabled(bool flag) { _shaderCompositionEnabled = flag; }
159 bool getShaderCompositionEnabled() const { return _shaderCompositionEnabled; }
162 void setShaderComposer(ShaderComposer* sc) { _shaderComposer = sc; }
165 ShaderComposer* getShaderComposer() { return _shaderComposer.get(); }
168 const ShaderComposer* getShaderComposer() const { return _shaderComposer.get(); }
170 /** Get the unform list in which to inject any uniforms that StateAttribute::apply(State&) methods provide.*/
171 StateSet::UniformList& getCurrentShaderCompositionUniformList() { return _currentShaderCompositionUniformList; }
173 /** Convenience method for StateAttribute::apply(State&) methods to pass on their uniforms to osg::State so it can apply them at the appropriate point.*/
174 void applyShaderCompositionUniform(const osg::Uniform* uniform, StateAttribute::OverrideValue value=StateAttribute::ON)
176 StateSet::RefUniformPair& up = _currentShaderCompositionUniformList[uniform->getName()];
177 up.first = const_cast<Uniform*>(uniform);
182 /** Push stateset onto state stack.*/
183 void pushStateSet(const StateSet* dstate);
185 /** Pop stateset off state stack.*/
188 /** pop all statesets off state stack, ensuring it is empty ready for the next frame.
189 * Note, to return OpenGL to default state, one should do any state.popAllStatSets(); state.apply().*/
190 void popAllStateSets();
192 /** Insert stateset onto state stack.*/
193 void insertStateSet(unsigned int pos,const StateSet* dstate);
195 /** Pop stateset off state stack.*/
196 void removeStateSet(unsigned int pos);
198 /** Get the number of StateSet's on the StateSet stack.*/
199 unsigned int getStateSetStackSize() { return static_cast<unsigned int>(_stateStateStack.size()); }
201 /** Pop StateSet's for the StateSet stack till its size equals the specified size.*/
202 void popStateSetStackToSize(unsigned int size) { while (_stateStateStack.size()>size) popStateSet(); }
204 typedef std::vector<const StateSet*> StateSetStack;
206 /** Get the StateSet stack.*/
207 StateSetStack& getStateSetStack() { return _stateStateStack; }
210 /** Copy the modes and attributes which capture the current state.*/
211 void captureCurrentState(StateSet& stateset) const;
213 /** Release all OpenGL objects associated cached by this osg::State object.*/
214 void releaseGLObjects();
216 /** reset the state object to an empty stack.*/
219 inline const Viewport* getCurrentViewport() const
221 return static_cast<const Viewport*>(getLastAppliedAttribute(osg::StateAttribute::VIEWPORT));
225 void setInitialViewMatrix(const osg::RefMatrix* matrix);
227 inline const osg::Matrix& getInitialViewMatrix() const { return *_initialViewMatrix; }
228 inline const osg::Matrix& getInitialInverseViewMatrix() const { return _initialInverseViewMatrix; }
230 void applyProjectionMatrix(const osg::RefMatrix* matrix);
232 inline const osg::Matrix& getProjectionMatrix() const { return *_projection; }
234 void applyModelViewMatrix(const osg::RefMatrix* matrix);
235 void applyModelViewMatrix(const osg::Matrix&);
237 const osg::Matrix& getModelViewMatrix() const { return *_modelView; }
239 void setUseModelViewAndProjectionUniforms(bool flag) { _useModelViewAndProjectionUniforms = flag; }
240 bool getUseModelViewAndProjectionUniforms() const { return _useModelViewAndProjectionUniforms; }
242 void updateModelViewAndProjectionMatrixUniforms();
244 void applyModelViewAndProjectionUniformsIfRequired();
246 osg::Uniform* getModelViewMatrixUniform() { return _modelViewMatrixUniform.get(); }
247 osg::Uniform* getProjectionMatrixUniform() { return _projectionMatrixUniform.get(); }
248 osg::Uniform* getModelViewProjectionMatrixUniform() { return _modelViewProjectionMatrixUniform.get(); }
249 osg::Uniform* getNormalMatrixUniform() { return _normalMatrixUniform.get(); }
252 Polytope getViewFrustum() const;
255 void setUseVertexAttributeAliasing(bool flag);
256 bool getUseVertexAttributeAliasing() const { return _useVertexAttributeAliasing ; }
258 typedef std::vector<VertexAttribAlias> VertexAttribAliasList;
260 /** Reset the vertex attribute aliasing to osg's default. This method needs to be called before render anything unless you really know what you're doing !*/
261 void resetVertexAttributeAlias(bool compactAliasing=true, unsigned int numTextureUnits=8);
263 /** Set the vertex attribute aliasing for "vertex". This method needs to be called before render anything unless you really know what you're doing !*/
264 void setVertexAlias(const VertexAttribAlias& alias) { _vertexAlias = alias; }
265 const VertexAttribAlias& getVertexAlias() { return _vertexAlias; }
267 /** Set the vertex attribute aliasing for "normal". This method needs to be called before render anything unless you really know what you're doing !*/
268 void setNormalAlias(const VertexAttribAlias& alias) { _normalAlias = alias; }
269 const VertexAttribAlias& getNormalAlias() { return _normalAlias; }
271 /** Set the vertex attribute aliasing for "color". This method needs to be called before render anything unless you really know what you're doing !*/
272 void setColorAlias(const VertexAttribAlias& alias) { _colorAlias = alias; }
273 const VertexAttribAlias& getColorAlias() { return _colorAlias; }
275 /** Set the vertex attribute aliasing for "secondary color". This method needs to be called before render anything unless you really know what you're doing !*/
276 void setSecondaryColorAlias(const VertexAttribAlias& alias) { _secondaryColorAlias = alias; }
277 const VertexAttribAlias& getSecondaryColorAlias() { return _secondaryColorAlias; }
279 /** Set the vertex attribute aliasing for "fog coord". This method needs to be called before render anything unless you really know what you're doing !*/
280 void setFogCoordAlias(const VertexAttribAlias& alias) { _fogCoordAlias = alias; }
281 const VertexAttribAlias& getFogCoordAlias() { return _fogCoordAlias; }
283 /** Set the vertex attribute aliasing list for texture coordinates. This method needs to be called before render anything unless you really know what you're doing !*/
284 void setTexCoordAliasList(const VertexAttribAliasList& aliasList) { _texCoordAliasList = aliasList; }
285 const VertexAttribAliasList& getTexCoordAliasList() { return _texCoordAliasList; }
287 /** Set the vertex attribute binding list. This method needs to be called before render anything unless you really know what you're doing !*/
288 void setAttributeBindingList(const Program::AttribBindingList& attribBindingList) { _attributeBindingList = attribBindingList; }
289 const Program::AttribBindingList& getAttributeBindingList() { return _attributeBindingList; }
291 bool convertVertexShaderSourceToOsgBuiltIns(std::string& source) const;
294 /** Apply stateset.*/
295 void apply(const StateSet* dstate);
297 /** Updates the OpenGL state so that it matches the \c StateSet at the
298 * top of the stack of <tt>StateSet</tt>s maintained internally by a
303 /** Apply any shader composed state.*/
304 void applyShaderComposition();
307 void glDrawBuffer(GLenum buffer);
308 GLenum getDrawBuffer() const { return _drawBuffer; }
310 void glReadBuffer(GLenum buffer);
311 GLenum getReadBuffer() const { return _readBuffer; }
314 /** Set whether a particular OpenGL mode is valid in the current graphics context.
315 * Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/
316 inline void setModeValidity(StateAttribute::GLMode mode,bool valid)
318 ModeStack& ms = _modeMap[mode];
322 /** Get whether a particular OpenGL mode is valid in the current graphics context.
323 * Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/
324 inline bool getModeValidity(StateAttribute::GLMode mode)
326 ModeStack& ms = _modeMap[mode];
330 inline void setGlobalDefaultModeValue(StateAttribute::GLMode mode,bool enabled)
332 ModeStack& ms = _modeMap[mode];
333 ms.global_default_value = enabled;
336 inline bool getGlobalDefaultModeValue(StateAttribute::GLMode mode)
338 return _modeMap[mode].global_default_value;
341 inline bool getLastAppliedModeValue(StateAttribute::GLMode mode)
343 return _modeMap[mode].last_applied_value;
346 /** Proxy helper class for applyig a model in a local scope, with the preivous value being resotred automatically on leaving the scope that proxy was created.*/
347 struct ApplyModeProxy
349 inline ApplyModeProxy(osg::State& state, GLenum mode, bool value):_state(state), _mode(mode)
351 _previous_value = _state.getLastAppliedModeValue(mode);
352 _need_to_apply_value = (_previous_value!=value);
353 if (_need_to_apply_value) _state.applyMode(_mode, value);
355 inline ~ApplyModeProxy()
357 if (_need_to_apply_value) _state.applyMode(_mode, _previous_value);
362 bool _previous_value;
363 bool _need_to_apply_value;
366 struct ApplyTextureModeProxy
368 inline ApplyTextureModeProxy(osg::State& state, unsigned int unit, GLenum mode, bool value):_state(state), _unit(unit), _mode(mode)
370 _previous_value = _state.getLastAppliedTextureModeValue(_unit, _mode);
371 _need_to_apply_value = (_previous_value!=value);
372 if (_need_to_apply_value) _state.applyTextureMode(_unit, _mode, value);
374 inline ~ApplyTextureModeProxy()
376 if (_need_to_apply_value) _state.applyTextureMode(_unit, _mode, _previous_value);
382 bool _previous_value;
383 bool _need_to_apply_value;
386 /** Apply an OpenGL mode if required. This is a wrapper around
387 * \c glEnable() and \c glDisable(), that just actually calls these
388 * functions if the \c enabled flag is different than the current
390 * @return \c true if the state was actually changed. \c false
391 * otherwise. Notice that a \c false return does not indicate
392 * an error, it just means that the mode was already set to the
393 * same value as the \c enabled parameter.
395 inline bool applyMode(StateAttribute::GLMode mode,bool enabled)
397 ModeStack& ms = _modeMap[mode];
399 return applyMode(mode,enabled,ms);
402 inline void setGlobalDefaultTextureModeValue(unsigned int unit, StateAttribute::GLMode mode,bool enabled)
404 ModeMap& modeMap = getOrCreateTextureModeMap(unit);
405 ModeStack& ms = modeMap[mode];
406 ms.global_default_value = enabled;
409 inline bool getGlobalDefaultTextureModeValue(unsigned int unit, StateAttribute::GLMode mode)
411 ModeMap& modeMap = getOrCreateTextureModeMap(unit);
412 ModeStack& ms = modeMap[mode];
413 return ms.global_default_value;
416 inline bool applyTextureMode(unsigned int unit, StateAttribute::GLMode mode,bool enabled)
418 ModeMap& modeMap = getOrCreateTextureModeMap(unit);
419 ModeStack& ms = modeMap[mode];
421 return applyModeOnTexUnit(unit,mode,enabled,ms);
424 inline bool getLastAppliedTextureModeValue(unsigned int unit, StateAttribute::GLMode mode)
426 ModeMap& modeMap = getOrCreateTextureModeMap(unit);
427 ModeStack& ms = modeMap[mode];
428 return ms.last_applied_value;
431 inline void setGlobalDefaultAttribute(const StateAttribute* attribute)
433 AttributeStack& as = _attributeMap[attribute->getTypeMemberPair()];
434 as.global_default_attribute = attribute;
437 inline const StateAttribute* getGlobalDefaultAttribute(StateAttribute::Type type, unsigned int member=0)
439 AttributeStack& as = _attributeMap[StateAttribute::TypeMemberPair(type,member)];
440 return as.global_default_attribute.get();
443 /** Apply an attribute if required. */
444 inline bool applyAttribute(const StateAttribute* attribute)
446 AttributeStack& as = _attributeMap[attribute->getTypeMemberPair()];
448 return applyAttribute(attribute,as);
451 inline void setGlobalDefaultTextureAttribute(unsigned int unit, const StateAttribute* attribute)
453 AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit);
454 AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
455 as.global_default_attribute = attribute;
458 inline const StateAttribute* getGlobalDefaultTextureAttribute(unsigned int unit, StateAttribute::Type type, unsigned int member = 0)
460 AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit);
461 AttributeStack& as = attributeMap[StateAttribute::TypeMemberPair(type,member)];
462 return as.global_default_attribute.get();
466 inline bool applyTextureAttribute(unsigned int unit, const StateAttribute* attribute)
468 AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit);
469 AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
471 return applyAttributeOnTexUnit(unit,attribute,as);
474 /** Mode has been set externally, update state to reflect this setting.*/
475 void haveAppliedMode(StateAttribute::GLMode mode,StateAttribute::GLModeValue value);
477 /** Mode has been set externally, therefore dirty the associated mode in osg::State
478 * so it is applied on next call to osg::State::apply(..)*/
479 void haveAppliedMode(StateAttribute::GLMode mode);
481 /** Attribute has been applied externally, update state to reflect this setting.*/
482 void haveAppliedAttribute(const StateAttribute* attribute);
484 /** Attribute has been applied externally,
485 * and therefore this attribute type has been dirtied
486 * and will need to be re-applied on next osg::State.apply(..).
487 * note, if you have an osg::StateAttribute which you have applied externally
488 * then use the have_applied(attribute) method as this will cause the osg::State to
489 * track the current state more accurately and enable lazy state updating such
490 * that only changed state will be applied.*/
491 void haveAppliedAttribute(StateAttribute::Type type, unsigned int member=0);
493 /** Get whether the current specified mode is enabled (true) or disabled (false).*/
494 bool getLastAppliedMode(StateAttribute::GLMode mode) const;
496 /** Get the current specified attribute, return NULL if one has not yet been applied.*/
497 const StateAttribute* getLastAppliedAttribute(StateAttribute::Type type, unsigned int member=0) const;
499 /** texture Mode has been set externally, update state to reflect this setting.*/
500 void haveAppliedTextureMode(unsigned int unit, StateAttribute::GLMode mode,StateAttribute::GLModeValue value);
502 /** texture Mode has been set externally, therefore dirty the associated mode in osg::State
503 * so it is applied on next call to osg::State::apply(..)*/
504 void haveAppliedTextureMode(unsigned int unit, StateAttribute::GLMode mode);
506 /** texture Attribute has been applied externally, update state to reflect this setting.*/
507 void haveAppliedTextureAttribute(unsigned int unit, const StateAttribute* attribute);
509 /** texture Attribute has been applied externally,
510 * and therefore this attribute type has been dirtied
511 * and will need to be re-applied on next osg::State.apply(..).
512 * note, if you have an osg::StateAttribute which you have applied externally
513 * then use the have_applied(attribute) method as this will the osg::State to
514 * track the current state more accurately and enable lazy state updating such
515 * that only changed state will be applied.*/
516 void haveAppliedTextureAttribute(unsigned int unit, StateAttribute::Type type, unsigned int member=0);
518 /** Get whether the current specified texture mode is enabled (true) or disabled (false).*/
519 bool getLastAppliedTextureMode(unsigned int unit, StateAttribute::GLMode mode) const;
521 /** Get the current specified texture attribute, return NULL if one has not yet been applied.*/
522 const StateAttribute* getLastAppliedTextureAttribute(unsigned int unit, StateAttribute::Type type, unsigned int member=0) const;
528 /** Dirty the modes previously applied in osg::State.*/
529 void dirtyAllModes();
531 /** Dirty the modes attributes previously applied in osg::State.*/
532 void dirtyAllAttributes();
535 /** Proxy helper class for applyig a VertexArrayState in a local scope, with the preivous value being resotred automatically on leaving the scope that proxy was created.*/
536 struct SetCurrentVertexArrayStateProxy
538 SetCurrentVertexArrayStateProxy(osg::State& state, VertexArrayState* vas):_state(state) { _state.setCurrentVertexArrayState(vas); }
539 ~SetCurrentVertexArrayStateProxy() { _state.setCurrentToGlobalVertexArrayState(); }
543 /** Set the CurrentVetexArrayState object that take which vertex arrays are bound.*/
544 void setCurrentVertexArrayState(VertexArrayState* vas) { _vas = vas; }
546 /** Get the CurrentVetexArrayState object that take which vertex arrays are bound.*/
547 VertexArrayState* getCurrentVertexArrayState() const { return _vas; }
549 /** Set the getCurrentVertexArrayState to the GlobalVertexArrayState.*/
550 void setCurrentToGlobalVertexArrayState() { _vas = _globalVertexArrayState.get(); }
552 /** Reset the CurrentVertexArrayState/VertexArrayObject if it's value matches the specificied vas - use when deleting a vas.*/
553 void resetCurrentVertexArrayStateOnMatch(VertexArrayState* vas)
555 if (vas->getVertexArrayObject()== _currentVAO) _currentVAO = 0;
556 if (_vas==vas) _vas = _globalVertexArrayState.get();
560 /** disable the vertex, normal, color, tex coords, secondary color, fog coord and index arrays.*/
561 void disableAllVertexArrays();
564 void lazyDisablingOfVertexAttributes() { _vas->lazyDisablingOfVertexAttributes(); }
565 void applyDisablingOfVertexAttributes() { _vas->applyDisablingOfVertexAttributes(*this); }
567 void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _vas->setCurrentVertexBufferObject(vbo); }
568 const GLBufferObject* getCurrentVertexBufferObject() { return _vas->getCurrentVertexBufferObject(); }
570 void bindVertexBufferObject(osg::GLBufferObject* vbo) { _vas->bindVertexBufferObject(vbo); }
571 void unbindVertexBufferObject() { _vas->unbindVertexBufferObject(); }
573 void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _vas->setCurrentElementBufferObject(ebo); }
574 const GLBufferObject* getCurrentElementBufferObject() { return _vas->getCurrentElementBufferObject(); }
576 void bindElementBufferObject(osg::GLBufferObject* ebo) { _vas->bindElementBufferObject(ebo); }
577 void unbindElementBufferObject() { _vas->unbindElementBufferObject(); }
580 void setCurrentPixelBufferObject(osg::GLBufferObject* pbo) { _currentPBO = pbo; }
581 const GLBufferObject* getCurrentPixelBufferObject() const { return _currentPBO; }
583 inline void bindPixelBufferObject(osg::GLBufferObject* pbo)
587 if (pbo == _currentPBO) return;
589 if (pbo->isDirty()) pbo->compileBuffer();
590 else pbo->bindBuffer();
596 unbindPixelBufferObject();
600 inline void unbindPixelBufferObject()
602 if (!_currentPBO) return;
604 _glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,0);
609 inline void bindDrawIndirectBufferObject(osg::GLBufferObject* ibo)
613 ibo->compileBuffer();
616 else if (ibo != _currentDIBO)
623 inline void unbindDrawIndirectBufferObject()
625 if (!_currentDIBO) return;
626 _glBindBuffer(GL_DRAW_INDIRECT_BUFFER,0);
630 void setCurrentVertexArrayObject(GLuint vao) { _currentVAO = vao; }
631 GLuint getCurrentVertexArrayObject() const { return _currentVAO; }
633 inline void bindVertexArrayObject(const VertexArrayState* vas) { bindVertexArrayObject(vas->getVertexArrayObject()); }
635 inline void bindVertexArrayObject(GLuint vao) { if (_currentVAO!=vao) { _glExtensions->glBindVertexArray(vao); _currentVAO = vao; } }
637 inline void unbindVertexArrayObject() { if (_currentVAO!=0) { _glExtensions->glBindVertexArray(0); _currentVAO = 0; } }
640 typedef std::vector<GLushort> IndicesGLushort;
641 IndicesGLushort _quadIndicesGLushort[4];
643 typedef std::vector<GLuint> IndicesGLuint;
644 IndicesGLuint _quadIndicesGLuint[4];
646 void drawQuads(GLint first, GLsizei count, GLsizei primCount=0);
648 inline void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
650 if (primcount>=1 && _glDrawArraysInstanced!=0) _glDrawArraysInstanced(mode, first, count, primcount);
651 else glDrawArrays(mode, first, count);
654 inline void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount )
656 if (primcount>=1 && _glDrawElementsInstanced!=0) _glDrawElementsInstanced(mode, count, type, indices, primcount);
657 else glDrawElements(mode, count, type, indices);
661 inline void Vertex(float x, float y, float z, float w=1.0f)
663 #if defined(OSG_GL_VERTEX_FUNCS_AVAILABLE) && !defined(OSG_GLES1_AVAILABLE)
664 if (_useVertexAttributeAliasing) _glVertexAttrib4f( _vertexAlias._location, x,y,z,w);
665 else glVertex4f(x,y,z,w);
667 _glVertexAttrib4f( _vertexAlias._location, x,y,z,w);
671 inline void Color(float r, float g, float b, float a=1.0f)
673 #ifdef OSG_GL_VERTEX_FUNCS_AVAILABLE
674 if (_useVertexAttributeAliasing) _glVertexAttrib4f( _colorAlias._location, r,g,b,a);
675 else glColor4f(r,g,b,a);
677 _glVertexAttrib4f( _colorAlias._location, r,g,b,a);
681 void Normal(float x, float y, float z)
683 #ifdef OSG_GL_VERTEX_FUNCS_AVAILABLE
684 if (_useVertexAttributeAliasing) _glVertexAttrib4f( _normalAlias._location, x,y,z,0.0);
685 else glNormal3f(x,y,z);
687 _glVertexAttrib4f( _normalAlias._location, x,y,z,0.0);
691 void TexCoord(float x, float y=0.0f, float z=0.0f, float w=1.0f)
693 #if !defined(OSG_GLES1_AVAILABLE)
694 #ifdef OSG_GL_VERTEX_FUNCS_AVAILABLE
695 if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[0]._location, x,y,z,w);
696 else glTexCoord4f(x,y,z,w);
698 _glVertexAttrib4f( _texCoordAliasList[0]._location, x,y,z,w);
703 void MultiTexCoord(unsigned int unit, float x, float y=0.0f, float z=0.0f, float w=1.0f)
705 #if !defined(OSG_GLES1_AVAILABLE)
706 #ifdef OSG_GL_VERTEX_FUNCS_AVAILABLE
707 if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[unit]._location, x,y,z,w);
708 else _glMultiTexCoord4f(GL_TEXTURE0+unit,x,y,z,w);
710 _glVertexAttrib4f( _texCoordAliasList[unit]._location, x,y,z,w);
715 void VerteAttrib(unsigned int location, float x, float y=0.0f, float z=0.0f, float w=0.0f)
717 _glVertexAttrib4f( location, x,y,z,w);
721 /** Wrapper around glInterleavedArrays(..).
722 * also resets the internal array points and modes within osg::State to keep the other
723 * vertex array operations consistent. */
724 void setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer) { _vas->setInterleavedArrays( *this, format, stride, pointer); }
726 /** Set the vertex pointer using an osg::Array, and manage any VBO that are required.*/
727 inline void setVertexPointer(const Array* array) { _vas->setVertexArray(*this, array); }
728 inline void setVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE) { _vas->setVertexArray( *this, size, type, stride, ptr, normalized); }
729 inline void disableVertexPointer() { _vas->disableVertexArray(*this); }
732 inline void setNormalPointer(const Array* array) { _vas->setNormalArray(*this, array); }
733 inline void setNormalPointer( GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE ) { _vas->setNormalArray( *this, type, stride, ptr, normalized); }
734 inline void disableNormalPointer() { _vas->disableNormalArray(*this); }
736 inline void setColorPointer(const Array* array) { _vas->setColorArray(*this, array); }
737 inline void setColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_TRUE ) { _vas->setColorArray(*this, size, type, stride, ptr, normalized); }
738 inline void disableColorPointer() { _vas->disableColorArray(*this); }
740 inline bool isSecondaryColorSupported() const { return _isSecondaryColorSupported; }
741 inline void setSecondaryColorPointer(const Array* array) { _vas->setSecondaryColorArray(*this, array); }
742 inline void disableSecondaryColorPointer() { _vas->disableSecondaryColorArray(*this); }
744 inline bool isFogCoordSupported() const { return _isFogCoordSupported; }
745 inline void setFogCoordPointer(const Array* array) { _vas->setFogCoordArray(*this, array); }
746 inline void disableFogCoordPointer() { _vas->disableFogCoordArray(*this); }
749 inline void setTexCoordPointer(unsigned int unit, const Array* array) { _vas->setTexCoordArray(*this, unit, array); }
750 inline void setTexCoordPointer( unsigned int unit, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE ) { _vas->setTexCoordArray(*this, unit, size, type, stride, ptr, normalized); }
751 inline void disableTexCoordPointer( unsigned int unit ) { _vas->disableTexCoordArray(*this, unit); }
752 inline void disableTexCoordPointersAboveAndIncluding( unsigned int unit ) { _vas->disableTexCoordArrayAboveAndIncluding(*this, unit); }
754 /// For GL>=2.0 uses GL_MAX_TEXTURE_COORDS, for GL<2 uses GL_MAX_TEXTURE_UNITS
755 inline GLint getMaxTextureCoords() const { return _glMaxTextureCoords; }
757 /// For GL>=2.0 uses GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, for GL<2 uses GL_MAX_TEXTURE_UNITS
758 inline GLint getMaxTextureUnits() const { return _glMaxTextureUnits; }
761 /** Set the current texture unit, return true if selected,
762 * false if selection failed such as when multi texturing is not supported.
763 * note, only updates values that change.*/
764 inline bool setActiveTextureUnit( unsigned int unit );
766 /** Get the current texture unit.*/
767 unsigned int getActiveTextureUnit() const { return _currentActiveTextureUnit; }
769 /** Set the current tex coord array texture unit, return true if selected,
770 * false if selection failed such as when multi texturing is not supported.
771 * note, only updates values that change.*/
772 bool setClientActiveTextureUnit( unsigned int unit );
774 /** Get the current tex coord array texture unit.*/
775 unsigned int getClientActiveTextureUnit() const;
777 inline void setVertexAttribPointer(unsigned int unit, const Array* array) { _vas->setVertexAttribArray(*this, unit, array); }
778 inline void setVertexAttribLPointer(unsigned int unit, const Array* array) { _vas->setVertexAttribArray(*this, unit, array); }
779 inline void setVertexAttribIPointer(unsigned int unit, const Array* array) { _vas->setVertexAttribArray(*this, unit, array); }
781 inline void disableVertexAttribPointer( unsigned int index ) { _vas->disableVertexAttribArray(*this, index); }
782 inline void disableVertexAttribPointersAboveAndIncluding( unsigned int index ) { _vas->disableVertexAttribArray(*this, index); }
785 /** dirty the vertex, normal, color, tex coords, secondary color, fog coord and index arrays.*/
786 void dirtyAllVertexArrays();
789 inline bool isVertexBufferObjectSupported() const { return _isVertexBufferObjectSupported; }
790 inline bool useVertexBufferObject(bool useVBO) const { return _forceVertexBufferObject || (_isVertexBufferObjectSupported && useVBO); }
792 inline bool isVertexArrayObjectSupported() const { return _isVertexArrayObjectSupported; }
793 inline bool useVertexArrayObject(bool useVAO) const { return _forceVertexArrayObject || (_isVertexArrayObjectSupported && useVAO); }
796 inline void setLastAppliedProgramObject(const Program::PerContextProgram* program)
798 if (_lastAppliedProgramObject!=program)
800 _lastAppliedProgramObject = program;
803 inline const Program::PerContextProgram* getLastAppliedProgramObject() const { return _lastAppliedProgramObject; }
805 inline GLint getUniformLocation( unsigned int uniformNameID ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getUniformLocation(uniformNameID) : -1; }
807 * Alternative version of getUniformLocation( unsigned int uniformNameID )
808 * retrofited into OSG for backward compatibility with osgCal,
809 * after uniform ids were refactored from std::strings to GLints in OSG version 2.9.10.
811 * Drawbacks: This method is not particularly fast. It has to access mutexed static
812 * map of uniform ids. So don't overuse it or your app performance will suffer.
814 inline GLint getUniformLocation( const std::string & uniformName ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getUniformLocation(uniformName) : -1; }
815 inline GLint getAttribLocation( const std::string& name ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getAttribLocation(name) : -1; }
817 typedef std::pair<const StateAttribute*,StateAttribute::OverrideValue> AttributePair;
818 typedef std::vector<AttributePair> AttributeVec;
820 AttributeVec& getAttributeVec( const osg::StateAttribute* attribute )
822 AttributeStack& as = _attributeMap[ attribute->getTypeMemberPair() ];
823 return as.attributeVec;
826 /** Set the frame stamp for the current frame.*/
827 inline void setFrameStamp(FrameStamp* fs) { _frameStamp = fs; }
829 /** Get the frame stamp for the current frame.*/
830 inline FrameStamp* getFrameStamp() { return _frameStamp.get(); }
832 /** Get the const frame stamp for the current frame.*/
833 inline const FrameStamp* getFrameStamp() const { return _frameStamp.get(); }
836 /** Set the DisplaySettings. Note, nothing is applied, the visual settings are just
837 * used in the State object to pass the current visual settings to Drawables
838 * during rendering. */
839 inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; }
841 /** Get the const DisplaySettings */
842 inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); }
844 /** Get the DisplaySettings that is current active DisplaySettings to be used by osg::State, - if DisplaySettings is not directly assigned then fallback to DisplaySettings::instance(). */
845 inline DisplaySettings* getActiveDisplaySettings() { return _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get(); }
847 /** Get the const DisplaySettings that is current active DisplaySettings to be used by osg::State, - if DisplaySettings is not directly assigned then fallback to DisplaySettings::instance(). */
848 inline const DisplaySettings* getActiveDisplaySettings() const { return _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get(); }
851 /** Set flag for early termination of the draw traversal.*/
852 void setAbortRenderingPtr(bool* abortPtr) { _abortRenderingPtr = abortPtr; }
854 /** Get flag for early termination of the draw traversal,
855 * if true steps should be taken to complete rendering early.*/
856 bool getAbortRendering() const { return _abortRenderingPtr!=0?(*_abortRenderingPtr):false; }
859 struct DynamicObjectRenderingCompletedCallback : public osg::Referenced
861 virtual void completed(osg::State*) = 0;
864 /** Set the callback to be called when the dynamic object count hits 0.*/
865 void setDynamicObjectRenderingCompletedCallback(DynamicObjectRenderingCompletedCallback* cb){ _completeDynamicObjectRenderingCallback = cb; }
867 /** Get the callback to be called when the dynamic object count hits 0.*/
868 DynamicObjectRenderingCompletedCallback* getDynamicObjectRenderingCompletedCallback() { return _completeDynamicObjectRenderingCallback.get(); }
870 /** Set the number of dynamic objects that will be rendered in this graphics context this frame.*/
871 void setDynamicObjectCount(unsigned int count, bool callCallbackOnZero = false)
873 if (_dynamicObjectCount != count)
875 _dynamicObjectCount = count;
876 if (_dynamicObjectCount==0 && callCallbackOnZero && _completeDynamicObjectRenderingCallback.valid())
878 _completeDynamicObjectRenderingCallback->completed(this);
883 /** Get the number of dynamic objects that will be rendered in this graphics context this frame.*/
884 unsigned int getDynamicObjectCount() const { return _dynamicObjectCount; }
886 /** Decrement the number of dynamic objects left to render this frame, and once the count goes to zero call the
887 * DynamicObjectRenderingCompletedCallback to inform of completion.*/
888 inline void decrementDynamicObjectCount()
890 --_dynamicObjectCount;
891 if (_dynamicObjectCount==0 && _completeDynamicObjectRenderingCallback.valid())
893 _completeDynamicObjectRenderingCallback->completed(this);
897 void setMaxTexturePoolSize(unsigned int size);
898 unsigned int getMaxTexturePoolSize() const { return _maxTexturePoolSize; }
900 void setMaxBufferObjectPoolSize(unsigned int size);
901 unsigned int getMaxBufferObjectPoolSize() const { return _maxBufferObjectPoolSize; }
904 enum CheckForGLErrors
906 /** NEVER_CHECK_GL_ERRORS hints that OpenGL need not be checked for, this
907 is the fastest option since checking for errors does incur a small overhead.*/
908 NEVER_CHECK_GL_ERRORS,
909 /** ONCE_PER_FRAME means that OpenGL errors will be checked for once per
910 frame, the overhead is still small, but at least OpenGL errors that are occurring
911 will be caught, the reporting isn't fine grained enough for debugging purposes.*/
913 /** ONCE_PER_ATTRIBUTE means that OpenGL errors will be checked for after
914 every attribute is applied, allow errors to be directly associated with
915 particular operations which makes debugging much easier.*/
919 /** Set whether and how often OpenGL errors should be checked for.*/
920 void setCheckForGLErrors(CheckForGLErrors check) { _checkGLErrors = check; }
922 /** Get whether and how often OpenGL errors should be checked for.*/
923 CheckForGLErrors getCheckForGLErrors() const { return _checkGLErrors; }
925 bool checkGLErrors(const char* str1=0, const char* str2=0) const;
926 bool checkGLErrors(StateAttribute::GLMode mode) const;
927 bool checkGLErrors(const StateAttribute* attribute) const;
929 /** print out the internal details of osg::State - useful for debugging.*/
930 void print(std::ostream& fout) const;
932 /** Initialize extension used by osg::State.*/
933 void initializeExtensionProcs();
935 /** Get the helper class for dispatching osg::Arrays as OpenGL attribute data.*/
936 inline AttributeDispatchers& getAttributeDispatchers() { return _arrayDispatchers; }
939 /** Set the helper class that provides applications with estimate on how much different graphics operations will cost.*/
940 inline void setGraphicsCostEstimator(GraphicsCostEstimator* gce) { _graphicsCostEstimator = gce; }
942 /** Get the helper class that provides applications with estimate on how much different graphics operations will cost.*/
943 inline GraphicsCostEstimator* getGraphicsCostEstimator() { return _graphicsCostEstimator.get(); }
945 /** Get the cont helper class that provides applications with estimate on how much different graphics operations will cost.*/
946 inline const GraphicsCostEstimator* getGraphicsCostEstimator() const { return _graphicsCostEstimator.get(); }
950 /** Support for synchronizing the system time and the timestamp
951 * counter available with ARB_timer_query. Note that State
952 * doesn't update these values itself.
954 Timer_t getStartTick() const { return _startTick; }
955 void setStartTick(Timer_t tick) { _startTick = tick; }
956 Timer_t getGpuTick() const { return _gpuTick; }
958 double getGpuTime() const
960 return osg::Timer::instance()->delta_s(_startTick, _gpuTick);
962 GLuint64 getGpuTimestamp() const { return _gpuTimestamp; }
964 void setGpuTimestamp(Timer_t tick, GLuint64 timestamp)
967 _gpuTimestamp = timestamp;
969 int getTimestampBits() const { return _timestampBits; }
970 void setTimestampBits(int bits) { _timestampBits = bits; }
972 /** called by the GraphicsContext just before GraphicsContext::swapBuffersImplementation().*/
973 virtual void frameCompleted();
978 typedef std::vector<StateAttribute::GLModeValue> ValueVec;
984 last_applied_value = false;
985 global_default_value = false;
988 void print(std::ostream& fout) const;
992 bool last_applied_value;
993 bool global_default_value;
997 struct AttributeStack
1002 last_applied_attribute = 0L;
1003 last_applied_shadercomponent = 0L;
1004 global_default_attribute = 0L;
1008 void print(std::ostream& fout) const;
1010 /** apply an attribute if required, passing in attribute and appropriate attribute stack */
1012 const StateAttribute* last_applied_attribute;
1013 const ShaderComponent* last_applied_shadercomponent;
1014 ref_ptr<const StateAttribute> global_default_attribute;
1015 AttributeVec attributeVec;
1021 typedef std::pair<const Uniform*,StateAttribute::OverrideValue> UniformPair;
1022 typedef std::vector<UniformPair> UniformVec;
1026 void print(std::ostream& fout) const;
1028 UniformVec uniformVec;
1033 typedef std::vector<StateSet::DefinePair> DefineVec;
1038 void print(std::ostream& fout) const;
1041 DefineVec defineVec;
1049 typedef std::map<std::string, DefineStack> DefineStackMap;
1052 StateSet::DefineList currentDefines;
1054 bool updateCurrentDefines();
1058 typedef std::map<StateAttribute::GLMode,ModeStack> ModeMap;
1059 typedef std::vector<ModeMap> TextureModeMapList;
1061 typedef std::map<StateAttribute::TypeMemberPair,AttributeStack> AttributeMap;
1062 typedef std::vector<AttributeMap> TextureAttributeMapList;
1064 typedef std::map<std::string, UniformStack> UniformMap;
1067 typedef std::vector< ref_ptr<const Matrix> > MatrixStack;
1069 inline const ModeMap& getModeMap() const {return _modeMap;}
1070 inline const AttributeMap& getAttributeMap() const {return _attributeMap;}
1071 inline const UniformMap& getUniformMap() const {return _uniformMap;}
1072 inline DefineMap& getDefineMap() {return _defineMap;}
1073 inline const DefineMap& getDefineMap() const {return _defineMap;}
1074 inline const TextureModeMapList& getTextureModeMapList() const {return _textureModeMapList;}
1075 inline const TextureAttributeMapList& getTextureAttributeMapList() const {return _textureAttributeMapList;}
1077 std::string getDefineString(const osg::ShaderDefines& shaderDefines);
1078 bool supportsShaderRequirements(const osg::ShaderDefines& shaderRequirements);
1079 bool supportsShaderRequirement(const std::string& shaderRequirement);
1085 GraphicsContext* _graphicsContext;
1086 unsigned int _contextID;
1088 osg::ref_ptr<VertexArrayState> _globalVertexArrayState;
1089 VertexArrayState* _vas;
1091 bool _shaderCompositionEnabled;
1092 bool _shaderCompositionDirty;
1093 osg::ref_ptr<ShaderComposer> _shaderComposer;
1094 osg::Program* _currentShaderCompositionProgram;
1095 StateSet::UniformList _currentShaderCompositionUniformList;
1097 ref_ptr<FrameStamp> _frameStamp;
1102 ref_ptr<const RefMatrix> _identity;
1103 ref_ptr<const RefMatrix> _initialViewMatrix;
1104 ref_ptr<const RefMatrix> _projection;
1105 ref_ptr<const RefMatrix> _modelView;
1106 ref_ptr<RefMatrix> _modelViewCache;
1108 bool _useModelViewAndProjectionUniforms;
1109 ref_ptr<Uniform> _modelViewMatrixUniform;
1110 ref_ptr<Uniform> _projectionMatrixUniform;
1111 ref_ptr<Uniform> _modelViewProjectionMatrixUniform;
1112 ref_ptr<Uniform> _normalMatrixUniform;
1114 Matrix _initialInverseViewMatrix;
1116 ref_ptr<DisplaySettings> _displaySettings;
1118 bool* _abortRenderingPtr;
1119 CheckForGLErrors _checkGLErrors;
1122 bool _useVertexAttributeAliasing;
1123 VertexAttribAlias _vertexAlias;
1124 VertexAttribAlias _normalAlias;
1125 VertexAttribAlias _colorAlias;
1126 VertexAttribAlias _secondaryColorAlias;
1127 VertexAttribAlias _fogCoordAlias;
1128 VertexAttribAliasList _texCoordAliasList;
1130 Program::AttribBindingList _attributeBindingList;
1132 void setUpVertexAttribAlias(VertexAttribAlias& alias, GLuint location, const std::string glName, const std::string osgName, const std::string& declaration);
1134 /** Apply an OpenGL mode if required, passing in mode, enable flag and
1135 * appropriate mode stack. This is a wrapper around \c glEnable() and
1136 * \c glDisable(), that just actually calls these functions if the
1137 * \c enabled flag is different than the current state.
1138 * @return \c true if the state was actually changed. \c false
1139 * otherwise. Notice that a \c false return does not indicate
1140 * an error, it just means that the mode was already set to the
1141 * same value as the \c enabled parameter.
1143 inline bool applyMode(StateAttribute::GLMode mode,bool enabled,ModeStack& ms)
1145 if (ms.valid && ms.last_applied_value != enabled)
1147 ms.last_applied_value = enabled;
1149 if (enabled) glEnable(mode);
1150 else glDisable(mode);
1152 if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(mode);
1160 inline bool applyModeOnTexUnit(unsigned int unit,StateAttribute::GLMode mode,bool enabled,ModeStack& ms)
1162 if (ms.valid && ms.last_applied_value != enabled)
1164 if (setActiveTextureUnit(unit))
1166 ms.last_applied_value = enabled;
1168 if (enabled) glEnable(mode);
1169 else glDisable(mode);
1171 if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(mode);
1182 /** apply an attribute if required, passing in attribute and appropriate attribute stack */
1183 inline bool applyAttribute(const StateAttribute* attribute,AttributeStack& as)
1185 if (as.last_applied_attribute != attribute)
1187 if (!as.global_default_attribute.valid()) as.global_default_attribute = attribute->cloneType()->asStateAttribute();
1189 as.last_applied_attribute = attribute;
1190 attribute->apply(*this);
1192 const ShaderComponent* sc = attribute->getShaderComponent();
1193 if (as.last_applied_shadercomponent != sc)
1195 as.last_applied_shadercomponent = sc;
1196 _shaderCompositionDirty = true;
1199 if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(attribute);
1207 inline bool applyAttributeOnTexUnit(unsigned int unit,const StateAttribute* attribute,AttributeStack& as)
1209 if (as.last_applied_attribute != attribute)
1211 if (setActiveTextureUnit(unit))
1213 if (!as.global_default_attribute.valid()) as.global_default_attribute = attribute->cloneType()->asStateAttribute();
1215 as.last_applied_attribute = attribute;
1216 attribute->apply(*this);
1218 const ShaderComponent* sc = attribute->getShaderComponent();
1219 if (as.last_applied_shadercomponent != sc)
1221 as.last_applied_shadercomponent = sc;
1222 _shaderCompositionDirty = true;
1225 if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(attribute);
1237 inline bool applyGlobalDefaultAttribute(AttributeStack& as)
1239 if (as.last_applied_attribute != as.global_default_attribute.get())
1241 as.last_applied_attribute = as.global_default_attribute.get();
1242 if (as.global_default_attribute.valid())
1244 as.global_default_attribute->apply(*this);
1245 const ShaderComponent* sc = as.global_default_attribute->getShaderComponent();
1246 if (as.last_applied_shadercomponent != sc)
1248 as.last_applied_shadercomponent = sc;
1249 _shaderCompositionDirty = true;
1252 if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(as.global_default_attribute.get());
1260 inline bool applyGlobalDefaultAttributeOnTexUnit(unsigned int unit,AttributeStack& as)
1262 if (as.last_applied_attribute != as.global_default_attribute.get())
1264 if (setActiveTextureUnit(unit))
1266 as.last_applied_attribute = as.global_default_attribute.get();
1267 if (as.global_default_attribute.valid())
1269 as.global_default_attribute->apply(*this);
1270 const ShaderComponent* sc = as.global_default_attribute->getShaderComponent();
1271 if (as.last_applied_shadercomponent != sc)
1273 as.last_applied_shadercomponent = sc;
1274 _shaderCompositionDirty = true;
1276 if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(as.global_default_attribute.get());
1288 AttributeMap _attributeMap;
1289 UniformMap _uniformMap;
1290 DefineMap _defineMap;
1292 TextureModeMapList _textureModeMapList;
1293 TextureAttributeMapList _textureAttributeMapList;
1295 const Program::PerContextProgram* _lastAppliedProgramObject;
1297 StateSetStack _stateStateStack;
1299 unsigned int _maxTexturePoolSize;
1300 unsigned int _maxBufferObjectPoolSize;
1303 unsigned int _currentActiveTextureUnit;
1304 unsigned int _currentClientActiveTextureUnit;
1305 GLBufferObject* _currentPBO;
1306 GLBufferObject* _currentDIBO;
1310 inline ModeMap& getOrCreateTextureModeMap(unsigned int unit)
1312 if (unit>=_textureModeMapList.size()) _textureModeMapList.resize(unit+1);
1313 return _textureModeMapList[unit];
1317 inline AttributeMap& getOrCreateTextureAttributeMap(unsigned int unit)
1319 if (unit>=_textureAttributeMapList.size()) _textureAttributeMapList.resize(unit+1);
1320 return _textureAttributeMapList[unit];
1323 inline void pushModeList(ModeMap& modeMap,const StateSet::ModeList& modeList);
1324 inline void pushAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList);
1325 inline void pushUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList);
1326 inline void pushDefineList(DefineMap& defineMap,const StateSet::DefineList& defineList);
1328 inline void popModeList(ModeMap& modeMap,const StateSet::ModeList& modeList);
1329 inline void popAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList);
1330 inline void popUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList);
1331 inline void popDefineList(DefineMap& uniformMap,const StateSet::DefineList& defineList);
1333 inline void applyModeList(ModeMap& modeMap,const StateSet::ModeList& modeList);
1334 inline void applyAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList);
1335 inline void applyUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList);
1336 inline void applyDefineList(DefineMap& uniformMap,const StateSet::DefineList& defineList);
1338 inline void applyModeMap(ModeMap& modeMap);
1339 inline void applyAttributeMap(AttributeMap& attributeMap);
1340 inline void applyUniformMap(UniformMap& uniformMap);
1342 inline void applyModeListOnTexUnit(unsigned int unit,ModeMap& modeMap,const StateSet::ModeList& modeList);
1343 inline void applyAttributeListOnTexUnit(unsigned int unit,AttributeMap& attributeMap,const StateSet::AttributeList& attributeList);
1345 inline void applyModeMapOnTexUnit(unsigned int unit,ModeMap& modeMap);
1346 inline void applyAttributeMapOnTexUnit(unsigned int unit,AttributeMap& attributeMap);
1348 void haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode,StateAttribute::GLModeValue value);
1349 void haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode);
1350 void haveAppliedAttribute(AttributeMap& attributeMap,const StateAttribute* attribute);
1351 void haveAppliedAttribute(AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member);
1352 bool getLastAppliedMode(const ModeMap& modeMap,StateAttribute::GLMode mode) const;
1353 const StateAttribute* getLastAppliedAttribute(const AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member) const;
1355 void loadModelViewMatrix();
1358 bool _isSecondaryColorSupported;
1359 bool _isFogCoordSupported;
1360 bool _isVertexBufferObjectSupported;
1361 bool _isVertexArrayObjectSupported;
1362 bool _forceVertexBufferObject;
1363 bool _forceVertexArrayObject;
1365 typedef void (GL_APIENTRY * ActiveTextureProc) (GLenum texture);
1366 typedef void (GL_APIENTRY * FogCoordPointerProc) (GLenum type, GLsizei stride, const GLvoid *pointer);
1367 typedef void (GL_APIENTRY * SecondaryColorPointerProc) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
1368 typedef void (GL_APIENTRY * MultiTexCoord4fProc) (GLenum target, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
1369 typedef void (GL_APIENTRY * VertexAttrib4fProc)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
1370 typedef void (GL_APIENTRY * VertexAttrib4fvProc)(GLuint index, const GLfloat *v);
1371 typedef void (GL_APIENTRY * VertexAttribPointerProc) (unsigned int, GLint, GLenum, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
1372 typedef void (GL_APIENTRY * VertexAttribIPointerProc) (unsigned int, GLint, GLenum, GLsizei stride, const GLvoid *pointer);
1373 typedef void (GL_APIENTRY * VertexAttribLPointerProc) (unsigned int, GLint, GLenum, GLsizei stride, const GLvoid *pointer);
1374 typedef void (GL_APIENTRY * EnableVertexAttribProc) (unsigned int);
1375 typedef void (GL_APIENTRY * DisableVertexAttribProc) (unsigned int);
1376 typedef void (GL_APIENTRY * BindBufferProc) (GLenum target, GLuint buffer);
1378 typedef void (GL_APIENTRY * DrawArraysInstancedProc)( GLenum mode, GLint first, GLsizei count, GLsizei primcount );
1379 typedef void (GL_APIENTRY * DrawElementsInstancedProc)( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount );
1381 bool _extensionProcsInitialized;
1382 GLint _glMaxTextureCoords;
1383 GLint _glMaxTextureUnits;
1384 ActiveTextureProc _glClientActiveTexture;
1385 ActiveTextureProc _glActiveTexture;
1386 MultiTexCoord4fProc _glMultiTexCoord4f;
1387 VertexAttrib4fProc _glVertexAttrib4f;
1388 VertexAttrib4fvProc _glVertexAttrib4fv;
1389 FogCoordPointerProc _glFogCoordPointer;
1390 SecondaryColorPointerProc _glSecondaryColorPointer;
1391 VertexAttribPointerProc _glVertexAttribPointer;
1392 VertexAttribIPointerProc _glVertexAttribIPointer;
1393 VertexAttribLPointerProc _glVertexAttribLPointer;
1394 EnableVertexAttribProc _glEnableVertexAttribArray;
1395 DisableVertexAttribProc _glDisableVertexAttribArray;
1396 BindBufferProc _glBindBuffer;
1397 DrawArraysInstancedProc _glDrawArraysInstanced;
1398 DrawElementsInstancedProc _glDrawElementsInstanced;
1400 osg::ref_ptr<GLExtensions> _glExtensions;
1402 unsigned int _dynamicObjectCount;
1403 osg::ref_ptr<DynamicObjectRenderingCompletedCallback> _completeDynamicObjectRenderingCallback;
1405 AttributeDispatchers _arrayDispatchers;
1407 osg::ref_ptr<GraphicsCostEstimator> _graphicsCostEstimator;
1411 GLuint64 _gpuTimestamp;
1415inline void State::pushModeList(ModeMap& modeMap,const StateSet::ModeList& modeList)
1417 for(StateSet::ModeList::const_iterator mitr=modeList.begin();
1418 mitr!=modeList.end();
1421 // get the mode stack for incoming GLmode {mitr->first}.
1422 ModeStack& ms = modeMap[mitr->first];
1423 if (ms.valueVec.empty())
1425 // first pair so simply push incoming pair to back.
1426 ms.valueVec.push_back(mitr->second);
1428 else if ((ms.valueVec.back() & StateAttribute::OVERRIDE) && !(mitr->second & StateAttribute::PROTECTED)) // check the existing override flag
1430 // push existing back since override keeps the previous value.
1431 ms.valueVec.push_back(ms.valueVec.back());
1435 // no override on so simply push incoming pair to back.
1436 ms.valueVec.push_back(mitr->second);
1442inline void State::pushAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
1444 for(StateSet::AttributeList::const_iterator aitr=attributeList.begin();
1445 aitr!=attributeList.end();
1448 // get the attribute stack for incoming type {aitr->first}.
1449 AttributeStack& as = attributeMap[aitr->first];
1450 if (as.attributeVec.empty())
1452 // first pair so simply push incoming pair to back.
1453 as.attributeVec.push_back(
1454 AttributePair(aitr->second.first.get(),aitr->second.second));
1456 else if ((as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(aitr->second.second & StateAttribute::PROTECTED)) // check the existing override flag
1458 // push existing back since override keeps the previous value.
1459 as.attributeVec.push_back(as.attributeVec.back());
1463 // no override on so simply push incoming pair to back.
1464 as.attributeVec.push_back(
1465 AttributePair(aitr->second.first.get(),aitr->second.second));
1472inline void State::pushUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)
1474 for(StateSet::UniformList::const_iterator aitr=uniformList.begin();
1475 aitr!=uniformList.end();
1478 // get the attribute stack for incoming type {aitr->first}.
1479 UniformStack& us = uniformMap[aitr->first];
1480 if (us.uniformVec.empty())
1482 // first pair so simply push incoming pair to back.
1483 us.uniformVec.push_back(
1484 UniformStack::UniformPair(aitr->second.first.get(),aitr->second.second));
1486 else if ((us.uniformVec.back().second & StateAttribute::OVERRIDE) && !(aitr->second.second & StateAttribute::PROTECTED)) // check the existing override flag
1488 // push existing back since override keeps the previous value.
1489 us.uniformVec.push_back(us.uniformVec.back());
1493 // no override on so simply push incoming pair to back.
1494 us.uniformVec.push_back(
1495 UniformStack::UniformPair(aitr->second.first.get(),aitr->second.second));
1500inline void State::pushDefineList(DefineMap& defineMap,const StateSet::DefineList& defineList)
1502 for(StateSet::DefineList::const_iterator aitr=defineList.begin();
1503 aitr!=defineList.end();
1506 // get the attribute stack for incoming type {aitr->first}.
1507 DefineStack& ds = defineMap.map[aitr->first];
1508 DefineStack::DefineVec& dv = ds.defineVec;
1511 // first pair so simply push incoming pair to back.
1512 dv.push_back(StateSet::DefinePair(aitr->second.first,aitr->second.second));
1515 defineMap.changed = true;
1517 else if ((ds.defineVec.back().second & StateAttribute::OVERRIDE) && !(aitr->second.second & StateAttribute::PROTECTED)) // check the existing override flag
1519 // push existing back since override keeps the previous value.
1520 ds.defineVec.push_back(ds.defineVec.back());
1524 // no override on so simply push incoming pair to back.
1525 dv.push_back(StateSet::DefinePair(aitr->second.first,aitr->second.second));
1527 // if the back of the stack has changed since the last then mark it as changed.
1528 bool changed = (dv[dv.size()-2] != dv.back());
1532 defineMap.changed = true;
1538inline void State::popModeList(ModeMap& modeMap,const StateSet::ModeList& modeList)
1540 for(StateSet::ModeList::const_iterator mitr=modeList.begin();
1541 mitr!=modeList.end();
1544 // get the mode stack for incoming GLmode {mitr->first}.
1545 ModeStack& ms = modeMap[mitr->first];
1546 if (!ms.valueVec.empty())
1548 ms.valueVec.pop_back();
1554inline void State::popAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
1556 for(StateSet::AttributeList::const_iterator aitr=attributeList.begin();
1557 aitr!=attributeList.end();
1560 // get the attribute stack for incoming type {aitr->first}.
1561 AttributeStack& as = attributeMap[aitr->first];
1562 if (!as.attributeVec.empty())
1564 as.attributeVec.pop_back();
1570inline void State::popUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)
1572 for(StateSet::UniformList::const_iterator aitr=uniformList.begin();
1573 aitr!=uniformList.end();
1576 // get the attribute stack for incoming type {aitr->first}.
1577 UniformStack& us = uniformMap[aitr->first];
1578 if (!us.uniformVec.empty())
1580 us.uniformVec.pop_back();
1585inline void State::popDefineList(DefineMap& defineMap,const StateSet::DefineList& defineList)
1587 for(StateSet::DefineList::const_iterator aitr=defineList.begin();
1588 aitr!=defineList.end();
1591 // get the attribute stack for incoming type {aitr->first}.
1592 DefineStack& ds = defineMap.map[aitr->first];
1593 DefineStack::DefineVec& dv = ds.defineVec;
1596 // if the stack has less than 2 entries or new back vs old back are different then mark the DefineStack as changed
1597 if ((dv.size() < 2) || (dv[dv.size()-2] != dv.back()))
1600 defineMap.changed = true;
1607inline void State::applyModeList(ModeMap& modeMap,const StateSet::ModeList& modeList)
1609 StateSet::ModeList::const_iterator ds_mitr = modeList.begin();
1610 ModeMap::iterator this_mitr=modeMap.begin();
1612 while (this_mitr!=modeMap.end() && ds_mitr!=modeList.end())
1614 if (this_mitr->first<ds_mitr->first)
1617 // note GLMode = this_mitr->first
1618 ModeStack& ms = this_mitr->second;
1622 if (!ms.valueVec.empty())
1624 bool new_value = ms.valueVec.back() & StateAttribute::ON;
1625 applyMode(this_mitr->first,new_value,ms);
1629 // assume default of disabled.
1630 applyMode(this_mitr->first,ms.global_default_value,ms);
1639 else if (ds_mitr->first<this_mitr->first)
1642 // ds_mitr->first is a new mode, therefore
1643 // need to insert a new mode entry for ds_mistr->first.
1644 ModeStack& ms = modeMap[ds_mitr->first];
1646 bool new_value = ds_mitr->second & StateAttribute::ON;
1647 applyMode(ds_mitr->first,new_value,ms);
1649 // will need to disable this mode on next apply so set it to changed.
1657 // this_mitr & ds_mitr refer to the same mode, check the override
1658 // if any otherwise just apply the incoming mode.
1660 ModeStack& ms = this_mitr->second;
1662 if (!ms.valueVec.empty() && (ms.valueVec.back() & StateAttribute::OVERRIDE) && !(ds_mitr->second & StateAttribute::PROTECTED))
1664 // override is on, just treat as a normal apply on modes.
1669 bool new_value = ms.valueVec.back() & StateAttribute::ON;
1670 applyMode(this_mitr->first,new_value,ms);
1676 // no override on or no previous entry, therefore consider incoming mode.
1677 bool new_value = ds_mitr->second & StateAttribute::ON;
1678 if (applyMode(ds_mitr->first,new_value,ms))
1689 // iterator over the remaining state modes to apply any previous changes.
1691 this_mitr!=modeMap.end();
1694 // note GLMode = this_mitr->first
1695 ModeStack& ms = this_mitr->second;
1699 if (!ms.valueVec.empty())
1701 bool new_value = ms.valueVec.back() & StateAttribute::ON;
1702 applyMode(this_mitr->first,new_value,ms);
1706 // assume default of disabled.
1707 applyMode(this_mitr->first,ms.global_default_value,ms);
1714 // iterator over the remaining incoming modes to apply any new mode.
1716 ds_mitr!=modeList.end();
1719 ModeStack& ms = modeMap[ds_mitr->first];
1721 bool new_value = ds_mitr->second & StateAttribute::ON;
1722 applyMode(ds_mitr->first,new_value,ms);
1724 // will need to disable this mode on next apply so set it to changed.
1729inline void State::applyModeListOnTexUnit(unsigned int unit,ModeMap& modeMap,const StateSet::ModeList& modeList)
1731 StateSet::ModeList::const_iterator ds_mitr = modeList.begin();
1732 ModeMap::iterator this_mitr=modeMap.begin();
1734 while (this_mitr!=modeMap.end() && ds_mitr!=modeList.end())
1736 if (this_mitr->first<ds_mitr->first)
1739 // note GLMode = this_mitr->first
1740 ModeStack& ms = this_mitr->second;
1744 if (!ms.valueVec.empty())
1746 bool new_value = ms.valueVec.back() & StateAttribute::ON;
1747 applyModeOnTexUnit(unit,this_mitr->first,new_value,ms);
1751 // assume default of disabled.
1752 applyModeOnTexUnit(unit,this_mitr->first,ms.global_default_value,ms);
1761 else if (ds_mitr->first<this_mitr->first)
1764 // ds_mitr->first is a new mode, therefore
1765 // need to insert a new mode entry for ds_mistr->first.
1766 ModeStack& ms = modeMap[ds_mitr->first];
1768 bool new_value = ds_mitr->second & StateAttribute::ON;
1769 applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms);
1771 // will need to disable this mode on next apply so set it to changed.
1779 // this_mitr & ds_mitr refer to the same mode, check the override
1780 // if any otherwise just apply the incoming mode.
1782 ModeStack& ms = this_mitr->second;
1784 if (!ms.valueVec.empty() && (ms.valueVec.back() & StateAttribute::OVERRIDE) && !(ds_mitr->second & StateAttribute::PROTECTED))
1786 // override is on, just treat as a normal apply on modes.
1791 bool new_value = ms.valueVec.back() & StateAttribute::ON;
1792 applyModeOnTexUnit(unit,this_mitr->first,new_value,ms);
1798 // no override on or no previous entry, therefore consider incoming mode.
1799 bool new_value = ds_mitr->second & StateAttribute::ON;
1800 if (applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms))
1811 // iterator over the remaining state modes to apply any previous changes.
1813 this_mitr!=modeMap.end();
1816 // note GLMode = this_mitr->first
1817 ModeStack& ms = this_mitr->second;
1821 if (!ms.valueVec.empty())
1823 bool new_value = ms.valueVec.back() & StateAttribute::ON;
1824 applyModeOnTexUnit(unit,this_mitr->first,new_value,ms);
1828 // assume default of disabled.
1829 applyModeOnTexUnit(unit,this_mitr->first,ms.global_default_value,ms);
1836 // iterator over the remaining incoming modes to apply any new mode.
1838 ds_mitr!=modeList.end();
1841 ModeStack& ms = modeMap[ds_mitr->first];
1843 bool new_value = ds_mitr->second & StateAttribute::ON;
1844 applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms);
1846 // will need to disable this mode on next apply so set it to changed.
1851inline void State::applyAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
1853 StateSet::AttributeList::const_iterator ds_aitr=attributeList.begin();
1855 AttributeMap::iterator this_aitr=attributeMap.begin();
1857 while (this_aitr!=attributeMap.end() && ds_aitr!=attributeList.end())
1859 if (this_aitr->first<ds_aitr->first)
1862 // note attribute type = this_aitr->first
1863 AttributeStack& as = this_aitr->second;
1867 if (!as.attributeVec.empty())
1869 const StateAttribute* new_attr = as.attributeVec.back().first;
1870 applyAttribute(new_attr,as);
1874 applyGlobalDefaultAttribute(as);
1881 else if (ds_aitr->first<this_aitr->first)
1884 // ds_aitr->first is a new attribute, therefore
1885 // need to insert a new attribute entry for ds_aitr->first.
1886 AttributeStack& as = attributeMap[ds_aitr->first];
1888 const StateAttribute* new_attr = ds_aitr->second.first.get();
1889 applyAttribute(new_attr,as);
1898 // this_mitr & ds_mitr refer to the same attribute, check the override
1899 // if any otherwise just apply the incoming attribute
1901 AttributeStack& as = this_aitr->second;
1903 if (!as.attributeVec.empty() && (as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED))
1905 // override is on, just treat as a normal apply on attribute.
1910 const StateAttribute* new_attr = as.attributeVec.back().first;
1911 applyAttribute(new_attr,as);
1916 // no override on or no previous entry, therefore consider incoming attribute.
1917 const StateAttribute* new_attr = ds_aitr->second.first.get();
1918 if (applyAttribute(new_attr,as))
1929 // iterator over the remaining state attributes to apply any previous changes.
1931 this_aitr!=attributeMap.end();
1934 // note attribute type = this_aitr->first
1935 AttributeStack& as = this_aitr->second;
1939 if (!as.attributeVec.empty())
1941 const StateAttribute* new_attr = as.attributeVec.back().first;
1942 applyAttribute(new_attr,as);
1946 applyGlobalDefaultAttribute(as);
1951 // iterator over the remaining incoming attribute to apply any new attribute.
1953 ds_aitr!=attributeList.end();
1956 // ds_aitr->first is a new attribute, therefore
1957 // need to insert a new attribute entry for ds_aitr->first.
1958 AttributeStack& as = attributeMap[ds_aitr->first];
1960 const StateAttribute* new_attr = ds_aitr->second.first.get();
1961 applyAttribute(new_attr,as);
1963 // will need to update this attribute on next apply so set it to changed.
1969inline void State::applyAttributeListOnTexUnit(unsigned int unit,AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
1971 StateSet::AttributeList::const_iterator ds_aitr=attributeList.begin();
1973 AttributeMap::iterator this_aitr=attributeMap.begin();
1975 while (this_aitr!=attributeMap.end() && ds_aitr!=attributeList.end())
1977 if (this_aitr->first<ds_aitr->first)
1980 // note attribute type = this_aitr->first
1981 AttributeStack& as = this_aitr->second;
1985 if (!as.attributeVec.empty())
1987 const StateAttribute* new_attr = as.attributeVec.back().first;
1988 applyAttributeOnTexUnit(unit,new_attr,as);
1992 applyGlobalDefaultAttributeOnTexUnit(unit,as);
1999 else if (ds_aitr->first<this_aitr->first)
2002 // ds_aitr->first is a new attribute, therefore
2003 // need to insert a new attribute entry for ds_aitr->first.
2004 AttributeStack& as = attributeMap[ds_aitr->first];
2006 const StateAttribute* new_attr = ds_aitr->second.first.get();
2007 applyAttributeOnTexUnit(unit,new_attr,as);
2016 // this_mitr & ds_mitr refer to the same attribute, check the override
2017 // if any otherwise just apply the incoming attribute
2019 AttributeStack& as = this_aitr->second;
2021 if (!as.attributeVec.empty() && (as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED))
2023 // override is on, just treat as a normal apply on attribute.
2028 const StateAttribute* new_attr = as.attributeVec.back().first;
2029 applyAttributeOnTexUnit(unit,new_attr,as);
2034 // no override on or no previous entry, therefore consider incoming attribute.
2035 const StateAttribute* new_attr = ds_aitr->second.first.get();
2036 if (applyAttributeOnTexUnit(unit,new_attr,as))
2047 // iterator over the remaining state attributes to apply any previous changes.
2049 this_aitr!=attributeMap.end();
2052 // note attribute type = this_aitr->first
2053 AttributeStack& as = this_aitr->second;
2057 if (!as.attributeVec.empty())
2059 const StateAttribute* new_attr = as.attributeVec.back().first;
2060 applyAttributeOnTexUnit(unit,new_attr,as);
2064 applyGlobalDefaultAttributeOnTexUnit(unit,as);
2069 // iterator over the remaining incoming attribute to apply any new attribute.
2071 ds_aitr!=attributeList.end();
2074 // ds_aitr->first is a new attribute, therefore
2075 // need to insert a new attribute entry for ds_aitr->first.
2076 AttributeStack& as = attributeMap[ds_aitr->first];
2078 const StateAttribute* new_attr = ds_aitr->second.first.get();
2079 applyAttributeOnTexUnit(unit,new_attr,as);
2081 // will need to update this attribute on next apply so set it to changed.
2087inline void State::applyUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)
2089 if (!_lastAppliedProgramObject) return;
2091 StateSet::UniformList::const_iterator ds_aitr=uniformList.begin();
2093 UniformMap::iterator this_aitr=uniformMap.begin();
2095 while (this_aitr!=uniformMap.end() && ds_aitr!=uniformList.end())
2097 if (this_aitr->first<ds_aitr->first)
2099 // note attribute type = this_aitr->first
2100 UniformStack& as = this_aitr->second;
2101 if (!as.uniformVec.empty())
2103 _lastAppliedProgramObject->apply(*as.uniformVec.back().first);
2109 else if (ds_aitr->first<this_aitr->first)
2111 _lastAppliedProgramObject->apply(*(ds_aitr->second.first.get()));
2117 // this_mitr & ds_mitr refer to the same attribute, check the override
2118 // if any otherwise just apply the incoming attribute
2120 UniformStack& as = this_aitr->second;
2122 if (!as.uniformVec.empty() && (as.uniformVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED))
2124 // override is on, just treat as a normal apply on uniform.
2125 _lastAppliedProgramObject->apply(*as.uniformVec.back().first);
2129 // no override on or no previous entry, therefore consider incoming attribute.
2130 _lastAppliedProgramObject->apply(*(ds_aitr->second.first.get()));
2138 // iterator over the remaining state attributes to apply any previous changes.
2140 this_aitr!=uniformMap.end();
2143 // note attribute type = this_aitr->first
2144 UniformStack& as = this_aitr->second;
2145 if (!as.uniformVec.empty())
2147 _lastAppliedProgramObject->apply(*as.uniformVec.back().first);
2151 // iterator over the remaining incoming attribute to apply any new attribute.
2153 ds_aitr!=uniformList.end();
2156 _lastAppliedProgramObject->apply(*(ds_aitr->second.first.get()));
2161inline void State::applyDefineList(DefineMap& defineMap, const StateSet::DefineList& defineList)
2163 StateSet::DefineList::const_iterator dl_itr = defineList.begin();
2164 DefineMap::DefineStackMap::iterator dm_itr = defineMap.map.begin();
2166 defineMap.changed = false;
2167 defineMap.currentDefines.clear();
2169 while (dm_itr!=defineMap.map.end() && dl_itr!=defineList.end())
2171 if (dm_itr->first<dl_itr->first)
2173 DefineStack& ds = dm_itr->second;
2174 DefineStack::DefineVec& dv = ds.defineVec;
2175 if (!dv.empty() && (dv.back().second & StateAttribute::ON)!=0) defineMap.currentDefines[dm_itr->first] = dv.back();
2179 else if (dl_itr->first<dm_itr->first)
2181 if ((dl_itr->second.second & StateAttribute::ON)!=0) defineMap.currentDefines[dl_itr->first] = dl_itr->second;
2187 // this_mitr & ds_mitr refer to the same mode, check the override
2188 // if any otherwise just apply the incoming mode.
2190 DefineStack& ds = dm_itr->second;
2191 DefineStack::DefineVec& dv = ds.defineVec;
2193 if (!dv.empty() && (dv.back().second & StateAttribute::OVERRIDE)!=0 && !(dl_itr->second.second & StateAttribute::PROTECTED))
2195 // override is on, just treat as a normal apply on modes.
2196 if ((dv.back().second & StateAttribute::ON)!=0) defineMap.currentDefines[dm_itr->first] = dv.back();
2200 // no override on or no previous entry, therefore consider incoming mode.
2201 if ((dl_itr->second.second & StateAttribute::ON)!=0) defineMap.currentDefines[dl_itr->first] = dl_itr->second;
2209 // iterator over the remaining state modes to apply any previous changes.
2211 dm_itr!=defineMap.map.end();
2214 // note GLMode = this_mitr->first
2215 DefineStack& ds = dm_itr->second;
2216 DefineStack::DefineVec& dv = ds.defineVec;
2217 if (!dv.empty() && (dv.back().second & StateAttribute::ON)!=0) defineMap.currentDefines[dm_itr->first] = dv.back();
2220 // iterator over the remaining incoming modes to apply any new mode.
2222 dl_itr!=defineList.end();
2225 if ((dl_itr->second.second & StateAttribute::ON)!=0) defineMap.currentDefines[dl_itr->first] = dl_itr->second;
2229inline void State::applyModeMap(ModeMap& modeMap)
2231 for(ModeMap::iterator mitr=modeMap.begin();
2232 mitr!=modeMap.end();
2235 // note GLMode = mitr->first
2236 ModeStack& ms = mitr->second;
2240 if (!ms.valueVec.empty())
2242 bool new_value = ms.valueVec.back() & StateAttribute::ON;
2243 applyMode(mitr->first,new_value,ms);
2247 // assume default of disabled.
2248 applyMode(mitr->first,ms.global_default_value,ms);
2255inline void State::applyModeMapOnTexUnit(unsigned int unit,ModeMap& modeMap)
2257 for(ModeMap::iterator mitr=modeMap.begin();
2258 mitr!=modeMap.end();
2261 // note GLMode = mitr->first
2262 ModeStack& ms = mitr->second;
2266 if (!ms.valueVec.empty())
2268 bool new_value = ms.valueVec.back() & StateAttribute::ON;
2269 applyModeOnTexUnit(unit,mitr->first,new_value,ms);
2273 // assume default of disabled.
2274 applyModeOnTexUnit(unit,mitr->first,ms.global_default_value,ms);
2281inline void State::applyAttributeMap(AttributeMap& attributeMap)
2283 for(AttributeMap::iterator aitr=attributeMap.begin();
2284 aitr!=attributeMap.end();
2287 AttributeStack& as = aitr->second;
2291 if (!as.attributeVec.empty())
2293 const StateAttribute* new_attr = as.attributeVec.back().first;
2294 applyAttribute(new_attr,as);
2298 applyGlobalDefaultAttribute(as);
2305inline void State::applyAttributeMapOnTexUnit(unsigned int unit,AttributeMap& attributeMap)
2307 for(AttributeMap::iterator aitr=attributeMap.begin();
2308 aitr!=attributeMap.end();
2311 AttributeStack& as = aitr->second;
2315 if (!as.attributeVec.empty())
2317 const StateAttribute* new_attr = as.attributeVec.back().first;
2318 applyAttributeOnTexUnit(unit,new_attr,as);
2322 applyGlobalDefaultAttributeOnTexUnit(unit,as);
2329inline void State::applyUniformMap(UniformMap& uniformMap)
2331 if (!_lastAppliedProgramObject) return;
2333 for(UniformMap::iterator aitr=uniformMap.begin();
2334 aitr!=uniformMap.end();
2337 UniformStack& as = aitr->second;
2338 if (!as.uniformVec.empty())
2340 _lastAppliedProgramObject->apply(*as.uniformVec.back().first);
2345inline bool State::setActiveTextureUnit( unsigned int unit )
2347 if (unit!=_currentActiveTextureUnit)
2349 if (_glActiveTexture && unit < (unsigned int)(maximum(_glMaxTextureCoords,_glMaxTextureUnits)) )
2351 _glActiveTexture(GL_TEXTURE0+unit);
2352 _currentActiveTextureUnit = unit;
2364// forward declare speciailization of State::get() method
2365template<> inline GLExtensions* State::get<GLExtensions>() { return _glExtensions.get(); }
2366template<> inline const GLExtensions* State::get<GLExtensions>() const { return _glExtensions.get(); }
2367template<> inline void State::set<GLExtensions>(GLExtensions* ptr) { _glExtensions = ptr; }