/*---------------------------------------------------------------------------* Project: NintendoWare File: MultiAnimationDemo.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: $ *---------------------------------------------------------------------------*/ #define NW_DEBUG_CHECK_MEMORY_LEAK #include #include #include #include #include #include #include #include namespace { //---------------------------------------- // メモリ関係 // デバイスメモリを確保するためのアロケータです。 nw::demo::DemoAllocator s_DeviceAllocator; //---------------------------------------- // ファイル名の定義です。 const wchar_t* SKY_SPHERE_FILE_NAME = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl"); const wchar_t* RESOURCE_FILES[] = { NW_DEMO_FILE_PATH(L"MultiAnimation.bcmdl"), NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"), NW_DEMO_FILE_PATH(L"FragmentLight.bcenv"), NW_DEMO_FILE_PATH(L"Walk.bcskla"), NW_DEMO_FILE_PATH(L"MatAnim.bcmata"), NW_DEMO_FILE_PATH(L"VisibilityAnim.bcmdla"), NW_DEMO_FILE_PATH(L"CameraAnim.bccam"), NW_DEMO_FILE_PATH(L"LightAnim.bclgt"), NW_DEMO_FILE_PATH(L"LightAnim.bcenv"), NW_DEMO_FILE_PATH(L"Pierrot.bcskla"), NW_DEMO_FILE_PATH(L"Robot.bcskla") }; const wchar_t* LUT_RESOURCE_FILE = NW_DEMO_FILE_PATH(L"LightAnim.bcres"); //---------------------------------------- // 描画関係 const int RENDER_TARGET_COUNT = 1; typedef nw::ut::FixedSizeArray RenderTargetArray; RenderTargetArray s_RenderTargets; nw::demo::SceneSystem* s_SceneSystem = NULL; nw::demo::RenderSystem* s_RenderSystem = NULL; nw::demo::GraphicsDrawing s_GraphicsDrawing; //---------------------------------------- // リソース関係 nw::demo::ResourceArray s_Resources; nw::demo::ResourceSet* s_LutResource; //---------------------------------------- // シーン関係 nw::gfx::SceneNode* s_SceneRoot = NULL; s32 s_FrameCount = 0; nw::gfx::Camera* s_BaseCamera = NULL; nw::gfx::Camera* s_LeftCamera = NULL; nw::gfx::Camera* s_RightCamera = NULL; nw::gfx::Camera* s_AnimCamera = NULL; nw::gfx::Camera* s_ActiveCamera = NULL; const f32 s_fNearPlane = 0.1f; nw::gfx::SceneNode* s_SceneRootInvisible = NULL; nw::gfx::SceneNode* s_SkeletalRoot = NULL; nw::gfx::SceneNode* s_MaterialRoot = NULL; nw::gfx::SceneNode* s_VisibilityRoot = NULL; nw::gfx::SceneNode* s_CameraRoot = NULL; nw::gfx::SceneNode* s_LightRoot = NULL; //---------------------------------------- // シーン環境関係 const s32 ENVIRONMENT_SETTINGS_COUNT = 2; typedef nw::ut::FixedSizeArray SceneEnvironmentSettingArray; SceneEnvironmentSettingArray s_SceneEnvironmentSettings; const s32 s_BaseCameraIndex = 0; const s32 s_AnimCameraIndex = 1; //---------------------------------------- // アニメーション関係 const int MAX_ANIM_OBJECTS = 10; nw::ut::FixedSizeArray s_AnimObjects; float s_AnimWeight0 = 0.5f; float s_AnimWeight1 = 0.5f; s32 s_ActiveCameraIndex = s_BaseCameraIndex; const int ANIMATION_RESOURCES_COUNT =11; const int ANIMATION_TARGETS_COUNT = 17; nw::ut::FixedSizeArray s_ResAnims; nw::ut::FixedSizeArray s_AnimTargets; struct AnimBindingTable { const char* targetName; const char* animName; nw::demo::Utility::AnimationType animType; }; const AnimBindingTable ANIM_BINDING_TABLE[] = { { "Male", "Walk", nw::demo::Utility::SKELETAL_ANIMATION }, { "Pierrot", "Pierrot", nw::demo::Utility::SKELETAL_ANIMATION }, { "Robot", "Robot", nw::demo::Utility::SKELETAL_ANIMATION }, { "MatAnim", "MatAnim", nw::demo::Utility::MATERIAL_ANIMATION }, { "VisibilityAnim", "VisibilityAnim", nw::demo::Utility::VISIBILITY_ANIMATION }, { "AnimCamera", "CameraAnim", nw::demo::Utility::CAMERA_ANIMATION }, { "pointLight1", "pointLight1", nw::demo::Utility::LIGHT_ANIMATION }, { "pointLight2", "pointLight2", nw::demo::Utility::LIGHT_ANIMATION }, { "pointLight3", "pointLight3", nw::demo::Utility::LIGHT_ANIMATION } }; //---------------------------------------- // 操作関係 int s_AnimMode = 0; /*!--------------------------------------------------------------------------* @brief グラフィックス関連の初期化を行います。 *---------------------------------------------------------------------------*/ void InitializeGraphics() { nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator ); // renderDescriptionへステレオの設定を行います。 nw::demo::RenderSystem::Description renderDescription; renderDescription.reusableCommandBufferSize = 0x100000; renderDescription.reusableCommandRequestCount = 512; renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO; s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription); s_GraphicsDrawing.SetScreenSize( renderDescription.lowerScreenDescription.width, renderDescription.lowerScreenDescription.height ); nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing); s_RenderTargets.push_back( nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription) ); NW_ASSERT(!s_RenderTargets.empty()); s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front()); // sceneDescriptionへの標準的な設定はコンストラクタで行われています。 nw::demo::SceneSystem::Description sceneDescription; s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription); // デモ用の最遠景モデルをレンダリングシステムに設定します。 // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。 s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME); NW_GL_ASSERT(); } /*!--------------------------------------------------------------------------* @brief グラフィックス関連の後始末をします。 *---------------------------------------------------------------------------*/ void TerminateGraphics() { nw::gfx::SafeDestroy(s_LeftCamera); nw::gfx::SafeDestroy(s_RightCamera); nw::gfx::SafeDestroy(s_SceneSystem); nw::gfx::SafeDestroyAll(s_RenderTargets); s_GraphicsDrawing.Finalize(); nw::gfx::SafeDestroy(s_RenderSystem); NW_GL_ASSERT(); } /*!--------------------------------------------------------------------------* @brief アニメーションの後始末をします。 *---------------------------------------------------------------------------*/ void TerminateAnim(void) { for (int animIdx = 0; animIdx < s_AnimObjects.Size(); ++animIdx) { nw::gfx::SafeDestroy(s_AnimObjects[animIdx]); } s_AnimObjects.clear(); } /*!--------------------------------------------------------------------------* @brief カメラを切り替えます。 *---------------------------------------------------------------------------*/ void ChangeCamera(s32 cameraIndex) { s_RenderSystem->GetRenderContext()->SetActiveCamera(cameraIndex); s_ActiveCamera = s_RenderSystem->GetRenderContext()->GetActiveCamera(); s_ActiveCameraIndex = cameraIndex; nw::demo::Utility::SetCameraAspectRatio(s_ActiveCamera, s_RenderTargets[0]); } /*!--------------------------------------------------------------------------* @brief ルートノード関連の構築をします。 *---------------------------------------------------------------------------*/ void BuildRootNodes() { NW_ASSERT(s_SceneRoot == NULL); s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder() .IsFixedSizeMemory(false) .Create(&s_DeviceAllocator); NW_NULL_ASSERT(s_SceneRoot); NW_ASSERT(s_SceneRootInvisible == NULL); s_SceneRootInvisible = nw::gfx::TransformNode::DynamicBuilder() .IsFixedSizeMemory(false) .Create(&s_DeviceAllocator); // 各アニメーション毎にルートノードを作成します。 NW_ASSERT(s_SkeletalRoot == NULL); s_SkeletalRoot = nw::gfx::TransformNode::DynamicBuilder() .IsFixedSizeMemory(false) .Create(&s_DeviceAllocator); s_SceneRootInvisible->AttachChild(s_SkeletalRoot); NW_NULL_ASSERT(s_SkeletalRoot); NW_ASSERT(s_MaterialRoot == NULL); s_MaterialRoot = nw::gfx::TransformNode::DynamicBuilder() .IsFixedSizeMemory(false) .Create(&s_DeviceAllocator); s_SceneRootInvisible->AttachChild(s_MaterialRoot); NW_NULL_ASSERT(s_MaterialRoot); NW_ASSERT(s_VisibilityRoot == NULL); s_VisibilityRoot = nw::gfx::TransformNode::DynamicBuilder() .IsFixedSizeMemory(false) .Create(&s_DeviceAllocator); s_SceneRootInvisible->AttachChild(s_VisibilityRoot); NW_NULL_ASSERT(s_VisibilityRoot); NW_ASSERT(s_CameraRoot == NULL); s_CameraRoot = nw::gfx::TransformNode::DynamicBuilder() .IsFixedSizeMemory(false) .Create(&s_DeviceAllocator); s_SceneRootInvisible->AttachChild(s_CameraRoot); NW_NULL_ASSERT(s_CameraRoot); NW_ASSERT(s_LightRoot == NULL); s_LightRoot = nw::gfx::TransformNode::DynamicBuilder() .IsFixedSizeMemory(false) .Create(&s_DeviceAllocator); s_SceneRootInvisible->AttachChild(s_LightRoot); NW_NULL_ASSERT(s_LightRoot); } /*!--------------------------------------------------------------------------* @brief カメラ関連の構築をします。 *---------------------------------------------------------------------------*/ void BuildCameras() { nw::demo::Utility::CreateStereoCameras( &s_BaseCamera, &s_LeftCamera, &s_RightCamera, &s_DeviceAllocator, nw::math::VEC3(20.0f, 15.0f, 20.0f), nw::math::VEC3(0.0f, 0.0f, 0.0f), s_fNearPlane ); s_SceneRoot->AttachChild(s_BaseCamera); s_SceneSystem->GetCameraController()->Register(s_BaseCamera); } /*!--------------------------------------------------------------------------* @brief リソース関連の構築をします。 *---------------------------------------------------------------------------*/ void BuildResources(nw::demo::ResourceSet* resourceSet) { resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP)); resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP)); resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP)); nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator); if (result.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT) { result = resourceSet->resource.Setup(&s_DeviceAllocator, s_LutResource->resource); } if (result.IsFailure()) { NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode()); } nw::ut::MoveArray sceneNodeArray(&s_DeviceAllocator); nw::gfx::ResModelArray models = resourceSet->resource.GetModels(); nw::gfx::ResModelArray::iterator modelsEnd = models.end(); for (nw::gfx::ResModelArray::iterator modelResource = models.begin(); modelResource != modelsEnd; ++modelResource) { nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode( &s_DeviceAllocator, (*modelResource) ); NW_NULL_ASSERT(node); sceneNodeArray.push_back(node); s_AnimTargets.push_back(node); } nw::gfx::ResLightArray lights = resourceSet->resource.GetLights(); nw::gfx::ResLightArray::iterator lightsEnd = lights.end(); for (nw::gfx::ResLightArray::iterator lightResource = lights.begin(); lightResource != lightsEnd; ++lightResource) { nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode( &s_DeviceAllocator, (*lightResource) ); NW_NULL_ASSERT(node); sceneNodeArray.push_back(node); s_AnimTargets.push_back(node); } nw::gfx::ResCameraArray cameras = resourceSet->resource.GetCameras(); nw::gfx::ResCameraArray::iterator camerasEnd = cameras.end(); for (nw::gfx::ResCameraArray::iterator cameraResource = cameras.begin(); cameraResource != camerasEnd; ++cameraResource) { nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode( &s_DeviceAllocator, (*cameraResource) ); NW_NULL_ASSERT(node); sceneNodeArray.push_back(node); s_AnimTargets.push_back(node); } // 親子付け参照関係を解決 nw::gfx::SceneHelper::ResolveReference(sceneNodeArray); // モデルをシーンに追加 nw::gfx::SceneHelper::ForeachRootNodes( sceneNodeArray.Begin(), sceneNodeArray.End(), nw::gfx::AttachNode(s_SceneRoot) ); nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings(); nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end(); for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin(); settingResource != settingsEnd; ++settingResource) { nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder() .Resource(*settingResource) .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator); nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting = nw::ut::DynamicCast(sceneObject); NW_NULL_ASSERT(sceneEnvironmentSetting); s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting); } } /*!--------------------------------------------------------------------------* @brief アニメーション関連の構築をします。 *---------------------------------------------------------------------------*/ void BuildAnimations() { s_AnimCamera = NULL; NW_FOREACH(AnimBindingTable animBindingTable, ANIM_BINDING_TABLE) { nw::anim::ResAnim resAnim; resAnim = nw::demo::Utility::FindResAnimByName( s_ResAnims, animBindingTable.animName, animBindingTable.animType); NW_ASSERT(resAnim.IsValid()); nw::gfx::SceneObject* targetObject; targetObject = nw::demo::Utility::FindObjectByName( s_AnimTargets, animBindingTable.targetName); NW_NULL_ASSERT(targetObject); // フルベイク形式のアニメーションリソースであれば、 // スケルタルモデルの設定を行ないます。 if (resAnim.IsFullBakedAnim()) { nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast(targetObject); NW_NULL_ASSERT(skeletalModel); skeletalModel->SetFullBakedAnimEnabled(true); } // アニメーション評価を生成し、バインドします。 s_AnimObjects.PushBack( nw::demo::Utility::BindAnimation( &s_DeviceAllocator, targetObject, resAnim, animBindingTable.animType, false) ); // カメラアニメーションの場合は、バインド対象のカメラを保持しておきます。 if (animBindingTable.animType == nw::demo::Utility::CAMERA_ANIMATION) { s_AnimCamera = nw::ut::DynamicCast (nw::demo::Utility::FindObjectByName(s_AnimTargets, animBindingTable.targetName)); } } NW_NULL_ASSERT(s_AnimCamera); } /*!--------------------------------------------------------------------------* @brief 指定した名前のオブジェクトを指定したシーンルートに再配置します。 *---------------------------------------------------------------------------*/ void ReattachObjectByName(const char* name, nw::gfx::SceneNode* root) { nw::gfx::SceneNode* node = nw::ut::DynamicCast (nw::demo::Utility::FindObjectByName(s_AnimTargets, name)); NW_NULL_ASSERT(node); node->GetParent()->DetachChild( node ); root->AttachChild( node ); } /*!--------------------------------------------------------------------------* @brief 指定した名前のオブジェクトを移動します。 *---------------------------------------------------------------------------*/ void MoveObjectByName(const char* name, f32 x, f32 y, f32 z) { nw::gfx::TransformNode* node = nw::ut::DynamicCast (nw::demo::Utility::FindObjectByName(s_AnimTargets, name)); NW_NULL_ASSERT(node); node->Transform().SetTranslate(x,y,z); } /*!--------------------------------------------------------------------------* @brief オブジェクトを各シーンルートに再配置します。 *---------------------------------------------------------------------------*/ void ReattachObjects() { // スケルタルアニメーション ReattachObjectByName("Male", s_SkeletalRoot); MoveObjectByName("Male", 0.0f, -8.0f, 0.0f); ReattachObjectByName("Pierrot", s_SkeletalRoot); MoveObjectByName("Pierrot", 10.0f, -8.0f, 0.0f); ReattachObjectByName("Robot", s_SkeletalRoot); MoveObjectByName("Robot", -10.0f, -8.0f, 0.0f); // マテリアルアニメーション ReattachObjectByName("MatAnim", s_MaterialRoot); // ビジビリティアニメーション ReattachObjectByName("VisibilityAnim", s_VisibilityRoot); MoveObjectByName("VisibilityAnim", 0.0f, -8.0f, 0.0f); // カメラアニメーション ReattachObjectByName("CameraAnim", s_CameraRoot); // ライトアニメーション ReattachObjectByName("LightAnim", s_LightRoot); } /*!--------------------------------------------------------------------------* @brief アニメーションを切り替えます。 *---------------------------------------------------------------------------*/ void ToggleAnimationMode(bool isIncremental) { // s_SceneRoot から取り外したシーンノードは描画されなくなります。 // 不可視にするためには取り外すだけで十分なのですが、 // 破棄などの処理を行いやすくするために、描画しないシーンノードは // s_SceneRootInvisible という別のシーンルートに取り付けておきます。 switch (s_AnimMode) { case 0: s_SceneRoot->DetachChild(s_SkeletalRoot); s_SceneRootInvisible->AttachChild(s_SkeletalRoot); break; case 1: s_SceneRoot->DetachChild(s_MaterialRoot); s_SceneRootInvisible->AttachChild(s_MaterialRoot); break; case 2: s_SceneRoot->DetachChild(s_VisibilityRoot); s_SceneRootInvisible->AttachChild(s_VisibilityRoot); break; case 3: ChangeCamera(s_BaseCameraIndex); s_SceneRoot->DetachChild(s_CameraRoot); s_SceneRootInvisible->AttachChild(s_CameraRoot); break; case 4: s_SceneRoot->DetachChild(s_LightRoot); s_SceneRootInvisible->AttachChild(s_LightRoot); break; default: NW_ASSERT(false); } if (isIncremental) { s_AnimMode++; if (s_AnimMode > 4) { s_AnimMode = 0; } } else { s_AnimMode--; if (s_AnimMode < 0) { s_AnimMode = 4; } } switch (s_AnimMode) { case 0: s_SceneRootInvisible->DetachChild(s_SkeletalRoot); s_SceneRoot->AttachChild(s_SkeletalRoot); break; case 1: s_SceneRootInvisible->DetachChild(s_MaterialRoot); s_SceneRoot->AttachChild(s_MaterialRoot); break; case 2: s_SceneRootInvisible->DetachChild(s_VisibilityRoot); s_SceneRoot->AttachChild(s_VisibilityRoot); break; case 3: s_SceneRootInvisible->DetachChild(s_CameraRoot); s_SceneRoot->AttachChild(s_CameraRoot); ChangeCamera(s_AnimCameraIndex); break; case 4: s_SceneRootInvisible->DetachChild(s_LightRoot); s_SceneRoot->AttachChild(s_LightRoot); break; default: NW_ASSERT(false); } // シーン構造が変化したので、シーンの初期化を行います。 s_SceneSystem->InitializeScene(s_SceneRoot); } /*!--------------------------------------------------------------------------* @brief シーンを初期化します。 *---------------------------------------------------------------------------*/ void InitializeScenes() { BuildRootNodes(); BuildCameras(); // LUT を持ったリソースを読み込みます。 s_LutResource = nw::demo::Utility::LoadResources(s_Resources, LUT_RESOURCE_FILE, &s_DeviceAllocator); BuildResources(s_LutResource); // モデルやそれ以外のリソースを読み込みます。 NW_FOREACH(const wchar_t* name, RESOURCE_FILES) { nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator); BuildResources(resourceSet); s_ResAnims.push_back(resourceSet->resource); } BuildAnimations(); ReattachObjects(); // ライトアニメーションを表示します s_SceneRootInvisible->DetachChild(s_LightRoot); s_SceneRoot->AttachChild(s_LightRoot); s_AnimMode = 4; // シーンツリーを巡回して初期化を行います。 s_SceneSystem->InitializeScene(s_SceneRoot); s_SceneSystem->UpdateScene(); // シーン環境の参照解決を行い設定します。 s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings); nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment(); sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera); sceneEnvironment.SetCamera(s_AnimCameraIndex, s_AnimCamera); ChangeCamera(s_BaseCameraIndex); NW_GL_ASSERT(); s_FrameCount = 0; } /*!--------------------------------------------------------------------------* @brief シーン関連の後始末をします。 *---------------------------------------------------------------------------*/ void TerminateScenes() { // 表示されていないシーンオブジェクトも破棄するために s_SceneRootInvisible に対して SafeDestroyBranch を実行します。 nw::gfx::SafeDestroyBranch(s_SceneRoot); nw::gfx::SafeDestroyBranch(s_SceneRootInvisible); nw::demo::SafeCleanupResources(s_Resources); nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings); TerminateAnim(); NW_GL_ASSERT(); s_Resources.clear(); s_SceneEnvironmentSettings.clear(); s_AnimTargets.clear(); s_ResAnims.clear(); s_SceneRoot = NULL; s_SkeletalRoot = NULL; s_MaterialRoot = NULL; s_VisibilityRoot = NULL; s_CameraRoot = NULL; s_LightRoot = NULL; } /*!--------------------------------------------------------------------------* @brief シーンを更新します。 *---------------------------------------------------------------------------*/ void UpdateScene() { s_SceneSystem->GetCameraController()->Update(); s_SceneSystem->UpdateScene(); s_ActiveCamera->UpdateCameraMatrix(); f32 near = s_ActiveCamera->GetNear(); s_RenderSystem->CalcStereoCamera( s_LeftCamera, s_RightCamera, s_ActiveCamera, near + 5.0f); ++s_FrameCount; } /*!--------------------------------------------------------------------------* @brief 負荷表示やテスト機能の処理をおこないます。 *---------------------------------------------------------------------------*/ void ReportDemo() { NW_PROFILE("ReportDemo"); // 負荷表示からはこれらの負荷は除きます。 s_RenderSystem->SuspendLoadMeter(); nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem); s_GraphicsDrawing.BeginDrawingShape(); nw::demo::DebugUtility::DrawLoadMeter( s_RenderSystem, &s_GraphicsDrawing ); s_GraphicsDrawing.EndDrawingShape(); s_GraphicsDrawing.BeginDrawingString(); nw::demo::DebugUtility::DrawLoadMeterText( s_RenderSystem, &s_GraphicsDrawing ); const int dumpPositionX = 10; const int dumpPositionY = 10; const char* mode; switch (s_AnimMode) { case 0: mode = "Skeletal"; break; case 1: mode = "Material"; break; case 2: mode = "Visibility"; break; case 3: mode = "Camera"; break; case 4: mode = "Light"; break; default: mode = ""; break; } s_GraphicsDrawing.DrawString( dumpPositionX, dumpPositionY, "%s", mode ); s_GraphicsDrawing.EndDrawingString(); s_RenderSystem->ResumeLoadMeter(); } /*!--------------------------------------------------------------------------* @brief シーンをデモンストレーションします。 *---------------------------------------------------------------------------*/ void DemoScene() { NW_ASSERT(!s_RenderTargets.empty()); nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext(); InitializeScenes(); nw::demo::DebugUtility::PostInitializeScenes(); bool isContinuing = true; while ( isContinuing ) { nw::demo::DebugUtility::AdvanceAutoTestFrame(); nw::demo::PadFactory::GetPad()->Update(); if (nw::demo::PadFactory::GetPad()->IsButtonDown( nw::demo::Pad::BUTTON_L )) { ToggleAnimationMode(true); } if (nw::demo::PadFactory::GetPad()->IsButtonDown( nw::demo::Pad::BUTTON_R )) { ToggleAnimationMode(false); } UpdateScene(); renderContext->SetActiveCamera(s_ActiveCameraIndex); s_RenderSystem->SubmitView(s_SceneSystem); s_RenderSystem->SetRenderTarget(s_RenderTargets[0]); s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera); s_RenderSystem->ClearBySkyModel(renderContext->GetActiveCamera()); ReportDemo(); s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN); s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN); renderContext->ResetState(); if (nw::demo::Utility::IsTerminating()) { isContinuing = false; } } nw::demo::DebugUtility::PreTerminateScenes(); TerminateScenes(); } } // namespace /*!--------------------------------------------------------------------------* @brief メイン関数です。 *---------------------------------------------------------------------------*/ void nnMain() { nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator); nw::demo::PadFactory::Initialize(&s_DeviceAllocator); NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem) { InitializeGraphics(); DemoScene(); TerminateGraphics(); } nw::demo::PadFactory::Finalize(); nw::demo::FinalizeGraphicsSystem(); }