Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4734 was 4734, checked in by bensch, 20 years ago

orxonox/trunk: light loadable

File size: 14.4 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/**
48   \param lightNumber the Light Number to initiate
49*/
50Light::Light(int lightNumber)
51{
52  this->init(lightNumber);
53}
54
55/**
56 * \param root The XML-element to load the Light from
57 */
58 Light::Light(const TiXmlElement* root)
59{
60  this->init(1);
61  this->loadParams(root);
62}
63
64/**
65   \brief destroys a Light
66*/
67Light::~Light(void)
68{
69  glDisable(lightsV[this->lightNumber]);
70}
71
72/**
73 * \brief initializes a Light
74 */
75void Light::init(int lightNumber)
76{
77  this->setClassID(CL_LIGHT, "Light");
78  char tmpName[10];
79  sprintf(tmpName, "Light[%d]", lightNumber);
80  this->setName(tmpName);
81
82  PRINTF(4)("initializing Light number %d.\n", lightNumber);
83  // enable The light
84  glEnable(lightsV[lightNumber]); // postSpawn
85
86  // set values (defaults)
87  this->lightNumber = lightNumber;
88  this->setPosition(0,0,0);
89  this->setDiffuseColor(1.0, 1.0, 1.0);
90  this->setSpecularColor(1.0, 1.0, 1.0);
91}
92
93/**
94 * \param root The XML-element to load the Light from
95 */
96void Light::loadParams(const TiXmlElement* root)
97{
98  static_cast<PNode*>(this)->loadParams(root);
99
100  LoadParam<Light>(root, "diffuse-color", this, &Light::setDiffuseColor)
101      .describe("sets the diffuse color of the Light (red [0-1], green [0-1], blue [0-1])");
102
103  LoadParam<Light>(root, "specular-color", this, &Light::setSpecularColor)
104      .describe("sets the specular color of the Light (red [0-1], green [0-1], blue [0-1])");
105
106  LoadParam<Light>(root, "spot-direction", this, &Light::setSpotDirection)
107      .describe("sets the Direction of the Spot");
108
109  LoadParam<Light>(root, "spot-cutoff", this, &Light::setSpotCutoff)
110      .describe("the cuttoff of the Spotlight");
111}
112
113/**
114   \brief Sets a Position for the Light.
115   \param position The new position of the Light.
116   \todo patrick: is it ok to set a Light Position even if it is derived from p_node??
117*/
118void Light::setPosition(const Vector& position)
119{
120  this->lightPosition[0] = position.x;
121  this->lightPosition[1] = position.y;
122  this->lightPosition[2] = position.z;
123  this->lightPosition[3] = 0.0;
124
125  this->setAbsCoor(position);
126
127  glLightfv (lightsV[this->lightNumber], GL_POSITION, this->lightPosition);
128}
129
130
131/**
132   \brief Sets a Position of this Light.
133   \param x the x-coordinate
134   \param y the y-coordinate
135   \param z the z-coordinate
136*/
137void Light::setPosition(GLfloat x, GLfloat y, GLfloat z)
138{
139  this->setPosition(Vector(x, y, z));
140}
141
142
143/**
144   \brief sets an emitting Diffuse color of this Light
145   \param r red
146   \param g green
147   \param b blue
148*/
149void Light::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
150{
151  this->diffuseColor[0] = r;
152  this->diffuseColor[1] = g;
153  this->diffuseColor[2] = b;
154  this->diffuseColor[3] = 1.0;
155
156  glLightfv (lightsV[this->lightNumber], GL_DIFFUSE, this->diffuseColor);
157}
158
159/**
160   \brief sets an emitting Specular color of this Light
161   \param r red
162   \param g green
163   \param b blue
164*/
165void Light::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
166{
167  this->specularColor[0] = r;
168  this->specularColor[1] = g;
169  this->specularColor[2] = b;
170  this->specularColor[3] = 1.0;
171
172  glLightfv (lightsV[this->lightNumber], GL_SPECULAR, this->specularColor);
173}
174
175
176/**
177   \brief Sets the AttenuationType of this Light Source
178   \param constantAttenuation The Constant Attenuation of the Light
179   \param linearAttenuation The Linear Attenuation of the Light
180   \param quadraticAttenuation The Quadratic Attenuation of the Light
181*/
182void Light::setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation)
183{
184  this->constantAttenuation  = constantAttenuation;
185  this->linearAttenuation    = linearAttenuation;
186  this->quadraticAttenuation = quadraticAttenuation;
187
188  glLightf(lightsV[this->lightNumber], GL_CONSTANT_ATTENUATION,  constantAttenuation);
189  glLightf(lightsV[this->lightNumber], GL_LINEAR_ATTENUATION,    linearAttenuation);
190  glLightf(lightsV[this->lightNumber], GL_QUADRATIC_ATTENUATION, quadraticAttenuation);
191}
192
193
194/**
195   \brief stets the direction of the Spot Light.
196   \param direction The direction of the Spot Light.
197*/
198void Light::setSpotDirection(const Vector& direction)
199{
200  this->spotDirection[0] = direction.x;
201  this->spotDirection[1] = direction.y;
202  this->spotDirection[2] = direction.z;
203
204  glLightfv(lightsV[this->lightNumber], GL_SPOT_DIRECTION, this->spotDirection);
205}
206
207
208/**
209   \brief sets the cutoff angle of the Light.
210   \param cutoff The cutoff angle.
211*/
212void Light::setSpotCutoff(GLfloat cutoff)
213{
214  this->spotCutoff = cutoff;
215  glLightf(lightsV[this->lightNumber], GL_SPOT_CUTOFF, cutoff);
216}
217
218
219/**
220   \returns the Position of the Light
221*/
222Vector Light::getPosition() const
223{
224  return Vector(this->lightPosition[0], this->lightPosition[1], this->lightPosition[2]);
225}
226
227
228/**
229   \brief draws this Light. Being a World-entity the possibility to do this lies at hand.
230*/
231void Light::draw()
232{
233  float pos[4] = {this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z, 1.0};
234  PRINTF(4)("Drawing The Lights new Position at %f %f %f\n", pos[0], pos[1], pos[2]);
235  glLightfv(lightsV[this->lightNumber], GL_POSITION, pos);
236}
237
238
239/**
240   \brief Prints out some nice formated debug information about the Light
241*/
242void Light::debug(void) const
243{
244  PRINT(0)(":: %d ::  -- reference %p\n", this->lightNumber, this);
245  PRINT(0)(" GL-state: ");
246  GLboolean param;
247  glGetBooleanv(lightsV[this->lightNumber], &param);
248  if (param)
249    PRINT(0)("ON\n");
250  else
251    PRINT(0)("OFF\n");
252
253  PRINT(0)(" Position:      %f/%f/%f\n", this->lightPosition[0], this->lightPosition[1], this->lightPosition[2]);
254  PRINT(0)(" DiffuseColor:  %f/%f/%f\n", this->diffuseColor[0], this->diffuseColor[1], this->diffuseColor[2]);
255  PRINT(0)(" SpecularColor: %f/%f/%f\n", this->specularColor[0], this->specularColor[1], this->specularColor[2]);
256  PRINT(0)(" Attenuation: constant=%f linear=%f quadratic=%f\n", this->constantAttenuation, this->linearAttenuation, this->quadraticAttenuation);
257}
258
259
260/******************
261** LIGHT-MANAGER **
262******************/
263/**
264   \brief standard constructor for a Light
265*/
266LightManager::LightManager ()
267{
268  this->setClassID(CL_LIGHT_MANAGER, "LightManager");
269
270  glEnable (GL_LIGHTING);
271  this->setAmbientColor(.3, .3, .3);
272  this->lights = new Light*[NUMBEROFLIGHTS];
273  for (int i = 0; i < NUMBEROFLIGHTS; i++)
274    lights[i] = NULL;
275  this->currentLight = NULL;
276}
277
278/**
279   \brief standard deconstructor
280
281   first disables Lighting
282
283   then deletes the rest of the allocated memory
284   and in the end sets the singleton Reference to zero.
285*/
286LightManager::~LightManager ()
287{
288  glDisable(GL_LIGHTING);
289
290  // this will be done either by worldEntity, or by pNode as each light is one of them
291  //  for (int i = 0; i < NUMBEROFLIGHTS; i++)
292  //    this->deleteLight(i);
293  delete lights;
294  LightManager::singletonRef = NULL;
295}
296
297
298/**
299   \brief singleton-Reference to the Light-class
300*/
301LightManager* LightManager::singletonRef = NULL;
302
303/**
304   \brief initializes a new Light with default values, and enables GL_LIGHTING
305*/
306void LightManager::initLight(int lightNumber)
307{
308  lights[lightNumber] = new Light(lightNumber);
309}
310
311
312/**
313   \brief Adds a new Light, by selecting the First free slot.
314
315   if no slot is free error
316*/
317int LightManager::addLight(void)
318{
319  for (int i = 0; i < NUMBEROFLIGHTS; i++)
320    if (!this->lights[i])
321      return addLight(i);
322  PRINTF(1)("no more light slots availiable. All %d already taken\n", NUMBEROFLIGHTS);
323  return -1;
324}
325
326
327/**
328   \brief Adds a new Light
329   \param lightNumber The number of the light to add.
330
331   if the Number is not free: warn, automatically choose another slot.
332*/
333int LightManager::addLight(int lightNumber)
334{
335  if (this->lights[lightNumber])
336    {
337      PRINTF(2)("Lightslot %d is allready taken, trying another one\n", lightNumber);
338      return this->addLight();
339    }
340  this->initLight(lightNumber);
341  this->currentLight = this->lights[lightNumber];
342  return lightNumber;
343}
344
345
346/**
347   \brief select the light to work with
348   \param lightNumber the light to work with
349*/
350void LightManager::editLightNumber(int lightNumber)
351{
352  if (!this->currentLight)
353    {
354      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
355      return;
356    }
357  this->currentLight = lights[lightNumber];
358}
359
360
361/**
362   \brief Delete the current Light
363*/
364void LightManager::deleteLight(void)
365{
366  if (!this->currentLight)
367    {
368      PRINTF(1)("no Light defined yet. So you cannot delete any Light right now.\n");
369      return;
370    }
371
372  this->deleteLight(this->currentLight->getLightNumber());
373}
374
375
376/**
377   \brief delete light.
378   \param lightNumber the number of the light to delete
379*/
380void LightManager::deleteLight(int lightNumber)
381{
382  if (this->lights[lightNumber])
383    {
384      PRINTF(4)("deleting Light number %d\n", lightNumber);
385      delete this->lights[lightNumber];
386      this->lights[lightNumber] = NULL;
387    }
388}
389
390
391/**
392   \brief draws all the Lights in their appropriate position
393*/
394void LightManager::draw()
395{
396  glMatrixMode(GL_MODELVIEW);
397  glLoadIdentity();
398  PRINTF(4)("Drawing the Lights\n");
399  for (int i = 0; i < NUMBEROFLIGHTS; i++)
400    if (this->lights[i])
401      lights[i]->draw();
402}
403
404
405
406// set Attributes
407/**
408   \brief sets the ambient Color of the Scene
409   \param r red
410   \param g green
411   \param b blue
412*/
413void LightManager::setAmbientColor(GLfloat r, GLfloat g, GLfloat b)
414{
415  this->ambientColor[0] = r;
416  this->ambientColor[1] = g;
417  this->ambientColor[2] = b;
418  this->ambientColor[3] = 1.0;
419
420  glLightfv (GL_LIGHT0, GL_AMBIENT, this->ambientColor);
421}
422
423
424/**
425   \brief sets The Position of the currently selected Light
426   \param position the new Position
427*/
428void LightManager::setPosition(Vector position)
429{
430  this->currentLight->setPosition(position);
431}
432
433
434/**
435   \brief Sets a Position for the currently selected Light.
436   \param x the x-coordinate
437   \param y the y-coordinate
438   \param z the z-coordinate
439*/
440void LightManager::setPosition(GLfloat x, GLfloat y, GLfloat z)
441{
442  if (!this->currentLight)
443    {
444      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
445      return;
446    }
447  this->currentLight->setPosition(x, y, z);
448}
449
450
451/**
452   \brief sets an emitting Diffuse color of the currently selected Light
453   \param r red
454   \param g green
455   \param b blue
456*/
457void LightManager::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
458{
459  if (!this->currentLight)
460    {
461      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
462      return;
463    }
464  this->currentLight->setDiffuseColor(r,g,b);
465}
466
467
468/**
469   \brief sets an emitting Specular color of the currently selected Light
470   \param r red
471   \param g green
472   \param b blue
473*/
474void LightManager::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
475{
476  if (!this->currentLight)
477    {
478      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
479      return;
480    }
481  this->currentLight->setSpecularColor(r, g, b);
482}
483
484
485/**
486   \brief Sets the AttenuationType of th currently selecte LightSource Light Source
487   \param constantAttenuation The Constant Attenuation of the Light
488   \param linearAttenuation The Linear Attenuation of the Light
489   \param quadraticAttenuation The Quadratic Attenuation of the Light
490*/
491void LightManager::setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation)
492{
493  if (!this->currentLight)
494    {
495      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
496      return;
497    }
498  this->currentLight->setAttenuation(constantAttenuation, linearAttenuation, quadraticAttenuation);
499}
500
501
502/**
503   \brief stets the direction of the Spot Light.
504   \param direction The direction of the Spot Light.
505*/
506void LightManager::setSpotDirection(Vector direction)
507{
508  if (!this->currentLight)
509    {
510      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
511      return;
512    }
513  this->currentLight->setSpotDirection(direction);
514}
515
516
517/**
518   \brief sets the cutoff angle of the Light.
519   \param cutoff The cutoff angle.
520*/
521void LightManager::setSpotCutoff(GLfloat cutoff)
522{
523  if (!this->currentLight)
524    {
525      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
526      return;
527    }
528  this->currentLight->setSpotCutoff(cutoff);
529}
530
531
532// get Attributes
533/**
534   \returns the Position of the Light
535*/
536Vector LightManager::getPosition(void) const
537{
538  if (!this->currentLight)
539    {
540      PRINTF(2)("no Light defined yet\n");
541      return Vector(.0, .0, .0);
542    }
543  else
544    return this->currentLight->getPosition();
545}
546
547
548/**
549   \returns the Position of Light
550   \param lightNumber lightnumber
551*/
552Vector LightManager::getPosition(int lightNumber) const
553{
554  if (!this->lights[lightNumber])
555    {
556      PRINTF(2)("no Light defined yet\n");
557      return Vector(.0,.0,.0);
558    }
559  else
560    return this->lights[lightNumber]->getPosition();
561}
562
563
564/**
565   \returns a pointer to a Light
566   \param lightNumber The light to request the pointer from
567*/
568Light* LightManager::getLight(int lightNumber) const
569{
570  return this->lights[lightNumber];
571}
572
573
574/**
575   \brief outputs debug information about the Class and its lights
576*/
577void LightManager::debug(void) const
578{
579  PRINT(0)("=================================\n");
580  PRINT(0)("= DEBUG INFORMATION CLASS LIGHT =\n");
581  PRINT(0)("=================================\n");
582  PRINT(0)("Reference: %p\n", LightManager::singletonRef);
583  if (this->currentLight)
584    PRINT(0)("current Light Nr: %d\n", this->currentLight->getLightNumber());
585  PRINT(0)("Ambient Color: %f:%f:%f\n", this->ambientColor[0], this->ambientColor[0], this->ambientColor[0]);
586  PRINT(0)("=== Lights ===\n");
587  for (int i = 0; i < NUMBEROFLIGHTS; i++)
588    if (this->lights[i])
589      {
590        this->lights[i]->debug();
591      }
592  PRINT(0)("--------------------------------\n");
593}
Note: See TracBrowser for help on using the repository browser.