/*---------------------------------------------------------------------------* Project: NintendoWare File: main.cpp Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ //------------------------------------------------------------------ // デモ: perspective // // 概要 // 3D風に表示するレイアウトのデモです。 // // 操作 // Aボタンで、射影行列を透視射影、正射影と切り替わります。 // 透視射影のときが3D風の表示なります。 // 正射影のときは通常の2D表示になります。 // //------------------------------------------------------------------ #include #include namespace { typedef nw::ut::MoveArray File; /*---------------------------------------------------------------------------* @brief 描画の初期設定を行います。 @param width 画面の幅。 @param height 画面の高さ。 *---------------------------------------------------------------------------*/ void InitDraw(int width, int height) { // カラーバッファ情報 // LCDの向きに合わせて、幅と高さを入れ替えています。 const nw::font::ColorBufferInfo colBufInfo = { height, width, PICA_DATA_DEPTH24_STENCIL8_EXT }; const u32 commands[] = { // ビューポートの設定 NW_FONT_CMD_SET_VIEWPORT(0, 0, colBufInfo.width, colBufInfo.height), // シザー処理を無効 NW_FONT_CMD_SET_DISABLE_SCISSOR(colBufInfo), // wバッファの無効化 // デプスレンジの設定 // ポリゴンオフセットの無効化 NW_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET( 0.0f, // wScale : 0.0 でWバッファが無効 0.0f, // depth range near 1.0f, // depth range far 0, // polygon offset units : 0.0 で ポリゴンオフセットが無効 colBufInfo), }; nngxAdd3DCommand(commands, sizeof(commands), true); static const u32 constCommands[] = { // カリングを無効 NW_FONT_CMD_SET_CULL_FACE(NW_FONT_CMD_CULL_FACE_DISABLE), // ステンシルテストを無効 NW_FONT_CMD_SET_DISABLE_STENCIL_TEST(), // デプステストを無効 // カラーバッファの全ての成分を書き込み可 NW_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK( false, // isDepthTestEnabled 0, // depthFunc true, // depthMask true, // red true, // green true, // blue true), // alpha // アーリーデプステストを無効 NW_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST(false), // フレームバッファアクセス制御 NW_FONT_CMD_SET_FBACCESS( true, // colorRead true, // colorWrite false, // depthRead false, // depthWrite false, // stencilRead false), // stencilWrite }; nngxAdd3DCommand(constCommands, sizeof(constCommands), true); } /*---------------------------------------------------------------------------* @brief Zバッファによる比較を有効にするか無効にするかを切り替えます。 @param bEnable 真のとき、Zバッファによる比較を有効にします。 *---------------------------------------------------------------------------*/ void EnableZCompare(bool bEnable) { if (bEnable) { // Z比較を行います。 glEnable(GL_DEPTH_TEST); } else { // Z比較を行いません。常に、レイアウトの階層の下に行くほど手前に表示されます。 glDisable(GL_DEPTH_TEST); } } /*---------------------------------------------------------------------------* @brief モデルビュー行列と射影行列を設定します。 @param drawInfo 描画情報です。 @param layout レイアウトです。 @param bPerspective 射影の種類を指定します。 真のときは、射影行列を透視射影にします。 偽のときは、正射影にします。 *---------------------------------------------------------------------------*/ void SetupCamera( nw::lyt::DrawInfo& drawInfo, const nw::lyt::Layout& layout, bool bPerspective ) { nw::ut::Rect layoutRect = layout.GetLayoutRect(); if (bPerspective) { const f32 fovy = 45.f; const f32 znear = 0.05f; const f32 zfar = 10000.f; const f32 width = layoutRect.top - layoutRect.bottom; const f32 height = layoutRect.right - layoutRect.left; // 射影行列を透視射影に設定します。 nw::math::MTX44 projMtx; nw::math::MTX44Perspective( &projMtx, fovy, width / height, znear, zfar); drawInfo.SetProjectionMtx(projMtx); // ビュー行列 // 注視点を(0, 0, 0)とし、Zの位置が0であるペインの見た目が正射影のときと同じになるように、 // カメラの位置を手前にセットします。 const f32 dist = height * 0.5f / nw::math::TanDeg(fovy * 0.5f); nw::math::VEC3 pos(0.f, 0.f, dist); nw::math::VEC3 up(-1, 0, 0); nw::math::VEC3 target(0.f, 0.f, 0.f); nw::math::MTX34 viewMtx; // ビュー行列 nw::math::MTX34LookAt( &viewMtx, &pos, // カメラの位置 &up, // カメラの上方向 &target); // 注視点 drawInfo.SetViewMtx(viewMtx); } else { const f32 znear = -1000.f; const f32 zfar = 1000.f; // 射影行列を正射影に設定 // (Layoutデータは横向きなので向きを変換する) nw::math::MTX44 projMtx; nw::math::MTX44Ortho( &projMtx, layoutRect.bottom, // left layoutRect.top, // right -layoutRect.right, // bottom -layoutRect.left, // top znear, zfar); drawInfo.SetProjectionMtx(projMtx); // モデルビュー行列を設定 // (Layoutデータは横向きなので画面の上方向はレイアウトの-X方向) nw::math::VEC3 pos(0, 0, 1); nw::math::VEC3 up(-1, 0, 0); nw::math::VEC3 target(0, 0, 0); nw::math::MTX34 viewMtx; nw::math::MTX34LookAt(&viewMtx, &pos, &up, &target); drawInfo.SetViewMtx(viewMtx); } } } // namespace /*---------------------------------------------------------------------------* @brief サンプルのメイン関数です。 *---------------------------------------------------------------------------*/ void nnMain() { nw::demo::SimpleApp& demoApp = nw::demo::SimpleApp::GetInstance(); demoApp.Initialize(); nw::lyt::Initialize(&demoApp.GetAllocator(), &demoApp.GetDeviceAllocator()); // レイアウトのバイナリリソース(アーカイブ)を読み込み。 File fileLayout = nw::demo::Utility::LoadFile( &demoApp.GetDeviceAllocator(), NW_DEMO_FILE_PATH(L"layout.arc"), 128); if (fileLayout.empty()) { NW_FATAL_ERROR("can not open layout archive.\n"); } // バイナリリソースのルートディレクトリを指定してリソースアクセサを生成。 nw::lyt::ArcResourceAccessor* pResAccessor = new nw::lyt::ArcResourceAccessor; if (!pResAccessor->Attach(fileLayout.begin(), ".")) { NW_FATAL_ERROR("can not attach layout archive.\n"); } nw::lyt::Layout* pLayout = new nw::lyt::Layout(); // レイアウトリソースの読み込み { const void* lytRes = pResAccessor->GetResource(0, "perspective.bclyt"); NW_NULL_ASSERT(lytRes); pLayout->Build(lytRes, pResAccessor); } nw::lyt::AnimTransform* pAnimTrans = 0; // アニメーションリソースの読み込み { const void* lpaRes = pResAccessor->GetResource(0, "perspective.bclan"); NW_NULL_ASSERT(lpaRes); pAnimTrans = pLayout->CreateAnimTransform(lpaRes, pResAccessor); pLayout->BindAnimation(pAnimTrans); } f32 animFrame = 0; bool bPerspective = true; nw::lyt::GraphicsResource graphicsResource; // グローバルなリソースファイルを読み込みます。 { graphicsResource.StartSetup(); const wchar_t* resourcePath = 0; for (int i = 0; (resourcePath = graphicsResource.GetResourcePath(i)) != NULL; ++i) { File file = nw::demo::Utility::LoadFile(&demoApp.GetAllocator(), resourcePath); if (file.empty()) { NW_FATAL_ERROR("can not read lyt resource file."); } graphicsResource.SetResource(i, file.begin(), file.size(), false); } graphicsResource.FinishSetup(); } nw::lyt::DrawInfo drawInfo; drawInfo.SetGraphicsResource(&graphicsResource); nw::lyt::Drawer drawer; drawer.Initialize(graphicsResource); nw::demo::Pad& pad = *nw::demo::PadFactory::GetPad(); const nw::ut::FloatColor clearColor(0.3f, 0.3f, 0.3f, 1.0f); const f32 clearDepth = 0.0f; bool loop = true; while (loop) { pad.Update(); if (pad.IsButtonDown(pad.BUTTON_A)) { // 透視射影か正射影かを切り替えます。 bPerspective = ! bPerspective; } demoApp.SetRenderingTarget(demoApp.DISPLAY0); { demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth); InitDraw(demoApp.DISPLAY0_WIDTH, demoApp.DISPLAY0_HEIGHT); EnableZCompare(bPerspective); SetupCamera(drawInfo, *pLayout, bPerspective); pLayout->Animate(); pLayout->CalculateMtx(drawInfo); drawer.DrawBegin(drawInfo); drawer.Draw(pLayout, drawInfo); drawer.DrawEnd(drawInfo); // フレームの更新 animFrame += 1.0f; while (animFrame >= pAnimTrans->GetFrameSize()) { animFrame -= pAnimTrans->GetFrameSize(); } pAnimTrans->SetFrame(animFrame); } demoApp.SetRenderingTarget(demoApp.DISPLAY1); { demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth); } demoApp.SwapBuffer(demoApp.DISPLAY_BOTH); } delete pLayout; delete pResAccessor; }