1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     LytCtrl.cpp
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 #include <nn/os.h>
18 
19 #include <nw/types.h>
20 //#include <nw/demo.h>
21 #include <nw/dev.h>
22 #include <nw/gfx.h>
23 #include <nw/ut.h>
24 
25 #include "../include/LytCtrl.h"
26 
27 
28 namespace
29 {
30 
31 
32 /*---------------------------------------------------------------------------*
33   @brief グラフィックスの初期設定を行います。
34  *---------------------------------------------------------------------------*/
35 void
InitGX()36 InitGX()
37 {
38 #ifdef NW_PLATFORM_CTR
39     GLenum curCmdGenMode = 0;
40     nngxGetCommandGenerationMode(&curCmdGenMode);
41 
42     if (curCmdGenMode != NN_GX_CMDGEN_MODE_UNCONDITIONAL)
43     {
44         // NN_GX_STATE_OTHER ステートのコマンドをただちに発行させます。
45         nngxSetCommandGenerationMode(NN_GX_CMDGEN_MODE_UNCONDITIONAL);
46     }
47 #endif
48 
49     glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
50     glDisable(GL_CULL_FACE);
51     glDisable(GL_DEPTH_TEST);
52     glDisable(GL_SCISSOR_TEST);
53     glDisable(GL_STENCIL_TEST);
54     glDisable(GL_POLYGON_OFFSET_FILL);
55     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
56     glDepthMask(GL_TRUE);
57 #ifdef NW_PLATFORM_CTR
58     glDisable(GL_EARLY_DEPTH_TEST_DMP);
59 #endif
60 
61 #ifdef NW_PLATFORM_CTR
62     // コマンド発行モードを元に戻します。
63     if (curCmdGenMode != NN_GX_CMDGEN_MODE_UNCONDITIONAL)
64     {
65         nngxSetCommandGenerationMode(curCmdGenMode);
66     }
67 
68     // NN_GX_STATE_OTHERS 以外のステートはバリデートによりコマンドを発行します。
69     const GLbitfield stateMask =
70         NN_GX_STATE_TRIOFFSET |
71         NN_GX_STATE_SCISSOR |
72         NN_GX_STATE_FBACCESS;
73 
74     nngxUpdateState(stateMask);
75     NW_LYT_DRAWER_VALIDATE(stateMask);
76 #endif
77 
78     NW_GL_ASSERT();
79 }
80 
81 
82 /*!--------------------------------------------------------------------------*
83   @brief        コンストラクタ。
84  *---------------------------------------------------------------------------*/
LytCtrl()85 LytCtrl::LytCtrl()
86 {
87     m_ResourcesArray.clear();
88 
89     // シェーダファイル等のロード
90     {
91         m_GraphicsResource.StartSetup();
92         const wchar_t* resourcePath = 0;
93         for (int i = 0;
94              (resourcePath = m_GraphicsResource.GetResourcePath(i)) != NULL;
95              ++i)
96         {
97             // todo:ここでロードされたメモリの行方
98             SmFile file;
99             if (!file.Read(resourcePath, m_Allocator))
100             {
101                 NW_FATAL_ERROR("can not read lyt resource file.");
102             }
103             m_GraphicsResource.SetResource(i, file.Buffer(), file.Size());
104         }
105         m_GraphicsResource.FinishSetup();
106 
107         m_DrawInfo.SetGraphicsResource( &m_GraphicsResource );
108     }
109 
110     // Drawerの初期化
111     m_Drawer.Initialize( m_GraphicsResource );
112 }
113 
114 
115 /*!--------------------------------------------------------------------------*
116   @brief        デストラクタ。
117  *---------------------------------------------------------------------------*/
~LytCtrl()118 LytCtrl::~LytCtrl()
119 {
120     uint i = 0;
121 
122     // SmLayout インスタンスを破棄します。
123     for ( i=0; i<m_ResourcesArray.size(); i++ )
124     {
125         SM_SAFE_DELETE( m_SmLytInstanceArray[i] );
126     }
127 
128     // SmLytResource インスタンスを破棄します。
129     for ( i=0; i<m_SmLytResourceArray.size(); i++ )
130     {
131         SM_SAFE_DELETE( m_SmLytResourceArray[i] );
132     }
133 
134     // 読み込んだレイアウトリソースの解放を行います。
135     for ( i=0; i<m_ResourcesArray.size(); i++ )
136     {
137         SM_SAFE_DELETE( m_ResourcesArray[i].resAccessor );
138         m_ResourcesArray[i].lytFile.Release();
139     }
140 }
141 
142 
143 /*!--------------------------------------------------------------------------*
144   @brief        レイアウトリソースをセットアップします。
145  *---------------------------------------------------------------------------*/
146 SmLayoutResource*
CreateSmLayoutResource(const wchar_t * archivePath,LytResourceFile & lytResFile)147 LytCtrl::CreateSmLayoutResource( const wchar_t* archivePath, LytResourceFile& lytResFile )
148 {
149     LytResourceSet      resSet;
150     SmLayoutResource*   smLytResource = NULL;
151     bool                isPushed = false;
152     NW_UNUSED_VARIABLE(isPushed);
153 
154     // レイアウトのバイナリリソース(アーカイブ)を読み込みます。
155     if (!resSet.lytFile.Read( archivePath, m_DeviceAllocator ) )
156     {
157         NW_FATAL_ERROR("can not open layout archive.\n");
158     }
159 
160     // バイナリリソースのルートディレクトリを指定してリソースアクセサを生成します。
161     resSet.resAccessor = new nw::lyt::ArcResourceAccessor;
162     if (!resSet.resAccessor->Attach(resSet.lytFile.Buffer(), "."))
163     {
164         NW_FATAL_ERROR("can not attach layout archive.\n");
165     }
166 
167     // レイアウトリソースクラスを生成します。
168     smLytResource = new SmLayoutResource();
169 
170     // nw::lyt::Layoutを生成します。
171     const void* lytRes = resSet.resAccessor->GetResource( 0, lytResFile.clyt.c_str() );
172     NW_NULL_ASSERT( lytRes );
173      if ( !smLytResource->InitLayout( lytRes, resSet.resAccessor ) )
174     {
175         NW_FATAL_ERROR("can not setup layout archive.\n");
176     }
177 
178     // アニメーションリソースの読み込みます。
179     for ( uint i = 0; i < lytResFile.clan.size(); i++ )
180     {
181         const void* lpaRes = resSet.resAccessor->GetResource( 0, lytResFile.clan[i].c_str() );
182          if ( lpaRes )
183         {
184              if ( !smLytResource->AddAnimation( lpaRes, resSet.resAccessor ) )
185             {
186                 NW_FATAL_ERROR("can not setup layout animation archive.\n");
187             }
188         }
189     }
190 
191     isPushed = m_SmLytResourceArray.push_back( smLytResource );
192     NW_ASSERT(isPushed);
193 
194     isPushed = m_ResourcesArray.push_back( resSet );
195     NW_ASSERT(isPushed);
196 
197     // カメラのセットアップ
198     setupCamera( smLytResource->GetLayout()->GetLayoutRect() );
199 
200     return smLytResource;
201 }
202 
203 
204 /*!--------------------------------------------------------------------------*
205   @brief        レイアウトリソースクラスのインスタンスを引数に、SmLayoutクラスのインスタンスを生成します。
206  *---------------------------------------------------------------------------*/
207 SmLayout*
CreateSmLayout(SmLayoutResource * layoutResource)208 LytCtrl::CreateSmLayout( SmLayoutResource* layoutResource )
209 {
210     SmLayout* smLyt = new SmLayout( layoutResource );
211     NW_NULL_ASSERT( smLyt );
212 
213     // 生成したインスタンスを保持します。
214     bool isPushed = m_SmLytInstanceArray.push_back( smLyt );
215     NW_ASSERT(isPushed);
216 
217     return smLyt;
218 }
219 
220 
221 /*!--------------------------------------------------------------------------*
222   @brief        保持するSmLayoutクラスの描画を行います。
223  *---------------------------------------------------------------------------*/
224 void
Render()225 LytCtrl::Render()
226 {
227     if ( m_SmLytInstanceArray.empty() ) return;
228 
229     InitGX();
230     NW_LYT_DRAWER_VALIDATE(NN_GX_STATE_ALL);
231 
232     // 保持しているSmLaytouの配列分だけエントリを行います。
233     for ( uint i = 0; i < m_SmLytInstanceArray.size(); i++ )
234     {
235         SmLayout* pLayout = m_SmLytInstanceArray[i];
236 
237         if ( pLayout->GetVisible() )
238         {
239             m_Drawer.DrawBegin( m_DrawInfo );
240 
241             // レイアウトへデータを反映する
242              if ( pLayout->SetupLayout() )
243             {
244                 SmLayoutResource* smLayoutRes = pLayout->GetLayoutResource();
245                 nw::lyt::Layout* layout = smLayoutRes->GetLayout();
246                 layout->Animate();
247                 layout->CalculateMtx( m_DrawInfo );
248                 m_Drawer.Draw( layout, m_DrawInfo );
249                 m_Drawer.DrawEnd( m_DrawInfo );
250 
251                 pLayout->ResetLayout();
252             }
253         }
254     }
255 
256     nngxUpdateState(NN_GX_STATE_ALL);
257 }
258 
259 
260 /*!--------------------------------------------------------------------------*
261   @brief        m_DrawInfoの初期化を行います。
262  *---------------------------------------------------------------------------*/
263 void
setupCamera(nw::ut::Rect rect)264 LytCtrl::setupCamera( nw::ut::Rect rect )
265 {
266     f32 znear = 0.f;
267     f32 zfar = 500.f;
268 
269     // 射影行列を正射影に設定
270     // (Layoutデータは横向きなので向きを変換する)
271     nw::math::MTX44 projMtx;
272     nw::math::MTX44OrthoPivot(
273         &projMtx,
274         rect.left,   // left
275         rect.right,  // right
276         rect.bottom, // bottom
277         rect.top,    // top
278         znear,
279         zfar,
280         nw::math::PIVOT_UPSIDE_TO_TOP);
281     m_DrawInfo.SetProjectionMtx(projMtx);
282 
283     // モデルビュー行列を設定
284     // (Layoutデータは横向きなので画面の上方向はレイアウトの-X方向)
285     nw::math::VEC3 pos(0, 0, 1);
286     nw::math::VEC3 up(0, 1, 0);
287     nw::math::VEC3 target(0, 0, 0);
288 
289     nw::math::MTX34 viewMtx;
290     nw::math::MTX34LookAt(&viewMtx, &pos, &up, &target);
291     m_DrawInfo.SetViewMtx(viewMtx);
292 }
293 
294 } // namespace
295 
296 
297