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: 25401 $
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 
262     NW_GL_ASSERT();
263 }
264 
265 /*!--------------------------------------------------------------------------*
266   @brief        グラフィックスリソースをロードします。
267 
268   @param[in]    resourcePath ファイルのパス名
269 
270   @return       ロードしたグラフィックス情報を返します。
271  *---------------------------------------------------------------------------*/
272 ResourceSet*
LoadResources(const wchar_t * resourcePath)273 LoadResources(const wchar_t* resourcePath)
274 {
275     ResourceSet resourceSet;
276     // 現在、デバイスメモリ上に読み込む方式にのみ対応しています。
277     // テクスチャをロードするには128byteアライメントを行う必要があります。
278     static const int resourceAlignment = 128;
279     resourceSet.buffer = nw::demo::Utility::LoadFile(&s_DeviceAllocator , resourcePath, resourceAlignment);
280 
281     if (!resourceSet.buffer)
282     {
283         return NULL;
284     }
285 
286     resourceSet.resource = nw::gfx::ResGraphicsFile(&(resourceSet.buffer.front()));
287 
288     bool isPushed = s_Resources.push_back(resourceSet);
289 
290     NW_ASSERT(isPushed);
291 
292     return &(s_Resources.back());
293 }
294 
295 /*!--------------------------------------------------------------------------*
296   @brief        シーンノードを生成します。
297 
298   @param[in]    resource シーンノードのリソースです。
299 
300   @return       生成したシーンノードです。。
301  *---------------------------------------------------------------------------*/
302 nw::gfx::SceneNode*
CreateSceneNode(nw::gfx::ResSceneObject resource)303 CreateSceneNode(nw::gfx::ResSceneObject resource)
304 {
305     nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
306         .Resource(resource)
307         .MaxChildren(0)
308         .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
309 
310     return nw::ut::DynamicCast<nw::gfx::SceneNode*>(sceneObject);
311 }
312 
313 /*!--------------------------------------------------------------------------*
314   @brief        リソース関連の構築をします。
315 *---------------------------------------------------------------------------*/
316 void
BuildResources(ResourceSet * resourceSet)317 BuildResources(ResourceSet* resourceSet)
318 {
319     resourceSet->resource.ForeachTexture(nw::gfx::TextureLocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
320     resourceSet->resource.ForeachIndexStream(nw::gfx::IndexStreamLocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
321     resourceSet->resource.ForeachVertexStream(nw::gfx::VertexStreamLocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
322 
323     nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
324     if (result.IsFailure())
325     {
326         NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
327     }
328 
329     nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
330     nw::gfx::ResModelArray::iterator modelsEnd = models.end();
331     for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
332         modelResource != modelsEnd; ++modelResource)
333     {
334         nw::gfx::SceneNode* node = CreateSceneNode(*modelResource);
335         NW_NULL_ASSERT(node);
336 
337         s_Models.push_back(static_cast<nw::gfx::Model*>(node));
338     }
339 
340     nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
341     for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
342         lightResource != lights.end(); ++lightResource)
343     {
344         nw::gfx::SceneNode* node = CreateSceneNode(*lightResource);
345         NW_NULL_ASSERT(node);
346         NW_ASSERT(nw::ut::IsTypeOf<nw::gfx::FragmentLight>(node));
347 
348         s_FragmentLights.push_back(static_cast<nw::gfx::FragmentLight*>(node));
349     }
350 }
351 
352 /*!--------------------------------------------------------------------------*
353   @brief        カメラの構築をします。
354 *---------------------------------------------------------------------------*/
355 void
BuildCameras()356 BuildCameras()
357 {
358     nw::gfx::LookAtTargetViewUpdater* viewUpdater
359         = nw::gfx::LookAtTargetViewUpdater::Create(&s_DeviceAllocator);
360 
361     nw::gfx::ResLookAtTargetViewUpdater resViewUpdater =
362         nw::gfx::ResStaticCast<nw::gfx::ResLookAtTargetViewUpdater>(
363             viewUpdater->GetResource());
364     resViewUpdater.SetTargetPosition(0.0f,0.0f,0.0f);
365     resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f);
366 
367     nw::gfx::PerspectiveProjectionUpdater* projectionUpdater
368         = nw::gfx::PerspectiveProjectionUpdater::Create(&s_DeviceAllocator);
369 
370     nw::gfx::ResPerspectiveProjectionUpdater resProjectionUpdater =
371         nw::gfx::ResStaticCast<nw::gfx::ResPerspectiveProjectionUpdater>(
372             projectionUpdater->GetResource());
373     resProjectionUpdater.SetNear(s_NearPlane);
374     resProjectionUpdater.SetFar(1000.0f);
375     resProjectionUpdater.SetFovy(NW_MATH_DEG_TO_RAD(37.8f));
376 
377     resProjectionUpdater.SetAspectRatio(
378         static_cast<f32>(s_RenderTarget->GetDescription().height) /
379             static_cast<f32>(s_RenderTarget->GetDescription().width));
380 
381     s_BaseCamera =
382         nw::gfx::Camera::DynamicBuilder()
383         .MaxChildren(0)
384         .MaxCallbacks(0)
385         .ViewUpdater(viewUpdater)
386         .ProjectionUpdater(projectionUpdater)
387         .Create(&s_DeviceAllocator);
388     NW_POINTER_ASSERT(s_BaseCamera);
389     s_BaseCamera->Transform().SetTranslate(nw::math::VEC3(7.0f, 3.5f, -5.0f));
390 
391     s_LeftCamera =
392         nw::gfx::Camera::DynamicBuilder()
393         .MaxChildren(0)
394         .MaxCallbacks(0)
395         .Create(&s_DeviceAllocator);
396     NW_POINTER_ASSERT(s_LeftCamera);
397 
398     s_RightCamera =
399         nw::gfx::Camera::DynamicBuilder()
400         .MaxChildren(0)
401         .MaxCallbacks(0)
402         .Create(&s_DeviceAllocator);
403     NW_POINTER_ASSERT(s_RightCamera);
404 
405     s_CameraController =
406         nw::demo::CameraController::Builder()
407         .MaxCameraCount(1)
408         .Create(&s_DeviceAllocator);
409     s_CameraController->Register(s_BaseCamera);
410 }
411 
412 /*!--------------------------------------------------------------------------*
413   @brief        シーンを初期化します。
414 *---------------------------------------------------------------------------*/
415 void
InitializeScenes()416 InitializeScenes()
417 {
418     BuildCameras();
419 
420     NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
421     {
422         BuildResources(LoadResources(name));
423     }
424 
425     NW_GL_ASSERT();
426 
427     s_FrameCount = 0;
428 }
429 
430 /*!--------------------------------------------------------------------------*
431   @brief        シーン関連の後始末をします。
432 *---------------------------------------------------------------------------*/
433 void
TerminateScenes()434 TerminateScenes()
435 {
436     nw::gfx::SafeDestroyAll(s_FragmentLights);
437     nw::gfx::SafeDestroyAll(s_Models);
438     nw::demo::SafeCleanupResources(s_Resources);
439     nw::gfx::SafeDestroy(s_BaseCamera);
440     nw::gfx::SafeDestroy(s_LeftCamera);
441     nw::gfx::SafeDestroy(s_RightCamera);
442     nw::gfx::SafeDestroy(s_CameraController);
443 
444     NW_GL_ASSERT();
445 
446     s_Resources.clear();
447 }
448 
449 /*!--------------------------------------------------------------------------*
450   @brief        ノードを更新します。
451  *---------------------------------------------------------------------------*/
452 void
UpdateNode(nw::gfx::TransformNode * node)453 UpdateNode(nw::gfx::TransformNode* node)
454 {
455     // 一度計算したら計算処理をスキップする。
456     // ただし、ツリー構造は正しく解釈されない。
457     if (node->Transform().IsEnabledFlags(nw::gfx::CalculatedTransform::FLAG_IS_DIRTY))
458     {
459         s_WorldMatrixUpdater->UpdateBasic(
460             &node->WorldMatrix(),
461             &node->WorldTransform(),
462             node->Transform(),
463             nw::gfx::CalculatedTransform::Identity(),
464             nw::gfx::CalculatedTransform::Identity());
465 
466         node->Transform().DisableFlags(nw::gfx::CalculatedTransform::FLAG_IS_DIRTY);
467     }
468 }
469 
470 /*!--------------------------------------------------------------------------*
471   @brief        カメラを更新します。
472  *---------------------------------------------------------------------------*/
UpdateCamera()473 void UpdateCamera()
474 {
475     s_CameraController->Update();
476     UpdateNode(s_BaseCamera);
477     s_BaseCamera->UpdateCameraMatrix();
478 
479     // ステレオカメラの計算
480     NW_NULL_ASSERT(s_LeftCamera);
481     NW_NULL_ASSERT(s_RightCamera);
482     NW_NULL_ASSERT(s_BaseCamera);
483     nn::math::MTX44& projOriginal = s_BaseCamera->ProjectionMatrix();
484     nn::math::MTX34& viewOriginal = s_BaseCamera->ViewMatrix();
485     nn::math::MTX44& projL = s_LeftCamera->ProjectionMatrix();
486     nn::math::MTX34& viewL = s_LeftCamera->ViewMatrix();
487     nn::math::MTX44& projR = s_RightCamera->ProjectionMatrix();
488     nn::math::MTX34& viewR = s_RightCamera->ViewMatrix();
489 
490     // Ortho カメラでは別の処理を行う必要があります。
491     // 例として demo::RenderSystem::CalcStereoCamera() を参照してください。
492     const f32 DEPTH_LEVEL = 5.0f + s_NearPlane;
493     const f32 DEPTH_RANGE = 1.0f;
494     s_StereoCamera->CalculateMatrices(
495         &projL,
496         &viewL,
497         &projR,
498         &viewR,
499         &projOriginal,
500         &viewOriginal,
501         DEPTH_LEVEL,
502         DEPTH_RANGE,
503         false);
504 }
505 
506 /*!--------------------------------------------------------------------------*
507   @brief        生成されたノードを更新します。
508  *---------------------------------------------------------------------------*/
UpdateNodes()509 void UpdateNodes()
510 {
511     // フラグメントライト更新
512     FragmentLightArray::iterator lightEnd = s_FragmentLights.end();
513     for (FragmentLightArray::iterator light = s_FragmentLights.begin(); light != lightEnd; ++light)
514     {
515         UpdateNode(*light);
516     }
517 
518     // モデル更新
519     ModelArray::iterator modelEnd = s_Models.end();
520     for (ModelArray::iterator model = s_Models.begin(); model != modelEnd; ++model)
521     {
522         UpdateNode(*model);
523     }
524 }
525 
526 /*!--------------------------------------------------------------------------*
527   @brief        シーンを更新します。
528  *---------------------------------------------------------------------------*/
529 void
UpdateScene()530 UpdateScene()
531 {
532     UpdateNodes();
533 
534     UpdateCamera();
535 
536     ++s_FrameCount;
537 }
538 
539 /*!--------------------------------------------------------------------------*
540   @brief        カメラ、ライト、フォグなどのシーン環境を設定します。
541  *---------------------------------------------------------------------------*/
542 void
SetEnvironment()543 SetEnvironment()
544 {
545     nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderContext->GetSceneEnvironment();
546     sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
547 
548     //-----------------------------
549     FragmentLightArray::iterator lightEnd = s_FragmentLights.end();
550     for (FragmentLightArray::iterator light = s_FragmentLights.begin(); light != lightEnd; ++light)
551     {
552         sceneEnvironment.SetFragmentLight(*light);
553     }
554 }
555 
556 /*!--------------------------------------------------------------------------*
557   @brief        ビューに関連する更新処理を行います。
558  *---------------------------------------------------------------------------*/
559 void
SubmitView()560 SubmitView()
561 {
562     ModelArray::iterator modelEnd = s_Models.end();
563     for (ModelArray::iterator model = s_Models.begin(); model != modelEnd; ++model)
564     {
565         if (!(*model)->IsVisible())
566         {
567             continue;
568         }
569 
570         (*model)->UpdateModelViewMatrixAndNormalMatrix(s_BaseCamera->ViewMatrix(), false);
571     }
572 }
573 
574 /*!--------------------------------------------------------------------------*
575   @brief        シーンを描画します。
576  *---------------------------------------------------------------------------*/
577 void
RenderScene()578 RenderScene()
579 {
580     s_RenderContext->SetRenderTarget(s_RenderTarget);
581 
582     // 描画コマンドを生成します。
583     s_CommandListSwapper->StartCommandSave();
584     NW_GL_ASSERT();
585 
586     s_RenderContext->ClearBuffer(
587         GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
588         nw::ut::FloatColor(0.5f, 0.5f, 0.5f, 1.0f),
589         1.0f);
590 
591     ModelArray::iterator modelEnd = s_Models.end();
592     for (ModelArray::iterator model = s_Models.begin(); model != modelEnd; ++model)
593     {
594         if ((*model)->IsVisible())
595         {
596             nw::gfx::ResMeshArray resMeshes = (*model)->GetResMeshes();
597 
598             nw::gfx::ResMeshArray::iterator meshEnd = resMeshes.end();
599             for(nw::gfx::ResMeshArray::iterator mesh = resMeshes.begin();
600                 mesh != meshEnd;
601                 ++mesh)
602             {
603                 if ((*model)->IsMeshVisible(*mesh))
604                 {
605                     s_MeshRenderer->RenderMesh(*mesh, *model);
606                 }
607             }
608         }
609     }
610     NW_GL_ASSERT();
611 
612     s_CommandListSwapper->EndCommandSave();
613 
614     // 左目の描画を行います。
615     s_RenderContext->SetCameraMatrix(s_LeftCamera);
616     s_CommandListSwapper->ReuseCommand(false);
617     s_UpperSwapper->MakeTransferBufferCommand(s_RenderTarget, false);
618 
619     // 右目の描画を行います。
620     s_RenderContext->SetCameraMatrix(s_RightCamera);
621     s_CommandListSwapper->ReuseCommand(false);
622     s_ExtensionSwapper->MakeTransferBufferCommand(s_RenderTarget, false);
623 
624     s_CommandListSwapper->WaitDone();
625     s_CommandListSwapper->RunAsync();
626 }
627 
628 /*!--------------------------------------------------------------------------*
629   @brief        ディスプレイバッファをスワップして表示します。
630  *---------------------------------------------------------------------------*/
631 void
PresentBuffer()632 PresentBuffer()
633 {
634     s_UpperSwapper->ActivateBuffer();
635     s_ExtensionSwapper->ActivateBuffer();
636 
637     nngxSwapBuffers(NN_GX_DISPLAY0);
638 
639     glBindFramebuffer(GL_FRAMEBUFFER, 0);
640 
641     NW_GL_ASSERT();
642 
643     nngxWaitVSync(NN_GX_DISPLAY0);
644 }
645 
646 /*!--------------------------------------------------------------------------*
647   @brief        シーンをデモンストレーションします。
648  *---------------------------------------------------------------------------*/
649 void
DemoScene()650 DemoScene()
651 {
652     NW_NULL_ASSERT(s_RenderTarget);
653 
654     InitializeScenes();
655 
656     s_CommandListSwapper->RunAsync();
657 
658     bool isContinuing = true;
659 
660     while ( isContinuing )
661     {
662         nw::demo::DebugUtility::AdvanceAutoTestFrame();
663 
664         nw::demo::PadFactory::GetPad()->Update();
665 
666         UpdateScene();
667 
668         SetEnvironment();
669 
670         s_RenderContext->SetActiveCamera(s_BaseCameraIndex);
671 
672         SubmitView();
673 
674         RenderScene();
675 
676         s_RenderContext->ResetState();
677 
678         PresentBuffer();
679 
680         if (nw::demo::Utility::IsTerminating())
681         {
682             isContinuing = false;
683         }
684     }
685 
686     TerminateScenes();
687 }
688 
689 } // namespace
690 
691 /*!--------------------------------------------------------------------------*
692   @brief        メイン関数です。
693  *---------------------------------------------------------------------------*/
694 void
nnMain()695 nnMain()
696 {
697     InitializeGraphicsSystem();
698 
699     nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
700 
701     NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, NULL)
702     {
703         InitializeGraphics();
704 
705         DemoScene();
706 
707         TerminateGraphics();
708     }
709 
710     nw::demo::PadFactory::Finalize();
711 
712     FinalizeGraphicsSystem();
713 }
714