From 0469d2c45a3bcb41a4772c8eb5c98b1fa09ad807 Mon Sep 17 00:00:00 2001
From: Robert Menzel <menzel@informatik.rwth-aachen.de>
Date: Thu, 9 Feb 2012 14:33:15 +0100
Subject: [PATCH] RenderObject, SPO and Uniform should still work (with minor
 adjustments), VBO is broken

---
 .../Controller/ShaderProgramObjectControl.hh  |  6 +-
 .../OpenGL/HiLevelObjects/RenderObject.hh     | 71 ++++++++------
 .../HiLevelObjects/ShaderProgramObject.hh     | 22 ++---
 .../HiLevelObjects/VertexBufferObject.hh      |  5 +
 .../ACGL/OpenGL/HiLevelObjects/Viewport.hh    | 11 ++-
 .../ACGL/OpenGL/Objects/FrameBufferObject.hh  | 29 +++++-
 include/ACGL/OpenGL/Objects/RenderBuffer.hh   |  3 +-
 include/ACGL/OpenGL/Objects/Texture.hh        |  2 +
 .../Controller/ShaderProgramObjectControl.cc  |  2 +-
 .../OpenGL/HiLevelObjects/RenderObject.cc     | 94 +++++++++----------
 src/ACGL/OpenGL/Objects/FrameBufferObject.cc  |  2 +-
 11 files changed, 148 insertions(+), 99 deletions(-)

diff --git a/include/ACGL/OpenGL/Controller/ShaderProgramObjectControl.hh b/include/ACGL/OpenGL/Controller/ShaderProgramObjectControl.hh
index c832ddee..123a359a 100644
--- a/include/ACGL/OpenGL/Controller/ShaderProgramObjectControl.hh
+++ b/include/ACGL/OpenGL/Controller/ShaderProgramObjectControl.hh
@@ -46,7 +46,7 @@ public:
     // ============================================================================================ CONSTRUCTORS \/
     // ========================================================================================================= \/
 public:
-    ShaderProgramObjectControl(const ConstSharedShaderProgram& _shaderProgram)
+    ShaderProgramObjectControl(const SharedShaderProgram& _shaderProgram)
     :   Resource::BasicCreateController<ShaderProgramObject>(),
         mShaderProgram(_shaderProgram),
         mUniformAttachmentDefines(),
@@ -58,7 +58,7 @@ public:
     // ============================================================================================ METHODS \/
     // ==================================================================================================== \/
 public:
-    inline ShaderProgramObjectControl& shaderProgram (const ConstSharedShaderProgram& _shaderProgram) { mShaderProgram = _shaderProgram; return *this; }
+    inline ShaderProgramObjectControl& shaderProgram (const SharedShaderProgram& _shaderProgram) { mShaderProgram = _shaderProgram; return *this; }
 
     inline ShaderProgramObjectControl& uniform (const std::string& _name, const ConstSharedUniform& _uniform)
     {
@@ -84,7 +84,7 @@ public:
     // ============================================================================================ FIELDS \/
     // =================================================================================================== \/
 protected:
-    ConstSharedShaderProgram          mShaderProgram;
+    SharedShaderProgram               mShaderProgram;
     UniformAttachmentDefineVec        mUniformAttachmentDefines;
     UniformTextureAttachmentDefineVec mUniformTextureAttachmentDefines;
 };
diff --git a/include/ACGL/OpenGL/HiLevelObjects/RenderObject.hh b/include/ACGL/OpenGL/HiLevelObjects/RenderObject.hh
index 7f367d0d..ceef2386 100644
--- a/include/ACGL/OpenGL/HiLevelObjects/RenderObject.hh
+++ b/include/ACGL/OpenGL/HiLevelObjects/RenderObject.hh
@@ -6,20 +6,18 @@
 #ifndef ACGL_OPENGL_OBJECTS_RENDEROBJECT_HH
 #define ACGL_OPENGL_OBJECTS_RENDEROBJECT_HH
 
