]> git.tdb.fi Git - libs/gl.git/blob - source/uniform.h
Move buffer resizing out of Bufferable
[libs/gl.git] / source / uniform.h
1 #ifndef MSP_GL_UNIFORM_H_
2 #define MSP_GL_UNIFORM_H_
3
4 #include <algorithm>
5 #include "program.h"
6
7 namespace Msp {
8 namespace GL {
9
10 class Uniform
11 {
12 protected:
13         Uniform() { }
14 private:
15         Uniform(const Uniform &);
16         Uniform &operator=(const Uniform &);
17 public:
18         virtual ~Uniform() { }
19
20         virtual void apply(int) const = 0;
21         virtual void store(const Program::UniformInfo &, void *) const = 0;
22         virtual Uniform *clone() const = 0;
23 };
24
25
26 template<typename T>
27 class UniformScalar: public Uniform
28 {
29 public:
30         typedef T BaseType;
31         typedef T Type;
32
33 private:
34         Type value;
35
36 public:
37         UniformScalar(Type v): value(v) { }
38
39         Type get() const { return value; }
40
41         virtual void apply(int index) const
42         { apply(index, 1, &value); }
43
44         static void apply(int, unsigned, const T *);
45
46         virtual void store(const Program::UniformInfo &info, void *buffer) const
47         { store(info, buffer, &value); }
48
49         static void store(const Program::UniformInfo &, void *buffer, const T *value)
50         { *reinterpret_cast<T *>(buffer) = *value; }
51
52         virtual UniformScalar *clone() const
53         { return new UniformScalar(value); }
54 };
55
56 typedef UniformScalar<int> Uniform1i;
57 typedef UniformScalar<float> Uniform1f;
58
59
60 template<typename T, unsigned vecsize>
61 class UniformVector: public Uniform
62 {
63 public:
64         typedef T BaseType;
65         typedef T Type[vecsize];
66
67 private:
68         Type value;
69
70 public:
71         UniformVector(const T *vp)
72         { std::copy(vp, vp+vecsize, value); }
73
74         BaseType get(unsigned i) const { return value[i]; }
75
76         virtual void apply(int index) const
77         { apply(index, 1, value); }
78
79         static void apply(int index, unsigned size, const T *value);
80
81         virtual void store(const Program::UniformInfo &info, void *buffer) const
82         { store(info, buffer, value); }
83
84         static void store(const Program::UniformInfo &, void *buffer, const T *value)
85         { std::copy(value, value+vecsize, reinterpret_cast<T *>(buffer)); }
86
87         virtual UniformVector *clone() const
88         { return new UniformVector(value); }
89 };
90
91 typedef UniformVector<int, 2> Uniform2i;
92 typedef UniformVector<float, 2> Uniform2f;
93 typedef UniformVector<int, 3> Uniform3i;
94 typedef UniformVector<float, 3> Uniform3f;
95 typedef UniformVector<int, 4> Uniform4i;
96 typedef UniformVector<float, 4> Uniform4f;
97
98
99 template<typename T, unsigned rows, unsigned cols>
100 class UniformMatrix: public Uniform
101 {
102 public:
103         typedef T BaseType;
104         typedef T Type[rows*cols];
105
106 private:
107         Type value;
108
109 public:
110         UniformMatrix(const T *vp)
111         { std::copy(vp, vp+rows*cols, value); }
112
113         virtual void apply(int index) const
114         { apply(index, 1, value); }
115
116         static void apply(int index, unsigned size, const T *value);
117
118         virtual void store(const Program::UniformInfo &info, void *buffer) const
119         { store(info, buffer, value); }
120
121         static void store(const Program::UniformInfo &info, void *buffer, const T *value)
122         {
123                 for(unsigned i=0; i<cols; ++i)
124                         UniformVector<T, rows>::store(info, reinterpret_cast<char *>(buffer)+i*info.matrix_stride, value+i*rows);
125         }
126
127         virtual UniformMatrix *clone() const
128         { return new UniformMatrix(value); }
129 };
130
131 // The naming of these types follows the OpenGL convention of columns x rows
132 typedef UniformMatrix<float, 2, 2> UniformMatrix2x2f;
133 typedef UniformMatrix<float, 2, 3> UniformMatrix3x2f;
134 typedef UniformMatrix<float, 2, 4> UniformMatrix4x2f;
135 typedef UniformMatrix<float, 3, 2> UniformMatrix2x3f;
136 typedef UniformMatrix<float, 3, 3> UniformMatrix3x3f;
137 typedef UniformMatrix<float, 3, 4> UniformMatrix4x3f;
138 typedef UniformMatrix<float, 4, 2> UniformMatrix2x4f;
139 typedef UniformMatrix<float, 4, 3> UniformMatrix3x4f;
140 typedef UniformMatrix<float, 4, 4> UniformMatrix4x4f;
141
142
143 template<typename T>
144 class UniformArray: public Uniform
145 {
146 private:
147         typedef typename T::BaseType BaseType;
148         enum { elemsize = sizeof(typename T::Type)/sizeof(typename T::BaseType) };
149
150         BaseType *values;
151         unsigned size;
152
153 public:
154         UniformArray(unsigned n, const BaseType *vp):
155                 size(n)
156         {
157                 values = new BaseType[elemsize*size];
158                 std::copy(vp, vp+elemsize*size, values);
159         }
160
161         ~UniformArray()
162         {
163                 delete[] values;
164         }
165
166         virtual void apply(int index) const
167         { T::apply(index, size, values); }
168
169         virtual void store(const Program::UniformInfo &info, void *buffer) const
170         {
171                 for(unsigned i=0; i<size; ++i)
172                         T::store(info, reinterpret_cast<char *>(buffer)+i*info.array_stride, values+i*elemsize);
173         }
174
175         virtual UniformArray *clone() const
176         { return new UniformArray(size, values); }
177 };
178
179 } // namespace GL
180 } // namespace Msp
181
182 #endif