1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     AnimationChangeDemo.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: 22362 $
14  *---------------------------------------------------------------------------*/
15 
16 #define NW_DEBUG_CHECK_MEMORY_LEAK
17 
18 #include <nn/os.h>
19 #include <nn/fs.h>
20 
21 #include <nw/types.h>
22 
23 #include <nw/demo.h>
24 #include <nw/dev.h>
25 #include <nw/gfx.h>
26 #include <nw/ut.h>
27 #include <nw/anim.h>
28 
29 namespace
30 {
31 
32 //----------------------------------------
33 // メモリ関係
34 
35 // デバイスメモリを確保するためのアロケータです。
36 nw::demo::DemoAllocator s_DeviceAllocator;
37 
38 //----------------------------------------
39 // ファイル名の定義です。
40 const wchar_t* SKY_SPHERE_FILE_NAME  = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
41 
42 const wchar_t* MODEL_RESOURCE_FILES[] =
43 {
44     NW_DEMO_FILE_PATH(L"Male.bcmdl"),
45     NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
46     NW_DEMO_FILE_PATH(L"FragmentLight.bcenv"),
47 };
48 
49 const wchar_t* SKELETAL_ANIM_RESOURCE_FILES[] =
50 {
51     NW_DEMO_FILE_PATH(L"Walk.bcskla"),
52     NW_DEMO_FILE_PATH(L"Run.bcskla")
53 };
54 
55 //----------------------------------------
56 // 描画関係
57 const int RENDER_TARGET_COUNT = 1;
58 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
59 
60 RenderTargetArray s_RenderTargets;
61 nw::demo::SceneSystem*  s_SceneSystem = NULL;
62 nw::demo::RenderSystem* s_RenderSystem = NULL;
63 
64 nw::demo::GraphicsDrawing  s_GraphicsDrawing;
65 
66 //----------------------------------------
67 // リソース関係
68 nw::demo::ResourceArray s_Resources;
69 
70 //----------------------------------------
71 // シーン関係
72 const int SCENE_NODE_COUNT = 4;
73 nw::gfx::SceneNode* s_SceneRoot = NULL;
74 nw::gfx::SceneNode* s_ModelRoot = NULL;
75 s32 s_FrameCount = 0;
76 nw::gfx::Camera* s_BaseCamera = NULL;
77 nw::gfx::Camera* s_LeftCamera = NULL;
78 nw::gfx::Camera* s_RightCamera = NULL;
79 const f32 s_fNearPlane = 0.1f;
80 
81 //----------------------------------------
82 // シーン環境関係
83 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
84 
85 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
86 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
87 
88 const s32 s_BaseCameraIndex = 0;
89 
90 //----------------------------------------
91 // アニメーション関係
92 nw::gfx::SkeletalModel* s_AnimModel = NULL;
93 nw::gfx::TransformAnimEvaluator* s_AnimEvaluator;
94 nw::anim::res::ResAnim s_ResAnim0;
95 nw::anim::res::ResAnim s_ResAnim1;
96 nw::anim::res::ResAnim s_ResAnimEmpty;
97 
98 /*!--------------------------------------------------------------------------*
99   @brief        グラフィックス関連の初期化を行います。
100  *---------------------------------------------------------------------------*/
101 void
InitializeGraphics()102 InitializeGraphics()
103 {
104     nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
105 
106     // renderDescriptionへステレオの設定を行います。
107     nw::demo::RenderSystem::Description renderDescription;
108 
109     renderDescription.reusableCommandBufferSize = 0x100000;
110     renderDescription.reusableCommandRequestCount      = 512;
111     renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
112 
113     s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
114 
115     s_GraphicsDrawing.SetScreenSize(
116         renderDescription.lowerScreenDescription.width,
117         renderDescription.lowerScreenDescription.height
118     );
119 
120     nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
121 
122     s_RenderTargets.push_back(
123         nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
124     );
125     NW_ASSERT(!s_RenderTargets.empty());
126     s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
127 
128     // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
129     nw::demo::SceneSystem::Description sceneDescription;
130     sceneDescription.isFixedSizeMemory = true;
131     s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
132 
133     // デモ用の最遠景モデルをレンダリングシステムに設定します。
134     // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
135     s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
136 
137     NW_GL_ASSERT();
138 }
139 
140 /*!--------------------------------------------------------------------------*
141   @brief        グラフィックス関連の後始末をします。
142  *---------------------------------------------------------------------------*/
143 void
TerminateGraphics()144 TerminateGraphics()
145 {
146     nw::gfx::SafeDestroy(s_LeftCamera);
147 
148     nw::gfx::SafeDestroy(s_RightCamera);
149 
150     nw::gfx::SafeDestroy(s_SceneSystem);
151 
152     nw::gfx::SafeDestroyAll(s_RenderTargets);
153 
154     s_GraphicsDrawing.Finalize();
155 
156     nw::gfx::SafeDestroy(s_RenderSystem);
157 
158     NW_GL_ASSERT();
159 }
160 
161 /*!--------------------------------------------------------------------------*
162   @brief ファイルからトランスフォームアニメーションリソースを読み込みます。
163 
164   @param[in] filePath トランスフォームアニメーションファイルのフルパスです。
165 
166   @return トランスフォームアニメーションリソースです。
167  *---------------------------------------------------------------------------*/
168 nw::anim::res::ResAnim
BuildTransformAnimResource(const wchar_t * filePath)169 BuildTransformAnimResource(const wchar_t* filePath)
170 {
171     //----------------------------------------
172     // アニメーションリソースを生成します。
173     nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, filePath, &s_DeviceAllocator);
174     if (resourceSet->resource.GetSkeletalAnimsCount() == 0)
175     {
176         return nw::anim::res::ResAnim(NULL);
177     }
178     return resourceSet->resource.GetSkeletalAnims(0);
179 }
180 
181 /*!--------------------------------------------------------------------------*
182   @brief ファイルからトランスフォームアニメーション評価を生成します。
183 
184   他のデモと違い、アニメーションリソースの読み込みを行いません。
185 
186   @param[in] maxBones 最大メンバ数です。
187   @param[in] maxAnimMembers 最大アニメーションメンバ数です。
188   @param[in] translateAnimEnabled 移動アニメーションが有効かどうかです。
189   @param[in] resAnim アニメーションリソースです。
190 
191   @return トランスフォームアニメーション評価です。
192  *---------------------------------------------------------------------------*/
193 nw::gfx::TransformAnimEvaluator*
CreateTransformAnimEvaluator(const int maxMembers,const int maxAnimMembers,const bool translateAnimEnabled,nw::anim::res::ResAnim resAnim)194 CreateTransformAnimEvaluator(
195     const int maxMembers,
196     const int maxAnimMembers,
197     const bool translateAnimEnabled,
198     nw::anim::res::ResAnim resAnim
199 )
200 {
201     nw::gfx::TransformAnimEvaluator* evaluator = nw::gfx::TransformAnimEvaluator::Builder()
202         .AnimData(resAnim)
203         .MaxMembers(maxMembers)
204         .MaxAnimMembers(maxAnimMembers)
205         .AllocCache(false)
206         .Create(&s_DeviceAllocator);
207 
208     // 移動アニメーションの無効化フラグを設定します。
209     evaluator->SetIsTranslateDisabled(!translateAnimEnabled);
210 
211     return evaluator;
212 }
213 
214 /*!--------------------------------------------------------------------------*
215   @brief        スケルタルアニメーションを初期化します。
216 
217   後で切り替えるために、複数のアニメーションリソースを読み込んでおきます。
218   また、空のアニメーションリソースも生成しておき、これに切り替えられるようにします。
219 
220   @param[in]    model スケルタルモデルです。
221 
222   @return       トランスフォームアニメーション評価です。
223  *---------------------------------------------------------------------------*/
224 nw::gfx::TransformAnimEvaluator*
InitializeSkeletalAnim(nw::gfx::SkeletalModel * model)225 InitializeSkeletalAnim(nw::gfx::SkeletalModel* model)
226 {
227     nw::gfx::AnimGroup* animGroup = model->GetSkeletalAnimGroup();
228     if (animGroup == NULL)
229     {
230         return NULL;
231     }
232 
233     nw::gfx::ResSkeletalModel resModel = model->GetResSkeletalModel();
234     nw::gfx::ResSkeleton resSkeleton = resModel.GetSkeleton();
235     const int maxBones = resSkeleton.GetBonesCount();
236     const bool translateAnimEnabled =
237         nw::ut::CheckFlag(resSkeleton.GetFlags(), nw::gfx::ResSkeletonData::FLAG_TRANSLATE_ANIMATION_ENABLED);
238 
239     // アニメーションリソースを読み込みます。
240     s_ResAnim0 = BuildTransformAnimResource(SKELETAL_ANIM_RESOURCE_FILES[0]);
241     s_ResAnim1 = BuildTransformAnimResource(SKELETAL_ANIM_RESOURCE_FILES[1]);
242     NW_ASSERT(s_ResAnim0.IsValid());
243     NW_ASSERT(s_ResAnim1.IsValid());
244 
245     // 空のアニメーションリソースを生成します。
246     s_ResAnimEmpty = nw::anim::res::ResAnim::CreateEmptySkeletalAnim(&s_DeviceAllocator);
247 
248     // 最大アニメーションメンバ数を所得します。
249     const int maxAnimMembers =
250         nw::ut::Max(s_ResAnim0.GetMemberAnimSetCount(), s_ResAnim1.GetMemberAnimSetCount());
251 
252     nw::gfx::TransformAnimEvaluator* evaluator0 = CreateTransformAnimEvaluator(
253         maxBones, maxAnimMembers, translateAnimEnabled, s_ResAnim0);
254     if (evaluator0 == NULL)
255     {
256         return NULL;
257     }
258 
259     bool bindResult = evaluator0->Bind(animGroup);
260     model->SetSkeletalAnimObject(evaluator0);
261 
262     return evaluator0;
263 }
264 
265 /*!--------------------------------------------------------------------------*
266   @brief        アニメーション評価のアニメーションリソースを変更します。
267 
268   @param[in]    model モデルです。
269  *---------------------------------------------------------------------------*/
270 void
ChangeAnimation(nw::gfx::SkeletalModel * model)271 ChangeAnimation(nw::gfx::SkeletalModel* model)
272 {
273     NW_NULL_ASSERT(model);
274 
275     nw::gfx::AnimObject* animObject = model->GetSkeletalAnimObject();
276     nw::gfx::TransformAnimEvaluator* evaluator =
277         nw::ut::DynamicCast<nw::gfx::TransformAnimEvaluator*>(animObject);
278     if (evaluator != NULL)
279     {
280         nw::demo::Pad* pad = nw::demo::PadFactory::GetPad();
281 
282         // 十字キーの左右でアニメーションを切り替えます。
283         if (pad->IsButtonDown(nw::demo::Pad::BUTTON_LEFT))
284         {
285             evaluator->ChangeAnim(s_ResAnim0);
286         }
287         if (pad->IsButtonDown(nw::demo::Pad::BUTTON_RIGHT))
288         {
289             evaluator->ChangeAnim(s_ResAnim1);
290         }
291 
292         // L キーで空アニメーションに切り替えます。
293         if (pad->IsButtonDown(nw::demo::Pad::BUTTON_L))
294         {
295             evaluator->ChangeAnim(s_ResAnimEmpty);
296         }
297 
298         // R キーでバインドポーズに戻します。
299         if (pad->IsButtonDown(nw::demo::Pad::BUTTON_R))
300         {
301             evaluator->Reset();
302         }
303     }
304 }
305 
306 /*!--------------------------------------------------------------------------*
307   @brief        ルートノード関連の構築をします。
308  *---------------------------------------------------------------------------*/
309 void
BuildRootNodes()310 BuildRootNodes()
311 {
312     NW_ASSERT(s_SceneRoot == NULL);
313     s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
314         .Create(&s_DeviceAllocator);
315     NW_NULL_ASSERT(s_SceneRoot);
316 
317     NW_ASSERT(s_ModelRoot == NULL);
318     s_ModelRoot = nw::gfx::TransformNode::DynamicBuilder()
319         .Create(&s_DeviceAllocator);
320     s_SceneRoot->AttachChild(s_ModelRoot);
321     NW_NULL_ASSERT(s_ModelRoot);
322 }
323 
324 /*!--------------------------------------------------------------------------*
325   @brief        カメラ関連の構築をします。
326  *---------------------------------------------------------------------------*/
327 void
BuildCameras()328 BuildCameras()
329 {
330     nw::demo::Utility::CreateStereoCameras(
331         &s_BaseCamera,
332         &s_LeftCamera,
333         &s_RightCamera,
334         &s_DeviceAllocator,
335         nw::math::VEC3(20.0f, 15.0f, 20.0f),
336         nw::math::VEC3(0.0f, 10.0f, 0.0f),
337         s_fNearPlane
338     );
339 
340     s_SceneRoot->AttachChild(s_BaseCamera);
341     s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
342 }
343 
344 /*!--------------------------------------------------------------------------*
345   @brief        リソース関連の構築をします。
346  *---------------------------------------------------------------------------*/
347 void
BuildResources(nw::demo::ResourceSet * resourceSet)348 BuildResources(nw::demo::ResourceSet* resourceSet)
349 {
350     resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
351     resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
352     resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
353 
354     nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
355     if (result.IsFailure())
356     {
357         NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
358     }
359 
360     nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(SCENE_NODE_COUNT, &s_DeviceAllocator);
361 
362     nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
363     nw::gfx::ResModelArray::iterator modelsEnd = models.end();
364     for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
365          modelResource != modelsEnd; ++modelResource)
366     {
367         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
368             &s_DeviceAllocator,
369             (*modelResource)
370         );
371         NW_NULL_ASSERT(node);
372         sceneNodeArray.push_back(node);
373         s_AnimModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(node);
374     }
375 
376     nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
377     nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
378     for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
379          lightResource != lightsEnd; ++lightResource)
380     {
381         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
382             &s_DeviceAllocator,
383             (*lightResource)
384         );
385         NW_NULL_ASSERT(node);
386         sceneNodeArray.push_back(node);
387     }
388 
389     // 親子付け参照関係を解決
390     nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
391 
392     // モデルをシーンに追加
393     nw::gfx::SceneHelper::ForeachRootNodes(
394         sceneNodeArray.Begin(),
395         sceneNodeArray.End(),
396         nw::gfx::AttachNode(s_ModelRoot)
397     );
398 
399     nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
400     nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
401     for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
402         settingResource != settingsEnd; ++settingResource)
403     {
404         nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
405             .Resource(*settingResource)
406             .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
407 
408         nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
409             nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
410 
411         NW_NULL_ASSERT(sceneEnvironmentSetting);
412         s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
413     }
414 }
415 
416 /*!--------------------------------------------------------------------------*
417   @brief        シーンを初期化します。
418  *---------------------------------------------------------------------------*/
419 void
InitializeScenes()420 InitializeScenes()
421 {
422     BuildRootNodes();
423 
424     BuildCameras();
425 
426     NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
427     {
428         BuildResources(nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator));
429     }
430 
431     s_AnimEvaluator = InitializeSkeletalAnim(s_AnimModel);
432     NW_NULL_ASSERT(s_AnimEvaluator);
433 
434     // シーンツリーを巡回して初期化を行います。
435     s_SceneSystem->InitializeScene(s_SceneRoot);
436     s_SceneSystem->UpdateScene();
437 
438     // シーン環境の参照解決を行い設定します。
439     s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
440 
441     // カメラを設定します。
442     nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
443     sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
444     nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
445 
446     NW_GL_ASSERT();
447 
448     s_FrameCount = 0;
449 }
450 
451 /*!--------------------------------------------------------------------------*
452   @brief        シーン関連の後始末をします。
453  *---------------------------------------------------------------------------*/
454 void
TerminateScenes()455 TerminateScenes()
456 {
457     nw::gfx::SafeDestroyBranch(s_SceneRoot);
458     nw::demo::SafeCleanupResources(s_Resources);
459     nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings);
460 
461     // 空のアニメーションリソースを破棄します。
462     s_DeviceAllocator.Free(s_ResAnimEmpty.ptr());
463     s_ResAnimEmpty = nw::anim::res::ResAnim(NULL);
464 
465     nw::ut::SafeDestroy(s_AnimEvaluator);
466 
467     NW_GL_ASSERT();
468 
469     s_Resources.clear();
470     s_SceneEnvironmentSettings.clear();
471     s_ModelRoot = NULL;
472 }
473 
474 /*!--------------------------------------------------------------------------*
475   @brief        シーンを更新します。
476  *---------------------------------------------------------------------------*/
477 void
UpdateScene()478 UpdateScene()
479 {
480     ChangeAnimation(s_AnimModel);
481 
482     s_SceneSystem->GetCameraController()->Update();
483 
484     s_SceneSystem->UpdateScene();
485 
486     s_BaseCamera->UpdateCameraMatrix();
487 
488     s_RenderSystem->CalcStereoCamera(s_LeftCamera, s_RightCamera, s_BaseCamera, s_fNearPlane + 5.0f);
489 
490     ++s_FrameCount;
491 }
492 
493 /*!--------------------------------------------------------------------------*
494   @brief        負荷表示やテスト機能の処理をおこないます。
495  *---------------------------------------------------------------------------*/
496 void
ReportDemo()497 ReportDemo()
498 {
499     NW_PROFILE("ReportDemo");
500 
501     // 負荷表示からはこれらの負荷は除きます。
502     s_RenderSystem->SuspendLoadMeter();
503 
504     nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
505 
506     s_GraphicsDrawing.BeginDrawingShape();
507 
508     nw::demo::DebugUtility::DrawLoadMeter(
509         s_RenderSystem,
510         &s_GraphicsDrawing
511     );
512 
513     s_GraphicsDrawing.EndDrawingShape();
514 
515     s_GraphicsDrawing.BeginDrawingString();
516 
517     nw::demo::DebugUtility::DrawLoadMeterText(
518         s_RenderSystem,
519         &s_GraphicsDrawing
520     );
521 
522     s_GraphicsDrawing.EndDrawingString();
523 
524     s_RenderSystem->ResumeLoadMeter();
525 }
526 
527 /*!--------------------------------------------------------------------------*
528   @brief        シーンをデモンストレーションします。
529  *---------------------------------------------------------------------------*/
530 void
DemoScene()531 DemoScene()
532 {
533     NW_ASSERT(!s_RenderTargets.empty());
534 
535     nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
536 
537     InitializeScenes();
538 
539     nw::demo::DebugUtility::PostInitializeScenes();
540 
541     NW_LOG("[Animation Change Demo usage]\n");
542     NW_LOG("left/right: change animation\n");
543     NW_LOG("l         : change to empty animation\n");
544     NW_LOG("r         : reset\n");
545 
546     bool isContinuing = true;
547 
548     while ( isContinuing )
549     {
550         nw::demo::DebugUtility::AdvanceAutoTestFrame();
551 
552         nw::demo::PadFactory::GetPad()->Update();
553 
554         UpdateScene();
555 
556         renderContext->SetActiveCamera(s_BaseCameraIndex);
557         s_RenderSystem->SubmitView(s_SceneSystem);
558 
559         s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
560         s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
561 
562         s_RenderSystem->ClearBySkyModel(s_BaseCamera);
563         ReportDemo();
564         s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
565 
566         s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
567 
568         renderContext->ResetState();
569 
570         if (nw::demo::Utility::IsTerminating())
571         {
572             isContinuing = false;
573         }
574     }
575 
576     nw::demo::DebugUtility::PreTerminateScenes();
577 
578     TerminateScenes();
579 }
580 
581 } // namespace
582 
583 /*!--------------------------------------------------------------------------*
584   @brief        メイン関数です。
585  *---------------------------------------------------------------------------*/
586 void
nnMain()587 nnMain()
588 {
589     nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
590 
591     nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
592 
593     NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
594     {
595         InitializeGraphics();
596 
597         DemoScene();
598 
599         TerminateGraphics();
600     }
601 
602     nw::demo::PadFactory::Finalize();
603 
604     nw::demo::FinalizeGraphicsSystem();
605 }
606