Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

fixed numerous issues:

  • fixed memory leaks (delete allocated heap space)
  • use 'new' only when necessary
  • use orxonox_cast instead of static_cast
  • fixed warning in MSVC

also fixed formatting and added certain c++11 features

  • Property svn:eol-style set to native
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 *      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)
49    {
50        RegisterObject(LensFlare);
51       
52        this->lensConfiguration_.emplace_back("lensflare/burst",     1.0f,  1.0f, 1.0f); //main burst
53        this->lensConfiguration_.emplace_back("lensflare/burst",     0.7f,  1.2f, 1.05f); //secondary burst
54        this->lensConfiguration_.emplace_back("lensflare/bursthalo", 0.7f,  0.9f, 1.0f); //halo around main burst
55        this->lensConfiguration_.emplace_back("lensflare/ring",      0.1f,  2.5f, 0.9f); //all the different distanced lenses
56        this->lensConfiguration_.emplace_back("lensflare/iris",      0.1f,  0.2f, 0.5f);
57        this->lensConfiguration_.emplace_back("lensflare/halo5",     0.1f,  0.3f, 0.45f);
58        this->lensConfiguration_.emplace_back("lensflare/halo5",     0.4f,  0.2f, 0.35f);
59        this->lensConfiguration_.emplace_back("lensflare/iris",      0.1f,  0.4f, 0.25f);
60        this->lensConfiguration_.emplace_back("lensflare/halo4",     0.05f, 0.2f, 0.2f);
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->getContext());
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 (const LensFlare::Lens& lens : lensConfiguration_)
102        {
103            Billboard* lensPart = new Billboard(this->getContext());
104            lensPart->setMaterial(lens.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(const Vector3& viewDirection, float dimension, bool lightIsVisible)
122    { 
123        this->occlusionBillboard_->setDefaultDimensions(dimension * 0.5f, dimension * 0.5f);
124        this->occlusionBillboard_->setVisible(lightIsVisible);
125
126        int i = 0;
127        for (WorldEntity* attachedObject : this->getAttachedObjects())
128        {
129            Billboard* billboard = orxonox_cast<Billboard*>(attachedObject);
130            if (billboard == this->occlusionBillboard_)
131                continue;
132            const LensFlare::Lens& lens = lensConfiguration_.at(i);
133            billboard->setPosition(-viewDirection * (1.0f - lens.position_));
134            billboard->setVisible(lightIsVisible);
135            billboard->setDefaultDimensions(dimension * lens.scale_, dimension * lens.scale_);
136            i++;
137        }
138    }
139
140    /**
141    @brief
142        This function updates the alpha values for all billboards except for the one used for Hardware Occlusion Querying
143    @param alpha
144        the new alpha value all visible billboards should use
145    */
146    void LensFlare::updateBillboardAlphas(float alpha)
147    {
148        ColourValue cur = this->colour_;
149
150        int i = 0;
151        for (WorldEntity* attachedObject : this->getAttachedObjects())
152        {
153            Billboard* billboard = orxonox_cast<Billboard*>(attachedObject);
154            if (billboard == this->occlusionBillboard_)
155                continue;
156            cur.a = alpha * lensConfiguration_.at(i).alpha_;
157            billboard->setColour(cur);
158            i++;
159        }
160    }
161   
162    /**
163    @brief
164        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
165    @param dimension
166        the current dimension of the main billboard, we're always using square billboards
167    @return
168        the absolute amount of point samples that are currently captured by the camera of the view port
169    */
170    unsigned int LensFlare::getPointCount(float dimension) const
171    {
172        Ogre::Camera* camera = CameraManager::getInstance().getActiveCamera()->getOgreCamera();
173        Vector3 position = this->getWorldPosition();
174        Vector3 nX = camera->getDerivedOrientation().xAxis().normalisedCopy();
175        Vector3 nY = camera->getDerivedOrientation().yAxis().normalisedCopy();
176        int halfRes = fadeResolution_ / 2;
177        float resDim = dimension / fadeResolution_;
178        unsigned int count = 0;
179        for (int i = -halfRes; i <= halfRes; i++)
180        {
181            for (int j = -halfRes; j <= halfRes; j++)
182            {
183                Vector3 point = position + (i*resDim) * nX + (j*resDim) * nY;//generate point samples
184                if (camera->isVisible(point))
185                {
186                    count++;
187                }
188            }
189        }
190        return count;
191    }
192
193    void LensFlare::tick(float dt)
194    {
195        if(this->isVisible())
196        {
197            // get the current distance of the lensflare center from the camera
198            Ogre::Camera* camera = CameraManager::getInstance().getActiveCamera()->getOgreCamera(); //get active Ogre Camera Instance, so we can check whether the light source is visible
199            float cameraDistance = camera->getDerivedPosition().distance(this->getPosition());
200            float dimension = cameraDistance * this->scale_;
201            if (!this->fadeOnViewBorder_)
202            {
203                this->fadeResolution_ = 3;//this is so we can still determine when the billboard has left the screen
204            }
205            unsigned int pointCount = this->getPointCount(dimension * 0.25f * this->scale_);
206            Vector3 viewDirection = this->getWorldPosition() - camera->getDerivedPosition() - camera->getDerivedDirection() * cameraDistance;
207            this->updateBillboardStates(viewDirection, dimension, pointCount > 0);
208            if (pointCount > 0)
209            {
210                Ogre::Sphere sphere(this->getPosition(), dimension * 0.25f * this->scale_);
211                float left, right, top, bottom;
212                camera->projectSphere(sphere, &left, &top, &right, &bottom);//approximate maximum pixel count of billboard with a sphere
213               
214                Ogre::RenderWindow* window = GraphicsManager::getInstance().getRenderWindow();
215                float maxCount = (right - left) * (top - bottom) * window->getWidth() * window->getHeight() * 0.25f;
216                unsigned int pixelCount = this->getScene()->getRenderQueueListener()->getPixelCount();//get pixel count
217                float ratio = (maxCount < 0.0f) ? 0.0f : (1.0f * pixelCount / maxCount);//prevent underflow and division by zero
218                float borderRatio = 1.0f;
219                if (this->fadeOnViewBorder_)
220                {
221                    borderRatio = ((float) pointCount) / (((float) fadeResolution_) * ((float) fadeResolution_));//ratio for the border fade
222                }
223                //update alpha values of all billboards except the HOQ billboard
224                this->updateBillboardAlphas(std::min(1.0f, std::pow(std::min(ratio, borderRatio), this->fadeExponent_)));
225            }
226        }
227    }
228
229    void LensFlare::changedVisibility()
230    {
231     
232    }
233}
Note: See TracBrowser for help on using the repository browser.