diff --git a/include/ACGL/OpenGL/Objects.hh b/include/ACGL/OpenGL/Objects.hh
index 6c73332807e6db8a92c3c23c48331c19211027c7..3da8f33bcc100881a3becfaaf076e467d4ce749f 100644
--- a/include/ACGL/OpenGL/Objects.hh
+++ b/include/ACGL/OpenGL/Objects.hh
@@ -16,6 +16,7 @@
 #include <ACGL/OpenGL/Objects/ElementArrayBuffer.hh>
 #include <ACGL/OpenGL/Objects/FrameBufferObject.hh>
 #include <ACGL/OpenGL/Objects/RenderBuffer.hh>
+#include <ACGL/OpenGL/Objects/UniformBuffer.hh>
 #include <ACGL/OpenGL/Objects/RenderObject.hh>
 #include <ACGL/OpenGL/Objects/Shader.hh>
 #include <ACGL/OpenGL/Objects/ShaderProgram.hh>
diff --git a/include/ACGL/OpenGL/Objects/Buffer.hh b/include/ACGL/OpenGL/Objects/Buffer.hh
index a333bab6e0c8a8e561937379b2d602f7506ede83..08ff352caa3b36006b8637b3acc44ed032d747b7 100644
--- a/include/ACGL/OpenGL/Objects/Buffer.hh
+++ b/include/ACGL/OpenGL/Objects/Buffer.hh
@@ -150,6 +150,7 @@ public:
     inline GLint     getAccessFlags() { return (GLint)     getParameter  ( GL_BUFFER_ACCESS_FLAGS ); }
     inline GLboolean isMapped()       { return (GLboolean) getParameter  ( GL_BUFFER_MAPPED       ); }
 
+    //! the size is in bytes
     inline GLint64   getSize()        { return mSize; }
 
     //! Bind this buffer
@@ -233,8 +234,29 @@ public:
         flushMappedRange( mTarget, _offset, _length );
     }
 
-    // TODO: bindBufferRange
-    // TODO: bindBufferBase
+    //! valid targets are only GL_TRANSFORM_FEEDBACK_BUFFER and GL_UNIFORM_BUFFER
+    inline void bindBufferRange( GLenum _target, GLuint _index, GLintptr _offset, GLsizeiptr _size ) {
+        glBindBufferRange( _target, _index, mBuffer->mObjectName, _offset, _size );
+    }
+
+    //! maps a subset of the buffer defined by _offset and _size
+    //! valid targets are only GL_TRANSFORM_FEEDBACK_BUFFER and GL_UNIFORM_BUFFER
+    inline void bindBufferRange( GLuint _index, GLintptr _offset, GLsizeiptr _size ) {
+        glBindBufferRange( mTarget, _index, mBuffer->mObjectName, _offset, _size );
+    }
+
+    //! maps the full buffer to the given index (binding point)
+    //! valid targets are only GL_TRANSFORM_FEEDBACK_BUFFER and GL_UNIFORM_BUFFER
+    inline void bindBufferBase( GLenum _target, GLuint _index ) {
+        glBindBufferBase( _target, _index, mBuffer->mObjectName );
+    }
+
+    //! maps the full buffer to the given index (binding point)
+    //! valid targets are only GL_TRANSFORM_FEEDBACK_BUFFER and GL_UNIFORM_BUFFER
+    inline void bindBufferBase( GLuint _index ) {
+        glBindBufferBase( mTarget, _index, mBuffer->mObjectName );
+    }
+
 #endif // OpenGL >= 3.0
 
     //! Maps the whole buffer, if using GL 3+, better use mapRange!
diff --git a/include/ACGL/OpenGL/Objects/ShaderProgram.hh b/include/ACGL/OpenGL/Objects/ShaderProgram.hh
index 0e928e90a0dd6506a6262f03ba0aca0a86ec1ddb..a3dcb3b45c8242449c2d9b71cbdc3ce05833cb5e 100644
--- a/include/ACGL/OpenGL/Objects/ShaderProgram.hh
+++ b/include/ACGL/OpenGL/Objects/ShaderProgram.hh
@@ -110,12 +110,29 @@ public:
     // =========================================================================================== LOCATIONS \/
     // ===================================================================================================== \/
 
