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