diff --git a/include/ACGL/OpenGL/Objects/ArrayBuffer.hh b/include/ACGL/OpenGL/Objects/ArrayBuffer.hh
index 1f9a7dd2cddc0d7fa780ba3f181c742de9b0bb5b..5f5ef85eca1c0481645445353362318ec780dd4b 100644
--- a/include/ACGL/OpenGL/Objects/ArrayBuffer.hh
+++ b/include/ACGL/OpenGL/Objects/ArrayBuffer.hh
@@ -24,6 +24,33 @@
  *       itself are called ArrayBuffer and ElementArrayBuffer.
  */
 
+/***************************************************************************************************************
+ * Attributes:
+ *************
+ *
+ * _type is the GL type
+ * _size the number of elements in this attribute (1..4)
+ * _normalized is the attribute normalization for int types
+ *
+ * Want to add tightly packed attributes in order?
+ *  -> use defineAttribute()
+ *
+ * Want to add attributes with individual padding in order?
+ *  -> use defineAttributeWithPadding()
+ *
+ * Want to add attributes out-of-order?
+ *  -> use defineAttributeWithOffset()
+ *
+ * The stride size gets always set to the minimal stride size that covers all defined attributes (/w padding).
+ * All define methods can get mixed!
+ *
+ *
+ * ab->defineAttribute(            "pos",       GL_FLOAT, 3    ); // stride: 12 bytes
+ * ab->defineAttributeWithPadding( "color",     GL_CHAR,  3, 1 ); // stride: 12 + 3 + 1 = 16 bytes
+ * ab->defineAttributeWithOffset(  "colorNorm", GL_CHAR,  3, 12, GL_TRUE ); // stride is still 16 as 12+3 <= 16!
+ *
+ **************************************************************************************************************/
+
 #include <ACGL/ACGL.hh>
 
 #include <ACGL/Base/Macros.hh>
@@ -49,9 +76,9 @@ public:
     {
         std::string name;       // human readable name, can be used to match the attribute to shader programs
         GLenum      type;       // GL_FLOAT, GL_UNSIGNED_BYTE etc.
-        GLint       size;       // #elements per attribute
+        GLint       size;       // #elements per attribute, size in bytes would be: size*sizeof(type)
         GLuint      offset;     // offset in bytes into the array
-        GLboolean   normalized; // int types can get normalzed to 0..1 / -1..1 by GL
+        GLboolean   normalized; // int types can get normalzed to 0..1 / -1..1 by GL, useful e.g. for colors
     };
 
     // ===================================================================================================== \/
@@ -80,39 +107,20 @@ public:
     // ============================================================================================ GETTERS \/
     // ==================================================================================================== \/
 public:
+
+    //! often the number of vertices:
     inline       GLsizei       getElements   (void) const { return mSize/mStride; }
+
+    //! size in bytes of all attributes that make up one element (vertex):
     inline       GLsizei       getStride     (void) const { return mStride;     }
+
+    //! Returns the definitions of the attributes:
     inline const AttributeVec& getAttributes (void) const { return mAttributes; }
 
     // ==================================================================================================== \/
     // ============================================================================================ METHODS \/
     // ==================================================================================================== \/
 public:
-    //int_t getAttributeIndexByName(const std::string& _nameInArray) const;
-
-    /* Attributes:
-     *
-     * _type is the GL type
-     * _size the number of elements in this attribute (1..4)
-     * _normalized is the attribute normalization for int types
-     *
-     * Want to add tightly packed attributes in order?
-     *  -> use defineAttribute()
-     *
-     * Want to add attributes with individual padding in order?
-     *  -> use defineAttributeWithPadding()
-     *
-     * Want to add attributes out-of-order?
-     *  -> use defineAttributeWithOffset()
-     *
-     * The stride size gets always set to the minimal stride size that covers all defined attributes (/w padding).
-     * All define methods can get mixed!
-     *
-     *
-     * ab->defineAttribute(            "pos",       GL_FLOAT, 3    ); // stride: 12 bytes
-     * ab->defineAttributeWithPadding( "color",     GL_CHAR,  3, 1 ); // stride: 12 + 3 + 1 = 16 bytes
-     * ab->defineAttributeWithOffset(  "colorNorm", GL_CHAR,  3, 12, GL_TRUE ); // stride is still 16 as 12+3 <= 16!
-     */
     //! Adds the attribute at the end of the existing attributes, stride gets computed automatically
     void defineAttribute(
         const std::string& _name,
@@ -121,13 +129,12 @@ public:
         GLboolean _normalized = GL_FALSE)
     {
         GLuint offset = mStride;
-
         Attribute attribute = { _name, _type, _size, offset, _normalized };
         defineAttribute(attribute);
     }
 
     //! Adds the attribute at the end of the existing attributes, stride gets computed automatically
