Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: factory is now registered in Factory, not in Gameloader

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_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  this->setAmbientColor(.0,.0,.0);
241
242  for (int i = 0; i < NUMBEROFLIGHTS; i++)
243    if (this->lights[i])
244      delete lights[i];
245  delete lights;
246  LightManager::singletonRef = NULL;
247}
248
249/**
250   \brief singleton-Reference to the Light-class
251*/
252LightManager* LightManager::singletonRef = NULL;
253
254/**
255  \param root the XML-element to load the LightManager's settings from
256 */
257void LightManager::loadParams(const TiXmlElement* root)
258{
259  LoadParam<LightManager>(root, "Lights", this, &LightManager::loadLights)
260      .describe("an XML-Element to load lights from.");
261
262  LoadParam<LightManager>(root, "ambient-color", this, &LightManager::setAmbientColor)
263      .describe("sets the ambient Color of the Environmental Light");
264}
265
266/**
267  \param root The XML-element to load Lights from
268 */
269void LightManager::loadLights(const TiXmlElement* root)
270{
271  const TiXmlElement* element = root->FirstChildElement();
272
273  while (element != NULL)
274  {
275    Factory::getFirst()->fabricate(element);
276
277    element = element->NextSiblingElement();
278  }
279}
280
281// set Attributes
282/**
283   \brief sets the ambient Color of the Scene
284   \param r red
285   \param g green
286   \param b blue
287*/
288void LightManager::setAmbientColor(GLfloat r, GLfloat g, GLfloat b)
289{
290  this->ambientColor[0] = r;
291  this->ambientColor[1] = g;
292  this->ambientColor[2] = b;
293  this->ambientColor[3] = 1.0;
294
295  glLightfv (GL_LIGHT0, GL_AMBIENT, this->ambientColor);
296}
297
298/**
299  \param light the Light to register to the LightManager
300
301  This is done explicitely by the constructor of a Light
302*/
303int LightManager::registerLight(Light* light)
304{
305  for (int i = 0; i < NUMBEROFLIGHTS; i++)
306    if (!this->lights[i])
307  {
308    this->lights[i]=light;
309    return i;
310  }
311  PRINTF(1)("no more light slots availiable. All %d already taken\n", NUMBEROFLIGHTS);
312  return -1;
313}
314
315/**
316  \param light The light to unregister from the LightManager
317
318  This is done every time a Light is destroyed explicitely by the Light-destructor
319 */
320void LightManager::unregisterLight(Light* light)
321{
322  for (int i = 0; i < NUMBEROFLIGHTS; i++)
323  {
324    if (this->lights[i] == light)
325    {
326      this->lights[i] = NULL;
327      return;
328    }
329  }
330  PRINTF(2)("Light %p could not be unloaded (this should not heappen\n)");
331  return;
332}
333
334/**
335   \brief draws all the Lights in their appropriate position
336 */
337void LightManager::draw() const
338{
339  glMatrixMode(GL_MODELVIEW);
340  glLoadIdentity();
341  PRINTF(4)("Drawing the Lights\n");
342  for (int i = 0; i < NUMBEROFLIGHTS; i++)
343    if (this->lights[i])
344      lights[i]->draw();
345}
346
347/**
348   \brief outputs debug information about the Class and its lights
349*/
350void LightManager::debug(void) const
351{
352  PRINT(0)("=================================\n");
353  PRINT(0)("= DEBUG INFORMATION CLASS LIGHT =\n");
354  PRINT(0)("=================================\n");
355  PRINT(0)("Reference: %p\n", LightManager::singletonRef);
356  if (this->currentLight)
357    PRINT(0)("current Light Nr: %d\n", this->currentLight->getLightNumber());
358  PRINT(0)("Ambient Color: %f:%f:%f\n", this->ambientColor[0], this->ambientColor[0], this->ambientColor[0]);
359  PRINT(0)("=== Lights ===\n");
360  for (int i = 0; i < NUMBEROFLIGHTS; i++)
361    if (this->lights[i])
362      {
363        this->lights[i]->debug();
364      }
365  PRINT(0)("-----------------------------LM-\n");
366}
Note: See TracBrowser for help on using the repository browser.