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