Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

adapted many classes to the new ClassID System, now comes the hard part… Scripting… then Network… wow this will be so bad :/

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.h"
30
31CREATE_FACTORY(Light, CL_LIGHT);
32NewObjectListDefinitionID(Light, CL_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******************/
217NewObjectListDefinition(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.