Merge branch 'lua_versions' into main/rendor-staging
[ryzomcore.git] / snowballs2 / client / src / lens_flare.cpp
blobe9f308529567e1386a0ac95390d3e1d311c95d31
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 // Includes
21 #include <nel/misc/types_nl.h>
22 #include <nel/misc/vector.h>
23 #include <nel/misc/matrix.h>
25 #include <nel/3d/u_material.h>
26 #include <nel/3d/u_camera.h>
27 #include <nel/3d/u_driver.h>
28 #include <nel/3d/u_text_context.h>
29 #include <nel/3d/u_texture.h>
31 #include "camera.h"
32 #include "landscape.h"
33 #include "snowballs_client.h"
34 #include "mouse_listener.h"
37 // Namespaces
40 using namespace NLMISC;
41 using namespace NL3D;
42 using namespace std;
44 namespace SBCLIENT {
46 /// If axis segment is longer than this value then no lens flare is displayed
47 static const float _MaxLensFlareLenght = 0.4f;
50 // Functions
53 /**
54 * A lens-flare class
55 * \author Stephane Coutelas
56 * \author Nevrax France
57 * \date 2000
59 class CLensFlare
61 float _AlphaCoef;
63 /// flare
64 struct _CFlare
66 NL3D::UMaterial Material;
68 float Width;
69 float Height;
71 float Location;
73 float Scale;
75 _CFlare(NL3D::UTexture *texture, float width, float height, float location, float scale)
77 // -- -- nicely re-usable class, but why should it know about the snowballs specific driver global
78 Material = Driver->createMaterial ();
79 Material.initUnlit ();
80 Material.setTexture (texture);
81 Material.setBlendFunc (UMaterial::srcalpha, UMaterial::one);
82 Material.setBlend(true);
83 Material.setZFunc (UMaterial::always);
84 Material.setZWrite (false);
86 // quad dimension
87 Width = width;
88 Height = height;
90 // location on the lens-flare ray
91 Location = location;
93 // texture scale
94 Scale = scale;
97 ~_CFlare()
99 Driver->deleteMaterial(Material);
103 /// flares due to light
104 std::vector<_CFlare *> _Flares;
106 public:
108 /// constructor
109 CLensFlare()
111 _AlphaCoef = 1.0f;
114 ~CLensFlare()
116 for (std::vector<_CFlare *>::iterator it(_Flares.begin()), end(_Flares.end()); it != end; ++it)
117 delete (*it);
118 _Flares.clear();
121 /// add a flare to the flare list
122 void addFlare(NL3D::UTexture * texture, float width, float height, float location = 1.f, float scale = 1.f);
124 void setAlphaCoef(float coef)
126 _AlphaCoef = coef;
129 // -- -- random note: show actually shows and is used within update
130 /// lens flare display function
131 void show();
135 /*********************************************************\
136 addFlare()
137 \*********************************************************/
138 void CLensFlare::addFlare(UTexture * texture, float width, float height, float location, float scale)
140 _Flares.push_back(new _CFlare(texture, width, height, location, scale));
144 /*********************************************************\
145 show()
146 \*********************************************************/
147 void CLensFlare::show()
149 CMatrix mtx;
150 mtx.identity();
152 nlassert(Driver!=NULL && !Camera.empty());
154 Driver->setMatrixMode2D11 ();
156 // Determining axis "screen center - light" vector
157 CMatrix cameraMatrix = Camera.getMatrix();
158 cameraMatrix.invert();
159 CVector light = (-100000 * SunDirection);
160 light = cameraMatrix * light;
161 light = Camera.getFrustum().project(light);
163 CVector screenCenter(0.5f,0.5f,0);
164 CVector axis = light - screenCenter;
166 if(axis.norm()>_MaxLensFlareLenght)
168 return;
171 // rendering flares
172 vector<_CFlare *>::iterator itflr;
173 for(itflr = _Flares.begin(); itflr!=_Flares.end(); itflr++)
175 (*itflr)->Material.setColor(CRGBA(255,255,255,(uint8)(_AlphaCoef*255)));
177 CQuadUV quad;
179 float xCenterQuad = screenCenter.x + (*itflr)->Location * axis.x;
180 float yCenterQuad = screenCenter.y + (*itflr)->Location * axis.y;
182 float x,y;
185 x = xCenterQuad - (*itflr)->Width * (*itflr)->Scale / 2.f;
186 y = yCenterQuad - (*itflr)->Height * (*itflr)->Scale / 2.f;
187 quad.V0.set (x, y, 0);
189 x = xCenterQuad + (*itflr)->Width * (*itflr)->Scale / 2.f;
190 y = yCenterQuad - (*itflr)->Height * (*itflr)->Scale / 2.f;
191 quad.V1.set (x, y, 0);
193 x = xCenterQuad + (*itflr)->Width * (*itflr)->Scale / 2.f;
194 y = yCenterQuad + (*itflr)->Height * (*itflr)->Scale / 2.f;
195 quad.V2.set (x, y, 0);
197 x = xCenterQuad - (*itflr)->Width * (*itflr)->Scale / 2.f;
198 y = yCenterQuad + (*itflr)->Height * (*itflr)->Scale / 2.f;
199 quad.V3.set (x, y, 0);
201 quad.Uv0.U = 0.0f; quad.Uv0.V = 1.0f;
202 quad.Uv1.U = 1.0f; quad.Uv1.V = 1.0f;
203 quad.Uv2.U = 1.0f; quad.Uv2.V = 0.0f;
204 quad.Uv3.U = 0.0f; quad.Uv3.V = 0.0f;
206 Driver->drawQuad (quad, (*itflr)->Material);
210 static CLensFlare *LensFlare = NULL;
211 static UTextureFile *flareTexture1 = NULL;
212 static UTextureFile *flareTexture3 = NULL;
213 static UTextureFile *flareTexture4 = NULL;
214 static UTextureFile *flareTexture5 = NULL;
215 static UTextureFile *flareTexture6 = NULL;
216 static UTextureFile *flareTexture7 = NULL;
218 void initLensFlare ()
220 // -- -- getting this from a config file would be more re-usable
222 LensFlare = new CLensFlare ();
224 flareTexture1 = Driver->createTextureFile("flare01.tga");
225 flareTexture3 = Driver->createTextureFile("flare03.tga");
226 flareTexture4 = Driver->createTextureFile("flare04.tga");
227 flareTexture5 = Driver->createTextureFile("flare05.tga");
228 flareTexture6 = Driver->createTextureFile("flare06.tga");
229 flareTexture7 = Driver->createTextureFile("flare07.tga");
231 float w = 30/800.0f;
232 float h = 30/600.0f;
234 // shine
235 LensFlare->addFlare (flareTexture3, w, h, 1.f, 16.f);
237 LensFlare->addFlare (flareTexture1, w, h, 1.f, 6.f);
238 LensFlare->addFlare (flareTexture6, w, h, 1.3f, 1.2f);
239 LensFlare->addFlare (flareTexture7, w, h, 1.0f, 3.f);
240 LensFlare->addFlare (flareTexture6, w, h, 0.5f, 4.f);
241 LensFlare->addFlare (flareTexture5, w, h, 0.2f, 2.f);
242 LensFlare->addFlare (flareTexture7, w, h, 0.0f, 0.8f);
243 LensFlare->addFlare (flareTexture7, w, h, -0.25f, 2.f);
244 LensFlare->addFlare (flareTexture1, w, h, -0.4f, 1.f);
245 LensFlare->addFlare (flareTexture4, w, h, -1.0f, 12.f);
246 LensFlare->addFlare (flareTexture5, w, h, -0.6f, 6.f);
249 void updateLensFlare ()
251 // -- -- todo: see how much of this can be modified to depend on nel
252 // things only, and moved into the lensflare class
254 // vector to sun
255 //==============
256 CVector userLook = MouseListener->getViewDirection ();
258 CVector sunDirection = (-100000 * SunDirection);
260 // cosinus between the two previous vectors
261 //=========================================
262 float cosAngle = sunDirection*userLook/sunDirection.norm();
264 // alpha
265 //======
266 float alphaf;
267 if(cosAngle<0)
269 alphaf = 0;
271 else
273 alphaf = 255*(float)(pow(cosAngle,20));
276 // landscape's masking sun ?
277 //==========================
278 CMatrix camMatrix;
279 camMatrix = Camera.getMatrix();
280 camMatrix.setPos(CVector::Null);
281 camMatrix.invert();
282 CVector tmp = camMatrix * sunDirection;
283 tmp = Camera.getFrustum().project(tmp);
284 uint32 w,h;
285 Driver->getWindowSize(w,h);
286 float sunRadius = 24; // -- -- why 24
287 CRect rect((uint32)(tmp.x*w)-(uint32)sunRadius,(uint32)(tmp.y*h)-(uint32)sunRadius,2*(uint32)sunRadius,2*(uint32)sunRadius);
288 vector<float> zbuff;
289 Driver->getZBufferPart(zbuff, rect);
290 float view = 0.f;
291 float sum = 0;
292 sint i; // -- -- signed?
293 for(i=0; i<(sint)zbuff.size(); i++)
295 if(zbuff[i]>=0.99999f) sum ++;
297 view = sum/(sunRadius*2*sunRadius*2);
299 Driver->setMatrixMode2D11 ();
301 // quad for dazzle
302 //================
303 uint8 alpha = (uint8)(alphaf*view/2.0f);
304 if(alpha!=0)
306 Driver->drawQuad(0,0,1,1,CRGBA(255,255,255,alpha));
309 // Display lens-flare
310 LensFlare->setAlphaCoef( 1.f - (float)cos(alphaf*view*Pi/(2.f*255.f)) );
311 LensFlare->show();
314 void releaseLensFlare ()
316 delete LensFlare; LensFlare = NULL;
317 Driver->deleteTextureFile(flareTexture1); flareTexture1 = NULL;
318 Driver->deleteTextureFile(flareTexture3); flareTexture3 = NULL;
319 Driver->deleteTextureFile(flareTexture4); flareTexture4 = NULL;
320 Driver->deleteTextureFile(flareTexture5); flareTexture5 = NULL;
321 Driver->deleteTextureFile(flareTexture6); flareTexture6 = NULL;
322 Driver->deleteTextureFile(flareTexture7); flareTexture7 = NULL;
325 } /* namespace SBCLIENT */
327 /* end of file */