Index: /OpenSceneGraph/trunk/include/osg/State
===================================================================
--- /OpenSceneGraph/trunk/include/osg/State (revision 10769)
+++ /OpenSceneGraph/trunk/include/osg/State (revision 10926)
@@ -299,13 +299,8 @@
         inline bool applyTextureMode(unsigned int unit, StateAttribute::GLMode mode,bool enabled)
         {
-            if (setActiveTextureUnit(unit))
-            {
-                ModeMap& modeMap = getOrCreateTextureModeMap(unit);
-                ModeStack& ms = modeMap[mode];
-                ms.changed = true;
-                return applyMode(mode,enabled,ms);
-            }
-            else
-                return false;
+            ModeMap& modeMap = getOrCreateTextureModeMap(unit);
+            ModeStack& ms = modeMap[mode];
+            ms.changed = true;
+            return applyModeOnTexUnit(unit,mode,enabled,ms);
         }
 
@@ -347,13 +342,8 @@
         inline bool applyTextureAttribute(unsigned int unit, const StateAttribute* attribute)
         {
-            if (setActiveTextureUnit(unit))
-            {
-                AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit);
-                AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
-                as.changed = true;
-                return applyAttribute(attribute,as);
-            }
-            else
-                return false;
+            AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit);
+            AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
+            as.changed = true;
+            return applyAttributeOnTexUnit(unit,attribute,as);
         }
 
@@ -1139,5 +1129,5 @@
         * false if selection failed such as when multi texturing is not supported.
         * note, only updates values that change.*/
-        bool setActiveTextureUnit( unsigned int unit );
+        inline bool setActiveTextureUnit( unsigned int unit );
 
         /** Get the current texture unit.*/
@@ -1456,4 +1446,25 @@
         }
 
+        inline bool applyModeOnTexUnit(unsigned int unit,StateAttribute::GLMode mode,bool enabled,ModeStack& ms)
+        {
+            if (ms.valid && ms.last_applied_value != enabled)
+            {
+                if (setActiveTextureUnit(unit))
+                {
+                    ms.last_applied_value = enabled;
+
+                    if (enabled) glEnable(mode);
+                    else glDisable(mode);
+
+                    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(mode);
+
+                    return true;
+                }
+                else
+                    return false;
+            }
+            else
+                return false;
+        }
 
         /** apply an attribute if required, passing in attribute and appropriate attribute stack */
@@ -1475,4 +1486,27 @@
         }
 
+        inline bool applyAttributeOnTexUnit(unsigned int unit,const StateAttribute* attribute,AttributeStack& as)
+        {
+            if (as.last_applied_attribute != attribute)
+            {
+                if (setActiveTextureUnit(unit))
+                {
+                    if (!as.global_default_attribute.valid()) as.global_default_attribute = dynamic_cast<StateAttribute*>(attribute->cloneType());
+
+                    as.last_applied_attribute = attribute;
+                    attribute->apply(*this);
+
+                    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(attribute);
+
+                    return true;
+                }
+                else
+                    return false;
+            }
+            else
+                return false;
+        }
+
+
         inline bool applyGlobalDefaultAttribute(AttributeStack& as)
         {
@@ -1486,4 +1520,25 @@
                 }
                 return true;
+            }
+            else
+                return false;
+        }
+
+        inline bool applyGlobalDefaultAttributeOnTexUnit(unsigned int unit,AttributeStack& as)
+        {
+            if (as.last_applied_attribute != as.global_default_attribute.get())
+            {
+                if (setActiveTextureUnit(unit))
+                {
+                    as.last_applied_attribute = as.global_default_attribute.get();
+                    if (as.global_default_attribute.valid())
+                    {
+                        as.global_default_attribute->apply(*this);
+                        if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(as.global_default_attribute.get());
+                    }
+                    return true;
+                }
+                else
+                    return false;
             }
             else
@@ -1579,4 +1634,10 @@
         inline void applyAttributeMap(AttributeMap& attributeMap);
         inline void applyUniformMap(UniformMap& uniformMap);
+
+        inline void applyModeListOnTexUnit(unsigned int unit,ModeMap& modeMap,const StateSet::ModeList& modeList);
+        inline void applyAttributeListOnTexUnit(unsigned int unit,AttributeMap& attributeMap,const StateSet::AttributeList& attributeList);
+
+        inline void applyModeMapOnTexUnit(unsigned int unit,ModeMap& modeMap);
+        inline void applyAttributeMapOnTexUnit(unsigned int unit,AttributeMap& attributeMap);
 
         void haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode,StateAttribute::GLModeValue value);
