2005-04-15 05:41:28 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
2003-01-22 00:45:36 +08:00
*
* This library is open source and may be redistributed and / or modified under
* the terms of the OpenSceneGraph Public License ( OSGPL ) version 0.0 or
* ( at your option ) any later version . The full license is in LICENSE file
* included with this distribution , and on the openscenegraph . org website .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* OpenSceneGraph Public License for more details .
*/
2001-09-20 05:19:47 +08:00
# include <osg/State>
# include <osg/Notify>
2001-10-04 05:44:07 +08:00
# include <osg/GLU>
2003-05-09 21:07:06 +08:00
# include <osg/GLExtensions>
2001-09-20 05:19:47 +08:00
2003-06-24 23:40:09 +08:00
using namespace std ;
2001-09-20 05:19:47 +08:00
using namespace osg ;
State : : State ( )
{
2005-07-20 23:55:07 +08:00
_graphicsContext = 0 ;
2001-09-20 05:19:47 +08:00
_contextID = 0 ;
2003-01-10 17:25:42 +08:00
_identity = new osg : : RefMatrix ( ) ; // default RefMatrix constructs to identity.
2003-07-23 05:03:59 +08:00
_initialViewMatrix = _identity ;
2002-03-30 01:26:40 +08:00
_projection = _identity ;
2002-07-21 06:44:21 +08:00
_modelView = _identity ;
2003-03-11 23:25:49 +08:00
_abortRenderingPtr = false ;
2005-04-30 04:56:20 +08:00
_checkGLErrors = ONCE_PER_FRAME ;
2002-07-21 06:44:21 +08:00
_currentActiveTextureUnit = 0 ;
_currentClientActiveTextureUnit = 0 ;
2002-11-13 19:09:55 +08:00
2003-06-30 05:41:57 +08:00
_isSecondaryColorSupportResolved = false ;
_isSecondaryColorSupported = false ;
2002-11-13 19:09:55 +08:00
_isFogCoordSupportResolved = false ;
_isFogCoordSupported = false ;
2003-06-30 05:41:57 +08:00
_isVertexBufferObjectSupportResolved = false ;
_isVertexBufferObjectSupported = false ;
2005-04-13 20:00:28 +08:00
_lastAppliedProgramObject = 0 ;
2001-09-20 05:19:47 +08:00
}
State : : ~ State ( )
{
}
void State : : reset ( )
{
2005-05-04 05:46:47 +08:00
2001-10-15 22:07:54 +08:00
/*
for ( ModeMap : : iterator mitr = _modeMap . begin ( ) ;
mitr ! = _modeMap . end ( ) ;
+ + mitr )
{
ModeStack & ms = mitr - > second ;
ms . valueVec . clear ( ) ;
ms . last_applied_value = ! ms . global_default_value ;
ms . changed = true ;
}
*/
2001-09-20 05:19:47 +08:00
_modeMap . clear ( ) ;
2001-10-15 22:07:54 +08:00
_modeMap [ GL_DEPTH_TEST ] . global_default_value = true ;
2002-04-22 06:05:26 +08:00
_modeMap [ GL_DEPTH_TEST ] . changed = true ;
2002-07-09 17:35:42 +08:00
// go through all active StateAttribute's, setting to change to force update,
// the idea is to leave only the global defaults left.
2001-10-15 22:07:54 +08:00
for ( AttributeMap : : iterator aitr = _attributeMap . begin ( ) ;
aitr ! = _attributeMap . end ( ) ;
+ + aitr )
{
AttributeStack & as = aitr - > second ;
as . attributeVec . clear ( ) ;
as . last_applied_attribute = NULL ;
as . changed = true ;
2002-07-09 17:35:42 +08:00
}
// we can do a straight clear, we arn't intrested in GL_DEPTH_TEST defaults in texture modes.
for ( TextureModeMapList : : iterator tmmItr = _textureModeMapList . begin ( ) ;
tmmItr ! = _textureModeMapList . end ( ) ;
+ + tmmItr )
{
tmmItr - > clear ( ) ;
}
2001-10-15 22:07:54 +08:00
2002-07-09 17:35:42 +08:00
// empty all the texture attributes as per normal attributes, leaving only the global defaults left.
for ( TextureAttributeMapList : : iterator tamItr = _textureAttributeMapList . begin ( ) ;
tamItr ! = _textureAttributeMapList . end ( ) ;
+ + tamItr )
{
AttributeMap & attributeMap = * tamItr ;
// go through all active StateAttribute's, setting to change to force update.
for ( AttributeMap : : iterator aitr = attributeMap . begin ( ) ;
aitr ! = attributeMap . end ( ) ;
+ + aitr )
{
AttributeStack & as = aitr - > second ;
as . attributeVec . clear ( ) ;
as . last_applied_attribute = NULL ;
as . changed = true ;
}
}
2001-10-15 22:07:54 +08:00
2005-04-13 20:00:28 +08:00
_stateStateStack . clear ( ) ;
2002-03-30 01:26:40 +08:00
_modelView = _identity ;
_projection = _identity ;
2002-09-28 15:47:10 +08:00
dirtyAllVertexArrays ( ) ;
2002-10-01 02:11:34 +08:00
setActiveTextureUnit ( 0 ) ;
2005-04-13 20:00:28 +08:00
_lastAppliedProgramObject = 0 ;
2005-05-04 05:46:47 +08:00
for ( AppliedProgramObjectSet : : iterator apitr = _appliedProgramObjectSet . begin ( ) ;
apitr ! = _appliedProgramObjectSet . end ( ) ;
+ + apitr )
{
2005-05-06 17:58:49 +08:00
( * apitr ) - > resetAppliedUniforms ( ) ;
2005-05-04 05:46:47 +08:00
}
_appliedProgramObjectSet . clear ( ) ;
2005-04-13 20:00:28 +08:00
// what about uniforms??? need to clear them too...
// go through all active Unfirom's, setting to change to force update,
// the idea is to leave only the global defaults left.
for ( UniformMap : : iterator uitr = _uniformMap . begin ( ) ;
uitr ! = _uniformMap . end ( ) ;
+ + uitr )
{
UniformStack & us = uitr - > second ;
us . uniformVec . clear ( ) ;
}
2001-09-20 05:19:47 +08:00
}
2003-08-25 21:06:15 +08:00
void State : : setInitialViewMatrix ( const osg : : RefMatrix * matrix )
{
if ( matrix ) _initialViewMatrix = matrix ;
else _initialViewMatrix = _identity ;
_initialInverseViewMatrix . invert ( * _initialViewMatrix ) ;
}
2001-09-20 05:19:47 +08:00
void State : : pushStateSet ( const StateSet * dstate )
{
2005-04-13 20:00:28 +08:00
_stateStateStack . push_back ( dstate ) ;
2001-09-20 05:19:47 +08:00
if ( dstate )
{
2002-07-09 17:35:42 +08:00
pushModeList ( _modeMap , dstate - > getModeList ( ) ) ;
// iterator through texture modes.
unsigned int unit ;
const StateSet : : TextureModeList & ds_textureModeList = dstate - > getTextureModeList ( ) ;
for ( unit = 0 ; unit < ds_textureModeList . size ( ) ; + + unit )
2002-01-23 20:04:53 +08:00
{
2002-07-09 17:35:42 +08:00
pushModeList ( getOrCreateTextureModeMap ( unit ) , ds_textureModeList [ unit ] ) ;
2002-01-23 20:04:53 +08:00
}
2002-07-09 17:35:42 +08:00
pushAttributeList ( _attributeMap , dstate - > getAttributeList ( ) ) ;
// iterator through texture attributes.
const StateSet : : TextureAttributeList & ds_textureAttributeList = dstate - > getTextureAttributeList ( ) ;
for ( unit = 0 ; unit < ds_textureAttributeList . size ( ) ; + + unit )
2001-09-20 05:19:47 +08:00
{
2002-07-09 17:35:42 +08:00
pushAttributeList ( getOrCreateTextureAttributeMap ( unit ) , ds_textureAttributeList [ unit ] ) ;
2001-09-20 05:19:47 +08:00
}
2005-05-10 21:56:05 +08:00
pushUniformList ( _uniformMap , dstate - > getUniformList ( ) ) ;
2002-01-17 05:23:29 +08:00
}
}
2003-09-11 05:22:47 +08:00
void State : : popAllStateSets ( )
{
2005-04-13 20:00:28 +08:00
while ( ! _stateStateStack . empty ( ) ) popStateSet ( ) ;
2003-09-11 07:18:52 +08:00
applyProjectionMatrix ( 0 ) ;
applyModelViewMatrix ( 0 ) ;
2005-05-12 16:54:11 +08:00
_lastAppliedProgramObject = 0 ;
2003-09-11 05:22:47 +08:00
}
2002-01-17 05:23:29 +08:00
void State : : popStateSet ( )
{
2005-04-13 20:00:28 +08:00
if ( _stateStateStack . empty ( ) ) return ;
2002-01-17 05:23:29 +08:00
2005-04-13 20:00:28 +08:00
const StateSet * dstate = _stateStateStack . back ( ) ;
2002-01-17 05:23:29 +08:00
if ( dstate )
{
2001-09-20 05:19:47 +08:00
2002-07-09 17:35:42 +08:00
popModeList ( _modeMap , dstate - > getModeList ( ) ) ;
// iterator through texture modes.
unsigned int unit ;
const StateSet : : TextureModeList & ds_textureModeList = dstate - > getTextureModeList ( ) ;
for ( unit = 0 ; unit < ds_textureModeList . size ( ) ; + + unit )
2002-01-17 05:23:29 +08:00
{
2002-07-09 17:35:42 +08:00
popModeList ( getOrCreateTextureModeMap ( unit ) , ds_textureModeList [ unit ] ) ;
2002-01-17 05:23:29 +08:00
}
2002-07-09 17:35:42 +08:00
popAttributeList ( _attributeMap , dstate - > getAttributeList ( ) ) ;
// iterator through texture attributes.
const StateSet : : TextureAttributeList & ds_textureAttributeList = dstate - > getTextureAttributeList ( ) ;
for ( unit = 0 ; unit < ds_textureAttributeList . size ( ) ; + + unit )
2002-01-23 20:04:53 +08:00
{
2002-07-09 17:35:42 +08:00
popAttributeList ( getOrCreateTextureAttributeMap ( unit ) , ds_textureAttributeList [ unit ] ) ;
2002-01-23 20:04:53 +08:00
}
2005-05-10 21:56:05 +08:00
popUniformList ( _uniformMap , dstate - > getUniformList ( ) ) ;
2001-09-20 05:19:47 +08:00
}
// remove the top draw state from the stack.
2005-04-13 20:00:28 +08:00
_stateStateStack . pop_back ( ) ;
2001-09-20 05:19:47 +08:00
}
2001-10-23 06:02:47 +08:00
void State : : captureCurrentState ( StateSet & stateset ) const
{
// empty the stateset first.
2004-10-07 17:40:03 +08:00
stateset . clear ( ) ;
2001-10-23 06:02:47 +08:00
for ( ModeMap : : const_iterator mitr = _modeMap . begin ( ) ;
mitr ! = _modeMap . end ( ) ;
+ + mitr )
{
// note GLMode = mitr->first
const ModeStack & ms = mitr - > second ;
if ( ! ms . valueVec . empty ( ) )
{
stateset . setMode ( mitr - > first , ms . valueVec . back ( ) ) ;
}
}
2002-01-23 20:04:53 +08:00
for ( AttributeMap : : const_iterator aitr = _attributeMap . begin ( ) ;
aitr ! = _attributeMap . end ( ) ;
+ + aitr )
{
const AttributeStack & as = aitr - > second ;
if ( ! as . attributeVec . empty ( ) )
{
stateset . setAttribute ( const_cast < StateAttribute * > ( as . attributeVec . back ( ) . first ) ) ;
}
}
2001-10-23 06:02:47 +08:00
}
2003-02-24 20:02:00 +08:00
// revert to using maximum for consistency, maximum should be defined by STLport on VS.
// // visual studio 6.0 doesn't appear to define maximum?!? So do our own here..
2003-02-22 04:22:32 +08:00
// template<class T>
// T mymax(const T& a,const T& b)
// {
2003-05-07 21:13:13 +08:00
// return (((a) > (b)) ? (a) : (b));
2003-02-22 04:22:32 +08:00
// }
2001-10-23 06:02:47 +08:00
2001-09-20 05:19:47 +08:00
void State : : apply ( const StateSet * dstate )
{
2005-04-30 04:56:20 +08:00
if ( _checkGLErrors = = ONCE_PER_ATTRIBUTE ) checkGLErrors ( " start of State::apply(StateSet*) " ) ;
2003-01-22 00:45:36 +08:00
2001-09-20 05:19:47 +08:00
// equivilant to:
//pushStateSet(dstate);
//apply();
//popStateSet();
2003-03-11 21:30:03 +08:00
//return;
2001-09-20 05:19:47 +08:00
if ( dstate )
{
2002-07-09 17:35:42 +08:00
applyModeList ( _modeMap , dstate - > getModeList ( ) ) ;
applyAttributeList ( _attributeMap , dstate - > getAttributeList ( ) ) ;
2001-09-20 05:19:47 +08:00
2002-07-09 17:35:42 +08:00
const StateSet : : TextureModeList & ds_textureModeList = dstate - > getTextureModeList ( ) ;
const StateSet : : TextureAttributeList & ds_textureAttributeList = dstate - > getTextureAttributeList ( ) ;
2001-09-20 05:19:47 +08:00
2002-07-09 17:35:42 +08:00
unsigned int unit ;
2003-02-24 20:02:00 +08:00
unsigned int unitMax = maximum ( static_cast < unsigned int > ( ds_textureModeList . size ( ) ) , static_cast < unsigned int > ( ds_textureAttributeList . size ( ) ) ) ;
unitMax = maximum ( static_cast < unsigned int > ( unitMax ) , static_cast < unsigned int > ( _textureModeMapList . size ( ) ) ) ;
unitMax = maximum ( static_cast < unsigned int > ( unitMax ) , static_cast < unsigned int > ( _textureAttributeMapList . size ( ) ) ) ;
2002-07-09 17:35:42 +08:00
for ( unit = 0 ; unit < unitMax ; + + unit )
2001-09-20 05:19:47 +08:00
{
2002-07-09 17:35:42 +08:00
if ( setActiveTextureUnit ( unit ) )
2001-09-20 05:19:47 +08:00
{
2002-07-09 17:35:42 +08:00
if ( unit < ds_textureModeList . size ( ) ) applyModeList ( getOrCreateTextureModeMap ( unit ) , ds_textureModeList [ unit ] ) ;
else if ( unit < _textureModeMapList . size ( ) ) applyModeMap ( _textureModeMapList [ unit ] ) ;
if ( unit < ds_textureAttributeList . size ( ) ) applyAttributeList ( getOrCreateTextureAttributeMap ( unit ) , ds_textureAttributeList [ unit ] ) ;
else if ( unit < _textureAttributeMapList . size ( ) ) applyAttributeMap ( _textureAttributeMapList [ unit ] ) ;
2001-09-20 05:19:47 +08:00
}
}
2005-04-13 20:00:28 +08:00
2005-05-10 21:56:05 +08:00
# if 1
applyUniformList ( _uniformMap , dstate - > getUniformList ( ) ) ;
# else
2005-04-13 20:00:28 +08:00
if ( _lastAppliedProgramObject )
{
2005-04-13 22:31:25 +08:00
for ( StateSetStack : : iterator sitr = _stateStateStack . begin ( ) ;
sitr ! = _stateStateStack . end ( ) ;
+ + sitr )
{
const StateSet * stateset = * sitr ;
const StateSet : : UniformList & uniformList = stateset - > getUniformList ( ) ;
for ( StateSet : : UniformList : : const_iterator itr = uniformList . begin ( ) ;
itr ! = uniformList . end ( ) ;
+ + itr )
{
_lastAppliedProgramObject - > apply ( * ( itr - > second . first ) ) ;
}
}
2005-04-13 22:12:06 +08:00
const StateSet : : UniformList & uniformList = dstate - > getUniformList ( ) ;
for ( StateSet : : UniformList : : const_iterator itr = uniformList . begin ( ) ;
itr ! = uniformList . end ( ) ;
+ + itr )
{
_lastAppliedProgramObject - > apply ( * ( itr - > second . first ) ) ;
}
2005-04-13 20:00:28 +08:00
}
2005-05-10 21:56:05 +08:00
# endif
2001-09-20 05:19:47 +08:00
}
else
{
// no incomming stateset, so simply apply state.
apply ( ) ;
}
2005-04-30 04:56:20 +08:00
if ( _checkGLErrors = = ONCE_PER_ATTRIBUTE ) checkGLErrors ( " end of State::apply(StateSet*) " ) ;
2001-09-20 05:19:47 +08:00
}
void State : : apply ( )
{
2005-04-30 04:56:20 +08:00
if ( _checkGLErrors = = ONCE_PER_ATTRIBUTE ) checkGLErrors ( " start of State::apply() " ) ;
2003-01-22 00:45:36 +08:00
2001-09-20 05:19:47 +08:00
// go through all active OpenGL modes, enabling/disable where
// appropriate.
2002-07-09 17:35:42 +08:00
applyModeMap ( _modeMap ) ;
2002-01-23 20:04:53 +08:00
// go through all active StateAttribute's, applying where appropriate.
2002-07-09 17:35:42 +08:00
applyAttributeMap ( _attributeMap ) ;
unsigned int unit ;
2003-02-24 20:02:00 +08:00
unsigned int unitMax = maximum ( _textureModeMapList . size ( ) , _textureAttributeMapList . size ( ) ) ;
2002-07-09 17:35:42 +08:00
for ( unit = 0 ; unit < unitMax ; + + unit )
2002-01-23 20:04:53 +08:00
{
2002-07-09 17:35:42 +08:00
if ( setActiveTextureUnit ( unit ) )
2002-01-23 20:04:53 +08:00
{
2002-07-09 17:35:42 +08:00
if ( unit < _textureModeMapList . size ( ) ) applyModeMap ( _textureModeMapList [ unit ] ) ;
if ( unit < _textureAttributeMapList . size ( ) ) applyAttributeMap ( _textureAttributeMapList [ unit ] ) ;
2002-01-23 20:04:53 +08:00
}
2002-07-09 17:35:42 +08:00
}
2003-04-19 03:46:46 +08:00
2005-05-10 21:56:05 +08:00
# if 1
applyUniformMap ( _uniformMap ) ;
# else
2005-04-13 22:12:06 +08:00
if ( _lastAppliedProgramObject & & ! _stateStateStack . empty ( ) )
2005-04-13 20:00:28 +08:00
{
2005-04-13 22:31:25 +08:00
for ( StateSetStack : : iterator sitr = _stateStateStack . begin ( ) ;
sitr ! = _stateStateStack . end ( ) ;
+ + sitr )
2005-04-13 22:12:06 +08:00
{
2005-04-13 22:31:25 +08:00
const StateSet * stateset = * sitr ;
const StateSet : : UniformList & uniformList = stateset - > getUniformList ( ) ;
for ( StateSet : : UniformList : : const_iterator itr = uniformList . begin ( ) ;
itr ! = uniformList . end ( ) ;
+ + itr )
{
_lastAppliedProgramObject - > apply ( * ( itr - > second . first ) ) ;
}
2005-04-13 22:12:06 +08:00
}
2005-04-13 20:00:28 +08:00
}
2005-05-10 21:56:05 +08:00
# endif
2005-04-13 20:00:28 +08:00
2005-04-30 04:56:20 +08:00
if ( _checkGLErrors = = ONCE_PER_ATTRIBUTE ) checkGLErrors ( " end of State::apply() " ) ;
2001-09-20 05:19:47 +08:00
}
2002-09-02 20:31:35 +08:00
void State : : haveAppliedMode ( StateAttribute : : GLMode mode , StateAttribute : : GLModeValue value )
2001-09-20 05:19:47 +08:00
{
2002-07-09 17:35:42 +08:00
haveAppliedMode ( _modeMap , mode , value ) ;
}
2002-09-02 20:31:35 +08:00
void State : : haveAppliedMode ( StateAttribute : : GLMode mode )
2002-07-09 17:35:42 +08:00
{
haveAppliedMode ( _modeMap , mode ) ;
}
void State : : haveAppliedAttribute ( const StateAttribute * attribute )
{
haveAppliedAttribute ( _attributeMap , attribute ) ;
}
2004-10-13 19:15:50 +08:00
void State : : haveAppliedAttribute ( StateAttribute : : Type type , unsigned int member )
2002-07-09 17:35:42 +08:00
{
2004-10-13 19:15:50 +08:00
haveAppliedAttribute ( _attributeMap , type , member ) ;
2002-07-09 17:35:42 +08:00
}
2002-09-02 20:31:35 +08:00
bool State : : getLastAppliedMode ( StateAttribute : : GLMode mode ) const
2002-07-09 17:35:42 +08:00
{
return getLastAppliedMode ( _modeMap , mode ) ;
}
2004-10-13 19:15:50 +08:00
const StateAttribute * State : : getLastAppliedAttribute ( StateAttribute : : Type type , unsigned int member ) const
2002-07-09 17:35:42 +08:00
{
2004-10-13 19:15:50 +08:00
return getLastAppliedAttribute ( _attributeMap , type , member ) ;
2002-07-09 17:35:42 +08:00
}
2002-09-02 20:31:35 +08:00
void State : : haveAppliedTextureMode ( unsigned int unit , StateAttribute : : GLMode mode , StateAttribute : : GLModeValue value )
2002-07-09 17:35:42 +08:00
{
haveAppliedMode ( getOrCreateTextureModeMap ( unit ) , mode , value ) ;
}
2002-09-02 20:31:35 +08:00
void State : : haveAppliedTextureMode ( unsigned int unit , StateAttribute : : GLMode mode )
2002-07-09 17:35:42 +08:00
{
haveAppliedMode ( getOrCreateTextureModeMap ( unit ) , mode ) ;
}
void State : : haveAppliedTextureAttribute ( unsigned int unit , const StateAttribute * attribute )
{
haveAppliedAttribute ( getOrCreateTextureAttributeMap ( unit ) , attribute ) ;
}
2004-10-13 19:15:50 +08:00
void State : : haveAppliedTextureAttribute ( unsigned int unit , StateAttribute : : Type type , unsigned int member )
2002-07-09 17:35:42 +08:00
{
2004-10-13 19:15:50 +08:00
haveAppliedAttribute ( getOrCreateTextureAttributeMap ( unit ) , type , member ) ;
2002-07-09 17:35:42 +08:00
}
2002-09-02 20:31:35 +08:00
bool State : : getLastAppliedTextureMode ( unsigned int unit , StateAttribute : : GLMode mode ) const
2002-07-09 17:35:42 +08:00
{
if ( unit > = _textureModeMapList . size ( ) ) return false ;
return getLastAppliedMode ( _textureModeMapList [ unit ] , mode ) ;
}
2004-10-13 19:15:50 +08:00
const StateAttribute * State : : getLastAppliedTextureAttribute ( unsigned int unit , StateAttribute : : Type type , unsigned int member ) const
2002-07-09 17:35:42 +08:00
{
if ( unit > = _textureAttributeMapList . size ( ) ) return false ;
2004-10-13 19:15:50 +08:00
return getLastAppliedAttribute ( _textureAttributeMapList [ unit ] , type , member ) ;
2002-07-09 17:35:42 +08:00
}
2002-09-02 20:31:35 +08:00
void State : : haveAppliedMode ( ModeMap & modeMap , StateAttribute : : GLMode mode , StateAttribute : : GLModeValue value )
2002-07-09 17:35:42 +08:00
{
ModeStack & ms = modeMap [ mode ] ;
2001-09-20 05:19:47 +08:00
ms . last_applied_value = value & StateAttribute : : ON ;
// will need to disable this mode on next apply so set it to changed.
ms . changed = true ;
}
2002-03-21 20:00:10 +08:00
/** mode has been set externally, update state to reflect this setting.*/
2002-09-02 20:31:35 +08:00
void State : : haveAppliedMode ( ModeMap & modeMap , StateAttribute : : GLMode mode )
2002-03-21 20:00:10 +08:00
{
2002-07-09 17:35:42 +08:00
ModeStack & ms = modeMap [ mode ] ;
2002-03-21 20:00:10 +08:00
// don't know what last applied value is can't apply it.
// assume that it has changed by toggle the value of last_applied_value.
ms . last_applied_value = ! ms . last_applied_value ;
// will need to disable this mode on next apply so set it to changed.
ms . changed = true ;
}
2001-09-20 05:19:47 +08:00
/** attribute has been applied externally, update state to reflect this setting.*/
2002-07-09 17:35:42 +08:00
void State : : haveAppliedAttribute ( AttributeMap & attributeMap , const StateAttribute * attribute )
2001-09-20 05:19:47 +08:00
{
if ( attribute )
{
2004-10-13 19:15:50 +08:00
AttributeStack & as = attributeMap [ attribute - > getTypeMemberPair ( ) ] ;
2001-09-20 05:19:47 +08:00
as . last_applied_attribute = attribute ;
// will need to update this attribute on next apply so set it to changed.
as . changed = true ;
}
}
2004-10-13 19:15:50 +08:00
void State : : haveAppliedAttribute ( AttributeMap & attributeMap , StateAttribute : : Type type , unsigned int member )
2002-03-21 20:00:10 +08:00
{
2004-10-13 19:15:50 +08:00
AttributeMap : : iterator itr = attributeMap . find ( StateAttribute : : TypeMemberPair ( type , member ) ) ;
2002-07-09 17:35:42 +08:00
if ( itr ! = attributeMap . end ( ) )
2002-03-21 20:00:10 +08:00
{
AttributeStack & as = itr - > second ;
as . last_applied_attribute = 0L ;
// will need to update this attribute on next apply so set it to changed.
as . changed = true ;
}
}
2002-04-01 00:40:44 +08:00
2002-09-02 20:31:35 +08:00
bool State : : getLastAppliedMode ( const ModeMap & modeMap , StateAttribute : : GLMode mode ) const
2002-05-21 16:59:26 +08:00
{
2002-07-09 17:35:42 +08:00
ModeMap : : const_iterator itr = modeMap . find ( mode ) ;
if ( itr ! = modeMap . end ( ) )
2002-05-21 16:59:26 +08:00
{
const ModeStack & ms = itr - > second ;
return ms . last_applied_value ;
}
else
{
return false ;
}
}
2004-10-13 19:15:50 +08:00
const StateAttribute * State : : getLastAppliedAttribute ( const AttributeMap & attributeMap , StateAttribute : : Type type , unsigned int member ) const
2002-05-21 16:59:26 +08:00
{
2004-10-13 19:15:50 +08:00
AttributeMap : : const_iterator itr = attributeMap . find ( StateAttribute : : TypeMemberPair ( type , member ) ) ;
2002-07-09 17:35:42 +08:00
if ( itr ! = attributeMap . end ( ) )
2002-05-21 16:59:26 +08:00
{
const AttributeStack & as = itr - > second ;
return as . last_applied_attribute ;
}
else
{
return NULL ;
}
}
2003-01-19 23:28:08 +08:00
void State : : dirtyAllModes ( )
{
for ( ModeMap : : iterator mitr = _modeMap . begin ( ) ;
mitr ! = _modeMap . end ( ) ;
+ + mitr )
{
ModeStack & ms = mitr - > second ;
ms . last_applied_value = ! ms . last_applied_value ;
ms . changed = true ;
}
for ( TextureModeMapList : : iterator tmmItr = _textureModeMapList . begin ( ) ;
tmmItr ! = _textureModeMapList . end ( ) ;
+ + tmmItr )
{
for ( ModeMap : : iterator mitr = tmmItr - > begin ( ) ;
mitr ! = tmmItr - > end ( ) ;
+ + mitr )
{
ModeStack & ms = mitr - > second ;
ms . last_applied_value = ! ms . last_applied_value ;
ms . changed = true ;
}
}
}
void State : : dirtyAllAttributes ( )
{
for ( AttributeMap : : iterator aitr = _attributeMap . begin ( ) ;
aitr ! = _attributeMap . end ( ) ;
+ + aitr )
{
AttributeStack & as = aitr - > second ;
as . last_applied_attribute = 0 ;
as . changed = true ;
}
for ( TextureAttributeMapList : : iterator tamItr = _textureAttributeMapList . begin ( ) ;
tamItr ! = _textureAttributeMapList . end ( ) ;
+ + tamItr )
{
AttributeMap & attributeMap = * tamItr ;
for ( AttributeMap : : iterator aitr = attributeMap . begin ( ) ;
aitr ! = attributeMap . end ( ) ;
+ + aitr )
{
AttributeStack & as = aitr - > second ;
as . last_applied_attribute = 0 ;
as . changed = true ;
}
}
}
2002-06-03 23:39:41 +08:00
Polytope State : : getViewFrustum ( ) const
2002-04-01 00:40:44 +08:00
{
2002-06-03 23:39:41 +08:00
Polytope cv ;
2002-04-01 00:40:44 +08:00
cv . setToUnitFrustum ( ) ;
cv . transformProvidingInverse ( ( * _modelView ) * ( * _projection ) ) ;
return cv ;
}
2002-07-12 05:08:02 +08:00
2003-01-19 23:28:08 +08:00
2002-09-13 21:50:58 +08:00
void State : : disableAllVertexArrays ( )
{
disableVertexPointer ( ) ;
disableTexCoordPointersAboveAndIncluding ( 0 ) ;
2003-05-07 21:13:13 +08:00
disableVertexAttribPointersAboveAndIncluding ( 0 ) ;
2002-09-13 21:50:58 +08:00
disableColorPointer ( ) ;
disableFogCoordPointer ( ) ;
disableIndexPointer ( ) ;
disableNormalPointer ( ) ;
disableSecondaryColorPointer ( ) ;
}
void State : : dirtyAllVertexArrays ( )
{
dirtyVertexPointer ( ) ;
dirtyTexCoordPointersAboveAndIncluding ( 0 ) ;
2003-05-07 21:13:13 +08:00
dirtyVertexAttribPointersAboveAndIncluding ( 0 ) ;
2002-09-13 21:50:58 +08:00
dirtyColorPointer ( ) ;
dirtyFogCoordPointer ( ) ;
dirtyIndexPointer ( ) ;
dirtyNormalPointer ( ) ;
dirtySecondaryColorPointer ( ) ;
}
2003-03-06 05:02:37 +08:00
void State : : setInterleavedArrays ( GLenum format , GLsizei stride , const GLvoid * pointer )
2002-11-19 18:56:59 +08:00
{
2003-03-06 18:38:56 +08:00
disableAllVertexArrays ( ) ;
2002-11-19 18:56:59 +08:00
glInterleavedArrays ( format , stride , pointer ) ;
2003-03-06 18:38:56 +08:00
2002-11-19 18:56:59 +08:00
// the crude way, assume that all arrays have been effected so dirty them and
// disable them...
dirtyAllVertexArrays ( ) ;
}
2002-07-12 05:08:02 +08:00
typedef void ( APIENTRY * ActiveTextureProc ) ( GLenum texture ) ;
bool State : : setClientActiveTextureUnit ( unsigned int unit )
{
if ( unit ! = _currentClientActiveTextureUnit )
{
static ActiveTextureProc s_glClientActiveTexture =
( ActiveTextureProc ) osg : : getGLExtensionFuncPtr ( " glClientActiveTexture " , " glClientActiveTextureARB " ) ;
if ( s_glClientActiveTexture )
{
s_glClientActiveTexture ( GL_TEXTURE0 + unit ) ;
_currentClientActiveTextureUnit = unit ;
}
else
{
return unit = = 0 ;
}
}
return true ;
}
/** set the current texture unit, return true if selected, false if selection failed such as when multitexturing is not supported.
* note , only updates values that change . */
bool State : : setActiveTextureUnit ( unsigned int unit )
{
if ( unit ! = _currentActiveTextureUnit )
{
static ActiveTextureProc s_glActiveTexture =
( ActiveTextureProc ) osg : : getGLExtensionFuncPtr ( " glActiveTexture " , " glActiveTextureARB " ) ;
if ( s_glActiveTexture )
{
s_glActiveTexture ( GL_TEXTURE0 + unit ) ;
_currentActiveTextureUnit = unit ;
}
else
{
return unit = = 0 ;
}
}
return true ;
}
2002-08-16 04:27:33 +08:00
typedef void ( APIENTRY * FogCoordPointerProc ) ( GLenum type , GLsizei stride , const GLvoid * pointer ) ;
void State : : setFogCoordPointer ( GLenum type , GLsizei stride , const GLvoid * ptr )
{
static FogCoordPointerProc s_glFogCoordPointer =
( FogCoordPointerProc ) osg : : getGLExtensionFuncPtr ( " glFogCoordPointer " , " glFogCoordPointerEXT " ) ;
if ( s_glFogCoordPointer )
{
2002-09-13 21:50:58 +08:00
if ( ! _fogArray . _enabled | | _fogArray . _dirty )
2002-08-16 04:27:33 +08:00
{
_fogArray . _enabled = true ;
glEnableClientState ( GL_FOG_COORDINATE_ARRAY ) ;
}
2003-06-30 05:41:57 +08:00
//if (_fogArray._pointer!=ptr || _fogArray._dirty)
2002-08-16 04:27:33 +08:00
{
_fogArray . _pointer = ptr ;
s_glFogCoordPointer ( type , stride , ptr ) ;
}
2002-09-13 21:50:58 +08:00
_fogArray . _dirty = false ;
2002-08-16 04:27:33 +08:00
}
}
typedef void ( APIENTRY * SecondaryColorPointerProc ) ( GLint size , GLenum type , GLsizei stride , const GLvoid * pointer ) ;
void State : : setSecondaryColorPointer ( GLint size , GLenum type ,
GLsizei stride , const GLvoid * ptr )
{
static SecondaryColorPointerProc s_glSecondaryColorPointer =
2002-08-20 18:14:12 +08:00
( SecondaryColorPointerProc ) osg : : getGLExtensionFuncPtr ( " glSecondaryColorPointer " , " glSecondaryColorPointerEXT " ) ;
2002-08-16 04:27:33 +08:00
if ( s_glSecondaryColorPointer )
{
2002-09-13 21:50:58 +08:00
if ( ! _secondaryColorArray . _enabled | | _secondaryColorArray . _dirty )
2002-08-16 04:27:33 +08:00
{
_secondaryColorArray . _enabled = true ;
glEnableClientState ( GL_SECONDARY_COLOR_ARRAY ) ;
}
2003-06-30 05:41:57 +08:00
//if (_secondaryColorArray._pointer!=ptr || _secondaryColorArray._dirty)
2002-08-16 04:27:33 +08:00
{
_secondaryColorArray . _pointer = ptr ;
s_glSecondaryColorPointer ( size , type , stride , ptr ) ;
}
2002-09-13 21:50:58 +08:00
_secondaryColorArray . _dirty = false ;
2002-08-16 04:27:33 +08:00
}
}
2002-11-13 19:09:55 +08:00
2003-05-09 21:07:06 +08:00
typedef void ( APIENTRY * VertexAttribPointerProc ) ( unsigned int , GLint , GLenum , GLboolean normalized , GLsizei stride , const GLvoid * pointer ) ;
typedef void ( APIENTRY * EnableVertexAttribProc ) ( unsigned int ) ;
typedef void ( APIENTRY * DisableVertexAttribProc ) ( unsigned int ) ;
/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
* note , only updates values that change . */
void State : : setVertexAttribPointer ( unsigned int index ,
GLint size , GLenum type , GLboolean normalized ,
GLsizei stride , const GLvoid * ptr )
{
static VertexAttribPointerProc s_glVertexAttribPointer =
( VertexAttribPointerProc ) osg : : getGLExtensionFuncPtr ( " glVertexAttribPointer " , " glVertexAttribPointerARB " ) ;
static EnableVertexAttribProc s_glEnableVertexAttribArray =
( EnableVertexAttribProc ) osg : : getGLExtensionFuncPtr ( " glEnableVertexAttribArray " , " glEnableVertexAttribArrayARB " ) ;
if ( s_glVertexAttribPointer )
{
if ( index > = _vertexAttribArrayList . size ( ) ) _vertexAttribArrayList . resize ( index + 1 ) ;
EnabledArrayPair & eap = _vertexAttribArrayList [ index ] ;
if ( ! eap . _enabled | | eap . _dirty )
{
eap . _enabled = true ;
s_glEnableVertexAttribArray ( index ) ;
}
2003-06-30 05:41:57 +08:00
//if (eap._pointer != ptr || eap._normalized!=normalized || eap._dirty)
2003-05-09 21:07:06 +08:00
{
s_glVertexAttribPointer ( index , size , type , normalized , stride , ptr ) ;
eap . _pointer = ptr ;
eap . _normalized = normalized ;
}
eap . _dirty = false ;
}
}
/** wrapper around DisableVertexAttribArrayARB(index);
* note , only updates values that change . */
void State : : disableVertexAttribPointer ( unsigned int index )
{
static DisableVertexAttribProc s_glDisableVertexAttribArray =
( DisableVertexAttribProc ) osg : : getGLExtensionFuncPtr ( " glDisableVertexAttribArray " , " glDisableVertexAttribArrayARB " ) ;
if ( s_glDisableVertexAttribArray )
{
if ( index > = _vertexAttribArrayList . size ( ) ) _vertexAttribArrayList . resize ( index + 1 ) ;
EnabledArrayPair & eap = _vertexAttribArrayList [ index ] ;
if ( eap . _enabled | | eap . _dirty )
{
eap . _enabled = false ;
eap . _dirty = false ;
s_glDisableVertexAttribArray ( index ) ;
}
}
}
void State : : disableVertexAttribPointersAboveAndIncluding ( unsigned int index )
{
static DisableVertexAttribProc s_glDisableVertexAttribArray =
( DisableVertexAttribProc ) osg : : getGLExtensionFuncPtr ( " glDisableVertexAttribArray " , " glDisableVertexAttribArrayARB " ) ;
if ( s_glDisableVertexAttribArray )
{
while ( index < _vertexAttribArrayList . size ( ) )
{
EnabledArrayPair & eap = _vertexAttribArrayList [ index ] ;
if ( eap . _enabled | | eap . _dirty )
{
eap . _enabled = false ;
eap . _dirty = false ;
s_glDisableVertexAttribArray ( index ) ;
}
+ + index ;
}
}
}
2002-11-13 19:09:55 +08:00
bool State : : computeSecondaryColorSupported ( ) const
{
2003-06-30 05:41:57 +08:00
_isSecondaryColorSupportResolved = true ;
2005-04-26 21:15:27 +08:00
_isSecondaryColorSupported = osg : : isGLExtensionSupported ( _contextID , " GL_EXT_secondary_color " ) ;
2003-06-30 05:41:57 +08:00
return _isSecondaryColorSupported ;
2002-11-13 19:09:55 +08:00
}
bool State : : computeFogCoordSupported ( ) const
{
_isFogCoordSupportResolved = true ;
2005-04-26 21:15:27 +08:00
_isFogCoordSupported = osg : : isGLExtensionSupported ( _contextID , " GL_EXT_fog_coord " ) ;
2002-11-13 19:09:55 +08:00
return _isFogCoordSupported ;
}
2003-01-22 00:45:36 +08:00
2003-06-30 05:41:57 +08:00
bool State : : computeVertexBufferObjectSupported ( ) const
{
_isVertexBufferObjectSupportResolved = true ;
2005-04-26 21:15:27 +08:00
_isVertexBufferObjectSupported = osg : : isGLExtensionSupported ( _contextID , " GL_ARB_vertex_buffer_object " ) ;
2003-06-30 05:41:57 +08:00
return _isVertexBufferObjectSupported ;
}
2003-01-22 00:45:36 +08:00
bool State : : checkGLErrors ( const char * str ) const
{
GLenum errorNo = glGetError ( ) ;
if ( errorNo ! = GL_NO_ERROR )
{
2005-11-01 19:18:40 +08:00
const char * error = ( char * ) gluErrorString ( errorNo ) ;
2005-11-02 04:16:31 +08:00
if ( error ) osg : : notify ( WARN ) < < " Warning: detected OpenGL error ' " < < error < < " ' " ;
else osg : : notify ( WARN ) < < " Warning: detected OpenGL error number 0x " < < std : : hex < < errorNo ;
2005-11-01 19:18:40 +08:00
2005-11-02 04:16:31 +08:00
if ( str ) osg : : notify ( WARN ) < < " at " < < str < < std : : endl ;
else osg : : notify ( WARN ) < < " in osg::State. " < < std : : endl ;
2005-11-01 19:18:40 +08:00
2003-01-22 00:45:36 +08:00
return true ;
}
return false ;
}
bool State : : checkGLErrors ( StateAttribute : : GLMode mode ) const
{
GLenum errorNo = glGetError ( ) ;
if ( errorNo ! = GL_NO_ERROR )
{
2005-11-01 19:18:40 +08:00
const char * error = ( char * ) gluErrorString ( errorNo ) ;
if ( error ) osg : : notify ( WARN ) < < " Warning: detected OpenGL error ' " < < error < < " ' after applying GLMode 0x " < < hex < < mode < < dec < < std : : endl ;
2005-11-02 04:16:31 +08:00
else osg : : notify ( WARN ) < < " Warning: detected OpenGL error number 0x " < < std : : hex < < errorNo < < " after applying GLMode 0x " < < hex < < mode < < dec < < std : : endl ;
2005-11-01 19:18:40 +08:00
2003-01-22 00:45:36 +08:00
return true ;
}
return false ;
}
bool State : : checkGLErrors ( const StateAttribute * attribute ) const
{
GLenum errorNo = glGetError ( ) ;
if ( errorNo ! = GL_NO_ERROR )
{
2005-11-01 19:18:40 +08:00
const char * error = ( char * ) gluErrorString ( errorNo ) ;
if ( error ) osg : : notify ( WARN ) < < " Warning: detected OpenGL error ' " < < error < < " ' after applying attribute " < < attribute - > className ( ) < < " " < < attribute < < std : : endl ;
2005-11-02 04:16:31 +08:00
else osg : : notify ( WARN ) < < " Warning: detected OpenGL error number 0x " < < std : : hex < < errorNo < < " after applying attribute " < < attribute - > className ( ) < < " " < < attribute < < std : : endl ;
2005-11-01 19:18:40 +08:00
2003-01-22 00:45:36 +08:00
return true ;
}
return false ;
}
2005-11-01 19:18:40 +08:00