1 /* bzflag
2 * Copyright (c) 1993-2021 Tim Riker
3 *
4 * This package is free software; you can redistribute it and/or
5 * modify it under the terms of the license found in the file
6 * named COPYING that should have accompanied this file.
7 *
8 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 */
12
13 #include <string.h>
14
15 #include "BzMaterial.h"
16 #include "TextureMatrix.h"
17 #include "DynamicColor.h"
18 #include "Pack.h"
19
20
21 /****************************************************************************/
22 //
23 // BzMaterialManager
24 //
25
26 BzMaterialManager MATERIALMGR;
27
28
BzMaterialManager()29 BzMaterialManager::BzMaterialManager()
30 {
31 return;
32 }
33
34
~BzMaterialManager()35 BzMaterialManager::~BzMaterialManager()
36 {
37 clear();
38 return;
39 }
40
41
clear()42 void BzMaterialManager::clear()
43 {
44 for (unsigned int i = 0; i < materials.size(); i++)
45 delete materials[i];
46 materials.clear();
47 return;
48 }
49
50
addMaterial(const BzMaterial * material)51 const BzMaterial* BzMaterialManager::addMaterial(const BzMaterial* material)
52 {
53 for (unsigned int i = 0; i < materials.size(); i++)
54 {
55 if (*material == *(materials[i]))
56 {
57 const std::string& name = material->getName();
58 if (name.size() > 0)
59 materials[i]->addAlias(name);
60 return materials[i];
61 }
62 }
63 BzMaterial* newMat = new BzMaterial(*material);
64 if (findMaterial(newMat->getName()) != NULL)
65 newMat->setName("");
66 materials.push_back(newMat);
67 return newMat;
68 }
69
70
findMaterial(const std::string & target) const71 const BzMaterial* BzMaterialManager::findMaterial(const std::string& target) const
72 {
73 if (target.size() <= 0)
74 return NULL;
75 else if ((target[0] >= '0') && (target[0] <= '9'))
76 {
77 int index = atoi (target.c_str());
78 if ((index < 0) || (index >= (int)materials.size()))
79 return NULL;
80 else
81 return materials[index];
82 }
83 else
84 {
85 for (unsigned int i = 0; i < materials.size(); i++)
86 {
87 const BzMaterial* mat = materials[i];
88 // check the base name
89 if (target == mat->getName())
90 return mat;
91 // check the aliases
92 const std::vector<std::string>& aliases = mat->getAliases();
93 for (unsigned int j = 0; j < aliases.size(); j++)
94 {
95 if (target == aliases[j])
96 return mat;
97 }
98 }
99 return NULL;
100 }
101 }
102
103
getMaterial(int id) const104 const BzMaterial* BzMaterialManager::getMaterial(int id) const
105 {
106 if ((id < 0) || (id >= (int)materials.size()))
107 return BzMaterial::getDefault();
108 return materials[id];
109 }
110
111
getIndex(const BzMaterial * material) const112 int BzMaterialManager::getIndex(const BzMaterial* material) const
113 {
114 for (unsigned int i = 0; i < materials.size(); i++)
115 {
116 if (material == materials[i])
117 return i;
118 }
119 return -1;
120 }
121
122
pack(void * buf)123 void* BzMaterialManager::pack(void* buf)
124 {
125 buf = nboPackUInt(buf, (unsigned int)materials.size());
126 for (unsigned int i = 0; i < materials.size(); i++)
127 buf = materials[i]->pack(buf);
128
129 return buf;
130 }
131
132
unpack(const void * buf)133 const void* BzMaterialManager::unpack(const void* buf)
134 {
135 unsigned int i;
136 uint32_t count;
137 buf = nboUnpackUInt (buf, count);
138 for (i = 0; i < count; i++)
139 {
140 BzMaterial* mat = new BzMaterial;
141 buf = mat->unpack(buf);
142 materials.push_back(mat);
143 }
144 return buf;
145 }
146
147
packSize()148 int BzMaterialManager::packSize()
149 {
150 int fullSize = sizeof (uint32_t);
151 for (unsigned int i = 0; i < materials.size(); i++)
152 fullSize += materials[i]->packSize();
153 return fullSize;
154 }
155
156
print(std::ostream & out,const std::string & indent) const157 void BzMaterialManager::print(std::ostream& out, const std::string& indent) const
158 {
159 for (unsigned int i = 0; i < materials.size(); i++)
160 materials[i]->print(out, indent);
161 return;
162 }
163
164
printMTL(std::ostream & out,const std::string & indent) const165 void BzMaterialManager::printMTL(std::ostream& out, const std::string& indent) const
166 {
167 for (unsigned int i = 0; i < materials.size(); i++)
168 materials[i]->printMTL(out, indent);
169 return;
170 }
171
172
printReference(std::ostream & out,const BzMaterial * mat) const173 void BzMaterialManager::printReference(std::ostream& out,
174 const BzMaterial* mat) const
175 {
176 if (mat == NULL)
177 {
178 out << "-1";
179 return;
180 }
181 int index = getIndex(mat);
182 if (index == -1)
183 {
184 out << "-1";
185 return;
186 }
187 if (mat->getName().size() > 0)
188 {
189 out << mat->getName();
190 return;
191 }
192 else
193 {
194 out << index;
195 return;
196 }
197 }
198
199
makeTextureList(TextureSet & set,bool referenced) const200 void BzMaterialManager::makeTextureList(TextureSet& set, bool referenced) const
201 {
202 set.clear();
203 for (unsigned int i = 0; i < materials.size(); i++)
204 {
205 const BzMaterial* mat = materials[i];
206 for (int j = 0; j < mat->getTextureCount(); j++)
207 {
208 if (mat->getReference() || !referenced)
209 set.insert(mat->getTexture(j));
210 }
211 }
212 return;
213 }
214
215
setTextureLocal(const std::string & url,const std::string & local)216 void BzMaterialManager::setTextureLocal(const std::string& url,
217 const std::string& local)
218 {
219 for (unsigned int i = 0; i < materials.size(); i++)
220 {
221 BzMaterial* mat = materials[i];
222 for (int j = 0; j < mat->getTextureCount(); j++)
223 {
224 if (mat->getTexture(j) == url)
225 mat->setTextureLocal(j, local);
226 }
227 }
228 return;
229 }
230
231
232 /****************************************************************************/
233 //
234 // BzMaterial
235 //
236
237 BzMaterial BzMaterial::defaultMaterial;
238 std::string BzMaterial::nullString = "";
239
240
reset()241 void BzMaterial::reset()
242 {
243 dynamicColor = -1;
244 const float defAmbient[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
245 const float defDiffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
246 const float defSpecular[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
247 const float defEmission[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
248 memcpy (ambient, defAmbient, sizeof(ambient));
249 memcpy (diffuse, defDiffuse, sizeof(diffuse));
250 memcpy (specular, defSpecular, sizeof(specular));
251 memcpy (emission, defEmission, sizeof(emission));
252 shininess = 0.0f;
253 alphaThreshold = 0.0f;
254 occluder = false;
255 groupAlpha = false;
256 noRadar = false;
257 noShadow = false;
258 noCulling = false;
259 noSorting = false;
260 noLighting = false;
261
262 delete[] textures;
263 textures = NULL;
264 textureCount = 0;
265
266 delete[] shaders;
267 shaders = NULL;
268 shaderCount = 0;
269
270 referenced = false;
271
272 return;
273 }
274
275
BzMaterial()276 BzMaterial::BzMaterial()
277 {
278 textures = NULL;
279 shaders = NULL;
280 reset();
281 return;
282 }
283
284
~BzMaterial()285 BzMaterial::~BzMaterial()
286 {
287 delete[] textures;
288 delete[] shaders;
289 return;
290 }
291
292
BzMaterial(const BzMaterial & m)293 BzMaterial::BzMaterial(const BzMaterial& m)
294 {
295 textures = NULL;
296 shaders = NULL;
297 *this = m;
298 return;
299 }
300
301
operator =(const BzMaterial & m)302 BzMaterial& BzMaterial::operator=(const BzMaterial& m)
303 {
304 int i;
305
306 referenced = false;
307
308 name = m.name;
309 aliases = m.aliases;
310
311 dynamicColor = m.dynamicColor;
312 memcpy (ambient, m.ambient, sizeof(ambient));
313 memcpy (diffuse, m.diffuse, sizeof(diffuse));
314 memcpy (specular, m.specular, sizeof(specular));
315 memcpy (emission, m.emission, sizeof(emission));
316 shininess = m.shininess;
317 alphaThreshold = m.alphaThreshold;
318 occluder = m.occluder;
319 groupAlpha = m.groupAlpha;
320 noRadar = m.noRadar;
321 noShadow = m.noShadow;
322 noCulling = m.noCulling;
323 noSorting = m.noSorting;
324 noLighting = m.noLighting;
325
326 delete[] textures;
327 textureCount = m.textureCount;
328 if (textureCount > 0)
329 textures = new TextureInfo[textureCount];
330 else
331 textures = NULL;
332 for (i = 0; i < textureCount; i++)
333 textures[i] = m.textures[i];
334
335 delete[] shaders;
336 shaderCount = m.shaderCount;
337 if (shaderCount > 0)
338 shaders = new ShaderInfo[shaderCount];
339 else
340 shaders = NULL;
341 for (i = 0; i < shaderCount; i++)
342 shaders[i] = m.shaders[i];
343
344 return *this;
345 }
346
347
operator ==(const BzMaterial & m) const348 bool BzMaterial::operator==(const BzMaterial& m) const
349 {
350 int i;
351
352 if ((dynamicColor != m.dynamicColor) ||
353 (memcmp (ambient, m.ambient, sizeof(float[4])) != 0) ||
354 (memcmp (diffuse, m.diffuse, sizeof(float[4])) != 0) ||
355 (memcmp (specular, m.specular, sizeof(float[4])) != 0) ||
356 (memcmp (emission, m.emission, sizeof(float[4])) != 0) ||
357 (shininess != m.shininess) || (alphaThreshold != m.alphaThreshold) ||
358 (occluder != m.occluder) || (groupAlpha != m.groupAlpha) ||
359 (noRadar != m.noRadar) || (noShadow != m.noShadow) ||
360 (noCulling != m.noCulling) || (noSorting != m.noSorting) ||
361 (noLighting != m.noLighting))
362 return false;
363
364 if (textureCount != m.textureCount)
365 return false;
366 for (i = 0; i < textureCount; i++)
367 {
368 if ((textures[i].name != m.textures[i].name) ||
369 (textures[i].matrix != m.textures[i].matrix) ||
370 (textures[i].combineMode != m.textures[i].combineMode) ||
371 (textures[i].useAlpha != m.textures[i].useAlpha) ||
372 (textures[i].useColor != m.textures[i].useColor) ||
373 (textures[i].useSphereMap != m.textures[i].useSphereMap))
374 return false;
375 }
376
377 if (shaderCount != m.shaderCount)
378 return false;
379 for (i = 0; i < shaderCount; i++)
380 {
381 if (shaders[i].name != m.shaders[i].name)
382 return false;
383 }
384
385 return true;
386 }
387
388
pack4Float(void * buf,const float values[4])389 static void* pack4Float(void *buf, const float values[4])
390 {
391 int i;
392 for (i = 0; i < 4; i++)
393 buf = nboPackFloat(buf, values[i]);
394 return buf;
395 }
396
397
unpack4Float(const void * buf,float values[4])398 static const void* unpack4Float(const void *buf, float values[4])
399 {
400 int i;
401 for (i = 0; i < 4; i++)
402 buf = nboUnpackFloat(buf, values[i]);
403 return buf;
404 }
405
406
pack(void * buf) const407 void* BzMaterial::pack(void* buf) const
408 {
409 int i;
410
411 buf = nboPackStdString(buf, name);
412
413 uint8_t modeByte = 0;
414 if (noCulling) modeByte |= (1 << 0);
415 if (noSorting) modeByte |= (1 << 1);
416 if (noRadar) modeByte |= (1 << 2);
417 if (noShadow) modeByte |= (1 << 3);
418 if (occluder) modeByte |= (1 << 4);
419 if (groupAlpha) modeByte |= (1 << 5);
420 if (noLighting) modeByte |= (1 << 6);
421 buf = nboPackUByte(buf, modeByte);
422
423 buf = nboPackInt(buf, dynamicColor);
424 buf = pack4Float(buf, ambient);
425 buf = pack4Float(buf, diffuse);
426 buf = pack4Float(buf, specular);
427 buf = pack4Float(buf, emission);
428 buf = nboPackFloat(buf, shininess);
429 buf = nboPackFloat(buf, alphaThreshold);
430
431 buf = nboPackUByte(buf, textureCount);
432 for (i = 0; i < textureCount; i++)
433 {
434 const TextureInfo* texinfo = &textures[i];
435
436 buf = nboPackStdString(buf, texinfo->name);
437 buf = nboPackInt(buf, texinfo->matrix);
438 buf = nboPackInt(buf, texinfo->combineMode);
439 unsigned char stateByte = 0;
440 if (texinfo->useAlpha)
441 stateByte = stateByte | (1 << 0);
442 if (texinfo->useColor)
443 stateByte = stateByte | (1 << 1);
444 if (texinfo->useSphereMap)
445 stateByte = stateByte | (1 << 2);
446 buf = nboPackUByte(buf, stateByte);
447 }
448
449 buf = nboPackUByte(buf, shaderCount);
450 for (i = 0; i < shaderCount; i++)
451 buf = nboPackStdString(buf, shaders[i].name);
452
453 return buf;
454 }
455
456
unpack(const void * buf)457 const void* BzMaterial::unpack(const void* buf)
458 {
459 int i;
460 int32_t inTmp;
461
462 buf = nboUnpackStdString(buf, name);
463
464 uint8_t modeByte;
465 buf = nboUnpackUByte(buf, modeByte);
466 noCulling = (modeByte & (1 << 0)) != 0;
467 noSorting = (modeByte & (1 << 1)) != 0;
468 noRadar = (modeByte & (1 << 2)) != 0;
469 noShadow = (modeByte & (1 << 3)) != 0;
470 occluder = (modeByte & (1 << 4)) != 0;
471 groupAlpha = (modeByte & (1 << 5)) != 0;
472 noLighting = (modeByte & (1 << 6)) != 0;
473
474 buf = nboUnpackInt(buf, inTmp);
475 dynamicColor = int(inTmp);
476 buf = unpack4Float(buf, ambient);
477 buf = unpack4Float(buf, diffuse);
478 buf = unpack4Float(buf, specular);
479 buf = unpack4Float(buf, emission);
480 buf = nboUnpackFloat(buf, shininess);
481 buf = nboUnpackFloat(buf, alphaThreshold);
482
483 unsigned char tCount;
484 buf = nboUnpackUByte(buf, tCount);
485 textureCount = tCount;
486 textures = new TextureInfo[textureCount];
487 for (i = 0; i < textureCount; i++)
488 {
489 TextureInfo* texinfo = &textures[i];
490 buf = nboUnpackStdString(buf, texinfo->name);
491 texinfo->localname = texinfo->name;
492 buf = nboUnpackInt(buf, inTmp);
493 texinfo->matrix = int(inTmp);
494 buf = nboUnpackInt(buf, inTmp);
495 texinfo->combineMode = int(inTmp);
496 texinfo->useAlpha = false;
497 texinfo->useColor = false;
498 texinfo->useSphereMap = false;
499 unsigned char stateByte;
500 buf = nboUnpackUByte(buf, stateByte);
501 if (stateByte & (1 << 0))
502 texinfo->useAlpha = true;
503 if (stateByte & (1 << 1))
504 texinfo->useColor = true;
505 if (stateByte & (1 << 2))
506 texinfo->useSphereMap = true;
507 }
508
509 unsigned char sCount;
510 buf = nboUnpackUByte(buf, sCount);
511 shaderCount = sCount;
512 shaders = new ShaderInfo[shaderCount];
513 for (i = 0; i < shaderCount; i++)
514 buf = nboUnpackStdString(buf, shaders[i].name);
515
516 return buf;
517 }
518
519
packSize() const520 int BzMaterial::packSize() const
521 {
522 int i;
523
524 const int modeSize = sizeof(uint8_t);
525
526 const int colorSize = sizeof(int32_t) + (4 * sizeof(float[4])) +
527 sizeof(float) + sizeof(float);
528
529 int textureSize = sizeof(unsigned char);
530 for (i = 0; i < textureCount; i++)
531 {
532 textureSize += nboStdStringPackSize(textures[i].name);
533 textureSize += sizeof(int32_t);
534 textureSize += sizeof(int32_t);
535 textureSize += sizeof(unsigned char);
536 }
537
538 int shaderSize = sizeof(unsigned char);
539 for (i = 0; i < shaderCount; i++)
540 shaderSize += nboStdStringPackSize(shaders[i].name);
541
542 return nboStdStringPackSize(name) + modeSize + colorSize + textureSize + shaderSize;
543 }
544
545
printColor(std::ostream & out,const char * name,const float color[4],const float reference[4])546 static void printColor(std::ostream& out, const char *name,
547 const float color[4], const float reference[4])
548 {
549 if (memcmp(color, reference, sizeof(float[4])) != 0)
550 {
551 out << name << color[0] << " " << color[1] << " "
552 << color[2] << " " << color[3] << std::endl;
553 }
554 return;
555 }
556
557
print(std::ostream & out,const std::string & indent) const558 void BzMaterial::print(std::ostream& out, const std::string& indent) const
559 {
560 int i;
561
562 out << indent << "material" << std::endl;
563
564 if (name.size() > 0)
565 out << indent << " name " << name << std::endl;
566
567 if (dynamicColor != defaultMaterial.dynamicColor)
568 {
569 out << indent << " dyncol ";
570 const DynamicColor* dyncol = DYNCOLORMGR.getColor(dynamicColor);
571 if ((dyncol != NULL) && (dyncol->getName().size() > 0))
572 out << dyncol->getName();
573 else
574 out << dynamicColor;
575 out << std::endl;
576 }
577 printColor(out, " ambient ", ambient, defaultMaterial.ambient);
578 printColor(out, " diffuse ", diffuse, defaultMaterial.diffuse);
579 printColor(out, " specular ", specular, defaultMaterial.specular);
580 printColor(out, " emission ", emission, defaultMaterial.emission);
581 if (shininess != defaultMaterial.shininess)
582 out << indent << " shininess " << shininess << std::endl;
583 if (alphaThreshold != defaultMaterial.alphaThreshold)
584 out << indent << " alphathresh " << alphaThreshold << std::endl;
585 if (occluder)
586 out << indent << " occluder" << std::endl;
587 if (groupAlpha)
588 out << indent << " groupAlpha" << std::endl;
589 if (noRadar)
590 out << indent << " noradar" << std::endl;
591 if (noShadow)
592 out << indent << " noshadow" << std::endl;
593 if (noCulling)
594 out << indent << " noculling" << std::endl;
595 if (noSorting)
596 out << indent << " nosorting" << std::endl;
597 if (noLighting)
598 out << indent << " nolighting" << std::endl;
599
600 for (i = 0; i < textureCount; i++)
601 {
602 const TextureInfo* texinfo = &textures[i];
603 out << indent << " addtexture " << texinfo->name << std::endl;
604 if (texinfo->matrix != -1)
605 {
606 out << indent << " texmat ";
607 const TextureMatrix* texmat = TEXMATRIXMGR.getMatrix(texinfo->matrix);
608 if ((texmat != NULL) && (texmat->getName().size() > 0))
609 out << texmat->getName();
610 else
611 out << texinfo->matrix;
612 out << std::endl;
613 }
614
615 if (!texinfo->useAlpha)
616 out << indent << " notexalpha" << std::endl;
617 if (!texinfo->useColor)
618 out << indent << " notexcolor" << std::endl;
619 if (texinfo->useSphereMap)
620 out << indent << " spheremap" << std::endl;
621 }
622
623 for (i = 0; i < shaderCount; i++)
624 {
625 const ShaderInfo* shdinfo = &shaders[i];
626 out << indent << " addshader " << shdinfo->name << std::endl;
627 }
628
629 out << indent << "end" << std::endl << std::endl;
630
631 return;
632 }
633
634
printMTL(std::ostream & out,const std::string & UNUSED (indent)) const635 void BzMaterial::printMTL(std::ostream& out, const std::string& UNUSED(indent)) const
636 {
637 out << "newmtl ";
638 if (name.size() > 0)
639 out << name << std::endl;
640 else
641 out << MATERIALMGR.getIndex(this) << std::endl;
642 if (noLighting)
643 out << "illum 0" << std::endl;
644 else
645 out << "illum 2" << std::endl;
646 out << "d " << diffuse[3] << std::endl;
647 const float* c;
648 c = ambient; // not really used
649 out << "#Ka " << c[0] << " " << c[1] << " " << c[2] << std::endl;
650 c = diffuse;
651 out << "Kd " << c[0] << " " << c[1] << " " << c[2] << std::endl;
652 c = emission;
653 out << "Ke " << c[0] << " " << c[1] << " " << c[2] << std::endl;
654 c = specular;
655 out << "Ks " << c[0] << " " << c[1] << " " << c[2] << std::endl;
656 out << "Ns " << (1000.0f * (shininess / 128.0f)) << std::endl;
657 if (textureCount > 0)
658 {
659 const TextureInfo* ti = &textures[0];
660 const unsigned int nlen = (unsigned int)ti->name.size();
661 if (nlen > 0)
662 {
663 std::string texname = ti->name;
664 const char* cname = texname.c_str();
665 if ((nlen < 4) || (strcasecmp(cname + (nlen - 4), ".png") != 0))
666 texname += ".png";
667 out << "map_Kd " << texname << std::endl;
668 }
669 }
670 out << std::endl;
671 return;
672 }
673
674
675 /****************************************************************************/
676 //
677 // Parameter setting
678 //
679
setName(const std::string & matname)680 bool BzMaterial::setName(const std::string& matname)
681 {
682 if (matname.size() <= 0)
683 {
684 name = "";
685 return false;
686 }
687 else if ((matname[0] >= '0') && (matname[0] <= '9'))
688 {
689 name = "";
690 return false;
691 }
692 else
693 name = matname;
694 return true;
695 }
696
addAlias(const std::string & alias)697 bool BzMaterial::addAlias(const std::string& alias)
698 {
699 if (alias.size() <= 0)
700 {
701 name = "";
702 return false;
703 }
704 else if ((alias[0] >= '0') && (alias[0] <= '9'))
705 {
706 name = "";
707 return false;
708 }
709 else
710 {
711 for ( unsigned int i = 0; i < (unsigned int)aliases.size(); i++)
712 {
713 if ( aliases[i] == alias )
714 return true;
715 }
716 aliases.push_back(alias); // only add it if it's new
717 }
718 return true;
719 }
720
setDynamicColor(int dyncol)721 void BzMaterial::setDynamicColor(int dyncol)
722 {
723 dynamicColor = dyncol;
724 return;
725 }
726
setAmbient(const float color[4])727 void BzMaterial::setAmbient(const float color[4])
728 {
729 memcpy (ambient, color, sizeof(float[4]));
730 return;
731 }
732
setDiffuse(const float color[4])733 void BzMaterial::setDiffuse(const float color[4])
734 {
735 memcpy (diffuse, color, sizeof(float[4]));
736 return;
737 }
738
setSpecular(const float color[4])739 void BzMaterial::setSpecular(const float color[4])
740 {
741 memcpy (specular, color, sizeof(float[4]));
742 return;
743 }
744
setEmission(const float color[4])745 void BzMaterial::setEmission(const float color[4])
746 {
747 memcpy (emission, color, sizeof(float[4]));
748 return;
749 }
750
setShininess(const float shine)751 void BzMaterial::setShininess(const float shine)
752 {
753 shininess = shine;
754 return;
755 }
756
setAlphaThreshold(const float thresh)757 void BzMaterial::setAlphaThreshold(const float thresh)
758 {
759 alphaThreshold = thresh;
760 return;
761 }
762
setOccluder(bool value)763 void BzMaterial::setOccluder(bool value)
764 {
765 occluder = value;
766 return;
767 }
768
setGroupAlpha(bool value)769 void BzMaterial::setGroupAlpha(bool value)
770 {
771 groupAlpha = value;
772 return;
773 }
774
setNoRadar(bool value)775 void BzMaterial::setNoRadar(bool value)
776 {
777 noRadar = value;
778 return;
779 }
780
setNoShadow(bool value)781 void BzMaterial::setNoShadow(bool value)
782 {
783 noShadow = value;
784 return;
785 }
786
setNoCulling(bool value)787 void BzMaterial::setNoCulling(bool value)
788 {
789 noCulling = value;
790 return;
791 }
792
setNoSorting(bool value)793 void BzMaterial::setNoSorting(bool value)
794 {
795 noSorting = value;
796 return;
797 }
798
setNoLighting(bool value)799 void BzMaterial::setNoLighting(bool value)
800 {
801 noLighting = value;
802 return;
803 }
804
805
addTexture(const std::string & texname)806 void BzMaterial::addTexture(const std::string& texname)
807 {
808 textureCount++;
809 TextureInfo* tmpinfo = new TextureInfo[textureCount];
810 for (int i = 0; i < (textureCount - 1); i++)
811 tmpinfo[i] = textures[i];
812 delete[] textures;
813 textures = tmpinfo;
814
815 TextureInfo* texinfo = &textures[textureCount - 1];
816 texinfo->name = texname;
817 texinfo->localname = texname;
818 texinfo->matrix = -1;
819 texinfo->combineMode = decal;
820 texinfo->useAlpha = true;
821 texinfo->useColor = true;
822 texinfo->useSphereMap = false;
823
824 return;
825 }
826
setTexture(const std::string & texname)827 void BzMaterial::setTexture(const std::string& texname)
828 {
829 if (textureCount <= 0)
830 addTexture(texname);
831 else
832 textures[textureCount - 1].name = texname;
833
834 return;
835 }
836
setTextureLocal(int texid,const std::string & localname)837 void BzMaterial::setTextureLocal(int texid, const std::string& localname)
838 {
839 if ((texid >= 0) && (texid < textureCount))
840 textures[texid].localname = localname;
841 return;
842 }
843
setTextureMatrix(int matrix)844 void BzMaterial::setTextureMatrix(int matrix)
845 {
846 if (textureCount > 0)
847 textures[textureCount - 1].matrix = matrix;
848 return;
849 }
850
setCombineMode(int mode)851 void BzMaterial::setCombineMode(int mode)
852 {
853 if (textureCount > 0)
854 textures[textureCount - 1].combineMode = mode;
855 return;
856 }
857
setUseTextureAlpha(bool value)858 void BzMaterial::setUseTextureAlpha(bool value)
859 {
860 if (textureCount > 0)
861 textures[textureCount - 1].useAlpha = value;
862 return;
863 }
864
setUseColorOnTexture(bool value)865 void BzMaterial::setUseColorOnTexture(bool value)
866 {
867 if (textureCount > 0)
868 textures[textureCount - 1].useColor = value;
869 return;
870 }
871
setUseSphereMap(bool value)872 void BzMaterial::setUseSphereMap(bool value)
873 {
874 if (textureCount > 0)
875 textures[textureCount - 1].useSphereMap = value;
876 return;
877 }
878
879
clearTextures()880 void BzMaterial::clearTextures()
881 {
882 delete[] textures;
883 textures = NULL;
884 textureCount = 0;
885 return;
886 }
887
888
setShader(const std::string & shadername)889 void BzMaterial::setShader(const std::string& shadername)
890 {
891 if (shaderCount <= 0)
892 addShader(shadername);
893 else
894 shaders[shaderCount - 1].name = shadername;
895
896 return;
897 }
898
addShader(const std::string & shaderName)899 void BzMaterial::addShader(const std::string& shaderName)
900 {
901 shaderCount++;
902 ShaderInfo* tmpinfo = new ShaderInfo[shaderCount];
903 for (int i = 0; i < (shaderCount - 1); i++)
904 tmpinfo[i] = shaders[i];
905 delete[] shaders;
906 shaders = tmpinfo;
907 shaders[shaderCount - 1].name = shaderName;
908 return;
909 }
910
911
clearShaders()912 void BzMaterial::clearShaders()
913 {
914 delete[] shaders;
915 shaders = NULL;
916 shaderCount = 0;
917 return;
918 }
919
920
921 /****************************************************************************/
922 //
923 // Parameter retrieval
924 //
925
getName() const926 const std::string& BzMaterial::getName() const
927 {
928 return name;
929 }
930
getAliases() const931 const std::vector<std::string>& BzMaterial::getAliases() const
932 {
933 return aliases;
934 }
935
getDynamicColor() const936 int BzMaterial::getDynamicColor() const
937 {
938 return dynamicColor;
939 }
940
getAmbient() const941 const float* BzMaterial::getAmbient() const
942 {
943 return ambient;
944 }
945
getDiffuse() const946 const float* BzMaterial::getDiffuse() const
947 {
948 return diffuse;
949 }
950
getSpecular() const951 const float* BzMaterial::getSpecular() const
952 {
953 return specular;
954 }
955
getEmission() const956 const float* BzMaterial::getEmission() const
957 {
958 return emission;
959 }
960
getShininess() const961 float BzMaterial::getShininess() const
962 {
963 return shininess;
964 }
965
getAlphaThreshold() const966 float BzMaterial::getAlphaThreshold() const
967 {
968 return alphaThreshold;
969 }
970
getOccluder() const971 bool BzMaterial::getOccluder() const
972 {
973 return occluder;
974 }
975
getGroupAlpha() const976 bool BzMaterial::getGroupAlpha() const
977 {
978 return groupAlpha;
979 }
980
getNoRadar() const981 bool BzMaterial::getNoRadar() const
982 {
983 return noRadar;
984 }
985
getNoShadow() const986 bool BzMaterial::getNoShadow() const
987 {
988 return noShadow;
989 }
990
getNoCulling() const991 bool BzMaterial::getNoCulling() const
992 {
993 return noCulling;
994 }
995
getNoSorting() const996 bool BzMaterial::getNoSorting() const
997 {
998 return noSorting;
999 }
1000
getNoLighting() const1001 bool BzMaterial::getNoLighting() const
1002 {
1003 return noLighting;
1004 }
1005
1006
getTextureCount() const1007 int BzMaterial::getTextureCount() const
1008 {
1009 return textureCount;
1010 }
1011
getTexture(int texid) const1012 const std::string& BzMaterial::getTexture(int texid) const
1013 {
1014 if ((texid >= 0) && (texid < textureCount))
1015 return textures[texid].name;
1016 else
1017 return nullString;
1018 }
1019
getTextureLocal(int texid) const1020 const std::string& BzMaterial::getTextureLocal(int texid) const
1021 {
1022 if ((texid >= 0) && (texid < textureCount))
1023 return textures[texid].localname;
1024 else
1025 return nullString;
1026 }
1027
getTextureMatrix(int texid) const1028 int BzMaterial::getTextureMatrix(int texid) const
1029 {
1030 if ((texid >= 0) && (texid < textureCount))
1031 return textures[texid].matrix;
1032 else
1033 return -1;
1034 }
1035
getCombineMode(int texid) const1036 int BzMaterial::getCombineMode(int texid) const
1037 {
1038 if ((texid >= 0) && (texid < textureCount))
1039 return textures[texid].combineMode;
1040 else
1041 return -1;
1042 }
1043
getUseTextureAlpha(int texid) const1044 bool BzMaterial::getUseTextureAlpha(int texid) const
1045 {
1046 if ((texid >= 0) && (texid < textureCount))
1047 return textures[texid].useAlpha;
1048 else
1049 return false;
1050 }
1051
getUseColorOnTexture(int texid) const1052 bool BzMaterial::getUseColorOnTexture(int texid) const
1053 {
1054 if ((texid >= 0) && (texid < textureCount))
1055 return textures[texid].useColor;
1056 else
1057 return false;
1058 }
1059
getUseSphereMap(int texid) const1060 bool BzMaterial::getUseSphereMap(int texid) const
1061 {
1062 if ((texid >= 0) && (texid < textureCount))
1063 return textures[texid].useSphereMap;
1064 else
1065 return false;
1066 }
1067
1068
getShaderCount() const1069 int BzMaterial::getShaderCount() const
1070 {
1071 return shaderCount;
1072 }
1073
getShader(int shdid) const1074 const std::string& BzMaterial::getShader(int shdid) const
1075 {
1076 if ((shdid >= 0) && (shdid < shaderCount))
1077 return shaders[shdid].name;
1078 else
1079 return nullString;
1080 }
1081
1082
isInvisible() const1083 bool BzMaterial::isInvisible() const
1084 {
1085 const DynamicColor* dyncol = DYNCOLORMGR.getColor(dynamicColor);
1086 if ((diffuse[3] == 0.0f) && (dyncol == NULL) &&
1087 !((textureCount > 0) && !textures[0].useColor))
1088 return true;
1089 return false;
1090 }
1091
1092
1093 // Local Variables: ***
1094 // mode: C++ ***
1095 // tab-width: 4 ***
1096 // c-basic-offset: 4 ***
1097 // indent-tabs-mode: nil ***
1098 // End: ***
1099 // ex: shiftwidth=4 tabstop=4
1100