-/*
+/**
  * A RenderObject combines a FrameBuffer to draw to, a ShaderProgramObject
  * to draw with and a VertexBufferObject to name what to draw.
  *
  * Instead of setting those objects individually and hoping that they match
  * a RenderObject can take care of that.
  *
+ * The FBO is optional, if none is set, rendering is performed onscreen.
+ * A Viewport is also optional.
  *
- *
- * The RenderObject build around automatic mapping of VBOs to Shader-Attribute-Names
- * to Shader-Outputs to Texture-Names.
- * The needed calls (and GLSL in/out type shader-inputs/outputs) are not supported
- * on GL prior to 3.0, so RenderObject is not available on older GL implementations.
- * A similar class however could get implemented for GL 2.1 and GLES 2.0...
+ * NOTE: The RenderObject can change the Attributelocation mappings of the VAO
+ * as well as the frag data locations of the ShaderProgram.
  */
 
 #include <ACGL/ACGL.hh>
@@ -43,8 +41,8 @@ class RenderObject
     // ============================================================================================ CONSTRUCTORS \/
     // ========================================================================================================= \/
 public:
-    RenderObject(ConstSharedVertexArrayObject   _vertexArrayObject,
-                 ConstSharedShaderProgramObject _shaderProgramObject,
+    RenderObject(     SharedVertexArrayObject   _vertexArrayObject,
+                      SharedShaderProgramObject _shaderProgramObject,
                  ConstSharedFrameBufferObject   _frameBufferObject = ConstSharedFrameBufferObject(),
                  ConstSharedViewport            _viewport = ConstSharedViewport())
     :   mpVertexArrayObject(_vertexArrayObject),
@@ -59,9 +57,9 @@ public:
     // ============================================================================================ GETTERS \/
     // ==================================================================================================== \/
 public:
-    inline ConstSharedVertexArrayObject   getVertexArrayObject()   const { return mpVertexArrayObject;   }
+    inline      SharedVertexArrayObject   getVertexArrayObject()   const { return mpVertexArrayObject;   }
     inline ConstSharedFrameBufferObject   getFrameBufferObject()   const { return mpFrameBufferObject;   }
-    inline ConstSharedShaderProgramObject getShaderProgramObject() const { return mpShaderProgramObject; }
+    inline      SharedShaderProgramObject getShaderProgramObject() const { return mpShaderProgramObject; }
     inline ConstSharedViewport            getViewport()            const { return mpViewport;            }
 
     // ==================================================================================================== \/
@@ -71,45 +69,64 @@ public:
     //! Assigns the attribute locations of the VAO to the locations of the ShaderProgram where there are matching names
     void updateMappings();
 
-    void bindFrameBufferObject()    const;
-    void useShaderProgramObject()   const;
-    void enableVertexArrayObject()  const;
-    void disableVertexArrayObject() const;
-    void useViewport()              const;
-
-    inline void enable() const
+    //! setup everything for drawing and store old states
+    inline void enable()
     {
-        bindFrameBufferObject();
-        useShaderProgramObject();
+        enableFrameBufferObject();
+        enableShaderProgramObject();
         enableVertexArrayObject();
-        useViewport();
+        enableViewport();
     }
 
-    inline void disable() const
+    //! restore old states
+    inline void disable()
     {
+        disableViewport();
         disableVertexArrayObject();
+        disableShaderProgramObject();
+        disableFrameBufferObject();
     }
 
+    //! draws the VAO, call enable() first!
     inline void draw() const
     {
         mpVertexArrayObject->draw();
     }
 
-    inline void render() const
+    //! draws the VAO, everything needed for drawing is performed by this call
+    inline void render()
     {
         enable();
         draw();
         disable();
     }
 
+private:
+    void enableFrameBufferObject();
+    void disableFrameBufferObject();
+
+    void enableShaderProgramObject();
+    void disableShaderProgramObject();
+
+    void enableViewport();
+    void disableViewport();
+
+    void enableVertexArrayObject();
+    void disableVertexArrayObject();
+
     // =================================================================================================== \/
     // ============================================================================================ FIELDS \/
     // =================================================================================================== \/
 protected:
-    ConstSharedVertexArrayObject mpVertexArrayObject;
-    ConstSharedShaderProgramObject mpShaderProgramObject;
-    ConstSharedFrameBufferObject mpFrameBufferObject;
-    ConstSharedViewport mpViewport;
+    SharedVertexArrayObject        mpVertexArrayObject;   // mandatory
+    SharedShaderProgramObject      mpShaderProgramObject; // mandatory
+    ConstSharedFrameBufferObject   mpFrameBufferObject;   // optional
+    ConstSharedViewport            mpViewport;            // optional
+
+    Viewport mLastViewport;
+    GLint    mLastShaderProgram;
+    GLint    mLastFBO;
+    GLint    mLastVAO;
 };
 
 ACGL_SMARTPOINTER_TYPEDEFS(RenderObject)