@@ -1893,4 +1954,126 @@
 }
 
+inline void State::applyModeListOnTexUnit(unsigned int unit,ModeMap& modeMap,const StateSet::ModeList& modeList)
+{
+    StateSet::ModeList::const_iterator ds_mitr = modeList.begin();
+    ModeMap::iterator this_mitr=modeMap.begin();
+
+    while (this_mitr!=modeMap.end() && ds_mitr!=modeList.end())
+    {
+        if (this_mitr->first<ds_mitr->first)
+        {
+
+            // note GLMode = this_mitr->first
+            ModeStack& ms = this_mitr->second;
+            if (ms.changed)
+            {
+                ms.changed = false;
+                if (!ms.valueVec.empty())
+                {
+                    bool new_value = ms.valueVec.back() & StateAttribute::ON;
+                    applyModeOnTexUnit(unit,this_mitr->first,new_value,ms);
+                }
+                else
+                {
+                    // assume default of disabled.
+                    applyModeOnTexUnit(unit,this_mitr->first,ms.global_default_value,ms);
+
+                }
+
+            }
+
+            ++this_mitr;
+
+        }
+        else if (ds_mitr->first<this_mitr->first)
+        {
+
+            // ds_mitr->first is a new mode, therefore
+            // need to insert a new mode entry for ds_mistr->first.
+            ModeStack& ms = modeMap[ds_mitr->first];
+
+            bool new_value = ds_mitr->second & StateAttribute::ON;
+            applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms);
+
+            // will need to disable this mode on next apply so set it to changed.
+            ms.changed = true;
+
+            ++ds_mitr;
+
+        }
+        else
+        {
+            // this_mitr & ds_mitr refer to the same mode, check the override
+            // if any otherwise just apply the incoming mode.
+
+            ModeStack& ms = this_mitr->second;
+
+            if (!ms.valueVec.empty() && (ms.valueVec.back() & StateAttribute::OVERRIDE) && !(ds_mitr->second & StateAttribute::PROTECTED))
+            {
+                // override is on, just treat as a normal apply on modes.
+
+                if (ms.changed)
+                {
+                    ms.changed = false;
+                    bool new_value = ms.valueVec.back() & StateAttribute::ON;
+                    applyModeOnTexUnit(unit,this_mitr->first,new_value,ms);
+
+                }
+            }
+            else
+            {
+                // no override on or no previous entry, therefore consider incoming mode.
+                bool new_value = ds_mitr->second & StateAttribute::ON;
+                if (applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms))
+                {
+                    ms.changed = true;
+                }
+            }
+
+            ++this_mitr;
+            ++ds_mitr;
+        }
+    }
+
+    // iterator over the remaining state modes to apply any previous changes.
+    for(;
+        this_mitr!=modeMap.end();
+        ++this_mitr)
+    {
+        // note GLMode = this_mitr->first
+        ModeStack& ms = this_mitr->second;
+        if (ms.changed)
+        {
+            ms.changed = false;
+            if (!ms.valueVec.empty())
+            {
+                bool new_value = ms.valueVec.back() & StateAttribute::ON;
+                applyModeOnTexUnit(unit,this_mitr->first,new_value,ms);
+            }
+            else
+            {
+                // assume default of disabled.
+                applyModeOnTexUnit(unit,this_mitr->first,ms.global_default_value,ms);
+
+            }
+
+        }
+    }
+
+    // iterator over the remaining incoming modes to apply any new mode.
+    for(;
+        ds_mitr!=modeList.end();
+        ++ds_mitr)
+    {
+        ModeStack& ms = modeMap[ds_mitr->first];
+
+        bool new_value = ds_mitr->second & StateAttribute::ON;
+        applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms);
+
+        // will need to disable this mode on next apply so set it to changed.
+        ms.changed = true;
+    }
+}
+
 inline void State::applyAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
 {
@@ -2004,4 +2187,122 @@
         const StateAttribute* new_attr = ds_aitr->second.first.get();
         applyAttribute(new_attr,as);
+
+        // will need to update this attribute on next apply so set it to changed.
+        as.changed = true;
+    }
+
+}
+
+inline void State::applyAttributeListOnTexUnit(unsigned int unit,AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
+{
+    StateSet::AttributeList::const_iterator ds_aitr=attributeList.begin();
+
+    AttributeMap::iterator this_aitr=attributeMap.begin();
+
+    while (this_aitr!=attributeMap.end() && ds_aitr!=attributeList.end())
+    {
+        if (this_aitr->first<ds_aitr->first)
+        {
+
+            // note attribute type = this_aitr->first
+            AttributeStack& as = this_aitr->second;
+            if (as.changed)
+            {
+                as.changed = false;
+                if (!as.attributeVec.empty())
+                {
+                    const StateAttribute* new_attr = as.attributeVec.back().first;
+                    applyAttributeOnTexUnit(unit,new_attr,as);
+                }
+                else
+                {
+                    applyGlobalDefaultAttributeOnTexUnit(unit,as);
+                }
+            }
+
+            ++this_aitr;
+
+        }
+        else if (ds_aitr->first<this_aitr->first)
+        {
+
+            // ds_aitr->first is a new attribute, therefore
+            // need to insert a new attribute entry for ds_aitr->first.
+            AttributeStack& as = attributeMap[ds_aitr->first];
+
+            const StateAttribute* new_attr = ds_aitr->second.first.get();
+            applyAttributeOnTexUnit(unit,new_attr,as);
+
+            as.changed = true;
+
+            ++ds_aitr;
+
+        }
+        else
+        {
+            // this_mitr & ds_mitr refer to the same attribute, check the override
+            // if any otherwise just apply the incoming attribute
+
+            AttributeStack& as = this_aitr->second;
+
+            if (!as.attributeVec.empty() && (as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED))
+            {
+                // override is on, just treat as a normal apply on attribute.
+
+                if (as.changed)
+                {
+                    as.changed = false;
+                    const StateAttribute* new_attr = as.attributeVec.back().first;
+                    applyAttributeOnTexUnit(unit,new_attr,as);
+                }
+            }
+            else
+            {
+                // no override on or no previous entry, therefore consider incoming attribute.
+                const StateAttribute* new_attr = ds_aitr->second.first.get();
+                if (applyAttributeOnTexUnit(unit,new_attr,as))
+                {
+                    as.changed = true;
+                }
+            }
+
+            ++this_aitr;
+            ++ds_aitr;
+        }
+    }
+
+    // iterator over the remaining state attributes to apply any previous changes.
+    for(;
+        this_aitr!=attributeMap.end();
+        ++this_aitr)
+    {
+        // note attribute type = this_aitr->first
+        AttributeStack& as = this_aitr->second;
+        if (as.changed)
+        {
+            as.changed = false;
+            if (!as.attributeVec.empty())
+            {
+                const StateAttribute* new_attr = as.attributeVec.back().first;
+                applyAttributeOnTexUnit(unit,new_attr,as);
+            }
+            else
+            {
+                applyGlobalDefaultAttributeOnTexUnit(unit,as);
+            }
+        }
+    }
+
+    // iterator over the remaining incoming attribute to apply any new attribute.
+    for(;
+        ds_aitr!=attributeList.end();
+        ++ds_aitr)
+    {
+        // ds_aitr->first is a new attribute, therefore
+        // need to insert a new attribute entry for ds_aitr->first.
+        AttributeStack& as = attributeMap[ds_aitr->first];
+
+        const StateAttribute* new_attr = ds_aitr->second.first.get();
+        applyAttributeOnTexUnit(unit,new_attr,as);
 
         // will need to update this attribute on next apply so set it to changed.
@@ -2111,4 +2412,30 @@
 }
 
+inline void State::applyModeMapOnTexUnit(unsigned int unit,ModeMap& modeMap)
+{
+    for(ModeMap::iterator mitr=modeMap.begin();
+        mitr!=modeMap.end();
+        ++mitr)
+    {
+        // note GLMode = mitr->first
+        ModeStack& ms = mitr->second;
+        if (ms.changed)
+        {
+            ms.changed = false;
+            if (!ms.valueVec.empty())
+            {
+                bool new_value = ms.valueVec.back() & StateAttribute::ON;
+                applyModeOnTexUnit(unit,mitr->first,new_value,ms);
+            }
+            else
+            {
+                // assume default of disabled.
+                applyModeOnTexUnit(unit,mitr->first,ms.global_default_value,ms);
+            }
+
+        }
+    }
+}
+
 inline void State::applyAttributeMap(AttributeMap& attributeMap)
 {
@@ -2135,4 +2462,28 @@
 }
 
+inline void State::applyAttributeMapOnTexUnit(unsigned int unit,AttributeMap& attributeMap)
+{
+    for(AttributeMap::iterator aitr=attributeMap.begin();
+        aitr!=attributeMap.end();
+        ++aitr)
+    {
+        AttributeStack& as = aitr->second;
+        if (as.changed)
+        {
+            as.changed = false;
+            if (!as.attributeVec.empty())
+            {
+                const StateAttribute* new_attr = as.attributeVec.back().first;
+                applyAttributeOnTexUnit(unit,new_attr,as);
+            }
+            else
+            {
+                applyGlobalDefaultAttributeOnTexUnit(unit,as);
+            }
+
+        }
+    }
+}
+
 inline void State::applyUniformMap(UniformMap& uniformMap)
 {
@@ -2151,6 +2502,22 @@
 }
 
-
+inline bool State::setActiveTextureUnit( unsigned int unit )
+{
+    if (unit!=_currentActiveTextureUnit)
+    {
+        if (_glActiveTexture && unit < (unsigned int)(maximum(_glMaxTextureCoords,_glMaxTextureUnits)) )
+        {
+            _glActiveTexture(GL_TEXTURE0+unit);
+            _currentActiveTextureUnit = unit;
+        }
+        else
+        {
+            return unit==0;
+        }
+    }
+    return true;
 }
 
+}
+
 #endif
Index: /OpenSceneGraph/trunk/src/osg/State.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osg/State.cpp (revision 10765)
+++ /OpenSceneGraph/trunk/src/osg/State.cpp (revision 10926)
@@ -502,12 +502,9 @@
         for(unit=0;unit<unitMax;++unit)
         {
-            if (setActiveTextureUnit(unit))
-            {
-                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]);
-            }
+            if (unit<ds_textureModeList.size()) applyModeListOnTexUnit(unit,getOrCreateTextureModeMap(unit),ds_textureModeList[unit]);
+            else if (unit<_textureModeMapList.size()) applyModeMapOnTexUnit(unit,_textureModeMapList[unit]);
+
+            if (unit<ds_textureAttributeList.size()) applyAttributeListOnTexUnit(unit,getOrCreateTextureAttributeMap(unit),ds_textureAttributeList[unit]);
+            else if (unit<_textureAttributeMapList.size()) applyAttributeMapOnTexUnit(unit,_textureAttributeMapList[unit]);
         }
 
