Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / 3d / heat_haze.cpp
blob03ea4dc066f22d9802912fdfdf7e3670d4bcf352
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/>.
17 #include "std3d.h"
20 #include "nel/3d/heat_haze.h"
21 #include "nel/3d/scene.h"
22 #include "nel/3d/deform_2d.h"
23 #include "nel/misc/vector_2f.h"
25 #ifdef DEBUG_NEW
26 #define new DEBUG_NEW
27 #endif
29 namespace NL3D
33 struct CSinWave : public CDeform2d::IPerturbUV
35 virtual ~CSinWave() {}
36 float Phase;
37 virtual void perturbUV(float x, float y, float &du, float &dv) const
39 du = 0.01f * sinf(25.f * y + Phase);
40 dv = 0.05f * cosf(19.3f * x + Phase);
42 } _SinWave;
47 void CHeatHaze::performHeatHaze(uint width, uint height, CScene &s, IDriver *drv)
49 NLMISC::CMatrix m = s.getCam()->getMatrix();
50 NLMISC::CMatrix im = m.inverted();
52 // compute the shape of the horizon
54 // first we compute the direction of the world up vector in the viewer basis.
55 NLMISC::CVector up = im * NLMISC::CVector::K;
56 // project onto the I and K vectors
57 float upNorm = (up.x * up.x + up.z * up.z);
59 const float threshold = 10E-4f;
61 if (upNorm < threshold) return; // the viewer is looking above or below himlself
63 // Compute the right vector. This is done by intersecting the horizon plane with a near plane.
64 // to do this, we transform the horizon plane into the view basis.This may be optimized, but is not critical.
66 NLMISC::CPlane h;
67 h.make(NLMISC::CVector::K, NLMISC::CVector::Null);
69 h = h * m; // note : this multiply by the transposition of m
71 // intersect with near plane : we got y = 0, which gives us, as a right vector :
72 // if c is not 0, we got : x = 1 and z = (-a - d) / c as a working solution.
73 // Else we got x = (- d - c )/ a and z = 1
76 NLMISC::CVector right;
78 if (fabsf(h.c) > threshold)
80 right.set(1, 0, (h.a + h.d) / - h.c );
82 else
84 right.set( (h.d + h.c) / h.a, 0, 1);
87 right.normalize();
89 // now, find a point on screen that lay on the horizon line
90 static std::vector<NLMISC::CVector2f> poly(4);
94 const sint xCenter = width >> 1;
95 const sint yCenter = height >> 1;
97 const float horizonHeight = (float) (height >> 2);
98 const float horizonWidth = (float) (width >> 2);
100 NLMISC::CVector tmp ;
102 tmp = horizonWidth * right + horizonHeight * up;
103 poly[0] = NLMISC::CVector2f(xCenter + tmp.x, yCenter + tmp.z) ;
104 tmp = horizonWidth * right - horizonHeight * up;
105 poly[1] = NLMISC::CVector2f(xCenter + tmp.x, yCenter + tmp.z) ;
106 tmp = - horizonWidth * right - horizonHeight * up;
107 poly[2] = NLMISC::CVector2f(xCenter + tmp.x, yCenter + tmp.z);
108 tmp = - horizonWidth * right + horizonHeight * up;
109 poly[3] = NLMISC::CVector2f(xCenter + tmp.x, yCenter + tmp.z);
112 CDeform2d::doDeform(poly, drv, &_SinWave);
119 } // NL3D