Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/graphics/light.cc @ 9716

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

more renamings

File size: 9.6 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Benjamin Grauer
15   co-programmer: ...
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
19
20#include "light.h"
21
22#include "glincl.h"
23#include "vector.h"
24#include "parser/tinyxml/tinyxml.h"
25#include "util/loading/load_param.h"
26#include "util/loading/factory.h"
27#include "debug.h"
28
29#include "class_id_DEPRECATED.h"
30
31ObjectListDefinitionID(Light, CL_LIGHT);
32CREATE_FACTORY(Light);
33
34//! Definition of the Lights and their Names
35int lightsV[] =
36  {
37    GL_LIGHT0,
38    GL_LIGHT1,
39    GL_LIGHT2,
40    GL_LIGHT3,
41    GL_LIGHT4,
42    GL_LIGHT5,
43    GL_LIGHT6,
44    GL_LIGHT7
45  };
46
47/**
48 * @param root The XML-element to load the Light from
49
50  @todo what to do, if no Light-Slots are open anymore ???
51 */
52Light::Light(const TiXmlElement* root)
53{
54  PRINTF(4)("initializing Light number %d.\n", this->lightNumber);
55
56  this->registerObject(this, Light::_objectList);
57
58  this->lightNumber = LightManager::getInstance()->registerLight(this);
59
60  char tmpName[10];
61  sprintf(tmpName, "Light[%d]", this->lightNumber);
62  this->setName(tmpName);
63
64  // enable The light
65  glEnable(lightsV[this->lightNumber]); // postSpawn
66
67  // set values (defaults)
68  this->setDiffuseColor(1.0, 1.0, 1.0);
69  this->setSpecularColor(1.0, 1.0, 1.0);
70
71  if (root != NULL)
72    this->loadParams(root);
73}
74
75/**
76 *  destroys a Light
77*/
78Light::~Light()
79{
80  glDisable(lightsV[this->lightNumber]);
81
82  LightManager::getInstance()->unregisterLight(this);
83}
84
85/**
86 * @param root The XML-element to load the Light from
87 */
88void Light::loadParams(const TiXmlElement* root)
89{
90  PNode::loadParams(root);
91
92  LoadParam(root, "diffuse-color", this, Light, setDiffuseColor)
93  .describe("sets the diffuse color of the Light (red [0-1], green [0-1], blue [0-1])");
94
95  LoadParam(root, "specular-color", this, Light, setSpecularColor)
96  .describe("sets the specular color of the Light (red [0-1], green [0-1], blue [0-1])");
97
98  LoadParam(root, "attenuation", this, Light, setAttenuation)
99  .describe("sets the Attenuation of the LightSource (constant Factor, linear Factor, quadratic Factor).");
100
101  LoadParam(root, "spot-direction", this, Light, setSpotDirection)
102  .describe("sets the Direction of the Spot");
103
104  LoadParam(root, "spot-cutoff", this, Light, setSpotCutoff)
105  .describe("the cuttoff of the Spotlight");
106}
107
108/**
109 *  sets an emitting Diffuse color of this Light
110 * @param r red
111 * @param g green
112 * @param b blue
113*/
114void Light::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
115{
116  this->diffuseColor[0] = r;
117  this->diffuseColor[1] = g;
118  this->diffuseColor[2] = b;
119  this->diffuseColor[3] = 1.0;
120
121  glLightfv (lightsV[this->lightNumber], GL_DIFFUSE, this->diffuseColor);
122}
123
124/**
125 *  sets an emitting Specular color of this Light
126 * @param r red
127 * @param g green
128 * @param b blue
129*/
130void Light::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
131{
132  this->specularColor[0] = r;
133  this->specularColor[1] = g;
134  this->specularColor[2] = b;
135  this->specularColor[3] = 1.0;
136
137  glLightfv (lightsV[this->lightNumber], GL_SPECULAR, this->specularColor);
138}
139
140
141/**
142 *  Sets the AttenuationType of this Light Source
143 * @param constantAttenuation The Constant Attenuation of the Light
144 * @param linearAttenuation The Linear Attenuation of the Light
145 * @param quadraticAttenuation The Quadratic Attenuation of the Light
146*/
147void Light::setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation)
148{
149  this->constantAttenuation  = constantAttenuation;
150  this->linearAttenuation    = linearAttenuation;
151  this->quadraticAttenuation = quadraticAttenuation;
152
153  glLightf(lightsV[this->lightNumber], GL_CONSTANT_ATTENUATION,  constantAttenuation);
154  glLightf(lightsV[this->lightNumber], GL_LINEAR_ATTENUATION,    linearAttenuation);
155  glLightf(lightsV[this->lightNumber], GL_QUADRATIC_ATTENUATION, quadraticAttenuation);
156}
157
158
159/**
160 *  stets the direction of the Spot Light.
161 * @param direction The direction of the Spot Light.
162*/
163void Light::setSpotDirection(const Vector& direction)
164{
165  this->spotDirection[0] = direction.x;
166  this->spotDirection[1] = direction.y;
167  this->spotDirection[2] = direction.z;
168
169  glLightfv(lightsV[this->lightNumber], GL_SPOT_DIRECTION, this->spotDirection);
170}
171
172
173/**
174 *  sets the cutoff angle of the Light.
175 * @param cutoff The cutoff angle.
176*/
177void Light::setSpotCutoff(GLfloat cutoff)
178{
179  this->spotCutoff = cutoff;
180  glLightf(lightsV[this->lightNumber], GL_SPOT_CUTOFF, cutoff);
181}
182
183/**
184 *  draws this Light. Being a World-entity the possibility to do this lies at hand.
185*/
186void Light::draw() const
187{
188  float pos[4] = {this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z, 1.0};
189  PRINTF(4)("Drawing The Lights new Position at %f %f %f\n", pos[0], pos[1], pos[2]);
190  glLightfv(lightsV[this->lightNumber], GL_POSITION, pos);
191}
192
193
194/**
195 *  Prints out some nice formated debug information about the Light
196*/
197void Light::debug() const
198{
199  PRINT(0)(":: %d ::  -- reference %p\n", this->lightNumber, this);
200  PRINT(0)(" GL-state: ");
201  GLboolean param;
202  glGetBooleanv(lightsV[this->lightNumber], &param);
203  if (param)
204    PRINT(0)("ON\n");
205  else
206    PRINT(0)("OFF\n");
207
208  PRINT(0)(" DiffuseColor:  %f/%f/%f\n", this->diffuseColor[0], this->diffuseColor[1], this->diffuseColor[2]);
209  PRINT(0)(" SpecularColor: %f/%f/%f\n", this->specularColor[0], this->specularColor[1], this->specularColor[2]);
210  PRINT(0)(" Attenuation: constant=%f linear=%f quadratic=%f\n", this->constantAttenuation, this->linearAttenuation, this->quadraticAttenuation);
211}
212
213
214/******************
215** LIGHT-MANAGER **
216******************/
217ObjectListDefinition(LightManager);
218/**
219 *  standard constructor for a Light
220*/
221LightManager::LightManager ()
222{
223  this->registerObject(this, LightManager::_objectList);
224
225  glEnable (GL_LIGHTING);
226  glEnable ( GL_COLOR_MATERIAL ) ;
227  glColorMaterial ( GL_FRONT, GL_DIFFUSE ) ;
228
229  this->setAmbientColor(.3, .3, .3);
230  this->lights = new Light*[NUMBEROFLIGHTS];
231  for (int i = 0; i < NUMBEROFLIGHTS; i++)
232    lights[i] = NULL;
233  this->currentLight = NULL;
234}
235
236/**
237 *  standard deconstructor
238
239   first disables Lighting
240
241   then deletes the rest of the allocated memory
242   and in the end sets the singleton Reference to zero.
243*/
244LightManager::~LightManager ()
245{
246  glDisable(GL_COLOR_MATERIAL);
247  glDisable(GL_LIGHTING);
248  this->setAmbientColor(.0,.0,.0);
249
250  for (int i = 0; i < NUMBEROFLIGHTS; i++)
251    if (this->lights[i] != NULL)
252      delete lights[i];
253  delete[] lights;
254  LightManager::singletonRef = NULL;
255}
256
257/**
258 *  singleton-Reference to the Light-class
259*/
260LightManager* LightManager::singletonRef = NULL;
261
262/**
263* @param root the XML-element to load the LightManager's settings from
264 */
265void LightManager::loadParams(const TiXmlElement* root)
266{
267  LoadParamXML(root, "Lights", this, LightManager, loadLights)
268  .describe("an XML-Element to load lights from.");
269
270  LoadParam(root, "ambient-color", this, LightManager, setAmbientColor)
271  .describe("sets the ambient Color of the Environmental Light");
272}
273
274/**
275* @param root The XML-element to load Lights from
276 */
277void LightManager::loadLights(const TiXmlElement* root)
278{
279  const TiXmlElement* element = root->FirstChildElement();
280
281  while (element != NULL)
282  {
283    Factory::fabricate(element);
284
285    element = element->NextSiblingElement();
286  }
287}
288
289// set Attributes
290/**
291 *  sets the ambient Color of the Scene
292 * @param r red
293 * @param g green
294 * @param b blue
295*/
296void LightManager::setAmbientColor(GLfloat r, GLfloat g, GLfloat b)
297{
298  this->ambientColor[0] = r;
299  this->ambientColor[1] = g;
300  this->ambientColor[2] = b;
301  this->ambientColor[3] = 1.0;
302
303  glLightfv (GL_LIGHT0, GL_AMBIENT, this->ambientColor);
304}
305
306/**
307* @param light the Light to register to the LightManager
308
309  This is done explicitely by the constructor of a Light
310*/
311int LightManager::registerLight(Light* light)
312{
313  for (int i = 0; i < NUMBEROFLIGHTS; i++)
314    if (!this->lights[i])
315    {
316      this->lights[i]=light;
317      return i;
318    }
319  PRINTF(1)("no more light slots availiable. All %d already taken\n", NUMBEROFLIGHTS);
320  return -1;
321}
322
323/**
324* @param light The light to unregister from the LightManager
325
326  This is done every time a Light is destroyed explicitely by the Light-destructor
327 */
328void LightManager::unregisterLight(Light* light)
329{
330  for (int i = 0; i < NUMBEROFLIGHTS; i++)
331  {
332    if (this->lights[i] == light)
333    {
334      this->lights[i] = NULL;
335      return;
336    }
337  }
338  PRINTF(2)("Light %p could not be unloaded (this should not heappen\n)");
339  return;
340}
341
342
343Light* LightManager::getLight(int lightNumber) const
344{
345  if( lightNumber < NUMBEROFLIGHTS)
346    return this->lights[lightNumber];
347
348  return NULL;
349}
350
351/**
352 *  draws all the Lights in their appropriate position
353 */
354void LightManager::draw() const
355{
356  PRINTF(4)("Drawing the Lights\n");
357  for (int i = 0; i < NUMBEROFLIGHTS; i++)
358    if (this->lights[i] != NULL)
359      lights[i]->draw();
360}
361
362/**
363 *  outputs debug information about the Class and its lights
364*/
365void LightManager::debug() const
366{
367  PRINT(0)("=================================\n");
368  PRINT(0)("= DEBUG INFORMATION CLASS LIGHT =\n");
369  PRINT(0)("=================================\n");
370  PRINT(0)("Reference: %p\n", LightManager::singletonRef);
371  if (this->currentLight)
372    PRINT(0)("current Light Nr: %d\n", this->currentLight->getLightNumber());
373  PRINT(0)("Ambient Color: %f:%f:%f\n", this->ambientColor[0], this->ambientColor[0], this->ambientColor[0]);
374  PRINT(0)("=== Lights ===\n");
375  for (int i = 0; i < NUMBEROFLIGHTS; i++)
376    if (this->lights[i])
377    {
378      this->lights[i]->debug();
379    }
380  PRINT(0)("-----------------------------LM-\n");
381}
Note: See TracBrowser for help on using the repository browser.