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