Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: light: added ability to generate a spot light

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