-    //////////// uniform locations:
-    inline GLint getUniformLocation      (const std::string& _nameInShader) const { return glGetUniformLocation (mObjectName, _nameInShader.c_str()); }
+    //////////// uniform (block) locations:
+    inline GLint getUniformLocation    (const std::string& _nameInShader) const { return glGetUniformLocation (mObjectName, _nameInShader.c_str()); }
+
+#if (ACGL_OPENGL_VERSION >= 31)
+    //! if the block name does not exist, GL_INVALID_INDEX will get returned
+    inline GLuint getUniformBlockIndex (const std::string& _nameInShader) { return glGetUniformBlockIndex(mObjectName, _nameInShader.c_str()); }
+
+    inline void   setUniformBlockBinding( GLuint            _blockIndex, GLuint _bindingPoint ) { glUniformBlockBinding( mObjectName, _blockIndex, _bindingPoint ); }
+    inline void   setUniformBlockBinding( const std::string& _blockName, GLuint _bindingPoint ) { glUniformBlockBinding( mObjectName, getUniformBlockIndex(_blockName), _bindingPoint ); }
+
+    //! returns a mapping from the uniforms in a given block to the offset within the block
+    SharedLocationMappings getUniformOffsetsOfBlock( const std::string &_blockName  ) { return getUniformOffsetsOfBlock(getUniformBlockIndex(_blockName)); }
+    SharedLocationMappings getUniformOffsetsOfBlock( GLuint             _blockIndex );
+
+    //! returns the size in bytes of the uniform block, can be used to allocate the right amount of memory
+    GLsizeiptr getUniformBlockSize( const std::string &_blockName  ) { return getUniformBlockSize(getUniformBlockIndex(_blockName)); }
+    GLsizeiptr getUniformBlockSize( GLuint             _blockIndex );
+
+#endif // OpenGL >= 3.1
 
     //////////// attribute locations:
-    inline GLint getAttributeLocation    (const std::string& _nameInShader) const { return glGetAttribLocation  (mObjectName, _nameInShader.c_str()); }
-    inline void bindAttributeLocation    (const std::string& _nameInShader, GLuint _location) const { glBindAttribLocation   (mObjectName, _location, _nameInShader.c_str()); }
+    inline GLint getAttributeLocation  (const std::string& _nameInShader) const { return glGetAttribLocation  (mObjectName, _nameInShader.c_str()); }
+    inline void bindAttributeLocation  (const std::string& _nameInShader, GLuint _location) const { glBindAttribLocation   (mObjectName, _location, _nameInShader.c_str()); }
 
     //! Sets the attribute locations of this ShaderProgram according to the mappings specified in
     void setAttributeLocations( ConstSharedLocationMappings _locationMappings );
@@ -124,6 +141,7 @@ public:
 
     //////////// fragdata locations:
 #if (ACGL_OPENGL_VERSION >= 30)
+    //! if the location does not exist, -1 will get returned
     inline GLint getFragmentDataLocation (const std::string& _nameInShader) const { return glGetFragDataLocation(mObjectName, _nameInShader.c_str()); }
     inline void bindFragmentDataLocation (const std::string& _nameInShader, GLuint _location) const { glBindFragDataLocation (mObjectName, _location, _nameInShader.c_str()); }
 