diff --git a/include/ACGL/OpenGL/HiLevelObjects/ShaderProgramObject.hh b/include/ACGL/OpenGL/HiLevelObjects/ShaderProgramObject.hh
index 9ff1c16a..127b1f2f 100644
--- a/include/ACGL/OpenGL/HiLevelObjects/ShaderProgramObject.hh
+++ b/include/ACGL/OpenGL/HiLevelObjects/ShaderProgramObject.hh
@@ -62,10 +62,8 @@ public:
     // ============================================================================================ CONSTRUCTORS \/
     // ========================================================================================================= \/
 public:
-    ShaderProgramObject(const ConstSharedShaderProgram& _shaderProgram)
-    :   mpShaderProgram(_shaderProgram),
-        mUniformAttachments(),
-        mUniformTextureAttachments()
+    ShaderProgramObject(const SharedShaderProgram& _shaderProgram)
+    :   mpShaderProgram(_shaderProgram)
     {}
 
     virtual ~ShaderProgramObject(void) {}
@@ -74,9 +72,9 @@ public:
     // ============================================================================================ GETTERS \/
     // ==================================================================================================== \/
 public:
-    inline const ConstSharedShaderProgram&    getShaderProgram             (void) const { return mpShaderProgram;            }
-    inline const UniformAttachmentVec&        getUniformAttachments        (void) const { return mUniformAttachments;        }
-    inline const UniformTextureAttachmentVec& getUniformTextureAttachments (void) const { return mUniformTextureAttachments; }
+    inline SharedShaderProgram         getShaderProgram             (void) const { return mpShaderProgram;            }
+    inline UniformAttachmentVec        getUniformAttachments        (void) const { return mUniformAttachments;        }
+    inline UniformTextureAttachmentVec getUniformTextureAttachments (void) const { return mUniformTextureAttachments; }
 
     // ===================================================================================================== \/
     // ============================================================================================ WRAPPERS \/
@@ -89,9 +87,7 @@ public:
         const std::string& _name,
         const ConstSharedUniform& _uniform)
     {
-        UniformAttachment uniformAttachment = {
-            mpShaderProgram->getUniformLocation(_name),
-            _uniform};
+        UniformAttachment uniformAttachment = { mpShaderProgram->getUniformLocation(_name), _uniform };
         mUniformAttachments.push_back(uniformAttachment);
     }
 
@@ -99,9 +95,7 @@ public:
         const std::string& _name,
         const ConstSharedUniformTexture& _uniformTexture)
     {
-        UniformTextureAttachment uniformTextureAttachment = {
-            mpShaderProgram->getUniformLocation(_name),
-            _uniformTexture};
+        UniformTextureAttachment uniformTextureAttachment = { mpShaderProgram->getUniformLocation(_name), _uniformTexture };
         mUniformTextureAttachments.push_back(uniformTextureAttachment);
     }
 
@@ -109,7 +103,7 @@ public:
     // ============================================================================================ FIELDS \/
     // =================================================================================================== \/
 protected:
-    ConstSharedShaderProgram    mpShaderProgram;
+    SharedShaderProgram         mpShaderProgram;
     UniformAttachmentVec        mUniformAttachments;
     UniformTextureAttachmentVec mUniformTextureAttachments;
 };
diff --git a/include/ACGL/OpenGL/HiLevelObjects/VertexBufferObject.hh b/include/ACGL/OpenGL/HiLevelObjects/VertexBufferObject.hh
index 17cd1db0..a82724b6 100644
--- a/include/ACGL/OpenGL/HiLevelObjects/VertexBufferObject.hh
+++ b/include/ACGL/OpenGL/HiLevelObjects/VertexBufferObject.hh
@@ -6,6 +6,11 @@
 #ifndef ACGL_OPENGL_OBJECTS_VERTEXBUFFEROBJECT_HH
 #define ACGL_OPENGL_OBJECTS_VERTEXBUFFEROBJECT_HH
 
