Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4471 was 4471, checked in by patrick, 19 years ago

orxonox/trunk: synchronisable class commented, light altered

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