1 /*---------------------------------------------------------------------------*
2   Project: NintendoWare
3   File   : gfx_SceneEnvironment.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 27615 $
14  *---------------------------------------------------------------------------*/
15 #ifndef NW_GFX_SCENEENVIRONMENT_H_
16 #define NW_GFX_SCENEENVIRONMENT_H_
17 
18 #include <nw/gfx/gfx_Camera.h>
19 #include <nw/gfx/gfx_Fog.h>
20 #include <nw/gfx/gfx_SceneEnvironmentSetting.h>
21 #include <nw/gfx/gfx_LightSet.h>
22 
23 namespace nw
24 {
25 namespace gfx
26 {
27 
28 class FragmentLight;
29 class VertexLight;
30 class AmbientLight;
31 class Fog;
32 class HemiSphereLight;
33 class Camera;
34 
35 //---------------------------------------------------------------------------
36 //! @brief        シーン環境を表すクラスです。
37 //!
38 //! RenderEnvironment は廃止され、SceneEnvironment に変更されました。
39 //---------------------------------------------------------------------------
40 class SceneEnvironment
41 {
42 public:
43 
44     //! @brief シーン環境への設定内容です。
45     struct Description
46     {
47         CameraArray cameras;
48         FogArray fogs;
49         LightSetArray lightSets;
50         VertexLightArray vertexLights;
51     };
52 
53     //! コンストラクタです。
SceneEnvironment(const Description & description)54     SceneEnvironment(const Description& description)
55         : m_AmbientLight(NULL),
56           m_HemiSphereLight(NULL),
57           m_VertexLights(description.vertexLights),
58           m_Fog(NULL),
59           m_Camera(NULL),
60           m_Cameras(description.cameras),
61           m_CameraIndex(-1),
62           m_Fogs(description.fogs),
63           m_LightSets(description.lightSets),
64           m_LightSetIndex(-1),
65           m_ActiveVertexLightCount(0),
66           m_ActiveFragmentLightCount(0),
67           m_FragmentLightsDirty(true),
68           m_AmbientLightDirty(true),
69           m_VertexLightsDirty(true),
70           m_HemiSphereLightDirty(true),
71           m_FogDirty(true)
72     {
73         m_FragmentLights.resize(m_FragmentLights.capacity());
74         m_VertexLights.resize(m_VertexLights.capacity());
75 
76         m_Cameras.resize(m_Cameras.capacity());
77         std::fill(m_Cameras.begin(), m_Cameras.end(), static_cast<Camera*>(NULL));
78 
79         m_Fogs.resize(m_Fogs.capacity());
80         std::fill(m_Fogs.begin(), m_Fogs.end(), static_cast<Fog*>(NULL));
81 
82         m_LightSets.resize(m_LightSets.capacity());
83         std::fill(m_LightSets.begin(), m_LightSets.end(), static_cast<LightSet*>(NULL));
84     }
85 
86     //----------------------------------------
87     //! @name シーン環境設定関連
88     //@{
89 
90     //! @brief シーン環境設定からシーン環境を適用します。
91     //!
92     //! @param[in] setting 適用するシーン環境設定です。
93     //!
94     void ApplyFrom(const SceneEnvironmentSetting& setting);
95 
96     //! @brief シーン環境をクリアします。
97     void ClearSettings();
98 
99     //! @brief フォグ配列にフォグを設定します。
100     //!
101     //! @param[in] index 設定するインデクスです。
102     //! @param[in] fog 設定するフォグです。
103     //!
SetFog(s32 index,Fog * fog)104     void SetFog(s32 index, Fog* fog)
105     {
106         NW_MINMAXLT_ASSERT(index, 0, m_Fogs.size());
107         m_Fogs[index] = fog;
108     }
109 
110     //! @brief フォグ配列からフォグを取得します。
111     //!
112     //! @param[in] index 取得するインデクスです。
113     //!
GetFog(s32 index)114     Fog* GetFog(s32 index)
115     {
116         NW_MINMAXLT_ASSERT(index, 0, m_Fogs.size());
117         return m_Fogs[index];
118     }
119 
120     //! @brief フォグ配列からフォグを取得します。
121     //!
122     //! @param[in] index 取得するインデクスです。
123     //!
GetFog(s32 index)124     const Fog* GetFog(s32 index) const
125     {
126         NW_MINMAXLT_ASSERT(index, 0, m_Fogs.size());
127         return m_Fogs[index];
128     }
129 
130     //! @brief カメラ配列にカメラを設定します。
131     //!
132     //! @param[in] index 設定するインデックスです。
133     //! @param[in] camera 設定するカメラです。
134     //!
SetCamera(int index,Camera * camera)135     void SetCamera(int index, Camera* camera)
136     {
137         NW_MINMAXLT_ASSERT(index, 0, m_Cameras.size());
138         m_Cameras[index] = camera;
139     }
140 
141     //! @brief カメラ配列からカメラを取得します。
142     //!
143     //! @param[in] index 取得するカメラのインデックスです。
144     //!
GetCamera(int index)145     Camera* GetCamera(int index)
146     {
147         NW_MINMAXLT_ASSERT(index, 0, m_Cameras.size());
148         return m_Cameras[index];
149     }
150 
151     //! @brief カメラ配列からカメラを取得します。
152     //!
153     //! @param[in] index 取得するカメラのインデックスです。
154     //!
GetCamera(int index)155     const Camera* GetCamera(int index) const
156     {
157         NW_MINMAXLT_ASSERT(index, 0, m_Cameras.size());
158         return m_Cameras[index];
159     }
160 
161     //! @brief ライトセット配列にライトセットを設定します。
162     //!
163     //! @param[in] index 設定するインデックスです。
164     //! @param[in] lightSet 設定するカメラです。
165     //!
SetLightSet(int index,LightSet * lightSet)166     void SetLightSet(int index, LightSet* lightSet)
167     {
168         NW_MINMAXLT_ASSERT(index, 0, m_LightSets.size());
169         m_LightSets[index] = lightSet;
170     }
171 
172     //! @brief ライトセット配列からライトセットを取得します。
173     //!
174     //! @param[in] index 取得するライトセットのインデックスです。
175     //!
GetLightSet(int index)176     LightSet* GetLightSet(int index)
177     {
178         NW_MINMAXLT_ASSERT(index, 0, m_LightSets.size());
179         return m_LightSets[index];
180     }
181 
182     //! @brief ライトセットの配列からライトセットを取得します。
183     //!
184     //! @param[in] index 取得するライトセットのインデックスです。
185     //!
GetLightSet(int index)186     const LightSet* GetLightSet(int index) const
187     {
188         NW_MINMAXLT_ASSERT(index, 0, m_LightSets.size());
189         return m_LightSets[index];
190     }
191 
192     //@}
193 
194     //----------------------------------------
195     //! @name ライト関連
196     //@{
197 
198     //! @brief        フラグメントライトを設定します。
199     //!
200     //! 全種類の光源はディレクションの方向をライトの向きとするように
201     //! しています。
202     //! 平行光源ではポジションの値は参照しません。
203     //!
204     //! OpenGL では、平行光源はポジションのパラメータを
205     //! 逆向きにしたベクトルをディレクションとして扱いますが、
206     //! ディレクションのパラメータそのまま扱うようにしてあります。
207     //!
208     //! @param[in]    light 設定するフラグメントライトです。
209     //!
SetFragmentLight(FragmentLight * light)210     void SetFragmentLight(FragmentLight* light)
211     {
212         if (this->m_ActiveFragmentLightCount == LIGHT_COUNT)
213         {
214             return;
215         }
216 
217         m_FragmentLights[m_ActiveFragmentLightCount] = (light);
218         ++m_ActiveFragmentLightCount;
219     }
220 
221     //! @brief        フラグメントライトの数を取得します。
222     //!
GetFragmentLightCount()223     s32 GetFragmentLightCount() const
224     {
225         return this->m_ActiveFragmentLightCount;
226     }
227 
228     //! @brief        設定されているフラグメントライトを取得します。
229     //!
230     //! @param[in]    index   取得するフラグメントライトのインデクスです。
231     //!
232     //! @return       フラグメントライトのポインタを返します。
GetFragmentLight(int index)233     const FragmentLight* GetFragmentLight(int index) const
234     {
235         NW_MINMAXLT_ASSERT(index, 0, this->m_ActiveFragmentLightCount);
236         return this->m_FragmentLights[ index ];
237     }
238 
239     //! @brief        頂点ライトを設定します。
240     //!
241     //! 全種類の光源はディレクションの方向をライトの向きとするように
242     //! しています。
243     //! 平行光源ではポジションの値は参照しません。
244     //!
245     //! OpenGL では、平行光源はポジションのパラメータを
246     //! 逆向きにしたベクトルをディレクションとして扱いますが、
247     //! ディレクションのパラメータそのまま扱うようにしてあります。
248     //!
249     //! @param[in]    light 設定する頂点ライトです。
250     //!
SetVertexLight(VertexLight * light)251     void SetVertexLight(VertexLight* light)
252     {
253         if (m_ActiveVertexLightCount == m_VertexLights.capacity())
254         {
255             return;
256         }
257 
258         this->m_VertexLights[m_ActiveVertexLightCount] = light;
259         ++m_ActiveVertexLightCount;
260     }
261 
262     //! @brief        設定されている頂点ライトを取得します。
263     //!
264     //! @param[in]    index   取得する頂点ライトのインデクスです。
265     //!
266     //! @return       頂点ライトのポインタを返します。
GetVertexLight(int index)267     const VertexLight* GetVertexLight(int index) const
268     {
269         NW_MINMAXLT_ASSERT(index, 0, this->m_ActiveVertexLightCount);
270         return this->m_VertexLights[ index ];
271     }
272 
273     //! @brief        頂点ライトの数を取得します。
274     //!
GetVertexLightCount()275     s32 GetVertexLightCount() const
276     {
277         return this->m_ActiveVertexLightCount;
278     }
279 
280     //! @brief        アンビエントライトを設定します。
281     //!
282     //! @param[in]    ambientLight 設定するアンビエントライトです。
283     //!
SetAmbientLight(AmbientLight * ambientLight)284     void SetAmbientLight(AmbientLight* ambientLight)
285     {
286         this->m_AmbientLight = ambientLight;
287     }
288 
289     //! @brief        設定されているアンビエントライトを取得します。
290     //!
291     //! @return       アンビエントライトのポインタを返します。
GetAmbientLight()292     const AmbientLight* GetAmbientLight() const
293     {
294         return this->m_AmbientLight;
295     }
296 
297     //! @brief        半球ライトを設定します。
298     //!
299     //! @param[in]    hemiSphereLight 設定する半球ライトです。
300     //!
SetHemiSphereLight(HemiSphereLight * hemiSphereLight)301     void SetHemiSphereLight(HemiSphereLight* hemiSphereLight)
302     {
303         this->m_HemiSphereLight = hemiSphereLight;
304     }
305 
306     //! @brief        半球ライトを取得します。
307     //!
308     //! @return       半球ライトです。
309     //!
GetHemiSphereLight()310     const HemiSphereLight* GetHemiSphereLight() const
311     {
312         return this->m_HemiSphereLight;
313     }
314 
315 
316     //! @brief        有効なライトセットを設定します。
317     //!
318     //! @return       ライトセットのインデクスです。
319     //!
320     void SetActiveLightSet(int index);
321 
322     //@}
323 
324     //----------------------------------------
325     //! @name フォグ関連
326     //@{
327 
328     //! @brief        インデックスを指定してフォグを有効にします。
329     //!
330     //! @param[in]    index 設定するフォグのインデックス番号です。
331     //!
SetActiveFog(int index)332     void SetActiveFog(int index)
333     {
334         NW_MINMAXLT_ASSERT(index, 0, m_Fogs.size());
335 
336         Fog* fog = m_Fogs[index];
337 
338         if (this->m_Fog != fog)
339         {
340             this->m_Fog = fog;
341             this->m_FogDirty = true;
342         }
343     }
344 
345     //! @brief        有効なフォグを取得します。
346     //!
347     //! @return       フォグです。
348     //!
GetActiveFog()349     Fog* GetActiveFog()
350     {
351         return this->m_Fog;
352     }
353 
354     //! @brief        有効なフォグを取得します。
355     //!
356     //! @return       フォグです。
357     //!
GetActiveFog()358     const Fog* GetActiveFog() const
359     {
360         return this->m_Fog;
361     }
362 
363     //@}
364 
365     //----------------------------------------
366     //! @name フラグ関連
367     //@{
368 
369     //! @brief        フラグメントライトを設定しなおすかどうかを表すフラグを取得します。
370     //!               暫定的な機能となります。
IsFragmentLightsDirty()371     bool IsFragmentLightsDirty() const
372     {
373         return m_FragmentLightsDirty;
374     }
375 
376     //! @brief        フラグメントライトを設定しなおすかどうかを表すフラグを設定します。
377     //!               暫定的な機能となります。
SetFragmentLightsDirty(bool fragmentLightsDirty)378     void SetFragmentLightsDirty(bool fragmentLightsDirty)
379     {
380         m_FragmentLightsDirty = fragmentLightsDirty;
381     }
382 
383     //! @brief        アンビエントライトを設定しなおすかどうかを表すフラグを取得します。
384     //!               暫定的な機能となります。
IsAmbientLightDirty()385     bool IsAmbientLightDirty() const
386     {
387         return m_AmbientLightDirty;
388     }
389 
390     //! @brief        アンビエントライトを設定しなおすかどうかを表すフラグを設定します。
391     //!               暫定的な機能となります。
SetAmbientLightDirty(bool ambientLightDirty)392     void SetAmbientLightDirty(bool ambientLightDirty)
393     {
394         m_AmbientLightDirty = ambientLightDirty;
395     }
396 
397     //! @brief        頂点ライトを設定しなおすかどうかを表すフラグを取得します。
398     //!               暫定的な機能となります。
IsVertexLightsDirty()399     bool IsVertexLightsDirty() const
400     {
401 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
402         return m_VertexLightsDirty;
403 #else
404         return false;
405 #endif
406     }
407 
408     //! @brief        頂点ライトを設定しなおすかどうかを表すフラグを設定します。
409     //!               暫定的な機能となります。
SetVertexLightsDirty(bool vertexLightsDirty)410     void SetVertexLightsDirty(bool vertexLightsDirty)
411     {
412         m_VertexLightsDirty = vertexLightsDirty;
413     }
414 
415     //! @brief        半球ライトを設定しなおすかどうかを表すフラグを取得します。
416     //!               暫定的な機能となります。
IsHemiSphereLightDirty()417     bool IsHemiSphereLightDirty() const
418     {
419         return m_HemiSphereLightDirty;
420     }
421 
422     //! @brief        半球ライトを設定しなおすかどうかを表すフラグを設定します。
423     //!               暫定的な機能となります。
SetHemiSphereLightDirty(bool hemiSphereLightDirty)424     void SetHemiSphereLightDirty(bool hemiSphereLightDirty)
425     {
426         m_HemiSphereLightDirty = hemiSphereLightDirty;
427     }
428 
429     //! @brief        フォグを設定しなおすかどうかを表すフラグを取得します。
430     //!               暫定的な機能となります。
IsFogDirty()431     bool IsFogDirty() const
432     {
433         return m_FogDirty;
434     }
435 
436     //! @brief        フォグを設定しなおすかどうかを表すフラグを設定します。
437     //!               暫定的な機能となります。
SetFogDirty(bool fogDirty)438     void SetFogDirty(bool fogDirty)
439     {
440         m_FogDirty = fogDirty;
441     }
442 
443     //! @brief        ライトやフォグを設定しなおすかどうかを表すフラグを設定します。
444     //!               暫定的な機能となります。
SetAllFlagsDirty(bool flagsDirty)445     void SetAllFlagsDirty(bool flagsDirty)
446     {
447         m_FogDirty = flagsDirty;
448         m_AmbientLightDirty = flagsDirty;
449         m_FragmentLightsDirty = flagsDirty;
450 
451 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
452         m_VertexLightsDirty = flagsDirty;
453 #endif
454         m_HemiSphereLightDirty = flagsDirty;
455     }
456 
457     //@}
458 
459     //----------------------------------------
460     //! @name ステート関連
461     //@{
462 
463     //! @brief        全てのステートをリセットします。
464     void Reset();
465 
466     //! @brief        フラグメントライトのステートをリセットします。
467     void ResetFragmentLights();
468 
469     //! @brief        頂点ライトのステートをリセットします。
470     void ResetVertexLights();
471 
472     //! @brief        半球ライトのステートをリセットします。
473     void ResetHemiSphereLight();
474 
475     //! @brief        アンビエントライトのステートをリセットします。
476     void ResetAmbientLight();
477 
478     //! @brief        フォグのステートをリセットします。
479     void ResetFog();
480 
481     //! @brief        ライトセットのステートをリセットします。
482     void ResetLightSet();
483 
484     //@}
485 
486 private:
487     AmbientLight* m_AmbientLight;
488     HemiSphereLight* m_HemiSphereLight;
489     VertexLightArray m_VertexLights;
490     FixedFragmentLightArray m_FragmentLights;
491     Fog* m_Fog;
492     Camera* m_Camera;
493     CameraArray m_Cameras;
494     s32 m_CameraIndex;
495     FogArray m_Fogs;
496     LightSetArray m_LightSets;
497 
498     s32 m_LightSetIndex;
499     s32 m_ActiveVertexLightCount;
500     s32 m_ActiveFragmentLightCount;
501 
502     bool m_FragmentLightsDirty;
503     bool m_AmbientLightDirty;
504     bool m_VertexLightsDirty;
505     bool m_HemiSphereLightDirty;
506     bool m_FogDirty;
507 
508     friend class RenderContext;
509 };
510 
511 //! 互換性のための定義です。
512 typedef SceneEnvironment RenderEnvironment;
513 
514 } // namespace gfx
515 } // namespace nw
516 
517 #endif // NW_GFX_SCENEENVIRONMENT_H_
518 
519