Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: attenuation works, and the Light is now in lib/graphics

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