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