/* 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: ... */ #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}; /** \brief standard constructor for a Light */ Light::Light () { this->setClassName ("Light"); glEnable (GL_LIGHTING); this->setAmbientColor(.3, .3, .3); this->lights = new LightValue*[NUMBEROFLIGHTS]; for (int i = 0; i < NUMBEROFLIGHTS; i++) lights[i] = NULL; this->currentLight = NULL; } /** \brief standard deconstructor \todo this deconstructor is not jet implemented - do it */ Light::~Light () { glDisable(GL_LIGHTING); for (int i = 0; i < NUMBEROFLIGHTS; i++) this->deleteLight(i); delete lights; Light::singletonRef = NULL; } /** \brief singleton-Reference to the Light-class */ Light* Light::singletonRef = NULL; /** \returns The Instance of the Lights */ Light* Light::getInstance(void) { if (singletonRef) return singletonRef; else return Light::singletonRef = new Light(); } /** \brief initializes a new Light with default values, and enables GL_LIGHTING */ void Light::init(int lightNumber) { PRINTF(3)("initializing Light number %d.\n", lightNumber); // enable The light glEnable(lightsV[lightNumber]); this->currentLight = lights[lightNumber] = new LightValue; // set default values this->currentLight->lightNumber = lightNumber; this->setPosition(Vector(0.0, 0.0, 0.0)); this->setDiffuseColor(1.0, 1.0, 1.0); this->setSpecularColor(1.0, 1.0, 1.0); // lmodelAmbient[] = {.1, .1, .1, 1.0}; } /** \brief Adds a new Light, by selecting the First free slot. if no slot is free error */ int Light::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 Light::addLight(int lightNumber) { if (this->lights[lightNumber]) { PRINTF(2)("Lightslot %d is allready taken, trying another one\n", lightNumber); return this->addLight(); } this->init(lightNumber); this->currentLight = this->lights[lightNumber]; return lightNumber; } /** \brief select the light to work with \param lightNumber the light to work with */ void Light::editLightNumber(int lightNumber) { if (!this->currentLight) { PRINTF(1)("no Light defined yet\n"); return; } this->currentLight = lights[lightNumber]; } /** \brief Delete the current Light */ void Light::deleteLight(void) { if (!this->currentLight) { PRINTF(1)("no Light defined yet\n"); return; } this->deleteLight(this->currentLight->lightNumber); } /** \brief delete light. \param lightnumber the number of the light to delete */ void Light::deleteLight(int lightNumber) { if (this->lights[lightNumber]) { PRINTF(3)("deleting Light number %d\n", lightNumber); delete this->lights[lightNumber]; glDisable(lightsV[lightNumber]); this->lights[lightNumber] = NULL; } } // set Attributes /** \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) { if (!this->currentLight) { PRINTF(1)("no Light defined yet\n"); return; } this->currentLight->lightPosition[0] = position.x; this->currentLight->lightPosition[1] = position.y; this->currentLight->lightPosition[2] = position.z; this->currentLight->lightPosition[3] = 0.0; glLightfv (GL_LIGHT0, GL_POSITION, this->currentLight->lightPosition); } void Light::setPosition(GLfloat x, GLfloat y, GLfloat z) { if (!this->currentLight) { PRINTF(1)("no Light defined yet\n"); return; } this->currentLight->lightPosition[0] = x; this->currentLight->lightPosition[1] = y; this->currentLight->lightPosition[2] = z; this->currentLight->lightPosition[3] = 0.0; glLightfv (GL_LIGHT0, GL_POSITION, this->currentLight->lightPosition); } /** \brief sets an emitting Diffuse color for the Light \param r red \param g green \param b blue */ void Light::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b) { if (!this->currentLight) { PRINTF(1)("no Light defined yet\n"); return; } this->currentLight->diffuseColor[0] = r; this->currentLight->diffuseColor[1] = g; this->currentLight->diffuseColor[2] = b; this->currentLight->diffuseColor[3] = 1.0; glLightfv (GL_LIGHT0, GL_DIFFUSE, this->currentLight->diffuseColor); } /** \brief sets an emitting Ambient color for the Light \param r red \param g green \param b blue */ void Light::setSpecularColor(GLfloat r, GLfloat g, GLfloat b) { if (!this->currentLight) { PRINTF(1)("no Light defined yet\n"); return; } this->currentLight->specularColor[0] = r; this->currentLight->specularColor[1] = g; this->currentLight->specularColor[2] = b; this->currentLight->specularColor[3] = 1.0; glLightfv (GL_LIGHT0, GL_SPECULAR, this->currentLight->specularColor); } /** \brief sets the ambient Color of the Scene \param r red \param g green \param b blue */ void Light::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); } // get Attributes /** \returns the Position of the Light */ Vector Light::getPosition(void) { if (!this->currentLight) { PRINTF(1)("no Light defined yet\n"); return Vector(.0, .0, .0); } else return Vector(this->currentLight->lightPosition[0], this->currentLight->lightPosition[1], this->currentLight->lightPosition[2]); }