+////////////////////////////////////////////////////////////////////////////////
+// WARNING: broken due to refactoring of low-level objects, might get removed //
+// alternative: maybe VertexBufferObjects                                     //
+////////////////////////////////////////////////////////////////////////////////
+
 /*
  * A VertexBufferObject combines the two tightly related buffers from the
  * ARB_vertex_buffer_object extension.
diff --git a/include/ACGL/OpenGL/HiLevelObjects/Viewport.hh b/include/ACGL/OpenGL/HiLevelObjects/Viewport.hh
index 796785c9..c8887bbf 100644
--- a/include/ACGL/OpenGL/HiLevelObjects/Viewport.hh
+++ b/include/ACGL/OpenGL/HiLevelObjects/Viewport.hh
@@ -53,7 +53,7 @@ public:
 public:
     inline void use (void) const
     {
-        glViewport(mOffsetX, mOffsetY, mWidth, mHeight);
+        glViewport(mOffsetX, mOffsetY, mWidth, mHeight); openGLRareError();
     }
 
     inline void setOffset (GLint _offsetX, GLint _offsetY)
@@ -68,6 +68,15 @@ public:
         mHeight = _height;
     }
 
+    //! gets the current viewport form OpenGL
+    void setFromGLContext()
+    {
+        GLint viewport[4];
+        glGetIntegerv( GL_VIEWPORT, &(viewport[0]) );
+        setOffset(viewport[0], viewport[1]);
+        setSize(  viewport[1], viewport[2]);
+    }
+
     // =================================================================================================== \/
     // ============================================================================================ FIELDS \/
     // =================================================================================================== \/
diff --git a/include/ACGL/OpenGL/Objects/FrameBufferObject.hh b/include/ACGL/OpenGL/Objects/FrameBufferObject.hh
index 58e4127a..917fad54 100644
--- a/include/ACGL/OpenGL/Objects/FrameBufferObject.hh
+++ b/include/ACGL/OpenGL/Objects/FrameBufferObject.hh
@@ -180,6 +180,33 @@ public:
         return true;
     }
 
+    //! x,y coordinate is the FBO size in pixels, z coordinate the number of color attachments. x,y are both 0 if the FBO has no useful size
+    glm::uvec3 getSize() const
+    {
+        glm::uvec3 size;
+
+        if (mDepthAttachment.texture) {
+            // use the size of the depth texture
+            size = mDepthAttachment.texture->getSize();
+        } else if (mDepthAttachment.renderBuffer) {
+            // use the size of the depth render buffer
+            size = glm::uvec3( mDepthAttachment.renderBuffer->getSize(), 0 );
+        } else if ( mColorAttachments.size() > 0 ) {
+            if (mColorAttachments[0].texture) {
+                // use the size of the first texture:
+                size = mColorAttachments[0].texture->getSize();
+            } else if (mColorAttachments[0].renderBuffer) {
+                // use the size of the first renderBuffer:
+                size = glm::uvec3( mColorAttachments[0].renderBuffer->getSize(), 0 );
+            }
+        } else {
+            size = glm::uvec3(0);
+        }
+
+        size.z = mColorAttachments.size();
+        return size;
+    }
+
     // =================================================================================================== \/
     // =========================================================================================== METHODS \/
     // =================================================================================================== \/
@@ -188,7 +215,7 @@ public:
     void setAttachmentLocations(ConstSharedLocationMappings _locationMappings);
 
     //! get a list of attachment locations and names that can be used to set up a ShaderProgram
-    SharedLocationMappings getAttachmentLocations();
+    SharedLocationMappings getAttachmentLocations() const;
 
     // =================================================================================================== \/
     // ============================================================================================ FIELDS \/
diff --git a/include/ACGL/OpenGL/Objects/RenderBuffer.hh b/include/ACGL/OpenGL/Objects/RenderBuffer.hh
index 0b7235c3..c78bad52 100644
--- a/include/ACGL/OpenGL/Objects/RenderBuffer.hh
+++ b/include/ACGL/OpenGL/Objects/RenderBuffer.hh
@@ -19,7 +19,7 @@
 #include <ACGL/Base/Macros.hh>
 #include <ACGL/OpenGL/GL.hh>
 #include <ACGL/OpenGL/Tools.hh>
-
+#include <ACGL/Math/Math.hh>
 
 namespace ACGL{
 namespace OpenGL{
@@ -60,6 +60,7 @@ public:
     inline GLenum  getInternalFormat (void) const { return mInternalFormat; }
     inline GLsizei getWidth          (void) const { return mWidth;          }
     inline GLsizei getHeight         (void) const { return mHeight;         }
+    inline glm::uvec2 getSize        (void) const { return glm::uvec2( mWidth, mHeight ); }
 
     // ==================================================================================================== \/
     // ============================================================================================ METHODS \/
diff --git a/include/ACGL/OpenGL/Objects/Texture.hh b/include/ACGL/OpenGL/Objects/Texture.hh
index 925fea36..506a42ae 100644
--- a/include/ACGL/OpenGL/Objects/Texture.hh
+++ b/include/ACGL/OpenGL/Objects/Texture.hh
@@ -80,6 +80,8 @@ public:
     inline GLenum  getWrapT          (void) const { return mWrapT;          }
     inline GLenum  getWrapR          (void) const { return mWrapR;          }
 
+    inline glm::uvec3 getSize        (void) const { return glm::uvec3( mWidth, mHeight, mDepth ); }
+
     // ===================================================================================================== \/
     // ============================================================================================ WRAPPERS \/
     // ===================================================================================================== \/
diff --git a/src/ACGL/OpenGL/Controller/ShaderProgramObjectControl.cc b/src/ACGL/OpenGL/Controller/ShaderProgramObjectControl.cc
index 3b7e0973..4a9c7d08 100644
--- a/src/ACGL/OpenGL/Controller/ShaderProgramObjectControl.cc
+++ b/src/ACGL/OpenGL/Controller/ShaderProgramObjectControl.cc
@@ -9,7 +9,7 @@ using namespace ACGL::OpenGL;
 
 SharedShaderProgramObject ShaderProgramObjectControl::create(void)
 {
-    SharedShaderProgramObject shaderProgramObject(new ShaderProgramObject(mShaderProgram));
+    SharedShaderProgramObject shaderProgramObject = SharedShaderProgramObject(new ShaderProgramObject(mShaderProgram));
 
     for(UniformAttachmentDefineVec::size_type i = 0; i < mUniformAttachmentDefines.size(); i++)
         shaderProgramObject->attachUniform(mUniformAttachmentDefines[i].name, mUniformAttachmentDefines[i].uniform);
diff --git a/src/ACGL/OpenGL/HiLevelObjects/RenderObject.cc b/src/ACGL/OpenGL/HiLevelObjects/RenderObject.cc
index 2a2f1626..7f49a81b 100644
--- a/src/ACGL/OpenGL/HiLevelObjects/RenderObject.cc
+++ b/src/ACGL/OpenGL/HiLevelObjects/RenderObject.cc
@@ -1,5 +1,5 @@
 ////////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University         //
+// Copyright (c) 2011, 2012 Computer Graphics Group RWTH Aachen University    //
 // All rights reserved.                                                       //
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -8,6 +8,7 @@
 
 #include <ACGL/OpenGL/Tools.hh>
 #include <ACGL/Base/StringOperations.hh>
+#include <ACGL/OpenGL/Data/LocationMappings.hh>
 
 #include <iostream>
 #include <fstream>
@@ -18,89 +19,82 @@ using namespace ACGL::OpenGL;
 
 void RenderObject::updateMappings()
 {
-    // TODO: reimplement
-    /*
-    for(VertexBufferObject::AttributeVec::size_type i = 0; i < mpVertexBufferObject->getAttributes().size(); ++i)
-    {
-        AttributeMapping mapping = {(int_t)i, (int_t)mpShaderProgramObject->getShaderProgram()->getAttributeLocation(mpVertexBufferObject->getAttributes()[i].name)};
-        bool inserted = false;
-        for (AttributeMappingVec::iterator it = mAttributeMappings.begin(); it < mAttributeMappings.end() && !inserted; it++)
-        {
-            if(mpVertexBufferObject->getAttributes()[(*it).attributeID].bufferID > mpVertexBufferObject->getAttributes()[mapping.attributeID].bufferID)
-            {
-                mAttributeMappings.insert(it, mapping);
-                inserted = true;
-            }
-        }
-
-        if(!inserted)
-            mAttributeMappings.push_back(mapping);
+    if (mpFrameBufferObject) {
+        // set ShaderProgram out-mappings by the definition of the FBO
+        mpShaderProgramObject->getShaderProgram()->setFragmentDataLocations( mpFrameBufferObject->getAttachmentLocations() );
     }
 
-    if(mpFrameBufferObject)
-    {
-        mpDrawBuffers = new GLuint[mpFrameBufferObject->getColorAttachments().size()];
-        for(FrameBufferObject::AttachmentVec::size_type i = 0; i < mpFrameBufferObject->getColorAttachments().size(); ++i)
-            mpDrawBuffers[i] =  GL_COLOR_ATTACHMENT0 + mpShaderProgramObject->getShaderProgram()->getFragmentDataLocation(mpFrameBufferObject->getColorAttachments()[i].name);
-    }
-    */
-
-    // update the attribute locations of the VAO
-    // TODO: better move this to the controller
-    //mpVertexArrayObject->setAttributeLocationsByShaderProgram(mpShaderProgramObject->getShaderProgram());
-
-    // update the fragment data locations of the FBO
-    //mpFrameBufferObject->setAttachmentsByShaderProgram(mpShaderProgramObject->getShaderProgram());
-
+    mpVertexArrayObject->setAttributeLocations( mpShaderProgramObject->getShaderProgram()->getAttributeLocations() );
     openGLRareError();
 }
 