-    //! + extra padding in bytes
+    //! + extra padding in bytes at the end
     void defineAttributeWithPadding(
         const std::string& _name,
         GLenum _type,
@@ -135,7 +142,8 @@ public:
         GLuint _padding,
         GLboolean _normalized = GL_FALSE)
     {
-        Attribute attribute = { _name, _type, _size, (GLuint)mStride, _normalized };
+        GLuint offset = mStride;
+        Attribute attribute = { _name, _type, _size, offset, _normalized };
         defineAttribute(attribute);
         // defineAttribute will shift the mStride to the end of this attribute, so we only have to
         // add the explicit padding:
@@ -143,7 +151,8 @@ public:
     }
 
     //! Adds an attribute defined by an offset: this way an attribute can get added at arbitrary
-    //! locations in the stride. If it's added at the end, the stride gets resized.
+    //! locations in the stride. If it's added at the end, the stride gets resized. This way attributes can even
+    //! overlap, hope you know what you're doing...
     void defineAttributeWithOffset(
         const std::string& _name,
         GLenum _type,
@@ -159,8 +168,8 @@ public:
     void defineAttribute( const Attribute &_attribute )
     {
         // this way attribute definitions don't have to be in order!
-        mStride = std::max( (GLsizei)_attribute.offset + getGLTypeSize(_attribute.type)*_attribute.size,
-                                     mStride);
+        GLsizei attributeWidth = getGLTypeSize(_attribute.type)*_attribute.size; // in bytes
+        mStride = std::max( (GLsizei)_attribute.offset + attributeWidth, mStride);
         mAttributes.push_back( _attribute );
     }
 
diff --git a/include/ACGL/OpenGL/Objects/Buffer.hh b/include/ACGL/OpenGL/Objects/Buffer.hh
index 63ad3e1f65b5ea4c1de8d7092b7226ad1cc43f14..25ce2a23f35bbe3bdab85ccc8e13254cf984085e 100644
--- a/include/ACGL/OpenGL/Objects/Buffer.hh
+++ b/include/ACGL/OpenGL/Objects/Buffer.hh
@@ -31,7 +31,7 @@ namespace ACGL{
 namespace OpenGL{
 
 
-/*
+/**
  * A minimal(!) wrapper to allow multiple Buffer objects pointing to the same
  * OpenGL resource (like an ArrayBuffer and a TransformFeedbackBuffer).
  *
@@ -39,6 +39,7 @@ namespace OpenGL{
  * below to allow a unified API.
  */
 class BufferObject {
+    ACGL_NOT_COPYABLE(BufferObject)
 public:
     BufferObject()
     {
diff --git a/include/ACGL/OpenGL/Objects/ElementArrayBuffer.hh b/include/ACGL/OpenGL/Objects/ElementArrayBuffer.hh
index b20fe8126676a54cc1d7f76720daed6d6a4bc3bd..86f1f66cdd28105d34929ba5746b944f17e2b61b 100644
--- a/include/ACGL/OpenGL/Objects/ElementArrayBuffer.hh
+++ b/include/ACGL/OpenGL/Objects/ElementArrayBuffer.hh
@@ -62,15 +62,16 @@ public:
         mType = _type;
     }
 
+    //! Returns the number of indices:
+    GLuint getElements() {
+        return getSize() / getGLTypeSize(mType);
+    }
+
     //! Overloaded from the base class to _prevent_ redefining of the binding target! (see Buffer)
     inline void setTarget( GLenum ) {
         ACGL::Utils::error() << "DON'T redefine the target binding point of an ElementArrayBuffer" << std::endl;
     }
 
-    GLuint getElements() {
-        return getSize() / getGLTypeSize(mType);
-    }
-
     // =================================================================================================== \/
     // ============================================================================================ FIELDS \/
     // =================================================================================================== \/
diff --git a/include/ACGL/OpenGL/Objects/FrameBufferObject.hh b/include/ACGL/OpenGL/Objects/FrameBufferObject.hh
index 47de2190a0c18b5aaede8353233e3ec1da5f2854..1085e78e153b9bac622134dc096324f73644f983 100644
--- a/include/ACGL/OpenGL/Objects/FrameBufferObject.hh
+++ b/include/ACGL/OpenGL/Objects/FrameBufferObject.hh
@@ -140,15 +140,7 @@ public:
         openGLRareError();
     }*/
 
-    inline bool isFrameBufferObjectComplete(void) const
-    {
-        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
-        {
-            Utils::error() << "Failed to make complete FrameBufferObject object: " << (glCheckFramebufferStatus(GL_FRAMEBUFFER)) << std::endl;
-            return false;
-        }
-        return true;
-    }
+    bool isFrameBufferObjectComplete() const;
 
     inline bool attachColorRenderBuffer(const std::string _name, const ConstSharedRenderBuffer& _renderBuffer)
     {
diff --git a/include/ACGL/OpenGL/Objects/LocationMappings.hh b/include/ACGL/OpenGL/Objects/LocationMappings.hh
index fc8d9f45f076188a4e070e211c27dcc6ec8bd06f..0e7c69634b17759f00b9d86a214e84c661b69116 100644
--- a/include/ACGL/OpenGL/Objects/LocationMappings.hh
+++ b/include/ACGL/OpenGL/Objects/LocationMappings.hh
@@ -6,24 +6,39 @@
 #ifndef ACGL_OPENGL_OBJECTS_LOCATIONMAPPINGS_HH
 #define ACGL_OPENGL_OBJECTS_LOCATIONMAPPINGS_HH
 
+/*
+ * LocationMappings is a map from strings to GLuints that stores the mappings from
+ *
+ *    attribute names  to  attribute locations
+ *                     or
+ *    fragment outputs to  fragdata locations
+ *
+ * A mapping like this can be used to init all mappings of multiple ShaderProgram
+ * in the same way to they can be used with the same VAOs or FBOs, similar, these
+ * mapping objects can be used to configute VAOs and FBOs!
+ *
+ * To fully automate the mappings in a program the creation of these mappings can
+ * be done automatically by parsing shader sources, querying locations and names from
+ * ShaderPrograms or any other way that best suits the use case of the application.
+ */
+
 #include <map>
 #include <string>
 
 #include <ACGL/ACGL.hh>
 #include <ACGL/Base/Macros.hh>
+#include <ACGL/OpenGL/GL.hh>
 
 namespace ACGL{
 namespace OpenGL{
 
 class LocationMappings
 {
-    ACGL_NOT_COPYABLE(LocationMappings)
-
     // ===================================================================================================== \/
     // ============================================================================================ TYPEDEFS \/
     // ===================================================================================================== \/
 public:
-    typedef std::map< std::string, int_t > LocationMap;
+    typedef std::map< std::string, GLuint > LocationMap;
 
     // ========================================================================================================= \/
     // ============================================================================================ CONSTRUCTORS \/
@@ -40,11 +55,12 @@ public:
     // ============================================================================================ GETTERS \/
     // ==================================================================================================== \/
 public:
-    inline int_t getLocation(const std::string& _name) const
+    //! Returns the stored location for a given name or -1 if the name could not get found (similar to how GL behaves)
+    GLint getLocation(const std::string& _name) const
     {
         if(exists(_name))
         {
-            return mMappings.at(_name);
+            return (GLint) mMappings.at(_name);
         }
         else
         {
@@ -52,15 +68,18 @@ public:
         }
     }
 
-    inline const LocationMap& getLocations() const { return mMappings; }
+    //! Returns the raw location map:
+    const LocationMap& getLocations() const { return mMappings; }
 
     // ==================================================================================================== \/
     // ============================================================================================ SETTERS \/
     // ==================================================================================================== \/
 public:
-    inline void setLocation(const std::string& _name, int_t _location)
+
+    //! Adds one location:
+    inline void setLocation(const std::string& _name, GLuint _location)
     {
-        if(exists(_name))
+        if (exists(_name) && (mMappings[_name] != _location))
         {
             ACGL::Utils::warning() << "LocationMappings: Overwriting location mapping for " << _name;
             ACGL::Utils::warning() << " (previous value: " << mMappings[_name] << ", new value: " << _location<< ")" << std::endl;
diff --git a/include/ACGL/OpenGL/Objects/ShaderProgram.hh b/include/ACGL/OpenGL/Objects/ShaderProgram.hh
index 9a90e5f08f3f003026726547467af27e9a793585..e1dd512fea3bcd4651416c8f84b642247f3c6079 100644
--- a/include/ACGL/OpenGL/Objects/ShaderProgram.hh
+++ b/include/ACGL/OpenGL/Objects/ShaderProgram.hh
@@ -46,7 +46,6 @@
 #include <ACGL/OpenGL/GL.hh>
 #include <ACGL/OpenGL/Objects/Shader.hh>
 #include <ACGL/OpenGL/Objects/Texture.hh>
-//#include <ACGL/OpenGL/Objects/FrameBufferObject.hh>
 #include <ACGL/OpenGL/Objects/LocationMappings.hh>
 #include <ACGL/Math/Math.hh>
 
@@ -55,11 +54,11 @@
 namespace ACGL{
 namespace OpenGL{
 
-class VertexArrayObject;
-ACGL_SHARED_TYPEDEF(VertexArrayObject)
+//class VertexArrayObject;
+//ACGL_SHARED_TYPEDEF(VertexArrayObject)
 
-class FrameBufferObject;
-ACGL_SHARED_TYPEDEF(FrameBufferObject)
+//class FrameBufferObject;
+//ACGL_SHARED_TYPEDEF(FrameBufferObject)
 
 class ShaderProgram
 {
@@ -123,11 +122,10 @@ public:
     // ============================================================================================= METHODS \/
     // ===================================================================================================== \/
 public:
-    //! Matches the attribute locations of this ShaderProgram to the names of the ArrayBuffer attributes currently attached to _vao
-    void setAttributeLocationsByVAO( ConstSharedVertexArrayObject _vao );
-
-    //! Matches the fragment data locations of this ShaderProgram to the names of the color attachments of _fbo
-    void setFragmentDataLocationsByFBO( ConstSharedFrameBufferObject _fbo );
+    // Matches the attribute locations of this ShaderProgram to the names of the ArrayBuffer attributes currently attached to _vao
+    //void setAttributeLocationsByVAO( ConstSharedVertexArrayObject _vao );
+    // Matches the fragment data locations of this ShaderProgram to the names of the color attachments of _fbo
+    //void setFragmentDataLocationsByFBO( ConstSharedFrameBufferObject _fbo );
 
     //! Sets the attribute locations of this ShaderProgram according to the mappings specified in
     void setAttributeLocations( ConstSharedLocationMappings _locationMappings );
@@ -245,9 +243,22 @@ public:
     inline void setProgramUniform (GLint _location, const glm::dmat4&   _v, GLboolean _transpose = GL_FALSE) const { glProgramUniformMatrix4dv  (mObjectName, _location, 1, _transpose, glm::value_ptr(_v)); }
 #endif // OpenGL >= 4.0
 
-    // texture
-    inline void setTexture        (GLint _location,                  const ConstSharedTexture& _texture, GLenum _unit = 0) const { glUniform1i(_location, _unit);                                        _texture->bind(_unit); }
-    inline void setProgramTexture (const std::string& _nameInShader, const ConstSharedTexture& _texture, GLenum _unit = 0) const { setProgramUniform( getUniformLocation(_nameInShader), (GLint) _unit); _texture->bind(_unit); }
+    //! sets a texture uniform to a given texture unit and also binds the texture to the same unit
+    inline void setTexture        (GLint _location,                  const ConstSharedTexture& _texture, GLenum _unit) const { glUniform1i(_location, _unit);                                        _texture->bind(_unit); }
+    inline void setTexture        (const std::string& _nameInShader, const ConstSharedTexture& _texture, GLenum _unit) const { setUniform( getUniformLocation(_nameInShader), (GLint) _unit);        _texture->bind(_unit); }
+    inline void setProgramTexture (GLint _location,                  const ConstSharedTexture& _texture, GLenum _unit) const { glProgramUniform1i(mObjectName, _location, _unit);                    _texture->bind(_unit); }
+    inline void setProgramTexture (const std::string& _nameInShader, const ConstSharedTexture& _texture, GLenum _unit) const { setProgramUniform( getUniformLocation(_nameInShader), (GLint) _unit); _texture->bind(_unit); }
+
+    //! set the texture to the texture unit the uniform is set to.
+    //! Note: it is not guaranteed that all uniforms for textures are set to unique samplers by default after linking!
+    void setTexture( const std::string& _nameInShader, const ConstSharedTexture& _texture ) {
+        GLint unit;
+        GLint uniformLocation = getUniformLocation(_nameInShader);
+        if ( uniformLocation != -1 ) {
+            glGetUniformiv( mObjectName, uniformLocation, &unit );
+            _texture->bind( unit );
+        }
+    }
 
     // ======================================================================================================= \/
     // ============================================================================================ HIGH LEVEL \/
@@ -295,9 +306,6 @@ public:
         setProgramUniform( getUniformLocation(_nameInShader), _v, _transpose);
     }
 
-    inline void setTexture        (const std::string& _nameInShader, const ConstSharedTexture& _texture, GLenum _unit = 0) const { setUniform( getUniformLocation(_nameInShader), (GLint) _unit);        _texture->bind(_unit); }
-    inline void setProgramTexture (GLint _location,                  const ConstSharedTexture& _texture, GLenum _unit = 0) const { glProgramUniform1i(mObjectName, _location, _unit);                    _texture->bind(_unit); }
-
     // =================================================================================================== \/
     // ============================================================================================ FIELDS \/
     // =================================================================================================== \/
diff --git a/include/ACGL/OpenGL/Objects/VertexArrayObject.hh b/include/ACGL/OpenGL/Objects/VertexArrayObject.hh
index 0cfa7c39a2577a921e296521a5d3b2826c05541a..67f0aef584d2ad8aa6ee084e72743b90b6e42d23 100755
--- a/include/ACGL/OpenGL/Objects/VertexArrayObject.hh
+++ b/include/ACGL/OpenGL/Objects/VertexArrayObject.hh
@@ -253,6 +253,7 @@ public:
      * Query the attribute locations based on the attribute names in the ArrayBuffers and the ShaderProgram
      * If they match, use the location reported from the ShaderProgram.
      */
+    /*
     void setAttributeLocationsByShaderProgram( const SharedShaderProgram &_shaderProgram )
     {
         // TODO: deprecate
@@ -296,82 +297,19 @@ public:
 
             disable();
         }
-    }
+    }*/
 
     /**
-     * Query the attribute locations based on the attribute names in the ArrayBuffers and the ShaderProgram
-     * If they match, use the location reported from the ShaderProgram.
+     * Query the attribute locations based on the attribute names in the ArrayBuffers.
+     * If they match, use the location reported from _locationMappings.
      */
-    void setAttributeLocations( ConstSharedLocationMappings _locationMappings )
-    {
-        bool fullUpdateNeeded = false;
-
-        for (AttributeVec::size_type i = 0; i < mAttributes.size(); ++i)
-        {
-            std::string attributeName = mAttributes[i].arrayBuffer->getAttributes()[ mAttributes[i].attributeID ].name;
-            int_t       location      = _locationMappings->getLocation(attributeName);
-
-            if(location == -1)
-            {
-                // TODO: fail silently?
-                ACGL::Utils::error() << "can't update VAO mappings: attribute " << attributeName << " not specified" << std::endl;
-                continue; // try to match as much as possible
-            }
-
-            if(mAttributes[i].location != location)
-            {
-                mAttributes[i].location = location;
-                fullUpdateNeeded = true;
-            }
-        }
-
-        // why the full update? setting the new location right when a change is detected will get problamatic
-        // if two attributes exchange there position...
-        if (fullUpdateNeeded)
-        {
-            enable();
-
-            // disable all attributes
-            GLint maxAttributes;
-            glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &maxAttributes );
-            for (GLint i = 0; i < maxAttributes; ++i)
-                glDisableVertexAttribArray( i );
-
-            // set all attributes:
-            for (uint32_t i = 0; i < mAttributes.size(); ++i)
-            {
-                setAttributePointer(mAttributes[i]);
-            }
-
-            disable();
-        }
-    }
+    void setAttributeLocations( ConstSharedLocationMappings _locationMappings );
 
 private:
     //! Sets the vertex attribute pointer for the current VAO according to the specified attribute data
     //! Note: expects that this VAO is currently bound
     //! Note: will bind the ArrayBuffer referenced by _attribute.arrayBuffer
-    void setAttributePointer(const Attribute& _attribute)
-    {
-        if(_attribute.location == -1)
-        {
-            // An attribute location of -1 indicates that this attribute should remain unbound for now
-            return;
-        }
-
-        SharedArrayBuffer arrayBuffer = _attribute.arrayBuffer;
-        arrayBuffer->bind();
-
-        ArrayBuffer::Attribute arrayBufferAttribute = arrayBuffer->getAttributes()[_attribute.attributeID];
-        glVertexAttribPointer(_attribute.location,
-                              arrayBufferAttribute.size,
-                              arrayBufferAttribute.type,
-                              arrayBufferAttribute.normalized,
-                              arrayBuffer->getStride(),
-                              reinterpret_cast<GLvoid*>(arrayBufferAttribute.offset)
-                              );
-        glEnableVertexAttribArray(_attribute.location);
-    }
+    void setAttributePointer(const Attribute& _attribute);
 
     // ===================================================================================================== \/
     // ============================================================================================ WRAPPERS \/
@@ -383,39 +321,17 @@ public:
         glBindVertexArray( mObjectName );
     }
 
-    //! Bind this VAO and remember the previously bound VAO
-    //! Note: every call to this method must be paired with a corresponding call to disable()
-    inline void enable(void) const
-    {
-        // remember old VAO
-        glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &sPreviousVAOName );
-        bind();
-    }
-
-    //! Bind the VAO that was bound before the most recent enable() call
-    inline void disable(void) const
-    {
-        glBindVertexArray(sPreviousVAOName);
-    }
-
     //! Nothing has to be prepared for a render call
-    inline void render (void)  const
+    inline void render (void)
     {
         enable();
         draw();
         disable();
     }
 
-    //! Will select the matching draw call. Remember to enable first!
+    //! Will select the matching draw call. Remember to bind() first!
     void draw(void) const
     {
-        // TODO: fail silently?
-        if(mAttributes.empty())
-        {
-            ACGL::Utils::error() << "cannot draw VAO with no attributes attached" << std::endl;
-            return;
-        }
-
         if(mpElementArrayBuffer)
             drawElements();
         else
@@ -447,20 +363,39 @@ public:
     //! Draws all elements
     inline void drawArrays(void) const
     {
+        if(mAttributes.empty())
+        {
+            ACGL::Utils::error() << "cannot draw VAO with no attributes attached" << std::endl;
+            return;
+        }
         drawArrays(mAttributes[0].arrayBuffer->getElements());
     }
 
     // =================================================================================================== \/
     // ============================================================================================ FIELDS \/
     // =================================================================================================== \/
-protected:
+private:
     GLuint                   mObjectName;          // OpenGL object name
     SharedElementArrayBuffer mpElementArrayBuffer; // optional EAB
     AttributeVec             mAttributes;          // vertex attributes
     GLenum                   mMode;                // primitive type to render (e.g. GL_TRIANGLES)
 
-private:
-    static GLint             sPreviousVAOName;     // the VAO that was bound before the last enable() call
+    //! Bind this VAO and remember the previously bound VAO
+    //! Note: every call to this method must be paired with a corresponding call to disable()
+    inline void enable(void)
+    {
+        // remember old VAO
+        glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &mPreviousVAOName );
+        if (mObjectName != (GLuint)mPreviousVAOName) bind();
+    }
+
+    //! Bind the VAO that was bound before the most recent enable() call
+    inline void disable(void)
+    {
+        if (mObjectName != (GLuint)mPreviousVAOName) glBindVertexArray((GLuint)mPreviousVAOName);
+    }
+
+    GLint mPreviousVAOName;     // the VAO that was bound before the last enable() call
 };
 
 ACGL_SHARED_TYPEDEF(VertexArrayObject)
diff --git a/src/ACGL/OpenGL/Objects/FrameBufferObject.cc b/src/ACGL/OpenGL/Objects/FrameBufferObject.cc
index 846c298440e8fc31c334fb84aaaf3084d0293558..46697c28cb83971196e977286b45a499a935fe7d 100644
--- a/src/ACGL/OpenGL/Objects/FrameBufferObject.cc
+++ b/src/ACGL/OpenGL/Objects/FrameBufferObject.cc
@@ -34,8 +34,35 @@ int_t FrameBufferObject::getColorAttachmentIndexByName(const std::string& _name)
      return -1;
  }
 
+bool FrameBufferObject::isFrameBufferObjectComplete() const
+{
+    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    if (status != GL_FRAMEBUFFER_COMPLETE)
+    {
+        Utils::error() << "Failed to make complete FrameBufferObject object: ";
+        if (status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
+            Utils::error() << "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
+        } else if (status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
+            Utils::error() << "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
+        } else if (status == GL_FRAMEBUFFER_UNSUPPORTED) {
+            Utils::error() << "GL_FRAMEBUFFER_UNSUPPORTED";
+        } else if (status == GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE) {
+            Utils::error() << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
+        } else {
+            Utils::error() << status;
+        }
+        Utils::error() << std::endl;
+        return false;
+    }
+    return true;
+}
+
 void FrameBufferObject::validate(void) const
 {
+    // if OpenGL says were ok, return
+    if (isFrameBufferObjectComplete()) return;
+
+    // the above call will create some output, but let's try to get more infos:
     if(mColorAttachments.size() > 0)
     {
         int width  = -1;
diff --git a/src/ACGL/OpenGL/Objects/RenderObject.cc b/src/ACGL/OpenGL/Objects/RenderObject.cc
index df9833936d61a70b4d3c7f3c01506bdee82a9395..a1d4b16825598be0090d4c3f91477d90b968861f 100644
--- a/src/ACGL/OpenGL/Objects/RenderObject.cc
+++ b/src/ACGL/OpenGL/Objects/RenderObject.cc
@@ -79,7 +79,7 @@ void RenderObject::enableVertexArrayObject() const
 {
     if(mpVertexArrayObject)
     {
-        mpVertexArrayObject->enable();
+        mpVertexArrayObject->bind();
     }
     else
     {
diff --git a/src/ACGL/OpenGL/Objects/ShaderProgram.cc b/src/ACGL/OpenGL/Objects/ShaderProgram.cc
index 3821e1c3d640b325b62f3649a808923af181d47d..02e39ee0f2a2cd123ed6705e7722da896860b286 100644
--- a/src/ACGL/OpenGL/Objects/ShaderProgram.cc
+++ b/src/ACGL/OpenGL/Objects/ShaderProgram.cc
@@ -50,29 +50,24 @@ bool ShaderProgram::link() const
     return true;
 }
 
-void ShaderProgram::setAttributeLocationsByVAO(ConstSharedVertexArrayObject _vao)
+void ShaderProgram::setAttributeLocations(ConstSharedLocationMappings _locationMappings)
 {
-    // TODO: deprecate
-
     bool needsRelink = false;
 
-    // search through all attributes of _vao
-    VertexArrayObject::AttributeVec vaoAttributes = _vao->getAttributes();
-    for(VertexArrayObject::AttributeVec::size_type i = 0; i < vaoAttributes.size(); ++i)
-    {
-        if(vaoAttributes[i].location == -1)
-            continue;
+    // search through all attributes:
+    LocationMappings::LocationMap locations = _locationMappings->getLocations();
 
-        // find the name of the current attribute in its ArrayBuffer
-        std::string arrayBufferAttributeName = vaoAttributes[i].arrayBuffer->getAttributes()[vaoAttributes[i].attributeID].name;
+    for(LocationMappings::LocationMap::iterator it = locations.begin();
+        it != locations.end();
+        ++it)
+    {
+        // find out whether a fragment data location with a matching name exists in this shader
+        GLint attributeLocation = getAttributeLocation((*it).first);
 
-        // find out whether an attribute with a matching name exists in this ShaderProgram
-        GLint attribLocation = getAttributeLocation(arrayBufferAttributeName);
-        if(attribLocation != -1                         // attribute with that name exists?
-        && attribLocation != vaoAttributes[i].location) // attribute with that name not already bound correctly?
+        if (            attributeLocation  != -1            // attributeLocation with that name exists?
+            && ((GLuint)attributeLocation) != (*it).second) // attributeLocation with that name not already bound correctly?
         {
-            bindAttributeLocation(arrayBufferAttributeName, vaoAttributes[i].location);
-
+            bindAttributeLocation((*it).first, (*it).second);
             needsRelink = true;
         }
     }
@@ -85,23 +80,24 @@ void ShaderProgram::setAttributeLocationsByVAO(ConstSharedVertexArrayObject _vao
     }
 }
 
-void ShaderProgram::setFragmentDataLocationsByFBO(ConstSharedFrameBufferObject _fbo)
+void ShaderProgram::setFragmentDataLocations(ConstSharedLocationMappings _locationMappings)
 {
-    // TODO: deprecate
-
     bool needsRelink = false;
 
-    // search through all color attachments of _fbo
-    FrameBufferObject::AttachmentVec fboAttachments = _fbo->getColorAttachments();
-    for(FrameBufferObject::AttachmentVec::size_type i = 0; i < fboAttachments.size(); ++i)
+    // search through all color attachments:
+    LocationMappings::LocationMap locations = _locationMappings->getLocations();
+
+    for(LocationMappings::LocationMap::iterator it = locations.begin();
+        it != locations.end();
+        ++it)
     {
         // find out whether a fragment data location with a matching name exists in this shader
-        GLint fragmentDataLocation = getFragmentDataLocation(fboAttachments[i].name);
-        if (   fragmentDataLocation != -1           // fragment data location with that name exists?
-            && fragmentDataLocation !=  (GLint) i)  // fragment data location with that name not already bound correctly?
-        {
-            bindFragmentDataLocation(fboAttachments[i].name, i);
+        GLint fragmentDataLocation = getFragmentDataLocation((*it).first);
 
+        if (             fragmentDataLocation  != -1            // fragment data location with that name exists?
+            && ((GLuint) fragmentDataLocation) != (*it).second) // fragment data location with that name not already bound correctly?
+        {
+            bindFragmentDataLocation((*it).first, (*it).second);
             needsRelink = true;
         }
     }
@@ -114,24 +110,31 @@ void ShaderProgram::setFragmentDataLocationsByFBO(ConstSharedFrameBufferObject _
     }
 }
 
-void ShaderProgram::setAttributeLocations(ConstSharedLocationMappings _locationMappings)
+
+
+/*
+void ShaderProgram::setAttributeLocationsByVAO(ConstSharedVertexArrayObject _vao)
 {
-    bool needsRelink = false;
+    // TODO: deprecate
 
-    // search through all color attachments of _fbo
-    LocationMappings::LocationMap locations = _locationMappings->getLocations();
+    bool needsRelink = false;
 
-    for(LocationMappings::LocationMap::iterator it = locations.begin();
-        it != locations.end();
-        ++it)
+    // search through all attributes of _vao
+    VertexArrayObject::AttributeVec vaoAttributes = _vao->getAttributes();
+    for(VertexArrayObject::AttributeVec::size_type i = 0; i < vaoAttributes.size(); ++i)
     {
-        // find out whether a fragment data location with a matching name exists in this shader
-        GLint fragmentDataLocation = getAttributeLocation((*it).first);
+        if(vaoAttributes[i].location == -1)
+            continue;
 
-        if(fragmentDataLocation != -1            // fragment data location with that name exists?
-        && fragmentDataLocation != (*it).second) // fragment data location with that name not already bound correctly?
+        // find the name of the current attribute in its ArrayBuffer
+        std::string arrayBufferAttributeName = vaoAttributes[i].arrayBuffer->getAttributes()[vaoAttributes[i].attributeID].name;
+
+        // find out whether an attribute with a matching name exists in this ShaderProgram
+        GLint attribLocation = getAttributeLocation(arrayBufferAttributeName);
+        if(attribLocation != -1                         // attribute with that name exists?
+        && attribLocation != vaoAttributes[i].location) // attribute with that name not already bound correctly?
         {
-            bindAttributeLocation((*it).first, (*it).second);
+            bindAttributeLocation(arrayBufferAttributeName, vaoAttributes[i].location);
 
             needsRelink = true;
         }
@@ -143,26 +146,24 @@ void ShaderProgram::setAttributeLocations(ConstSharedLocationMappings _locationM
         link();
         openGLRareError();
     }
-}
-
-void ShaderProgram::setFragmentDataLocations(ConstSharedLocationMappings _locationMappings)
+}*/
+/*
+void ShaderProgram::setFragmentDataLocationsByFBO(ConstSharedFrameBufferObject _fbo)
 {
+    // TODO: deprecate
+
     bool needsRelink = false;
 
     // search through all color attachments of _fbo
-    LocationMappings::LocationMap locations = _locationMappings->getLocations();
-
-    for(LocationMappings::LocationMap::iterator it = locations.begin();
-        it != locations.end();
-        ++it)
+    FrameBufferObject::AttachmentVec fboAttachments = _fbo->getColorAttachments();
+    for(FrameBufferObject::AttachmentVec::size_type i = 0; i < fboAttachments.size(); ++i)
     {
         // find out whether a fragment data location with a matching name exists in this shader
-        GLint fragmentDataLocation = getFragmentDataLocation((*it).first);
-
-        if(fragmentDataLocation != -1            // fragment data location with that name exists?
-        && fragmentDataLocation != (*it).second) // fragment data location with that name not already bound correctly?
+        GLint fragmentDataLocation = getFragmentDataLocation(fboAttachments[i].name);
+        if (   fragmentDataLocation != -1           // fragment data location with that name exists?
+            && fragmentDataLocation !=  (GLint) i)  // fragment data location with that name not already bound correctly?
         {
-            bindFragmentDataLocation((*it).first, (*it).second);
+            bindFragmentDataLocation(fboAttachments[i].name, i);
 
             needsRelink = true;
         }
@@ -174,4 +175,4 @@ void ShaderProgram::setFragmentDataLocations(ConstSharedLocationMappings _locati
         link();
         openGLRareError();
     }
-}
+}*/
diff --git a/src/ACGL/OpenGL/Objects/VertexArrayObject.cc b/src/ACGL/OpenGL/Objects/VertexArrayObject.cc
index 5c4ad9fc26189dd0ff177b29515fcd5542a41e4e..df72ae3dd4319e3b67afd92e680d3320dfeefd9b 100755
--- a/src/ACGL/OpenGL/Objects/VertexArrayObject.cc
+++ b/src/ACGL/OpenGL/Objects/VertexArrayObject.cc
@@ -9,8 +9,6 @@
 using namespace ACGL;
 using namespace ACGL::OpenGL;
 
-GLint VertexArrayObject::sPreviousVAOName = 0;
-
 bool VertexArrayObject::isValid(void) const
 {
     GLsizei elements = 0;
@@ -39,4 +37,82 @@ bool VertexArrayObject::isValid(void) const
     return true;
 }
 
+
+
+void VertexArrayObject::setAttributeLocations( ConstSharedLocationMappings _locationMappings )
+{
+    bool fullUpdateNeeded = false;
+    GLint maxAttributes;
+    glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &maxAttributes );
+
+    for (AttributeVec::size_type i = 0; i < mAttributes.size(); ++i)
+    {
+        std::string attributeName = mAttributes[i].arrayBuffer->getAttributes()[ mAttributes[i].attributeID ].name;
+        int_t       location      = _locationMappings->getLocation(attributeName);
+
+        if(location == -1)
+        {
+            // TODO: fail silently?
+            ACGL::Utils::error() << "can't update VAO mapping: attribute " << attributeName << " not specified" << std::endl;
+            continue; // try to match as much as possible
+        }
+        if(location >= maxAttributes)
+        {
+            ACGL::Utils::error() << "can't update VAO mapping: location of attribute " << attributeName << " is too high ("
+                                 << location << ") GL_MAX_VERTEX_ATTRIBS is " << maxAttributes << std::endl;
+            continue; // try to match as much as possible
+        }
+
+        if(mAttributes[i].location != location)
+        {
+            mAttributes[i].location = location;
+            fullUpdateNeeded = true;
+        }
+    }
+
+    // why the full update? setting the new location right when a change is detected will get problamatic
+    // if two attributes exchange there position...
+    if (fullUpdateNeeded)
+    {
+        enable();
+
+        // disable all attributes
+        for (GLint i = 0; i < maxAttributes; ++i)
+            glDisableVertexAttribArray( i );
+
+        // set all attributes:
+        for (uint32_t i = 0; i < mAttributes.size(); ++i)
+        {
+            setAttributePointer(mAttributes[i]);
+        }
+
+        disable();
+    }
+}
+
+
+void VertexArrayObject::setAttributePointer(const Attribute& _attribute)
+{
+    if(_attribute.location == -1)
+    {
+        // An attribute location of -1 indicates that this attribute should remain unbound for now
+        return;
+    }
+
+    SharedArrayBuffer arrayBuffer = _attribute.arrayBuffer;
+    arrayBuffer->bind();
+
+    ArrayBuffer::Attribute arrayBufferAttribute = arrayBuffer->getAttributes()[_attribute.attributeID];
+    glVertexAttribPointer(_attribute.location,
+                          arrayBufferAttribute.size,
+                          arrayBufferAttribute.type,
+                          arrayBufferAttribute.normalized,
+                          arrayBuffer->getStride(),
+                          reinterpret_cast<GLvoid*>(arrayBufferAttribute.offset)
+                          );
+    glEnableVertexAttribArray(_attribute.location);
+}
+
+
+
 #endif // (ACGL_OPENGL_VERSION >= 30)