1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: MultiAnimationDemo.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: 19751 $
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
23 #include <nw/demo.h>
24 #include <nw/dev.h>
25 #include <nw/gfx.h>
26 #include <nw/ut.h>
27 #include <nw/anim.h>
28
29 namespace
30 {
31
32 //----------------------------------------
33 // メモリ関係
34
35 // デバイスメモリを確保するためのアロケータです。
36 nw::demo::DemoAllocator s_DeviceAllocator;
37
38 //----------------------------------------
39 // ファイル名の定義です。
40 const wchar_t* FONT_SHADER_FILE_NAME = NW_DEMO_FILE_PATH(L"nwfont_RectDrawerShader.shbin");
41 const wchar_t* FONT_FILE_NAME = NW_DEMO_FILE_PATH(L"Font.bcfnt");
42 const wchar_t* SKY_SPHERE_FILE_NAME = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
43
44 const wchar_t* RESOURCE_FILES[] =
45 {
46 NW_DEMO_FILE_PATH(L"MultiAnimation.bcmdl"),
47 NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
48 NW_DEMO_FILE_PATH(L"FragmentLight.bcenv"),
49 NW_DEMO_FILE_PATH(L"Walk.bcskla"),
50 NW_DEMO_FILE_PATH(L"MatAnim.bcmata"),
51 NW_DEMO_FILE_PATH(L"VisibilityAnim.bcmdla"),
52 NW_DEMO_FILE_PATH(L"CameraAnim.bccam"),
53 NW_DEMO_FILE_PATH(L"LightAnim.bclgt"),
54 NW_DEMO_FILE_PATH(L"LightAnim.bcenv")
55 };
56
57 const wchar_t* LUT_RESOURCE_FILE = NW_DEMO_FILE_PATH(L"LightAnim.bcres");
58
59 //----------------------------------------
60 // プロファイル関係
61 const int NW_LOAD_METER_INTERVAL = 60;
62
63 //----------------------------------------
64 // 描画関係
65 const int RENDER_TARGET_COUNT = 1;
66 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
67
68 RenderTargetArray s_RenderTargets;
69 nw::demo::SceneSystem* s_SceneSystem = NULL;
70 nw::demo::RenderSystem* s_RenderSystem = NULL;
71
72 nw::demo::GraphicsDrawing s_GraphicsDrawing;
73
74 //----------------------------------------
75 // リソース関係
76 nw::demo::ResourceArray s_Resources;
77 nw::demo::ResourceSet* s_LutResource;
78
79 //----------------------------------------
80 // シーン関係
81 const int SCENE_NODE_COUNT = 4;
82 nw::gfx::SceneNode* s_SceneRoot = NULL;
83 s32 s_FrameCount = 0;
84 nw::gfx::Camera* s_BaseCamera = NULL;
85 nw::gfx::Camera* s_LeftCamera = NULL;
86 nw::gfx::Camera* s_RightCamera = NULL;
87 nw::gfx::Camera* s_AnimCamera = NULL;
88 nw::gfx::Camera* s_ActiveCamera = NULL;
89
90 const f32 s_fNearPlane = 0.1f;
91
92 nw::gfx::SceneNode* s_SceneRootInvisible = NULL;
93 nw::gfx::SceneNode* s_SkeletalRoot = NULL;
94 nw::gfx::SceneNode* s_MaterialRoot = NULL;
95 nw::gfx::SceneNode* s_VisibilityRoot = NULL;
96 nw::gfx::SceneNode* s_CameraRoot = NULL;
97 nw::gfx::SceneNode* s_LightRoot = NULL;
98
99 //----------------------------------------
100 // シーン環境関係
101 const s32 ENVIRONMENT_SETTINGS_COUNT = 2;
102
103 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
104 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
105
106 const s32 s_BaseCameraIndex = 0;
107 const s32 s_AnimCameraIndex = 1;
108
109 //----------------------------------------
110 // アニメーション関係
111 const int MAX_ANIM_OBJECTS = 8;
112 nw::ut::FixedSizeArray<nw::gfx::AnimObject*, MAX_ANIM_OBJECTS> s_AnimObjects;
113 float s_AnimWeight0 = 0.5f;
114 float s_AnimWeight1 = 0.5f;
115
116 s32 s_ActiveCameraIndex = s_BaseCameraIndex;
117 const int ANIMATION_RESOURCES_COUNT = 9;
118 const int ANIMATION_TARGETS_COUNT = 15;
119
120 nw::ut::FixedSizeArray<nw::gfx::ResGraphicsFile, ANIMATION_RESOURCES_COUNT> s_ResAnims;
121 nw::ut::FixedSizeArray<nw::gfx::SceneObject*, ANIMATION_TARGETS_COUNT> s_AnimTargets;
122
123 struct AnimBindingTable
124 {
125 const char* targetName;
126 const char* animName;
127 nw::demo::Utility::AnimationType animType;
128 };
129
130 const AnimBindingTable ANIM_BINDING_TABLE[] =
131 {
132 { "Male", "Walk", nw::demo::Utility::SKELETAL_ANIMATION },
133 { "MatAnim", "MatAnim", nw::demo::Utility::MATERIAL_ANIMATION },
134 { "VisibilityAnim", "VisibilityAnim", nw::demo::Utility::VISIBILITY_ANIMATION },
135 { "AnimCamera", "CameraAnim", nw::demo::Utility::CAMERA_ANIMATION },
136 { "pointLight1", "pointLight1", nw::demo::Utility::LIGHT_ANIMATION },
137 { "pointLight2", "pointLight2", nw::demo::Utility::LIGHT_ANIMATION },
138 { "pointLight3", "pointLight3", nw::demo::Utility::LIGHT_ANIMATION }
139 };
140
141 //----------------------------------------
142 // 操作関係
143 int s_AnimMode = 0;
144
145 /*!--------------------------------------------------------------------------*
146 @brief グラフィックス関連の初期化を行います。
147 *---------------------------------------------------------------------------*/
148 void
InitializeGraphics()149 InitializeGraphics()
150 {
151 nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
152
153 // renderDescriptionへステレオの設定を行います。
154 nw::demo::RenderSystem::Description renderDescription;
155
156 renderDescription.reusableCommandBufferSize = 0x100000;
157 renderDescription.reusableCommandRequestCount = 512;
158 renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
159
160 s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
161
162 s_GraphicsDrawing.SetScreenSize(
163 renderDescription.lowerScreenDescription.width,
164 renderDescription.lowerScreenDescription.height
165 );
166
167 bool result = s_GraphicsDrawing.InitializeFont(&s_DeviceAllocator, FONT_SHADER_FILE_NAME, FONT_FILE_NAME);
168
169 NN_ASSERTMSG(result, "Fail to load Font.");
170
171 s_RenderTargets.push_back(
172 nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
173 );
174 NW_ASSERT(!s_RenderTargets.empty());
175 s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
176
177 // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
178 nw::demo::SceneSystem::Description sceneDescription;
179 s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
180
181 // デモ用の最遠景モデルをレンダリングシステムに設定します。
182 // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
183 s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
184
185 NW_GL_ASSERT();
186 }
187
188 /*!--------------------------------------------------------------------------*
189 @brief グラフィックス関連の後始末をします。
190 *---------------------------------------------------------------------------*/
191 void
TerminateGraphics()192 TerminateGraphics()
193 {
194 nw::gfx::SafeDestroy(s_LeftCamera);
195
196 nw::gfx::SafeDestroy(s_RightCamera);
197
198 nw::gfx::SafeDestroy(s_SceneSystem);
199
200 nw::gfx::SafeDestroyAll(s_RenderTargets);
201
202 s_GraphicsDrawing.Finalize();
203
204 nw::gfx::SafeDestroy(s_RenderSystem);
205
206 NW_GL_ASSERT();
207 }
208
209 /*!--------------------------------------------------------------------------*
210 @brief アニメーションの後始末をします。
211 *---------------------------------------------------------------------------*/
212 void
TerminateAnim(void)213 TerminateAnim(void)
214 {
215 for (int animIdx = 0; animIdx < s_AnimObjects.Size(); ++animIdx)
216 {
217 nw::gfx::SafeDestroy(s_AnimObjects[animIdx]);
218 }
219 s_AnimObjects.clear();
220 }
221
222 /*!--------------------------------------------------------------------------*
223 @brief カメラを切り替えます。
224 *---------------------------------------------------------------------------*/
225 void
ChangeCamera(s32 cameraIndex)226 ChangeCamera(s32 cameraIndex)
227 {
228 s_RenderSystem->GetRenderContext()->SetActiveCamera(cameraIndex);
229
230 s_ActiveCamera = s_RenderSystem->GetRenderContext()->GetActiveCamera();
231 s_ActiveCameraIndex = cameraIndex;
232
233 nw::demo::Utility::SetCameraAspectRatio(s_ActiveCamera, s_RenderTargets[0]);
234 }
235
236 /*!--------------------------------------------------------------------------*
237 @brief ルートノード関連の構築をします。
238 *---------------------------------------------------------------------------*/
239 void
BuildRootNodes()240 BuildRootNodes()
241 {
242 NW_ASSERT(s_SceneRoot == NULL);
243 s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
244 .IsFixedSizeMemory(false)
245 .Create(&s_DeviceAllocator);
246 NW_NULL_ASSERT(s_SceneRoot);
247
248 NW_ASSERT(s_SceneRootInvisible == NULL);
249 s_SceneRootInvisible = nw::gfx::TransformNode::DynamicBuilder()
250 .IsFixedSizeMemory(false)
251 .Create(&s_DeviceAllocator);
252
253 // 各アニメーション毎にルートノードを作成します。
254 NW_ASSERT(s_SkeletalRoot == NULL);
255 s_SkeletalRoot = nw::gfx::TransformNode::DynamicBuilder()
256 .IsFixedSizeMemory(false)
257 .Create(&s_DeviceAllocator);
258 s_SceneRootInvisible->AttachChild(s_SkeletalRoot);
259 NW_NULL_ASSERT(s_SkeletalRoot);
260
261 NW_ASSERT(s_MaterialRoot == NULL);
262 s_MaterialRoot = nw::gfx::TransformNode::DynamicBuilder()
263 .IsFixedSizeMemory(false)
264 .Create(&s_DeviceAllocator);
265 s_SceneRootInvisible->AttachChild(s_MaterialRoot);
266 NW_NULL_ASSERT(s_MaterialRoot);
267
268 NW_ASSERT(s_VisibilityRoot == NULL);
269 s_VisibilityRoot = nw::gfx::TransformNode::DynamicBuilder()
270 .IsFixedSizeMemory(false)
271 .Create(&s_DeviceAllocator);
272 s_SceneRootInvisible->AttachChild(s_VisibilityRoot);
273 NW_NULL_ASSERT(s_VisibilityRoot);
274
275 NW_ASSERT(s_CameraRoot == NULL);
276 s_CameraRoot = nw::gfx::TransformNode::DynamicBuilder()
277 .IsFixedSizeMemory(false)
278 .Create(&s_DeviceAllocator);
279 s_SceneRootInvisible->AttachChild(s_CameraRoot);
280 NW_NULL_ASSERT(s_CameraRoot);
281
282 NW_ASSERT(s_LightRoot == NULL);
283 s_LightRoot = nw::gfx::TransformNode::DynamicBuilder()
284 .IsFixedSizeMemory(false)
285 .Create(&s_DeviceAllocator);
286 s_SceneRootInvisible->AttachChild(s_LightRoot);
287 NW_NULL_ASSERT(s_LightRoot);
288 }
289
290 /*!--------------------------------------------------------------------------*
291 @brief カメラ関連の構築をします。
292 *---------------------------------------------------------------------------*/
293 void
BuildCameras()294 BuildCameras()
295 {
296 nw::demo::Utility::CreateStereoCameras(
297 &s_BaseCamera,
298 &s_LeftCamera,
299 &s_RightCamera,
300 &s_DeviceAllocator,
301 nw::math::VEC3(20.0f, 15.0f, 20.0f),
302 nw::math::VEC3(0.0f, 0.0f, 0.0f),
303 s_fNearPlane
304 );
305
306 s_SceneRoot->AttachChild(s_BaseCamera);
307 s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
308 }
309
310 /*!--------------------------------------------------------------------------*
311 @brief リソース関連の構築をします。
312 *---------------------------------------------------------------------------*/
313 void
BuildResources(nw::demo::ResourceSet * resourceSet)314 BuildResources(nw::demo::ResourceSet* resourceSet)
315 {
316 resourceSet->resource.ForeachTexture(nw::gfx::TextureLocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
317 resourceSet->resource.ForeachIndexStream(nw::gfx::IndexStreamLocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
318 resourceSet->resource.ForeachVertexStream(nw::gfx::VertexStreamLocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
319
320 nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
321 if (result.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT)
322 {
323 result = resourceSet->resource.Setup(&s_DeviceAllocator, s_LutResource->resource);
324 }
325 if (result.IsFailure())
326 {
327 NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
328 }
329
330 nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(&s_DeviceAllocator);
331
332 nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
333 nw::gfx::ResModelArray::iterator modelsEnd = models.end();
334 for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
335 modelResource != modelsEnd; ++modelResource)
336 {
337 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
338 &s_DeviceAllocator,
339 (*modelResource)
340 );
341 NW_NULL_ASSERT(node);
342 sceneNodeArray.push_back(node);
343
344 s_AnimTargets.push_back(node);
345 }
346
347 nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
348 nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
349 for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
350 lightResource != lightsEnd; ++lightResource)
351 {
352 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
353 &s_DeviceAllocator,
354 (*lightResource)
355 );
356 NW_NULL_ASSERT(node);
357 sceneNodeArray.push_back(node);
358
359 s_AnimTargets.push_back(node);
360 }
361
362 nw::gfx::ResCameraArray cameras = resourceSet->resource.GetCameras();
363 nw::gfx::ResCameraArray::iterator camerasEnd = cameras.end();
364 for (nw::gfx::ResCameraArray::iterator cameraResource = cameras.begin();
365 cameraResource != camerasEnd; ++cameraResource)
366 {
367 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
368 &s_DeviceAllocator,
369 (*cameraResource)
370 );
371 NW_NULL_ASSERT(node);
372 sceneNodeArray.push_back(node);
373
374 s_AnimTargets.push_back(node);
375 }
376
377 // 親子付け参照関係を解決
378 nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
379
380 // モデルをシーンに追加
381 nw::gfx::SceneHelper::ForeachRootNodes(
382 sceneNodeArray.Begin(),
383 sceneNodeArray.End(),
384 nw::gfx::AttachNode(s_SceneRoot)
385 );
386
387 nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
388 nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
389 for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
390 settingResource != settingsEnd; ++settingResource)
391 {
392 nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
393 .Resource(*settingResource)
394 .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
395
396 nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
397 nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
398
399 NW_NULL_ASSERT(sceneEnvironmentSetting);
400 s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
401 }
402 }
403
404 /*!--------------------------------------------------------------------------*
405 @brief アニメーション関連の構築をします。
406 *---------------------------------------------------------------------------*/
407 void
BuildAnimations()408 BuildAnimations()
409 {
410 s_AnimCamera = NULL;
411
412 NW_FOREACH(AnimBindingTable animBindingTable, ANIM_BINDING_TABLE)
413 {
414 s_AnimObjects.PushBack(
415 nw::demo::Utility::BindAnimationByName(
416 &s_DeviceAllocator,
417 s_AnimTargets,
418 s_ResAnims,
419 animBindingTable.targetName,
420 animBindingTable.animName,
421 animBindingTable.animType,
422 false)
423 );
424
425 if (animBindingTable.animType == nw::demo::Utility::CAMERA_ANIMATION)
426 {
427 s_AnimCamera = nw::ut::DynamicCast<nw::gfx::Camera*>
428 (nw::demo::Utility::FindObjectByName(s_AnimTargets, animBindingTable.targetName));
429 }
430 }
431
432 NW_NULL_ASSERT(s_AnimCamera);
433 }
434
435 /*!--------------------------------------------------------------------------*
436 @brief 指定した名前のオブジェクトを指定したシーンルートに再配置します。
437 *---------------------------------------------------------------------------*/
438 void
ReattachObjectByName(const char * name,nw::gfx::SceneNode * root)439 ReattachObjectByName(const char* name, nw::gfx::SceneNode* root)
440 {
441 nw::gfx::SceneNode* node = nw::ut::DynamicCast<nw::gfx::SceneNode*>
442 (nw::demo::Utility::FindObjectByName(s_AnimTargets, name));
443
444 NW_NULL_ASSERT(node);
445
446 node->GetParent()->DetachChild( node );
447 root->AttachChild( node );
448 }
449
450 /*!--------------------------------------------------------------------------*
451 @brief 指定した名前のオブジェクトを移動します。
452 *---------------------------------------------------------------------------*/
453 void
MoveObjectByName(const char * name,f32 x,f32 y,f32 z)454 MoveObjectByName(const char* name, f32 x, f32 y, f32 z)
455 {
456 nw::gfx::TransformNode* node = nw::ut::DynamicCast<nw::gfx::TransformNode*>
457 (nw::demo::Utility::FindObjectByName(s_AnimTargets, name));
458
459 NW_NULL_ASSERT(node);
460
461 node->Transform().SetTranslate(x,y,z);
462 }
463
464 /*!--------------------------------------------------------------------------*
465 @brief オブジェクトを各シーンルートに再配置します。
466 *---------------------------------------------------------------------------*/
467 void
ReattachObjects()468 ReattachObjects()
469 {
470 // スケルタルアニメーション
471 ReattachObjectByName("Male", s_SkeletalRoot);
472 MoveObjectByName("Male", 0.0f, -8.0f, 0.0f);
473
474 // マテリアルアニメーション
475 ReattachObjectByName("MatAnim", s_MaterialRoot);
476
477 // ビジビリティアニメーション
478 ReattachObjectByName("VisibilityAnim", s_VisibilityRoot);
479 MoveObjectByName("VisibilityAnim", 0.0f, -8.0f, 0.0f);
480
481 // カメラアニメーション
482 ReattachObjectByName("CameraAnim", s_CameraRoot);
483
484 // ライトアニメーション
485 ReattachObjectByName("LightAnim", s_LightRoot);
486 }
487
488 /*!--------------------------------------------------------------------------*
489 @brief アニメーションを切り替えます。
490 *---------------------------------------------------------------------------*/
491 void
ToggleAnimationMode(bool isIncremental)492 ToggleAnimationMode(bool isIncremental)
493 {
494 // s_SceneRoot から取り外したシーンノードは描画されなくなります。
495 // 不可視にするためには取り外すだけで十分なのですが、
496 // 破棄などの処理を行いやすくするために、描画しないシーンノードは
497 // s_SceneRootInvisible という別のシーンルートに取り付けておきます。
498
499 switch (s_AnimMode)
500 {
501 case 0:
502 s_SceneRoot->DetachChild(s_SkeletalRoot);
503 s_SceneRootInvisible->AttachChild(s_SkeletalRoot);
504 break;
505 case 1:
506 s_SceneRoot->DetachChild(s_MaterialRoot);
507 s_SceneRootInvisible->AttachChild(s_MaterialRoot);
508 break;
509 case 2:
510 s_SceneRoot->DetachChild(s_VisibilityRoot);
511 s_SceneRootInvisible->AttachChild(s_VisibilityRoot);
512 break;
513 case 3:
514 ChangeCamera(s_BaseCameraIndex);
515 s_SceneRoot->DetachChild(s_CameraRoot);
516 s_SceneRootInvisible->AttachChild(s_CameraRoot);
517 break;
518 case 4:
519 s_SceneRoot->DetachChild(s_LightRoot);
520 s_SceneRootInvisible->AttachChild(s_LightRoot);
521 break;
522 default:
523 NW_ASSERT(false);
524 }
525
526 if (isIncremental)
527 {
528 s_AnimMode++;
529 if (s_AnimMode > 4)
530 {
531 s_AnimMode = 0;
532 }
533 }
534 else
535 {
536 s_AnimMode--;
537 if (s_AnimMode < 0)
538 {
539 s_AnimMode = 4;
540 }
541 }
542
543 switch (s_AnimMode)
544 {
545 case 0:
546 s_SceneRootInvisible->DetachChild(s_SkeletalRoot);
547 s_SceneRoot->AttachChild(s_SkeletalRoot);
548 break;
549 case 1:
550 s_SceneRootInvisible->DetachChild(s_MaterialRoot);
551 s_SceneRoot->AttachChild(s_MaterialRoot);
552 break;
553 case 2:
554 s_SceneRootInvisible->DetachChild(s_VisibilityRoot);
555 s_SceneRoot->AttachChild(s_VisibilityRoot);
556 break;
557 case 3:
558 s_SceneRootInvisible->DetachChild(s_CameraRoot);
559 s_SceneRoot->AttachChild(s_CameraRoot);
560 ChangeCamera(s_AnimCameraIndex);
561 break;
562 case 4:
563 s_SceneRootInvisible->DetachChild(s_LightRoot);
564 s_SceneRoot->AttachChild(s_LightRoot);
565 break;
566 default:
567 NW_ASSERT(false);
568 }
569
570 // シーン構造が変化したので、シーンの初期化を行います。
571 s_SceneSystem->InitializeScene(s_SceneRoot);
572 }
573 /*!--------------------------------------------------------------------------*
574 @brief シーンを初期化します。
575 *---------------------------------------------------------------------------*/
576 void
InitializeScenes()577 InitializeScenes()
578 {
579 BuildRootNodes();
580
581 BuildCameras();
582
583 // LUT を持ったリソースを読み込みます。
584 s_LutResource = nw::demo::Utility::LoadResources(s_Resources, LUT_RESOURCE_FILE, &s_DeviceAllocator);
585 BuildResources(s_LutResource);
586
587 // モデルやそれ以外のリソースを読み込みます。
588 NW_FOREACH(const wchar_t* name, RESOURCE_FILES)
589 {
590 nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator);
591 BuildResources(resourceSet);
592 s_ResAnims.push_back(resourceSet->resource);
593 }
594
595 BuildAnimations();
596 ReattachObjects();
597
598 // ライトアニメーションを表示します
599 s_SceneRootInvisible->DetachChild(s_LightRoot);
600 s_SceneRoot->AttachChild(s_LightRoot);
601 s_AnimMode = 4;
602
603 // シーンツリーを巡回して初期化を行います。
604 s_SceneSystem->InitializeScene(s_SceneRoot);
605 s_SceneSystem->UpdateScene();
606
607 // シーン環境の参照解決を行い設定します。
608 s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
609 nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
610 sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
611 sceneEnvironment.SetCamera(s_AnimCameraIndex, s_AnimCamera);
612 ChangeCamera(s_BaseCameraIndex);
613
614 NW_GL_ASSERT();
615
616 s_FrameCount = 0;
617 }
618
619 /*!--------------------------------------------------------------------------*
620 @brief シーン関連の後始末をします。
621 *---------------------------------------------------------------------------*/
622 void
TerminateScenes()623 TerminateScenes()
624 {
625 // 表示されていないシーンオブジェクトも破棄するために s_SceneRootInvisible に対して SafeDestroyBranch を実行します。
626 nw::gfx::SafeDestroyBranch(s_SceneRoot);
627 nw::gfx::SafeDestroyBranch(s_SceneRootInvisible);
628 nw::demo::SafeCleanupResources(s_Resources);
629 nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings);
630
631 TerminateAnim();
632
633 NW_GL_ASSERT();
634
635 s_Resources.clear();
636 s_SceneEnvironmentSettings.clear();
637
638 s_SceneRoot = NULL;
639 s_SkeletalRoot = NULL;
640 s_MaterialRoot = NULL;
641 s_VisibilityRoot = NULL;
642 s_CameraRoot = NULL;
643 s_LightRoot = NULL;
644 }
645
646 /*!--------------------------------------------------------------------------*
647 @brief シーンを更新します。
648 *---------------------------------------------------------------------------*/
649 void
UpdateScene()650 UpdateScene()
651 {
652 s_SceneSystem->GetCameraController()->Update();
653
654 s_SceneSystem->UpdateScene();
655
656 s_ActiveCamera->UpdateCameraMatrix();
657
658 f32 near = s_ActiveCamera->GetNear();
659
660 s_RenderSystem->CalcStereoCamera(
661 s_LeftCamera,
662 s_RightCamera,
663 s_ActiveCamera,
664 near + 5.0f);
665
666 ++s_FrameCount;
667 }
668
669 /*!--------------------------------------------------------------------------*
670 @brief 負荷表示やテスト機能の処理をおこないます。
671 *---------------------------------------------------------------------------*/
672 void
ReportDemo()673 ReportDemo()
674 {
675 NW_PROFILE("ReportDemo");
676
677 // 負荷表示からはこれらの負荷は除きます。
678 s_RenderSystem->SuspendLoadMeter();
679
680 s_GraphicsDrawing.BeginDrawingString();
681
682 nw::demo::DebugUtility::DrawLoadMeter(
683 s_RenderSystem,
684 &s_GraphicsDrawing,
685 (s_FrameCount % NW_LOAD_METER_INTERVAL == 0)
686 );
687
688 const int dumpPositionX = 10;
689 const int dumpPositionY = 10;
690 const char* mode;
691 switch (s_AnimMode)
692 {
693 case 0:
694 mode = "Skeletal";
695 break;
696 case 1:
697 mode = "Material";
698 break;
699 case 2:
700 mode = "Visibility";
701 break;
702 case 3:
703 mode = "Camera";
704 break;
705 case 4:
706 mode = "Light";
707 break;
708 default:
709 mode = "";
710 break;
711 }
712 s_GraphicsDrawing.DrawString(
713 dumpPositionX,
714 dumpPositionY,
715 "%s",
716 mode
717 );
718
719 s_GraphicsDrawing.FlushDrawing();
720
721 s_RenderSystem->ResumeLoadMeter();
722 }
723
724 /*!--------------------------------------------------------------------------*
725 @brief シーンをデモンストレーションします。
726 *---------------------------------------------------------------------------*/
727 void
DemoScene()728 DemoScene()
729 {
730 NW_ASSERT(!s_RenderTargets.empty());
731
732 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
733
734 InitializeScenes();
735
736 bool isContinuing = true;
737
738 while ( isContinuing )
739 {
740 nw::demo::DebugUtility::AdvanceAutoTestFrame();
741
742 nw::demo::PadFactory::GetPad()->Update();
743
744 if (nw::demo::PadFactory::GetPad()->IsButtonDown( nw::demo::Pad::BUTTON_L ))
745 {
746 ToggleAnimationMode(true);
747 }
748 if (nw::demo::PadFactory::GetPad()->IsButtonDown( nw::demo::Pad::BUTTON_R ))
749 {
750 ToggleAnimationMode(false);
751 }
752 UpdateScene();
753
754 renderContext->SetActiveCamera(s_ActiveCameraIndex);
755 s_RenderSystem->SubmitView(s_SceneSystem);
756
757 s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
758 s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
759
760 s_RenderSystem->ClearBySkyModel(renderContext->GetActiveCamera());
761 ReportDemo();
762 s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
763
764 s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
765
766 renderContext->ResetState();
767
768 if (nw::demo::Utility::IsTerminating())
769 {
770 isContinuing = false;
771 }
772 }
773
774 TerminateScenes();
775 }
776
777 } // namespace
778
779 /*!--------------------------------------------------------------------------*
780 @brief メイン関数です。
781 *---------------------------------------------------------------------------*/
782 void
nnMain()783 nnMain()
784 {
785 nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
786
787 nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
788
789 NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
790 {
791 InitializeGraphics();
792
793 DemoScene();
794
795 TerminateGraphics();
796 }
797
798 nw::demo::PadFactory::Finalize();
799
800 nw::demo::FinalizeGraphicsSystem();
801 }
802