@@ -539,9 +536,6 @@
     for(unit=0;unit<unitMax;++unit)
     {
-        if (setActiveTextureUnit(unit))
-        {
-            if (unit<_textureModeMapList.size()) applyModeMap(_textureModeMapList[unit]);
-            if (unit<_textureAttributeMapList.size()) applyAttributeMap(_textureAttributeMapList[unit]);
-        }
+        if (unit<_textureModeMapList.size()) applyModeMapOnTexUnit(unit,_textureModeMapList[unit]);
+        if (unit<_textureAttributeMapList.size()) applyAttributeMapOnTexUnit(unit,_textureAttributeMapList[unit]);
     }
 
@@ -849,24 +843,4 @@
             _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)
-    {
-        if (_glActiveTexture && unit < (unsigned int)(maximum(_glMaxTextureCoords,_glMaxTextureUnits)) )
-        {
-            _glActiveTexture(GL_TEXTURE0+unit);
-            _currentActiveTextureUnit = unit;
         }
         else
Index: /OpenSceneGraph/trunk/src/osgWrappers/osg/State.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgWrappers/osg/State.cpp (revision 10775)
+++ /OpenSceneGraph/trunk/src/osgWrappers/osg/State.cpp (revision 10926)
@@ -900,4 +900,11 @@
 	                   "",
 	                   "");
+
+
+
+
+
+
+
 
 
