1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     ParticleUpdaterDemo.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: 31311 $
16  *---------------------------------------------------------------------------*/
17 /*
18 現在は、UserUpdaterをCreativeStudio上で追加することができないので、
19 中間ファイルのParticleUpdatersのリスト内に
20 
21 <ParticleUserUpdaterXml IsUpdaterEnabled="true" UserParameter="0">
22     <ParticleAnimationData />
23     <TargetStreams />
24 </ParticleUserUpdaterXml>
25 
26 を追加してください。
27 
28 ParticleUpdatersはParticleSet毎の設定です。
29 */
30 
31 
32 #define NW_DEBUG_CHECK_MEMORY_LEAK
33 
34 #include <nn/os.h>
35 #include <nn/fs.h>
36 
37 #include <nw/types.h>
38 #include <nw/demo.h>
39 #include <nw/dev.h>
40 #include <nw/gfx.h>
41 #include <nw/ut.h>
42 
43 namespace
44 {
45 
46 //----------------------------------------
47 // メモリ関係
48 
49 // デバイスメモリを確保するためのアロケータです。
50 nw::demo::DemoAllocator s_DeviceAllocator;
51 nw::demo::DemoAllocator s_ParticleAllocator;
52 
53 //----------------------------------------
54 // ファイル名の定義です。
55 const wchar_t* SKY_SPHERE_FILE_NAME  = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
56 
57 const wchar_t* MODEL_RESOURCE_FILES[] =
58 {
59     NW_DEMO_FILE_PATH(L"fountain_particle_all.bcptl"),
60     NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
61     NW_DEMO_FILE_PATH(L"FragmentLight.bcenv"),
62 };
63 
64 //----------------------------------------
65 // 描画関係
66 const int RENDER_TARGET_COUNT = 1;
67 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
68 
69 RenderTargetArray s_RenderTargets;
70 nw::demo::SceneSystem*  s_SceneSystem = NULL;
71 nw::demo::RenderSystem* s_RenderSystem = NULL;
72 nw::gfx::ParticleContext* s_ParticleContext = NULL;
73 
74 nw::demo::GraphicsDrawing  s_GraphicsDrawing;
75 
76 //----------------------------------------
77 // リソース関係
78 nw::demo::ResourceArray s_Resources;
79 
80 //----------------------------------------
81 // シーン関係
82 nw::gfx::SceneNode* s_SceneRoot = NULL;
83 s32 s_FrameCount = 0;
84 nw::gfx::Camera* s_BaseCamera = NULL;
85 nw::gfx::Camera* s_LeftCamera = NULL;
86 nw::gfx::Camera* s_RightCamera = NULL;
87 const f32 s_fNearPlane = 0.1f;
88 
89 //----------------------------------------
90 // シーン環境関係
91 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
92 
93 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
94 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
95 
96 const s32 s_BaseCameraIndex = 0;
97 
98 //----------------------------------------
99 // パーティクル関係
100 nw::gfx::ParticleSceneUpdater* s_ParticleSceneUpdater = NULL;
101 
102 nw::demo::FlushCache* s_FlushCache;
103 
104 
105 /*!--------------------------------------------------------------------------*
106   @brief        グラフィックス関連の初期化を行います。
107  *---------------------------------------------------------------------------*/
108 void
InitializeGraphics()109 InitializeGraphics()
110 {
111     nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
112 
113     // renderDescriptionへステレオの設定を行います。
114     nw::demo::RenderSystem::Description renderDescription;
115 
116     renderDescription.reusableCommandBufferSize = 0x100000;
117     renderDescription.reusableCommandRequestCount      = 512;
118     renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
119 
120     s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
121 
122     s_GraphicsDrawing.SetScreenSize(
123         renderDescription.lowerScreenDescription.width,
124         renderDescription.lowerScreenDescription.height
125     );
126 
127     nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
128 
129     s_RenderTargets.push_back(
130         nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
131     );
132     NW_ASSERT(!s_RenderTargets.empty());
133     s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
134 
135     // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
136     nw::demo::SceneSystem::Description sceneDescription;
137     s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
138 
139     s_ParticleContext = nw::gfx::ParticleContext::Builder()
140         .MaxEmission(1000)
141         .Create(&s_DeviceAllocator);
142 
143     s_ParticleSceneUpdater = nw::gfx::ParticleSceneUpdater::Builder()
144         .Create(&s_DeviceAllocator);
145 
146     // デモ用の最遠景モデルをレンダリングシステムに設定します。
147     // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
148     s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
149 
150     NW_GL_ASSERT();
151 }
152 
153 /*!--------------------------------------------------------------------------*
154   @brief        グラフィックス関連の後始末をします。
155  *---------------------------------------------------------------------------*/
156 void
TerminateGraphics()157 TerminateGraphics()
158 {
159     nw::gfx::SafeDestroy(s_LeftCamera);
160 
161     nw::gfx::SafeDestroy(s_RightCamera);
162 
163     nw::gfx::SafeDestroy(s_ParticleSceneUpdater);
164 
165     nw::gfx::SafeDestroy(s_ParticleContext);
166 
167     nw::gfx::SafeDestroy(s_SceneSystem);
168 
169     nw::gfx::SafeDestroyAll(s_RenderTargets);
170 
171     s_GraphicsDrawing.Finalize();
172 
173     nw::gfx::SafeDestroy(s_RenderSystem);
174 
175     NW_GL_ASSERT();
176 }
177 
178 /*!--------------------------------------------------------------------------*
179   @brief        再生ステップを設定します。
180 
181   @param[in]    再生ステップです。
182  *---------------------------------------------------------------------------*/
183 void
SetStepFrame(f32 stepFrame)184 SetStepFrame(f32 stepFrame)
185 {
186     nw::gfx::SceneContext* sceneContext = s_SceneSystem->GetSceneContext();
187 
188     nw::gfx::SceneNodeArray::iterator end = sceneContext->GetSceneNodesEnd();
189     for (nw::gfx::SceneNodeArray::iterator i = sceneContext->GetSceneNodesBegin(); i != end; ++i)
190     {
191         nw::gfx::ParticleEmitter* emitter = nw::ut::DynamicCast<nw::gfx::ParticleEmitter*>(*i);
192         if (emitter != NULL)
193         {
194             emitter->ParticleAnimFrameController().SetStepFrame(stepFrame);
195         }
196         else
197         {
198             nw::gfx::ParticleModel* model = nw::ut::DynamicCast<nw::gfx::ParticleModel*>(*i);
199             if (model != NULL)
200             {
201                 model->ParticleAnimFrameController().SetStepFrame(stepFrame);
202             }
203         }
204     }
205 }
206 
207 /*!--------------------------------------------------------------------------*
208   @brief        ユーザ定義のアップデータです
209  *---------------------------------------------------------------------------*/
UserUpdater(nw::gfx::ParticleContext * context,nw::gfx::ParticleSet * particleSet,const nw::gfx::ResParticleUserUpdater * userUpdater,f32 prevTime,f32 time)210 static void UserUpdater(
211         nw::gfx::ParticleContext* context,
212         nw::gfx::ParticleSet* particleSet,
213         const nw::gfx::ResParticleUserUpdater* userUpdater,
214         f32 prevTime,
215         f32 time
216 )
217 {
218     NW_UNUSED_VARIABLE(context);
219     NW_UNUSED_VARIABLE(particleSet);
220     NW_UNUSED_VARIABLE(userUpdater);
221     NW_UNUSED_VARIABLE(prevTime);
222     NW_UNUSED_VARIABLE(time);
223 
224     nw::gfx::ParticleCollection* collection = particleSet->GetParticleCollection();
225     NW_NULL_ASSERT(collection);
226 
227     // 有効なパーティクルの個数
228     const int count = collection->GetCount();
229     if (count == 0)
230     {
231         return;
232     }
233 
234     // 有効なパーティクルへのインデックス・テーブル
235     // 必ずPARTICLE_BUFFER_BACKから取得してください
236     u16* activeIndex =
237         (u16*)collection->GetStreamPtr(
238             nw::gfx::PARTICLEUSAGE_ACTIVEINDEX,
239             nw::gfx::PARTICLE_BUFFER_BACK);
240 
241     // ACTIVEINDEX以外はPARTICLE_BUFFER_FRONTから取得します。
242     nw::math::VEC3* translate =
243         (nw::math::VEC3*)collection->GetStreamPtr(
244             nw::gfx::PARTICLEUSAGE_TRANSLATE,
245             nw::gfx::PARTICLE_BUFFER_FRONT);
246     if (translate == NULL)
247     {
248         // アニメーションが元々付いていない場合などは固定値の扱いとなります
249         // 粒子毎の設定が要らない場合は、Shapeのアトリビュートを変更するほうが効率的です
250         return;
251     }
252 
253     nw::math::VEC3* velocity =
254         (nw::math::VEC3*)collection->GetStreamPtr(
255             nw::gfx::PARTICLEUSAGE_VELOCITY,
256             nw::gfx::PARTICLE_BUFFER_FRONT);
257     if (velocity == NULL)
258     {
259         return;
260     }
261 
262     const bool isAscendingOrder = particleSet->IsAscendingOrder();
263     const int startIndex = (isAscendingOrder) ? 0 : collection->GetCapacity() - 1;
264     const int incrIndex = (isAscendingOrder) ? 1 : -1;
265     activeIndex += startIndex;
266 
267     for (int i = 0; i < count; ++i)
268     {
269         int index = *activeIndex;
270         activeIndex += incrIndex;
271 
272         nw::math::VEC3 nextPosition;
273         nextPosition = translate[index] + velocity[index];
274 
275         if (nextPosition.x > 2.0f)
276         {
277 #if 1 // 反射
278             velocity[index].x *= -1.0f;
279             velocity[index].z *= -1.0f;
280 #else // 消滅
281             collection->KillParticle(index);
282 #endif
283         }
284     }
285 }
286 
287 /*!--------------------------------------------------------------------------*
288   @brief        ユーザ定義のアップデータを設定します
289 
290   @param[in]    sceneNodeArray シーンノードのアレイです。
291 
292  *---------------------------------------------------------------------------*/
293 void
SetUserUpdater(nw::ut::MoveArray<nw::gfx::SceneNode * > * sceneNodeArray)294 SetUserUpdater(
295     nw::ut::MoveArray<nw::gfx::SceneNode*> *sceneNodeArray
296 )
297 {
298     NW_NULL_ASSERT(sceneNodeArray);
299 
300     NW_FOREACH(nw::gfx::SceneNode* node, *sceneNodeArray)
301     {
302         switch (node->GetResSceneNode().ptr()->typeInfo)
303         {
304         case nw::gfx::ResParticleModel::TYPE_INFO:
305             {
306                 nw::gfx::ParticleModel* model = reinterpret_cast<nw::gfx::ParticleModel*>(node);
307 
308                 for (u32 i = 0; i < model->GetParticleSetsCount(); ++i)
309                 {
310                     nw::gfx::ParticleSet* particleSet = model->GetParticleSets(i);
311 
312                     nw::ut::MoveArray<nw::gfx::ParticleSet::Updater>* updaters =
313                         particleSet->GetUpdaters();
314 
315                     nw::ut::MoveArray<nw::gfx::ParticleSet::Updater>::iterator endIter = updaters->end();
316                     for (nw::ut::MoveArray<nw::gfx::ParticleSet::Updater>::iterator iter = updaters->begin();
317                         iter != endIter;)
318                     {
319                         nw::gfx::ParticleSet::Updater& updater = *iter++;
320 
321                         nw::gfx::ResParticleUpdater resUpdater(updater.resource);
322                         NW_ASSERT(resUpdater.IsValid());
323 
324                         if (resUpdater.GetTypeInfo() == nw::gfx::ResParticleUserUpdater::TYPE_INFO)
325                         {
326                             nw::gfx::ResParticleUserUpdater userUpdater =
327                                 nw::gfx::ResDynamicCast<nw::gfx::ResParticleUserUpdater>(resUpdater);
328 
329                             updater.work = (u32)UserUpdater;
330                         }
331                     }
332                 }
333             }
334             break;
335         }
336     }
337 }
338 
339 /*!--------------------------------------------------------------------------*
340   @brief        ルートノード関連の構築をします。
341  *---------------------------------------------------------------------------*/
342 void
BuildRootNodes()343 BuildRootNodes()
344 {
345     NW_ASSERT(s_SceneRoot == NULL);
346     s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
347         .IsFixedSizeMemory(false)
348         .Create(&s_DeviceAllocator);
349     NW_NULL_ASSERT(s_SceneRoot);
350 }
351 
352 /*!--------------------------------------------------------------------------*
353   @brief        カメラ関連の構築をします。
354  *---------------------------------------------------------------------------*/
355 void
BuildCameras()356 BuildCameras()
357 {
358     nw::demo::Utility::CreateStereoCameras(
359         &s_BaseCamera,
360         &s_LeftCamera,
361         &s_RightCamera,
362         &s_DeviceAllocator,
363         nw::math::VEC3(28.0f, 22.0f, 28.0f),
364         nw::math::VEC3(0.0f, 0.0f, 0.0f),
365         s_fNearPlane
366     );
367 
368     s_SceneRoot->AttachChild(s_BaseCamera);
369     s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
370 }
371 
372 /*!--------------------------------------------------------------------------*
373   @brief        リソース関連の構築をします。
374  *---------------------------------------------------------------------------*/
375 void
BuildResources(nw::demo::ResourceSet * resourceSet)376 BuildResources(nw::demo::ResourceSet* resourceSet)
377 {
378     resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
379     resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
380     resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
381 
382     nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
383 
384     if (result.IsFailure())
385     {
386         NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
387     }
388 
389     nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(&s_DeviceAllocator);
390 
391     nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
392     nw::gfx::ResModelArray::iterator modelsEnd = models.end();
393     for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
394          modelResource != modelsEnd; ++modelResource)
395     {
396         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
397             &s_ParticleAllocator,
398             (*modelResource)
399         );
400         if (node != NULL)
401         {
402             sceneNodeArray.push_back(node);
403         }
404     }
405 
406     nw::gfx::ResEmitterArray emitters = resourceSet->resource.GetEmitters();
407     for (nw::gfx::ResEmitterArray::iterator emitterResource = emitters.begin();
408          emitterResource != emitters.end(); ++emitterResource)
409     {
410         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
411             &s_ParticleAllocator,
412             (*emitterResource)
413         );
414         if (node != NULL)
415         {
416             sceneNodeArray.push_back(node);
417         }
418     }
419 
420     nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
421     for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
422          lightResource != lights.end(); ++lightResource)
423     {
424         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
425             &s_DeviceAllocator,
426             (*lightResource)
427         );
428         NW_NULL_ASSERT(node);
429         sceneNodeArray.push_back(node);
430     }
431 
432     // 親子付け参照関係を解決
433     nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
434 
435     nw::gfx::ParticleUtil::SetupParticleObject(&sceneNodeArray, s_ParticleContext);
436 
437     SetUserUpdater(&sceneNodeArray);
438 
439     // モデルとエミッタをシーンに追加
440     nw::gfx::SceneHelper::ForeachRootNodes(
441         sceneNodeArray.Begin(),
442         sceneNodeArray.End(),
443         nw::gfx::AttachNode(s_SceneRoot)
444     );
445 
446     nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
447     nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
448     for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
449         settingResource != settingsEnd; ++settingResource)
450     {
451         nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
452             .Resource(*settingResource)
453             .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
454 
455         nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
456             nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
457 
458         NW_NULL_ASSERT(sceneEnvironmentSetting);
459         s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
460     }
461 }
462 /*!--------------------------------------------------------------------------*
463   @brief        シーンを初期化します。
464  *---------------------------------------------------------------------------*/
465 void
InitializeScenes()466 InitializeScenes()
467 {
468     BuildRootNodes();
469 
470     BuildCameras();
471 
472     NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
473     {
474         BuildResources(nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator));
475     }
476 
477     // シーンツリーを巡回して初期化を行います。
478     s_SceneSystem->InitializeScene(s_SceneRoot);
479     s_SceneSystem->UpdateScene();
480 
481     // シーン環境の参照解決を行い設定します。
482     s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
483 
484     // カメラを設定します。
485     nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
486     sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
487     nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
488 
489     NW_GL_ASSERT();
490 
491     s_FrameCount = 0;
492 }
493 
494 /*!--------------------------------------------------------------------------*
495   @brief        シーン関連の後始末をします。
496  *---------------------------------------------------------------------------*/
497 void
TerminateScenes()498 TerminateScenes()
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 }
509 
510 /*!--------------------------------------------------------------------------*
511   @brief        シーンを更新します。
512  *---------------------------------------------------------------------------*/
513 void
UpdateScene()514 UpdateScene()
515 {
516     NW_ASSERT(0 < s_RenderTargets.size());
517 
518     s_SceneSystem->GetCameraController()->Update();
519 
520     s_SceneSystem->UpdateScene();
521 
522     s_BaseCamera->UpdateCameraMatrix();
523 
524     NW_NULL_ASSERT(s_ParticleSceneUpdater);
525     s_ParticleSceneUpdater->UpdateNode(
526         s_SceneSystem->GetSceneContext(),
527         s_ParticleContext);
528 
529     s_RenderSystem->CalcStereoCamera(s_LeftCamera, s_RightCamera, s_BaseCamera, s_fNearPlane + 5.0f);
530 
531     s_FrameCount++;
532 
533     s_FlushCache->Execute();
534 }
535 
536 /*!--------------------------------------------------------------------------*
537   @brief        負荷表示やテスト機能の処理をおこないます。
538  *---------------------------------------------------------------------------*/
539 void
ReportDemo()540 ReportDemo()
541 {
542     NW_PROFILE("ReportDemo");
543 
544     // 負荷表示からはこれらの負荷は除きます。
545     s_RenderSystem->SuspendLoadMeter();
546 
547     nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
548 
549     s_GraphicsDrawing.BeginDrawingShape();
550 
551     nw::demo::DebugUtility::DrawLoadMeter(
552         s_RenderSystem,
553         &s_GraphicsDrawing
554     );
555 
556     s_GraphicsDrawing.EndDrawingShape();
557 
558     s_GraphicsDrawing.BeginDrawingString();
559 
560     nw::demo::DebugUtility::DrawLoadMeterText(
561         s_RenderSystem,
562         &s_GraphicsDrawing
563     );
564 
565     s_GraphicsDrawing.EndDrawingString();
566 
567     s_RenderSystem->ResumeLoadMeter();
568 }
569 
570 /*!--------------------------------------------------------------------------*
571   @brief        シーンをデモンストレーションします。
572  *---------------------------------------------------------------------------*/
573 void
DemoScene()574 DemoScene()
575 {
576     NW_ASSERT(!s_RenderTargets.empty());
577 
578     nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
579 
580     InitializeScenes();
581 
582     nw::demo::DebugUtility::PostInitializeScenes();
583 
584     bool isContinuing = true;
585 
586     while ( isContinuing )
587     {
588         nw::demo::DebugUtility::AdvanceAutoTestFrame();
589 
590         nw::demo::PadFactory::GetPad()->Update();
591 
592         SetStepFrame(1.0f);
593         UpdateScene();
594 
595         renderContext->SetActiveCamera(s_BaseCameraIndex);
596         s_RenderSystem->SubmitView(s_SceneSystem);
597 
598         s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
599         s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
600 
601         s_RenderSystem->ClearBySkyModel(s_BaseCamera);
602         ReportDemo();
603         s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
604 
605         s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
606 
607         renderContext->ResetState();
608 
609         if (nw::demo::Utility::IsTerminating())
610         {
611             isContinuing = false;
612         }
613     }
614 
615     nw::demo::DebugUtility::PreTerminateScenes();
616 
617     TerminateScenes();
618 }
619 
620 } // namespace
621 
622 /*!--------------------------------------------------------------------------*
623   @brief        メイン関数です。
624  *---------------------------------------------------------------------------*/
625 void
nnMain()626 nnMain()
627 {
628     nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
629     nw::demo::InitializeDemoAllocator(&s_ParticleAllocator, nw::demo::DEMO_PARTICLE_MEMORY_SIZE);
630 
631     nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
632 
633     NW_DEMO_TEST_LOOP(&s_DeviceAllocator, &s_ParticleAllocator, &s_RenderSystem)
634     {
635         InitializeGraphics();
636 
637         s_FlushCache = nw::demo::FlushCache::Create(&s_DeviceAllocator);
638 
639         DemoScene();
640 
641         nw::ut::SafeDestroy(s_FlushCache);
642 
643         TerminateGraphics();
644     }
645 
646     nw::demo::PadFactory::Finalize();
647 
648     nw::demo::FinalizeDemoAllocator(&s_ParticleAllocator);
649 
650     nw::demo::FinalizeGraphicsSystem();
651 }
652