1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     main.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: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 //------------------------------------------------------------------
19 // デモ: perspective
20 //
21 // 概要
22 //   3D風に表示するレイアウトのデモです。
23 //
24 // 操作
25 //   Aボタンで、射影行列を透視射影、正射影と切り替わります。
26 //   透視射影のときが3D風の表示なります。
27 //   正射影のときは通常の2D表示になります。
28 //
29 //------------------------------------------------------------------
30 
31 #include <nw/lyt.h>
32 #include <nw/demo.h>
33 
34 namespace
35 {
36 
37 typedef nw::ut::MoveArray<u8> File;
38 
39 /*---------------------------------------------------------------------------*
40   @brief 描画の初期設定を行います。
41 
42   @param width  画面の幅。
43   @param height  画面の高さ。
44  *---------------------------------------------------------------------------*/
45 void
InitDraw(int width,int height)46 InitDraw(int width, int height)
47 {
48     // カラーバッファ情報
49     // LCDの向きに合わせて、幅と高さを入れ替えています。
50     const nw::font::ColorBufferInfo colBufInfo =
51     {
52         height, width, PICA_DATA_DEPTH24_STENCIL8_EXT
53     };
54 
55     const u32 commands[] =
56     {
57         // ビューポートの設定
58         NW_FONT_CMD_SET_VIEWPORT(0, 0, colBufInfo.width, colBufInfo.height),
59 
60         // シザー処理を無効
61         NW_FONT_CMD_SET_DISABLE_SCISSOR(colBufInfo),
62 
63         // wバッファの無効化
64         // デプスレンジの設定
65         // ポリゴンオフセットの無効化
66         NW_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET(
67             0.0f,           // wScale : 0.0 でWバッファが無効
68             0.0f,           // depth range near
69             1.0f,           // depth range far
70             0,              // polygon offset units : 0.0 で ポリゴンオフセットが無効
71             colBufInfo),
72     };
73 
74     nngxAdd3DCommand(commands, sizeof(commands), true);
75 
76     static const u32 constCommands[] =
77     {
78         // カリングを無効
79         NW_FONT_CMD_SET_CULL_FACE(NW_FONT_CMD_CULL_FACE_DISABLE),
80 
81         // ステンシルテストを無効
82         NW_FONT_CMD_SET_DISABLE_STENCIL_TEST(),
83 
84         // デプステストを無効
85         // カラーバッファの全ての成分を書き込み可
86         NW_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK(
87             false,  // isDepthTestEnabled
88             0,      // depthFunc
89             true,   // depthMask
90             true,   // red
91             true,   // green
92             true,   // blue
93             true),  // alpha
94 
95         // アーリーデプステストを無効
96         NW_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST(false),
97 
98         // フレームバッファアクセス制御
99         NW_FONT_CMD_SET_FBACCESS(
100             true,   // colorRead
101             true,   // colorWrite
102             false,  // depthRead
103             false,  // depthWrite
104             false,  // stencilRead
105             false), // stencilWrite
106     };
107 
108     nngxAdd3DCommand(constCommands, sizeof(constCommands), true);
109 }
110 
111 /*---------------------------------------------------------------------------*
112   @brief Zバッファによる比較を有効にするか無効にするかを切り替えます。
113 
114   @param bEnable  真のとき、Zバッファによる比較を有効にします。
115  *---------------------------------------------------------------------------*/
116 void
EnableZCompare(bool bEnable)117 EnableZCompare(bool bEnable)
118 {
119     if (bEnable)
120     {
121         // Z比較を行います。
122         glEnable(GL_DEPTH_TEST);
123     }
124     else
125     {
126         // Z比較を行いません。常に、レイアウトの階層の下に行くほど手前に表示されます。
127         glDisable(GL_DEPTH_TEST);
128     }
129 }
130 
131 /*---------------------------------------------------------------------------*
132   @brief モデルビュー行列と射影行列を設定します。
133 
134   @param drawInfo  描画情報です。
135   @param layout  レイアウトです。
136   @param bPerspective  射影の種類を指定します。
137                        真のときは、射影行列を透視射影にします。
138                        偽のときは、正射影にします。
139  *---------------------------------------------------------------------------*/
140 void
SetupCamera(nw::lyt::DrawInfo & drawInfo,const nw::lyt::Layout & layout,bool bPerspective)141 SetupCamera(
142     nw::lyt::DrawInfo& drawInfo,
143     const nw::lyt::Layout& layout,
144     bool bPerspective
145 )
146 {
147     nw::ut::Rect layoutRect = layout.GetLayoutRect();
148 
149     if (bPerspective)
150     {
151         const f32 fovy = 45.f;
152         const f32 znear = 0.05f;
153         const f32 zfar = 10000.f;
154         const f32 width = layoutRect.top - layoutRect.bottom;
155         const f32 height = layoutRect.right - layoutRect.left;
156 
157         // 射影行列を透視射影に設定します。
158         nw::math::MTX44 projMtx;
159         nw::math::MTX44Perspective(
160             &projMtx,
161             fovy,
162             width / height,
163             znear,
164             zfar);
165         drawInfo.SetProjectionMtx(projMtx);
166 
167         //  ビュー行列
168         //      注視点を(0, 0, 0)とし、Zの位置が0であるペインの見た目が正射影のときと同じになるように、
169         //      カメラの位置を手前にセットします。
170         const f32 dist = height * 0.5f / nw::math::TanDeg(fovy * 0.5f);
171 
172         nw::math::VEC3 pos(0.f, 0.f, dist);
173         nw::math::VEC3 up(-1, 0, 0);
174         nw::math::VEC3 target(0.f, 0.f, 0.f);
175 
176         nw::math::MTX34 viewMtx;  // ビュー行列
177         nw::math::MTX34LookAt(
178             &viewMtx,
179             &pos,                 // カメラの位置
180             &up,                  // カメラの上方向
181             &target);             // 注視点
182         drawInfo.SetViewMtx(viewMtx);
183     }
184     else
185     {
186         const f32 znear   =  -1000.f;
187         const f32 zfar    =   1000.f;
188 
189         // 射影行列を正射影に設定
190         // (Layoutデータは横向きなので向きを変換する)
191         nw::math::MTX44 projMtx;
192         nw::math::MTX44Ortho(
193             &projMtx,
194             layoutRect.bottom,  // left
195             layoutRect.top,     // right
196             -layoutRect.right,  // bottom
197             -layoutRect.left,   // top
198             znear,
199             zfar);
200         drawInfo.SetProjectionMtx(projMtx);
201 
202         // モデルビュー行列を設定
203         // (Layoutデータは横向きなので画面の上方向はレイアウトの-X方向)
204         nw::math::VEC3 pos(0, 0, 1);
205         nw::math::VEC3 up(-1, 0, 0);
206         nw::math::VEC3 target(0, 0, 0);
207 
208         nw::math::MTX34 viewMtx;
209         nw::math::MTX34LookAt(&viewMtx, &pos, &up, &target);
210         drawInfo.SetViewMtx(viewMtx);
211     }
212 }
213 
214 }   // namespace
215 
216 /*---------------------------------------------------------------------------*
217   @brief サンプルのメイン関数です。
218  *---------------------------------------------------------------------------*/
219 void
nnMain()220 nnMain()
221 {
222     nw::demo::SimpleApp& demoApp = nw::demo::SimpleApp::GetInstance();
223     demoApp.Initialize();
224 
225     nw::lyt::Initialize(&demoApp.GetAllocator(), &demoApp.GetDeviceAllocator());
226 
227     // レイアウトのバイナリリソース(アーカイブ)を読み込み。
228     File fileLayout = nw::demo::Utility::LoadFile(
229         &demoApp.GetDeviceAllocator(), NW_DEMO_FILE_PATH(L"layout.arc"), 128);
230 
231     if (fileLayout.empty())
232     {
233         NW_FATAL_ERROR("can not open layout archive.\n");
234     }
235 
236     // バイナリリソースのルートディレクトリを指定してリソースアクセサを生成。
237     nw::lyt::ArcResourceAccessor* pResAccessor = new nw::lyt::ArcResourceAccessor;
238     if (!pResAccessor->Attach(fileLayout.begin(), "."))
239     {
240         NW_FATAL_ERROR("can not attach layout archive.\n");
241     }
242 
243     nw::lyt::Layout* pLayout = new nw::lyt::Layout();
244 
245     // レイアウトリソースの読み込み
246     {
247         const void* lytRes = pResAccessor->GetResource(0, "perspective.bclyt");
248         NW_NULL_ASSERT(lytRes);
249         pLayout->Build(lytRes, pResAccessor);
250     }
251 
252     nw::lyt::AnimTransform* pAnimTrans = 0;
253     // アニメーションリソースの読み込み
254     {
255         const void* lpaRes = pResAccessor->GetResource(0, "perspective.bclan");
256         NW_NULL_ASSERT(lpaRes);
257         pAnimTrans = pLayout->CreateAnimTransform(lpaRes, pResAccessor);
258         pLayout->BindAnimation(pAnimTrans);
259     }
260 
261     f32 animFrame = 0;
262     bool bPerspective = true;
263 
264     nw::lyt::GraphicsResource graphicsResource;
265     // グローバルなリソースファイルを読み込みます。
266     {
267         graphicsResource.StartSetup();
268         const wchar_t* resourcePath = 0;
269         for (int i = 0;
270              (resourcePath = graphicsResource.GetResourcePath(i)) != NULL;
271              ++i)
272         {
273             File file = nw::demo::Utility::LoadFile(&demoApp.GetAllocator(), resourcePath);
274 
275             if (file.empty())
276             {
277                 NW_FATAL_ERROR("can not read lyt resource file.");
278             }
279 
280             graphicsResource.SetResource(i, file.begin(), file.size(), false);
281         }
282 
283         graphicsResource.FinishSetup();
284     }
285 
286     nw::lyt::DrawInfo drawInfo;
287     drawInfo.SetGraphicsResource(&graphicsResource);
288 
289     nw::lyt::Drawer drawer;
290     drawer.Initialize(graphicsResource);
291 
292     nw::demo::Pad& pad = *nw::demo::PadFactory::GetPad();
293 
294     const nw::ut::FloatColor clearColor(0.3f, 0.3f, 0.3f, 1.0f);
295     const f32 clearDepth = 0.0f;
296 
297     bool loop = true;
298     while (loop)
299     {
300         pad.Update();
301 
302         if (pad.IsButtonDown(pad.BUTTON_A))
303         {
304             // 透視射影か正射影かを切り替えます。
305             bPerspective = ! bPerspective;
306         }
307 
308         demoApp.SetRenderingTarget(demoApp.DISPLAY0);
309         {
310             demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth);
311 
312             InitDraw(demoApp.DISPLAY0_WIDTH, demoApp.DISPLAY0_HEIGHT);
313 
314             EnableZCompare(bPerspective);
315             SetupCamera(drawInfo, *pLayout, bPerspective);
316 
317             pLayout->Animate();
318             pLayout->CalculateMtx(drawInfo);
319 
320             drawer.DrawBegin(drawInfo);
321             drawer.Draw(pLayout, drawInfo);
322             drawer.DrawEnd(drawInfo);
323 
324             // フレームの更新
325             animFrame += 1.0f;
326             while (animFrame >= pAnimTrans->GetFrameSize())
327             {
328                 animFrame -= pAnimTrans->GetFrameSize();
329             }
330             pAnimTrans->SetFrame(animFrame);
331         }
332 
333         demoApp.SetRenderingTarget(demoApp.DISPLAY1);
334         {
335             demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth);
336         }
337 
338         demoApp.SwapBuffer(demoApp.DISPLAY_BOTH);
339     }
340 
341     delete pLayout;
342     delete pResAccessor;
343 }
344 
345