rev |
line source |
nuclear@13
|
1 #include <map>
|
nuclear@13
|
2 #include <vector>
|
nuclear@13
|
3 #include "unistate.h"
|
nuclear@13
|
4 #include "shader.h"
|
nuclear@13
|
5 #include "logger.h"
|
nuclear@13
|
6
|
nuclear@13
|
7 struct StateItem {
|
nuclear@13
|
8 StType type;
|
nuclear@13
|
9
|
nuclear@13
|
10 union {
|
nuclear@13
|
11 int ival[4];
|
nuclear@13
|
12 float fval[16];
|
nuclear@13
|
13 };
|
nuclear@13
|
14 int transpose; // for matrices
|
nuclear@13
|
15 };
|
nuclear@13
|
16
|
nuclear@13
|
17 static const char *typestr(StType type);
|
nuclear@13
|
18 static int type_nelem(StType type);
|
nuclear@13
|
19 static StType float_type(int elem);
|
nuclear@13
|
20 static StType int_type(int elem);
|
nuclear@13
|
21
|
nuclear@13
|
22 std::vector<StateItem> state;
|
nuclear@13
|
23 std::map<std::string, int> stateidx;
|
nuclear@13
|
24
|
nuclear@13
|
25
|
nuclear@13
|
26 int add_unistate(const char *name, StType type)
|
nuclear@13
|
27 {
|
nuclear@13
|
28 static const float ident3[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
|
nuclear@13
|
29 static const float ident4[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
|
nuclear@13
|
30
|
nuclear@13
|
31 if(stateidx.find(name) != stateidx.end()) {
|
nuclear@13
|
32 return stateidx[name];
|
nuclear@13
|
33 }
|
nuclear@13
|
34
|
nuclear@13
|
35 StateItem sitem;
|
nuclear@13
|
36 memset(&sitem, 0, sizeof sitem);
|
nuclear@13
|
37 sitem.type = type;
|
nuclear@13
|
38
|
nuclear@13
|
39 // initialize to a reasonable default value
|
nuclear@13
|
40 switch(type) {
|
nuclear@13
|
41 case ST_MATRIX3:
|
nuclear@13
|
42 memcpy(sitem.fval, ident3, sizeof ident3);
|
nuclear@13
|
43 break;
|
nuclear@13
|
44
|
nuclear@13
|
45 case ST_MATRIX4:
|
nuclear@13
|
46 memcpy(sitem.fval, ident4, sizeof ident4);
|
nuclear@13
|
47 break;
|
nuclear@13
|
48
|
nuclear@13
|
49 default:
|
nuclear@13
|
50 break; // in all other cases leave it zero (see memset above)
|
nuclear@13
|
51 }
|
nuclear@13
|
52
|
nuclear@13
|
53 int sidx = state.size();
|
nuclear@13
|
54 state.push_back(sitem);
|
nuclear@13
|
55 stateidx[name] = sidx;
|
nuclear@13
|
56
|
nuclear@13
|
57 debug_log("adding uniform state [%d]: %s %s\n", sidx, typestr(sitem.type), name);
|
nuclear@13
|
58
|
nuclear@13
|
59 return sidx;
|
nuclear@13
|
60 }
|
nuclear@13
|
61
|
nuclear@13
|
62 int get_unistate_index(const char *name)
|
nuclear@13
|
63 {
|
nuclear@13
|
64 std::map<std::string, int>::const_iterator it = stateidx.find(name);
|
nuclear@13
|
65 if(it != stateidx.end()) {
|
nuclear@13
|
66 return it->second;
|
nuclear@13
|
67 }
|
nuclear@13
|
68 return -1;
|
nuclear@13
|
69 }
|
nuclear@13
|
70
|
nuclear@13
|
71 #define CHECK_INDEX(i) \
|
nuclear@13
|
72 if(i < 0 || i >= (int)state.size()) return
|
nuclear@13
|
73
|
nuclear@13
|
74 #define CHECK_COUNT(count, type) \
|
nuclear@13
|
75 do { \
|
nuclear@13
|
76 int max_elem = type_nelem(type); \
|
nuclear@13
|
77 if(!(count) || (count) > max_elem) { \
|
nuclear@13
|
78 count = max_elem; \
|
nuclear@13
|
79 } \
|
nuclear@13
|
80 } while(0)
|
nuclear@13
|
81
|
nuclear@13
|
82 void set_unistate(int sidx, const int *val, int count)
|
nuclear@13
|
83 {
|
nuclear@13
|
84 CHECK_INDEX(sidx);
|
nuclear@13
|
85 CHECK_COUNT(count, state[sidx].type);
|
nuclear@13
|
86
|
nuclear@13
|
87 memcpy(state[sidx].ival, val, count * sizeof *state[sidx].ival);
|
nuclear@13
|
88 }
|
nuclear@13
|
89
|
nuclear@13
|
90 void set_unistate(int sidx, const float *val, int count)
|
nuclear@13
|
91 {
|
nuclear@13
|
92 CHECK_INDEX(sidx);
|
nuclear@13
|
93 CHECK_COUNT(count, state[sidx].type);
|
nuclear@13
|
94
|
nuclear@13
|
95 memcpy(state[sidx].fval, val, count * sizeof *state[sidx].fval);
|
nuclear@13
|
96 state[sidx].transpose = 0;
|
nuclear@13
|
97 }
|
nuclear@13
|
98
|
nuclear@13
|
99 void get_unistate(int sidx, int *val, int count)
|
nuclear@13
|
100 {
|
nuclear@13
|
101 CHECK_INDEX(sidx);
|
nuclear@13
|
102 CHECK_COUNT(count, state[sidx].type);
|
nuclear@13
|
103
|
nuclear@13
|
104 memcpy(val, state[sidx].ival, count * sizeof *val);
|
nuclear@13
|
105 }
|
nuclear@13
|
106
|
nuclear@13
|
107 void get_unistate(int sidx, float *val, int count)
|
nuclear@13
|
108 {
|
nuclear@13
|
109 CHECK_INDEX(sidx);
|
nuclear@13
|
110 CHECK_COUNT(count, state[sidx].type);
|
nuclear@13
|
111
|
nuclear@13
|
112 memcpy(val, state[sidx].fval, count * sizeof *val);
|
nuclear@13
|
113 }
|
nuclear@13
|
114
|
nuclear@13
|
115 void set_unistate(int sidx, int val)
|
nuclear@13
|
116 {
|
nuclear@13
|
117 set_unistate(sidx, &val, 1);
|
nuclear@13
|
118 }
|
nuclear@13
|
119
|
nuclear@13
|
120 void set_unistate(int sidx, float val)
|
nuclear@13
|
121 {
|
nuclear@13
|
122 set_unistate(sidx, &val, 1);
|
nuclear@13
|
123 }
|
nuclear@13
|
124
|
nuclear@13
|
125 void set_unistate(int sidx, const Vector2 &vec)
|
nuclear@13
|
126 {
|
nuclear@13
|
127 set_unistate(sidx, &vec.x, 2);
|
nuclear@13
|
128 }
|
nuclear@13
|
129
|
nuclear@13
|
130 void set_unistate(int sidx, const Vector3 &vec)
|
nuclear@13
|
131 {
|
nuclear@13
|
132 set_unistate(sidx, &vec.x, 3);
|
nuclear@13
|
133 }
|
nuclear@13
|
134
|
nuclear@13
|
135 void set_unistate(int sidx, const Vector4 &vec)
|
nuclear@13
|
136 {
|
nuclear@13
|
137 set_unistate(sidx, &vec.x, 4);
|
nuclear@13
|
138 }
|
nuclear@13
|
139
|
nuclear@13
|
140 void set_unistate(int sidx, const Matrix3x3 &mat)
|
nuclear@13
|
141 {
|
nuclear@13
|
142 set_unistate(sidx, mat[0], 9);
|
nuclear@13
|
143 state[sidx].transpose = 1;
|
nuclear@13
|
144 }
|
nuclear@13
|
145
|
nuclear@13
|
146 void set_unistate(int sidx, const Matrix4x4 &mat)
|
nuclear@13
|
147 {
|
nuclear@13
|
148 set_unistate(sidx, mat[0], 16);
|
nuclear@13
|
149 state[sidx].transpose = 1;
|
nuclear@13
|
150 }
|
nuclear@13
|
151
|
nuclear@13
|
152
|
nuclear@13
|
153 int set_unistate(const char *name, int *val, int count)
|
nuclear@13
|
154 {
|
nuclear@13
|
155 int sidx = get_unistate_index(name);
|
nuclear@13
|
156 if(sidx < 0) {
|
nuclear@13
|
157 StType type = int_type(count);
|
nuclear@13
|
158 if(type == ST_UNKNOWN) {
|
nuclear@13
|
159 error_log("invalid element count (%d) while setting previously unknown unistate item \"%s\"\n",
|
nuclear@13
|
160 count, name);
|
nuclear@13
|
161 return -1;
|
nuclear@13
|
162 }
|
nuclear@13
|
163
|
nuclear@13
|
164 sidx = add_unistate(name, type);
|
nuclear@13
|
165 }
|
nuclear@13
|
166 set_unistate(sidx, val);
|
nuclear@13
|
167 return sidx;
|
nuclear@13
|
168 }
|
nuclear@13
|
169
|
nuclear@13
|
170 int set_unistate(const char *name, float *val, int count)
|
nuclear@13
|
171 {
|
nuclear@13
|
172 int sidx = get_unistate_index(name);
|
nuclear@13
|
173 if(sidx < 0) {
|
nuclear@13
|
174 StType type = float_type(count);
|
nuclear@13
|
175 if(type == ST_UNKNOWN) {
|
nuclear@13
|
176 error_log("invalid element count (%d) while setting previously unknown unistate item \"%s\"\n",
|
nuclear@13
|
177 count, name);
|
nuclear@13
|
178 return -1;
|
nuclear@13
|
179 }
|
nuclear@13
|
180
|
nuclear@13
|
181 sidx = add_unistate(name, type);
|
nuclear@13
|
182 }
|
nuclear@13
|
183 set_unistate(sidx, val);
|
nuclear@13
|
184 return sidx;
|
nuclear@13
|
185 }
|
nuclear@13
|
186
|
nuclear@13
|
187 int set_unistate(const char *name, int val)
|
nuclear@13
|
188 {
|
nuclear@13
|
189 int sidx = get_unistate_index(name);
|
nuclear@13
|
190 if(sidx < 0) {
|
nuclear@13
|
191 sidx = add_unistate(name, ST_INT);
|
nuclear@13
|
192 }
|
nuclear@13
|
193 set_unistate(sidx, val);
|
nuclear@13
|
194 return sidx;
|
nuclear@13
|
195 }
|
nuclear@13
|
196
|
nuclear@13
|
197 int set_unistate(const char *name, float val)
|
nuclear@13
|
198 {
|
nuclear@13
|
199 int sidx = get_unistate_index(name);
|
nuclear@13
|
200 if(sidx < 0) {
|
nuclear@13
|
201 sidx = add_unistate(name, ST_FLOAT);
|
nuclear@13
|
202 }
|
nuclear@13
|
203 set_unistate(sidx, val);
|
nuclear@13
|
204 return sidx;
|
nuclear@13
|
205 }
|
nuclear@13
|
206
|
nuclear@13
|
207 int set_unistate(const char *name, const Vector2 &vec)
|
nuclear@13
|
208 {
|
nuclear@13
|
209 int sidx = get_unistate_index(name);
|
nuclear@13
|
210 if(sidx < 0) {
|
nuclear@13
|
211 sidx = add_unistate(name, ST_FLOAT2);
|
nuclear@13
|
212 }
|
nuclear@13
|
213 set_unistate(sidx, vec);
|
nuclear@13
|
214 return sidx;
|
nuclear@13
|
215 }
|
nuclear@13
|
216
|
nuclear@13
|
217 int set_unistate(const char *name, const Vector3 &vec)
|
nuclear@13
|
218 {
|
nuclear@13
|
219 int sidx = get_unistate_index(name);
|
nuclear@13
|
220 if(sidx < 0) {
|
nuclear@13
|
221 sidx = add_unistate(name, ST_FLOAT3);
|
nuclear@13
|
222 }
|
nuclear@13
|
223 set_unistate(sidx, vec);
|
nuclear@13
|
224 return sidx;
|
nuclear@13
|
225 }
|
nuclear@13
|
226
|
nuclear@13
|
227 int set_unistate(const char *name, const Vector4 &vec)
|
nuclear@13
|
228 {
|
nuclear@13
|
229 int sidx = get_unistate_index(name);
|
nuclear@13
|
230 if(sidx < 0) {
|
nuclear@13
|
231 sidx = add_unistate(name, ST_FLOAT4);
|
nuclear@13
|
232 }
|
nuclear@13
|
233 set_unistate(sidx, vec);
|
nuclear@13
|
234 return sidx;
|
nuclear@13
|
235 }
|
nuclear@13
|
236
|
nuclear@13
|
237 int set_unistate(const char *name, const Matrix3x3 &mat)
|
nuclear@13
|
238 {
|
nuclear@13
|
239 int sidx = get_unistate_index(name);
|
nuclear@13
|
240 if(sidx < 0) {
|
nuclear@13
|
241 sidx = add_unistate(name, ST_MATRIX3);
|
nuclear@13
|
242 }
|
nuclear@13
|
243 set_unistate(sidx, mat);
|
nuclear@13
|
244 return sidx;
|
nuclear@13
|
245 }
|
nuclear@13
|
246
|
nuclear@13
|
247 int set_unistate(const char *name, const Matrix4x4 &mat)
|
nuclear@13
|
248 {
|
nuclear@13
|
249 int sidx = get_unistate_index(name);
|
nuclear@13
|
250 if(sidx < 0) {
|
nuclear@13
|
251 sidx = add_unistate(name, ST_MATRIX4);
|
nuclear@13
|
252 }
|
nuclear@13
|
253 set_unistate(sidx, mat);
|
nuclear@13
|
254 return sidx;
|
nuclear@13
|
255 }
|
nuclear@13
|
256
|
nuclear@13
|
257
|
nuclear@13
|
258 int get_unistate_int(int sidx)
|
nuclear@13
|
259 {
|
nuclear@13
|
260 int val = 0;
|
nuclear@13
|
261 get_unistate(sidx, &val, 1);
|
nuclear@13
|
262 return val;
|
nuclear@13
|
263 }
|
nuclear@13
|
264
|
nuclear@13
|
265 float get_unistate_float(int sidx)
|
nuclear@13
|
266 {
|
nuclear@13
|
267 float val = 0.0f;
|
nuclear@13
|
268 get_unistate(sidx, &val, 1);
|
nuclear@13
|
269 return val;
|
nuclear@13
|
270 }
|
nuclear@13
|
271
|
nuclear@13
|
272 Vector2 get_unistate_vec2(int sidx)
|
nuclear@13
|
273 {
|
nuclear@13
|
274 float val[2] = {0.0f, 0.0f};
|
nuclear@13
|
275 get_unistate(sidx, val, 2);
|
nuclear@13
|
276 return Vector2(val[0], val[1]);
|
nuclear@13
|
277 }
|
nuclear@13
|
278
|
nuclear@13
|
279 Vector3 get_unistate_vec3(int sidx)
|
nuclear@13
|
280 {
|
nuclear@13
|
281 float val[3] = {0.0f, 0.0f, 0.0f};
|
nuclear@13
|
282 get_unistate(sidx, val, 3);
|
nuclear@13
|
283 return Vector3(val[0], val[1], val[2]);
|
nuclear@13
|
284 }
|
nuclear@13
|
285
|
nuclear@13
|
286 Vector4 get_unistate_vec4(int sidx)
|
nuclear@13
|
287 {
|
nuclear@13
|
288 float val[4] = {0.0f, 0.0f, 0.0f};
|
nuclear@13
|
289 get_unistate(sidx, val, 4);
|
nuclear@13
|
290 return Vector4(val[0], val[1], val[2], val[3]);
|
nuclear@13
|
291 }
|
nuclear@13
|
292
|
nuclear@13
|
293 Matrix3x3 get_unistate_mat3(int sidx)
|
nuclear@13
|
294 {
|
nuclear@13
|
295 Matrix3x3 res;
|
nuclear@13
|
296 get_unistate(sidx, res.m[0], 9);
|
nuclear@13
|
297 return res;
|
nuclear@13
|
298 }
|
nuclear@13
|
299
|
nuclear@13
|
300 Matrix4x4 get_unistate_mat4(int sidx)
|
nuclear@13
|
301 {
|
nuclear@13
|
302 Matrix4x4 res;
|
nuclear@13
|
303 get_unistate(sidx, res.m[0], 16);
|
nuclear@13
|
304 return res;
|
nuclear@13
|
305 }
|
nuclear@13
|
306
|
nuclear@13
|
307
|
nuclear@13
|
308 int get_unistate_int(const char *name)
|
nuclear@13
|
309 {
|
nuclear@13
|
310 int sidx = get_unistate_index(name);
|
nuclear@13
|
311 if(sidx == -1) {
|
nuclear@13
|
312 return 0;
|
nuclear@13
|
313 }
|
nuclear@13
|
314 return get_unistate_int(sidx);
|
nuclear@13
|
315 }
|
nuclear@13
|
316
|
nuclear@13
|
317 float get_unistate_float(const char *name)
|
nuclear@13
|
318 {
|
nuclear@13
|
319 int sidx = get_unistate_index(name);
|
nuclear@13
|
320 if(sidx == -1) {
|
nuclear@13
|
321 return 0.0f;
|
nuclear@13
|
322 }
|
nuclear@13
|
323 return get_unistate_float(sidx);
|
nuclear@13
|
324 }
|
nuclear@13
|
325
|
nuclear@13
|
326 Vector2 get_unistate_vec2(const char *name)
|
nuclear@13
|
327 {
|
nuclear@13
|
328 int sidx = get_unistate_index(name);
|
nuclear@13
|
329 if(sidx == -1) {
|
nuclear@13
|
330 return Vector2();
|
nuclear@13
|
331 }
|
nuclear@13
|
332 return get_unistate_vec2(sidx);
|
nuclear@13
|
333 }
|
nuclear@13
|
334
|
nuclear@13
|
335 Vector3 get_unistate_vec3(const char *name)
|
nuclear@13
|
336 {
|
nuclear@13
|
337 int sidx = get_unistate_index(name);
|
nuclear@13
|
338 if(sidx == -1) {
|
nuclear@13
|
339 return Vector3();
|
nuclear@13
|
340 }
|
nuclear@13
|
341 return get_unistate_vec3(sidx);
|
nuclear@13
|
342 }
|
nuclear@13
|
343
|
nuclear@13
|
344 Vector4 get_unistate_vec4(const char *name)
|
nuclear@13
|
345 {
|
nuclear@13
|
346 int sidx = get_unistate_index(name);
|
nuclear@13
|
347 if(sidx == -1) {
|
nuclear@13
|
348 return Vector4();
|
nuclear@13
|
349 }
|
nuclear@13
|
350 return get_unistate_vec4(sidx);
|
nuclear@13
|
351 }
|
nuclear@13
|
352
|
nuclear@13
|
353 Matrix3x3 get_unistate_mat3(const char *name)
|
nuclear@13
|
354 {
|
nuclear@13
|
355 int sidx = get_unistate_index(name);
|
nuclear@13
|
356 if(sidx == -1) {
|
nuclear@13
|
357 return Matrix3x3();
|
nuclear@13
|
358 }
|
nuclear@13
|
359 return get_unistate_mat3(sidx);
|
nuclear@13
|
360 }
|
nuclear@13
|
361
|
nuclear@13
|
362 Matrix4x4 get_unistate_mat4(const char *name)
|
nuclear@13
|
363 {
|
nuclear@13
|
364 int sidx = get_unistate_index(name);
|
nuclear@13
|
365 if(sidx == -1) {
|
nuclear@13
|
366 return Matrix4x4();
|
nuclear@13
|
367 }
|
nuclear@13
|
368 return get_unistate_mat4(sidx);
|
nuclear@13
|
369 }
|
nuclear@13
|
370
|
nuclear@13
|
371
|
nuclear@13
|
372 void setup_unistate(const ShaderProg *sdr)
|
nuclear@13
|
373 {
|
nuclear@13
|
374 if(!sdr) {
|
nuclear@13
|
375 if(!(sdr = ShaderProg::current)) {
|
nuclear@13
|
376 return;
|
nuclear@13
|
377 }
|
nuclear@13
|
378 }
|
nuclear@13
|
379
|
nuclear@13
|
380 sdr->setup_state_uniforms();
|
nuclear@13
|
381 }
|
nuclear@13
|
382
|
nuclear@13
|
383 bool setup_unistate(int sidx, const ShaderProg *sdr, int loc)
|
nuclear@13
|
384 {
|
nuclear@13
|
385 if(loc < 0 || sidx < 0 || sidx >= (int)state.size()) {
|
nuclear@13
|
386 return false;
|
nuclear@13
|
387 }
|
nuclear@13
|
388
|
nuclear@13
|
389 CHECKGLERR;
|
nuclear@13
|
390 glUseProgram(sdr->get_id());
|
nuclear@13
|
391 CHECKGLERR;
|
nuclear@13
|
392
|
nuclear@13
|
393 switch(state[sidx].type) {
|
nuclear@13
|
394 case ST_INT:
|
nuclear@13
|
395 glUniform1iv(loc, 1, state[sidx].ival);
|
nuclear@13
|
396 break;
|
nuclear@13
|
397 case ST_INT2:
|
nuclear@13
|
398 glUniform2iv(loc, 1, state[sidx].ival);
|
nuclear@13
|
399 break;
|
nuclear@13
|
400 case ST_INT3:
|
nuclear@13
|
401 glUniform3iv(loc, 1, state[sidx].ival);
|
nuclear@13
|
402 break;
|
nuclear@13
|
403 case ST_INT4:
|
nuclear@13
|
404 glUniform4iv(loc, 1, state[sidx].ival);
|
nuclear@13
|
405 break;
|
nuclear@13
|
406
|
nuclear@13
|
407 case ST_FLOAT:
|
nuclear@13
|
408 glUniform1fv(loc, 1, state[sidx].fval);
|
nuclear@13
|
409 break;
|
nuclear@13
|
410 case ST_FLOAT2:
|
nuclear@13
|
411 glUniform2fv(loc, 1, state[sidx].fval);
|
nuclear@13
|
412 break;
|
nuclear@13
|
413 case ST_FLOAT3:
|
nuclear@13
|
414 glUniform3fv(loc, 1, state[sidx].fval);
|
nuclear@13
|
415 break;
|
nuclear@13
|
416 case ST_FLOAT4:
|
nuclear@13
|
417 glUniform4fv(loc, 1, state[sidx].fval);
|
nuclear@13
|
418 break;
|
nuclear@13
|
419
|
nuclear@13
|
420 case ST_MATRIX3:
|
nuclear@13
|
421 #ifdef GL_ES_VERSION_2_0
|
nuclear@13
|
422 {
|
nuclear@13
|
423 float tmat[9], *ptr = tmat;
|
nuclear@13
|
424 for(int i=0; i<3; i++) {
|
nuclear@13
|
425 for(int j=0; j<3; j++) {
|
nuclear@13
|
426 *ptr++ = state[sidx].fval[j * 3 + i];
|
nuclear@13
|
427 }
|
nuclear@13
|
428 }
|
nuclear@13
|
429 glUniformMatrix3fv(loc, 1, GL_FALSE, tmat);
|
nuclear@13
|
430 }
|
nuclear@13
|
431 #else
|
nuclear@13
|
432 glUniformMatrix3fv(loc, 1, state[sidx].transpose, state[sidx].fval);
|
nuclear@13
|
433 #endif
|
nuclear@13
|
434 break;
|
nuclear@13
|
435
|
nuclear@13
|
436 case ST_MATRIX4:
|
nuclear@13
|
437 #ifdef GL_ES_VERSION_2_0
|
nuclear@13
|
438 {
|
nuclear@13
|
439 float tmat[16], *ptr = tmat;
|
nuclear@13
|
440 for(int i=0; i<4; i++) {
|
nuclear@13
|
441 for(int j=0; j<4; j++) {
|
nuclear@13
|
442 *ptr++ = state[sidx].fval[j * 4 + i];
|
nuclear@13
|
443 }
|
nuclear@13
|
444 }
|
nuclear@13
|
445 glUniformMatrix4fv(loc, 1, GL_FALSE, tmat);
|
nuclear@13
|
446 }
|
nuclear@13
|
447 #else
|
nuclear@13
|
448 glUniformMatrix4fv(loc, 1, state[sidx].transpose, state[sidx].fval);
|
nuclear@13
|
449 #endif
|
nuclear@13
|
450 break;
|
nuclear@13
|
451
|
nuclear@13
|
452 default:
|
nuclear@13
|
453 return false;
|
nuclear@13
|
454 }
|
nuclear@13
|
455
|
nuclear@13
|
456 CHECKGLERR;
|
nuclear@13
|
457 return true;
|
nuclear@13
|
458 }
|
nuclear@13
|
459
|
nuclear@13
|
460 bool setup_unistate(const char *name, const ShaderProg *sdr)
|
nuclear@13
|
461 {
|
nuclear@13
|
462 int loc = sdr->get_uniform_location(name);
|
nuclear@13
|
463 if(loc == -1) {
|
nuclear@13
|
464 return false;
|
nuclear@13
|
465 }
|
nuclear@13
|
466 return setup_unistate(get_unistate_index(name), sdr, loc);
|
nuclear@13
|
467 }
|
nuclear@13
|
468
|
nuclear@13
|
469 void set_world_matrix(const Matrix4x4 &mat)
|
nuclear@13
|
470 {
|
nuclear@13
|
471 static int sidx = -1, sidx_transp, sidx_mat3;
|
nuclear@13
|
472
|
nuclear@13
|
473 if(sidx == -1) {
|
nuclear@13
|
474 sidx = add_unistate("st_world_matrix", ST_MATRIX4);
|
nuclear@13
|
475 sidx_mat3 = add_unistate("st_world_matrix3", ST_MATRIX3);
|
nuclear@13
|
476 sidx_transp = add_unistate("st_world_matrix_transpose", ST_MATRIX4);
|
nuclear@13
|
477 }
|
nuclear@13
|
478
|
nuclear@13
|
479 set_unistate(sidx, mat);
|
nuclear@13
|
480 set_unistate(sidx_mat3, Matrix3x3(mat));
|
nuclear@13
|
481 set_unistate(sidx_transp, mat[0]); // by using the float* variant, we unset the transpose flag
|
nuclear@13
|
482 }
|
nuclear@13
|
483
|
nuclear@13
|
484 void set_view_matrix(const Matrix4x4 &mat)
|
nuclear@13
|
485 {
|
nuclear@13
|
486 static int sidx = -1, sidx_transp, sidx_mat3;
|
nuclear@13
|
487
|
nuclear@13
|
488 if(sidx == -1) {
|
nuclear@13
|
489 sidx = add_unistate("st_view_matrix", ST_MATRIX4);
|
nuclear@13
|
490 sidx_mat3 = add_unistate("st_view_matrix3", ST_MATRIX3);
|
nuclear@13
|
491 sidx_transp = add_unistate("st_view_matrix_transpose", ST_MATRIX4);
|
nuclear@13
|
492 }
|
nuclear@13
|
493
|
nuclear@13
|
494 set_unistate(sidx, mat);
|
nuclear@13
|
495 set_unistate(sidx_mat3, Matrix3x3(mat));
|
nuclear@13
|
496 set_unistate(sidx_transp, mat[0]); // by using the float* variant, we unset the transpose flag
|
nuclear@13
|
497 }
|
nuclear@13
|
498
|
nuclear@13
|
499 void set_projection_matrix(const Matrix4x4 &mat)
|
nuclear@13
|
500 {
|
nuclear@13
|
501 static int sidx = -1;
|
nuclear@13
|
502
|
nuclear@13
|
503 if(sidx == -1) {
|
nuclear@13
|
504 sidx = add_unistate("st_proj_matrix", ST_MATRIX4);
|
nuclear@13
|
505 }
|
nuclear@13
|
506
|
nuclear@13
|
507 set_unistate(sidx, mat);
|
nuclear@13
|
508 }
|
nuclear@13
|
509
|
nuclear@13
|
510 void set_texture_matrix(const Matrix4x4 &mat)
|
nuclear@13
|
511 {
|
nuclear@13
|
512 static int sidx = -1;
|
nuclear@13
|
513
|
nuclear@13
|
514 if(sidx == -1) {
|
nuclear@13
|
515 sidx = add_unistate("st_tex_matrix", ST_MATRIX4);
|
nuclear@13
|
516 }
|
nuclear@13
|
517
|
nuclear@13
|
518 set_unistate(sidx, mat);
|
nuclear@13
|
519 }
|
nuclear@13
|
520
|
nuclear@13
|
521 Matrix4x4 get_world_matrix()
|
nuclear@13
|
522 {
|
nuclear@13
|
523 static int sidx = -1;
|
nuclear@13
|
524
|
nuclear@13
|
525 if(sidx == -1) {
|
nuclear@13
|
526 if((sidx = get_unistate_index("st_world_matrix")) == -1) {
|
nuclear@13
|
527 return Matrix4x4();
|
nuclear@13
|
528 }
|
nuclear@13
|
529 }
|
nuclear@13
|
530 return get_unistate_mat4(sidx);
|
nuclear@13
|
531 }
|
nuclear@13
|
532
|
nuclear@13
|
533 Matrix4x4 get_view_matrix()
|
nuclear@13
|
534 {
|
nuclear@13
|
535 static int sidx = -1;
|
nuclear@13
|
536
|
nuclear@13
|
537 if(sidx == -1) {
|
nuclear@13
|
538 if((sidx = get_unistate_index("st_view_matrix")) == -1) {
|
nuclear@13
|
539 return Matrix4x4();
|
nuclear@13
|
540 }
|
nuclear@13
|
541 }
|
nuclear@13
|
542 return get_unistate_mat4(sidx);
|
nuclear@13
|
543 }
|
nuclear@13
|
544
|
nuclear@13
|
545 Matrix4x4 get_projection_matrix()
|
nuclear@13
|
546 {
|
nuclear@13
|
547 static int sidx = -1;
|
nuclear@13
|
548
|
nuclear@13
|
549 if(sidx == -1) {
|
nuclear@13
|
550 if((sidx = get_unistate_index("st_proj_matrix")) == -1) {
|
nuclear@13
|
551 return Matrix4x4();
|
nuclear@13
|
552 }
|
nuclear@13
|
553 }
|
nuclear@13
|
554 return get_unistate_mat4(sidx);
|
nuclear@13
|
555 }
|
nuclear@13
|
556
|
nuclear@13
|
557 Matrix4x4 get_texture_matrix()
|
nuclear@13
|
558 {
|
nuclear@13
|
559 static int sidx = -1;
|
nuclear@13
|
560
|
nuclear@13
|
561 if(sidx == -1) {
|
nuclear@13
|
562 if((sidx = get_unistate_index("st_tex_matrix")) == -1) {
|
nuclear@13
|
563 return Matrix4x4();
|
nuclear@13
|
564 }
|
nuclear@13
|
565 }
|
nuclear@13
|
566 return get_unistate_mat4(sidx);
|
nuclear@13
|
567 }
|
nuclear@13
|
568
|
nuclear@13
|
569 void setup_gl_matrices()
|
nuclear@13
|
570 {
|
nuclear@13
|
571 #ifdef USE_OLDGL
|
nuclear@13
|
572 Matrix4x4 modelview = get_world_matrix() * get_view_matrix();
|
nuclear@13
|
573 Matrix4x4 proj = get_projection_matrix();
|
nuclear@13
|
574 Matrix4x4 tex = get_texture_matrix();
|
nuclear@13
|
575
|
nuclear@13
|
576 glMatrixMode(GL_TEXTURE);
|
nuclear@13
|
577 glLoadTransposeMatrixf(tex[0]);
|
nuclear@13
|
578 glMatrixMode(GL_PROJECTION);
|
nuclear@13
|
579 glLoadTransposeMatrixf(proj[0]);
|
nuclear@13
|
580 glMatrixMode(GL_MODELVIEW);
|
nuclear@13
|
581 glLoadTransposeMatrixf(modelview[0]);
|
nuclear@13
|
582 #endif
|
nuclear@13
|
583 }
|
nuclear@13
|
584
|
nuclear@13
|
585 static const char *typestr(StType type)
|
nuclear@13
|
586 {
|
nuclear@13
|
587 switch(type) {
|
nuclear@13
|
588 case ST_INT:
|
nuclear@13
|
589 return "int";
|
nuclear@13
|
590 case ST_INT2:
|
nuclear@13
|
591 return "ivec2";
|
nuclear@13
|
592 case ST_INT3:
|
nuclear@13
|
593 return "ivec3";
|
nuclear@13
|
594 case ST_INT4:
|
nuclear@13
|
595 return "ivec4";
|
nuclear@13
|
596 case ST_FLOAT:
|
nuclear@13
|
597 return "float";
|
nuclear@13
|
598 case ST_FLOAT2:
|
nuclear@13
|
599 return "vec2";
|
nuclear@13
|
600 case ST_FLOAT3:
|
nuclear@13
|
601 return "vec3";
|
nuclear@13
|
602 case ST_FLOAT4:
|
nuclear@13
|
603 return "vec4";
|
nuclear@13
|
604 case ST_MATRIX3:
|
nuclear@13
|
605 return "mat3";
|
nuclear@13
|
606 case ST_MATRIX4:
|
nuclear@13
|
607 return "mat4";
|
nuclear@13
|
608
|
nuclear@13
|
609 default:
|
nuclear@13
|
610 break;
|
nuclear@13
|
611 }
|
nuclear@13
|
612 return "<unknown>";
|
nuclear@13
|
613 }
|
nuclear@13
|
614
|
nuclear@13
|
615 static int type_nelem(StType type)
|
nuclear@13
|
616 {
|
nuclear@13
|
617 switch(type) {
|
nuclear@13
|
618 case ST_INT:
|
nuclear@13
|
619 case ST_FLOAT:
|
nuclear@13
|
620 return 1;
|
nuclear@13
|
621 case ST_INT2:
|
nuclear@13
|
622 case ST_FLOAT2:
|
nuclear@13
|
623 return 2;
|
nuclear@13
|
624 case ST_INT3:
|
nuclear@13
|
625 case ST_FLOAT3:
|
nuclear@13
|
626 return 3;
|
nuclear@13
|
627 case ST_INT4:
|
nuclear@13
|
628 case ST_FLOAT4:
|
nuclear@13
|
629 return 4;
|
nuclear@13
|
630 case ST_MATRIX3:
|
nuclear@13
|
631 return 9;
|
nuclear@13
|
632 case ST_MATRIX4:
|
nuclear@13
|
633 return 16;
|
nuclear@13
|
634
|
nuclear@13
|
635 default:
|
nuclear@13
|
636 break;
|
nuclear@13
|
637 }
|
nuclear@13
|
638
|
nuclear@13
|
639 return 0;
|
nuclear@13
|
640 }
|
nuclear@13
|
641
|
nuclear@13
|
642 static StType float_type(int elem)
|
nuclear@13
|
643 {
|
nuclear@13
|
644 switch(elem) {
|
nuclear@13
|
645 case 1:
|
nuclear@13
|
646 return ST_FLOAT;
|
nuclear@13
|
647 case 2:
|
nuclear@13
|
648 return ST_FLOAT2;
|
nuclear@13
|
649 case 3:
|
nuclear@13
|
650 return ST_FLOAT3;
|
nuclear@13
|
651 case 4:
|
nuclear@13
|
652 return ST_FLOAT4;
|
nuclear@13
|
653 case 9:
|
nuclear@13
|
654 return ST_MATRIX3;
|
nuclear@13
|
655 case 16:
|
nuclear@13
|
656 return ST_MATRIX4;
|
nuclear@13
|
657 default:
|
nuclear@13
|
658 break;
|
nuclear@13
|
659 }
|
nuclear@13
|
660 return ST_UNKNOWN;
|
nuclear@13
|
661 }
|
nuclear@13
|
662
|
nuclear@13
|
663 static StType int_type(int elem)
|
nuclear@13
|
664 {
|
nuclear@13
|
665 switch(elem) {
|
nuclear@13
|
666 case 1:
|
nuclear@13
|
667 return ST_INT;
|
nuclear@13
|
668 case 2:
|
nuclear@13
|
669 return ST_INT2;
|
nuclear@13
|
670 case 3:
|
nuclear@13
|
671 return ST_INT3;
|
nuclear@13
|
672 case 4:
|
nuclear@13
|
673 return ST_INT4;
|
nuclear@13
|
674 default:
|
nuclear@13
|
675 break;
|
nuclear@13
|
676 }
|
nuclear@13
|
677 return ST_UNKNOWN;
|
nuclear@13
|
678 }
|