Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/light.cc @ 4738

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

orxonox/trunk: cleanup, renice, and other stuff (doxygen-tags, loadparam)

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