1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     FastCreateDemo.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: $
16  *---------------------------------------------------------------------------*/
17 
18 // FastCreateDemo はフレームヒープアロケータを使用して、
19 // 高速にオブジェクトの生成と破棄を行なうデモです。
20 //
21 // 詳しくはドキュメント、および
22 // PrepareBuilder(), BuildLattices(), DestroyLattices() などの実装を
23 // 参照してください。
24 
25 #define NW_DEBUG_CHECK_MEMORY_LEAK
26 
27 // オブジェクトの生成にフレームヒープアロケータを使用します。
28 #define USE_FRAME_HEAP
29 
30 #include <nn/os.h>
31 #include <nn/fs.h>
32 
33 #include <nw/types.h>
34 #include <nw/demo.h>
35 #include <nw/dev.h>
36 #include <nw/gfx.h>
37 #include <nw/ut.h>
38 
39 namespace
40 {
41 
42 //----------------------------------------
43 // メモリ関係
44 
45 // デバイスメモリを確保するためのアロケータです。
46 nw::demo::DemoAllocator s_DeviceAllocator;
47 
48 // フレームヒープアロケータです。
49 nw::demo::FrameHeapAllocator s_FrameHeapAllocator;
50 
51 //----------------------------------------
52 // ファイル名の定義です。
53 const wchar_t* SKY_SPHERE_FILE_NAME  = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
54 
55 const wchar_t* MODEL_RESOURCE_FILES[] =
56 {
57     NW_DEMO_FILE_PATH(L"Beam.bcmdl"),
58     NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
59     NW_DEMO_FILE_PATH(L"FragmentLight.bcenv"),
60 };
61 
62 //----------------------------------------
63 // 描画関係
64 const int RENDER_TARGET_COUNT = 1;
65 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
66 
67 RenderTargetArray s_RenderTargets;
68 nw::demo::SceneSystem*  s_SceneSystem = NULL;
69 nw::demo::RenderSystem* s_RenderSystem = NULL;
70 
71 static nw::demo::GraphicsDrawing  s_GraphicsDrawing;
72 //----------------------------------------
73 // リソース関係
74 nw::demo::ResourceArray s_Resources;
75 
76 //----------------------------------------
77 // シーン関係
78 nw::gfx::TransformNode* s_SceneRoot = NULL;
79 nw::gfx::TransformNode* s_ModelRoot = NULL;
80 s32 s_FrameCount = 0;
81 nw::gfx::Camera* s_BaseCamera = NULL;
82 nw::gfx::Camera* s_LeftCamera = NULL;
83 nw::gfx::Camera* s_RightCamera = NULL;
84 const f32 s_fNearPlane = 0.1f;
85 
86 const s32 s_BaseCameraIndex = 0;
87 
88 //----------------------------------------
89 // シーン環境関係
90 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
91 
92 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
93 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
94 
95 //----------------------------------------
96 // モデル関係
97 const int LATTICE_WIDTH = 2;
98 const int LATTICE_COUNT = (LATTICE_WIDTH * 2) * (LATTICE_WIDTH * 2) * (LATTICE_WIDTH * 2);
99 
100 const f32 LATTICE_SIZE = 14.0f;
101 
102 const int MODEL_PER_LATTICE = 3;
103 const int NODE_PER_LATTICE = MODEL_PER_LATTICE + 1;
104 
105 nw::gfx::ResSceneNode s_ResBeam;
106 
107 nw::gfx::SceneBuilder s_BeamBuilder;
108 nw::gfx::TransformNode::DynamicBuilder s_LatticeRootBuilder;
109 size_t s_SizeOfLattice;
110 
111 struct Lattice
112 {
113     nw::gfx::TransformNode* root;
114     nw::math::VEC3 position;
115 };
116 
117 typedef nw::ut::FixedSizeArray<Lattice, LATTICE_COUNT> LatticeArray;
118 LatticeArray s_Lattices;
119 
120 f32 s_PhaseAxis = 0.0f;
121 f32 s_PhaseRot = 0.0f;
122 f32 s_PhaseScale = 0.0f;
123 
124 const f32 STEP_PHASE_AXIS = 0.012f;
125 const f32 STEP_PHASE_ROT = 0.14f;
126 const f32 STEP_PHASE_SCALE = 0.004f;
127 
128 /*!--------------------------------------------------------------------------*
129   @brief        グラフィックス関連の初期化を行います。
130  *---------------------------------------------------------------------------*/
131 void
InitializeGraphics()132 InitializeGraphics()
133 {
134     nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
135 
136     // renderDescriptionへステレオの設定を行います。
137     nw::demo::RenderSystem::Description renderDescription;
138 
139     renderDescription.reusableCommandBufferSize = 0x100000;
140     renderDescription.reusableCommandRequestCount      = 512;
141     renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
142 
143     s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
144 
145     s_GraphicsDrawing.SetScreenSize(
146         renderDescription.lowerScreenDescription.width,
147         renderDescription.lowerScreenDescription.height
148     );
149 
150     nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
151 
152     s_RenderTargets.push_back(
153         nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
154     );
155     NW_ASSERT(!s_RenderTargets.empty());
156     s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
157 
158     // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
159     nw::demo::SceneSystem::Description sceneDescription;
160 
161     sceneDescription.maxSceneNodes = NODE_PER_LATTICE * LATTICE_COUNT + 4;
162     sceneDescription.maxModels = MODEL_PER_LATTICE * LATTICE_COUNT;
163     sceneDescription.maxMaterials = MODEL_PER_LATTICE * LATTICE_COUNT;
164 
165     s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
166 
167     // デモ用の最遠景モデルをレンダリングシステムに設定します。
168     // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
169     s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
170 
171     NW_GL_ASSERT();
172 }
173 
174 /*!--------------------------------------------------------------------------*
175   @brief        グラフィックス関連の後始末をします。
176  *---------------------------------------------------------------------------*/
177 void
TerminateGraphics()178 TerminateGraphics()
179 {
180     nw::gfx::SafeDestroy(s_LeftCamera);
181 
182     nw::gfx::SafeDestroy(s_RightCamera);
183 
184     nw::gfx::SafeDestroy(s_SceneSystem);
185 
186     nw::gfx::SafeDestroyAll(s_RenderTargets);
187 
188     s_GraphicsDrawing.Finalize();
189 
190     nw::gfx::SafeDestroy(s_RenderSystem);
191 
192     NW_GL_ASSERT();
193 }
194 
195 /*!--------------------------------------------------------------------------*
196   @brief        ルートノード関連の構築をします。
197  *---------------------------------------------------------------------------*/
198 void
BuildRootNodes()199 BuildRootNodes()
200 {
201     NW_ASSERT(s_SceneRoot == NULL);
202     s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
203         .Create(&s_DeviceAllocator);
204     NW_NULL_ASSERT(s_SceneRoot);
205 
206     NW_ASSERT(s_ModelRoot == NULL);
207     s_ModelRoot = nw::gfx::TransformNode::DynamicBuilder()
208         .MaxChildren(LATTICE_COUNT)
209         .Create(&s_DeviceAllocator);
210     s_SceneRoot->AttachChild(s_ModelRoot);
211     NW_NULL_ASSERT(s_ModelRoot);
212 }
213 
214 /*!--------------------------------------------------------------------------*
215   @brief        カメラ関連の構築をします。
216  *---------------------------------------------------------------------------*/
217 void
BuildCameras()218 BuildCameras()
219 {
220     nw::demo::Utility::CreateStereoCameras(
221         &s_BaseCamera,
222         &s_LeftCamera,
223         &s_RightCamera,
224         &s_DeviceAllocator,
225         nw::math::VEC3(60.0f, 40.0f, 45.0f),
226         nw::math::VEC3(0.0f, 0.0f, 0.0f),
227         s_fNearPlane
228     );
229 
230     s_SceneRoot->AttachChild(s_BaseCamera);
231     s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
232 }
233 
234 /*!--------------------------------------------------------------------------*
235   @brief        リソース関連の構築をします。
236  *---------------------------------------------------------------------------*/
237 void
BuildResources(nw::demo::ResourceSet * resourceSet)238 BuildResources(nw::demo::ResourceSet* resourceSet)
239 {
240     resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
241     resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
242     resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
243 
244     nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
245     if (result.IsFailure())
246     {
247         NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
248     }
249 
250     nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(&s_DeviceAllocator);
251 
252     nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
253     if (models.size() > 0)
254     {
255         // モデルのリソースを記憶しておきます。
256         s_ResBeam = models[0];
257     }
258 
259     nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
260     nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
261     for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
262          lightResource != lightsEnd; ++lightResource)
263     {
264         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
265             &s_DeviceAllocator,
266             (*lightResource)
267         );
268         NW_NULL_ASSERT(node);
269         sceneNodeArray.push_back(node);
270     }
271 
272     // 親子付け参照関係を解決
273     nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
274 
275     // モデルをシーンに追加
276     nw::gfx::SceneHelper::ForeachRootNodes(
277         sceneNodeArray.Begin(),
278         sceneNodeArray.End(),
279         nw::gfx::AttachNode(s_SceneRoot)
280     );
281 
282     nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
283     nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
284     for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
285         settingResource != settingsEnd; ++settingResource)
286     {
287         nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
288             .Resource(*settingResource)
289             .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
290 
291         nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
292             nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
293 
294         NW_NULL_ASSERT(sceneEnvironmentSetting);
295         s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
296     }
297 }
298 
299 /*!--------------------------------------------------------------------------*
300   @brief        モデルを作成します。
301  *---------------------------------------------------------------------------*/
302 void
BuildLattices()303 BuildLattices()
304 {
305     nw::os::IAllocator* allocator;
306 
307 #ifdef USE_FRAME_HEAP
308     // 必要なサイズのメモリをまとめて確保し、
309     // フレームヒープアロケータにそのメモリを渡して初期化します。
310 
311     size_t memorySize = s_SizeOfLattice * LATTICE_COUNT;
312     void* memory = s_DeviceAllocator.Alloc(memorySize);
313     s_FrameHeapAllocator.Initialize(reinterpret_cast<uptr>(memory), memorySize);
314 
315     allocator = &s_FrameHeapAllocator;
316 #else
317     allocator = &s_DeviceAllocator;
318 #endif
319 
320 
321     for (int x = -LATTICE_WIDTH ; x < LATTICE_WIDTH ; ++x)
322     {
323         for (int y = -LATTICE_WIDTH ; y < LATTICE_WIDTH ; ++y)
324         {
325             for (int z = -LATTICE_WIDTH ; z < LATTICE_WIDTH ; ++z)
326             {
327                 nw::gfx::TransformNode* root = s_LatticeRootBuilder.Create(allocator);
328 
329                 Lattice lattice;
330                 lattice.position = nw::math::VEC3(
331                     LATTICE_SIZE * x + LATTICE_SIZE * 0.5f,
332                     LATTICE_SIZE * y + LATTICE_SIZE * 0.5f,
333                     LATTICE_SIZE * z + LATTICE_SIZE * 0.5f);
334                 lattice.root = root;
335 
336                 for (int i = 0 ; i < 3 ; ++i)
337                 {
338                     nw::gfx::SceneObject* sceneObject =
339                         s_BeamBuilder.CreateObject(allocator, allocator);
340 
341                     nw::gfx::Model* beam =
342                         reinterpret_cast<nw::gfx::Model*>(sceneObject);
343 
344                     beam->Transform().SetRotateXYZ(
345                         (i == 1 ? nn::math::F_PI * 0.5f : 0.0f),
346                         (i == 2 ? nn::math::F_PI * 0.5f : 0.0f),
347                         0.0f);
348 
349                     root->AttachChild(beam);
350                 }
351 
352                 s_Lattices.push_back(lattice);
353                 s_ModelRoot->AttachChild(root);
354             }
355         }
356     }
357 }
358 
359 /*!--------------------------------------------------------------------------*
360   @brief        すべてのモデルを破棄します。
361  *---------------------------------------------------------------------------*/
362 void
DestroyLattices()363 DestroyLattices()
364 {
365     s_ModelRoot->DetachAllChildren();
366 
367 #ifdef USE_FRAME_HEAP
368     // フレームヒープを使用してモデルを作成した場合、
369     // 確保したメモリをまとめて破棄することで、
370     // Destroy の呼び出しを省略することができます。
371 
372     void* memory = reinterpret_cast<void*>(s_FrameHeapAllocator.GetStartAddress());
373 
374     s_FrameHeapAllocator.Finalize();
375 
376     s_DeviceAllocator.Free(memory);
377 #else
378     // 拡張ヒープを使用してモデルを作成した場合、
379     // それぞれ Destroy を呼んで、
380     // 適切にメモリを解放する必要があります。
381 
382     LatticeArray::iterator end = s_Lattices.end();
383     for (LatticeArray::iterator model = s_Lattices.begin();
384         model != end;
385         ++model)
386     {
387         (*model).root->DestroyBranch();
388     }
389 #endif
390 
391     s_Lattices.clear();
392 }
393 
394 /*!--------------------------------------------------------------------------*
395   @brief        モデルの位置を更新し、また再作成を行ないます。
396  *---------------------------------------------------------------------------*/
397 void
UpdateLattices()398 UpdateLattices()
399 {
400     DestroyLattices();
401     BuildLattices();
402 
403     // 各格子の位置を計算します。
404     f32 scale = -nw::math::CosRad(s_PhaseScale) * 0.5f + 0.5f;
405 
406     nw::math::VEC3 axis(0.0f, 0.0f, 0.0f);
407     nw::math::SinCosRad(&axis.x, &axis.y, s_PhaseAxis);
408 
409     nw::math::MTX34 mat;
410     nw::math::MTX34RotAxisDeg(&mat, &axis, s_PhaseRot);
411 
412     LatticeArray::iterator end = s_Lattices.end();
413     for (LatticeArray::iterator model = s_Lattices.begin();
414         model != end;
415         ++model)
416     {
417         nw::math::VEC3 pos = (*model).position * scale;
418         VEC3TransformNormal(&pos, &mat, &pos);
419         (*model).root->Transform().SetTranslate(pos);
420     }
421 
422     s_PhaseAxis += STEP_PHASE_AXIS;
423     s_PhaseRot += STEP_PHASE_ROT;
424     s_PhaseScale += STEP_PHASE_SCALE;
425 }
426 
427 /*!--------------------------------------------------------------------------*
428   @brief        ノードの Builder の準備を行ないます。
429  *---------------------------------------------------------------------------*/
430 void
PrepareBuilder()431 PrepareBuilder()
432 {
433     NW_ASSERT(s_ResBeam.IsValid());
434 
435     // 各 Builder を設定します。
436     s_BeamBuilder
437         .Resource(s_ResBeam)
438         .MaxCallbacks(0)
439         .MaxChildren(0)
440         .BufferOption(nw::gfx::Model::FLAG_BUFFER_NOT_USE)
441         .IsAnimationEnabled(false);
442 
443     s_LatticeRootBuilder
444         .MaxCallbacks(0)
445         .MaxChildren(3);
446 
447     // 1つの格子を生成するために必要なメモリサイズを計算します。
448     s_SizeOfLattice =
449         s_BeamBuilder.GetMemorySize() * 3 +
450         s_LatticeRootBuilder.GetMemorySize();
451 }
452 
453 /*!--------------------------------------------------------------------------*
454   @brief        シーンを初期化します。
455  *---------------------------------------------------------------------------*/
456 void
InitializeScenes()457 InitializeScenes()
458 {
459     BuildRootNodes();
460 
461     BuildCameras();
462 
463     NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
464     {
465         BuildResources(nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator));
466     }
467 
468     PrepareBuilder();
469     BuildLattices();
470 
471     // シーンツリーを巡回して初期化を行います。
472     s_SceneSystem->InitializeScene(s_SceneRoot);
473     s_SceneSystem->UpdateScene();
474 
475     // シーン環境の参照解決を行い設定します。
476     s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
477 
478     // カメラを設定します。
479     nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
480     sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
481     nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
482 
483     NW_GL_ASSERT();
484 
485     s_FrameCount = 0;
486 
487     s_PhaseAxis = 0.0f;
488     s_PhaseRot = 0.0f;
489     s_PhaseScale = 0.0f;
490 }
491 
492 /*!--------------------------------------------------------------------------*
493   @brief        シーン関連の後始末をします。
494  *---------------------------------------------------------------------------*/
495 void
TerminateScenes()496 TerminateScenes()
497 {
498     DestroyLattices();
499 
500     nw::gfx::SafeDestroyBranch(s_SceneRoot);
501     nw::demo::SafeCleanupResources(s_Resources);
502     nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings);
503 
504     NW_GL_ASSERT();
505 
506     s_Resources.clear();
507     s_SceneEnvironmentSettings.clear();
508     s_Lattices.clear();
509     s_ModelRoot = NULL;
510 }
511 
512 /*!--------------------------------------------------------------------------*
513   @brief        シーンを更新します。
514  *---------------------------------------------------------------------------*/
515 void
UpdateScene()516 UpdateScene()
517 {
518     UpdateLattices();
519 
520     s_SceneSystem->GetCameraController()->Update();
521 
522     s_SceneSystem->UpdateScene();
523 
524     s_BaseCamera->UpdateCameraMatrix();
525 
526     nw::gfx::ResCameraProjectionUpdater resProjectionUpdater =
527         s_BaseCamera->GetProjectionUpdater()->GetResource();
528 
529     int near = resProjectionUpdater.GetNear();
530 
531     s_RenderSystem->CalcStereoCamera(
532         s_LeftCamera,
533         s_RightCamera,
534         s_BaseCamera,
535         near + 5.0f);
536 
537     ++s_FrameCount;
538 }
539 
540 /*!--------------------------------------------------------------------------*
541   @brief        負荷表示やテスト機能の処理をおこないます。
542  *---------------------------------------------------------------------------*/
543 void
ReportDemo()544 ReportDemo()
545 {
546     NW_PROFILE("ReportDemo");
547 
548     // 負荷表示からはこれらの負荷は除きます。
549     s_RenderSystem->SuspendLoadMeter();
550 
551     nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
552 
553     s_GraphicsDrawing.BeginDrawingShape();
554 
555     nw::demo::DebugUtility::DrawLoadMeter(
556         s_RenderSystem,
557         &s_GraphicsDrawing
558     );
559 
560     s_GraphicsDrawing.EndDrawingShape();
561 
562     s_GraphicsDrawing.BeginDrawingString();
563 
564     nw::demo::DebugUtility::DrawLoadMeterText(
565         s_RenderSystem,
566         &s_GraphicsDrawing
567     );
568 
569     s_GraphicsDrawing.EndDrawingString();
570 
571     s_RenderSystem->ResumeLoadMeter();
572 }
573 
574 /*!--------------------------------------------------------------------------*
575   @brief        シーンをデモンストレーションします。
576  *---------------------------------------------------------------------------*/
577 void
DemoScene()578 DemoScene()
579 {
580     NW_ASSERT(!s_RenderTargets.empty());
581 
582     nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
583 
584     InitializeScenes();
585 
586     nw::demo::DebugUtility::PostInitializeScenes();
587 
588     bool isContinuing = true;
589 
590     while ( isContinuing )
591     {
592         nw::demo::DebugUtility::AdvanceAutoTestFrame();
593 
594         nw::demo::PadFactory::GetPad()->Update();
595 
596         UpdateScene();
597 
598         renderContext->SetActiveCamera(s_BaseCameraIndex);
599         s_RenderSystem->SubmitView(s_SceneSystem);
600 
601         s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
602         s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
603 
604         s_RenderSystem->ClearBySkyModel(s_BaseCamera);
605         ReportDemo();
606         s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
607 
608         s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
609 
610         renderContext->ResetState();
611 
612         if (nw::demo::Utility::IsTerminating())
613         {
614             isContinuing = false;
615         }
616     }
617 
618     nw::demo::DebugUtility::PreTerminateScenes();
619 
620     TerminateScenes();
621 }
622 
623 } // namespace
624 
625 /*!--------------------------------------------------------------------------*
626   @brief        メイン関数です。
627  *---------------------------------------------------------------------------*/
628 void
nnMain()629 nnMain()
630 {
631     nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
632 
633     nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
634 
635     NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
636     {
637         InitializeGraphics();
638 
639         DemoScene();
640 
641         TerminateGraphics();
642     }
643 
644     nw::demo::PadFactory::Finalize();
645 
646     nw::demo::FinalizeGraphicsSystem();
647 }
648