/* 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: Patrick Boenzli */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS #include "lense_flare.h" #include "load_param.h" #include "factory.h" #include "glincl.h" #include "texture.h" #include "light.h" #include "state.h" #include "render2D/billboard.h" #include "light.h" #include "camera.h" using namespace std; CREATE_FACTORY(LenseFlare, CL_LENSE_FLARE); /** * default constructor * @param root The XML-element to load the LenseFlare from */ LenseFlare::LenseFlare(const TiXmlElement* root) { if (root != NULL) this->loadParams(root); this->flareMatrix = new float[14]; /* length image scale */ this->flareMatrix[0] = 1.0f; this->flareMatrix[1] = 1.0f; this->flareMatrix[2] = 0.5f; this->flareMatrix[3] = 0.5f; this->flareMatrix[4] = 0.33f; this->flareMatrix[5] = 0.25f; this->flareMatrix[6] = 0.125f; this->flareMatrix[7] = 1.0f; this->flareMatrix[8] = -0.5f; this->flareMatrix[9] = 0.5f; this->flareMatrix[10] = -0.25f; this->flareMatrix[11] = 0.15f; this->flareMatrix[12] = -1.82f; this->flareMatrix[13] = 0.25f; this->lightSource = (LightManager::getInstance())->getLight(0); } /** * destroys a LenseFlare */ LenseFlare::~LenseFlare() { std::vector::iterator it; for( it = flares.begin(); it != flares.end(); it++) delete (*it); } /** * @param root The XML-element to load the LenseFlare from */ void LenseFlare::loadParams(const TiXmlElement* root) { GraphicsEffect::loadParams(root); LoadParam(root, "add-flare-texture", this, LenseFlare, addFlare) .describe("adds a lensflare texture to the engine"); } /** * initializes the fog effect */ bool LenseFlare::init() {} /** * activates the fog effect */ bool LenseFlare::activate() { this->bActivated = true; } /** * deactivates the fog effect */ bool LenseFlare::deactivate() { this->bActivated = false; } /** * converts a gl mode char to a GLint * @param mode the mode character */ GLint LenseFlare::charToFogMode(const char* mode) {} /** * adds a texture flare * @param textureName the name of the flare texture * * 1st: Texture of the Sun/Light source itself * 2nd: Texture of the fist halo * 3rd: Texture of small burst * 4th: Texture of the second halo * 5th: Texutre of the second burst * 6th: Texture of the third halo * 7th: Texture of the third burst */ void LenseFlare::addFlare(const char* textureName) { if( this->flares.size() > LF_MAX_FLARES) { PRINTF(2)("You tried to add more than %i lense flares, ignoring\n", LF_MAX_FLARES); return; } Billboard* bb = new Billboard(NULL); bb->setTexture(textureName); bb->setSize(50, 50); this->flares.push_back(bb); PRINTF(0)("Added a Lenseflare Billboard with texture %s\n", textureName); // the first flare belongs to the light source if( this->flares.size() == 1 && this->lightSource != NULL) { bb->setBindNode(static_cast(this->lightSource)); bb->setVisibility(true); } } bool LenseFlare::sourceVisible() const { float dist = this->frustumPlane.distancePoint(this->lightSource->getAbsCoor()); if( dist < 0.0f) { std::vector::const_iterator it = flares.begin(); it++; for(; it != flares.end(); it++) (*it)->setVisibility(true); return true; } std::vector::const_iterator it = flares.begin(); it++; for(; it != flares.end(); it++) (*it)->setVisibility(false); return false; } /** * tick the effect */ void LenseFlare::tick(float dt) { if( unlikely(!this->bActivated || this->flares.size() == 0)) return; // refetch light source information if needed if( unlikely( this->lightSource == NULL)) { this->lightSource = (LightManager::getInstance())->getLight(0); if( this->flares.size() > 0) this->flares[0]->setBindNode(static_cast(this->lightSource)); } //set the frustum plane Vector psTarget = (State::getCameraTarget())->getAbsCoor(); Vector psCamera = (State::getCamera())->getAbsCoor(); Vector psCameraDir = psCamera - psTarget; //PRINTF(0)("camera Dir: %f %f %f, camera: %f %f %f\n", psCameraDir.x, psCameraDir.y, psCameraDir.z, psCamera.x, psCamera.y, psCamera.z); this->frustumPlane = Plane(psCameraDir, Vector(-70.0,0.0,0.0)); // always update the screen center, it could be, that the window is resized this->screenCenter = Vector(State::getResX()/2.0f, State::getResY()/2.0f, 0.0f); // flare vector is the direction from the center to the light source this->flareVector = this->flares[0]->getAbsCoor2D() - this->screenCenter; this->flareVector.z = 0.0f; this->distance = this->flareVector.len(); this->flareVector.normalize(); // now calculate the new coordinates of the billboards std::vector::iterator it; int i; for( it = flares.begin(), i = 0; it != flares.end(); it++, i++) { // set the new position if( i == 0) continue; (*it)->setAbsCoor2D( this->screenCenter + this->flareVector * this->flareMatrix[i * 2] * this->distance); (*it)->setSize2D(50.0f * this->flareMatrix[i * 2 + 1], 50.0f * this->flareMatrix[i * 2 + 1]); PRINTF(5)("Tick flare %i @ (%f, %f)\n", i, (*it)->getAbsCoor2D().x, (*it)->getAbsCoor2D().y); // tick them (*it)->tick(dt); } } /** * draws the LenseFlares */ void LenseFlare::draw() const { if( !this->bActivated) return; this->sourceVisible(); }