Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: made include more local. stdincl.h not in base_object.h anymore

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