]> git.tdb.fi Git - libs/gl.git/blob - source/render/instancearray.h
Check the flat qualifier from the correct member
[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 <msp/core/noncopyable.h>
6 #include "programdata.h"
7 #include "renderable.h"
8 #include "vertexarray.h"
9 #include "vertexsetup.h"
10
11 namespace Msp {
12 namespace GL {
13
14 class Buffer;
15 class Object;
16 class ObjectInstance;
17
18 /**
19 Renders multiple instances of an Object in an efficient manner.
20
21 The instance specific transform is passed to the shader in an attribute with
22 the name instance_transform.  The attribute should have the type vec4[3].  Each
23 elements of the array corresponds to a row of the transform matrix.
24
25 If the Mesh or Technique of the Object is changed during the lifetime of the
26 InstanceArray, behaviour is undefined.
27 */
28 class InstanceArray: public Renderable, public NonCopyable
29 {
30 public:
31         template<typename T>
32         class Instance: public T
33         {
34         private:
35                 InstanceArray &array;
36                 unsigned index;
37
38         public:
39                 Instance(const Object &o, InstanceArray &a, unsigned i): T(o), array(a), index(i) { }
40
41                 virtual void set_matrix(const Matrix &);
42         };
43
44 private:
45         const Object &object;
46         std::vector<ObjectInstance *> instances;
47         VertexArray instance_data;
48         Buffer *instance_buffer = 0;
49         VertexSetup vtx_setup;
50         int matrix_location = -1;
51         unsigned matrix_offset = 0;
52
53 public:
54         InstanceArray(const Object &);
55         ~InstanceArray();
56
57         void set_matrix_attribute(const std::string &);
58
59         /** Adds a new instance to the array.  The instance class must have a
60         constructor taking a const reference to Object as its sole parameter. */
61         template<typename T = ObjectInstance>
62         T &append();
63 private:
64         void append(ObjectInstance *);
65         void update_instance_matrix(unsigned);
66 public:
67         void remove(ObjectInstance &);
68
69         virtual void render(Renderer &, Tag) const;
70 };
71
72 template<typename T>
73 T &InstanceArray::append()
74 {
75         Instance<T> *inst = new Instance<T>(object, *this, instances.size());
76         append(inst);
77         return *inst;
78 }
79
80 template<typename T>
81 void InstanceArray::Instance<T>::set_matrix(const Matrix &m)
82 {
83         T::set_matrix(m);
84         array.update_instance_matrix(index);
85 }
86
87 } // namespace GL
88 } // namespace Msp
89
90 #endif