Index: /OpenSceneGraph/trunk/include/osg/State
===================================================================
--- /OpenSceneGraph/trunk/include/osg/State (revision 10601)
+++ /OpenSceneGraph/trunk/include/osg/State (revision 10621)
@@ -167,38 +167,44 @@
             if (_projection!=matrix)
             {
+                if (matrix)
+                {
+                    _projection=matrix;
+                }
+                else
+                {
+                    _projection=_identity;
+                }
+
+                if (_projectionMatrixUniform.valid()) _projectionMatrixUniform->set(*_projection);
+                if (_modelViewProjectionMatrixUniform.valid()) _modelViewProjectionMatrixUniform->set((*_modelView) * (*_projection));
+
                 glMatrixMode( GL_PROJECTION );
+                    glLoadMatrix(_projection->ptr());
+                glMatrixMode( GL_MODELVIEW );
+            }
+        }
+
+        inline const osg::Matrix& getProjectionMatrix() const
+        {
+            return *_projection;
+        }
+
+        inline void applyModelViewMatrix(const osg::RefMatrix* matrix)
+        {
+            if (_modelView!=matrix)
+            {
                 if (matrix)
                 {
-                    _projection=matrix;
-                    glLoadMatrix(matrix->ptr());
+                    _modelView=matrix;
                 }
                 else
                 {
-                    _projection=_identity;
-                    glLoadIdentity();
-                }
-                glMatrixMode( GL_MODELVIEW );
-            }
-        }
-
-        inline const osg::Matrix& getProjectionMatrix() const
-        {
-            return *_projection;
-        }
-
-        inline void applyModelViewMatrix(const osg::RefMatrix* matrix)
-        {
-            if (_modelView!=matrix)
-            {
-                if (matrix)
-                {
-                    _modelView=matrix;
-                    glLoadMatrix(matrix->ptr());
-                }
-                else
-                {
                     _modelView=_identity;
-                    glLoadIdentity();
-                }
+                }
+
+                if (_modelViewMatrixUniform.valid()) _modelViewMatrixUniform->set(*_modelView);
+                if (_modelViewProjectionMatrixUniform.valid()) _modelViewProjectionMatrixUniform->set((*_modelView) * (*_projection));
+
+                glLoadMatrix(_modelView->ptr());
             }
         }
@@ -208,4 +214,10 @@
             return *_modelView;
         }
+
+        void applyModelViewAndProjectionUniformsIfRequired();
+
+        osg::Uniform* getModelViewMatrixUniform() { return _modelViewMatrixUniform.get(); }
+        osg::Uniform* getProjectionMatrixUniform() { return _projectionMatrixUniform.get(); }
+        osg::Uniform* getModelViewProjectionMatrixUniform() { return _modelViewProjectionMatrixUniform.get(); }
 
 
@@ -1088,4 +1100,8 @@
         ref_ptr<const RefMatrix>    _projection;
         ref_ptr<const RefMatrix>    _modelView;
+
+        ref_ptr<Uniform>            _modelViewMatrixUniform;
+        ref_ptr<Uniform>            _projectionMatrixUniform;
+        ref_ptr<Uniform>            _modelViewProjectionMatrixUniform;
 
         Matrix                      _initialInverseViewMatrix;
Index: /OpenSceneGraph/trunk/src/osgUtil/RenderLeaf.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgUtil/RenderLeaf.cpp (revision 7328)
+++ /OpenSceneGraph/trunk/src/osgUtil/RenderLeaf.cpp (revision 10621)
@@ -55,5 +55,8 @@
 
         }
-        
+
+        // if we are using osg::Program which requires OSG's generated uniforms to track
+        // modelview and projection matrices then apply them now.
+        state.applyModelViewAndProjectionUniformsIfRequired();
 
         // draw the drawable
@@ -71,4 +74,8 @@
         state.apply(_parent->getStateSet());
 
