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