Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/new_class_id: now it should also be possible, to cache the resources, by suppling a LoadString.
This is vital to loading Resources, when you only know the TypeName and a LoadString, but not the c++-type and the LoadParameters as is the case when loading over the internet.

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