1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_Fog.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: 23256 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NW_GFX_FOG_H_
17 #define NW_GFX_FOG_H_
18 
19 #include <nw/gfx/gfx_TransformNode.h>
20 #include <nw/gfx/res/gfx_ResFog.h>
21 
22 #include <nw/ut/ut_MovePtr.h>
23 #include <functional>
24 
25 namespace nw
26 {
27 namespace gfx
28 {
29 
30 class Camera;
31 
32 //---------------------------------------------------------------------------
33 //! @brief        フォグを表すクラスです。
34 //---------------------------------------------------------------------------
35 class Fog : public TransformNode
36 {
37 private:
38     NW_DISALLOW_COPY_AND_ASSIGN(Fog);
39 
40     #define NW_FOG_TABLE_COMMAND_NUM    (132)   // idex(2) + table128(129) + terminate(1)
41     #define NW_FOG_TABLE_COMMAND_SIZE   (NW_FOG_TABLE_COMMAND_NUM * 4)
42 
43 public:
44     NW_UT_RUNTIME_TYPEINFO;
45 
46     //! @brief 設定内容です。
47     struct Description : public TransformNode::Description
48     {
49         //! @brief コンストラクタです。
DescriptionDescription50         Description(){}
51     };
52 
53     //---------------------------------------------------------------------------
54     //! @brief フォグを更新するための関数オブジェクトです。
55     //---------------------------------------------------------------------------
56     struct UpdateFunctor
57     {
UpdateFunctorUpdateFunctor58         UpdateFunctor(Camera* camera) : camera(camera) {}
59 
operatorUpdateFunctor60         void operator() (Fog* fog)
61         {
62             if (fog != NULL)
63             {
64                 fog->Update(camera);
65             }
66         }
67 
68         Camera* camera;
69     };
70 
71     //----------------------------------------
72     //! @name 作成/破棄
73     //@{
74 
75     //! フォグを動的に構築するためのクラスです。
76     //!
77     //! IsFixedSizeMemory の初期値は true です。false に変更すると、各種最大数の設定は無視されます。
78     class DynamicBuilder
79     {
80     public:
81         //! コンストラクタです。
DynamicBuilder()82         DynamicBuilder() {}
83         //! デストラクタです。
~DynamicBuilder()84         ~DynamicBuilder() {}
85 
86         //! @brief 生成時以外にもメモリを確保するかどうかのフラグを設定します。
87         //!
88         //!        true を指定すると、生成時のみ固定サイズのメモリ確保を行います。
89         //!
90         //!        false を指定すると、生成時以外にも必要に応じて動的にメモリ確保が行われます。
IsFixedSizeMemory(bool isFixedSizeMemory)91         DynamicBuilder& IsFixedSizeMemory(bool isFixedSizeMemory)
92         {
93             m_Description.isFixedSizeMemory = isFixedSizeMemory;
94             return *this;
95         }
96 
97         //! 子の最大数を設定します。
MaxChildren(int maxChildren)98         DynamicBuilder& MaxChildren(int maxChildren)
99         {
100             m_Description.maxChildren = maxChildren;
101             return *this;
102         }
103 
104         //! 管理できるコールバックの最大数を設定します。
MaxCallbacks(int maxCallbacks)105         DynamicBuilder& MaxCallbacks(int maxCallbacks)
106         {
107             m_Description.maxCallbacks = maxCallbacks;
108             return *this;
109         }
110 
111         //! @brief        フォグを生成します。
112         //!
113         //! @param[in]    allocator アロケータです。
114         //!
115         //! @return       生成したフォグを返します。
116         //!
117         Fog* Create(os::IAllocator* allocator);
118 
119     private:
120         Fog::Description m_Description;
121     };
122 
123     //! @brief        フォグを生成します。
124     //!
125     //! @param[in]    parent 親のノードです。
126     //! @param[in]    resource リソースです。
127     //! @param[in]    description 設定内容です。
128     //! @param[in]    allocator アロケータです。
129     //!
130     //! @return       生成されたフォグです。
131     //!
132     static Fog* Create(
133         SceneNode* parent,
134         ResSceneObject resource,
135         const Fog::Description& description,
136         os::IAllocator* allocator);
137 
138     //@}
139 
140     //----------------------------------------
141     //! @name 参照テーブル
142     //@{
143 
144     //! @brief フォグの参照テーブルを更新します。
145     //!
146     //! @param[in] camera カメラです。
147     //!
148     void Update(const Camera* camera);
149 
150     //@}
151 
152     //----------------------------------------
153     //! @name シーンツリー
154     //@{
155 
156     //! @brief        ビジターを受け付けます。
157     //!
158     //! @param[in]    visitor ビジターです。
159     //!
160     virtual void Accept(ISceneVisitor* visitor);
161 
162     //@}
163 
164     //----------------------------------------
165     //! @name リソース
166     //@{
167 
168     //! フォグのリソースを取得します。
GetResFog()169     ResFog GetResFog()
170     {
171         return ResStaticCast<ResFog>(this->GetResSceneObject());
172     }
173 
174     //! フォグのリソースを取得します。
GetResFog()175     const ResFog GetResFog() const
176     {
177         return ResStaticCast<ResFog>(this->GetResSceneObject());
178     }
179 
180     //@}
181 
182 protected:
183     struct ResFogDataDestroyer : public std::unary_function<ResFogData*, void>
184     {
m_AllocatorResFogDataDestroyer185         ResFogDataDestroyer(os::IAllocator* allocator = 0) : m_Allocator(allocator)
186         {}
operatorResFogDataDestroyer187         result_type operator()(argument_type data)
188         {
189             DestroyResFog(m_Allocator, data);
190         }
191 
192         os::IAllocator* m_Allocator;
193     };
194 
195     struct ResFogUpdaterDataDestroyer : public std::unary_function<ResFogUpdaterData*, void>
196     {
m_AllocatorResFogUpdaterDataDestroyer197         ResFogUpdaterDataDestroyer(os::IAllocator* allocator = 0) : m_Allocator(allocator)
198         {}
operatorResFogUpdaterDataDestroyer199         result_type operator()(argument_type data)
200         {
201             DestroyResFogUpdater(m_Allocator, data);
202         }
203 
204         os::IAllocator* m_Allocator;
205     };
206 
207     //! 動的生成したライトリソースを破棄するための MovePtr の定義です。
208     typedef ut::MovePtr<ResFogData, ResFogDataDestroyer> ResPtr;
209     typedef ut::MovePtr<ResFogUpdaterData, ResFogUpdaterDataDestroyer> ResUpdaterPtr;
210 
211     //----------------------------------------
212     //! @name コンストラクタ/デストラクタ
213     //@{
214 
215     //! コンストラクタです。
Fog(os::IAllocator * allocator,ResFog resObj,const Fog::Description & description)216     Fog(
217         os::IAllocator* allocator,
218         ResFog resObj,
219         const Fog::Description& description)
220      : TransformNode(
221         allocator,
222         resObj,
223         description),
224         m_Near(0.0f),
225         m_Far(0.0f),
226         m_WScale(0.0f)
227     {}
228 
229     //! コンストラクタです。
Fog(os::IAllocator * allocator,ResPtr resource,const Fog::Description & description)230     Fog(
231         os::IAllocator* allocator,
232         ResPtr resource,
233         const Fog::Description& description)
234     : TransformNode(
235         allocator,
236         ResFog(resource.Get()),
237         description),
238       m_Resource(resource),
239       m_Near(0.0f),
240       m_Far(0.0f),
241       m_WScale(0.0f)
242     {}
243 
244     //! デストラクタです。
~Fog()245     virtual ~Fog() {}
246 
247     //@}
248 
249 private:
250     virtual Result Initialize(os::IAllocator* allocator);
251 
252     //---------------------------------------------------------------------------
253     //! @brief        ResFogData のリソースを生成します。
254     //!
255     //! @param[in]    allocator   リソース用のメモリを確保するアロケータです。
256     //! @param[in]    name        リソースにつける名前へのポインタです。名前が必要ない場合には NULL を指定してください。
257     //!
258     //! @return       ResFogData へのポインタです。
259     //---------------------------------------------------------------------------
260     static ResFogData*    CreateResFog(os::IAllocator* allocator, const char* name = NULL);
261 
262     //---------------------------------------------------------------------------
263     //! @brief        ResFogData のリソースを破棄します。
264     //!
265     //! @param[in]    allocator        リソース用のメモリを開放するアロケータです。
266     //! @param[in]    resFog ResFogData へのポインタです。
267     //---------------------------------------------------------------------------
268     static void DestroyResFog(os::IAllocator* allocator, ResFogData* resFog);
269 
270     //---------------------------------------------------------------------------
271     //! @brief        ResFogUpdaterData のリソースを生成します。
272     //!
273     //! @param[in]    allocator   リソース用のメモリを確保するアロケータです。
274     //!
275     //! @return       ResFogUpdaterData へのポインタです。
276     //---------------------------------------------------------------------------
277     static ResFogUpdaterData*    CreateResFogUpdater(os::IAllocator* allocator);
278 
279     //---------------------------------------------------------------------------
280     //! @brief        ResFogData のリソースを破棄します。
281     //!
282     //! @param[in]    allocator        リソース用のメモリを開放するアロケータです。
283     //! @param[in]    resFogUpdater ResFogUpdaterData へのポインタです。
284     //---------------------------------------------------------------------------
285     static void DestroyResFogUpdater(os::IAllocator* allocator, ResFogUpdaterData* resFogUpdater);
286 
287     void SetupFogSampler(
288         ResImageLookupTable fogSampler,
289         ResFogUpdater fogUpdater,
290         const math::MTX44& inverseProjectionMatrix);
291 
292     ResPtr m_Resource;
293     ResUpdaterPtr m_UpdaterCache;
294     f32 m_Near;
295     f32 m_Far;
296     f32 m_WScale;
297     static const float FOG_DENSITY;
298     static const ResFogUpdater::FogUpdaterType FOG_UPDATER_TYPE;
299     static const float FOG_MAX_DEPTH;
300     static const float FOG_MIN_DEPTH;
301 };
302 
303 } // namespace gfx
304 } // namespace nw
305 
306 #endif // NW_GFX_FOG_H_
307