/* 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 "util/loading/load_param.h" #include "util/loading/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) { this->setClassID(CL_LENSE_FLARE, "LenseFlare"); 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); PRINTF(0)("light is: %p\n", this->lightSource); this->isVisible = true; if (root != NULL) { this->loadParams(root); this->activate(); } this->setSourceVisibility(false); this->isVisible = true; } /** * 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); LOAD_PARAM_START_CYCLE(root, element); { LoadParam_CYCLE(element, "add-flare-texture", this, LenseFlare, addFlare) .describe("adds a lensflare texture to the engine"); } LOAD_PARAM_END_CYCLE(element); } /** * 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::stringToFogMode(const std::string& 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 std::string& 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(4)("Added a Lenseflare Billboard with texture %s\n", textureName.c_str()); // 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); } PRINTF(4)("Finished adding\n"); } void LenseFlare::setSourceVisibility(bool visibility) { if (this->isVisible == visibility) return; float dist = this->frustumPlane.distancePoint(this->lightSource->getAbsCoor()); PRINTF(0)("dist: %f\n", dist); std::vector::const_iterator it; for(it = flares.begin(); it != flares.end(); it++) (*it)->setVisibility(visibility); this->isVisible = visibility; } /** * 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 this->frustumPlane = State::getCamera()->getViewFrustum(); if (State::getCamera()->distance(lightSource) < 0) this->setSourceVisibility(false); else this->setSourceVisibility(true); // 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; }