Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/light.cc @ 3543

Last change on this file since 3543 was 3543, checked in by bensch, 20 years ago

orxonox/trunk: some more classes now destroy themselves via virtual-destructors and call to predecessing destroy-function
also made
#include "stdincl.h" out of unnecessary h-files, so we got faster compile time.

File size: 9.9 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
19#include "light.h"
20
21#include "glincl.h"
22
23using namespace std;
24
25//! Definition of the Lights
26int lightsV[] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7};
27
28
29/**
30   \brief standard constructor for a Light
31*/
32Light::Light () 
33{
34  this->setClassName ("Light");
35
36  glEnable (GL_LIGHTING);
37  this->setAmbientColor(.3, .3, .3);
38  this->lights = new LightValue*[NUMBEROFLIGHTS];
39  for (int i = 0; i < NUMBEROFLIGHTS; i++)
40    lights[i] = NULL;
41  this->currentLight = NULL;
42}
43
44/**
45   \brief standard deconstructor
46   
47   first disables Lighting
48   then deletes all the lights
49   then deletes the rest of the allocated memory
50   and in the end sets the singleton Reference to zero.
51*/
52Light::~Light () 
53{
54  this->destroy();
55}
56
57
58/**
59   \brief frees all alocated memory
60
61   and in this case also deletes the lightSources and GL_LIGHTING
62*/
63void Light::destroy(void)
64{
65  glDisable(GL_LIGHTING);
66 
67  for (int i = 0; i < NUMBEROFLIGHTS; i++)
68    this->deleteLight(i);
69  delete lights;
70  Light::singletonRef = NULL;
71
72  static_cast<WorldEntity*>(this)->destroy();
73}
74
75
76/**
77   \brief singleton-Reference to the Light-class
78*/
79Light* Light::singletonRef = NULL;
80
81/**
82   \returns The Instance of the Lights
83*/
84Light* Light::getInstance(void)
85{
86  if (singletonRef)
87    return singletonRef;
88  else
89    return Light::singletonRef = new Light();
90}
91
92/**
93   \brief initializes a new Light with default values, and enables GL_LIGHTING
94*/
95void Light::init(int lightNumber)
96{
97  PRINTF(3)("initializing Light number %d.\n", lightNumber);
98  // enable The light
99  glEnable(lightsV[lightNumber]);
100  this->currentLight = lights[lightNumber] = new LightValue;
101 
102  // set default values
103  this->currentLight->lightNumber = lightNumber;
104  this->setPosition(0.0, 0.0, 0.0);
105  this->setDiffuseColor(1.0, 1.0, 1.0);
106  this->setSpecularColor(1.0, 1.0, 1.0);
107}
108
109/**
110   \brief Adds a new Light, by selecting the First free slot.
111
112   if no slot is free error
113*/
114int Light::addLight(void)
115{
116  for (int i = 0; i < NUMBEROFLIGHTS; i++)
117    if (!this->lights[i])
118      return addLight(i); 
119  PRINTF(1)("no more light slots availiable. All %d already taken\n", NUMBEROFLIGHTS);
120  return -1;
121}
122
123/**
124   \brief Adds a new Light
125   \param lightNumber The number of the light to add.
126
127   if the Number is not free: warn, automatically choose another slot.
128*/
129int Light::addLight(int lightNumber)
130{
131  if (this->lights[lightNumber])
132    {
133      PRINTF(2)("Lightslot %d is allready taken, trying another one\n", lightNumber);
134      return this->addLight();
135    }
136  this->init(lightNumber);
137  this->currentLight = this->lights[lightNumber];
138  return lightNumber;
139}
140
141/**
142   \brief select the light to work with
143   \param lightNumber the light to work with
144*/
145void Light::editLightNumber(int lightNumber)
146{
147  if (!this->currentLight)
148    { 
149      PRINTF(1)("no Light defined yet\n");
150      return;
151    }
152
153  this->currentLight = lights[lightNumber];
154}
155
156/**
157   \brief Delete the current Light
158*/
159void Light::deleteLight(void)
160{
161  if (!this->currentLight)
162    { 
163      PRINTF(1)("no Light defined yet\n");
164      return;
165    }
166
167  this->deleteLight(this->currentLight->lightNumber);
168}
169
170/**
171   \brief delete light.
172   \param lightNumber the number of the light to delete
173*/
174void Light::deleteLight(int lightNumber)
175{
176  if (this->lights[lightNumber])
177    {
178      PRINTF(3)("deleting Light number %d\n", lightNumber);
179      delete this->lights[lightNumber];
180      glDisable(lightsV[lightNumber]);
181      this->lights[lightNumber] = NULL;
182    }
183}
184
185// set Attributes
186/**
187   \brief Sets a Position for the Light.
188   \param position The new position of the Light.
189   \todo patrick: is it ok to set a Light Position even if it is derived from p_node??
190*/
191void Light::setPosition(Vector position)
192{
193  if (!this->currentLight)
194    { 
195      PRINTF(1)("no Light defined yet\n");
196      return;
197    }
198  this->currentLight->lightPosition[0] = position.x;
199  this->currentLight->lightPosition[1] = position.y;
200  this->currentLight->lightPosition[2] = position.z;
201  this->currentLight->lightPosition[3] = 0.0;
202
203  glLightfv (GL_LIGHT0, GL_POSITION, this->currentLight->lightPosition);
204}
205
206/**
207   \brief Sets a Position for the Light.
208   \param x the x-coordinate
209   \param y the y-coordinate
210   \param z the z-coordinate
211*/
212void Light::setPosition(GLfloat x, GLfloat y, GLfloat z)
213{
214  if (!this->currentLight)
215    { 
216      PRINTF(1)("no Light defined yet\n");
217      return;
218    }
219
220  this->currentLight->lightPosition[0] = x;
221  this->currentLight->lightPosition[1] = y;
222  this->currentLight->lightPosition[2] = z;
223  this->currentLight->lightPosition[3] = 0.0;
224
225  glLightfv (GL_LIGHT0, GL_POSITION, this->currentLight->lightPosition);
226}
227
228/**
229   \brief sets an emitting Diffuse color for the Light
230   \param r red
231   \param g green
232   \param b blue
233*/
234void Light::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
235{
236  if (!this->currentLight)
237    { 
238      PRINTF(1)("no Light defined yet\n");
239      return;
240    }
241
242  this->currentLight->diffuseColor[0] = r;
243  this->currentLight->diffuseColor[1] = g;
244  this->currentLight->diffuseColor[2] = b;
245  this->currentLight->diffuseColor[3] = 1.0;
246
247  glLightfv (GL_LIGHT0, GL_DIFFUSE, this->currentLight->diffuseColor);
248}
249
250
251/**
252   \brief sets an emitting Ambient color for the Light
253   \param r red
254   \param g green
255   \param b blue
256*/
257void Light::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
258{
259  if (!this->currentLight)
260    { 
261      PRINTF(1)("no Light defined yet\n");
262      return;
263    }
264
265  this->currentLight->specularColor[0] = r;
266  this->currentLight->specularColor[1] = g;
267  this->currentLight->specularColor[2] = b;
268  this->currentLight->specularColor[3] = 1.0;
269
270  glLightfv (GL_LIGHT0, GL_SPECULAR, this->currentLight->specularColor);
271}
272
273/**
274   \brief Sets the AttenuationType of this Light Source
275   \param type the AttenuationType to set
276   \param factor the Factor to multipy the attenuation with
277
278   this actually just sets the following: glLightf(currentLight, type, factor)
279*/
280void Light::setAttenuation(AttenuationType type, float factor)
281{
282  if (!this->currentLight)
283    { 
284      PRINTF(1)("no Light defined yet\n");
285      return;
286    }
287  this->currentLight->attenuationFactor = factor;
288  this->currentLight->attenuationType = type;
289  switch (type)
290    {
291    case CONSTANT:
292      glLightf(lightsV[this->currentLight->lightNumber], GL_CONSTANT_ATTENUATION, factor);
293      break;
294    case LINEAR:
295      glLightf(lightsV[this->currentLight->lightNumber], GL_LINEAR_ATTENUATION, factor);
296      break;
297    case QUADRATIC:
298      glLightf(lightsV[this->currentLight->lightNumber], GL_QUADRATIC_ATTENUATION, factor);
299      break;
300    }
301}
302
303
304/**
305   \brief sets the ambient Color of the Scene
306   \param r red
307   \param g green
308   \param b blue
309*/
310void Light::setAmbientColor(GLfloat r, GLfloat g, GLfloat b)
311{
312  this->ambientColor[0] = r;
313  this->ambientColor[1] = g;
314  this->ambientColor[2] = b;
315  this->ambientColor[3] = 1.0;
316
317  glLightfv (GL_LIGHT0, GL_AMBIENT, this->ambientColor);
318}
319
320/**
321   \brief stets the direction of the Spot Light.
322   \param direction The direction of the Spot Light.
323*/
324void Light::setSpotDirection(Vector direction)
325{
326  this->currentLight->spotDirection[0] = direction.x;
327  this->currentLight->spotDirection[1] = direction.y;
328  this->currentLight->spotDirection[2] = direction.z;
329
330  glLightfv(lightsV[this->currentLight->lightNumber], GL_SPOT_DIRECTION, this->currentLight->spotDirection);
331}
332
333
334/**
335   \brief sets the cutoff angle of the Light.
336   \param cutoff The cutoff angle.
337*/
338void Light::setSpotCutoff(GLfloat cutoff)
339{
340  this->currentLight->spotCutoff = cutoff;
341  glLightf(lightsV[this->currentLight->lightNumber], GL_SPOT_CUTOFF, cutoff);
342}
343
344
345// get Attributes
346
347/**
348   \returns the Position of the Light
349*/
350Vector Light::getPosition(void)
351{
352  if (!this->currentLight)
353    { 
354      PRINTF(1)("no Light defined yet\n");
355      return Vector(.0, .0, .0);
356    }
357  else
358    return getPosition(currentLight->lightNumber);
359}
360
361
362
363
364/**
365   \brief outputs debug information about the Class and its lights
366*/
367void Light::debug(void)
368{
369  PRINT(0)("=================================\n");
370  PRINT(0)("= DEBUG INFORMATION CLASS LIGHT =\n");
371  PRINT(0)("=================================\n");
372  PRINT(0)("Reference: %p\n", Light::singletonRef);
373  if (this->currentLight)
374    PRINT(0)("current Light Nr: %d\n", this->currentLight->lightNumber);
375  PRINT(0)("Ambient Color: %f:%f:%f\n", this->ambientColor[0], this->ambientColor[0], this->ambientColor[0]);
376  PRINT(0)("=== Lights ===\n");
377  for (int i = 0; i < NUMBEROFLIGHTS; i++)
378    if (this->lights[i])
379      {
380        PRINT(0)(":: %d ::  -- reference %p\n", i, lights[i]);
381        PRINT(0)(" GL-state: ");
382        GLboolean param; 
383        glGetBooleanv(lightsV[i], &param);
384        if (param)
385          PRINT(0)("ON\n");
386        else
387          PRINT(0)("OFF\n");
388
389        if (i != lights[i]->lightNumber)
390          PRINTF(1)(" Lights are out of sync, this really should not happen,\n   %d % should be equal.\n", i, lights[i]->lightNumber);
391        PRINT(0)(" Position:      %f/%f/%f\n", lights[i]->lightPosition[0], lights[i]->lightPosition[1], lights[i]->lightPosition[2]);
392        PRINT(0)(" DiffuseColor:  %f/%f/%f\n", lights[i]->diffuseColor[0], lights[i]->diffuseColor[1], lights[i]->diffuseColor[2]);
393        PRINT(0)(" SpecularColor: %f/%f/%f\n", lights[i]->specularColor[0], lights[i]->specularColor[1], lights[i]->specularColor[2]);
394        PRINT(0)(" Attenuation:   ");
395        switch (lights[i]->attenuationType)
396          {
397          case CONSTANT:
398            PRINT(0)("constant");
399          case LINEAR:
400            PRINT(0)("linear");
401            break;
402          case QUADRATIC:
403            PRINT(0)("quadratic");
404            break;
405          }
406        PRINT(0)(" with Factor %f\n", lights[i]->attenuationFactor);
407      }
408  PRINT(0)("--------------------------------\n");
409}
Note: See TracBrowser for help on using the repository browser.