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