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