-void RenderObject::bindFrameBufferObject() const
+void RenderObject::enableFrameBufferObject()
 {
+    glGetIntegerv( GL_FRAMEBUFFER_BINDING, &mLastFBO );
+
     if(mpFrameBufferObject)
     {
         mpFrameBufferObject->bind();
-        //glDrawBuffers(mpFrameBufferObject->getColorAttachments().size(), mpDrawBuffers);
     }
     else
     {
-        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
     }
     openGLRareError();
 }
 
-void RenderObject::useShaderProgramObject() const
+void RenderObject::disableFrameBufferObject()
 {
+    glBindFramebuffer( GL_FRAMEBUFFER, mLastFBO );
+    openGLRareError();
+}
+
+
+void RenderObject::enableShaderProgramObject()
+{
+    glGetIntegerv( GL_CURRENT_PROGRAM, &mLastShaderProgram );
     mpShaderProgramObject->use();
     openGLRareError();
 }
 
-void RenderObject::enableVertexArrayObject() const
+void RenderObject::disableShaderProgramObject()
 {
-    if(mpVertexArrayObject)
-    {
-        mpVertexArrayObject->bind();
-    }
-    else
-    {
-        glBindVertexArray(0);
-    }
+    glUseProgram( mLastShaderProgram );
+    openGLRareError();
+}
+
+void RenderObject::enableVertexArrayObject()
+{
+    // remember old VAO
+    glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &mLastVAO );
+
+    mpVertexArrayObject->bind();
     openGLRareError();
 }
 
