Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/gui/src/lib/graphics/importer/material.cc @ 8575

Last change on this file since 8575 was 8572, checked in by bensch, 19 years ago

gui: nicer looks of Material

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