1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: ParticleLowLayerDemo.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: 28211 $
14 *---------------------------------------------------------------------------*/
15
16 #define NW_DEBUG_CHECK_MEMORY_LEAK
17
18 #include <nn/os.h>
19 #include <nn/fs.h>
20 #include <nn/gx.h>
21
22 #include <nw/types.h>
23 #include <nw/demo.h>
24 #include <nw/dev.h>
25 #include <nw/gfx.h>
26 #include <nw/ut.h>
27
28 namespace
29 {
30
31 //----------------------------------------
32 // メモリ関係
33 // デモではデバイスメモリから全てのメモリを確保するようになっています。
34
35 // デモで使用するメモリサイズです。
36 const size_t DEMO_MEMORY_SIZE = 0x1000000;
37
38 // デバイスメモリを確保するためのアロケータです。
39 nw::demo::DemoAllocator s_DeviceAllocator;
40
41 nw::demo::GraphicsMemoryAllocator s_GraphicsMemoryAllocator;
42
43 const int MAX_FILE = 256;
44 const int MAX_DIRECTORY = 16;
45
46 // メモリのフラッシュコード
47 nw::demo::FlushCache* s_FlushCache;
48
49 //----------------------------------------
50 // ファイル名の定義です。
51 static const wchar_t* MODEL_RESOURCE_FILES[] =
52 {
53 NW_DEMO_FILE_PATH(L"fountain_particle_all.bcptl"),
54 NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
55 };
56
57 //----------------------------------------
58 // 描画関係
59 nw::gfx::IRenderTarget* s_RenderTarget = NULL;
60
61 nw::gfx::ParticleContext* s_ParticleContext = NULL;
62
63 nw::gfx::RenderContext* s_RenderContext = NULL;
64 nw::gfx::MeshRenderer* s_MeshRenderer = NULL;
65 nw::demo::DisplayBufferSwapper* s_UpperSwapper = NULL;
66 nw::demo::DisplayBufferSwapper* s_ExtensionSwapper = NULL;
67
68 const size_t COMMAND_BUFFER_SIZE = 0x100000;
69 const size_t REQUEST_COUNT = 512;
70 nw::demo::CommandListSwapper* s_CommandListSwapper = NULL;
71
72 //----------------------------------------
73 // リソース関係
74 const int RESOURCES_COUNT = 3;
75 struct ResourceSet
76 {
77 nw::ut::MoveArray<u8> buffer;
78 nw::gfx::ResGraphicsFile resource;
79 };
80 typedef nw::ut::FixedSizeArray<ResourceSet, RESOURCES_COUNT> ResourceArray;
81
82 ResourceArray s_Resources;
83
84 //----------------------------------------
85 // シーン関係
86 s32 s_FrameCount = 0;
87 nw::gfx::WorldMatrixUpdater* s_WorldMatrixUpdater = NULL;
88
89 const s32 s_BaseCameraIndex = 0;
90 nw::gfx::Camera* s_BaseCamera = NULL;
91 nw::gfx::Camera* s_LeftCamera = NULL;
92 nw::gfx::Camera* s_RightCamera = NULL;
93 const f32 s_NearPlane = 0.1f;
94
95 nw::demo::CameraController* s_CameraController = NULL;
96
97 nn::ulcd::CTR::StereoCamera* s_StereoCamera;
98
99 const int MODEL_COUNT = 2;
100 const int EMITTER_COUNT = 1;
101 const int PARTICLESET_COUNT = 2;
102
103 typedef nw::ut::FixedSizeArray<nw::gfx::ParticleModel*, MODEL_COUNT> ParticleModelArray;
104 typedef nw::ut::FixedSizeArray<nw::gfx::ParticleEmitter*, EMITTER_COUNT> EmitterArray;
105 typedef nw::ut::FixedSizeArray<nw::gfx::ParticleSet*, PARTICLESET_COUNT> ParticleSetArray;
106
107 ParticleModelArray s_ParticleModels;
108 EmitterArray s_ParticleEmitters;
109 ParticleSetArray s_ParticleSets;
110
111 void UpdateNode(nw::gfx::TransformNode* node);
112
113 /*!--------------------------------------------------------------------------*
114 @brief グラフィックスメモリのアロケータです。
115
116 関数ポインタが nngxInitialize の引数として使用されます。
117 *---------------------------------------------------------------------------*/
AllocateGraphicsMemory(GLenum area,GLenum aim,GLuint id,GLsizei size)118 void* AllocateGraphicsMemory(GLenum area, GLenum aim, GLuint id, GLsizei size)
119 {
120 void* buffer = s_GraphicsMemoryAllocator.Allocate(area, aim, id, size);
121 return buffer;
122 }
123
124 /*!--------------------------------------------------------------------------*
125 @brief グラフィックスメモリのデアロケータです。
126
127 関数ポインタが nngxInitialize の引数として使用されます。
128 *---------------------------------------------------------------------------*/
DeallocateGraphicsMemory(GLenum area,GLenum aim,GLuint id,void * addr)129 void DeallocateGraphicsMemory(GLenum area, GLenum aim, GLuint id, void* addr)
130 {
131 s_GraphicsMemoryAllocator.Deallocate(area, aim, id, addr);
132 }
133
134 /*!--------------------------------------------------------------------------*
135 @brief グラフィックスシステムに必要なメモリなどの初期化を行います。
136 *---------------------------------------------------------------------------*/
137 void
InitializeGraphicsSystem()138 InitializeGraphicsSystem()
139 {
140 nn::os::Initialize();
141 nn::fs::Initialize();
142
143 nw::demo::InitializeDemoMemory();
144
145 nw::demo::InitializeDemoAllocator(&s_DeviceAllocator, DEMO_MEMORY_SIZE, nn::os::ALLOCATE_OPTION_LINEAR);
146
147 // デバイスメモリを用いるグラフィックスメモリアロケータを初期化します。
148 s_GraphicsMemoryAllocator.Initialize(&s_DeviceAllocator);
149
150 s32 workingMemorySize = nn::fs::GetRomRequiredMemorySize(MAX_FILE, MAX_DIRECTORY);
151 void* workingMemory = nw::demo::Alloc(workingMemorySize);
152 nn::Result result = nn::fs::MountRom(MAX_FILE, MAX_DIRECTORY, workingMemory, workingMemorySize);
153
154 NW_ASSERT(result.IsSuccess());
155 }
156
157 /*!--------------------------------------------------------------------------*
158 @brief グラフィックスシステムに必要なメモリなどの終了処理を行います。
159 *---------------------------------------------------------------------------*/
160 void
FinalizeGraphicsSystem()161 FinalizeGraphicsSystem()
162 {
163 s_GraphicsMemoryAllocator.Finalize();
164
165 nw::demo::FinalizeDemoAllocator(&s_DeviceAllocator);
166 }
167
168 /*!--------------------------------------------------------------------------*
169 @brief グラフィックス関連の初期化を行います。
170 *---------------------------------------------------------------------------*/
171 void
InitializeGraphics()172 InitializeGraphics()
173 {
174 s_ParticleContext = nw::gfx::ParticleContext::Builder()
175 .MaxEmission(1000)
176 .Create(&s_DeviceAllocator);
177
178 if (nngxInitialize(AllocateGraphicsMemory, DeallocateGraphicsMemory) == GL_FALSE)
179 {
180 NW_FATAL_ERROR("nngxInitialize failed.\n");
181 }
182
183 //-----------------------------
184 nw::demo::DisplayBufferSwapper::Description upperScreenDescription;
185 upperScreenDescription.screenKind = nw::demo::UPPER_SCREEN;
186 upperScreenDescription.width = 400;
187 upperScreenDescription.height = 240;
188 upperScreenDescription.bufferCount = 2;
189
190 nw::demo::DisplayBufferSwapper::Description extensionScreenDescription;
191 extensionScreenDescription.screenKind = nw::demo::EXTENSION_SCREEN;
192 extensionScreenDescription.width = upperScreenDescription.width;
193 extensionScreenDescription.height = upperScreenDescription.height;
194 extensionScreenDescription.bufferCount = upperScreenDescription.bufferCount;
195
196 s_UpperSwapper = nw::demo::DisplayBufferSwapper::Builder()
197 .BufferDescription(upperScreenDescription)
198 .Create(&s_DeviceAllocator);
199
200 s_ExtensionSwapper = nw::demo::DisplayBufferSwapper::Builder()
201 .BufferDescription(extensionScreenDescription)
202 .Create(&s_DeviceAllocator);
203
204 //-----------------------------
205 nw::demo::CommandListSwapper::Description commandListSwapperDescription;
206 commandListSwapperDescription.commandListCount = 1;
207 commandListSwapperDescription.bufferSize = COMMAND_BUFFER_SIZE;
208 commandListSwapperDescription.requestCount = REQUEST_COUNT;
209 commandListSwapperDescription.reusableBufferSize = COMMAND_BUFFER_SIZE;
210 commandListSwapperDescription.reusableRequestCount = REQUEST_COUNT;
211 commandListSwapperDescription.maxGpuProfilingEntryCount = 0;
212 s_CommandListSwapper =
213 nw::demo::CommandListSwapper::Create(&s_DeviceAllocator, commandListSwapperDescription);
214 s_CommandListSwapper->Bind();
215
216 //-----------------------------
217 nngxSetDisplayMode(nw::demo::UPPER_SCREEN_MODE_STEREO);
218
219 //-----------------------------
220 nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
221
222 //-----------------------------
223 s_RenderContext = nw::gfx::RenderContext::Builder()
224 .Create(&s_DeviceAllocator);
225
226 //-----------------------------
227 void* cameraMemory = s_DeviceAllocator.Alloc(sizeof(nn::ulcd::CTR::StereoCamera));
228 s_StereoCamera = new(cameraMemory) nn::ulcd::CTR::StereoCamera();
229 s_StereoCamera->Initialize();
230
231 //-----------------------------
232 s_MeshRenderer = nw::gfx::MeshRenderer::Create(&s_DeviceAllocator);
233 s_MeshRenderer->SetRenderContext(s_RenderContext);
234
235 //-----------------------------
236 nw::gfx::RenderColorFormat renderColorFormat = nw::gfx::RENDER_COLOR_FORMAT_RGBA8;
237 s_RenderTarget =
238 nw::gfx::IRenderTarget::Builder()
239 .BufferSize(upperScreenDescription.height, upperScreenDescription.width)
240 .ColorFormat(renderColorFormat)
241 .Create(&s_DeviceAllocator);
242 NW_NULL_ASSERT(s_RenderTarget);
243
244 //-----------------------------
245 s_WorldMatrixUpdater = nw::gfx::WorldMatrixUpdater::Builder()
246 .Create(&s_DeviceAllocator);
247
248 //-----------------------------
249 nngxStartLcdDisplay();
250
251 NW_GL_ASSERT();
252 }
253 /*!--------------------------------------------------------------------------*
254 @brief グラフィックス関連の後始末をします。
255 *---------------------------------------------------------------------------*/
256 void
TerminateGraphics()257 TerminateGraphics()
258 {
259 s_StereoCamera->Finalize();
260 s_DeviceAllocator.Free(s_StereoCamera);
261
262 nw::gfx::SafeDestroy(s_ParticleContext);
263
264 nw::gfx::SafeDestroy(s_WorldMatrixUpdater);
265
266 nw::gfx::SafeDestroy(s_RenderTarget);
267
268 nw::gfx::SafeDestroy(s_MeshRenderer);
269 nw::gfx::SafeDestroy(s_CommandListSwapper);
270 nw::gfx::SafeDestroy(s_UpperSwapper);
271 nw::gfx::SafeDestroy(s_ExtensionSwapper);
272 nw::gfx::SafeDestroy(s_RenderContext);
273
274 nngxFinalize();
275 s_GraphicsMemoryAllocator.Finalize();
276
277 NW_GL_ASSERT();
278 }
279
280 /*!--------------------------------------------------------------------------*
281 @brief グラフィックスリソースをロードします。
282
283 @param[in] resourcePath ファイルのパス名
284
285 @return ロードしたグラフィックス情報を返します。
286 *---------------------------------------------------------------------------*/
287 ResourceSet*
LoadResources(const wchar_t * resourcePath)288 LoadResources(const wchar_t* resourcePath)
289 {
290 ResourceSet resourceSet;
291 // 現在、デバイスメモリ上に読み込む方式にのみ対応しています。
292 // テクスチャをロードするには128byteアライメントを行う必要があります。
293 static const int resourceAlignment = 128;
294 resourceSet.buffer = nw::demo::Utility::LoadFile(&s_DeviceAllocator , resourcePath, resourceAlignment);
295
296 if (!resourceSet.buffer)
297 {
298 return NULL;
299 }
300
301 resourceSet.resource = nw::gfx::ResGraphicsFile(&(resourceSet.buffer.front()));
302
303 bool isPushed = s_Resources.push_back(resourceSet);
304
305 NW_ASSERT(isPushed);
306
307 return &(s_Resources.back());
308 }
309
310 /*!--------------------------------------------------------------------------*
311 @brief シーンノードを生成します。
312
313 @param[in] resource シーンノードのリソースです。
314
315 @return 生成したシーンノードです。。
316 *---------------------------------------------------------------------------*/
317 nw::gfx::SceneNode*
CreateSceneNode(nw::gfx::ResSceneObject resource)318 CreateSceneNode(nw::gfx::ResSceneObject resource)
319 {
320 nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
321 .Resource(resource)
322 .MaxChildren(0)
323 .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
324
325 return nw::ut::DynamicCast<nw::gfx::SceneNode*>(sceneObject);
326 }
327
328 /*!--------------------------------------------------------------------------*
329 @brief リソース関連の構築をします。
330 *---------------------------------------------------------------------------*/
331 void
BuildResources(ResourceSet * resourceSet)332 BuildResources(ResourceSet* resourceSet)
333 {
334 resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
335 resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
336 resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
337
338 nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
339 if (result.IsFailure())
340 {
341 NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
342 }
343
344 /*
345 リソースでの階層組みは無視します。
346 */
347 nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(&s_DeviceAllocator);
348
349 nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
350 nw::gfx::ResModelArray::iterator modelsEnd = models.end();
351 for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
352 modelResource != modelsEnd; ++modelResource)
353 {
354 nw::gfx::SceneNode* node = CreateSceneNode(*modelResource);
355 NW_NULL_ASSERT(node);
356
357 sceneNodeArray.push_back(node);
358
359 if (nw::ut::IsTypeOf<nw::gfx::ParticleModel>(node))
360 {
361 s_ParticleModels.push_back(static_cast<nw::gfx::ParticleModel*>(node));
362
363 nw::gfx::ParticleModel* particleModel =
364 static_cast<nw::gfx::ParticleModel*>(node);
365 for (int i = 0; i < particleModel->GetParticleSetsCount(); ++i)
366 {
367 s_ParticleSets.push_back(particleModel->GetParticleSets(i));
368 }
369 }
370 }
371
372 nw::gfx::ResEmitterArray emitters = resourceSet->resource.GetEmitters();
373 nw::gfx::ResEmitterArray::iterator emittersEnd = emitters.end();
374 for (nw::gfx::ResEmitterArray::iterator emitterResource = emitters.begin();
375 emitterResource != emittersEnd; ++emitterResource)
376 {
377 nw::gfx::SceneNode* node = CreateSceneNode(*emitterResource);
378 NW_NULL_ASSERT(node);
379
380 sceneNodeArray.push_back(node);
381
382 if (nw::ut::IsTypeOf<nw::gfx::ParticleEmitter>(node))
383 {
384 s_ParticleEmitters.push_back(static_cast<nw::gfx::ParticleEmitter*>(node));
385 }
386 }
387
388 // 親子付け参照関係を解決
389 //nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
390
391 nw::gfx::ParticleUtil::SetupParticleObject(&sceneNodeArray, s_ParticleContext);
392 }
393
394 /*!--------------------------------------------------------------------------*
395 @brief カメラの構築をします。
396 *---------------------------------------------------------------------------*/
397 void
BuildCameras()398 BuildCameras()
399 {
400 nw::gfx::LookAtTargetViewUpdater* viewUpdater
401 = nw::gfx::LookAtTargetViewUpdater::Create(&s_DeviceAllocator);
402
403 nw::gfx::ResLookAtTargetViewUpdater resViewUpdater =
404 nw::gfx::ResStaticCast<nw::gfx::ResLookAtTargetViewUpdater>(
405 viewUpdater->GetResource());
406 resViewUpdater.SetTargetPosition(0.0f,0.0f,0.0f);
407 resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f);
408
409 nw::gfx::PerspectiveProjectionUpdater* projectionUpdater
410 = nw::gfx::PerspectiveProjectionUpdater::Create(&s_DeviceAllocator);
411
412 nw::gfx::ResPerspectiveProjectionUpdater resProjectionUpdater =
413 nw::gfx::ResStaticCast<nw::gfx::ResPerspectiveProjectionUpdater>(
414 projectionUpdater->GetResource());
415 resProjectionUpdater.SetNear(s_NearPlane);
416 resProjectionUpdater.SetFar(1000.0f);
417 resProjectionUpdater.SetFovy(NW_MATH_DEG_TO_RAD(37.8f));
418
419 resProjectionUpdater.SetAspectRatio(
420 static_cast<f32>(s_RenderTarget->GetDescription().height) /
421 static_cast<f32>(s_RenderTarget->GetDescription().width));
422
423 s_BaseCamera =
424 nw::gfx::Camera::DynamicBuilder()
425 .MaxChildren(0)
426 .MaxCallbacks(0)
427 .ViewUpdater(viewUpdater)
428 .ProjectionUpdater(projectionUpdater)
429 .Create(&s_DeviceAllocator);
430 NW_POINTER_ASSERT(s_BaseCamera);
431 s_BaseCamera->Transform().SetTranslate(nw::math::VEC3(28.0f, 22.0f, 28.0f));
432
433 s_LeftCamera =
434 nw::gfx::Camera::DynamicBuilder()
435 .MaxChildren(0)
436 .MaxCallbacks(0)
437 .Create(&s_DeviceAllocator);
438 NW_POINTER_ASSERT(s_LeftCamera);
439
440 s_RightCamera =
441 nw::gfx::Camera::DynamicBuilder()
442 .MaxChildren(0)
443 .MaxCallbacks(0)
444 .Create(&s_DeviceAllocator);
445 NW_POINTER_ASSERT(s_RightCamera);
446
447 s_CameraController =
448 nw::demo::CameraController::Builder()
449 .MaxCameraCount(1)
450 .Create(&s_DeviceAllocator);
451 s_CameraController->Register(s_BaseCamera);
452 }
453
454 /*!--------------------------------------------------------------------------*
455 @brief シーンを初期化します。
456 *---------------------------------------------------------------------------*/
457 void
InitializeScenes()458 InitializeScenes()
459 {
460 BuildCameras();
461
462 NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
463 {
464 BuildResources(LoadResources(name));
465 }
466
467 NW_GL_ASSERT();
468
469 s_FrameCount = 0;
470 }
471
472 /*!--------------------------------------------------------------------------*
473 @brief シーン関連の後始末をします。
474 *---------------------------------------------------------------------------*/
475 void
TerminateScenes()476 TerminateScenes()
477 {
478 nw::gfx::SafeDestroyBranchAll(s_ParticleModels);
479 nw::gfx::SafeDestroyAll(s_ParticleEmitters);
480 s_ParticleSets.clear();
481 nw::demo::SafeCleanupResources(s_Resources);
482 nw::gfx::SafeDestroy(s_BaseCamera);
483 nw::gfx::SafeDestroy(s_LeftCamera);
484 nw::gfx::SafeDestroy(s_RightCamera);
485 nw::gfx::SafeDestroy(s_CameraController);
486
487 NW_GL_ASSERT();
488
489 s_Resources.clear();
490 }
491
492 /*!--------------------------------------------------------------------------*
493 @brief ノードを更新します。
494 *---------------------------------------------------------------------------*/
495 void
UpdateNode(nw::gfx::TransformNode * node)496 UpdateNode(nw::gfx::TransformNode* node)
497 {
498 // 一度計算したら計算処理をスキップする。
499 // ただし、ツリー構造は正しく解釈されない。
500 if (node->Transform().IsEnabledFlags(nw::gfx::CalculatedTransform::FLAG_IS_DIRTY))
501 {
502 s_WorldMatrixUpdater->UpdateBasic(
503 &node->WorldMatrix(),
504 &node->WorldTransform(),
505 node->Transform(),
506 nw::gfx::CalculatedTransform::Identity(),
507 nw::gfx::CalculatedTransform::Identity());
508
509 node->Transform().DisableFlags(nw::gfx::CalculatedTransform::FLAG_IS_DIRTY);
510 }
511 }
512
513 /*!--------------------------------------------------------------------------*
514 @brief カメラを更新します。
515 *---------------------------------------------------------------------------*/
UpdateCamera()516 void UpdateCamera()
517 {
518 s_CameraController->Update();
519 UpdateNode(s_BaseCamera);
520 s_BaseCamera->UpdateCameraMatrix();
521
522 // ステレオカメラの計算
523 NW_NULL_ASSERT(s_LeftCamera);
524 NW_NULL_ASSERT(s_RightCamera);
525 NW_NULL_ASSERT(s_BaseCamera);
526 nn::math::MTX44& projOriginal = s_BaseCamera->ProjectionMatrix();
527 nn::math::MTX34& viewOriginal = s_BaseCamera->ViewMatrix();
528 nn::math::MTX44& projL = s_LeftCamera->ProjectionMatrix();
529 nn::math::MTX34& viewL = s_LeftCamera->ViewMatrix();
530 nn::math::MTX44& projR = s_RightCamera->ProjectionMatrix();
531 nn::math::MTX34& viewR = s_RightCamera->ViewMatrix();
532
533 // Ortho カメラでは別の処理を行う必要があります。
534 // 例として demo::RenderSystem::CalcStereoCamera() を参照してください。
535 const f32 DEPTH_LEVEL = 5.0f + s_NearPlane;
536 const f32 DEPTH_RANGE = 1.0f;
537 s_StereoCamera->CalculateMatrices(
538 &projL,
539 &viewL,
540 &projR,
541 &viewR,
542 &projOriginal,
543 &viewOriginal,
544 DEPTH_LEVEL,
545 DEPTH_RANGE,
546 false);
547 }
548
549 /*!--------------------------------------------------------------------------*
550 @brief 生成されたノードを更新します。
551 *---------------------------------------------------------------------------*/
UpdateNodes()552 void UpdateNodes()
553 {
554 // モデル更新
555 ParticleModelArray::iterator particleModelEnd = s_ParticleModels.end();
556 for (ParticleModelArray::iterator node = s_ParticleModels.begin(); node != particleModelEnd; ++node)
557 {
558 UpdateNode(*node);
559 (*node)->UpdateParticleFrame();
560 }
561
562 EmitterArray::iterator particleEmitterEnd = s_ParticleEmitters.end();
563 for (EmitterArray::iterator node = s_ParticleEmitters.begin(); node != particleEmitterEnd; ++node)
564 {
565 UpdateNode(*node);
566 (*node)->UpdateParticleFrame();
567 (*node)->Emission(s_ParticleContext);
568 }
569
570 ParticleSetArray::iterator particleSetEnd = s_ParticleSets.end();
571 for (ParticleSetArray::iterator node = s_ParticleSets.begin(); node != particleSetEnd; ++node)
572 {
573 (*node)->UpdateParticles(s_ParticleContext);
574 }
575 }
576
577 /*!--------------------------------------------------------------------------*
578 @brief カメラ、ライト、フォグなどのシーン環境を設定します。
579 *---------------------------------------------------------------------------*/
580 void
SetEnvironment()581 SetEnvironment()
582 {
583 nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderContext->GetSceneEnvironment();
584 sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
585 }
586
587 /*!--------------------------------------------------------------------------*
588 @brief シーンを更新します。
589 *---------------------------------------------------------------------------*/
590 void
UpdateScene()591 UpdateScene()
592 {
593 UpdateNodes();
594
595 UpdateCamera();
596
597 ++s_FrameCount;
598
599 // デモでは少量のメモリしか扱わないので明示的にフラッシュする必要がある
600 s_FlushCache->Execute();
601 }
602
603 /*!--------------------------------------------------------------------------*
604 @brief ビューに関連する更新処理を行います。
605 *---------------------------------------------------------------------------*/
606 void
SubmitView()607 SubmitView()
608 {
609 ParticleModelArray::iterator particleModelEnd = s_ParticleModels.end();
610 for (ParticleModelArray::iterator node = s_ParticleModels.begin(); node != particleModelEnd; ++node)
611 {
612 nw::gfx::ResModel resModel = (*node)->GetResModel();
613 NW_ASSERT(resModel.IsValid());
614 if (!resModel.IsVisible()) {
615 continue;
616 }
617
618 (*node)->UpdateModelViewMatrixAndNormalMatrix(s_BaseCamera->ViewMatrix(), false);
619 }
620 }
621
622 /*!--------------------------------------------------------------------------*
623 @brief シーンを描画します。
624 *---------------------------------------------------------------------------*/
625 void
RenderScene()626 RenderScene()
627 {
628 s_RenderContext->SetRenderTarget(s_RenderTarget);
629 s_RenderContext->SetActiveCamera(0);
630
631 // 描画コマンドを生成します。
632 s_CommandListSwapper->StartCommandSave();
633 NW_GL_ASSERT();
634
635 s_RenderContext->ClearBuffer(
636 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
637 nw::ut::FloatColor(0.5f, 0.5f, 0.5f, 1.0f),
638 1.0f);
639
640 ParticleModelArray::iterator modelEnd = s_ParticleModels.end();
641 for (ParticleModelArray::iterator model = s_ParticleModels.begin(); model != modelEnd; ++model)
642 {
643 if ((*model)->IsVisible())
644 {
645 nw::gfx::ResMeshArray resMeshes = (*model)->GetResMeshes();
646
647 nw::gfx::ResMeshArray::iterator meshEnd = resMeshes.end();
648 for(nw::gfx::ResMeshArray::iterator mesh = resMeshes.begin();
649 mesh != meshEnd;
650 ++mesh)
651 {
652 if ((*model)->IsMeshVisible(*mesh))
653 {
654 s_MeshRenderer->RenderMesh(*mesh, *model);
655 }
656 }
657 }
658 }
659 NW_GL_ASSERT();
660
661 s_CommandListSwapper->EndCommandSave();
662
663 // 左目の描画を行います。
664 s_RenderContext->SetCameraMatrix(s_LeftCamera);
665 s_CommandListSwapper->ReuseCommand(false);
666 s_UpperSwapper->MakeTransferBufferCommand(s_RenderTarget, false);
667
668 // 右目の描画を行います。
669 s_RenderContext->SetCameraMatrix(s_RightCamera);
670 s_CommandListSwapper->ReuseCommand(false);
671 s_ExtensionSwapper->MakeTransferBufferCommand(s_RenderTarget, false);
672
673 s_CommandListSwapper->WaitDone();
674 s_CommandListSwapper->RunAsync();
675 }
676
677 /*!--------------------------------------------------------------------------*
678 @brief ディスプレイバッファをスワップして表示します。
679 *---------------------------------------------------------------------------*/
680 void
PresentBuffer()681 PresentBuffer()
682 {
683 s_UpperSwapper->ActivateBuffer();
684 s_ExtensionSwapper->ActivateBuffer();
685
686 nngxSwapBuffers(NN_GX_DISPLAY0);
687
688 glBindFramebuffer(GL_FRAMEBUFFER, 0);
689
690 NW_GL_ASSERT();
691
692 nngxWaitVSync(NN_GX_DISPLAY0);
693 }
694
695 /*!--------------------------------------------------------------------------*
696 @brief シーンをデモンストレーションします。
697 *---------------------------------------------------------------------------*/
698 void
DemoScene()699 DemoScene()
700 {
701 NW_NULL_ASSERT(s_RenderTarget);
702
703 InitializeScenes();
704
705 nw::demo::DebugUtility::PostInitializeScenes();
706
707 s_CommandListSwapper->RunAsync();
708
709 bool isContinuing = true;
710
711 while ( isContinuing )
712 {
713 nw::demo::DebugUtility::AdvanceAutoTestFrame();
714
715 nw::demo::PadFactory::GetPad()->Update();
716
717 UpdateScene();
718
719 SetEnvironment();
720
721 s_RenderContext->SetActiveCamera(s_BaseCameraIndex);
722
723 SubmitView();
724
725 RenderScene();
726
727 s_RenderContext->ResetState();
728
729 PresentBuffer();
730
731 if (nw::demo::Utility::IsTerminating())
732 {
733 isContinuing = false;
734 }
735 }
736
737 nw::demo::DebugUtility::PreTerminateScenes();
738
739 TerminateScenes();
740 }
741
742 } // namespace
743
744 /*!--------------------------------------------------------------------------*
745 @brief メイン関数です。
746 *---------------------------------------------------------------------------*/
747 void
nnMain()748 nnMain()
749 {
750 InitializeGraphicsSystem();
751
752 nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
753
754 NW_DEMO_TEST_LOOP(&s_DeviceAllocator, &s_DeviceAllocator, NULL)
755 {
756 InitializeGraphics();
757
758 s_FlushCache = nw::demo::FlushCache::Create(&s_DeviceAllocator);
759
760 DemoScene();
761
762 // キャッシュフラッシュ用のクラスを破棄
763 nw::ut::SafeDestroy(s_FlushCache);
764
765 TerminateGraphics();
766 }
767
768 nw::demo::PadFactory::Finalize();
769
770 FinalizeGraphicsSystem();
771 }
772