1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
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>
32 #include "landscape.h"
33 #include "snowballs_client.h"
34 #include "mouse_listener.h"
40 using namespace NLMISC
;
46 /// If axis segment is longer than this value then no lens flare is displayed
47 static const float _MaxLensFlareLenght
= 0.4f
;
55 * \author Stephane Coutelas
56 * \author Nevrax France
66 NL3D::UMaterial Material
;
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);
90 // location on the lens-flare ray
99 Driver
->deleteMaterial(Material
);
103 /// flares due to light
104 std::vector
<_CFlare
*> _Flares
;
116 for (std::vector
<_CFlare
*>::iterator
it(_Flares
.begin()), end(_Flares
.end()); it
!= end
; ++it
)
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
)
129 // -- -- random note: show actually shows and is used within update
130 /// lens flare display function
135 /*********************************************************\
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 /*********************************************************\
146 \*********************************************************/
147 void CLensFlare::show()
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
)
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)));
179 float xCenterQuad
= screenCenter
.x
+ (*itflr
)->Location
* axis
.x
;
180 float yCenterQuad
= screenCenter
.y
+ (*itflr
)->Location
* axis
.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");
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
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();
273 alphaf
= 255*(float)(pow(cosAngle
,20));
276 // landscape's masking sun ?
277 //==========================
279 camMatrix
= Camera
.getMatrix();
280 camMatrix
.setPos(CVector::Null
);
282 CVector tmp
= camMatrix
* sunDirection
;
283 tmp
= Camera
.getFrustum().project(tmp
);
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
);
289 Driver
->getZBufferPart(zbuff
, rect
);
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 ();
303 uint8 alpha
= (uint8
)(alphaf
*view
/2.0f
);
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
)) );
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 */