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