Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the new_class_id branche back to the trunk.
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/new_class_id trunk -r9683:HEAD
no conflicts… puh..

File size: 13.3 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 "resource_texture.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 == Material::selectedMaterial)
95    Material::selectedMaterial = NULL;
96}
97
98
99const Material* Material::selectedMaterial = NULL;
100
101/**
102 * @brief sets the material with which the following Faces will be painted
103 */
104bool Material::select() const
105{
106  if (unlikely(this == Material::selectedMaterial))
107    return true;
108
109  /// !!  HACK !!! FIX THIS IN MODEL ///
110  else if (likely(Material::selectedMaterial != NULL))
111  {
112    Material::unselect();
113    //     for(unsigned int i = 0; i < Material::selectedMaterial->textures.size(); ++i)
114    //     {
115    //         glActiveTexture(Material::glTextureArbs[i]);
116    //         glBindTexture(GL_TEXTURE_2D, 0);
117    //         glDisable(GL_TEXTURE_2D);
118    //     }
119  }
120
121  if (likely(Material::selectedMaterial != NULL))
122  {
123    for(unsigned int i = 0; i < Material::selectedMaterial->textures.size(); ++i)
124    {
125      glActiveTexture(Material::glTextureArbs[i]);
126      //glBindTexture(GL_TEXTURE_2D, 0);
127      glDisable(GL_TEXTURE_2D);
128    }
129  }
130
131  // setting diffuse color
132  glColor4f (diffuse.r(), diffuse.g(), diffuse.b(), diffuse.a());
133  // setting ambient color
134  glMaterialfv(GL_FRONT, GL_AMBIENT, &this->ambient[0]);
135  // setting up Sprecular
136  glMaterialfv(GL_FRONT, GL_SPECULAR, &this->specular[0]);
137  // setting up Shininess
138  glMaterialf(GL_FRONT, GL_SHININESS, this->shininess);
139
140  // setting the transparency
141  if (this->diffuse.a() < 1.0 ||       /* This allows alpha blending of 2D textures with the scene */
142      (likely(!this->textures.empty() && this->textures[0].hasAlpha())))
143  {
144    glEnable(GL_BLEND);
145    glBlendFunc(this->sFactor, this->tFactor);
146  }
147  else
148  {
149    glDisable(GL_BLEND);
150  }
151
152
153  // setting illumination Model
154  if (this->illumModel == 1) //! @todo make this work, if no vertex-normals are read.
155    glShadeModel(GL_FLAT);
156  else if (this->illumModel >= 2)
157    glShadeModel(GL_SMOOTH);
158
159  for(unsigned int i = 0; i < this->textures.size(); ++i)
160  {
161    glActiveTexture(Material::glTextureArbs[i]);
162    glEnable(GL_TEXTURE_2D);
163    if(this->textures[i].hasAlpha())
164    {
165      glEnable(GL_BLEND);
166    }
167    glBindTexture(GL_TEXTURE_2D, this->textures[i].getTexture());
168  }
169  Material::selectedMaterial = this;
170
171  return true;
172}
173/**
174 * @brief Deselect Material (if one is selected).
175 */
176void Material::unselect()
177{
178  Material::selectedMaterial = NULL;
179  for(unsigned int i = 0; i < 8; ++i)
180  {
181    glActiveTexture(Material::glTextureArbs[i]);
182    glBindTexture(GL_TEXTURE_2D, 0);
183    glDisable(GL_TEXTURE_2D);
184  }
185}
186
187/**
188 * @brief Sets the Material Illumination Model.
189 * @param illu illumination Model in int form
190 */
191void Material::setIllum (int illum)
192{
193  PRINTF(4)("setting illumModel of Material %s to %i\n", this->getCName(), illum);
194  this->illumModel = illum;
195}
196
197/**
198 * @brief Sets the Material Diffuse Color.
199 * @param r Red Color Channel.a
200 * @param g Green Color Channel.
201 * @param b Blue Color Channel.
202 */
203void Material::setDiffuse (float r, float g, float b)
204{
205  PRINTF(4)("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", this->getCName(), r, g, b);
206  this->diffuse = Color(r, g, b, this->diffuse.a() );
207}
208
209
210/**
211 * @brief Sets the Material Ambient Color.
212 * @param r Red Color Channel.
213 * @param g Green Color Channel.
214 * @param b Blue Color Channel.
215*/
216void Material::setAmbient (float r, float g, float b)
217{
218  PRINTF(4)("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", this->getCName(), r, g, b);
219  this->ambient = Color(r, g, b, 1.0);
220}
221
222/**
223 * @brief Sets the Material Specular Color.
224 * @param r Red Color Channel.
225 * @param g Green Color Channel.
226 * @param b Blue Color Channel.
227 */
228void Material::setSpecular (float r, float g, float b)
229{
230  PRINTF(4)("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", this->getCName(), r, g, b);
231  this->specular = Color (r, g, b, 1.0);
232}
233
234/**
235 * @brief Sets the Material Shininess.
236 * @param shini stes the Shininess from float.
237*/
238void Material::setShininess (float shini)
239{
240  this->shininess = shini;
241}
242
243/**
244 * @brief Sets the Material Transparency.
245 * @param trans stes the Transparency from int.
246*/
247void Material::setTransparency (float trans)
248{
249  PRINTF(4)("setting Transparency of Material %s to %f.\n", this->getCName(), trans);
250  this->diffuse.a() = trans;
251}
252
253/**
254 * @brief sets the Blend-Function Parameters
255 * @param sFactor the Source Parameter.
256 * @param tFactor the Desitnation Parameter.
257 */
258void Material::setBlendFuncS(const std::string& sFactor, const std::string& tFactor)
259{
260  this->setBlendFunc(Material::stringToBlendFunc(sFactor), Material::stringToBlendFunc(tFactor));
261}
262
263
264/**
265 * @brief Sets the Diffuse map of this Texture.
266 * @param texture The Texture to load
267 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS
268 */
269void Material::setDiffuseMap(const Texture& texture, unsigned int textureNumber)
270{
271  assert(textureNumber < Material::getMaxTextureUnits());
272
273  if (this->textures.size() <= textureNumber)
274    this->textures.resize(textureNumber+1, Texture());
275
276  //! @todo check if RESOURCE MANAGER is availiable
277  this->textures[textureNumber] = texture;
278}
279
280/**
281 * @brief Sets the Diffuse map of this Texture by a Texture-pointer.
282 * @param textureDataPointer The Texture-Data-Pointer to load.
283 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS
284 */
285void Material::setDiffuseMap(const TextureData::Pointer& textureDataPointer, unsigned int textureNumber)
286{
287  assert(textureNumber < Material::getMaxTextureUnits());
288
289  if (this->textures.size() <= textureNumber)
290    this->textures.resize(textureNumber+1, Texture());
291
292  this->textures[textureNumber] = textureDataPointer;
293}
294
295
296/**
297 * @brief Sets the Materials Diffuse Map
298 * @param dMap the Name of the Image to Use
299 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS
300 */
301void Material::setDiffuseMap(const std::string& dMap, GLenum target, unsigned int textureNumber)
302{
303  assert(textureNumber < Material::getMaxTextureUnits());
304
305  PRINTF(5)("setting Diffuse Map %s\n", dMap.c_str());
306  if (this->textures.size() <= textureNumber)
307    this->textures.resize(textureNumber+1, Texture());
308
309  //! @todo check if RESOURCE MANAGER is availiable
310  if (!dMap.empty())
311  {
312    this->textures[textureNumber] = ResourceTexture(dMap);
313        //dynamic_cast<Texture*>(ResourceManager::getInstance()->load(dMap, IMAGE, RP_GAME, (int)target));
314/*    if (tex != NULL)
315      this->textures[textureNumber] = tex;
316    else
317      this->textures[textureNumber] = Texture();*/
318  }
319  else
320  {
321    this->textures[textureNumber] = Texture();
322  }
323}
324
325/**
326 * @brief Sets the Materials Diffuse Map
327 * @param surface pointer to SDL_Surface which shall be used as texture.
328 * @param target the GL-Target to load the Surface to.
329 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS.
330 */
331void Material::setSDLDiffuseMap(SDL_Surface *surface, GLenum target, unsigned int textureNumber)
332{
333  assert(textureNumber < Material::getMaxTextureUnits());
334
335
336  if (this->textures.size() <= textureNumber)
337    this->textures.resize(textureNumber+1, Texture());
338
339  if(surface != NULL)
340  {
341    this->textures[textureNumber] = Texture(surface, GL_TEXTURE_2D);
342  }
343  else
344  {
345    this->textures[textureNumber] = Texture();
346  }
347
348}
349
350/**
351 * @brief Renders to a Texture.
352 * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS.
353 * @param target The GL-Target.
354 * @param level the MipMap-Level to render to.
355 * @param xoffset The offset in the Source from the left.
356 * @param yoffset The offset in the Source from the top (or bottom).
357 * @param x The Offset in the Destination from the left.
358 * @param y The Offset in the Destination from the top (or bottom).
359 * @param width The width of the region to copy.
360 * @param height The height of the region to copy.
361 */
362void Material::renderToTexture(unsigned int textureNumber, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
363{
364  assert(textureNumber < Material::getMaxTextureUnits());
365  assert(textureNumber < this->textures.size());
366
367  // HACK
368  glActiveTexture(textureNumber);
369  glEnable(GL_TEXTURE_2D);
370  glBindTexture(GL_TEXTURE_2D, this->textures[textureNumber].getTexture());
371  glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
372
373}
374
375/**
376 * @brief Sets the Materials Ambient Map
377 * @todo implement this
378 */
379void Material::setAmbientMap(const std::string& aMap, GLenum target)
380{
381  /// FIXME SDL_Surface* ambientMap;
382
383}
384
385/**
386 * @brief Sets the Materials Specular Map
387 * @param sMap the Name of the Image to Use
388 * @todo implement this
389 */
390void Material::setSpecularMap(const std::string& sMap, GLenum target)
391{
392  /// FIXME SDL_Surface* specularMap;
393
394}
395
396/**
397 * @brief Sets the Materials Bumpiness
398 * @param bump the Name of the Image to Use
399 * @todo implemet this
400 */
401void Material::setBump(const std::string& bump)
402{}
403
404
405/**
406 * @returns the Maximim Texture Unit the users OpenGL-Implementation supports.
407 */
408unsigned int Material::getMaxTextureUnits()
409{
410  int maxTexUnits = 0;
411  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTexUnits);
412  return maxTexUnits;
413}
414
415
416
417void Material::debug() const
418{
419  PRINT(0)("Debug Material: %s\n", this->getCName());
420  PRINT(0)("illumModel: %d ; ShiniNess %f\n", this->illumModel, shininess);
421  PRINT(0)("diffuseColor: "); diffuse.debug();
422  PRINT(0)("ambientColor: "); ambient.debug();
423  PRINT(0)("diffuseColor: "); specular.debug();
424  PRINT(0)("Blending Properties: Source: %s, Destination: %s\n", blendFuncToString(sFactor).c_str(), blendFuncToString(tFactor).c_str());
425
426  PRINT(0)("Textures: %d loaded", textures.size());
427  if (!this->textures.empty())
428  {
429    PRINT(0)(" - ID's: ");
430    for (unsigned int i = 0; i < textures.size(); ++i)
431    {
432      PRINT(0)("%d ", textures[i].getTexture());
433    }
434  }
435  PRINT(0)("\n");
436}
437
438
439const GLenum Material::glTextureArbs[] =
440{
441  GL_TEXTURE0,
442  GL_TEXTURE1,
443  GL_TEXTURE2,
444  GL_TEXTURE3,
445  GL_TEXTURE4,
446  GL_TEXTURE5,
447  GL_TEXTURE6,
448  GL_TEXTURE7
449};
450
451
452/**
453 * @param blendFunc the Enumerator to convert to a String.
454 * @returns the matching String if found
455 */
456const std::string& Material::blendFuncToString(GLenum blendFunc)
457{
458  for (unsigned int i = 0; i < 9; ++i)
459    if (blendFunc == Material::glBlendFuncParams[i])
460      return Material::blendFuncNames[i];
461  PRINTF(2)("Supplied an Invalid Enumerator to blendfunc %d\n", blendFunc);
462  return Material::blendFuncNames[0];
463}
464
465/**
466 * @param blendFuncString the String to convert into a gl-enumeration
467 * @returns the matching GL-enumeration if found.
468 */
469GLenum Material::stringToBlendFunc(const std::string& blendFuncString)
470{
471  for (unsigned int i = 0; i < 9; ++i)
472    if (blendFuncString == Material::blendFuncNames[i])
473      return Material::glBlendFuncParams[i];
474  PRINTF(2)("BlendFunction %s not recognized using %s\n", blendFuncString.c_str(), Material::blendFuncNames[0].c_str());
475  return Material::glBlendFuncParams[0];
476}
477
478
479const GLenum Material::glBlendFuncParams[] =
480  {
481    GL_ZERO,
482    GL_ONE,
483    GL_DST_COLOR,
484    GL_ONE_MINUS_DST_COLOR,
485    GL_SRC_ALPHA,
486    GL_ONE_MINUS_SRC_ALPHA,
487    GL_DST_ALPHA,
488    GL_ONE_MINUS_DST_ALPHA,
489    GL_SRC_ALPHA_SATURATE
490  };
491
492const std::string Material::blendFuncNames[] =
493  {
494    "ZERO",
495    "ONE",
496    "DST_COLOR",
497    "ONE_MINUS_DST_COLOR",
498    "SRC_ALPHA",
499    "ONE_MINUS_SRC_ALPHA",
500    "DST_ALPHA",
501    "ONE_MINUS_DST_ALPHA",
502    "SRC_ALPHA_SATURATE"
503
504  };
Note: See TracBrowser for help on using the repository browser.