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