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: 26316 $
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* 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 NW_LOAD_METER_INTERVAL = 60;
56 
57 //----------------------------------------
58 // 描画関係
59 const s32 RENDER_TARGET_COUNT = 1;
60 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
61 
62 RenderTargetArray s_RenderTargets;
63 nw::demo::SceneSystem*  s_SceneSystem = NULL;
64 nw::demo::RenderSystem* s_RenderSystem = NULL;
65 
66 nw::demo::GraphicsDrawing  s_GraphicsDrawing;
67 
68 //----------------------------------------
69 // リソース関係
70 nw::demo::ResourceArray s_Resources;
71 
72 //----------------------------------------
73 // シーン関係
74 const int SCENE_NODE_COUNT = 4;
75 nw::gfx::SceneNode* s_SceneRoot = NULL;
76 nw::gfx::SceneNode* s_ModelRoot = NULL;
77 s32 s_FrameCount = 0;
78 nw::gfx::Camera* s_BaseCamera = NULL;
79 nw::gfx::Camera* s_LeftCamera = NULL;
80 nw::gfx::Camera* s_RightCamera = NULL;
81 const f32 s_fNearPlane = 0.1f;
82 
83 //----------------------------------------
84 // シーン環境関係
85 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
86 
87 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
88 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
89 
90 const s32 s_BaseCameraIndex = 0;
91 
92 //----------------------------------------
93 // アニメーション関係
94 nw::gfx::SkeletalModel* s_AnimModel = NULL;
95 nw::gfx::TransformAnimEvaluator* s_AnimEvaluator = NULL;
96 
97 float s_StepFrame = 1.0f;
98 
99 /*!--------------------------------------------------------------------------*
100   @brief        グラフィックス関連の初期化を行います。
101  *---------------------------------------------------------------------------*/
102 void
InitializeGraphics()103 InitializeGraphics()
104 {
105     nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
106 
107     // renderDescriptionへステレオの設定を行います。
108     nw::demo::RenderSystem::Description renderDescription;
109 
110     renderDescription.reusableCommandBufferSize = 0x100000;
111     renderDescription.reusableCommandRequestCount      = 512;
112     renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
113 
114     s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
115 
116     s_GraphicsDrawing.SetScreenSize(
117         renderDescription.lowerScreenDescription.width,
118         renderDescription.lowerScreenDescription.height
119     );
120 
121     bool result = s_GraphicsDrawing.InitializeFont(&s_DeviceAllocator, FONT_SHADER_FILE_NAME, FONT_FILE_NAME);
122 
123     NN_ASSERTMSG(result, "Fail to load Font.");
124 
125     s_RenderTargets.push_back(
126         nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
127     );
128     NW_ASSERT(!s_RenderTargets.empty());
129     s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
130 
131     // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
132     nw::demo::SceneSystem::Description sceneDescription;
133     sceneDescription.isFixedSizeMemory = true;
134     s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
135 
136     // デモ用の最遠景モデルをレンダリングシステムに設定します。
137     // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
138     s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
139 
140     NW_GL_ASSERT();
141 }
142 
143 /*!--------------------------------------------------------------------------*
144   @brief        グラフィックス関連の後始末をします。
145  *---------------------------------------------------------------------------*/
146 void
TerminateGraphics()147 TerminateGraphics()
148 {
149     nw::gfx::SafeDestroy(s_LeftCamera);
150 
151     nw::gfx::SafeDestroy(s_RightCamera);
152 
153     nw::gfx::SafeDestroy(s_SceneSystem);
154 
155     nw::gfx::SafeDestroyAll(s_RenderTargets);
156 
157     s_GraphicsDrawing.Finalize();
158 
159     nw::gfx::SafeDestroy(s_RenderSystem);
160 
161     NW_GL_ASSERT();
162 }
163 
164 /*!--------------------------------------------------------------------------*
165   @brief ファイルから TransformAnimEvaluator を生成します。
166 
167   リソースからアニメーションを計算するための AnimEvaluator(アニメーション評価)を生成します。
168 
169   @param[in] maxBones 最大メンバ数です。
170   @param[in] translateAnimEnabled 移動アニメーションが有効かどうかです。
171   @param[in] filePath トランスフォームアニメーションファイルのフルパスです。
172 
173   @return トランスフォームアニメーション評価です。
174  *---------------------------------------------------------------------------*/
175 nw::gfx::TransformAnimEvaluator*
CreateTransformAnimEvaluator(const int maxMembers,const bool translateAnimEnabled,const wchar_t * filePath)176 CreateTransformAnimEvaluator(
177     const int maxMembers,
178     const bool translateAnimEnabled,
179     const wchar_t* filePath
180 )
181 {
182     // ファイルからアニメーションデータのインスタンスを生成します。
183     nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, filePath, &s_DeviceAllocator);
184     if (resourceSet->resource.GetSkeletalAnimsCount() == 0)
185     {
186         // スケルタルアニメーション用のアニメーションデータがありません。
187         return NULL;
188     }
189     nw::anim::ResAnim resAnim = resourceSet->resource.GetSkeletalAnims(0);
190 
191     if (!resAnim.IsValid())
192     {
193         return NULL;
194     }
195 
196     // resAnim から、AnimEvaluator::Builder を用いて AnimEvaluator を生成します。
197     // スケルタルアニメーションの場合は、TransformAnimEvaluator::Builder を使用します。
198     //
199     // アニメーションを1つのモデルにのみ適用する場合や、
200     // コマ形式データの場合は、 AllocCache を false にすると処理負荷が下がります。
201     nw::gfx::TransformAnimEvaluator* evaluator = nw::gfx::TransformAnimEvaluator::Builder()
202         .AnimData(resAnim)
203         .MaxMembers(maxMembers)
204         .MaxAnimMembers(resAnim.GetMemberAnimSetCount())
205         .AllocCache(false)
206         .Create(&s_DeviceAllocator);
207 
208     // 移動アニメーションの無効化フラグを設定します。
209     evaluator->SetIsTranslateDisabled(!translateAnimEnabled);
210 
211     return evaluator;
212 }
213 
214 /*!--------------------------------------------------------------------------*
215   @brief        スケルタルアニメーションを初期化します。
216 
217                 生成した AnimEvaluator のインスタンスにアニメーショングループを
218                 バインドし、その AnimEvaluator をモデルにセットします。
219 
220   @param[in]    model スケルタルモデルです。
221 
222   @return       トランスフォームアニメーション評価です。
223  *---------------------------------------------------------------------------*/
224 nw::gfx::TransformAnimEvaluator*
InitializeSkeletalAnim(nw::gfx::SkeletalModel * model)225 InitializeSkeletalAnim(nw::gfx::SkeletalModel* model)
226 {
227     // モデルからアニメーショングループを取得します。
228     //
229     // アニメーショングループはアニメーション対象メンバへのポインタを保持します。
230     // 対象メンバとは、モデルがもつアニメーション可能な要素
231     //(例えば、マテリアルアニメーションでは Diffuse や Texture など)です。
232     // ここでは、スケルタルモデルから、ボーンのトランスフォームを含む
233     // アニメーショングループを取得します。
234     //
235     // アニメーションの対象や種類によって用いる関数が異なります。
236     // ・SkeletalModel::GetSkeletalAnimGroup
237     // ・Model::GetVisibilityAnimGroup
238     // ・Model::GetMaterialAnimGroup
239     // ・Light::GetAnimGroup
240     // ・Camera::GetAnimGroup
241     nw::gfx::AnimGroup* animGroup = model->GetSkeletalAnimGroup();
242     if (animGroup == NULL) // スケルタルアニメーション用のアニメーショングループがありません。
243     {
244         return NULL;
245     }
246 
247     nw::gfx::ResSkeletalModel resModel = model->GetResSkeletalModel();
248     nw::gfx::ResSkeleton resSkeleton = resModel.GetSkeleton();
249     const int maxBones = resSkeleton.GetBonesCount();
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     s_GraphicsDrawing.BeginDrawingString();
534 
535     nw::demo::DebugUtility::DrawLoadMeter(
536         s_RenderSystem,
537         &s_GraphicsDrawing,
538         (s_FrameCount % NW_LOAD_METER_INTERVAL == 0)
539     );
540     const int dumpPositionX = 10;
541     const int dumpPositionY = 10;
542     s_GraphicsDrawing.DrawString(
543         dumpPositionX,
544         dumpPositionY,
545         "step frame: %0.2f",
546         s_StepFrame
547     );
548 
549     s_GraphicsDrawing.FlushDrawing();
550 
551     s_RenderSystem->ResumeLoadMeter();
552 }
553 
554 /*!--------------------------------------------------------------------------*
555   @brief        シーンをデモンストレーションします。
556  *---------------------------------------------------------------------------*/
557 void
DemoScene()558 DemoScene()
559 {
560     NW_ASSERT(!s_RenderTargets.empty());
561 
562     nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
563 
564     InitializeScenes();
565 
566     bool isContinuing = true;
567 
568     while ( isContinuing )
569     {
570         nw::demo::DebugUtility::AdvanceAutoTestFrame();
571 
572         nw::demo::PadFactory::GetPad()->Update();
573 
574         // アニメーションを含むシーンの更新を行います。
575         UpdateScene();
576 
577         renderContext->SetActiveCamera(s_BaseCameraIndex);
578         s_RenderSystem->SubmitView(s_SceneSystem);
579 
580         s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
581         s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
582 
583         s_RenderSystem->ClearBySkyModel(s_BaseCamera);
584         ReportDemo();
585         s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
586 
587         s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
588 
589         renderContext->ResetState();
590 
591         if (nw::demo::Utility::IsTerminating())
592         {
593             isContinuing = false;
594         }
595     }
596 
597     TerminateScenes();
598 }
599 
600 } // namespace
601 
602 /*!--------------------------------------------------------------------------*
603   @brief        メイン関数です。
604  *---------------------------------------------------------------------------*/
605 void
nnMain()606 nnMain()
607 {
608     nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
609 
610     nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
611 
612     NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
613     {
614         InitializeGraphics();
615 
616         DemoScene();
617 
618         TerminateGraphics();
619     }
620 
621     nw::demo::PadFactory::Finalize();
622 
623     nw::demo::FinalizeGraphicsSystem();
624 }
625