+        // if we are using osg::Program which requires OSG's generated uniforms to track
+        // modelview and projection matrices then apply them now.
+        state.applyModelViewAndProjectionUniformsIfRequired();
+
         // draw the drawable
         _drawable->draw(renderInfo);
Index: /OpenSceneGraph/trunk/src/osg/Geometry.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osg/Geometry.cpp (revision 10615)
+++ /OpenSceneGraph/trunk/src/osg/Geometry.cpp (revision 10621)
@@ -2115,5 +2115,14 @@
     AttributeFunctorArrayVisitor afav(af);
 
-    afav.applyArray(VERTICES,_vertexData.array.get());
+    if (_vertexData.array.valid())
+    {
+        afav.applyArray(VERTICES,_vertexData.array.get());
+    }
+    else if (_vertexAttribList.size()>0)
+    {
+        osg::notify(osg::INFO)<<"Geometry::accept(AttributeFunctor& af): Using vertex attribute instead"<<std::endl;
+        afav.applyArray(VERTICES,_vertexAttribList[0].array.get());
+    }
+
     afav.applyArray(NORMALS,_normalData.array.get());
     afav.applyArray(COLORS,_colorData.array.get());
@@ -2179,5 +2188,14 @@
     ConstAttributeFunctorArrayVisitor afav(af);
     
-    afav.applyArray(VERTICES,_vertexData.array.get());
+    if (_vertexData.array.valid())
+    {
+        afav.applyArray(VERTICES,_vertexData.array.get());
+    }
+    else if (_vertexAttribList.size()>0)
+    {
+        osg::notify(osg::INFO)<<"Geometry::accept(ConstAttributeFunctor& af): Using vertex attribute instead"<<std::endl;
+        afav.applyArray(VERTICES,_vertexAttribList[0].array.get());
+    }
+
     afav.applyArray(NORMALS,_normalData.array.get());
     afav.applyArray(COLORS,_colorData.array.get());
@@ -2198,30 +2216,40 @@
 void Geometry::accept(PrimitiveFunctor& functor) const
 {
-    if (!_vertexData.array.valid() || _vertexData.array->getNumElements()==0) return;
-
-    if (!_vertexData.indices.valid())
-    {
-        switch(_vertexData.array->getType())
+    const osg::Array* vertices = _vertexData.array.get();
+    const osg::IndexArray* indices = _vertexData.indices.get();
+
+    if (!vertices && _vertexAttribList.size()>0)
+    {
+        osg::notify(osg::INFO)<<"Using vertex attribute instead"<<std::endl;
+        vertices = _vertexAttribList[0].array.get();
+        indices = _vertexAttribList[0].indices.get();
+    }
+
+    if (!vertices || vertices->getNumElements()==0) return;
+
+    if (!indices)
+    {
+        switch(vertices->getType())
         {
         case(Array::Vec2ArrayType): 
-            functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec2*>(_vertexData.array->getDataPointer()));
+            functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec2*>(vertices->getDataPointer()));
             break;
         case(Array::Vec3ArrayType): 
-            functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec3*>(_vertexData.array->getDataPointer()));
+            functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec3*>(vertices->getDataPointer()));
             break;
         case(Array::Vec4ArrayType): 
-            functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec4*>(_vertexData.array->getDataPointer()));
+            functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec4*>(vertices->getDataPointer()));
             break;
         case(Array::Vec2dArrayType): 
-            functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec2d*>(_vertexData.array->getDataPointer()));
+            functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec2d*>(vertices->getDataPointer()));
             break;
         case(Array::Vec3dArrayType): 
-            functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec3d*>(_vertexData.array->getDataPointer()));
+            functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec3d*>(vertices->getDataPointer()));
             break;
         case(Array::Vec4dArrayType): 
-            functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec4d*>(_vertexData.array->getDataPointer()));
+            functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec4d*>(vertices->getDataPointer()));
             break;
         default:
