Index: orxonox/trunk/src/lib/graphics/light.cc
===================================================================
--- orxonox/trunk/src/lib/graphics/light.cc	(revision 3603)
+++ orxonox/trunk/src/lib/graphics/light.cc	(revision 3603)
@@ -0,0 +1,524 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LIGHT
+
+#include "light.h"
+
+#include "glincl.h"
+
+using namespace std;
+
+//! Definition of the Lights
+int lightsV[] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7};
+
+
+/**
+   \param lightNumber the Light Number to initiate
+*/
+Light::Light(int lightNumber)
+{
+  this->setClassName("Light");
+  char tmpName[7];
+  sprintf(tmpName, "Light%d", lightNumber);
+  this->setName(tmpName);
+
+  PRINTF(4)("initializing Light number %d.\n", lightNumber);
+  // enable The light
+  glEnable(lightsV[lightNumber]); // postSpawn
+  
+  // set values (defaults)
+  this->lightNumber = lightNumber;
+  this->setPosition(0.0, 0.0, 0.0);
+  this->setDiffuseColor(1.0, 1.0, 1.0);
+  this->setSpecularColor(1.0, 1.0, 1.0);
+}
+
+/**
+   \brief destroys a Light
+*/
+Light::~Light(void)
+{
+  glDisable(lightsV[this->lightNumber]);
+}
+
+/**
+   \brief Sets a Position for the Light.
+   \param position The new position of the Light.
+   \todo patrick: is it ok to set a Light Position even if it is derived from p_node??
+*/
+void Light::setPosition(Vector position)
+{
+  this->lightPosition[0] = position.x;
+  this->lightPosition[1] = position.y;
+  this->lightPosition[2] = position.z;
+  this->lightPosition[3] = 0.0;
+
+  this->setAbsCoor(&position);
+
+  glLightfv (lightsV[this->lightNumber], GL_POSITION, this->lightPosition);
+}
+
+/**
+   \brief Sets a Position of this Light.
+   \param x the x-coordinate
+   \param y the y-coordinate
+   \param z the z-coordinate
+*/
+void Light::setPosition(GLfloat x, GLfloat y, GLfloat z)
+{
+  this->setPosition(Vector(x, y, z));
+}
+
+/**
+   \brief sets an emitting Diffuse color of this Light
+   \param r red
+   \param g green
+   \param b blue
+*/
+void Light::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  this->diffuseColor[0] = r;
+  this->diffuseColor[1] = g;
+  this->diffuseColor[2] = b;
+  this->diffuseColor[3] = 1.0;
+
+  glLightfv (lightsV[this->lightNumber], GL_DIFFUSE, this->diffuseColor);
+}
+
+/**
+   \brief sets an emitting Specular color of this Light
+   \param r red
+   \param g green
+   \param b blue
+*/
+void Light::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  this->specularColor[0] = r;
+  this->specularColor[1] = g;
+  this->specularColor[2] = b;
+  this->specularColor[3] = 1.0;
+
+  glLightfv (lightsV[this->lightNumber], GL_SPECULAR, this->specularColor);
+}
+
+/**
+   \brief Sets the AttenuationType of this Light Source
+   \param constantAttenuation The Constant Attenuation of the Light
+   \param linearAttenuation The Linear Attenuation of the Light
+   \param quadraticAttenuation The Quadratic Attenuation of the Light
+*/
+void Light::setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation)
+{
+  this->constantAttenuation  = constantAttenuation;
+  this->linearAttenuation    = linearAttenuation;
+  this->quadraticAttenuation = quadraticAttenuation;
+
+  glLightf(lightsV[this->lightNumber], GL_CONSTANT_ATTENUATION,  constantAttenuation);
+  glLightf(lightsV[this->lightNumber], GL_LINEAR_ATTENUATION,    linearAttenuation);
+  glLightf(lightsV[this->lightNumber], GL_QUADRATIC_ATTENUATION, quadraticAttenuation);
+}
+
+/**
+   \brief stets the direction of the Spot Light.
+   \param direction The direction of the Spot Light.
+*/
+void Light::setSpotDirection(Vector direction)
+{
+  this->spotDirection[0] = direction.x;
+  this->spotDirection[1] = direction.y;
+  this->spotDirection[2] = direction.z;
+
+  glLightfv(lightsV[this->lightNumber], GL_SPOT_DIRECTION, this->spotDirection);
+}
+
+/**
+   \brief sets the cutoff angle of the Light.
+   \param cutoff The cutoff angle.
+*/
+void Light::setSpotCutoff(GLfloat cutoff)
+{
+  this->spotCutoff = cutoff;
+  glLightf(lightsV[this->lightNumber], GL_SPOT_CUTOFF, cutoff);
+}
+
+/**
+   \returns the Position of the Light
+*/
+Vector Light::getPosition() const
+{
+  return Vector(this->lightPosition[0], this->lightPosition[1], this->lightPosition[2]);
+}
+
+/**
+   \brief draws this Light. Being a World-entity the possibility to do this lies at hand.
+*/ 
+void Light::draw()
+{
+  float pos[4] = {this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z, 1.0};
+  PRINTF(4)("Drawing The Lights new Position at %f %f %f\n", pos[0], pos[1], pos[2]);
+  glLightfv(lightsV[this->lightNumber], GL_POSITION, pos);
+}
+
+/**
+   \brief Prints out some nice formated debug information about the Light
+*/
+void Light::debug(void) const
+{
+  PRINT(0)(":: %d ::  -- reference %p\n", this->lightNumber, this);
+  PRINT(0)(" GL-state: ");
+  GLboolean param; 
+  glGetBooleanv(lightsV[this->lightNumber], &param);
+  if (param)
+    PRINT(0)("ON\n");
+  else
+    PRINT(0)("OFF\n");
+  
+  PRINT(0)(" Position:      %f/%f/%f\n", this->lightPosition[0], this->lightPosition[1], this->lightPosition[2]);
+  PRINT(0)(" DiffuseColor:  %f/%f/%f\n", this->diffuseColor[0], this->diffuseColor[1], this->diffuseColor[2]);
+  PRINT(0)(" SpecularColor: %f/%f/%f\n", this->specularColor[0], this->specularColor[1], this->specularColor[2]);
+  PRINT(0)(" Attenuation: constant=%f linear=%f quadratic=%f\n", this->constantAttenuation, this->linearAttenuation, this->quadraticAttenuation);
+}
+
+
+/******************
+** LIGHT-MANAGER **
+******************/
+/**
+   \brief standard constructor for a Light
+*/
+LightManager::LightManager () 
+{
+  this->setClassName ("LightManager");
+
+  glEnable (GL_LIGHTING);
+  this->setAmbientColor(.3, .3, .3);
+  this->lights = new Light*[NUMBEROFLIGHTS];
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    lights[i] = NULL;
+  this->currentLight = NULL;
+}
+
+/**
+   \brief standard deconstructor
+   
+   first disables Lighting
+
+   then deletes the rest of the allocated memory
+   and in the end sets the singleton Reference to zero.
+*/
+LightManager::~LightManager () 
+{
+  glDisable(GL_LIGHTING);
+  
+  // this will be done either by worldEntity, or by pNode as each light is one of them
+  //  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+  //    this->deleteLight(i);
+  delete lights;
+  LightManager::singletonRef = NULL;
+}
+
+/**
+   \brief singleton-Reference to the Light-class
+*/
+LightManager* LightManager::singletonRef = NULL;
+
+/**
+   \returns The Instance of the Lights
+*/
+LightManager* LightManager::getInstance(void)
+{
+  if (!singletonRef)
+    LightManager::singletonRef = new LightManager();
+  return singletonRef;
+}
+
+/**
+   \brief initializes a new Light with default values, and enables GL_LIGHTING
+*/
+void LightManager::initLight(int lightNumber)
+{
+  lights[lightNumber] = new Light(lightNumber);
+}
+
+/**
+   \brief Adds a new Light, by selecting the First free slot.
+
+   if no slot is free error
+*/
+int LightManager::addLight(void)
+{
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (!this->lights[i])
+      return addLight(i); 
+  PRINTF(1)("no more light slots availiable. All %d already taken\n", NUMBEROFLIGHTS);
+  return -1;
+}
+
+/**
+   \brief Adds a new Light
+   \param lightNumber The number of the light to add.
+
+   if the Number is not free: warn, automatically choose another slot.
+*/
+int LightManager::addLight(int lightNumber)
+{
+  if (this->lights[lightNumber])
+    {
+      PRINTF(2)("Lightslot %d is allready taken, trying another one\n", lightNumber);
+      return this->addLight();
+    }
+  this->initLight(lightNumber);
+  this->currentLight = this->lights[lightNumber];
+  return lightNumber;
+}
+
+/**
+   \brief select the light to work with
+   \param lightNumber the light to work with
+*/
+void LightManager::editLightNumber(int lightNumber)
+{
+  if (!this->currentLight)
+    { 
+      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
+      return;
+    }
+  this->currentLight = lights[lightNumber];
+}
+
+/**
+   \brief Delete the current Light
+*/
+void LightManager::deleteLight(void)
+{
+  if (!this->currentLight)
+    { 
+      PRINTF(1)("no Light defined yet. So you cannot delete any Light right now.\n");
+      return;
+    }
+
+  this->deleteLight(this->currentLight->getLightNumber());
+}
+
+/**
+   \brief delete light.
+   \param lightNumber the number of the light to delete
+*/
+void LightManager::deleteLight(int lightNumber)
+{
+  if (this->lights[lightNumber])
+    {
+      PRINTF(4)("deleting Light number %d\n", lightNumber);
+      delete this->lights[lightNumber];
+      this->lights[lightNumber] = NULL;
+    }
+}
+
+/**
+   \brief draws all the Lights in their appropriate position
+*/
+void LightManager::draw()
+{
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  PRINTF(4)("Drawing the Lights\n");
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (this->lights[i])
+      lights[i]->draw();
+}
+
+
+
+// set Attributes
+/**
+   \brief sets the ambient Color of the Scene
+   \param r red
+   \param g green
+   \param b blue
+*/
+void LightManager::setAmbientColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  this->ambientColor[0] = r;
+  this->ambientColor[1] = g;
+  this->ambientColor[2] = b;
+  this->ambientColor[3] = 1.0;
+
+  glLightfv (GL_LIGHT0, GL_AMBIENT, this->ambientColor);
+}
+
+/**
+   \brief sets The Position of the currently selected Light
+   \param position the new Position
+*/
+void LightManager::setPosition(Vector position)
+{
+  this->currentLight->setPosition(position);
+}
+
+/**
+   \brief Sets a Position for the currently selected Light.
+   \param x the x-coordinate
+   \param y the y-coordinate
+   \param z the z-coordinate
+*/
+void LightManager::setPosition(GLfloat x, GLfloat y, GLfloat z)
+{
+  if (!this->currentLight)
+    { 
+      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
+      return;
+    }
+  this->currentLight->setPosition(x, y, z);
+}
+
+/**
+   \brief sets an emitting Diffuse color of the currently selected Light
+   \param r red
+   \param g green
+   \param b blue
+*/
+void LightManager::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  if (!this->currentLight)
+    { 
+      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
+      return;
+    }
+  this->currentLight->setDiffuseColor(r,g,b);
+}
+
+/**
+   \brief sets an emitting Specular color of the currently selected Light
+   \param r red
+   \param g green
+   \param b blue
+*/
+void LightManager::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  if (!this->currentLight)
+    { 
+      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
+      return;
+    }
+  this->currentLight->setSpecularColor(r, g, b);
+}
+
+/**
+   \brief Sets the AttenuationType of th currently selecte LightSource Light Source
+   \param constantAttenuation The Constant Attenuation of the Light
+   \param linearAttenuation The Linear Attenuation of the Light
+   \param quadraticAttenuation The Quadratic Attenuation of the Light
+*/
+void LightManager::setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation)
+{
+  if (!this->currentLight)
+    { 
+      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
+      return;
+    }
+  this->currentLight->setAttenuation(constantAttenuation, linearAttenuation, quadraticAttenuation);
+}
+
+
+/**
+   \brief stets the direction of the Spot Light.
+   \param direction The direction of the Spot Light.
+*/
+void LightManager::setSpotDirection(Vector direction)
+{
+  if (!this->currentLight)
+    { 
+      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
+      return;
+    }
+  this->currentLight->setSpotDirection(direction);
+}
+
+/**
+   \brief sets the cutoff angle of the Light.
+   \param cutoff The cutoff angle.
+*/
+void LightManager::setSpotCutoff(GLfloat cutoff)
+{
+  if (!this->currentLight)
+    { 
+      PRINTF(2)("no Light defined yet. Please define at least one light first befor editing.\n");
+      return;
+    }
+  this->currentLight->setSpotCutoff(cutoff);
+}
+
+// get Attributes
+/**
+   \returns the Position of the Light
+*/
+Vector LightManager::getPosition(void) const
+{
+  if (!this->currentLight)
+    { 
+      PRINTF(2)("no Light defined yet\n");
+      return Vector(.0, .0, .0);
+    }
+  else
+    return this->currentLight->getPosition();
+}
+
+/**
+   \returns the Position of Light 
+   \param lightNumber lightnumber
+*/
+Vector LightManager::getPosition(int lightNumber) const
+{
+  if (!this->lights[lightNumber])
+    {
+      PRINTF(2)("no Light defined yet\n");
+      return Vector(.0,.0,.0);
+    }
+  else
+    return this->lights[lightNumber]->getPosition();
+}
+
+/**
+   \returns a pointer to a Light
+   \param lightNumber The light to request the pointer from
+*/
+Light* LightManager::getLight(int lightNumber) const
+{
+  return this->lights[lightNumber];
+}
+
+/**
+   \brief outputs debug information about the Class and its lights
+*/
+void LightManager::debug(void) const
+{
+  PRINT(0)("=================================\n");
+  PRINT(0)("= DEBUG INFORMATION CLASS LIGHT =\n");
+  PRINT(0)("=================================\n");
+  PRINT(0)("Reference: %p\n", LightManager::singletonRef);
+  if (this->currentLight)
+    PRINT(0)("current Light Nr: %d\n", this->currentLight->getLightNumber());
+  PRINT(0)("Ambient Color: %f:%f:%f\n", this->ambientColor[0], this->ambientColor[0], this->ambientColor[0]);
+  PRINT(0)("=== Lights ===\n");
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (this->lights[i])
+      {
+	this->lights[i]->debug();
+      }
+  PRINT(0)("--------------------------------\n");
+}
Index: orxonox/trunk/src/lib/graphics/light.h
===================================================================
--- orxonox/trunk/src/lib/graphics/light.h	(revision 3603)
+++ orxonox/trunk/src/lib/graphics/light.h	(revision 3603)
@@ -0,0 +1,143 @@
+/*! 
+    \file light.h
+    \brief Handles Lights.
+
+    A Light is one of the more important things in a 3D-environment,
+    without it one sees nothing :)
+    It is here for diffuse-, specular- and Bump-Mappings.
+*/
+
+#ifndef _LIGHT_H
+#define _LIGHT_H
+
+#include "world_entity.h"
+#include "glincl.h"
+
+//! The maximum number of Lights this OpenGL-implementation supports.
+#define NUMBEROFLIGHTS GL_MAX_LIGHTS
+
+// FORWARD DEFINITIONS //
+class Vector;
+
+//! A class that handles Lights. The LightManager operates on this.
+class Light : public WorldEntity
+{
+ public:
+  Light(int lightNumber);
+  virtual ~Light(void);
+
+  void setPosition(Vector position);
+  void setPosition(GLfloat x, GLfloat y, GLfloat z);
+  void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
+  void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
+  void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
+  void setSpotDirection(Vector direction);
+  void setSpotCutoff(GLfloat cutoff);
+
+  Vector getPosition() const;
+  /** \returns the lightNumber*/
+  int getLightNumber(void) const {return this->lightNumber;}
+  
+  virtual void draw();
+
+  void debug(void) const;
+
+  // attributes
+ private:
+  int lightNumber;            //!< The number of this Light.
+  GLfloat lightPosition[4];   //!< The Position of this Light.
+  GLfloat diffuseColor[4];    //!< The Diffuse Color this Light emmits.
+  GLfloat specularColor[4];   //!< The specular Color of this Light.
+  float constantAttenuation;  //!< The Factor of the the Constant Attenuation.
+  float linearAttenuation;    //!< The Factor of the the Linear Attenuation.
+  float quadraticAttenuation; //!< The Factor of the the Quadratic Attenuation.
+  GLfloat spotDirection[4];   //!< The direction of the Spot Light.
+  GLfloat spotCutoff;         //!< The cutoff Angle of the Light Source
+};
+
+//! A class that handles Lights
+/**
+   A Light is a source that emits light rays (photons)
+
+   <b>Usage:</b>\n
+   First you have to get the Light Manager up and running by using LightManager::getInstance.
+   This automatically initiates the GL_LIGHTING, and sets some default stuff about the light.\n
+   Then you will create a new light using:
+   \li int addLight(void);
+   \li int addLight(int lightNumber);
+
+   now you can operate on the light as follows:
+   \li void setPosition(Vector position);
+   \li void setPosition(GLfloat x, GLfloat y, GLfloat z);
+   \li void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
+   \li void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
+   \li void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
+   \li void setSpotDirection(Vector direction);
+   \li void setSpotCutoff(GLfloat cutoff);
+
+   These functions are preatty selv-explaining, but you can read about them below.\n
+   If you want to fetch info, or the a Light use:
+   \li Vector getPosition(void) const;
+   \li Vector getPosition(int lightNumber) const;
+   \li Light* getLight(int LightNumber) const;
+
+   To redraw the light use
+   \li void draw();
+   
+   and to delete one just use
+   \li void deleteLight(void);
+
+   for some nice output just use:
+   \li void debug(void) const;
+
+   You can also operate on the single Lights themselves, by first retreaving them with 
+   \li Light* getLight(int LightNumber);
+   \n
+   and then using the same functions on this to change settings.
+*/
+class LightManager : public BaseObject
+{
+ private:
+  LightManager(void);
+  void initLight(int LightNumber);
+  
+  static LightManager* singletonRef;    //!< This is the LightHandlers Reference.
+  GLfloat ambientColor[4];       //!< The ambient Color of the scene.
+
+  Light** lights;                //!< An array of Lenght NUMBEROFLIGHTS, that holds pointers to all LightValues.
+  Light* currentLight;           //!< The current Light, we are working with.
+  
+ public:
+  static LightManager* getInstance();
+  virtual ~LightManager(void);
+
+  // set Attributes
+  int addLight(void);
+  int addLight(int lightNumber);
+  void editLightNumber(int lightNumber);
+  void deleteLight(void);
+  void deleteLight(int lightNumber);
+
+  void setAmbientColor(GLfloat r, GLfloat g, GLfloat b);
+
+  void draw();
+
+  //set Attributes
+  void setPosition(Vector position);
+  void setPosition(GLfloat x, GLfloat y, GLfloat z);
+  void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
+  void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
+  void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
+  void setSpotDirection(Vector direction);
+  void setSpotCutoff(GLfloat cutoff);
+
+  // get Attributes
+  Vector getPosition(void) const;
+  Vector getPosition(int lightNumber) const;
+  
+  Light* getLight(int lightNumber) const;
+  
+  void debug(void) const;
+};
+
+#endif /* _LIGHT_H */
