1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     AnimationDemo.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: 28317 $
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* SKY_SPHERE_FILE_NAME  = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
41 
42 const wchar_t* MODEL_RESOURCE_FILES[] =
43 {
44     NW_DEMO_FILE_PATH(L"Male.bcmdl"),
45     NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
46     NW_DEMO_FILE_PATH(L"FragmentLight.bcenv"),
47 };
48 
49 const wchar_t* SKELETAL_ANIM_RESOURCE_FILE = NW_DEMO_FILE_PATH(L"Walk.bcskla");
50 
51 //----------------------------------------
52 // 描画関係
53 const s32 RENDER_TARGET_COUNT = 1;
54 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
55 
56 RenderTargetArray s_RenderTargets;
57 nw::demo::SceneSystem*  s_SceneSystem = NULL;
58 nw::demo::RenderSystem* s_RenderSystem = NULL;
59 
60 nw::demo::GraphicsDrawing  s_GraphicsDrawing;
61 
62 //----------------------------------------
63 // リソース関係
64 nw::demo::ResourceArray s_Resources;
65 
66 //----------------------------------------
67 // シーン関係
68 const int SCENE_NODE_COUNT = 4;
69 nw::gfx::SceneNode* s_SceneRoot = NULL;
70 nw::gfx::SceneNode* s_ModelRoot = NULL;
71 s32 s_FrameCount = 0;
72 nw::gfx::Camera* s_BaseCamera = NULL;
73 nw::gfx::Camera* s_LeftCamera = NULL;
74 nw::gfx::Camera* s_RightCamera = NULL;
75 const f32 s_fNearPlane = 0.1f;
76 
77 //----------------------------------------
78 // シーン環境関係
79 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
80 
81 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
82 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
83 
84 const s32 s_BaseCameraIndex = 0;
85 
86 //----------------------------------------
87 // アニメーション関係
88 nw::gfx::SkeletalModel* s_AnimModel = NULL;
89 nw::gfx::TransformAnimEvaluator* s_AnimEvaluator = NULL;
90 
91 float s_StepFrame = 1.0f;
92 
93 /*!--------------------------------------------------------------------------*
94   @brief        グラフィックス関連の初期化を行います。
95  *---------------------------------------------------------------------------*/
96 void
InitializeGraphics()97 InitializeGraphics()
98 {
99     nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
100 
101     // renderDescriptionへステレオの設定を行います。
102     nw::demo::RenderSystem::Description renderDescription;
103 
104     renderDescription.reusableCommandBufferSize = 0x100000;
105     renderDescription.reusableCommandRequestCount = 512;
106     renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
107 
108     s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
109 
110     s_GraphicsDrawing.SetScreenSize(
111         renderDescription.lowerScreenDescription.width,
112         renderDescription.lowerScreenDescription.height
113     );
114 
115     nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
116 
117     s_RenderTargets.push_back(
118         nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
119     );
120     NW_ASSERT(!s_RenderTargets.empty());
121     s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
122 
123     // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
124     nw::demo::SceneSystem::Description sceneDescription;
125     sceneDescription.isFixedSizeMemory = true;
126     s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
127 
128     // デモ用の最遠景モデルをレンダリングシステムに設定します。
129     // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
130     s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
131 
132     NW_GL_ASSERT();
133 }
134 
135 /*!--------------------------------------------------------------------------*
136   @brief        グラフィックス関連の後始末をします。
137  *---------------------------------------------------------------------------*/
138 void
TerminateGraphics()139 TerminateGraphics()
140 {
141     nw::gfx::SafeDestroy(s_LeftCamera);
142 
143     nw::gfx::SafeDestroy(s_RightCamera);
144 
145     nw::gfx::SafeDestroy(s_SceneSystem);
146 
147     nw::gfx::SafeDestroyAll(s_RenderTargets);
148 
149     s_GraphicsDrawing.Finalize();
150 
151     nw::gfx::SafeDestroy(s_RenderSystem);
152 
153     NW_GL_ASSERT();
154 }
155 
156 /*!--------------------------------------------------------------------------*
157   @brief ファイルから TransformAnimEvaluator を生成します。
158 
159   リソースからアニメーションを計算するための AnimEvaluator(アニメーション評価)を生成します。
160 
161   @param[in] maxBones 最大メンバ数です。
162   @param[in] translateAnimEnabled 移動アニメーションが有効かどうかです。
163   @param[in] filePath トランスフォームアニメーションファイルのフルパスです。
164 
165   @return トランスフォームアニメーション評価です。
166  *---------------------------------------------------------------------------*/
167 nw::gfx::TransformAnimEvaluator*
CreateTransformAnimEvaluator(const int maxMembers,const bool translateAnimEnabled,const wchar_t * filePath)168 CreateTransformAnimEvaluator(
169     const int maxMembers,
170     const bool translateAnimEnabled,
171     const wchar_t* filePath
172 )
173 {
174     // ファイルからアニメーションデータのインスタンスを生成します。
175     nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, filePath, &s_DeviceAllocator);
176     if (resourceSet->resource.GetSkeletalAnimsCount() == 0)
177     {
178         // スケルタルアニメーション用のアニメーションデータがありません。
179         return NULL;
180     }
181     nw::anim::ResAnim resAnim = resourceSet->resource.GetSkeletalAnims(0);
182 
183     if (!resAnim.IsValid())
184     {
185         return NULL;
186     }
187 
188     // resAnim から、AnimEvaluator::Builder を用いて AnimEvaluator を生成します。
189     // スケルタルアニメーションの場合は、TransformAnimEvaluator::Builder を使用します。
190     //
191     // アニメーションを1つのモデルにのみ適用する場合や、
192     // コマ形式データの場合は、 AllocCache を false にすると処理負荷が下がります。
193     nw::gfx::TransformAnimEvaluator* evaluator = nw::gfx::TransformAnimEvaluator::Builder()
194         .AnimData(resAnim)
195         .MaxMembers(maxMembers)
196         .MaxAnimMembers(resAnim.GetMemberAnimSetCount())
197         .AllocCache(false)
198         .Create(&s_DeviceAllocator);
199 
200     // 移動アニメーションの無効化フラグを設定します。
201     evaluator->SetIsTranslateDisabled(!translateAnimEnabled);
202 
203     return evaluator;
204 }
205 
206 /*!--------------------------------------------------------------------------*
207   @brief        スケルタルアニメーションを初期化します。
208 
209                 生成した AnimEvaluator のインスタンスにアニメーショングループを
210                 バインドし、その AnimEvaluator をモデルにセットします。
211 
212   @param[in]    model スケルタルモデルです。
213 
214   @return       トランスフォームアニメーション評価です。
215  *---------------------------------------------------------------------------*/
216 nw::gfx::TransformAnimEvaluator*
InitializeSkeletalAnim(nw::gfx::SkeletalModel * model)217 InitializeSkeletalAnim(nw::gfx::SkeletalModel* model)
218 {
219     // モデルからアニメーショングループを取得します。
220     //
221     // アニメーショングループはアニメーション対象メンバへのポインタを保持します。
222     // 対象メンバとは、モデルがもつアニメーション可能な要素
223     //(例えば、マテリアルアニメーションでは Diffuse や Texture など)です。
224     // ここでは、スケルタルモデルから、ボーンのトランスフォームを含む
225     // アニメーショングループを取得します。
226     //
227     // アニメーションの対象や種類によって用いる関数が異なります。
228     // ・SkeletalModel::GetSkeletalAnimGroup
229     // ・Model::GetVisibilityAnimGroup
230     // ・Model::GetMaterialAnimGroup
231     // ・Light::GetAnimGroup
232     // ・Camera::GetAnimGroup
233     nw::gfx::AnimGroup* animGroup = model->GetSkeletalAnimGroup();
234     if (animGroup == NULL) // スケルタルアニメーション用のアニメーショングループがありません。
235     {
236         return NULL;
237     }
238 
239     nw::gfx::ResSkeletalModel resModel = model->GetResSkeletalModel();
240     nw::gfx::ResSkeleton resSkeleton = resModel.GetSkeleton();
241     const int maxBones = resSkeleton.GetBonesCount();
242 
243     // 体型の異なるモデルでアニメーションを共有する場合には
244     // アニメーションの平行移動成分を無効にする必要があります。
245     // 本デモでは ResSkeleton から取得したフラグにより
246     // TransformAnimEvaluator の移動アニメを無効化していますが、
247     // 現バージョンでは ResSkeleton にあらかじめフラグを設定しておく手段は用意されておりません。
248     // またフラグが有効であれば自動的に移動アニメを無効にするといった機能もありません。
249     // この機能についての将来的な対応は未定です。
250     const bool translateAnimEnabled =
251         nw::ut::CheckFlag(resSkeleton.GetFlags(), nw::gfx::ResSkeletonData::FLAG_TRANSLATE_ANIMATION_ENABLED);
252 
253     nw::gfx::TransformAnimEvaluator* evaluator = CreateTransformAnimEvaluator(
254         maxBones, translateAnimEnabled, SKELETAL_ANIM_RESOURCE_FILE);
255     if (evaluator == NULL)
256     {
257         return NULL;
258     }
259 
260     // アニメーショングループを AnimEvaluator にバインドします。
261     // これにより、アニメーション対象メンバにアニメーションデータが関連付けられます。
262     bool bindResult = evaluator->Bind(animGroup);
263 
264     // AnimEvaluator をモデルに設定します。
265     // AnimEvaluator は一つのモデルに対して複数設定することができ、
266     // その際には、AnimEvaluator 毎に objectIndex を指定します。
267     // 詳しくは、 PartialAnimationDemo を参照してください。
268     //
269     // アニメーションの対象や種類によって用いる関数が異なります。
270     // SkeletalModel::SetSkeletalAnimObject
271     // Model::SetVisibilityAnimObject
272     // Model::SetMaterialAnimObject
273     // Light::SetAnimObject
274     // Camera::SetAnimObject
275     model->SetSkeletalAnimObject(evaluator);
276 
277     return evaluator;
278 }
279 
280 /*!--------------------------------------------------------------------------*
281   @brief        アニメーションの再生速度を変更します。
282 
283                 十字ボタンの左右でアニメーションの更新フレームを変更します。
284 
285   @param[in]    model モデルです。
286  *---------------------------------------------------------------------------*/
287 void
ChangeSpeed(nw::gfx::SkeletalModel * model)288 ChangeSpeed(nw::gfx::SkeletalModel* model)
289 {
290     NW_NULL_ASSERT(model);
291 
292     nw::gfx::AnimObject* animObject = model->GetSkeletalAnimObject();
293     nw::gfx::TransformAnimEvaluator* evaluator =
294         nw::ut::DynamicCast<nw::gfx::TransformAnimEvaluator*>(animObject);
295     if (evaluator != NULL)
296     {
297         nw::demo::Pad* pad = nw::demo::PadFactory::GetPad();
298         if (pad->IsButtonPress(nw::demo::Pad::BUTTON_LEFT))
299         {
300             s_StepFrame -= 0.02f;
301         }
302         if (pad->IsButtonPress(nw::demo::Pad::BUTTON_RIGHT))
303         {
304             s_StepFrame += 0.02f;
305         }
306         s_StepFrame = nw::ut::Clamp(s_StepFrame, 0.0f, 50.0f);
307 
308         // アニメーションの更新フレームを変更します。
309         evaluator->SetStepFrame(s_StepFrame);
310     }
311 }
312 
313 /*!--------------------------------------------------------------------------*
314   @brief        ルートノード関連の構築をします。
315  *---------------------------------------------------------------------------*/
316 void
BuildRootNodes()317 BuildRootNodes()
318 {
319     NW_ASSERT(s_SceneRoot == NULL);
320     s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
321         .Create(&s_DeviceAllocator);
322     NW_NULL_ASSERT(s_SceneRoot);
323 
324     NW_ASSERT(s_ModelRoot == NULL);
325     s_ModelRoot = nw::gfx::TransformNode::DynamicBuilder()
326         .Create(&s_DeviceAllocator);
327     s_SceneRoot->AttachChild(s_ModelRoot);
328     NW_NULL_ASSERT(s_ModelRoot);
329 }
330 
331 /*!--------------------------------------------------------------------------*
332   @brief        カメラ関連の構築をします。
333  *---------------------------------------------------------------------------*/
334 void
BuildCameras()335 BuildCameras()
336 {
337     nw::demo::Utility::CreateStereoCameras(
338         &s_BaseCamera,
339         &s_LeftCamera,
340         &s_RightCamera,
341         &s_DeviceAllocator,
342         nw::math::VEC3(20.0f, 15.0f, 20.0f),
343         nw::math::VEC3(0.0f, 10.0f, 0.0f),
344         s_fNearPlane
345     );
346 
347     s_SceneRoot->AttachChild(s_BaseCamera);
348     s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
349 }
350 
351 
352 /*!--------------------------------------------------------------------------*
353   @brief        リソース関連の構築をします。
354  *---------------------------------------------------------------------------*/
355 void
BuildResources(nw::demo::ResourceSet * resourceSet)356 BuildResources(nw::demo::ResourceSet* resourceSet)
357 {
358     nw::gfx::ResGraphicsFile resFile = resourceSet->resource;
359     void* imageData = resFile.GetImageBlockData();
360 
361     // テクスチャ、頂点バッファを手動で VRAM に転送します。
362     if (imageData)
363     {
364         s32 size = resFile.GetImageBlockDataSize();
365 
366         void* vramAddr = nw::demo::AllocateGraphicsMemory(NN_GX_MEM_VRAMA, NN_GX_MEM_TEXTURE, 0, size);
367 
368         // データキャッシュをフラッシュし、VRAM に転送します。
369         nngxUpdateBuffer( imageData, size );
370         nngxAddVramDmaCommand( imageData, vramAddr, size );
371 
372         // 転送したイメージデータのアドレスを Setup 前にリソースに設定します。
373         nw::gfx::TransferedVramAddressSetter locationSetter( imageData, vramAddr );
374         resFile.ForeachTexture(locationSetter);
375         resFile.ForeachIndexStream(locationSetter);
376         resFile.ForeachVertexStream(locationSetter);
377     }
378 
379     nw::gfx::Result result = resFile.Setup(&s_DeviceAllocator);
380     if (result.IsFailure())
381     {
382         NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
383     }
384 
385     nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(SCENE_NODE_COUNT, &s_DeviceAllocator);
386 
387     // スケルタルモデルのインスタンスを生成します。
388     nw::gfx::ResModelArray models = resFile.GetModels();
389     nw::gfx::ResModelArray::iterator modelsEnd = models.end();
390     for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
391          modelResource != modelsEnd; ++modelResource)
392     {
393         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
394             &s_DeviceAllocator,
395             (*modelResource)
396         );
397         NW_NULL_ASSERT(node);
398         sceneNodeArray.push_back(node);
399 
400         s_AnimModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(node);
401     }
402 
403     nw::gfx::ResLightArray lights = resFile.GetLights();
404     nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
405     for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
406          lightResource != lightsEnd; ++lightResource)
407     {
408         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
409             &s_DeviceAllocator,
410             (*lightResource)
411         );
412         NW_NULL_ASSERT(node);
413         sceneNodeArray.push_back(node);
414     }
415 
416     // 親子付け参照関係を解決
417     nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
418 
419     // モデルをシーンに追加
420     nw::gfx::SceneHelper::ForeachRootNodes(
421         sceneNodeArray.Begin(),
422         sceneNodeArray.End(),
423         nw::gfx::AttachNode(s_ModelRoot)
424     );
425 
426     nw::gfx::ResSceneEnvironmentSettingArray settings = resFile.GetSceneEnvironmentSettings();
427     nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
428     for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
429         settingResource != settingsEnd; ++settingResource)
430     {
431         nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
432             .Resource(*settingResource)
433             .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
434 
435         nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
436             nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
437 
438         NW_NULL_ASSERT(sceneEnvironmentSetting);
439         s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
440     }
441 }
442 
443 /*!--------------------------------------------------------------------------*
444   @brief        シーンを初期化します。
445 
446                 アニメーションなどのリソースを構築し、初期化を行います。
447  *---------------------------------------------------------------------------*/
448 void
InitializeScenes()449 InitializeScenes()
450 {
451     s_StepFrame = 1.0f;
452 
453     BuildRootNodes();
454 
455     BuildCameras();
456 
457     NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
458     {
459         BuildResources(nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator));
460     }
461 
462     // スケルタルアニメーションの初期化を行います。
463     s_AnimEvaluator = InitializeSkeletalAnim(s_AnimModel);
464     NW_NULL_ASSERT(s_AnimEvaluator);
465 
466     s_SceneSystem->InitializeScene(s_SceneRoot);
467     s_SceneSystem->UpdateScene();
468 
469     s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
470 
471     nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
472     sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
473     nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
474 
475     NW_GL_ASSERT();
476 
477     s_FrameCount = 0;
478 }
479 
480 /*!--------------------------------------------------------------------------*
481   @brief        シーン関連の後始末をします。
482  *---------------------------------------------------------------------------*/
483 void
TerminateScenes()484 TerminateScenes()
485 {
486     nw::gfx::SafeDestroyBranch(s_SceneRoot);
487     nw::demo::SafeCleanupResources(s_Resources);
488     nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings);
489 
490     nw::ut::SafeDestroy(s_AnimEvaluator);
491 
492     NW_GL_ASSERT();
493 
494     s_Resources.clear();
495     s_SceneEnvironmentSettings.clear();
496 
497     s_ModelRoot = NULL;
498 }
499 
500 /*!--------------------------------------------------------------------------*
501   @brief        シーンを更新します。
502  *---------------------------------------------------------------------------*/
503 void
UpdateScene()504 UpdateScene()
505 {
506     ChangeSpeed(s_AnimModel);
507 
508     s_SceneSystem->GetCameraController()->Update();
509 
510     // SceneSystem::UpdateScene で SceneUpdater::UpdateAll が呼ばれます。
511     // UpdateAll を行うことにより、モデルにバインドされた AnimEvaluator が
512     // 評価され、アニメーションが毎フレーム更新されます。
513     s_SceneSystem->UpdateScene();
514 
515     s_BaseCamera->UpdateCameraMatrix();
516 
517     s_RenderSystem->CalcStereoCamera(s_LeftCamera, s_RightCamera, s_BaseCamera, s_fNearPlane + 5.0f);
518 
519     ++s_FrameCount;
520 }
521 
522 /*!--------------------------------------------------------------------------*
523   @brief        負荷表示やテスト機能の処理をおこないます。
524  *---------------------------------------------------------------------------*/
525 void
ReportDemo()526 ReportDemo()
527 {
528     NW_PROFILE("ReportDemo");
529 
530     // 負荷表示からはこれらの負荷は除きます。
531     s_RenderSystem->SuspendLoadMeter();
532 
533     nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
534 
535     s_GraphicsDrawing.BeginDrawingShape();
536 
537     nw::demo::DebugUtility::DrawLoadMeter(
538         s_RenderSystem,
539         &s_GraphicsDrawing
540     );
541 
542     s_GraphicsDrawing.EndDrawingShape();
543 
544     s_GraphicsDrawing.BeginDrawingString();
545 
546     nw::demo::DebugUtility::DrawLoadMeterText(
547         s_RenderSystem,
548         &s_GraphicsDrawing
549     );
550 
551     const int dumpPositionX = 10;
552     const int dumpPositionY = 10;
553     s_GraphicsDrawing.DrawString(
554         dumpPositionX,
555         dumpPositionY,
556         "step frame: %0.2f",
557         s_StepFrame
558     );
559 
560     s_GraphicsDrawing.EndDrawingString();
561 
562     s_RenderSystem->ResumeLoadMeter();
563 }
564 
565 /*!--------------------------------------------------------------------------*
566   @brief        シーンをデモンストレーションします。
567  *---------------------------------------------------------------------------*/
568 void
DemoScene()569 DemoScene()
570 {
571     NW_ASSERT(!s_RenderTargets.empty());
572 
573     nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
574 
575     InitializeScenes();
576 
577     nw::demo::DebugUtility::PostInitializeScenes();
578 
579     bool isContinuing = true;
580 
581     while ( isContinuing )
582     {
583         nw::demo::DebugUtility::AdvanceAutoTestFrame();
584 
585         nw::demo::PadFactory::GetPad()->Update();
586 
587         // アニメーションを含むシーンの更新を行います。
588         UpdateScene();
589 
590         renderContext->SetActiveCamera(s_BaseCameraIndex);
591         s_RenderSystem->SubmitView(s_SceneSystem);
592 
593         s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
594         s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
595 
596         s_RenderSystem->ClearBySkyModel(s_BaseCamera);
597         ReportDemo();
598         s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
599 
600         s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
601 
602         renderContext->ResetState();
603 
604         if (nw::demo::Utility::IsTerminating())
605         {
606             isContinuing = false;
607         }
608     }
609 
610     nw::demo::DebugUtility::PreTerminateScenes();
611 
612     TerminateScenes();
613 }
614 
615 } // namespace
616 
617 /*!--------------------------------------------------------------------------*
618   @brief        メイン関数です。
619  *---------------------------------------------------------------------------*/
620 void
nnMain()621 nnMain()
622 {
623     nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
624 
625     nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
626 
627     NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
628     {
629         InitializeGraphics();
630 
631         DemoScene();
632 
633         TerminateGraphics();
634     }
635 
636     nw::demo::PadFactory::Finalize();
637 
638     nw::demo::FinalizeGraphicsSystem();
639 }
640