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