1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: ParticleRecycleDemo.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 #define NW_DEBUG_CHECK_MEMORY_LEAK
17
18 #include <nn/os.h>
19 #include <nn/fs.h>
20
21 #include <nw/types.h>
22 #include <nw/demo.h>
23 #include <nw/dev.h>
24 #include <nw/gfx.h>
25 #include <nw/ut.h>
26
27 namespace
28 {
29
30 //----------------------------------------
31 // メモリ関係
32
33 // デバイスメモリを確保するためのアロケータです。
34 nw::demo::DemoAllocator s_DeviceAllocator;
35 nw::demo::DemoAllocator s_ParticleAllocator;
36
37 //----------------------------------------
38 // ファイル名の定義です。
39 const wchar_t* SKY_SPHERE_FILE_NAME = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
40
41 //----------------------------------------
42 // 描画関係
43 const int RENDER_TARGET_COUNT = 1;
44 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
45
46 RenderTargetArray s_RenderTargets;
47 nw::demo::SceneSystem* s_SceneSystem = NULL;
48 nw::demo::RenderSystem* s_RenderSystem = NULL;
49 nw::gfx::ParticleContext* s_ParticleContext = NULL;
50
51 nw::demo::GraphicsDrawing s_GraphicsDrawing;
52
53 //----------------------------------------
54 // リソース関係
55 nw::demo::ResourceArray s_Resources;
56
57 //----------------------------------------
58 // シーン関係
59 nw::gfx::SceneNode* s_SceneRoot = NULL;
60 s32 s_FrameCount = 0;
61 nw::gfx::Camera* s_BaseCamera = NULL;
62 nw::gfx::Camera* s_LeftCamera = NULL;
63 nw::gfx::Camera* s_RightCamera = NULL;
64 const f32 s_fNearPlane = 0.1f;
65
66 const s32 s_BaseCameraIndex = 0;
67
68 //----------------------------------------
69 // パーティクル関係
70 nw::gfx::ParticleSceneUpdater* s_ParticleSceneUpdater = NULL;
71
72 nw::demo::FlushCache* s_FlushCache;
73
74 /*!--------------------------------------------------------------------------*
75 @brief グラフィックス関連の初期化を行います。
76 *---------------------------------------------------------------------------*/
77 void
InitializeGraphics()78 InitializeGraphics()
79 {
80 nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
81
82 // renderDescriptionへステレオの設定を行います。
83 nw::demo::RenderSystem::Description renderDescription;
84
85 renderDescription.reusableCommandBufferSize = 0x100000;
86 renderDescription.reusableCommandRequestCount = 512;
87 renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
88
89 s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
90
91 s_GraphicsDrawing.SetScreenSize(
92 renderDescription.lowerScreenDescription.width,
93 renderDescription.lowerScreenDescription.height
94 );
95
96 nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
97
98 s_RenderTargets.push_back(
99 nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
100 );
101 NW_ASSERT(!s_RenderTargets.empty());
102 s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
103
104 // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
105 nw::demo::SceneSystem::Description sceneDescription;
106 s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
107
108 s_ParticleContext = nw::gfx::ParticleContext::Builder()
109 .Create(&s_DeviceAllocator);
110
111 s_ParticleSceneUpdater = nw::gfx::ParticleSceneUpdater::Builder()
112 .Create(&s_DeviceAllocator);
113
114 // デモ用の最遠景モデルをレンダリングシステムに設定します。
115 // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
116 s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
117
118 NW_GL_ASSERT();
119 }
120
121 /*!--------------------------------------------------------------------------*
122 @brief グラフィックス関連の後始末をします。
123 *---------------------------------------------------------------------------*/
124 void
TerminateGraphics()125 TerminateGraphics()
126 {
127 nw::gfx::SafeDestroy(s_LeftCamera);
128
129 nw::gfx::SafeDestroy(s_RightCamera);
130
131 nw::gfx::SafeDestroy(s_ParticleSceneUpdater);
132
133 nw::gfx::SafeDestroy(s_ParticleContext);
134
135 nw::gfx::SafeDestroy(s_SceneSystem);
136
137 nw::gfx::SafeDestroyAll(s_RenderTargets);
138
139 s_GraphicsDrawing.Finalize();
140
141 nw::gfx::SafeDestroy(s_RenderSystem);
142
143 NW_GL_ASSERT();
144 }
145
146 /*!--------------------------------------------------------------------------*
147 @brief ルートノード関連の構築をします。
148 *---------------------------------------------------------------------------*/
149 void
BuildRootNodes()150 BuildRootNodes()
151 {
152 NW_ASSERT(s_SceneRoot == NULL);
153 s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
154 .IsFixedSizeMemory(false)
155 .Create(&s_DeviceAllocator);
156 NW_NULL_ASSERT(s_SceneRoot);
157 }
158
159 /*!--------------------------------------------------------------------------*
160 @brief カメラ関連の構築をします。
161 *---------------------------------------------------------------------------*/
162 void
BuildCameras()163 BuildCameras()
164 {
165 nw::demo::Utility::CreateStereoCameras(
166 &s_BaseCamera,
167 &s_LeftCamera,
168 &s_RightCamera,
169 &s_DeviceAllocator,
170 nw::math::VEC3(28.0f, 22.0f, 28.0f),
171 nw::math::VEC3(0.0f, 0.0f, 0.0f),
172 s_fNearPlane
173 );
174
175 s_SceneRoot->AttachChild(s_BaseCamera);
176 s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
177 }
178
179
180 /*!--------------------------------------------------------------------------*
181 @brief シーンを初期化します。
182 *---------------------------------------------------------------------------*/
183 void
InitializeScenes()184 InitializeScenes()
185 {
186 BuildRootNodes();
187
188 BuildCameras();
189
190 // シーンツリーを巡回して初期化を行います。
191 s_SceneSystem->InitializeScene(s_SceneRoot);
192 s_SceneSystem->UpdateScene();
193
194 // カメラを設定します。
195 nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
196 sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
197 nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
198
199 NW_GL_ASSERT();
200
201 s_FrameCount = 0;
202 }
203
204 /*!--------------------------------------------------------------------------*
205 @brief シーン関連の後始末をします。
206 *---------------------------------------------------------------------------*/
207 void
TerminateScenes()208 TerminateScenes()
209 {
210 nw::gfx::SafeDestroyBranch(s_SceneRoot);
211 nw::demo::SafeCleanupResources(s_Resources);
212
213 NW_GL_ASSERT();
214
215 s_Resources.clear();
216 }
217
218 /*!--------------------------------------------------------------------------*
219 @brief シーンを更新します。
220 *---------------------------------------------------------------------------*/
221 void
UpdateScene()222 UpdateScene()
223 {
224 NW_ASSERT(0 < s_RenderTargets.size());
225
226 s_SceneSystem->GetCameraController()->Update();
227
228 s_SceneSystem->UpdateScene();
229
230 s_BaseCamera->UpdateCameraMatrix();
231
232 NW_NULL_ASSERT(s_ParticleSceneUpdater);
233 s_ParticleSceneUpdater->UpdateNode(
234 s_SceneSystem->GetSceneContext(),
235 s_ParticleContext);
236
237 s_RenderSystem->CalcStereoCamera(s_LeftCamera, s_RightCamera, s_BaseCamera, s_fNearPlane + 5.0f);
238
239 s_FrameCount++;
240
241 s_FlushCache->Execute();
242 }
243
244 /*!--------------------------------------------------------------------------*
245 @brief 負荷表示やテスト機能の処理をおこないます。
246 *---------------------------------------------------------------------------*/
247 void
ReportDemo()248 ReportDemo()
249 {
250 NW_PROFILE("ReportDemo");
251
252 // 負荷表示からはこれらの負荷は除きます。
253 s_RenderSystem->SuspendLoadMeter();
254
255 nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
256
257 s_GraphicsDrawing.BeginDrawingShape();
258
259 nw::demo::DebugUtility::DrawLoadMeter(
260 s_RenderSystem,
261 &s_GraphicsDrawing
262 );
263
264 s_GraphicsDrawing.EndDrawingShape();
265
266 s_GraphicsDrawing.BeginDrawingString();
267
268 nw::demo::DebugUtility::DrawLoadMeterText(
269 s_RenderSystem,
270 &s_GraphicsDrawing
271 );
272
273 s_GraphicsDrawing.EndDrawingString();
274
275 s_RenderSystem->ResumeLoadMeter();
276 }
277
278
279
280
281 //----------------------------------------
282 // デモ固有の変数
283
284 // パーティクルエフェクトクラス
285 nw::demo::ParticleEffect* s_ParticleEffect = NULL;
286
287 // パーティクルノードクラス
288 nw::demo::ParticleNode* s_particleNode = NULL;
289
290 // 親ノード
291 nw::gfx::SceneNode* s_ParentNode = NULL;
292
293 // カウンタ
294 u32 s_Count = 0;
295
296 // ロードするエフェクトファイル名
297 const wchar_t* EFFECT_RESOURCE_FILE = NW_DEMO_FILE_PATH(L"fountain_particle_all.bcptl");
298
299 // ロードするエフェクトシェーダファイル
300 const wchar_t* SHADER_RESOURCE_FILE_NAME = NW_DEMO_FILE_PATH(L"nwgfx_ParticleDefaultShader.bcsdr");
301
302
303 /*!--------------------------------------------------------------------------*
304 @brief ParticleRecycleDemoの初期化を行います。
305 *---------------------------------------------------------------------------*/
306 void
InitializeParticleRecycleDemo()307 InitializeParticleRecycleDemo()
308 {
309 // シェーダバイナリをロードします。
310 nw::demo::ParticleEffect::InitializeShaderBinary(SHADER_RESOURCE_FILE_NAME, &s_DeviceAllocator);
311
312 // パーティクルエフェクトクラスを生成します。
313 s_ParticleEffect = nw::demo::ParticleEffect::Create(&s_DeviceAllocator, &s_DeviceAllocator, false, s_ParticleContext);
314
315 // エフェクトデータをロードしてセットアップします。
316 nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, EFFECT_RESOURCE_FILE, &s_DeviceAllocator);
317
318 // リソースのセットアップを行います。
319 // fountain_particle_allはコンスタントカラーを使用しているので、ParticleMaterialは使用できません。
320 s_ParticleEffect->Setup(resourceSet->resource, false);
321
322 // ParticleEffectにリソースをセットします。
323 s_ParticleEffect->Register(resourceSet->resource);
324 s_ParticleEffect->AddPool(1);
325
326 // パーティクルノードクラスのインスタンスをリースします。
327 s_particleNode = s_ParticleEffect->LeaseInstance();
328
329 // シーンに追加します。
330 s_SceneRoot->AttachChild(s_particleNode);
331 s_SceneSystem->InitializeScene(s_SceneRoot);
332 s_SceneSystem->UpdateScene();
333
334 // このデモでは、親ノードへAttach,Detachを行うので、親ノードを保持します。
335 s_ParentNode = s_particleNode->GetParent();
336 }
337
338 /*!--------------------------------------------------------------------------*
339 @brief ParticleRecycleDemoの定期処理です。
340 *---------------------------------------------------------------------------*/
341 void
UpdateParticleRecycleDemo()342 UpdateParticleRecycleDemo()
343 {
344 ++s_Count;
345
346 if (s_Count % 180 == 120)
347 {
348 // シーンツリーからパーティクルを取り外します。
349 s_ParentNode->DetachChild(s_particleNode);
350 s_SceneSystem->InitializeScene(s_SceneRoot);
351 }
352
353 if (s_Count % 180 == 179)
354 {
355 // パーティクルを初期状態に戻し再利用します。
356 // Resetメソッド内では、ParticleEmitterのリセット処理、
357 // ParticleModel内、アニメーションフレームの0初期化、
358 // 及び、ParticleCollectionのClear処理が行われています。
359 // また、コマンド2重化時には、ResetメソッドをGPU処理中にコールすることができません。
360 // Detachした後、GPU処理が終了の後、コールしてください。
361 s_particleNode->Reset();
362
363 // シーンツリーに初期化したパーティクルを取り付けます。
364 s_ParentNode->AttachChild(s_particleNode);
365 s_SceneSystem->InitializeScene(s_SceneRoot);
366 }
367 }
368
369 /*!--------------------------------------------------------------------------*
370 @brief ParticleRecycleDemoの終了処理を行います。
371 *---------------------------------------------------------------------------*/
372 void
TerminateParticleRecycleDemo()373 TerminateParticleRecycleDemo()
374 {
375 nw::demo::ParticleNode* prevTarget = s_ParticleEffect->GetActiveEffect(0);
376 while (prevTarget != NULL)
377 {
378 s_ParticleEffect->ReleaseInstance(prevTarget);
379 prevTarget = s_ParticleEffect->GetActiveEffect(0);
380 }
381
382 s_ParticleEffect->FreePool();
383
384 nw::gfx::SafeDestroy(s_ParticleEffect);
385
386 // ロードしたパーティクルシェーダを破棄します。
387 nw::demo::ParticleEffect::FinalizeShaderBinary();
388 }
389
390
391
392
393 /*!--------------------------------------------------------------------------*
394 @brief シーンをデモンストレーションします。
395 *---------------------------------------------------------------------------*/
396 void
DemoScene()397 DemoScene()
398 {
399 NW_ASSERT(!s_RenderTargets.empty());
400
401 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
402
403 InitializeScenes();
404
405 // ParticleRecycleDemoの初期化処理です。
406 InitializeParticleRecycleDemo();
407
408 nw::demo::DebugUtility::PostInitializeScenes();
409
410 bool isContinuing = true;
411
412 while ( isContinuing )
413 {
414 nw::demo::DebugUtility::AdvanceAutoTestFrame();
415
416 nw::demo::PadFactory::GetPad()->Update();
417
418
419 // ParticleRecycleDemoの定期処理です。
420 UpdateParticleRecycleDemo();
421
422 UpdateScene();
423
424 renderContext->SetActiveCamera(s_BaseCameraIndex);
425 s_RenderSystem->SubmitView(s_SceneSystem);
426
427 s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
428 s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
429
430 s_RenderSystem->ClearBySkyModel(s_BaseCamera);
431 ReportDemo();
432 s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
433
434 s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
435
436 renderContext->ResetState();
437
438 if (nw::demo::Utility::IsTerminating())
439 {
440 isContinuing = false;
441 }
442 }
443
444 nw::demo::DebugUtility::PreTerminateScenes();
445
446 // ParticleRecycleDemoの終了処理です。
447 TerminateParticleRecycleDemo();
448
449 TerminateScenes();
450 }
451
452 } // namespace
453
454 /*!--------------------------------------------------------------------------*
455 @brief メイン関数です。
456 *---------------------------------------------------------------------------*/
457 void
nnMain()458 nnMain()
459 {
460 nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
461 nw::demo::InitializeDemoAllocator(&s_ParticleAllocator, nw::demo::DEMO_PARTICLE_MEMORY_SIZE);
462
463 nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
464
465 NW_DEMO_TEST_LOOP(&s_DeviceAllocator, &s_ParticleAllocator, &s_RenderSystem)
466 {
467 InitializeGraphics();
468
469 s_FlushCache = nw::demo::FlushCache::Create(&s_DeviceAllocator);
470
471 DemoScene();
472
473 nw::ut::SafeDestroy(s_FlushCache);
474
475 TerminateGraphics();
476 }
477
478 nw::demo::PadFactory::Finalize();
479
480 nw::demo::FinalizeDemoAllocator(&s_ParticleAllocator);
481
482 nw::demo::FinalizeGraphicsSystem();
483 }
484