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