Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4090 was 3809, checked in by patrick, 20 years ago

orxonox/trunk: changing pnode interface to const arguments

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