1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_UserRenderNode.h
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_GFX_USERRENDERNODE_H_
19 #define NW_GFX_USERRENDERNODE_H_
20 
21 #include <nw/gfx/gfx_TransformNode.h>
22 
23 #include <nw/gfx/gfx_UserRenderCommand.h>
24 
25 namespace nw
26 {
27 namespace gfx
28 {
29 
30 //---------------------------------------------------------------------------
31 //! @brief        ユーザ定義の描画ノードのクラスです。
32 //---------------------------------------------------------------------------
33 class UserRenderNode : public TransformNode
34 {
35 private:
36     NW_DISALLOW_COPY_AND_ASSIGN(UserRenderNode);
37 
38 public:
39     NW_UT_RUNTIME_TYPEINFO;
40 
41     //! @brief 設定内容です。
42     struct Description : public TransformNode::Description
43     {
44         gfx::ResMaterial::TranslucencyKind translucencyKind; //!< 描画順の種類
45         u8 priority; //!< 描画優先度
46         u8 layerId;  //!< 描画要素のソート時に最優先に区分される ID
47         UserRenderCommand* userRenderCommand; //!< レンダーコマンドへのポインタ
48 
49         //! @brief コンストラクタです。
DescriptionDescription50         Description() : translucencyKind(nw::gfx::ResMaterial::TRANSLUCENCY_KIND_OPAQUE), priority(0), layerId(0), userRenderCommand(NULL) {}
51     };
52 
53     //----------------------------------------
54     //! @name 作成/破棄
55     //@{
56 
57     //! @brief ユーザ定義の描画ノードを動的に構築するためのクラスです。
58     //!
59     //! IsFixedSizeMemory の初期値は true です。false に変更すると、各種最大数の設定は無視されます。
60     class DynamicBuilder
61     {
62     public:
63         //! @brief コンストラクタです。
DynamicBuilder()64         DynamicBuilder() {}
65         //! @brief デストラクタです。
~DynamicBuilder()66         ~DynamicBuilder() {}
67 
68         //! @brief 生成時以外にもメモリを確保するかどうかのフラグを設定します。
69         //!
70         //!        true を指定すると、生成時のみ固定サイズのメモリ確保を行います。
71         //!
72         //!        false を指定すると、生成時以外にも必要に応じて動的にメモリ確保が行われます。
IsFixedSizeMemory(bool isFixedSizeMemory)73         DynamicBuilder& IsFixedSizeMemory(bool isFixedSizeMemory)
74         {
75             m_Description.isFixedSizeMemory = isFixedSizeMemory;
76             return *this;
77         }
78 
79         //! @brief 子の最大数を設定します。
MaxChildren(int maxChildren)80         DynamicBuilder& MaxChildren(int maxChildren)
81         {
82             m_Description.maxChildren = maxChildren;
83             return *this;
84         }
85 
86         //! @brief 管理できるコールバックの最大数を設定します。
MaxCallbacks(int maxCallbacks)87         DynamicBuilder& MaxCallbacks(int maxCallbacks)
88         {
89             m_Description.maxCallbacks = maxCallbacks;
90             return *this;
91         }
92 
93         //! @brief        ユーザ定義の描画ノードを生成します。
94         //!
95         //! @param[in]    allocator アロケータです。
96         //!
97         //! @return       生成したユーザ定義の描画ノードを返します。
98         //!
99         UserRenderNode* Create(os::IAllocator* allocator);
100 
101         //! @brief 生成時に必要なメモリサイズを取得します。
102         //!
103         //! メモリサイズは Builder の設定によって変化します。
104         //! すべての設定が終わった後にこの関数を呼び出してください。
105         //!
106         //! @param[in] alignment 計算に用いるアライメントです。2 のべき乗である必要があります。
107         size_t GetMemorySize(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) const
108         {
109             os::MemorySizeCalculator size(alignment);
110 
111             size += sizeof(UserRenderNode);
112 
113             GetMemorySizeForInitialize(&size, m_Description);
114 
115             return size.GetSizeWithPadding(alignment);
116         }
117 
118     private:
119         UserRenderNode::Description m_Description;
120     };
121 
122     //! @brief        生成時に必要なメモリサイズを取得します。
123     //!
124     //! @param[in]    description 設定内容です。
125     //! @param[in] alignment 計算に用いるアライメントです。2 のべき乗である必要があります。
126     static size_t GetMemorySize(
127         Description description,
128         size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT)
129     {
130         os::MemorySizeCalculator size(alignment);
131 
132         GetMemorySizeInternal(&size, description);
133 
134         return size.GetSizeWithPadding(alignment);
135     }
136 
137     //! @details :private
GetMemorySizeInternal(os::MemorySizeCalculator * pSize,Description description)138     static void GetMemorySizeInternal(
139         os::MemorySizeCalculator* pSize,
140         Description description)
141     {
142         os::MemorySizeCalculator& size = *pSize;
143 
144         size += sizeof(UserRenderNode);
145         GetMemorySizeForInitialize(pSize, description);
146     }
147 
148     //@}
149 
150     //----------------------------------------
151     //! @name 描画の設定
152     //@{
153 
154     //! @brief      描画順の種類を設定します。
SetTranslucencyKind(const gfx::ResMaterial::TranslucencyKind translucencyKind)155     void SetTranslucencyKind(const gfx::ResMaterial::TranslucencyKind translucencyKind)
156     {
157         m_TranslucencyKind = translucencyKind;
158     }
159 
160     //! @brief      描画順の種類を取得します。
161     //
162     //! @return     描画順の種類です。
GetTranslucencyKind()163     gfx::ResMaterial::TranslucencyKind GetTranslucencyKind() const
164     {
165         return m_TranslucencyKind;
166     }
167 
168     //! @brief      描画優先度を設定します。
SetPriority(const u8 priority)169     void SetPriority(const u8 priority)
170     {
171         m_Priority = priority;
172     }
173 
174     //! @brief      描画優先度を取得します。
175     //
176     //! @return     描画優先度です。
GetPriority()177     u8 GetPriority() const
178     {
179         return m_Priority;
180     }
181 
182     //! @brief      描画要素のソート時に最優先に区分される ID を設定します。
SetLayerId(const u8 layerId)183     void SetLayerId(const u8 layerId)
184     {
185         m_LayerId = layerId;
186     }
187 
188     //! @brief      描画要素のソート時に最優先に区分される ID を取得します。
189     //
190     //! @return     描画要素のソート時に最優先に区分される ID です。
GetLayerId()191     u8 GetLayerId() const
192     {
193         return m_LayerId;
194     }
195 
196     //! @brief      ユーザの描画コマンドを設定します。
197     //!
198     //! @param[in]  userRenderCommand ユーザの描画コマンドです。
SetUserRenderCommand(UserRenderCommand * userRenderCommand)199     void SetUserRenderCommand(UserRenderCommand* userRenderCommand)
200     {
201         // 既にセットされている UserRenderCommand の UserRenderNode を解除します。
202         UserRenderCommand* lastUserRenderCommand = this->GetUserRenderCommand();
203         if ( lastUserRenderCommand != NULL )
204         {
205             lastUserRenderCommand->SetUserRenderNode(NULL);
206         }
207 
208         m_UserRenderCommand = userRenderCommand;
209         userRenderCommand->SetUserRenderNode(this);
210     }
211 
212     //! @brief      ユーザの描画コマンドを取得します。
213     //!
214     //! @return     ユーザの描画コマンドへのポインタです。
GetUserRenderCommand()215     UserRenderCommand* GetUserRenderCommand() const
216     {
217         return m_UserRenderCommand;
218     }
219 
220     //----------------------------------------
221     //! @name シーンツリー
222     //@{
223 
224     //! @brief        ビジターを受け付けます。
225     //!
226     //! @param[in]    visitor ビジターです。
227     //!
228     virtual void Accept(ISceneVisitor* visitor);
229 
230     //@}
231 
232 protected:
233     //----------------------------------------
234     //! @name コンストラクタ/デストラクタ
235     //@{
236 
237     //! @brief コンストラクタです。
238     UserRenderNode(
239         os::IAllocator* allocator,
240         const UserRenderNode::Description& description);
241 
242     //! @brief デストラクタです。
~UserRenderNode()243     virtual ~UserRenderNode()
244     {
245     }
246 
247     //@}
248 
249     //! @brief   Initialize() の実行に必要なメモリサイズを取得します。
250     //!
251     //! @details :private
GetMemorySizeForInitialize(os::MemorySizeCalculator * pSize,Description description)252     static void GetMemorySizeForInitialize(
253         os::MemorySizeCalculator* pSize,
254         Description description)
255     {
256         NW_ASSERT(description.isFixedSizeMemory);
257 
258         return TransformNode::GetMemorySizeForInitialize(pSize, ResTransformNode(), description);
259     }
260 
261 protected:
262     gfx::ResMaterial::TranslucencyKind m_TranslucencyKind;
263     u8                                 m_Priority;
264     u8                                 m_LayerId;
265     UserRenderCommand*                 m_UserRenderCommand;
266 
267     Description m_Description;
268 };
269 
270 } // namespace gfx
271 } // namespace nw
272 
273 #endif // NW_GFX_USERRENDERNODE_H_
274