--- /dev/null
+#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;
+ int matrix_location;
+ 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