diff --git a/include/ACGL/OpenGL/Objects/UniformBuffer.hh b/include/ACGL/OpenGL/Objects/UniformBuffer.hh
new file mode 100644
index 0000000000000000000000000000000000000000..4a097f533787b143394c40f5e823f7bdd0333b2f
--- /dev/null
+++ b/include/ACGL/OpenGL/Objects/UniformBuffer.hh
@@ -0,0 +1,101 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2012, Computer Graphics Group RWTH Aachen University         //
+// All rights reserved.                                                       //
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef ACGL_OPENGL_OBJECTS_UNIFORM_BUFFER_HH
+#define ACGL_OPENGL_OBJECTS_UNIFORM_BUFFER_HH
+
+#include <ACGL/ACGL.hh>
+
+#include <ACGL/Base/Macros.hh>
+#include <ACGL/OpenGL/GL.hh>
+#include <ACGL/OpenGL/Tools.hh>
+#include <ACGL/OpenGL/Objects/Buffer.hh>
+
+#include <ACGL/OpenGL/Objects/LocationMappings.hh>
+#include <ACGL/Math/Math.hh>
+
+namespace ACGL{
+namespace OpenGL{
+
+/**
+ * An OpenGL Uniform Buffer Object that can be used to share blocks of uniforms between multiple ShaderPrograms.
+ */
+
+#if (ACGL_OPENGL_VERSION >= 31)
+
+class UniformBuffer : public Buffer
+{
+    // ========================================================================================================= \/
+    // ============================================================================================ CONSTRUCTORS \/
+    // ========================================================================================================= \/
+public:
+    UniformBuffer()
+        : Buffer(GL_UNIFORM_BUFFER)
+    {}
+
+    UniformBuffer( SharedBufferObject _pBuffer )
+         : Buffer(_pBuffer, GL_UNIFORM_BUFFER)
+    {}
+
+    // ==================================================================================================== \/
+    // ============================================================================================ GETTERS \/
+    // ==================================================================================================== \/
+public:
+    GLint getUniformOffset (const std::string& _nameInShader) const {
+        if (!uniformNameToOffsetMap) return -1;
+        return uniformNameToOffsetMap->getLocation(_nameInShader);
+    }
+    void setUniformOffsets (SharedLocationMappings _uniformNameToOffsetMap) { uniformNameToOffsetMap = _uniformNameToOffsetMap; }
+
+    // ==================================================================================================== \/
+    // ============================================================================================ SETTERS \/
+    // ==================================================================================================== \/
+public:
+    //! reserve a number of bytes on the GPU for uniforms
+    inline void reserveMemory(GLsizeiptr _size){ setData( _size, NULL, GL_STREAM_DRAW ); }
+
+    // for scalar types:
+    inline void setUniform (const std::string &_nameInShader, GLfloat   _v) { setUniformScalar<GLfloat>  (_nameInShader, _v); }
+    inline void setUniform (const std::string &_nameInShader, GLint     _v) { setUniformScalar<GLint>    (_nameInShader, _v); }
+    inline void setUniform (const std::string &_nameInShader, GLuint    _v) { setUniformScalar<GLuint>   (_nameInShader, _v); }
+    inline void setUniform (const std::string &_nameInShader, GLboolean _v) { setUniformScalar<GLboolean>(_nameInShader, _v); }
+    inline void setUniform (const std::string &_nameInShader, GLdouble  _v) { setUniformScalar<GLdouble> (_nameInShader, _v); }
+
+    // for GLM types:
+    template <typename T>
+    void setUniform (const std::string &_nameInShader, T _v) {
+        GLint offset = getUniformOffset( _nameInShader );
+        if (offset == -1) {
+            ACGL::Utils::error() << "UniformBuffer does not know uniform " << _nameInShader << std::endl;
+            return;
+        }
+        setSubData( offset, sizeof(T), glm::value_ptr(_v) );
+    }
+
+    // =================================================================================================== \/
+    // ============================================================================================ FIELDS \/
+    // =================================================================================================== \/
+private:
+    // for scalar types:
+    template <typename T>
+    void setUniformScalar (const std::string &_nameInShader, T _v) {
+        GLint offset = getUniformOffset( _nameInShader );
+        if (offset == -1) {
+            ACGL::Utils::error() << "UniformBuffer does not know uniform " << _nameInShader << std::endl;
+            return;
+        }
+        setSubData( offset, sizeof(T), &_v );
+    }
+
+    SharedLocationMappings uniformNameToOffsetMap;
+};
+
+ACGL_SMARTPOINTER_TYPEDEFS(UniformBuffer)
+#endif // OpenGL >= 3.1
+
+} // OpenGL
+} // ACGL
+
+#endif // ACGL_OPENGL_OBJECTS_UNIFORM_BUFFER_HH
diff --git a/src/ACGL/OpenGL/Objects/ShaderProgram.cc b/src/ACGL/OpenGL/Objects/ShaderProgram.cc
index b24b6740b1e22e94725bb73ea3e39433ac8561d7..f1aaef31e3edce9fd34814daf3f5cfff817e546b 100644
--- a/src/ACGL/OpenGL/Objects/ShaderProgram.cc
+++ b/src/ACGL/OpenGL/Objects/ShaderProgram.cc
@@ -133,14 +133,14 @@ SharedLocationMappings ShaderProgram::getAttributeLocations()
         GLint   size;
         GLsizei length;
         glGetActiveAttrib( mObjectName, i, longestAttributeName, &length, &size, &type, name );
