Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/shaders/src/orxonox/graphics/LensFlare.cc @ 9500

Last change on this file since 9500 was 9500, checked in by davidsa, 11 years ago

Added nested Class Lens to LensFlare, to simplify lens flare configuration and some of the methods. Might also be used to define presets in the future.

File size: 9.8 KB
Line 
1 /*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *      Reto Grieder (physics)
25 *   Co-authors:
26 *      ...
27 *
28 */
29
30/**
31  @file LensFlare.cc
32  @brief Implementation of the LensFlare class.
33*/
34
35#include "LensFlare.h"
36
37#include "core/XMLPort.h"
38#include "graphics/Billboard.h"
39#include "CameraManager.h"
40#include "RenderQueueListener.h"
41
42#include <OgreSphere.h>
43#include <OgreRenderWindow.h>
44
45namespace orxonox
46{
47    CreateFactory(LensFlare);
48   
49    LensFlare::LensFlare(BaseObject* creator) : StaticEntity(creator), scale_(1.0f), fadeOnViewBorder_(true), fadeResolution_(7), fadeExponent_(2.0f), colour_(new ColourValue(1.0f,0.9f,0.9f))
50    {
51        RegisterObject(LensFlare);
52       
53        this->lensConfiguration_=new std::vector<LensFlare::Lens*>();
54        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/burst"),1.0f,1.0f,1.0f)); //main burst
55        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/bursthalo"),0.7f,0.9f,1.0f)); //halo around main burst
56        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/halo1"),0.4f,0.2f,0.8f)); //all the different distanced lenses
57        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/halo2"),0.7f,0.3f,0.7f));
58        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/halo3"),0.3f,0.4f,0.6f));
59        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/halo3"),0.1f,0.8f,0.4f));
60        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/halo1"),0.15f,0.5f,0.35f));
61       
62        this->createBillboards();
63       
64        this->registerVariables();
65    }
66
67    LensFlare::~LensFlare()
68    {
69    }
70
71    void LensFlare::XMLPort(Element& xmlelement, XMLPort::Mode mode)
72    {
73        SUPER(LensFlare, XMLPort, xmlelement, mode);
74        XMLPortParam(LensFlare, "scale", setScale, getScale, xmlelement, mode).defaultValues(1.0f);
75        XMLPortParam(LensFlare, "fadeOnViewBorder", setFadeOnViewBorder, isFadeOnViewBorder, xmlelement, mode).defaultValues(true);
76        XMLPortParam(LensFlare, "fadeResolution", setFadeResolution, getFadeResolution, xmlelement, mode).defaultValues(7);
77        XMLPortParam(LensFlare, "fadeExponent", setFadeExponent, getFadeExponent, xmlelement, mode).defaultValues(2.0f);
78        XMLPortParam(LensFlare, "colour", setColour, getColour, xmlelement, mode);
79    }
80   
81    void LensFlare::registerVariables()
82    {
83        registerVariable(this->scale_, VariableDirection::ToClient);
84        registerVariable(this->fadeOnViewBorder_, VariableDirection::ToClient);
85        registerVariable(this->fadeResolution_, VariableDirection::ToClient);
86    }
87
88    /**
89    @brief
90        This function creates all the billboards needed for the flare effect
91    */
92    void LensFlare::createBillboards()
93    {
94        this->occlusionBillboard_ = new Billboard(this);
95        this->occlusionBillboard_->setMaterial("lensflare/hoq");
96        this->occlusionBillboard_->setVisible(false);
97        this->occlusionBillboard_->disableFrustumCulling();
98        this->occlusionBillboard_->setRenderQueueGroup(RENDER_QUEUE_HOQ);
99        this->attach(this->occlusionBillboard_);
100       
101        for(std::vector<LensFlare::Lens*>::iterator it = lensConfiguration_->begin(); it != lensConfiguration_->end(); ++it) {
102            Billboard* lensPart=new Billboard(this);
103            lensPart->setMaterial(*(*it)->material_);
104            lensPart->disableFrustumCulling();
105            lensPart->setVisible(true);
106            this->attach(lensPart);
107        }
108    }
109
110    /**
111    @brief
112        This function updates the states of all the billboards, i.e. their positions, visibilty and dimensions
113    @param viewDirection
114        normalised vector pointing from the current camera to the point light center
115    @param dimension
116        the current dimension of the main billboard, we're always using square billboards
117    @param lightIsVisible
118        is the (point-)light source currently visible
119    */
120    void LensFlare::updateBillboardStates(Vector3& viewDirection, float dimension, bool lightIsVisible)
121    { 
122        this->occlusionBillboard_->setDefaultDimensions(dimension*0.5f,dimension*0.5f);
123        this->occlusionBillboard_->setVisible(lightIsVisible);
124        std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin();
125        it++;
126        for(int i=0; it != this->getAttachedObjects().end(); it++) {
127            Billboard* billboard=static_cast<Billboard*>(*it);
128            LensFlare::Lens* lens=lensConfiguration_->at(i);
129            billboard->setPosition(-viewDirection*(1.0f-lens->position_));
130            billboard->setVisible(lightIsVisible);
131            billboard->setDefaultDimensions(dimension*lens->scale_,dimension*lens->scale_);
132            i++;
133        }
134    }
135
136    /**
137    @brief
138        This function updates the alpha values for all billboards except for the one used for Hardware Occlusion Querying
139    @param alpha
140        the new alpha value all visible billboards should use
141    */
142    void LensFlare::updateBillboardAlphas(float alpha)
143    {
144        this->colour_->a=alpha;
145        std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin();
146        it++;
147        for(int i=0;it!=this->getAttachedObjects().end(); it++) {
148            ColourValue* cur=new ColourValue(0,0,0,0);
149            (*cur)+= *(this->colour_);
150            cur->a*=lensConfiguration_->at(i)->alpha_;
151            Billboard* billboard=static_cast<Billboard*>(*it);
152            billboard->setColour(*cur);
153            i++;
154        }
155    }
156   
157    /**
158    @brief
159        This function generates point samples of the main burst billboard according to the fadeResolution and returns how many of them are in the view port
160    @param dimension
161        the current dimension of the main billboard, we're always using square billboards
162    @return
163        the absolute amount of point samples that are currently captured by the camera of the view port
164    */
165    unsigned int LensFlare::getPointCount(float dimension) const
166    {
167        Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera();
168        Vector3 position = this->getWorldPosition();
169        Vector3 nX = camera->getDerivedOrientation().xAxis().normalisedCopy();
170        Vector3 nY = camera->getDerivedOrientation().yAxis().normalisedCopy();
171        int halfRes=fadeResolution_/2;
172        float resDim=dimension/fadeResolution_;
173        unsigned int count=0;
174        for(int i=-halfRes;i<=halfRes;i++)
175        {
176            for(int j=-halfRes;j<=halfRes;j++)
177            {
178                Vector3 point=position+(i*resDim)*nX+(j*resDim)*nY;//generate point samples
179                if(camera->isVisible(point))
180                {
181                    count++;
182                }
183            }
184        }
185        return count;
186    }
187
188    void LensFlare::tick(float dt)
189    {
190        if(this->isVisible())
191        {
192            Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera(); //get active Ogre Camera Instance, so we can check whether the light source is visible
193            this->cameraDistance_=camera->getDerivedPosition().distance(this->getPosition());
194            float dimension=this->cameraDistance_*this->scale_;
195            if(!this->fadeOnViewBorder_)
196            {
197                this->fadeResolution_=3;//this is so we can still determine when the billboard has left the screen
198            }
199            unsigned int pointCount=this->getPointCount(dimension*0.25f*this->scale_);
200            Vector3 viewDirection=this->getWorldPosition()-camera->getDerivedPosition()-camera->getDerivedDirection()*this->cameraDistance_;
201            updateBillboardStates(viewDirection,dimension,pointCount>0);
202            if(pointCount>0) {
203                Ogre::Sphere* sphere=new Ogre::Sphere(this->getPosition(),dimension*0.25f*this->scale_);
204                float left, right, top, bottom;
205                camera->projectSphere(*sphere,&left,&top,&right,&bottom);//approximate maximum pixel count of billboard with a sphere
206                delete sphere;
207               
208                Ogre::RenderWindow* window = GraphicsManager::getInstance().getRenderWindow();
209                float maxCount=(right-left)*(top-bottom)*window->getWidth()*window->getHeight()*0.25f;
210                float pixelCount=this->getScene()->getRenderQueueListener()->getPixelCount();//get pixel count
211                float ratio=(maxCount<0.0f)?0.0f:(pixelCount/maxCount);//prevent underflow and division by zero
212                float borderRatio=1.0f;
213                if(this->fadeOnViewBorder_)
214                {
215                    borderRatio=((float) pointCount)/(((float) fadeResolution_)*((float) fadeResolution_));//ratio for the border fade
216                }
217                //update alpha values of all billboards except the HOQ billboard
218                this->updateBillboardAlphas(std::min(1.0f,std::pow(std::min(ratio,borderRatio),this->fadeExponent_)));
219            }
220        }
221    }
222
223    void LensFlare::changedVisibility()
224    {
225     
226    }
227}
Note: See TracBrowser for help on using the repository browser.