-            notify(WARN)<<"Warning: Geometry::accept(PrimitiveFunctor&) cannot handle Vertex Array type"<<_vertexData.array->getType()<<std::endl;
+            notify(WARN)<<"Warning: Geometry::accept(PrimitiveFunctor&) cannot handle Vertex Array type"<<vertices->getType()<<std::endl;
             return;
         }
@@ -2242,31 +2270,30 @@
         const Vec3d* vec3dArray = 0;
         const Vec4d* vec4dArray = 0;
-        Array::Type type = _vertexData.array->getType();
+        Array::Type type = vertices->getType();
         switch(type)
         {
         case(Array::Vec2ArrayType): 
-            vec2Array = static_cast<const Vec2*>(_vertexData.array->getDataPointer());
+            vec2Array = static_cast<const Vec2*>(vertices->getDataPointer());
             break;
         case(Array::Vec3ArrayType): 
-            vec3Array = static_cast<const Vec3*>(_vertexData.array->getDataPointer());
+            vec3Array = static_cast<const Vec3*>(vertices->getDataPointer());
             break;
         case(Array::Vec4ArrayType): 
-            vec4Array = static_cast<const Vec4*>(_vertexData.array->getDataPointer());
+            vec4Array = static_cast<const Vec4*>(vertices->getDataPointer());
             break;
         case(Array::Vec2dArrayType): 
-            vec2dArray = static_cast<const Vec2d*>(_vertexData.array->getDataPointer());
+            vec2dArray = static_cast<const Vec2d*>(vertices->getDataPointer());
             break;
         case(Array::Vec3dArrayType): 
-            vec3dArray = static_cast<const Vec3d*>(_vertexData.array->getDataPointer());
+            vec3dArray = static_cast<const Vec3d*>(vertices->getDataPointer());
             break;
         case(Array::Vec4dArrayType): 
-            vec4dArray = static_cast<const Vec4d*>(_vertexData.array->getDataPointer());
+            vec4dArray = static_cast<const Vec4d*>(vertices->getDataPointer());
             break;
         default:
-            notify(WARN)<<"Warning: Geometry::accept(PrimitiveFunctor&) cannot handle Vertex Array type"<<_vertexData.array->getType()<<std::endl;
+            notify(WARN)<<"Warning: Geometry::accept(PrimitiveFunctor&) cannot handle Vertex Array type"<<vertices->getType()<<std::endl;
             return;
         }
 
-    
         for(PrimitiveSetList::const_iterator itr=_primitives.begin();
             itr!=_primitives.end();
@@ -2312,5 +2339,5 @@
 
                     }
-                    
+
                     functor.end();
                     break;
@@ -2355,5 +2382,5 @@
                             ++vindex;
                         }
-                        
+
                         functor.end();
 
@@ -2488,28 +2515,38 @@
 void Geometry::accept(PrimitiveIndexFunctor& functor) const
 {
-    if (!_vertexData.array.valid() || _vertexData.array->getNumElements()==0) return;
-
-    switch(_vertexData.array->getType())
+    const osg::Array* vertices = _vertexData.array.get();
+    const osg::IndexArray* indices = _vertexData.indices.get();
+
+    if (!vertices && _vertexAttribList.size()>0)
+    {
+        osg::notify(osg::INFO)<<"Geometry::accept(PrimitiveIndexFunctor& functor): Using vertex attribute instead"<<std::endl;
+        vertices = _vertexAttribList[0].array.get();
+        indices = _vertexAttribList[0].indices.get();
+    }
+
+    if (!vertices || vertices->getNumElements()==0) return;
+
+    switch(vertices->getType())
     {
     case(Array::Vec2ArrayType): 
-        functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec2*>(_vertexData.array->getDataPointer()));
+        functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec2*>(vertices->getDataPointer()));
         break;
     case(Array::Vec3ArrayType): 
-        functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec3*>(_vertexData.array->getDataPointer()));
+        functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec3*>(vertices->getDataPointer()));
         break;
     case(Array::Vec4ArrayType): 
-        functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec4*>(_vertexData.array->getDataPointer()));
+        functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec4*>(vertices->getDataPointer()));
         break;
     case(Array::Vec2dArrayType): 
