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