Beatmup
variables_bundle.cpp
Go to the documentation of this file.
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2019, lnstadrum
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "variables_bundle.h"
20 #include "../bitmap/pixel_arithmetic.h"
21 #include "bgl.h"
22 
23 using namespace Beatmup;
24 using namespace GL;
25 
27  data = src.data;
28  type = src.type;
29  width = src.width;
30  height = src.height;
31  count = src.count;
32  src.data = NULL;
33  return *this;
34 }
35 
37  data(nullptr), width(0), height(0), count(0), type(MatrixParameter::Type::UNDEFINED)
38 {}
39 
40 void VariablesBundle::MatrixParameter::configure(Type type, unsigned short int width, unsigned short int height, unsigned int count) {
41  free(data);
42  this->width = width;
43  this->height = height;
44  this->count = count;
45  this->type = type;
46  switch (type) {
47  case MatrixParameter::Type::INT:
48  data = malloc(sizeof(GLint) * width*height*count);
49  break;
50  case MatrixParameter::Type::FLOAT:
51  data = malloc(sizeof(GLfloat) * width*height*count);
52  break;
53  default:
54  Insanity::insanity("Invalid data type when construction matrix parameter");
55  }
56 }
57 
59  free(data);
60 }
61 
62 void VariablesBundle::setInteger(std::string name, int value) {
63  integers[name] = value;
64 }
65 
66 void VariablesBundle::setInteger(std::string name, int x, int y) {
67  MatrixParameter& param = params[name];
68  param.configure(MatrixParameter::Type::INT, 2);
69  GLint* data = param.getData<GLint>();
70  data[0] = x;
71  data[1] = y;
72 }
73 
74 void VariablesBundle::setInteger(std::string name, int x, int y, int z) {
75  MatrixParameter& param = params[name];
76  param.configure(MatrixParameter::Type::INT, 3);
77  GLint* data = param.getData<GLint>();
78  data[0] = x;
79  data[1] = y;
80  data[2] = z;
81 }
82 
83 void VariablesBundle::setInteger(std::string name, int x, int y, int z, int w) {
84  MatrixParameter& param = params[name];
85  param.configure(MatrixParameter::Type::INT, 4);
86  GLint* data = param.getData<GLint>();
87  data[0] = x;
88  data[1] = y;
89  data[2] = z;
90  data[3] = w;
91 }
92 
93 void VariablesBundle::setFloat(std::string name, float value) {
94  floats[name] = value;
95 }
96 
97 void VariablesBundle::setFloat(std::string name, float x, float y) {
98  MatrixParameter& param = params[name];
99  param.configure(MatrixParameter::Type::FLOAT, 2);
100  GLfloat* data = param.getData<GLfloat>();
101  data[0] = x;
102  data[1] = y;
103 }
104 
105 void VariablesBundle::setFloat(std::string name, float x, float y, float z) {
106  MatrixParameter& param = params[name];
107  param.configure(MatrixParameter::Type::FLOAT, 3);
108  GLfloat* data = param.getData<GLfloat>();
109  data[0] = x;
110  data[1] = y;
111  data[2] = z;
112 }
113 
114 void VariablesBundle::setFloat(std::string name, float x, float y, float z, float w) {
115  MatrixParameter& param = params[name];
116  param.configure(MatrixParameter::Type::FLOAT, 4);
117  GLfloat* data = param.getData<GLfloat>();
118  data[0] = x;
119  data[1] = y;
120  data[2] = z;
121  data[3] = w;
122 }
123 
124 void VariablesBundle::setFloatMatrix2(std::string name, const float matrix[4]) {
125  MatrixParameter& param = params[name];
126  param.configure(MatrixParameter::Type::FLOAT, 2, 2);
127  GLfloat *out = param.getData<GLfloat>();
128  for (const float* in = matrix; in < matrix + 4; ++in)
129  *out++ = *in;
130 }
131 
132 void VariablesBundle::setFloatMatrix3(std::string name, const float matrix[9]) {
133  MatrixParameter& param = params[name];
134  param.configure(MatrixParameter::Type::FLOAT, 3, 3);
135  GLfloat *out = param.getData<GLfloat>();
136  for (const float* in = matrix; in < matrix + 9; ++in)
137  *out++ = *in;
138 }
139 
140 void VariablesBundle::setFloatMatrix4(std::string name, const float matrix[16]) {
141  MatrixParameter& param = params[name];
142  param.configure(MatrixParameter::Type::FLOAT, 4, 4);
143  GLfloat *out = param.getData<GLfloat>();
144  for (const float* in = matrix; in < matrix + 16; ++in)
145  *out++ = *in;
146 }
147 
148 void VariablesBundle::setFloatMatrix4(std::string name, const Color::Matrix& matrix) {
149  MatrixParameter& param = params[name];
150  param.configure(MatrixParameter::Type::FLOAT, 4, 4);
151  GLfloat *out = param.getData<GLfloat>();
152  for (int x = 0; x < 4; ++x) {
153  const pixfloat4 row = matrix[x];
154  for (int y = 0; y < 4; ++y)
155  *out++ = row[y];
156  }
157 }
158 
159 void VariablesBundle::setFloatArray(std::string name, const std::vector<float>& values) {
160  floatArrays[name] = values;
161 }
162 
163 float VariablesBundle::getFloat(const std::string& name) const {
164  const auto& it = floats.find(name);
165  if (it == floats.cend())
166  return std::numeric_limits<float>::quiet_NaN();
167  return it->second;
168 }
169 
171  for (auto& var : integers)
172  program.setInteger(var.first.c_str(), var.second);
173 
174  for (auto& var : floats)
175  program.setFloat(var.first.c_str(), var.second);
176 
177  for (auto& var : params) {
178  // assign a vector
179  if (var.second.getHeight() == 1 && var.second.getCount() == 1)
180  switch (var.second.getType()) {
181  case MatrixParameter::Type::INT: {
182  GLint* data = var.second.getData<GLint>();
183  switch (var.second.getWidth()) {
184  case 2:
185  glUniform2i(program.getUniformLocation(var.first.c_str()), data[0], data[1]);
186  break;
187  case 3:
188  glUniform3i(program.getUniformLocation(var.first.c_str()), data[0], data[1], data[2]);
189  break;
190  case 4:
191  glUniform4i(program.getUniformLocation(var.first.c_str()), data[0], data[1], data[2], data[3]);
192  break;
193  default: Insanity::insanity("Invalid parameter size");
194  }
195  break;
196  }
197  case MatrixParameter::Type::FLOAT: {
198  GLfloat* data = var.second.getData<GLfloat>();
199  switch (var.second.getWidth()) {
200  case 2:
201  glUniform2f(program.getUniformLocation(var.first.c_str()), data[0], data[1]);
202  break;
203  case 3:
204  glUniform3f(program.getUniformLocation(var.first.c_str()), data[0], data[1], data[2]);
205  break;
206  case 4:
207  glUniform4f(program.getUniformLocation(var.first.c_str()), data[0], data[1], data[2], data[3]);
208  break;
209  default: Insanity::insanity("Invalid parameter size");
210  }
211  break;
212  }
213  default: Insanity::insanity("Invalid parameter type");
214  }
215  // assign an array
216  else if (var.second.getHeight() == 1)
217 #define CASE(n,t,T) case n: glUniform##n##t##v(program.getUniformLocation(var.first.c_str()), var.second.getCount(), var.second.getData<T>()); break;
218  switch (var.second.getType()) {
219  case MatrixParameter::Type::INT:
220  switch (var.second.getWidth()) {
221  CASE(1, i, GLint);
222  CASE(2, i, GLint);
223  CASE(3, i, GLint);
224  CASE(4, i, GLint);
225  default: Insanity::insanity("Invalid parameter size");
226  }
227  break;
228  case MatrixParameter::Type::FLOAT:
229  switch (var.second.getWidth()) {
230  CASE(1, f, GLfloat);
231  CASE(2, f, GLfloat);
232  CASE(3, f, GLfloat);
233  CASE(4, f, GLfloat);
234  default: Insanity::insanity("Invalid parameter size");
235  }
236  break;
237  default: Insanity::insanity("Invalid parameter type");
238  }
239  // assign a matrix
240  else if (var.second.getWidth() == var.second.getHeight())
241 #undef CASE
242 #define CASE(n) case n: glUniformMatrix##n##fv(program.getUniformLocation(var.first.c_str()), var.second.getCount(), GL_FALSE, var.second.getData<GLfloat>()); break;
243  switch (var.second.getType()) {
244  case MatrixParameter::Type::FLOAT: {
245  switch (var.second.getWidth()) {
246  CASE(2);
247  CASE(3);
248  CASE(4);
249  default: Insanity::insanity("Invalid parameter size");
250  }
251  break;
252  }
253  default: Insanity::insanity("Invalid parameter type");
254  }
255  // an error otherwise
256  else
257  Insanity::insanity("Invalid matrix size");
258  GL::GLException::check((std::string("setting uniform variable ") + var.first).c_str());
259  }
260 
261  for (auto& var : floatArrays) {
262  glUniform1fv(program.getUniformLocation(var.first.c_str()), var.second.size(), var.second.data());
263  GL::GLException::check((std::string("setting uniform variable ") + var.first).c_str());
264  }
265 }
266 
267 
269  integers.clear();
270  floats.clear();
271  floatArrays.clear();
272  params.clear();
273 }
RGBA color mapping.
Definition: matrix.h:29
void setInteger(const std::string &name, const int value, bool safe=false)
Assigns a value to a specific integer variable in the program.
Definition: program.cpp:308
handle_t getUniformLocation(const std::string &name)
Retrieves uniform variable location by its name.
Definition: program.cpp:288
void setFloat(const std::string &name, const float value, bool safe=false)
Assigns a value to a specific floating point variable in the program.
Definition: program.cpp:347
static void check(const std::string &info)
Definition: bgl.h:62
Regular OpenGL program.
Definition: program.h:229
void configure(Type type, unsigned short int width, unsigned short int height=1, unsigned int count=1)
MatrixParameter & operator=(MatrixParameter &&)
void setFloatMatrix4(std::string name, const float matrix[16])
Sets a float 4*4 matrix variable value.
float getFloat(const std::string &name) const
Retrieves a value of a scalar float uniform variable by its name.
void setInteger(std::string name, int value)
Sets a scalar integer uniform value.
void setFloat(std::string name, float value)
Sets a scalar float uniform value.
std::map< std::string, int > integers
std::map< std::string, MatrixParameter > params
void clear()
Removes all stored variables.
void setFloatMatrix3(std::string name, const float matrix[9])
Sets a float 3*3 matrix variable value.
void setFloatMatrix2(std::string name, const float matrix[4])
Sets a float 2*2 matrix variable value.
std::map< std::string, float > floats
void apply(Program &program)
void setFloatArray(std::string name, const std::vector< float > &values)
Sets a float array variable value.
std::map< std::string, std::vector< float > > floatArrays
static void insanity(const char *message)
Definition: exception.h:136
4-channel floating point arithmetic
#define CASE(n, t, T)
return(jlong) new Beatmup jlong jstring name
jlong jstring jint jint jint z
jobject jlong jint jint y
jlong jstring jint jint jint jint w
JNIEnv jlong jint jint count
jlong jint width
jlong jint jint height
jobject jlong jint x
JNIEnv jlong jint out
return(jlong) new Beatmup jlong jstring src