]> git.tdb.fi Git - libs/gl.git/commitdiff
Add support for multiple binding points in the RAII binders
authorMikko Rasa <tdb@tdb.fi>
Sat, 21 Dec 2013 09:58:57 +0000 (11:58 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sat, 21 Dec 2013 11:05:52 +0000 (13:05 +0200)
source/bindable.h
source/bufferable.cpp
source/mesh.cpp

index f534d7afd8e9788e412dd0d2ddd876eee0091c8e..8651c70ee066b6cbfa2e8f40cd967b0a92f148cd 100644 (file)
@@ -71,8 +71,9 @@ does nothing upon destruction.
 class Bind
 {
 private:
-       typedef void CleanupFunc();
+       typedef void CleanupFunc(int);
 
+       int slot;
        CleanupFunc *cleanup;
 
 public:
@@ -85,6 +86,15 @@ public:
        template<typename T>
        Bind(const T &o) { init(&o); }
 
+       template<typename T, typename S>
+       Bind(T *o, S s) { init(o, s); }
+
+       template<typename T, typename S>
+       Bind(const T *o, S s) { init(o, s); }
+
+       template<typename T, typename S>
+       Bind(const T &o, S s) { init(&o, s); }
+
 private:
        template<typename T>
        void init(const T *o)
@@ -96,14 +106,29 @@ private:
                        T::unbind();
        }
 
+       template<typename T, typename S>
+       void init(const T *o, S s)
+       {
+               cleanup = (o ? &unbind_from<T, S> : 0);
+               slot = s;
+               if(o)
+                       o->bind_to(s);
+               else
+                       T::unbind_from(s);
+       }
+
 public:
        ~Bind()
-       { if(cleanup) cleanup(); }
+       { if(cleanup) cleanup(slot); }
 
 private:
        template<typename T>
-       static void unbind()
+       static void unbind(int)
        { T::unbind(); }
+
+       template<typename T, typename S>
+       static void unbind_from(int s)
+       { T::unbind_from(static_cast<S>(s)); }
 };
 
 
@@ -113,9 +138,10 @@ Similar to Bind, but restores previous binding upon destruction.
 class BindRestore
 {
 private:
-       typedef void CleanupFunc(const void *);
+       typedef void CleanupFunc(const void *, int);
 
        const void *old;
+       int slot;
        CleanupFunc *cleanup;
 
 public:
@@ -128,6 +154,15 @@ public:
        template<typename T>
        BindRestore(const T &o) { init(&o); }
 
+       template<typename T, typename S>
+       BindRestore(T *o, S s) { init(o, s); }
+
+       template<typename T, typename S>
+       BindRestore(const T *o, S s) { init(o, s); }
+
+       template<typename T, typename S>
+       BindRestore(const T &o, S s) { init(&o, s); }
+
 private:
        template<typename T>
        void init(T *o)
@@ -140,19 +175,41 @@ private:
                        T::unbind();
        }
 
+       template<typename T, typename S>
+       void init(T *o, S s)
+       {
+               old = T::current(s);
+               slot = s;
+               cleanup = (o!=old ? &restore_to<T, S> : 0);
+               if(o)
+                       o->bind_to(s);
+               else if(old)
+                       T::unbind_from(s);
+       }
+
 public:
        ~BindRestore()
-       { if(cleanup) cleanup(old); }
+       { if(cleanup) cleanup(old, slot); }
 
 private:
        template<typename T>
-       static void restore(const void *o)
+       static void restore(const void *o, int)
        {
                if(o)
                        reinterpret_cast<const T *>(o)->bind();
                else
                        T::unbind();
        }
+
+       template<typename T, typename S>
+       static void restore_to(const void *o, int si)
+       {
+               S s = static_cast<S>(si);
+               if(o)
+                       reinterpret_cast<const T *>(o)->bind_to(s);
+               else
+                       T::unbind_from(s);
+       }
 };
 
 } // namespace GL
index 1f6122e0914561e91338a80650351ea48ae28306..eb3f1c006e925244f1c58ff671e4d28237378f4a 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdexcept>
+#include "bindable.h"
 #include "buffer.h"
 #include "bufferable.h"
 
@@ -81,8 +82,7 @@ void Bufferable::update_offset()
 
 void Bufferable::update_buffer() const
 {
-       const Buffer *old_buffer = Buffer::current(buffer->get_type());
-       buffer->bind();
+       BindRestore bind(buffer, buffer->get_type());
        if(offset+get_data_size()>=buffer->get_size())
        {
                const Bufferable *last = this;
@@ -102,10 +102,6 @@ void Bufferable::update_buffer() const
        }
 
        upload_data();
-       if(old_buffer)
-               old_buffer->bind_to(buffer->get_type());
-       else
-               buffer->unbind();
        dirty = false;
 }
 
index 26d660446b6c8c264c4fba19781069343282bdb6..c9819ae91c0e60dcec38f18febe5ffeb1747f94f 100644 (file)
@@ -88,8 +88,7 @@ void Mesh::refresh() const
                if(dirty&2)
                {
                        glBindVertexArray(vao_id);
-                       BufferAlias<ARRAY_BUFFER> vbuf_alias(*vbuf);
-                       Bind bind_vbuf(vbuf_alias);
+                       Bind bind_vbuf(vbuf, ARRAY_BUFFER);
 
                        const VertexFormat &fmt = vertices.get_format();
                        unsigned stride = get_stride(fmt)*sizeof(float);