]> git.tdb.fi Git - libs/gl.git/blob - source/render/instancearray.h
627051f75b123a973ef878546fddd762708afe59
[libs/gl.git] / source / render / instancearray.h
1 #ifndef MSP_GL_INSTANCEARRAY_H_
2 #define MSP_GL_INSTANCEARRAY_H_
3
4 #include <vector>
5 #include "programdata.h"
6 #include "renderable.h"
7
8 namespace Msp {
9 namespace GL {
10
11 class Buffer;
12 class Object;
13 class ObjectInstance;
14 class VertexArray;
15 class VertexSetup;
16
17 /**
18 Renders multiple instances of an Object in an efficient manner.  If instanced
19 rendering is supported, only one draw call per Batch needs to be issued.
20
21 Changing the Mesh of the Object while an InstanceArray exists is not supported.
22 */
23 class InstanceArray: public Renderable
24 {
25 public:
26         template<typename T>
27         class Instance: public T
28         {
29         private:
30                 InstanceArray &array;
31                 unsigned index;
32
33         public:
34                 Instance(const Object &o, InstanceArray &a, unsigned i): T(o), array(a), index(i) { }
35
36                 virtual void set_matrix(const Matrix &);
37         };
38
39 private:
40         const Object &object;
41         std::vector<ObjectInstance *> instances;
42         VertexArray *instance_data;
43         Buffer *instance_buffer;
44         VertexSetup *vtx_setup;
45         int matrix_location;
46         unsigned matrix_offset;
47
48 public:
49         InstanceArray(const Object &);
50         ~InstanceArray();
51
52         void set_matrix_attribute(const std::string &);
53
54         template<typename T = ObjectInstance>
55         T &append();
56 private:
57         void append(ObjectInstance *);
58         void update_instance_matrix(unsigned);
59 public:
60         void remove(ObjectInstance &);
61
62         virtual void render(Renderer &, const Tag &) const;
63 };
64
65 template<typename T>
66 T &InstanceArray::append()
67 {
68         Instance<T> *inst = new Instance<T>(object, *this, instances.size());
69         append(inst);
70         return *inst;
71 }
72
73 template<typename T>
74 void InstanceArray::Instance<T>::set_matrix(const Matrix &m)
75 {
76         T::set_matrix(m);
77         array.update_instance_matrix(index);
78 }
79
80 } // namespace GL
81 } // namespace Msp
82
83 #endif