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