]> git.tdb.fi Git - libs/gl.git/blobdiff - source/instancearray.h
Initial support for instanced rendering
[libs/gl.git] / source / instancearray.h
diff --git a/source/instancearray.h b/source/instancearray.h
new file mode 100644 (file)
index 0000000..ffba39e
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef MSP_GL_INSTANCEARRAY_H_
+#define MSP_GL_INSTANCEARRAY_H_
+
+#include <vector>
+#include "programdata.h"
+#include "renderable.h"
+
+namespace Msp {
+namespace GL {
+
+class Buffer;
+class Object;
+class ObjectInstance;
+class VertexArray;
+class VertexSetup;
+
+/**
+Renders multiple instances of an Object in an efficient manner.  If instanced
+rendering is supported, only one draw call per Batch needs to be issued.
+
+Changing the Mesh of the Object while an InstanceArray exists is not supported.
+*/
+class InstanceArray: public Renderable
+{
+public:
+       template<typename T>
+       class Instance: public T
+       {
+       private:
+               InstanceArray &array;
+               unsigned index;
+
+       public:
+               Instance(const Object &o, InstanceArray &a, unsigned i): T(o), array(a), index(i) { }
+
+               virtual void set_matrix(const Matrix &);
+       };
+
+private:
+       const Object &object;
+       std::vector<ObjectInstance *> instances;
+       VertexArray *instance_data;
+       Buffer *instance_buffer;
+       VertexSetup *vtx_setup;
+       unsigned matrix_offset;
+
+public:
+       InstanceArray(const Object &);
+       ~InstanceArray();
+
+       void set_matrix_attribute(const std::string &);
+
+       template<typename T = ObjectInstance>
+       T &append();
+private:
+       void append(ObjectInstance *);
+       void update_instance_matrix(unsigned);
+public:
+       void remove(ObjectInstance &);
+
+       virtual void render(Renderer &, const Tag &) const;
+};
+
+template<typename T>
+T &InstanceArray::append()
+{
+       Instance<T> *inst = new Instance<T>(object, *this, instances.size());
+       append(inst);
+       return *inst;
+}
+
+template<typename T>
+void InstanceArray::Instance<T>::set_matrix(const Matrix &m)
+{
+       T::set_matrix(m);
+       array.update_instance_matrix(index);
+}
+
+} // namespace GL
+} // namespace Msp
+
+#endif