Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/shaders_merge/src/orxonox/graphics/LensFlare.cc @ 11075

Last change on this file since 11075 was 11075, checked in by landauf, 8 years ago

fixed author and added some c++11 features

  • Property svn:eol-style set to native
File size: 10.1 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 *      David 'davidsa' Salvisberg
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30  @file LensFlare.cc
31  @brief Implementation of the LensFlare class.
32*/
33
34#include "LensFlare.h"
35
36#include "core/XMLPort.h"
37#include "graphics/Billboard.h"
38#include "CameraManager.h"
39#include "RenderQueueListener.h"
40
41#include <OgreSphere.h>
42#include <OgreRenderWindow.h>
43
44namespace orxonox
45{
46    RegisterClass(LensFlare);
47   
48    LensFlare::LensFlare(Context* context) : StaticEntity(context), scale_(1.0f), fadeOnViewBorder_(true), fadeResolution_(7), fadeExponent_(2.0f), colour_(new ColourValue(1.0f,0.9f,0.9f))
49    {
50        RegisterObject(LensFlare);
51       
52        this->lensConfiguration_=new std::vector<LensFlare::Lens*>();
53        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/burst"),1.0f,1.0f,1.0f)); //main burst
54        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/burst"),0.7f,1.2f,1.05f)); //secondary 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/ring"),0.1f,2.5f,0.9f)); //all the different distanced lenses
57        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/iris"),0.1f,0.2f,0.5f));
58        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/halo5"),0.1f,0.3f,0.45f));
59        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/halo5"),0.4f,0.2f,0.35f));
60        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/iris"),0.1f,0.4f,0.25f));
61        this->lensConfiguration_->push_back(new LensFlare::Lens(new std::string("lensflare/halo4"),0.05f,0.2f,0.2f));
62       
63        this->createBillboards();
64       
65        this->registerVariables();
66    }
67
68    LensFlare::~LensFlare()
69    {
70    }
71
72    void LensFlare::XMLPort(Element& xmlelement, XMLPort::Mode mode)
73    {
74        SUPER(LensFlare, XMLPort, xmlelement, mode);
75        XMLPortParam(LensFlare, "scale", setScale, getScale, xmlelement, mode).defaultValues(1.0f);
76        XMLPortParam(LensFlare, "fadeOnViewBorder", setFadeOnViewBorder, isFadeOnViewBorder, xmlelement, mode).defaultValues(true);
77        XMLPortParam(LensFlare, "fadeResolution", setFadeResolution, getFadeResolution, xmlelement, mode).defaultValues(7);
78        XMLPortParam(LensFlare, "fadeExponent", setFadeExponent, getFadeExponent, xmlelement, mode).defaultValues(2.0f);
79        XMLPortParam(LensFlare, "colour", setColour, getColour, xmlelement, mode);
80    }
81   
82    void LensFlare::registerVariables()
83    {
84        registerVariable(this->scale_, VariableDirection::ToClient);
85        registerVariable(this->fadeOnViewBorder_, VariableDirection::ToClient);
86        registerVariable(this->fadeResolution_, VariableDirection::ToClient);
87    }
88
89    /**
90    @brief
91        This function creates all the billboards needed for the flare effect
92    */
93    void LensFlare::createBillboards()
94    {
95        this->occlusionBillboard_ = new Billboard(this->getContext());
96        this->occlusionBillboard_->setMaterial("lensflare/hoq");
97        this->occlusionBillboard_->setVisible(false);
98        this->occlusionBillboard_->disableFrustumCulling();
99        this->occlusionBillboard_->setRenderQueueGroup(RENDER_QUEUE_HOQ);
100        this->attach(this->occlusionBillboard_);
101       
102        for(std::vector<LensFlare::Lens*>::iterator it = lensConfiguration_->begin(); it != lensConfiguration_->end(); ++it) {
103            Billboard* lensPart=new Billboard(this->getContext());
104            lensPart->setMaterial(*(*it)->material_);
105            lensPart->disableFrustumCulling();
106            lensPart->setVisible(true);
107            this->attach(lensPart);
108        }
109    }
110
111    /**
112    @brief
113        This function updates the states of all the billboards, i.e. their positions, visibilty and dimensions
114    @param viewDirection
115        normalised vector pointing from the current camera to the point light center
116    @param dimension
117        the current dimension of the main billboard, we're always using square billboards
118    @param lightIsVisible
119        is the (point-)light source currently visible
120    */
121    void LensFlare::updateBillboardStates(Vector3& viewDirection, float dimension, bool lightIsVisible)
122    { 
123        this->occlusionBillboard_->setDefaultDimensions(dimension*0.5f,dimension*0.5f);
124        this->occlusionBillboard_->setVisible(lightIsVisible);
125        std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin();
126        it++;
127        for(int i=0; it != this->getAttachedObjects().end(); it++) {
128            Billboard* billboard=static_cast<Billboard*>(*it);
129            LensFlare::Lens* lens=lensConfiguration_->at(i);
130            billboard->setPosition(-viewDirection*(1.0f-lens->position_));
131            billboard->setVisible(lightIsVisible);
132            billboard->setDefaultDimensions(dimension*lens->scale_,dimension*lens->scale_);
133            i++;
134        }
135    }
136
137    /**
138    @brief
139        This function updates the alpha values for all billboards except for the one used for Hardware Occlusion Querying
140    @param alpha
141        the new alpha value all visible billboards should use
142    */
143    void LensFlare::updateBillboardAlphas(float alpha)
144    {
145        this->colour_->a=alpha;
146        std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin();
147        it++;
148        for(int i=0;it!=this->getAttachedObjects().end(); it++) {
149            ColourValue* cur=new ColourValue(0,0,0,0);
150            (*cur)+= *(this->colour_);
151            cur->a*=lensConfiguration_->at(i)->alpha_;
152            Billboard* billboard=static_cast<Billboard*>(*it);
153            billboard->setColour(*cur);
154            i++;
155        }
156    }
157   
158    /**
159    @brief
160        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
161    @param dimension
162        the current dimension of the main billboard, we're always using square billboards
163    @return
164        the absolute amount of point samples that are currently captured by the camera of the view port
165    */
166    unsigned int LensFlare::getPointCount(float dimension) const
167    {
168        Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera();
169        Vector3 position = this->getWorldPosition();
170        Vector3 nX = camera->getDerivedOrientation().xAxis().normalisedCopy();
171        Vector3 nY = camera->getDerivedOrientation().yAxis().normalisedCopy();
172        int halfRes=fadeResolution_/2;
173        float resDim=dimension/fadeResolution_;
174        unsigned int count=0;
175        for(int i=-halfRes;i<=halfRes;i++)
176        {
177            for(int j=-halfRes;j<=halfRes;j++)
178            {
179                Vector3 point=position+(i*resDim)*nX+(j*resDim)*nY;//generate point samples
180                if(camera->isVisible(point))
181                {
182                    count++;
183                }
184            }
185        }
186        return count;
187    }
188
189    void LensFlare::tick(float dt)
190    {
191        if(this->isVisible())
192        {
193            Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera(); //get active Ogre Camera Instance, so we can check whether the light source is visible
194            this->cameraDistance_=camera->getDerivedPosition().distance(this->getPosition());
195            float dimension=this->cameraDistance_*this->scale_;
196            if(!this->fadeOnViewBorder_)
197            {
198                this->fadeResolution_=3;//this is so we can still determine when the billboard has left the screen
199            }
200            unsigned int pointCount=this->getPointCount(dimension*0.25f*this->scale_);
201            Vector3 viewDirection=this->getWorldPosition()-camera->getDerivedPosition()-camera->getDerivedDirection()*this->cameraDistance_;
202            updateBillboardStates(viewDirection,dimension,pointCount>0);
203            if(pointCount>0) {
204                Ogre::Sphere* sphere=new Ogre::Sphere(this->getPosition(),dimension*0.25f*this->scale_);
205                float left, right, top, bottom;
206                camera->projectSphere(*sphere,&left,&top,&right,&bottom);//approximate maximum pixel count of billboard with a sphere
207                delete sphere;
208               
209                Ogre::RenderWindow* window = GraphicsManager::getInstance().getRenderWindow();
210                float maxCount=(right-left)*(top-bottom)*window->getWidth()*window->getHeight()*0.25f;
211                float pixelCount=this->getScene()->getRenderQueueListener()->getPixelCount();//get pixel count
212                float ratio=(maxCount<0.0f)?0.0f:(pixelCount/maxCount);//prevent underflow and division by zero
213                float borderRatio=1.0f;
214                if(this->fadeOnViewBorder_)
215                {
216                    borderRatio=((float) pointCount)/(((float) fadeResolution_)*((float) fadeResolution_));//ratio for the border fade
217                }
218                //update alpha values of all billboards except the HOQ billboard
219                this->updateBillboardAlphas(std::min(1.0f,std::pow(std::min(ratio,borderRatio),this->fadeExponent_)));
220            }
221        }
222    }
223
224    void LensFlare::changedVisibility()
225    {
226     
227    }
228}
Note: See TracBrowser for help on using the repository browser.