Merge branch 'ryzom/ark-features' into main/gingo-test
[ryzomcore.git] / nel / src / 3d / light.cpp
blobba887a44723a78330e897b3e6f6592ad642945e5
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"
19 #include "nel/3d/light.h"
21 using namespace NLMISC;
23 #ifdef DEBUG_NEW
24 #define new DEBUG_NEW
25 #endif
27 namespace NL3D
30 // ***************************************************************************
32 void CLight::setupDirectional (const CRGBA& ambiant, const CRGBA& diffuse, const CRGBA& specular, const CVector& direction,
33 float constant, float linear, float quadratic)
35 // Set the mode
36 setMode (DirectionalLight);
38 // Set the colors
39 setAmbiant (ambiant);
40 setDiffuse (diffuse);
41 setSpecular (specular);
43 // Set the direction
44 setDirection (direction);
46 // Set attenuation
47 setConstantAttenuation (constant);
48 setLinearAttenuation (linear);
49 setQuadraticAttenuation (quadratic);
51 // Dummy to avoid uninit data, and problems of cache
52 setPosition(CVector::Null);
53 setExponent(0.f);
54 setCutoff(0.f);
57 // ***************************************************************************
59 void CLight::setupPointLight (const CRGBA& ambiant, const CRGBA& diffuse, const CRGBA& specular, const CVector& position,
60 const CVector& direction, float constant, float linear, float quadratic)
62 // Set the mode
63 setMode (PointLight);
65 // Set the colors
66 setAmbiant (ambiant);
67 setDiffuse (diffuse);
68 setSpecular (specular);
70 // Set the position and direction
71 setPosition (position);
72 setDirection (direction);
74 // Set attenuation
75 setConstantAttenuation (constant);
76 setLinearAttenuation (linear);
77 setQuadraticAttenuation (quadratic);
79 // Dummy to avoid uninit data, and problems of cache
80 setExponent(0.f);
81 setCutoff(0.f);
84 // ***************************************************************************
86 void CLight::setupSpotLight (const CRGBA& ambiant, const CRGBA& diffuse, const CRGBA& specular, const CVector& position,
87 const CVector& direction, float exponent, float cutoff, float constant, float linear, float quadratic)
89 // Set the mode
90 setMode (SpotLight);
92 // Set the colors
93 setAmbiant (ambiant);
94 setDiffuse (diffuse);
95 setSpecular (specular);
97 // Set the position and direction
98 setPosition (position);
99 setDirection (direction);
101 // Set spotlight parameters
102 setExponent (exponent);
103 setCutoff (cutoff);
105 // Set attenuation
106 setConstantAttenuation (constant);
107 setLinearAttenuation (linear);
108 setQuadraticAttenuation (quadratic);
111 // ***************************************************************************
112 void CLight::setupAttenuation (float farAttenuationBegin, float farAttenuationEnd)
114 /* Yoyo: I changed this method because it did not work well for me
115 The most important in a light is its farAttenuationEnd (anything beyond should not be lighted)
116 The old compute had too smooth decrease, regarding this (at farAttenuationEnd, the light could be
117 attenuated by a factor of 0.7 (instead of 0) and slowly decreased).
120 // limit case
121 if(farAttenuationEnd<=0)
123 _ConstantAttenuation= 1000000;
124 _LinearAttenuation= 0;
125 _QuadraticAttenuation= 0;
127 else
129 // The following factors are "it feels good for farAttenuationBegin=0/farAttenuationEnd=1" factors.
130 // btw, at r=farAttenuationEnd=1, att= 1/11 ~= 0.
131 const float constant= 1.0f;
132 const float linear= 0.f;
133 const float quadratic= 10.0f;
136 With GL/D3D 'att=1/(c+l*r+q*r2)' formula, I think it is impossible to simulate correctly
137 farAttenuationBegin (very big decrase if for instance farAttenuationBegin is near farAttenuationEnd),
138 hence I simulate it very badly by multiplying the farAttenuationEnd by some factor
140 float factor= 1.f;
141 if(farAttenuationBegin/farAttenuationEnd>0.5f)
142 factor= 2.f;
143 else if(farAttenuationBegin>0)
144 factor= 1.f + 2*farAttenuationBegin/farAttenuationEnd;
145 farAttenuationEnd*= factor;
147 // scale according to farAttenuationEnd.
148 _ConstantAttenuation= constant;
149 _LinearAttenuation= linear/farAttenuationEnd;
150 _QuadraticAttenuation= quadratic/sqr(farAttenuationEnd);
154 // ***************************************************************************
156 void CLight::setupSpotExponent (float hotSpotAngle)
158 float divid=(float)log (cos (hotSpotAngle));
159 if (divid==0.f)
160 divid=0.0001f;
161 setExponent ((float)(log (0.9)/divid));
164 // ***************************************************************************
166 void CLight::setNoAttenuation ()
168 _ConstantAttenuation=1.f;
169 _QuadraticAttenuation=0.f;
170 _LinearAttenuation=0.f;
173 // ***************************************************************************
175 } // NL3D