Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: lights now register themselves at the LightManager, as it is with all other engines too

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