-void RenderObject::disableVertexArrayObject() const
+void RenderObject::disableVertexArrayObject()
 {
-    glBindVertexArray(0);
+    glBindVertexArray( mLastVAO );
     openGLRareError();
 }
 
-void RenderObject::useViewport() const
+void RenderObject::enableViewport()
 {
+    mLastViewport.setFromGLContext();
+
     if(mpViewport)
     {
         mpViewport->use();
+    } else if (mpFrameBufferObject) {
+        glm::uvec3 size = mpFrameBufferObject->getSize();
+        glViewport( 0, 0, size.x, size.y );
+        openGLRareError();
     }
-    openGLRareError();
+}
+
+void RenderObject::disableViewport()
+{
+    mLastViewport.use();
 }
 
 #endif
diff --git a/src/ACGL/OpenGL/Objects/FrameBufferObject.cc b/src/ACGL/OpenGL/Objects/FrameBufferObject.cc
index 8c892e32..d3ab704b 100644
--- a/src/ACGL/OpenGL/Objects/FrameBufferObject.cc
+++ b/src/ACGL/OpenGL/Objects/FrameBufferObject.cc
@@ -179,7 +179,7 @@ void FrameBufferObject::setAttachmentLocations(ConstSharedLocationMappings _loca
 }
 
 
-SharedLocationMappings FrameBufferObject::getAttachmentLocations()
+SharedLocationMappings FrameBufferObject::getAttachmentLocations() const
 {
     SharedLocationMappings locationMap = SharedLocationMappings( new LocationMappings() );
 
-- 
GitLab