Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4566 was 4519, checked in by bensch, 19 years ago

orxonox/trunk: changed all getInstances into inline functions to save some (minor) time

File size: 13.2 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
26using namespace std;
27
28//! Definition of the Lights
29int lightsV[] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7};
30
31
32/**
33   \param lightNumber the Light Number to initiate
34*/
35Light::Light(int lightNumber)
36{
37  this->setClassID(CL_LIGHT, "Light");
38  char tmpName[7];
39  sprintf(tmpName, "Light%d", lightNumber);
40  this->setName(tmpName);
41
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}
52
53
54/**
55   \brief destroys a Light
56*/
57Light::~Light(void)
58{
59  glDisable(lightsV[this->lightNumber]);
60}
61
62
63/**
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
75  this->setAbsCoor(position);
76
77  glLightfv (lightsV[this->lightNumber], GL_POSITION, this->lightPosition);
78}
79
80
81/**
82   \brief Sets a Position of this Light.
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{
89  this->setPosition(Vector(x, y, z));
90}
91
92
93/**
94   \brief sets an emitting Diffuse color of this Light
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
106  glLightfv (lightsV[this->lightNumber], GL_DIFFUSE, this->diffuseColor);
107}
108
109
110/**
111   \brief sets an emitting Specular color of this Light
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
123  glLightfv (lightsV[this->lightNumber], GL_SPECULAR, this->specularColor);
124}
125
126
127/**
128   \brief Sets the AttenuationType of this Light Source
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
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
144
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
158
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
169
170/**
171   \returns the Position of the Light
172*/
173Vector Light::getPosition() const
174{
175  return Vector(this->lightPosition[0], this->lightPosition[1], this->lightPosition[2]);
176}
177
178
179/**
180   \brief draws this Light. Being a World-entity the possibility to do this lies at hand.
181*/ 
182void Light::draw()
183{
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]);
186  glLightfv(lightsV[this->lightNumber], GL_POSITION, pos);
187}
188
189
190/**
191   \brief Prints out some nice formated debug information about the Light
192*/
193void Light::debug(void) const
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/**
215   \brief standard constructor for a Light
216*/
217LightManager::LightManager () 
218{
219  this->setClassID(CL_LIGHT_MANAGER, "LightManager");
220
221  glEnable (GL_LIGHTING);
222  this->setAmbientColor(.3, .3, .3);
223  this->lights = new Light*[NUMBEROFLIGHTS];
224  for (int i = 0; i < NUMBEROFLIGHTS; i++)
225    lights[i] = NULL;
226  this->currentLight = NULL;
227}
228
229/**
230   \brief standard deconstructor
231   
232   first disables Lighting
233
234   then deletes the rest of the allocated memory
235   and in the end sets the singleton Reference to zero.
236*/
237LightManager::~LightManager () 
238{
239  glDisable(GL_LIGHTING);
240 
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);
244  delete lights;
245  LightManager::singletonRef = NULL;
246}
247
248
249/**
250   \brief singleton-Reference to the Light-class
251*/
252LightManager* LightManager::singletonRef = NULL;
253
254/**
255   \brief initializes a new Light with default values, and enables GL_LIGHTING
256*/
257void LightManager::initLight(int lightNumber)
258{
259  lights[lightNumber] = new Light(lightNumber);
260}
261
262
263/**
264   \brief Adds a new Light, by selecting the First free slot.
265
266   if no slot is free error
267*/
268int LightManager::addLight(void)
269{
270  for (int i = 0; i < NUMBEROFLIGHTS; i++)
271    if (!this->lights[i])
272      return addLight(i); 
273  PRINTF(1)("no more light slots availiable. All %d already taken\n", NUMBEROFLIGHTS);
274  return -1;
275}
276
277
278/**
279   \brief Adds a new Light
280   \param lightNumber The number of the light to add.
281
282   if the Number is not free: warn, automatically choose another slot.
283*/
284int LightManager::addLight(int lightNumber)
285{
286  if (this->lights[lightNumber])
287    {
288      PRINTF(2)("Lightslot %d is allready taken, trying another one\n", lightNumber);
289      return this->addLight();
290    }
291  this->initLight(lightNumber);
292  this->currentLight = this->lights[lightNumber];
293  return lightNumber;
294}
295
296
297/**
298   \brief select the light to work with
299   \param lightNumber the light to work with
300*/
301void LightManager::editLightNumber(int lightNumber)
302{
303  if (!this->currentLight)
304    { 
305      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
306      return;
307    }
308  this->currentLight = lights[lightNumber];
309}
310
311
312/**
313   \brief Delete the current Light
314*/
315void LightManager::deleteLight(void)
316{
317  if (!this->currentLight)
318    { 
319      PRINTF(1)("no Light defined yet. So you cannot delete any Light right now.\n");
320      return;
321    }
322
323  this->deleteLight(this->currentLight->getLightNumber());
324}
325
326
327/**
328   \brief delete light.
329   \param lightNumber the number of the light to delete
330*/
331void LightManager::deleteLight(int lightNumber)
332{
333  if (this->lights[lightNumber])
334    {
335      PRINTF(4)("deleting Light number %d\n", lightNumber);
336      delete this->lights[lightNumber];
337      this->lights[lightNumber] = NULL;
338    }
339}
340
341
342/**
343   \brief draws all the Lights in their appropriate position
344*/
345void LightManager::draw()
346{
347  glMatrixMode(GL_MODELVIEW);
348  glLoadIdentity();
349  PRINTF(4)("Drawing the Lights\n");
350  for (int i = 0; i < NUMBEROFLIGHTS; i++)
351    if (this->lights[i])
352      lights[i]->draw();
353}
354
355
356
357// set Attributes
358/**
359   \brief sets the ambient Color of the Scene
360   \param r red
361   \param g green
362   \param b blue
363*/
364void LightManager::setAmbientColor(GLfloat r, GLfloat g, GLfloat b)
365{
366  this->ambientColor[0] = r;
367  this->ambientColor[1] = g;
368  this->ambientColor[2] = b;
369  this->ambientColor[3] = 1.0;
370
371  glLightfv (GL_LIGHT0, GL_AMBIENT, this->ambientColor);
372}
373
374
375/**
376   \brief sets The Position of the currently selected Light
377   \param position the new Position
378*/
379void LightManager::setPosition(Vector position)
380{
381  this->currentLight->setPosition(position);
382}
383
384
385/**
386   \brief Sets a Position for the currently selected Light.
387   \param x the x-coordinate
388   \param y the y-coordinate
389   \param z the z-coordinate
390*/
391void LightManager::setPosition(GLfloat x, GLfloat y, GLfloat z)
392{
393  if (!this->currentLight)
394    { 
395      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
396      return;
397    }
398  this->currentLight->setPosition(x, y, z);
399}
400
401
402/**
403   \brief sets an emitting Diffuse color of the currently selected Light
404   \param r red
405   \param g green
406   \param b blue
407*/
408void LightManager::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
409{
410  if (!this->currentLight)
411    { 
412      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
413      return;
414    }
415  this->currentLight->setDiffuseColor(r,g,b);
416}
417
418
419/**
420   \brief sets an emitting Specular color of the currently selected Light
421   \param r red
422   \param g green
423   \param b blue
424*/
425void LightManager::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
426{
427  if (!this->currentLight)
428    { 
429      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
430      return;
431    }
432  this->currentLight->setSpecularColor(r, g, b);
433}
434
435
436/**
437   \brief Sets the AttenuationType of th currently selecte LightSource Light Source
438   \param constantAttenuation The Constant Attenuation of the Light
439   \param linearAttenuation The Linear Attenuation of the Light
440   \param quadraticAttenuation The Quadratic Attenuation of the Light
441*/
442void LightManager::setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation)
443{
444  if (!this->currentLight)
445    { 
446      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
447      return;
448    }
449  this->currentLight->setAttenuation(constantAttenuation, linearAttenuation, quadraticAttenuation);
450}
451
452
453/**
454   \brief stets the direction of the Spot Light.
455   \param direction The direction of the Spot Light.
456*/
457void LightManager::setSpotDirection(Vector direction)
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->setSpotDirection(direction);
465}
466
467
468/**
469   \brief sets the cutoff angle of the Light.
470   \param cutoff The cutoff angle.
471*/
472void LightManager::setSpotCutoff(GLfloat cutoff)
473{
474  if (!this->currentLight)
475    { 
476      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
477      return;
478    }
479  this->currentLight->setSpotCutoff(cutoff);
480}
481
482
483// get Attributes
484/**
485   \returns the Position of the Light
486*/
487Vector LightManager::getPosition(void) const
488{
489  if (!this->currentLight)
490    { 
491      PRINTF(2)("no Light defined yet\n");
492      return Vector(.0, .0, .0);
493    }
494  else
495    return this->currentLight->getPosition();
496}
497
498
499/**
500   \returns the Position of Light
501   \param lightNumber lightnumber
502*/
503Vector LightManager::getPosition(int lightNumber) const
504{
505  if (!this->lights[lightNumber])
506    {
507      PRINTF(2)("no Light defined yet\n");
508      return Vector(.0,.0,.0);
509    }
510  else
511    return this->lights[lightNumber]->getPosition();
512}
513
514
515/**
516   \returns a pointer to a Light
517   \param lightNumber The light to request the pointer from
518*/
519Light* LightManager::getLight(int lightNumber) const
520{
521  return this->lights[lightNumber];
522}
523
524
525/**
526   \brief outputs debug information about the Class and its lights
527*/
528void LightManager::debug(void) const
529{
530  PRINT(0)("=================================\n");
531  PRINT(0)("= DEBUG INFORMATION CLASS LIGHT =\n");
532  PRINT(0)("=================================\n");
533  PRINT(0)("Reference: %p\n", LightManager::singletonRef);
534  if (this->currentLight)
535    PRINT(0)("current Light Nr: %d\n", this->currentLight->getLightNumber());
536  PRINT(0)("Ambient Color: %f:%f:%f\n", this->ambientColor[0], this->ambientColor[0], this->ambientColor[0]);
537  PRINT(0)("=== Lights ===\n");
538  for (int i = 0; i < NUMBEROFLIGHTS; i++)
539    if (this->lights[i])
540      {
541        this->lights[i]->debug();
542      }
543  PRINT(0)("--------------------------------\n");
544}
Note: See TracBrowser for help on using the repository browser.