1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: FastCreateDemo.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: $
16 *---------------------------------------------------------------------------*/
17
18 // FastCreateDemo はフレームヒープアロケータを使用して、
19 // 高速にオブジェクトの生成と破棄を行なうデモです。
20 //
21 // 詳しくはドキュメント、および
22 // PrepareBuilder(), BuildLattices(), DestroyLattices() などの実装を
23 // 参照してください。
24
25 #define NW_DEBUG_CHECK_MEMORY_LEAK
26
27 // オブジェクトの生成にフレームヒープアロケータを使用します。
28 #define USE_FRAME_HEAP
29
30 #include <nn/os.h>
31 #include <nn/fs.h>
32
33 #include <nw/types.h>
34 #include <nw/demo.h>
35 #include <nw/dev.h>
36 #include <nw/gfx.h>
37 #include <nw/ut.h>
38
39 namespace
40 {
41
42 //----------------------------------------
43 // メモリ関係
44
45 // デバイスメモリを確保するためのアロケータです。
46 nw::demo::DemoAllocator s_DeviceAllocator;
47
48 // フレームヒープアロケータです。
49 nw::demo::FrameHeapAllocator s_FrameHeapAllocator;
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"Beam.bcmdl"),
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
71 static nw::demo::GraphicsDrawing s_GraphicsDrawing;
72 //----------------------------------------
73 // リソース関係
74 nw::demo::ResourceArray s_Resources;
75
76 //----------------------------------------
77 // シーン関係
78 nw::gfx::TransformNode* s_SceneRoot = NULL;
79 nw::gfx::TransformNode* s_ModelRoot = NULL;
80 s32 s_FrameCount = 0;
81 nw::gfx::Camera* s_BaseCamera = NULL;
82 nw::gfx::Camera* s_LeftCamera = NULL;
83 nw::gfx::Camera* s_RightCamera = NULL;
84 const f32 s_fNearPlane = 0.1f;
85
86 const s32 s_BaseCameraIndex = 0;
87
88 //----------------------------------------
89 // シーン環境関係
90 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
91
92 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
93 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
94
95 //----------------------------------------
96 // モデル関係
97 const int LATTICE_WIDTH = 2;
98 const int LATTICE_COUNT = (LATTICE_WIDTH * 2) * (LATTICE_WIDTH * 2) * (LATTICE_WIDTH * 2);
99
100 const f32 LATTICE_SIZE = 14.0f;
101
102 const int MODEL_PER_LATTICE = 3;
103 const int NODE_PER_LATTICE = MODEL_PER_LATTICE + 1;
104
105 nw::gfx::ResSceneNode s_ResBeam;
106
107 nw::gfx::SceneBuilder s_BeamBuilder;
108 nw::gfx::TransformNode::DynamicBuilder s_LatticeRootBuilder;
109 size_t s_SizeOfLattice;
110
111 struct Lattice
112 {
113 nw::gfx::TransformNode* root;
114 nw::math::VEC3 position;
115 };
116
117 typedef nw::ut::FixedSizeArray<Lattice, LATTICE_COUNT> LatticeArray;
118 LatticeArray s_Lattices;
119
120 f32 s_PhaseAxis = 0.0f;
121 f32 s_PhaseRot = 0.0f;
122 f32 s_PhaseScale = 0.0f;
123
124 const f32 STEP_PHASE_AXIS = 0.012f;
125 const f32 STEP_PHASE_ROT = 0.14f;
126 const f32 STEP_PHASE_SCALE = 0.004f;
127
128 /*!--------------------------------------------------------------------------*
129 @brief グラフィックス関連の初期化を行います。
130 *---------------------------------------------------------------------------*/
131 void
InitializeGraphics()132 InitializeGraphics()
133 {
134 nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
135
136 // renderDescriptionへステレオの設定を行います。
137 nw::demo::RenderSystem::Description renderDescription;
138
139 renderDescription.reusableCommandBufferSize = 0x100000;
140 renderDescription.reusableCommandRequestCount = 512;
141 renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
142
143 s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
144
145 s_GraphicsDrawing.SetScreenSize(
146 renderDescription.lowerScreenDescription.width,
147 renderDescription.lowerScreenDescription.height
148 );
149
150 nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
151
152 s_RenderTargets.push_back(
153 nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
154 );
155 NW_ASSERT(!s_RenderTargets.empty());
156 s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
157
158 // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
159 nw::demo::SceneSystem::Description sceneDescription;
160
161 sceneDescription.maxSceneNodes = NODE_PER_LATTICE * LATTICE_COUNT + 4;
162 sceneDescription.maxModels = MODEL_PER_LATTICE * LATTICE_COUNT;
163 sceneDescription.maxMaterials = MODEL_PER_LATTICE * LATTICE_COUNT;
164
165 s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
166
167 // デモ用の最遠景モデルをレンダリングシステムに設定します。
168 // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
169 s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
170
171 NW_GL_ASSERT();
172 }
173
174 /*!--------------------------------------------------------------------------*
175 @brief グラフィックス関連の後始末をします。
176 *---------------------------------------------------------------------------*/
177 void
TerminateGraphics()178 TerminateGraphics()
179 {
180 nw::gfx::SafeDestroy(s_LeftCamera);
181
182 nw::gfx::SafeDestroy(s_RightCamera);
183
184 nw::gfx::SafeDestroy(s_SceneSystem);
185
186 nw::gfx::SafeDestroyAll(s_RenderTargets);
187
188 s_GraphicsDrawing.Finalize();
189
190 nw::gfx::SafeDestroy(s_RenderSystem);
191
192 NW_GL_ASSERT();
193 }
194
195 /*!--------------------------------------------------------------------------*
196 @brief ルートノード関連の構築をします。
197 *---------------------------------------------------------------------------*/
198 void
BuildRootNodes()199 BuildRootNodes()
200 {
201 NW_ASSERT(s_SceneRoot == NULL);
202 s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
203 .Create(&s_DeviceAllocator);
204 NW_NULL_ASSERT(s_SceneRoot);
205
206 NW_ASSERT(s_ModelRoot == NULL);
207 s_ModelRoot = nw::gfx::TransformNode::DynamicBuilder()
208 .MaxChildren(LATTICE_COUNT)
209 .Create(&s_DeviceAllocator);
210 s_SceneRoot->AttachChild(s_ModelRoot);
211 NW_NULL_ASSERT(s_ModelRoot);
212 }
213
214 /*!--------------------------------------------------------------------------*
215 @brief カメラ関連の構築をします。
216 *---------------------------------------------------------------------------*/
217 void
BuildCameras()218 BuildCameras()
219 {
220 nw::demo::Utility::CreateStereoCameras(
221 &s_BaseCamera,
222 &s_LeftCamera,
223 &s_RightCamera,
224 &s_DeviceAllocator,
225 nw::math::VEC3(60.0f, 40.0f, 45.0f),
226 nw::math::VEC3(0.0f, 0.0f, 0.0f),
227 s_fNearPlane
228 );
229
230 s_SceneRoot->AttachChild(s_BaseCamera);
231 s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
232 }
233
234 /*!--------------------------------------------------------------------------*
235 @brief リソース関連の構築をします。
236 *---------------------------------------------------------------------------*/
237 void
BuildResources(nw::demo::ResourceSet * resourceSet)238 BuildResources(nw::demo::ResourceSet* resourceSet)
239 {
240 resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
241 resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
242 resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
243
244 nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
245 if (result.IsFailure())
246 {
247 NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
248 }
249
250 nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(&s_DeviceAllocator);
251
252 nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
253 if (models.size() > 0)
254 {
255 // モデルのリソースを記憶しておきます。
256 s_ResBeam = models[0];
257 }
258
259 nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
260 nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
261 for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
262 lightResource != lightsEnd; ++lightResource)
263 {
264 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
265 &s_DeviceAllocator,
266 (*lightResource)
267 );
268 NW_NULL_ASSERT(node);
269 sceneNodeArray.push_back(node);
270 }
271
272 // 親子付け参照関係を解決
273 nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
274
275 // モデルをシーンに追加
276 nw::gfx::SceneHelper::ForeachRootNodes(
277 sceneNodeArray.Begin(),
278 sceneNodeArray.End(),
279 nw::gfx::AttachNode(s_SceneRoot)
280 );
281
282 nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
283 nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
284 for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
285 settingResource != settingsEnd; ++settingResource)
286 {
287 nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
288 .Resource(*settingResource)
289 .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
290
291 nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
292 nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
293
294 NW_NULL_ASSERT(sceneEnvironmentSetting);
295 s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
296 }
297 }
298
299 /*!--------------------------------------------------------------------------*
300 @brief モデルを作成します。
301 *---------------------------------------------------------------------------*/
302 void
BuildLattices()303 BuildLattices()
304 {
305 nw::os::IAllocator* allocator;
306
307 #ifdef USE_FRAME_HEAP
308 // 必要なサイズのメモリをまとめて確保し、
309 // フレームヒープアロケータにそのメモリを渡して初期化します。
310
311 size_t memorySize = s_SizeOfLattice * LATTICE_COUNT;
312 void* memory = s_DeviceAllocator.Alloc(memorySize);
313 s_FrameHeapAllocator.Initialize(reinterpret_cast<uptr>(memory), memorySize);
314
315 allocator = &s_FrameHeapAllocator;
316 #else
317 allocator = &s_DeviceAllocator;
318 #endif
319
320
321 for (int x = -LATTICE_WIDTH ; x < LATTICE_WIDTH ; ++x)
322 {
323 for (int y = -LATTICE_WIDTH ; y < LATTICE_WIDTH ; ++y)
324 {
325 for (int z = -LATTICE_WIDTH ; z < LATTICE_WIDTH ; ++z)
326 {
327 nw::gfx::TransformNode* root = s_LatticeRootBuilder.Create(allocator);
328
329 Lattice lattice;
330 lattice.position = nw::math::VEC3(
331 LATTICE_SIZE * x + LATTICE_SIZE * 0.5f,
332 LATTICE_SIZE * y + LATTICE_SIZE * 0.5f,
333 LATTICE_SIZE * z + LATTICE_SIZE * 0.5f);
334 lattice.root = root;
335
336 for (int i = 0 ; i < 3 ; ++i)
337 {
338 nw::gfx::SceneObject* sceneObject =
339 s_BeamBuilder.CreateObject(allocator, allocator);
340
341 nw::gfx::Model* beam =
342 reinterpret_cast<nw::gfx::Model*>(sceneObject);
343
344 beam->Transform().SetRotateXYZ(
345 (i == 1 ? nn::math::F_PI * 0.5f : 0.0f),
346 (i == 2 ? nn::math::F_PI * 0.5f : 0.0f),
347 0.0f);
348
349 root->AttachChild(beam);
350 }
351
352 s_Lattices.push_back(lattice);
353 s_ModelRoot->AttachChild(root);
354 }
355 }
356 }
357 }
358
359 /*!--------------------------------------------------------------------------*
360 @brief すべてのモデルを破棄します。
361 *---------------------------------------------------------------------------*/
362 void
DestroyLattices()363 DestroyLattices()
364 {
365 s_ModelRoot->DetachAllChildren();
366
367 #ifdef USE_FRAME_HEAP
368 // フレームヒープを使用してモデルを作成した場合、
369 // 確保したメモリをまとめて破棄することで、
370 // Destroy の呼び出しを省略することができます。
371
372 void* memory = reinterpret_cast<void*>(s_FrameHeapAllocator.GetStartAddress());
373
374 s_FrameHeapAllocator.Finalize();
375
376 s_DeviceAllocator.Free(memory);
377 #else
378 // 拡張ヒープを使用してモデルを作成した場合、
379 // それぞれ Destroy を呼んで、
380 // 適切にメモリを解放する必要があります。
381
382 LatticeArray::iterator end = s_Lattices.end();
383 for (LatticeArray::iterator model = s_Lattices.begin();
384 model != end;
385 ++model)
386 {
387 (*model).root->DestroyBranch();
388 }
389 #endif
390
391 s_Lattices.clear();
392 }
393
394 /*!--------------------------------------------------------------------------*
395 @brief モデルの位置を更新し、また再作成を行ないます。
396 *---------------------------------------------------------------------------*/
397 void
UpdateLattices()398 UpdateLattices()
399 {
400 DestroyLattices();
401 BuildLattices();
402
403 // 各格子の位置を計算します。
404 f32 scale = -nw::math::CosRad(s_PhaseScale) * 0.5f + 0.5f;
405
406 nw::math::VEC3 axis(0.0f, 0.0f, 0.0f);
407 nw::math::SinCosRad(&axis.x, &axis.y, s_PhaseAxis);
408
409 nw::math::MTX34 mat;
410 nw::math::MTX34RotAxisDeg(&mat, &axis, s_PhaseRot);
411
412 LatticeArray::iterator end = s_Lattices.end();
413 for (LatticeArray::iterator model = s_Lattices.begin();
414 model != end;
415 ++model)
416 {
417 nw::math::VEC3 pos = (*model).position * scale;
418 VEC3TransformNormal(&pos, &mat, &pos);
419 (*model).root->Transform().SetTranslate(pos);
420 }
421
422 s_PhaseAxis += STEP_PHASE_AXIS;
423 s_PhaseRot += STEP_PHASE_ROT;
424 s_PhaseScale += STEP_PHASE_SCALE;
425 }
426
427 /*!--------------------------------------------------------------------------*
428 @brief ノードの Builder の準備を行ないます。
429 *---------------------------------------------------------------------------*/
430 void
PrepareBuilder()431 PrepareBuilder()
432 {
433 NW_ASSERT(s_ResBeam.IsValid());
434
435 // 各 Builder を設定します。
436 s_BeamBuilder
437 .Resource(s_ResBeam)
438 .MaxCallbacks(0)
439 .MaxChildren(0)
440 .BufferOption(nw::gfx::Model::FLAG_BUFFER_NOT_USE)
441 .IsAnimationEnabled(false);
442
443 s_LatticeRootBuilder
444 .MaxCallbacks(0)
445 .MaxChildren(3);
446
447 // 1つの格子を生成するために必要なメモリサイズを計算します。
448 s_SizeOfLattice =
449 s_BeamBuilder.GetMemorySize() * 3 +
450 s_LatticeRootBuilder.GetMemorySize();
451 }
452
453 /*!--------------------------------------------------------------------------*
454 @brief シーンを初期化します。
455 *---------------------------------------------------------------------------*/
456 void
InitializeScenes()457 InitializeScenes()
458 {
459 BuildRootNodes();
460
461 BuildCameras();
462
463 NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
464 {
465 BuildResources(nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator));
466 }
467
468 PrepareBuilder();
469 BuildLattices();
470
471 // シーンツリーを巡回して初期化を行います。
472 s_SceneSystem->InitializeScene(s_SceneRoot);
473 s_SceneSystem->UpdateScene();
474
475 // シーン環境の参照解決を行い設定します。
476 s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
477
478 // カメラを設定します。
479 nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
480 sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
481 nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
482
483 NW_GL_ASSERT();
484
485 s_FrameCount = 0;
486
487 s_PhaseAxis = 0.0f;
488 s_PhaseRot = 0.0f;
489 s_PhaseScale = 0.0f;
490 }
491
492 /*!--------------------------------------------------------------------------*
493 @brief シーン関連の後始末をします。
494 *---------------------------------------------------------------------------*/
495 void
TerminateScenes()496 TerminateScenes()
497 {
498 DestroyLattices();
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 s_Lattices.clear();
509 s_ModelRoot = NULL;
510 }
511
512 /*!--------------------------------------------------------------------------*
513 @brief シーンを更新します。
514 *---------------------------------------------------------------------------*/
515 void
UpdateScene()516 UpdateScene()
517 {
518 UpdateLattices();
519
520 s_SceneSystem->GetCameraController()->Update();
521
522 s_SceneSystem->UpdateScene();
523
524 s_BaseCamera->UpdateCameraMatrix();
525
526 nw::gfx::ResCameraProjectionUpdater resProjectionUpdater =
527 s_BaseCamera->GetProjectionUpdater()->GetResource();
528
529 int near = resProjectionUpdater.GetNear();
530
531 s_RenderSystem->CalcStereoCamera(
532 s_LeftCamera,
533 s_RightCamera,
534 s_BaseCamera,
535 near + 5.0f);
536
537 ++s_FrameCount;
538 }
539
540 /*!--------------------------------------------------------------------------*
541 @brief 負荷表示やテスト機能の処理をおこないます。
542 *---------------------------------------------------------------------------*/
543 void
ReportDemo()544 ReportDemo()
545 {
546 NW_PROFILE("ReportDemo");
547
548 // 負荷表示からはこれらの負荷は除きます。
549 s_RenderSystem->SuspendLoadMeter();
550
551 nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
552
553 s_GraphicsDrawing.BeginDrawingShape();
554
555 nw::demo::DebugUtility::DrawLoadMeter(
556 s_RenderSystem,
557 &s_GraphicsDrawing
558 );
559
560 s_GraphicsDrawing.EndDrawingShape();
561
562 s_GraphicsDrawing.BeginDrawingString();
563
564 nw::demo::DebugUtility::DrawLoadMeterText(
565 s_RenderSystem,
566 &s_GraphicsDrawing
567 );
568
569 s_GraphicsDrawing.EndDrawingString();
570
571 s_RenderSystem->ResumeLoadMeter();
572 }
573
574 /*!--------------------------------------------------------------------------*
575 @brief シーンをデモンストレーションします。
576 *---------------------------------------------------------------------------*/
577 void
DemoScene()578 DemoScene()
579 {
580 NW_ASSERT(!s_RenderTargets.empty());
581
582 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
583
584 InitializeScenes();
585
586 nw::demo::DebugUtility::PostInitializeScenes();
587
588 bool isContinuing = true;
589
590 while ( isContinuing )
591 {
592 nw::demo::DebugUtility::AdvanceAutoTestFrame();
593
594 nw::demo::PadFactory::GetPad()->Update();
595
596 UpdateScene();
597
598 renderContext->SetActiveCamera(s_BaseCameraIndex);
599 s_RenderSystem->SubmitView(s_SceneSystem);
600
601 s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
602 s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
603
604 s_RenderSystem->ClearBySkyModel(s_BaseCamera);
605 ReportDemo();
606 s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
607
608 s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
609
610 renderContext->ResetState();
611
612 if (nw::demo::Utility::IsTerminating())
613 {
614 isContinuing = false;
615 }
616 }
617
618 nw::demo::DebugUtility::PreTerminateScenes();
619
620 TerminateScenes();
621 }
622
623 } // namespace
624
625 /*!--------------------------------------------------------------------------*
626 @brief メイン関数です。
627 *---------------------------------------------------------------------------*/
628 void
nnMain()629 nnMain()
630 {
631 nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
632
633 nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
634
635 NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
636 {
637 InitializeGraphics();
638
639 DemoScene();
640
641 TerminateGraphics();
642 }
643
644 nw::demo::PadFactory::Finalize();
645
646 nw::demo::FinalizeGraphicsSystem();
647 }
648