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