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