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
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/**
256   \returns The Instance of the Lights
257*/
258LightManager* LightManager::getInstance(void)
259{
260  if (!singletonRef)
261    LightManager::singletonRef = new LightManager();
262  return singletonRef;
263}
264
265
266/**
267   \brief initializes a new Light with default values, and enables GL_LIGHTING
268*/
269void LightManager::initLight(int lightNumber)
270{
271  lights[lightNumber] = new Light(lightNumber);
272}
273
274
275/**
276   \brief Adds a new Light, by selecting the First free slot.
277
278   if no slot is free error
279*/
280int LightManager::addLight(void)
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
289
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*/
296int LightManager::addLight(int lightNumber)
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    }
303  this->initLight(lightNumber);
304  this->currentLight = this->lights[lightNumber];
305  return lightNumber;
306}
307
308
309/**
310   \brief select the light to work with
311   \param lightNumber the light to work with
312*/
313void LightManager::editLightNumber(int lightNumber)
314{
315  if (!this->currentLight)
316    { 
317      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
318      return;
319    }
320  this->currentLight = lights[lightNumber];
321}
322
323
324/**
325   \brief Delete the current Light
326*/
327void LightManager::deleteLight(void)
328{
329  if (!this->currentLight)
330    { 
331      PRINTF(1)("no Light defined yet. So you cannot delete any Light right now.\n");
332      return;
333    }
334
335  this->deleteLight(this->currentLight->getLightNumber());
336}
337
338
339/**
340   \brief delete light.
341   \param lightNumber the number of the light to delete
342*/
343void LightManager::deleteLight(int lightNumber)
344{
345  if (this->lights[lightNumber])
346    {
347      PRINTF(4)("deleting Light number %d\n", lightNumber);
348      delete this->lights[lightNumber];
349      this->lights[lightNumber] = NULL;
350    }
351}
352
353
354/**
355   \brief draws all the Lights in their appropriate position
356*/
357void LightManager::draw()
358{
359  glMatrixMode(GL_MODELVIEW);
360  glLoadIdentity();
361  PRINTF(4)("Drawing the Lights\n");
362  for (int i = 0; i < NUMBEROFLIGHTS; i++)
363    if (this->lights[i])
364      lights[i]->draw();
365}
366
367
368
369// set Attributes
370/**
371   \brief sets the ambient Color of the Scene
372   \param r red
373   \param g green
374   \param b blue
375*/
376void LightManager::setAmbientColor(GLfloat r, GLfloat g, GLfloat b)
377{
378  this->ambientColor[0] = r;
379  this->ambientColor[1] = g;
380  this->ambientColor[2] = b;
381  this->ambientColor[3] = 1.0;
382
383  glLightfv (GL_LIGHT0, GL_AMBIENT, this->ambientColor);
384}
385
386
387/**
388   \brief sets The Position of the currently selected Light
389   \param position the new Position
390*/
391void LightManager::setPosition(Vector position)
392{
393  this->currentLight->setPosition(position);
394}
395
396
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*/
403void LightManager::setPosition(GLfloat x, GLfloat y, GLfloat z)
404{
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    }
410  this->currentLight->setPosition(x, y, z);
411}
412
413
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*/
420void LightManager::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
421{
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    }
427  this->currentLight->setDiffuseColor(r,g,b);
428}
429
430
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*/
437void LightManager::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
438{
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    }
444  this->currentLight->setSpecularColor(r, g, b);
445}
446
447
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*/
454void LightManager::setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation)
455{
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    }
461  this->currentLight->setAttenuation(constantAttenuation, linearAttenuation, quadraticAttenuation);
462}
463
464
465/**
466   \brief stets the direction of the Spot Light.
467   \param direction The direction of the Spot Light.
468*/
469void LightManager::setSpotDirection(Vector direction)
470{
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    }
476  this->currentLight->setSpotDirection(direction);
477}
478
479
480/**
481   \brief sets the cutoff angle of the Light.
482   \param cutoff The cutoff angle.
483*/
484void LightManager::setSpotCutoff(GLfloat cutoff)
485{
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    }
491  this->currentLight->setSpotCutoff(cutoff);
492}
493
494
495// get Attributes
496/**
497   \returns the Position of the Light
498*/
499Vector LightManager::getPosition(void) const
500{
501  if (!this->currentLight)
502    { 
503      PRINTF(2)("no Light defined yet\n");
504      return Vector(.0, .0, .0);
505    }
506  else
507    return this->currentLight->getPosition();
508}
509
510
511/**
512   \returns the Position of Light
513   \param lightNumber lightnumber
514*/
515Vector LightManager::getPosition(int lightNumber) const
516{
517  if (!this->lights[lightNumber])
518    {
519      PRINTF(2)("no Light defined yet\n");
520      return Vector(.0,.0,.0);
521    }
522  else
523    return this->lights[lightNumber]->getPosition();
524}
525
526
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}
535
536
537/**
538   \brief outputs debug information about the Class and its lights
539*/
540void LightManager::debug(void) const
541{
542  PRINT(0)("=================================\n");
543  PRINT(0)("= DEBUG INFORMATION CLASS LIGHT =\n");
544  PRINT(0)("=================================\n");
545  PRINT(0)("Reference: %p\n", LightManager::singletonRef);
546  if (this->currentLight)
547    PRINT(0)("current Light Nr: %d\n", this->currentLight->getLightNumber());
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      {
553        this->lights[i]->debug();
554      }
555  PRINT(0)("--------------------------------\n");
556}
Note: See TracBrowser for help on using the repository browser.