Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/importer/material.cc @ 8774

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

merged the new Font-Implementation back here
merged with svn merge https://svn.orxonox.net/orxonox/branches/fontdata . -r8752:HEAD
no conflicts, naturally

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