-        functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec2d*>(_vertexData.array->getDataPointer()));
+        functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec2d*>(vertices->getDataPointer()));
         break;
     case(Array::Vec3dArrayType): 
-        functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec3d*>(_vertexData.array->getDataPointer()));
+        functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec3d*>(vertices->getDataPointer()));
         break;
     case(Array::Vec4dArrayType): 
-        functor.setVertexArray(_vertexData.array->getNumElements(),static_cast<const Vec4d*>(_vertexData.array->getDataPointer()));
+        functor.setVertexArray(vertices->getNumElements(),static_cast<const Vec4d*>(vertices->getDataPointer()));
         break;
     default:
-        notify(WARN)<<"Warning: Geometry::accept(PrimitiveIndexFunctor&) cannot handle Vertex Array type"<<_vertexData.array->getType()<<std::endl;
+        notify(WARN)<<"Warning: Geometry::accept(PrimitiveIndexFunctor&) cannot handle Vertex Array type"<<vertices->getType()<<std::endl;
         return;
     }
Index: /OpenSceneGraph/trunk/src/osg/State.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osg/State.cpp (revision 10614)
+++ /OpenSceneGraph/trunk/src/osg/State.cpp (revision 10621)
@@ -45,4 +45,8 @@
     _modelView = _identity;
 
+    _modelViewMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ModelViewMatrix");
+    _projectionMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ProjectionMatrix");
+    _modelViewProjectionMatrixUniform = new Uniform(Uniform::FLOAT_MAT4,"osg_ModelViewProjectionMatrix");
+
     _abortRenderingPtr = false;    
 
@@ -91,4 +95,6 @@
     _maxTexturePoolSize = 0;
     _maxBufferObjectPoolSize = 0;
+
+
 }
 
@@ -421,5 +427,5 @@
     //popStateSet();
     //return;
-    
+
     if (dstate)
     {
@@ -441,39 +447,11 @@
                 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 1        
+
         applyUniformList(_uniformMap,dstate->getUniformList());
-#else                
-        if (_lastAppliedProgramObject)
-        {
-            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));
-                }
-            }
-
-            const StateSet::UniformList& uniformList = dstate->getUniformList();
-            for(StateSet::UniformList::const_iterator itr=uniformList.begin();
-                itr!=uniformList.end();
-                ++itr)
-            {
-                _lastAppliedProgramObject->apply(*(itr->second.first));
-            }
-        }
-#endif
-
     }
     else
@@ -509,25 +487,5 @@
     }
 
-#if 1        
     applyUniformMap(_uniformMap);
-#else        
-    if (_lastAppliedProgramObject && !_stateStateStack.empty())
-    {
-        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));
-            }
-        }
-    }
-#endif
-
 
     if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply()");
@@ -1034,2 +992,10 @@
 
 
+void State::applyModelViewAndProjectionUniformsIfRequired()
+{
+    if (!_lastAppliedProgramObject) return;
+
+    if (_modelViewMatrixUniform.valid()) _lastAppliedProgramObject->apply(*_modelViewMatrixUniform);
+    if (_projectionMatrixUniform) _lastAppliedProgramObject->apply(*_projectionMatrixUniform);
+    if (_modelViewProjectionMatrixUniform) _lastAppliedProgramObject->apply(*_modelViewProjectionMatrixUniform);
+}
Index: /OpenSceneGraph/trunk/examples/osgvertexattributes/osgvertexattributes.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osgvertexattributes/osgvertexattributes.cpp (revision 10620)
+++ /OpenSceneGraph/trunk/examples/osgvertexattributes/osgvertexattributes.cpp (revision 10621)
@@ -52,5 +52,5 @@
         }
 
