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