1 /****************************************************************************
2 * MeshLab o o *
3 * A versatile mesh processing toolbox o o *
4 * _ O _ *
5 * Copyright(C) 2005-2008 \/)\/ *
6 * Visual Computing Lab /\/| *
7 * ISTI - Italian National Research Council | *
8 * \ *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
20 * for more details. *
21 * *
22 ****************************************************************************/
23 /****************************************************************************
24 History
25 $Log$
26 Revision 1.3 2007/12/11 16:18:56 corsini
27 minor change
28
29 Revision 1.2 2007/12/03 12:01:04 corsini
30 code restyling
31
32
33 ****************************************************************************/
34
35 // Local headers
36 #include "UniformVar.h"
37 #include "RmXmlParser.h"
38
39
UniformVar(QString & _name,QString & _typeString,UniformType _type)40 UniformVar::UniformVar(QString &_name, QString &_typeString, UniformType _type)
41 {
42 name = _name;
43 typeString = _typeString;
44 type = _type;
45 valid = true;
46 minSet = false;
47 maxSet = false;
48 realminSet = false;
49 realmaxSet = false;
50 }
51
setMin(int min)52 void UniformVar::setMin(int min)
53 {
54 if ((realminSet && min <= irealmin) || !realminSet) {
55 imin = min;
56 minSet = true;
57 }
58 }
59
setMax(int max)60 void UniformVar::setMax(int max)
61 {
62 if ((realmaxSet && max >= irealmax) || !realmaxSet) {
63 imax = max;
64 maxSet = true;
65 }
66 }
67
setMin(float min)68 void UniformVar::setMin(float min)
69 {
70 if ((realminSet && min <= frealmin) || !realminSet) {
71 fmin = min;
72 minSet = true;
73 }
74 }
75
setMax(float max)76 void UniformVar::setMax(float max)
77 {
78 if ((realmaxSet && max >= frealmax) || !realmaxSet) {
79 fmax = max;
80 maxSet = true;
81 }
82 }
83
testRealMin(int min)84 void UniformVar::testRealMin(int min)
85 {
86 if (!realminSet || min < irealmin) {
87 realminSet = true;
88 irealmin = min;
89 if (minSet && imin > irealmin)
90 minSet = false;
91 }
92 }
93
testRealMin(float min)94 void UniformVar::testRealMin(float min)
95 {
96 if (!realminSet || min < frealmin) {
97 realminSet = true;
98 frealmin = min;
99 if (minSet && fmin > frealmin)
100 minSet = false;
101 }
102 }
103
testRealMax(int max)104 void UniformVar::testRealMax(int max)
105 {
106 if (!realmaxSet || max > irealmax) {
107 realmaxSet = true;
108 irealmax = max;
109 if (maxSet && imax < irealmax)
110 maxSet = false;
111 }
112 }
113
testRealMax(float max)114 void UniformVar::testRealMax(float max)
115 {
116 if (!realmaxSet || max > irealmax) {
117 realmaxSet = true;
118 frealmax = max;
119 if (maxSet && fmax < frealmax)
120 maxSet = false;
121 }
122 }
123
getUniformKnownButUnimplementedTag(QDomElement & root,QString tag,QString tagname)124 bool UniformVar::getUniformKnownButUnimplementedTag(QDomElement &root, QString tag, QString tagname)
125 {
126 if (!RmXmlParser::getDomElement(root, tag, tagname).isNull()) {
127 representerTagName = tag;
128 return true;
129 }
130 return false;
131 }
132
133 /******************************/
134 /* 3 Common Methods for */
135 /* xml variable value mining */
136 /* [boolean][number][texture] */
137 /******************************/
getUniformBooleanVectorFromTag(QDomElement & root,QString tag,int vecsize,bool * vec,bool * found)138 bool UniformVar::getUniformBooleanVectorFromTag(QDomElement &root, QString tag, int vecsize, bool *vec, bool *found)
139 {
140 QDomElement el = RmXmlParser::getDomElement(root, tag, name);
141
142 if(!el.isNull()) {
143 if (found)
144 *found = true;
145 representerTagName = tag;
146 return UniformVar::getUniformBooleanVectorFromXmlTag(el, vecsize, vec);
147 }
148
149 if (found)
150 *found = false;
151 return false;
152 }
153
getUniformNumberVectorFromTag(QDomElement & root,QString tag,int vecsize,void * vec,bool intOrFloat,bool * found)154 bool UniformVar::getUniformNumberVectorFromTag(QDomElement &root, QString tag, int vecsize, void *vec, bool intOrFloat, bool *found)
155 {
156 QDomElement el = RmXmlParser::getDomElement(root, tag, name);
157
158 if (!el.isNull()) {
159 if (found)
160 *found = true;
161 representerTagName = tag;
162 return UniformVar::getUniformNumberVectorFromXmlTag(el, vecsize, vec, intOrFloat, this);
163 }
164
165 if (found)
166 *found = false;
167
168 return false;
169 }
170
getUniformTextureFromTag(QDomElement & root,QString tag,bool * found)171 bool UniformVar::getUniformTextureFromTag(QDomElement & root, QString tag, bool * found)
172 {
173 QDomElement el = RmXmlParser::getDomElement(root, tag, textureName);
174
175 if (!el.isNull()) {
176 if (found)
177 *found = true;
178 representerTagName = tag;
179 textureFilename = el.attribute("FILE_NAME");
180 return true;
181 }
182
183 if (found)
184 *found = false;
185
186 return false;
187 }
188
189
getValueFromXmlDocument(QDomElement & root,bool echoNotFound)190 bool UniformVar::getValueFromXmlDocument(QDomElement &root, bool echoNotFound)
191 {
192 bool fnd;
193 bool ok;
194
195 switch (type) {
196 case BOOL:
197 ok = getUniformBooleanVectorFromTag(root, "RmBooleanVariable", 1, &bvalue, &fnd);
198 if (fnd)
199 return ok;
200 break;
201
202 case INT:
203 ok = getUniformNumberVectorFromTag(root, "RmIntegerVariable", 1, &ivalue, &fnd);
204 if (fnd)
205 return ok;
206 break;
207
208 case FLOAT:
209 ok = getUniformNumberVectorFromTag(root, "RmFloatVariable", 1, &fvalue, &fnd);
210 if (fnd)
211 return ok;
212 break;
213
214 case IVEC2:
215 ok = getUniformNumberVectorFromTag(root, "RmVectorVariable", 2, ivec2, &fnd);
216 if (fnd)
217 return ok;
218 break;
219
220 case IVEC3:
221 ok = getUniformNumberVectorFromTag(root, "RmVectorVariable", 3, ivec3, &fnd);
222 if (fnd)
223 return ok;
224 break;
225
226 case IVEC4:
227 ok = getUniformNumberVectorFromTag(root, "RmVectorVariable", 4, ivec4, &fnd);
228 if (fnd)
229 return ok;
230 break;
231
232 case BVEC2:
233 ok = getUniformBooleanVectorFromTag(root, "RmVectorVariable", 2, bvec2, &fnd);
234 if (fnd)
235 return ok;
236 break;
237
238 case BVEC3:
239 ok = getUniformBooleanVectorFromTag(root, "RmVectorVariable", 3, bvec3, &fnd);
240 if (fnd)
241 return ok;
242 break;
243
244 case BVEC4:
245 ok = getUniformBooleanVectorFromTag(root, "RmVectorVariable", 4, bvec4, &fnd);
246 if (fnd)
247 return ok;
248 break;
249
250 case VEC2:
251 ok = getUniformNumberVectorFromTag(root, "RmVectorVariable", 2, vec2, &fnd);
252 if (fnd)
253 return ok;
254 break;
255
256 case VEC3:
257 ok = getUniformNumberVectorFromTag(root, "RmVectorVariable", 3, vec3, &fnd);
258 if (fnd)
259 return ok;
260 break;
261
262 case VEC4:
263 // * a vec4 can be RmVectorVariable or RmColorVariable
264 ok = getUniformNumberVectorFromTag(root, "RmVectorVariable", 4, vec4, &fnd);
265 if (fnd)
266 return ok;
267
268 ok = getUniformNumberVectorFromTag(root, "RmColorVariable", 4, vec4, &fnd);
269 if (fnd)
270 return ok;
271 break;
272
273 case MAT2:
274 ok = getUniformNumberVectorFromTag(root, "RmMatrixVariable", 4, (float*)mat2, &fnd);
275 if (fnd)
276 return ok;
277 break;
278
279 case MAT3:
280 ok = getUniformNumberVectorFromTag(root, "RmMatrixVariable", 8, (float*)mat3, &fnd);
281 if (fnd)
282 return ok;
283 break;
284
285 case MAT4:
286 ok = getUniformNumberVectorFromTag(root, "RmMatrixVariable", 16, (float*)mat4, &fnd);
287 if (fnd)
288 return ok;
289 break;
290
291 case SAMPLER2D:
292 // * sampler 2d can be Rm2DTextureVariable or not come from a texture file but
293 // * found in a RmRenderTarget xml tag
294 ok = getUniformTextureFromTag(root, "Rm2DTextureVariable", &fnd);
295 if (fnd)
296 return ok;
297
298 if (getUniformKnownButUnimplementedTag(root, "RmRenderTarget", textureName))
299 return true;
300 break;
301
302 case SAMPLER3D:
303 ok = getUniformTextureFromTag(root, "Rm3DTextureVariable", &fnd);
304 if (fnd)
305 return ok;
306 break;
307
308 case SAMPLERCUBE:
309 ok = getUniformTextureFromTag(root, "RmCubemapVariable", &fnd);
310 if (fnd)
311 return ok;
312 break;
313
314 default:
315 qDebug() << "RmXmlParser for uniform variable" << name << "of type"
316 << UniformVar::getStringFromUniformType(type);
317 qDebug() << "I don't know how to read my default value.. please implement me !";
318 return false;
319 }
320
321 // * any variable can be defined as RmDynamicVariable
322 if (getUniformKnownButUnimplementedTag( root, "RmDynamicVariable", name))
323 return true;
324
325 if (echoNotFound) {
326 qDebug() << "RmXmlParser for uniform variable" << name << "of type"
327 << UniformVar::getStringFromUniformType(type);
328 qDebug() << "Default value not found";
329 }
330 return false;
331 }
332
333 QString UniformVar::typeList[NUM_TYPES] = {
334 "int", "float", "bool",
335 "vec2", "vec3", "vec4",
336 "ivec2", "ivec3", "ivec4",
337 "bvec2", "bvec3", "bvec4",
338 "mat2", "mat3", "mat4",
339 "sampler1D", "sampler2D", "sampler3D",
340 "samplerCube",
341 "sampler1Dshadow", "sampler2Dshadow"
342 };
343
getTypeFromString(QString & type)344 enum UniformVar::UniformType UniformVar::getTypeFromString(QString &type)
345 {
346 for (int i = 0; i < 21; i++)
347 if (type == typeList[i])
348 return static_cast<UniformType>(i);
349 return OTHER;
350 }
351
352
getStringFromUniformType(UniformType type)353 QString UniformVar::getStringFromUniformType(UniformType type)
354 {
355 if (!(type < INT && type > SAMPLER2DSHADOW))
356 return typeList[type];
357 return "other";
358 }
359
VarDump(int indent,bool extendedVarDump)360 void UniformVar::VarDump(int indent, bool extendedVarDump)
361 {
362 QString ret = "";
363
364 for (int i = 0; i < indent; i++)
365 ret += " ";
366
367 ret += typeString + QString(" ") + name;
368
369 switch (type) {
370 case INT:
371 ret += " = " + QString().setNum(ivalue);
372 if (minSet || maxSet)
373 ret += " (";
374 if (minSet)
375 ret += "from " + QString().setNum(imin) + " ";
376 if (maxSet)
377 ret += "to "+ QString().setNum(imax);
378 if (minSet || maxSet)
379 ret += ")";
380 break;
381
382 case FLOAT:
383 ret += " = " + QString().setNum(fvalue);
384 if (minSet || maxSet)
385 ret += " (";
386 if (minSet)
387 ret += "from " + QString().setNum(fmin) + " ";
388 if (maxSet)
389 ret += "to "+ QString().setNum(fmax);
390 if (minSet || maxSet)
391 ret += ")";
392 break;
393
394 case BOOL:
395 ret += bvalue ? " = true" : " = false";
396 break;
397
398 case IVEC2:
399 ret += " = [ ";
400 for (int i = 0; i < 2; i++)
401 ret += QString().setNum(ivec2[i]) + " ";
402 ret += "]";
403 break;
404
405 case IVEC3:
406 ret += " = [ ";
407 for (int i = 0; i < 3; i++)
408 ret += QString().setNum(ivec3[i]) + " ";
409 ret += "]";
410 break;
411
412 case IVEC4:
413 ret += " = [ ";
414 for (int i = 0; i < 4; i++)
415 ret += QString().setNum(ivec4[i]) + " ";
416 ret += "]";
417 break;
418
419 case BVEC2:
420 ret += " = [ ";
421 for (int i = 0; i < 2; i++)
422 ret += bvec2[i] ? "true " : "false ";
423 ret += "]";
424 break;
425
426 case BVEC3:
427 ret += " = [ ";
428 for (int i = 0; i < 3; i++)
429 ret += bvec3[i] ? "true " : "false ";
430 ret += "]";
431 break;
432
433 case BVEC4:
434 ret += " = [ ";
435 for (int i = 0; i < 4; i++)
436 ret += bvec4[i] ? "true " : "false ";
437 ret += "]";
438 break;
439
440 case VEC2:
441 ret += " = [ ";
442 for (int i = 0; i < 2; i++)
443 ret += QString().setNum(vec2[i]) + " ";
444 ret += "]";
445 break;
446
447 case VEC3:
448 ret += " = [ ";
449 for (int i = 0; i < 3; i++)
450 ret += QString().setNum(vec3[i]) + " ";
451 ret += "]";
452 break;
453
454 case VEC4:
455 ret += " = [ ";
456 for (int i = 0; i < 4; i++)
457 ret += QString().setNum(vec3[i]) + " ";
458 ret += "]";
459 break;
460
461 case MAT2:
462 case MAT3:
463 case MAT4:
464 ret += " [matrix]";
465 if (extendedVarDump) {
466 int n = ((type == MAT2)? 2 : ((type == MAT3)? 3 : 4));
467 float *mat = ((type == MAT2)?
468 (float*)mat2 :
469 (type == MAT3)? (float*)mat3 : (float*)mat4);
470 ret += "\n";
471
472 for (int i = 0; i < n; i++) {
473 for (int k = 0; k < indent+2; k++)
474 ret += " ";
475 ret += "[ ";
476
477 for (int j = 0; j < n; j++)
478 ret += QString().setNum( mat[i*n+j] ) + " ";
479 ret += "]";
480
481 if (i + 1 < n)
482 ret += "\n";
483 }
484 }
485 break;
486
487 case SAMPLER1DSHADOW:
488 case SAMPLER2DSHADOW:
489 case SAMPLERCUBE:
490 case SAMPLER1D:
491 case SAMPLER2D:
492 case SAMPLER3D:
493 if (textureFilename.isEmpty())
494 ret += " = no filename, textureName = " + textureName;
495 else
496 ret += " = " + textureFilename;
497
498 if (representerTagName == "RmRenderTarget")
499 ret += " [RmRenderTarget]";
500
501 if (extendedVarDump) {
502 if (textureGLStates.size() == 0) {
503 ret += " [with no openGL states]";
504 } else {
505 ret += "\n";
506 for (int i = 0; i < textureGLStates.size(); i++) {
507 for (int j = 0; j < indent+2; j++)
508 ret += " ";
509
510 ret += "\"" + textureGLStates[i].getName() + "\" (" +
511 QString().setNum(textureGLStates[i].getState()).toLatin1().data() + ") => " +
512 QString().setNum(textureGLStates[i].getValue());
513
514 if (i + 1 < textureGLStates.size())
515 ret += "\n";
516 }
517 }
518 } else {
519 ret += " [openGL states: " + QString().setNum(textureGLStates.size()) + "]";
520 }
521 break;
522
523 default:
524 ret += " [implement me]";
525 }
526
527 qDebug() << ret.toLatin1().data();
528 }
529
530
getUniformNumberVectorFromXmlTag(QDomElement & el,int values,void * narr,bool intOrFloat,UniformVar * ptr)531 bool UniformVar::getUniformNumberVectorFromXmlTag(QDomElement &el, int values, void *narr, bool intOrFloat, UniformVar *ptr)
532 {
533 int *iarr = (int*)narr;
534 float *farr = (float*)narr;
535
536 bool ok1 = true, ok2 = true;
537
538 for (int i = 0; i < values; i++) {
539 QString attrname = "VALUE";
540 if (values > 1)
541 attrname += "_" + QString().setNum(i);
542 QString attrvalue = el.attribute(attrname);
543
544 if (intOrFloat) {
545 int val = attrvalue.toInt(&ok1);
546 if (ok1) {
547 iarr[i] = val;
548 ptr->testRealMin(val);
549 ptr->testRealMax(val);
550 }
551 } else {
552 float val = attrvalue.toFloat(&ok1);
553 if (ok1) {
554 farr[i] = val;
555 ptr->testRealMin(val);
556 ptr->testRealMax(val);
557 }
558 }
559
560 if (!ok1) {
561 qDebug() << "RmXmlParser: error while reading default value for "
562 << (intOrFloat ? "int" : "float" ) << " vector["
563 << values << "]" << el.attribute("NAME") << ":"
564 << attrname << "=>" << attrvalue;
565 return false;
566 }
567 }
568
569 if (!el.attribute("MIN").isEmpty()) {
570 if (intOrFloat) {
571 int min = el.attribute("MIN").toInt(&ok1);
572 if (ok1)
573 ptr->setMin(min);
574 } else {
575 float min = el.attribute("MIN").toFloat(&ok1);
576 if (ok1)
577 ptr->setMin(min);
578 }
579 }
580
581 if (!el.attribute("MAX").isEmpty()) {
582 if (intOrFloat) {
583 int max = el.attribute("MAX").toInt(&ok2);
584 if (ok2)
585 ptr->setMax(max);
586 } else {
587 float max = el.attribute("MAX").toFloat(&ok2);
588 if (ok2)
589 ptr->setMax(max);
590 }
591 }
592
593 if (!ok1 || !ok2) {
594 qDebug() << "RmXmlParser: error while reading default value for float vector["
595 << values << "]" << el.attribute("NAME");
596 qDebug() << "Min_ok("<< ok1 <<") Max_ok("<< ok2 <<")";
597 }
598
599 return true;
600 }
601
getUniformBooleanVectorFromXmlTag(QDomElement & el,int values,bool * barr)602 bool UniformVar::getUniformBooleanVectorFromXmlTag(QDomElement &el, int values, bool *barr)
603 {
604 for (int i = 0; i < values; i++) {
605 QString attrname = "VALUE";
606 if (values > 1)
607 attrname += "_" + QString().setNum(i);
608
609 QString attrvalue = el.attribute(attrname);
610
611 if (attrvalue != "TRUE" && attrvalue != "FALSE") {
612 qDebug() << "RmXmlParser: error while reading default value for boolean vector["
613 << values<<"]" << el.attribute("NAME");
614 qDebug() << attrvalue << "is not TRUE neither FALSE";
615 return false;
616 }
617 barr[i] = (attrvalue == "TRUE");
618 }
619 return true;
620 }
621