Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/graphics/importer/material.cc @ 9718

Last change on this file since 9718 was 9718, checked in by bensch, 18 years ago

more thoughts on Resources, and soon going to adapt… i think i've got a clue :)

File size: 14.4 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14
15*/
16
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
18
19#include "material.h"
20
21#include "texture.h"
22#include "debug.h"
23#include "compiler.h"
24
25#include "loading/load_param.h"
26
27#include "util/loading/resource_manager.h"
28
29ObjectListDefinition(Material);
30
31/**
32 * @brief creates a Material.
33 * @param mtlName Name of the Material to be added to the Material List
34 */
35Material::Material (const std::string& mtlName)
36{
37  this->registerObject(this, Material::_objectList);
38
39  this->setIllum(3);
40  this->setDiffuse(1,1,1);
41  this->setAmbient(0,0,0);
42  this->setSpecular(.5,.5,.5);
43  this->setShininess(2.0);
44  this->setTransparency(1.0);
45
46  this->ambientTexture = NULL;
47  this->specularTexture = NULL;
48  this->sFactor = GL_SRC_ALPHA;
49  this->tFactor = GL_ONE;
50
51  this->setName(mtlName);
52}
53
54Material& Material::operator=(const Material& material)
55{
56  this->illumModel = material.illumModel;
57  this->diffuse = material.diffuse;
58  this->specular = material.specular;
59  this->ambient = material.ambient;
60  this->shininess = material.shininess;
61
62  this->textures = material.textures;
63  this->sFactor = material.sFactor;
64  this->tFactor = material.tFactor;
65  this->setName(material.getName());
66
67  return *this;
68}
69
70
71
72void Material::loadParams(const TiXmlElement* root)
73{
74  LoadParam(root, "illum", this, Material, setIllum);
75
76  LoadParam(root, "diffuse-color", this, Material , setDiffuse);
77  LoadParam(root, "ambient-color", this, Material , setAmbient);
78  LoadParam(root, "specular-color", this, Material , setSpecular);
79  LoadParam(root, "transparency", this, Material , setTransparency);
80
81  LoadParam(root, "tex", this, Material, setDiffuseMap);
82  LoadParam(root, "blendfunc", this, Material, setBlendFuncS)
83      .defaultValues("ZERO", "ZERO");
84}
85
86
87/**
88 * @brief deletes a Material
89 */
90Material::~Material()
91{
92  PRINTF(5)("delete Material %s.\n", this->getCName());
93
94  if (this->ambientTexture != NULL)
95    ResourceManager::getInstance()->unload(this->ambientTexture);
96  if (this->specularTexture != NULL)
97    ResourceManager::getInstance()->unload(this->specularTexture);
98
99  if (this == Material::selectedMaterial)
100    Material::selectedMaterial = NULL;
101}
102
103
104const Material* Material::selectedMaterial = NULL;
105
106
107/// TODO FIX THIS
108// Material& Material::operator=(const Material& m)
109// {
110//   this->setIllum(m.illumModel);
111//   this->setDiffuse(m.diffuse[0],m.diffuse[1],m.diffuse[2]);
112//   this->setAmbient(m.ambient[0],m.ambient[1],m.ambient[2]);
113//   this->setSpecular(m.specular[0],m.specular[1],m.specular[2]);
114//   this->setShininess(m.shininess);
115//   this->setTransparency(m.transparency);
116//
117//   if (this->diffuseTexture != NULL)
118//     ResourceManager::getInstance()->unload(this->diffuseTexture);
119//   if (m.diffuseTexture != NULL)
120//     this->diffuseTexture = (Texture*)ResourceManager::getInstance()->copy(m.diffuseTexture);
121//   this->ambientTexture = NULL; /// FIXME
122//   this->specularTexture = NULL; /// FIXME
123//
124//   this->setName(m.getName());
125// }
126
127
128
129/**
130 * @brief sets the material with which the following Faces will be painted
131 */
132bool Material::select() const
133{
134  if (unlikely(this == Material::selectedMaterial))
135    return true;
136
137  /// !!  HACK !!! FIX THIS IN MODEL ///
138  else if (likely(Material::selectedMaterial != NULL))
139  {
140    Material::unselect();
141    //     for(unsigned int i = 0; i < Material::selectedMaterial->textures.size(); ++i)
142    //     {
143    //         glActiveTexture(Material::glTextureArbs[i]);
144    //         glBindTexture(GL_TEXTURE_2D, 0);
145    //         glDisable(GL_TEXTURE_2D);
146    //     }
147  }
148
149  if (likely(Material::selectedMaterial != NULL))
150  {
151    for(unsigned int i = 0; i < Material::selectedMaterial->textures.size(); ++i)
152    {
153      glActiveTexture(Material::glTextureArbs[i]);
154      //glBindTexture(GL_TEXTURE_2D, 0);
155      glDisable(GL_TEXTURE_2D);
156    }
157  }
158
159  // setting diffuse color
160  glColor4f (diffuse.r(), diffuse.g(), diffuse.b(), diffuse.a());
161  // setting ambient color
162  glMaterialfv(GL_FRONT, GL_AMBIENT, &this->ambient[0]);
163  // setting up Sprecular
164  glMaterialfv(GL_FRONT, GL_SPECULAR, &this->specular[0]);
165  // setting up Shininess
166  glMaterialf(GL_FRONT, GL_SHININESS, this->shininess);
167
168  // setting the transparency
169  if (this->diffuse.a() < 1.0 ||       /* This allows alpha blending of 2D textures with the scene */
170      (likely(!this->textures.empty() && this->textures[0].hasAlpha())))
171  {
172    glEnable(GL_BLEND);
173    glBlendFunc(this->sFactor, this->tFactor);
174  }
175  else
176  {
177    glDisable(GL_BLEND);
178  }
179
180
181  // setting illumination Model
182  if (this->illumModel == 1) //! @todo make this work, if no vertex-normals are read.
183    glShadeModel(GL_FLAT);
184  else if (this->illumModel >= 2)
185    glShadeModel(GL_SMOOTH);
186
187  for(unsigned int i = 0; i < this->textures.size(); ++i)
188  {
189    glActiveTexture(Material::glTextureArbs[i]);
190    glEnable(GL_TEXTURE_2D);
191    if(this->textures[i].hasAlpha())
192    {
193      glEnable(GL_BLEND);
194    }
195    glBindTexture(GL_TEXTURE_2D, this->textures[i].getTexture());
196  }
197  Material::selectedMaterial = this;
198
199  return true;
200}
201/**
202 * @brief Deselect Material (if one is selected).
203 */
204void Material::unselect()
205{
206  Material::selectedMaterial = NULL;
207  for(unsigned int i = 0; i < 8; ++i)
208  {
209    glActiveTexture(Material::glTextureArbs[i]);
210    glBindTexture(GL_TEXTURE_2D, 0);
211    glDisable(GL_TEXTURE_2D);
212  }
213}
214
215/**
216 * @brief Sets the Material Illumination Model.
217 * @param illu illumination Model in int form
218 */
219void Material::setIllum (int illum)
220{
221  PRINTF(4)("setting illumModel of Material %s to %i\n", this->getCName(), illum);
222  this->illumModel = illum;
223}
224
225/**
226 * @brief Sets the Material Diffuse Color.
227 * @param r Red Color Channel.a
228 * @param g Green Color Channel.
229 * @param b Blue Color Channel.
230 */
231void Material::setDiffuse (float r, float g, float b)
232{
233  PRINTF(4)("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", this->getCName(), r, g, b);
234  this->diffuse = Color(r, g, b, this->diffuse.a() );
235}
236
237
238/**
239 * @brief Sets the Material Ambient Color.
240 * @param r Red Color Channel.
241 * @param g Green Color Channel.
242 * @param b Blue Color Channel.
243*/
244void Material::setAmbient (float r, float g, float b)
245{
246  PRINTF(4)("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", this->getCName(), r, g, b);
247  this->ambient = Color(r, g, b, 1.0);
248}
249
250/**
251 * @brief Sets the Material Specular Color.
252 * @param r Red Color Channel.
253 * @param g Green Color Channel.
254 * @param b Blue Color Channel.
255 */
256void Material::setSpecular (float r, float g, float b)
257{
258  PRINTF(4)("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", this->getCName(), r, g, b);
259  this->specular = Color (r, g, b, 1.0);
260}
261
262/**
263 * @brief Sets the Material Shininess.
264 * @param shini stes the Shininess from float.
265*/
266void Material::setShininess (float shini)
267{
268  this->shininess = shini;
269}
270
271/**
272 * @brief Sets the Material Transparency.
273 * @param trans stes the Transparency from int.
274*/
275void Material::setTransparency (float trans)
276{
277  PRINTF(4)("setting Transparency of Material %s to %f.\n", this->getCName(), trans);
278  this->diffuse.a() = trans;
279}
280
281/**
282 * @brief sets the Blend-Function Parameters
283 * @param sFactor the Source Parameter.
284 * @param tFactor the Desitnation Parameter.
285 */
286void Material::setBlendFuncS(const std::string& sFactor, const std::string& tFactor)
287{
288  this->setBlendFunc(Material::stringToBlendFunc(sFactor), Material::stringToBlendFunc(tFactor));
289}
290
291
292
293/**
294 * @brief Adds a Texture Path to the List of already existing Paths
295 * @param pathName The Path to add.
296*/
297void Material::addTexturePath(const std::string& pathName)
298{
299  ResourceManager::getInstance()->addImageDir(pathName);
300}
301
302// MAPPING //
303
304
305/**
306 * @brief Sets the Diffuse map of this Texture.
307 * @param texture The Texture to load
308 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS
309 */
310void Material::setDiffuseMap(const Texture& texture, unsigned int textureNumber)
311{
312  assert(textureNumber < Material::getMaxTextureUnits());
313
314  if (this->textures.size() <= textureNumber)
315    this->textures.resize(textureNumber+1, Texture());
316
317  //! @todo check if RESOURCE MANAGER is availiable
318  this->textures[textureNumber] = texture;
319}
320
321/**
322 * @brief Sets the Diffuse map of this Texture by a Texture-pointer.
323 * @param textureDataPointer The Texture-Data-Pointer to load.
324 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS
325 */
326void Material::setDiffuseMap(const TextureData::Pointer& textureDataPointer, unsigned int textureNumber)
327{
328  assert(textureNumber < Material::getMaxTextureUnits());
329
330  if (this->textures.size() <= textureNumber)
331    this->textures.resize(textureNumber+1, Texture());
332
333  this->textures[textureNumber] = textureDataPointer;
334}
335
336
337/**
338 * @brief Sets the Materials Diffuse Map
339 * @param dMap the Name of the Image to Use
340 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS
341 */
342void Material::setDiffuseMap(const std::string& dMap, GLenum target, unsigned int textureNumber)
343{
344  assert(textureNumber < Material::getMaxTextureUnits());
345
346  PRINTF(5)("setting Diffuse Map %s\n", dMap.c_str());
347  if (this->textures.size() <= textureNumber)
348    this->textures.resize(textureNumber+1, Texture());
349
350  //! @todo check if RESOURCE MANAGER is availiable
351  if (!dMap.empty())
352  {
353    Texture* tex = dynamic_cast<Texture*>(ResourceManager::getInstance()->load(dMap, IMAGE, RP_GAME, (int)target));
354    if (tex != NULL)
355      this->textures[textureNumber] = *tex;
356    else
357      this->textures[textureNumber] = Texture();
358  }
359  else
360  {
361    this->textures[textureNumber] = Texture();
362  }
363}
364
365/**
366 * @brief Sets the Materials Diffuse Map
367 * @param surface pointer to SDL_Surface which shall be used as texture.
368 * @param target the GL-Target to load the Surface to.
369 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS.
370 */
371void Material::setSDLDiffuseMap(SDL_Surface *surface, GLenum target, unsigned int textureNumber)
372{
373  assert(textureNumber < Material::getMaxTextureUnits());
374
375
376  if (this->textures.size() <= textureNumber)
377    this->textures.resize(textureNumber+1, Texture());
378
379  if(surface != NULL)
380  {
381    this->textures[textureNumber] = Texture(surface, GL_TEXTURE_2D);
382  }
383  else
384  {
385    this->textures[textureNumber] = Texture();
386  }
387
388}
389
390/**
391 * @brief Renders to a Texture.
392 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS.
393 * @param target The GL-Target.
394 * @param level the MipMap-Level to render to.
395 * @param xoffset The offset in the Source from the left.
396 * @param yoffset The offset in the Source from the top (or bottom).
397 * @param x The Offset in the Destination from the left.
398 * @param y The Offset in the Destination from the top (or bottom).
399 * @param width The width of the region to copy.
400 * @param height The height of the region to copy.
401 */
402void Material::renderToTexture(unsigned int textureNumber, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
403{
404  assert(textureNumber < Material::getMaxTextureUnits());
405  assert(textureNumber < this->textures.size());
406
407  // HACK
408  glActiveTexture(textureNumber);
409  glEnable(GL_TEXTURE_2D);
410  glBindTexture(GL_TEXTURE_2D, this->textures[textureNumber].getTexture());
411  glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
412
413}
414
415/**
416 * @brief Sets the Materials Ambient Map
417 * @todo implement this
418 */
419void Material::setAmbientMap(const std::string& aMap, GLenum target)
420{
421  /// FIXME SDL_Surface* ambientMap;
422
423}
424
425/**
426 * @brief Sets the Materials Specular Map
427 * @param sMap the Name of the Image to Use
428 * @todo implement this
429 */
430void Material::setSpecularMap(const std::string& sMap, GLenum target)
431{
432  /// FIXME SDL_Surface* specularMap;
433
434}
435
436/**
437 * @brief Sets the Materials Bumpiness
438 * @param bump the Name of the Image to Use
439 * @todo implemet this
440 */
441void Material::setBump(const std::string& bump)
442{}
443
444
445/**
446 * @returns the Maximim Texture Unit the users OpenGL-Implementation supports.
447 */
448unsigned int Material::getMaxTextureUnits()
449{
450  int maxTexUnits = 0;
451  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTexUnits);
452  return maxTexUnits;
453}
454
455
456
457void Material::debug() const
458{
459  PRINT(0)("Debug Material: %s\n", this->getCName());
460  PRINT(0)("illumModel: %d ; ShiniNess %f\n", this->illumModel, shininess);
461  PRINT(0)("diffuseColor: "); diffuse.debug();
462  PRINT(0)("ambientColor: "); ambient.debug();
463  PRINT(0)("diffuseColor: "); specular.debug();
464  PRINT(0)("Blending Properties: Source: %s, Destination: %s\n", blendFuncToString(sFactor).c_str(), blendFuncToString(tFactor).c_str());
465
466  PRINT(0)("Textures: %d loaded", textures.size());
467  if (!this->textures.empty())
468  {
469    PRINT(0)(" - ID's: ");
470    for (unsigned int i = 0; i < textures.size(); ++i)
471    {
472      PRINT(0)("%d ", textures[i].getTexture());
473    }
474  }
475  PRINT(0)("\n");
476}
477
478
479const GLenum Material::glTextureArbs[] =
480{
481  GL_TEXTURE0,
482  GL_TEXTURE1,
483  GL_TEXTURE2,
484  GL_TEXTURE3,
485  GL_TEXTURE4,
486  GL_TEXTURE5,
487  GL_TEXTURE6,
488  GL_TEXTURE7
489};
490
491
492/**
493 * @param blendFunc the Enumerator to convert to a String.
494 * @returns the matching String if found
495 */
496const std::string& Material::blendFuncToString(GLenum blendFunc)
497{
498  for (unsigned int i = 0; i < 9; ++i)
499    if (blendFunc == Material::glBlendFuncParams[i])
500      return Material::blendFuncNames[i];
501  PRINTF(2)("Supplied an Invalid Enumerator to blendfunc %d\n", blendFunc);
502  return Material::blendFuncNames[0];
503}
504
505/**
506 * @param blendFuncString the String to convert into a gl-enumeration
507 * @returns the matching GL-enumeration if found.
508 */
509GLenum Material::stringToBlendFunc(const std::string& blendFuncString)
510{
511  for (unsigned int i = 0; i < 9; ++i)
512    if (blendFuncString == Material::blendFuncNames[i])
513      return Material::glBlendFuncParams[i];
514  PRINTF(2)("BlendFunction %s not recognized using %s\n", blendFuncString.c_str(), Material::blendFuncNames[0].c_str());
515  return Material::glBlendFuncParams[0];
516}
517
518
519const GLenum Material::glBlendFuncParams[] =
520  {
521    GL_ZERO,
522    GL_ONE,
523    GL_DST_COLOR,
524    GL_ONE_MINUS_DST_COLOR,
525    GL_SRC_ALPHA,
526    GL_ONE_MINUS_SRC_ALPHA,
527    GL_DST_ALPHA,
528    GL_ONE_MINUS_DST_ALPHA,
529    GL_SRC_ALPHA_SATURATE
530  };
531
532const std::string Material::blendFuncNames[] =
533  {
534    "ZERO",
535    "ONE",
536    "DST_COLOR",
537    "ONE_MINUS_DST_COLOR",
538    "SRC_ALPHA",
539    "ONE_MINUS_SRC_ALPHA",
540    "DST_ALPHA",
541    "ONE_MINUS_DST_ALPHA",
542    "SRC_ALPHA_SATURATE"
543
544  };
Note: See TracBrowser for help on using the repository browser.