-        void replaceAndBind(osg::Program& program, std::string& source, const std::string& originalStr, const AttributeAlias& alias, const std::string& declarationPrefix)
+        void replaceAndBindAttrib(osg::Program& program, std::string& source, const std::string& originalStr, const AttributeAlias& alias, const std::string& declarationPrefix)
         {
             if (replace(source, originalStr, alias.second))
@@ -61,4 +61,12 @@
         }
 
+        void replaceBuiltInUniform(std::string& source, const std::string& originalStr, const std::string& newStr, const std::string& declarationPrefix)
+        {
+            if (replace(source, originalStr, newStr))
+            {
+                source.insert(0, declarationPrefix + newStr + std::string(";\n"));
+            }
+        }
+
         void convertVertexShader(osg::Program& program, osg::Shader& shader)
         {
@@ -68,18 +76,18 @@
             replace(source, "ftransform()", "gl_ModelViewProjectionMatrix * gl_Vertex");
 
-            replaceAndBind(program, source, "gl_Normal", _normalAlias, "attribute vec3 ");
-            replaceAndBind(program, source, "gl_Vertex", _vertexAlias, "attribute vec4 ");
-            replaceAndBind(program, source, "gl_Color", _colorAlias, "attribute vec4 ");
-            replaceAndBind(program, source, "gl_SecondaryColor", _secondaryColorAlias, "attribute vec4 ");
-            replaceAndBind(program, source, "gl_FogCoord", _fogCoordAlias, "attribute float ");
-
-            replaceAndBind(program, source, "gl_MultiTexCoord0", _texCoordAlias[0], "attribute vec4 ");
-            replaceAndBind(program, source, "gl_MultiTexCoord1", _texCoordAlias[1], "attribute vec4 ");
-            replaceAndBind(program, source, "gl_MultiTexCoord2", _texCoordAlias[2], "attribute vec4 ");
-            replaceAndBind(program, source, "gl_MultiTexCoord3", _texCoordAlias[3], "attribute vec4 ");
-            replaceAndBind(program, source, "gl_MultiTexCoord4", _texCoordAlias[4], "attribute vec4 ");
-            replaceAndBind(program, source, "gl_MultiTexCoord5", _texCoordAlias[5], "attribute vec4 ");
-            replaceAndBind(program, source, "gl_MultiTexCoord6", _texCoordAlias[6], "attribute vec4 ");
-            replaceAndBind(program, source, "gl_MultiTexCoord7", _texCoordAlias[7], "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_Normal", _normalAlias, "attribute vec3 ");
+            replaceAndBindAttrib(program, source, "gl_Vertex", _vertexAlias, "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_Color", _colorAlias, "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_SecondaryColor", _secondaryColorAlias, "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_FogCoord", _fogCoordAlias, "attribute float ");
+
+            replaceAndBindAttrib(program, source, "gl_MultiTexCoord0", _texCoordAlias[0], "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_MultiTexCoord1", _texCoordAlias[1], "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_MultiTexCoord2", _texCoordAlias[2], "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_MultiTexCoord3", _texCoordAlias[3], "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_MultiTexCoord4", _texCoordAlias[4], "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_MultiTexCoord5", _texCoordAlias[5], "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_MultiTexCoord6", _texCoordAlias[6], "attribute vec4 ");
+            replaceAndBindAttrib(program, source, "gl_MultiTexCoord7", _texCoordAlias[7], "attribute vec4 ");
 
 
@@ -89,4 +97,9 @@
             replace(source, "gl_ModelViewProjectionMatrix", "osg_ModelViewProjectionMatrix");
             replace(source, "gl_ProjectionMatrix", "osg_ProjectionMatrix");
+#else
+            // replace built in uniform
+            replaceBuiltInUniform(source, "gl_ModelViewMatrix", "osg_ModeViewMatrix", "uniform mat4 ");
+            replaceBuiltInUniform(source, "gl_ModelViewProjectionMatrix", "osg_ModelViewProjectionMatrix", "uniform mat4 ");
+            replaceBuiltInUniform(source, "gl_ProjectionMatrix", "osg_ProjectionMatrix", "uniform mat4 ");
 #endif
             shader.setShaderSource(source);
