Change Encyclo button name and macros icon
[ryzomcore.git] / nel / src / 3d / driver / direct3d / driver_direct3d_light.cpp
blobf68caab3ad4b315d71745915dc95308d5353cc19
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 "stddirect3d.h"
19 #include "nel/3d/vertex_buffer.h"
20 #include "nel/3d/light.h"
21 #include "nel/3d/index_buffer.h"
22 #include "nel/misc/rect.h"
23 #include "nel/3d/viewport.h"
24 #include "nel/3d/scissor.h"
25 #include "nel/3d/u_driver.h"
27 #include "driver_direct3d.h"
29 #ifdef DEBUG_NEW
30 #define new DEBUG_NEW
31 #endif
33 using namespace std;
34 using namespace NLMISC;
36 namespace NL3D
39 // ***************************************************************************
40 const D3DLIGHTTYPE RemapLightTypeNeL2D3D[3]=
42 D3DLIGHT_DIRECTIONAL, // CLight::DirectionalLight
43 D3DLIGHT_POINT, // CLight::PointLight
44 D3DLIGHT_SPOT, // CLight::SpotLight
48 // ***************************************************************************
49 void CDriverD3D::setLight (uint8 index, const CLight &light)
51 H_AUTO_D3D(CDriverD3D_setLight);
52 // bkup real light, for lightmap dynamic lighting purpose
53 if(index==0)
55 _UserLight0= light;
56 // because the D3D setup change, must dirt lightmap rendering
57 _LightMapDynamicLightDirty= true;
60 setLightInternal(index, light);
64 // ***************************************************************************
65 void CDriverD3D::enableLight (uint8 index, bool enable)
67 H_AUTO_D3D(CDriverD3D_enableLight);
68 // User call => set the User flag
69 if(index<MaxLight)
71 _UserLightEnable[index]= enable;
74 // enable the light in D3D
75 enableLightInternal(index, enable);
77 // because the D3D setup has changed, must dirt lightmap rendering
78 _LightMapDynamicLightDirty= true;
81 static const float sqrtFLT_MAX = (float) sqrtf(FLT_MAX);
83 // ***************************************************************************
84 void CDriverD3D::setLightInternal (uint8 index, const CLight &light)
86 H_AUTO_D3D(CDriverD3D_setLightInternal);
87 nlassert (_DeviceInterface);
88 if (index<MaxLight)
90 // Ref on the state
91 D3DLIGHT9 &lightRef = _LightCache[index].Light;
92 lightRef.Type = RemapLightTypeNeL2D3D[light.getMode ()];
93 NL_D3DCOLORVALUE_RGBA(lightRef.Diffuse, light.getDiffuse());
94 NL_D3DCOLORVALUE_RGBA(lightRef.Specular, light.getSpecular());
95 NL_D3DCOLORVALUE_RGBA(lightRef.Ambient, light.getAmbiant());
96 CVector vect = light.getPosition();
97 NL_D3DVECTOR_VECTOR (lightRef.Position, vect);
98 vect = light.getDirection();
99 NL_D3DVECTOR_VECTOR (lightRef.Direction, vect);
100 lightRef.Range = sqrtFLT_MAX;
101 lightRef.Falloff = 1;
102 lightRef.Attenuation0 = light.getConstantAttenuation();
103 lightRef.Attenuation1 = light.getLinearAttenuation();
104 lightRef.Attenuation2 = light.getQuadraticAttenuation();
105 if (lightRef.Type == D3DLIGHT_SPOT)
107 lightRef.Phi = light.getCutoff();
108 float divid=light.getExponent();
109 if (divid==0.f)
110 divid=0.0001f;
111 float hotSpotAngle = (float)acos(exp(log (0.9)/divid));
112 lightRef.Theta = hotSpotAngle;
114 else
116 lightRef.Phi = (float) NLMISC::Pi * 0.5f;
117 lightRef.Theta = (float) NLMISC::Pi * 0.25f;
120 // Settings touched
121 _LightCache[index].SettingsTouched = true;
123 // Touch only if enabled
124 if (_LightCache[index].Enabled)
125 touchRenderVariable (&_LightCache[index]);
129 // ***************************************************************************
130 void CDriverD3D::enableLightInternal (uint8 index, bool enable)
132 H_AUTO_D3D(CDriverD3D_enableLightInternal);
133 nlassert (_DeviceInterface);
134 if (index<MaxLight)
136 if (_LightCache[index].Enabled != enable)
138 _LightCache[index].Enabled = enable;
139 _LightCache[index].EnabledTouched = true;
140 touchRenderVariable (&_LightCache[index]);
145 // ***************************************************************************
146 uint CDriverD3D::getMaxLight () const
148 H_AUTO_D3D(CDriverD3D_getMaxLight);
149 return _MaxLight;
152 // ***************************************************************************
153 void CDriverD3D::setAmbientColor (CRGBA color)
155 H_AUTO_D3D(CDriverD3D_setAmbientColor);
156 setRenderState(D3DRS_AMBIENT, NL_D3DCOLOR_RGBA(color));
160 // ***************************************************************************
161 void CDriverD3D::setLightMapDynamicLight (bool enable, const CLight& light)
163 H_AUTO_D3D(CDriverD3D_setLightMapDynamicLight);
164 // just store, for future setup in lightmap material rendering
165 _LightMapDynamicLightEnabled= enable;
166 _LightMapDynamicLight= light;
167 _LightMapDynamicLightDirty= true;
171 // ***************************************************************************
172 void CDriverD3D::setupLightMapDynamicLighting(bool enable)
174 H_AUTO_D3D(CDriverD3D_setupLightMapDynamicLighting);
175 // start lightmap dynamic lighting
176 if(enable)
178 // disable all lights but the 0th.
179 for(uint i=1;i<_MaxLight;++i)
180 enableLightInternal(uint8(i), false);
182 // if the dynamic light is really enabled
183 if(_LightMapDynamicLightEnabled)
185 // then setup and enable
186 setLightInternal(0, _LightMapDynamicLight);
187 enableLightInternal(0, true);
189 // else just disable also the light 0
190 else
192 enableLightInternal(0, false);
195 // ok it has been setup
196 _LightMapDynamicLightDirty= false;
198 // restore old lighting
199 else
201 // restore the light 0
202 setLightInternal(0, _UserLight0);
204 // restore all standard light enable states
205 for(uint i=0;i<_MaxLight;++i)
206 enableLightInternal(uint8(i), _UserLightEnable[i]);
212 } // NL3D