-        name[ length+1 ] = 0; // null terminate
+        name[ length+1 ] = 0; // null terminate string
 
         GLint attribLocation = glGetAttribLocation( mObjectName, name );
 
         locationMap->setLocation( std::string(name), (GLuint) attribLocation );
     }
 
-    delete name;
+    delete[] name;
     return locationMap;
 }
 
@@ -153,3 +153,53 @@ SharedLocationMappings ShaderProgram::getFragmentDataLocations()
     return locationMap;
 }
 
+SharedLocationMappings ShaderProgram::getUniformOffsetsOfBlock( GLuint _blockIndex )
+{
+    SharedLocationMappings locationMap = SharedLocationMappings( new LocationMappings() );
+
+    if (_blockIndex == GL_INVALID_INDEX) return locationMap; // block does not exist
+
+    // query the number of _active_ uniforms:
+    GLint uniformCount;
+    glGetProgramiv( mObjectName, GL_ACTIVE_UNIFORMS, &uniformCount );
+    if (uniformCount == 0) return locationMap;
+
+    // reserve a string long enought for the longest name:
+    GLint longestUniformName;
+    glGetProgramiv( mObjectName, GL_ACTIVE_UNIFORM_MAX_LENGTH,  &longestUniformName );
+    char *name = new char[longestUniformName+1];
+
+    // get the name and location of each active attribute:
+    for (int i = 0; i < uniformCount; ++i) {
+        GLsizei length;
+        glGetActiveUniformName( mObjectName, i, longestUniformName, &length, name );
+
+        name[ length+1 ] = 0; // null terminate string
+
+        GLuint idx = i;
+        GLint uniformBlockIndex;
+        glGetActiveUniformsiv( mObjectName, 1, &idx, GL_UNIFORM_BLOCK_INDEX, &uniformBlockIndex );
+
+        if (uniformBlockIndex != -1) {
+            if ((GLuint)uniformBlockIndex == _blockIndex) {
+                GLint offset;
+                glGetActiveUniformsiv( mObjectName, 1, &idx, GL_UNIFORM_OFFSET, &offset );
+                //ACGL::Utils::message() << "uniform " << i << " is " << name << " block: " << uniformBlockIndex << " offset: " << offset << std::endl;
+                locationMap->setLocation( std::string(name), (GLuint) offset );
+            }
+        }
+    }
+
+    delete[] name;
+    return locationMap;
+}
+
+GLsizeiptr ShaderProgram::getUniformBlockSize( GLuint _blockIndex )
+{
+    if (_blockIndex == GL_INVALID_INDEX) return 0; // block does not exist
+
+    GLint uniformBlockSize;
+    glGetActiveUniformBlockiv( mObjectName, _blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlockSize);
+
+    return (GLsizeiptr) uniformBlockSize;
+}
diff --git a/src/ACGL/OpenGL/Objects/UniformBuffer.cc b/src/ACGL/OpenGL/Objects/UniformBuffer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f0115a08d176728debc40b47ef4d7b3c1fc23bec
--- /dev/null
+++ b/src/ACGL/OpenGL/Objects/UniformBuffer.cc
@@ -0,0 +1,15 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University         //
+// All rights reserved.                                                       //
+////////////////////////////////////////////////////////////////////////////////
+
+#include <ACGL/OpenGL/Objects/UniformBuffer.hh>
+
+using namespace ACGL;
+using namespace ACGL::OpenGL;
+
+#if (ACGL_OPENGL_VERSION >= 31)
+
+
+
+#endif // OpenGL 3.1