1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: ShadowMapDemo.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: 28483 $
14 *---------------------------------------------------------------------------*/
15
16 #define NW_DEBUG_CHECK_MEMORY_LEAK
17
18 #include <nn/os.h>
19 #include <nn/fs.h>
20
21 #include <nw/types.h>
22
23 #include <nw/demo.h>
24 #include <nw/dev.h>
25 #include <nw/gfx.h>
26 #include <nw/ut.h>
27 #include <nw/anim.h>
28
29 namespace
30 {
31
32 //----------------------------------------
33 // シャドウ関係
34 // シャドウの状態を表す UserFlag です
35 enum UserFlags
36 {
37 SHADOW_CASTER_SHIFT = 0,
38 SHADOW_RECEIVER_SHIFT = 1,
39
40 SHADOW_CASTER = 0x1 << SHADOW_CASTER_SHIFT,
41 SHADOW_RECEIVER = 0x1 << SHADOW_RECEIVER_SHIFT
42 };
43
44 // Shadow の Caster のみを描画要素に加える関数オブジェクトです。
45 class IsShadowCasterModelFunctor : public nw::gfx::ISceneUpdater::IsVisibleModelFunctor
46 {
47 public:
IsVisible(const nw::gfx::Model * model)48 virtual bool IsVisible(const nw::gfx::Model* model)
49 {
50 return nw::ut::CheckFlag(model->GetUserParameter<u32>(), SHADOW_CASTER);
51 }
52 };
53
54 IsShadowCasterModelFunctor s_ShadowCasterModel;
55
56 // シャドウの設定を行うレンダーコマンドです。
57 class StartShadowRenderCommand : public nw::gfx::RenderCommand
58 {
59 NW_DISALLOW_COPY_AND_ASSIGN(StartShadowRenderCommand);
60
61 public:
StartShadowRenderCommand(nw::demo::CommandListSwapper * commandListSwapper,nw::gfx::IRenderTarget * renderTarget,s32 shadowCameraIndex,nw::gfx::Material * shadowMaterial)62 StartShadowRenderCommand(
63 nw::demo::CommandListSwapper* commandListSwapper,
64 nw::gfx::IRenderTarget* renderTarget,
65 s32 shadowCameraIndex,
66 nw::gfx::Material* shadowMaterial)
67 : m_CommandListSwapper(commandListSwapper),
68 m_RenderTarget(renderTarget),
69 m_ShadowCameraIndex(shadowCameraIndex),
70 m_ShadowMaterial(shadowMaterial),
71 m_CommandSize(0),
72 m_ProfilerPoint(0)
73 {}
~StartShadowRenderCommand()74 virtual ~StartShadowRenderCommand() {}
75
Invoke(nw::gfx::RenderContext * renderContext)76 virtual void Invoke(nw::gfx::RenderContext* renderContext)
77 {
78 m_CommandSize = m_CommandListSwapper->GetCommandBufferSize();
79 m_ProfilerPoint = m_CommandListSwapper->AddGpuProfilingStartPoint(true);
80
81 // オフスクリーンバッファに切り替えます。
82 renderContext->SetRenderTarget(m_RenderTarget);
83 renderContext->ClearBuffer(GL_COLOR_BUFFER_BIT, nw::ut::FloatColor(1.0f, 1.0f, 1.0f, 1.0f), 1.0f);
84
85 // シャドウ用のマテリアル、カメラを設定します。
86 renderContext->SetActiveCamera(m_ShadowCameraIndex);
87 renderContext->SetMaterial(m_ShadowMaterial);
88 nw::gfx::Camera* shadowCamera = renderContext->GetActiveCamera();
89 renderContext->SetCameraMatrix(shadowCamera);
90 renderContext->ActivateContext();
91
92 // 1Pass では RENDERMODE_IGNORE_MATERIAL を用いて以降のマテリアル設定を行いません。
93 renderContext->SetRenderMode(nw::gfx::RenderContext::RENDERMODE_IGNORE_MATERIAL);
94 }
95
GetCommandSize() const96 s32 GetCommandSize() const { return this->m_CommandSize; }
GetProfilerPoint() const97 s32 GetProfilerPoint() const { return this->m_ProfilerPoint; }
98
99 private:
100 nw::demo::CommandListSwapper* m_CommandListSwapper;
101 nw::gfx::IRenderTarget* m_RenderTarget;
102 s32 m_ShadowCameraIndex;
103 nw::gfx::Material* m_ShadowMaterial;
104 s32 m_CommandSize;
105 s32 m_ProfilerPoint;
106 };
107
108 // シャドウの後処理を行うレンダーコマンドです。
109 class EndShadowRenderCommand : public nw::gfx::RenderCommand
110 {
111 NW_DISALLOW_COPY_AND_ASSIGN(EndShadowRenderCommand);
112
113 public:
EndShadowRenderCommand(nw::demo::CommandListSwapper * commandListSwapper,StartShadowRenderCommand * startCommand)114 EndShadowRenderCommand(nw::demo::CommandListSwapper* commandListSwapper, StartShadowRenderCommand* startCommand)
115 : m_CommandListSwapper(commandListSwapper),
116 m_StartCommand(startCommand),
117 m_CommandSize(0)
118 {}
~EndShadowRenderCommand()119 virtual ~EndShadowRenderCommand() {}
120
Invoke(nw::gfx::RenderContext * renderContext)121 virtual void Invoke(nw::gfx::RenderContext* renderContext)
122 {
123 // レンダーモードをデフォルトに戻し、マテリアル設定が通常通り行われるようにします。
124 renderContext->SetRenderMode(nw::gfx::RenderContext::RENDERMODE_DEFAULT);
125
126 // 描画キャッシュを破棄するために ResetState を行います。
127 renderContext->ResetState();
128
129 m_CommandSize = m_CommandListSwapper->GetCommandBufferSize();
130 int profilerPoint = m_StartCommand->GetProfilerPoint();
131 m_CommandListSwapper->SetGpuProfilingEndPoint(profilerPoint);
132 }
133
GetCommandSize() const134 s32 GetCommandSize() const { return this->m_CommandSize; }
135
136 private:
137 nw::demo::CommandListSwapper* m_CommandListSwapper;
138 StartShadowRenderCommand* m_StartCommand;
139 s32 m_CommandSize;
140 };
141
142 // 描画開始の設定を行うレンダーコマンドです。
143 class StartRenderCommand : public nw::gfx::RenderCommand
144 {
145 NW_DISALLOW_COPY_AND_ASSIGN(StartRenderCommand);
146
147 public:
StartRenderCommand(nw::demo::RenderSystem * renderSystem,nw::gfx::IRenderTarget * renderTarget,s32 baseCameraIndex)148 StartRenderCommand(nw::demo::RenderSystem* renderSystem, nw::gfx::IRenderTarget* renderTarget, s32 baseCameraIndex)
149 : m_RenderSystem(renderSystem),
150 m_RenderTarget(renderTarget),
151 m_BaseCameraIndex(baseCameraIndex),
152 m_CommandSize(0)
153 {}
154
~StartRenderCommand()155 virtual ~StartRenderCommand() {}
156
Invoke(nw::gfx::RenderContext * renderContext)157 virtual void Invoke(nw::gfx::RenderContext* renderContext)
158 {
159 nw::demo::CommandListSwapper* commandListSwapper = m_RenderSystem->GetCommandListSwapper();
160
161 // 描画対象をオンスクリーンバッファに切り替えます
162 renderContext->SetRenderTarget(m_RenderTarget);
163 // ライト、環境マップなどの計算用カメラを設定します。
164 renderContext->SetActiveCamera(m_BaseCameraIndex);
165
166 // ステレオ表示用コマンドの作成を開始します。作成したコマンドは複数回描画するために再利用されます。
167 commandListSwapper->StartCommandSave();
168
169 m_CommandSize = commandListSwapper->GetCommandBufferSize();
170
171 m_RenderSystem->ClearBySkyModel(renderContext->GetActiveCamera());
172 }
173
GetCommandSize() const174 s32 GetCommandSize() const { return this->m_CommandSize; }
175
176 private:
177 nw::demo::RenderSystem* m_RenderSystem;
178 nw::gfx::IRenderTarget* m_RenderTarget;
179 s32 m_BaseCameraIndex;
180 s32 m_CommandSize;
181 };
182
183 // 描画終了の設定を行うレンダーコマンドです。
184 class EndRenderCommand : public nw::gfx::RenderCommand
185 {
186 NW_DISALLOW_COPY_AND_ASSIGN(EndRenderCommand);
187
188 public:
EndRenderCommand(nw::demo::RenderSystem * renderSystem,nw::gfx::Camera * leftCamera,nw::gfx::Camera * rightCamera,StartRenderCommand * startCommand)189 EndRenderCommand(
190 nw::demo::RenderSystem* renderSystem,
191 nw::gfx::Camera* leftCamera,
192 nw::gfx::Camera* rightCamera,
193 StartRenderCommand* startCommand)
194 : m_RenderSystem(renderSystem),
195 m_LeftCamera(leftCamera),
196 m_RightCamera(rightCamera),
197 m_StartCommand(startCommand)
198 {}
~EndRenderCommand()199 virtual ~EndRenderCommand() {}
200
Invoke(nw::gfx::RenderContext * renderContext)201 virtual void Invoke(nw::gfx::RenderContext* renderContext)
202 {
203 int commandSize = m_RenderSystem->GetCommandListSwapper()->GetCommandBufferSize();
204 m_RenderSystem->AddLoadMeterCommandSize(commandSize - m_StartCommand->GetCommandSize());
205
206 nw::demo::CommandListSwapper* commandListSwapper = m_RenderSystem->GetCommandListSwapper();
207
208 // ステレオ表示用コマンドの作成を終了します。
209 commandListSwapper->EndCommandSave();
210
211 // GPU処理時間計測開始
212 int profilerLeft = commandListSwapper->AddGpuProfilingStartPoint(true);
213
214 // 保存したコマンドを左目用の描画として再利用します。
215 renderContext->SetCameraMatrix(m_LeftCamera);
216 commandListSwapper->ReuseCommand(false);
217
218 // GPU処理時間計測終了
219 commandListSwapper->SetGpuProfilingEndPoint(profilerLeft);
220
221 m_RenderSystem->TransferBuffer(nw::demo::UPPER_SCREEN);
222
223 // GPU処理時間計測開始
224 int profilerRight = commandListSwapper->AddGpuProfilingStartPoint(true);
225
226 // 保存したコマンドを右目用の描画として再利用します。
227 renderContext->SetCameraMatrix(m_RightCamera);
228 commandListSwapper->ReuseCommand(false);
229
230 // GPU処理時間計測終了
231 commandListSwapper->SetGpuProfilingEndPoint(profilerRight);
232
233 m_RenderSystem->TransferBuffer(nw::demo::EXTENSION_SCREEN);
234 }
235 private:
236 nw::demo::RenderSystem* m_RenderSystem;
237 nw::gfx::Camera* m_LeftCamera;
238 nw::gfx::Camera* m_RightCamera;
239 StartRenderCommand* m_StartCommand;
240 };
241
242 enum CameraKind
243 {
244 PERSPECTIVE_CAMERA,
245 FRUSTUM_CAMERA,
246 ORTHO_CAMERA
247 };
248
249 nw::gfx::Camera* s_ShadowCamera = NULL;
250 // シャドウに用いるカメラの種類です。
251 CameraKind s_CameraKind = PERSPECTIVE_CAMERA;
252 // シャドウ用のカメラのパラメータです。
253 const f32 s_OrthoCameraHeight = 32.0f;
254 const f32 s_ShadowNear = 1.0f;
255 const f32 s_ShadowFar = 500.0f;
256
257 StartShadowRenderCommand* s_StartShadowRenderCommand = NULL;
258 EndShadowRenderCommand* s_EndShadowRenderCommand = NULL;
259 StartRenderCommand* s_StartRenderCommand = NULL;
260 EndRenderCommand* s_EndRenderCommand = NULL;
261
262 // シャドウのマテリアル、シェーダー設定用モデルです。
263 // このモデルはマテリアルとシェーダーの設定に利用されます。
264 // 実際には描画されません。
265 nw::gfx::Model* s_ShadowDummyModel = NULL;
266 // シャドウ用のテクスチャです。
267 nw::gfx::ResShadowTexture s_ShadowTexture;
268 // シャドウテクスチャのサイズです。
269 const s32 s_ShadowTextureSize = 512;
270 // シャドウに掛ける zBias です。
271 const f32 s_ShadowBias = 1.3f;
272 // 影の強度(濃さ)です。
273 const f32 s_ShadowIntensity = 0.2f;
274
275 //----------------------------------------
276 // メモリ関係
277
278 // デバイスメモリを確保するためのアロケータです。
279 nw::demo::DemoAllocator s_DeviceAllocator;
280
281 //----------------------------------------
282 // ファイル名の定義です。
283 const wchar_t* SKY_SPHERE_FILE_NAME = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
284
285 const wchar_t* MODEL_RESOURCE_FILES[] =
286 {
287 NW_DEMO_FILE_PATH(L"MaleShadow.bcmdl"),
288 NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
289 NW_DEMO_FILE_PATH(L"SpotLight.bcenv"),
290 NW_DEMO_FILE_PATH(L"AmbientLight.bcenv"),
291 };
292
293 const wchar_t* SKELETAL_ANIM_RESOURCE_FILE = NW_DEMO_FILE_PATH(L"WalkAimAt.bcskla");
294
295 const wchar_t* SHADOW_MATERIAL_FILE_NAME = NW_DEMO_FILE_PATH(L"ShadowModel.bcmdl");
296
297 //----------------------------------------
298 // 描画関係
299 const int RENDER_TARGET_COUNT = 2;
300 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
301
302 RenderTargetArray s_RenderTargets;
303 nw::demo::SceneSystem* s_SceneSystem = NULL;
304 nw::demo::RenderSystem* s_RenderSystem = NULL;
305
306 nw::demo::GraphicsDrawing s_GraphicsDrawing;
307
308 //----------------------------------------
309 // リソース関係
310 nw::demo::ResourceArray s_Resources;
311
312 //----------------------------------------
313 // シーン関係
314 nw::gfx::SceneNode* s_SceneRoot = NULL;
315 nw::gfx::SceneNode* s_ModelRoot = NULL;
316 nw::gfx::TransformNode* s_LightRoot = NULL;
317 s32 s_FrameCount = 0;
318 nw::gfx::Camera* s_BaseCamera = NULL;
319 nw::gfx::Camera* s_LeftCamera = NULL;
320 nw::gfx::Camera* s_RightCamera = NULL;
321 nw::gfx::FragmentLight* s_SpotLight = NULL;
322
323 const f32 s_fNearPlane = 0.1f;
324 const f32 s_fFarPlane = 1000.0f;
325
326 //----------------------------------------
327 // シーン環境関係
328 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
329
330 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
331 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
332
333 const s32 s_BaseCameraIndex = 0;
334 const s32 s_ShadowCameraIndex = 1;
335
336 //----------------------------------------
337 // アニメーション関係
338 nw::gfx::SkeletalModel* s_AnimModel = NULL;
339 const int MAX_ANIM_OBJECTS = 8;
340 nw::ut::FixedSizeArray<nw::gfx::AnimObject*, MAX_ANIM_OBJECTS> s_AnimObjects;
341
342 /*!--------------------------------------------------------------------------*
343 @brief グラフィックス関連の初期化を行います。
344 *---------------------------------------------------------------------------*/
345 void
InitializeGraphics()346 InitializeGraphics()
347 {
348 nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
349
350 // renderDescriptionへステレオの設定を行います。
351 nw::demo::RenderSystem::Description renderDescription;
352
353 renderDescription.reusableCommandBufferSize = 0x100000;
354 renderDescription.reusableCommandRequestCount = 512;
355 renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
356
357 s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
358
359 s_GraphicsDrawing.SetScreenSize(
360 renderDescription.lowerScreenDescription.width,
361 renderDescription.lowerScreenDescription.height
362 );
363
364 nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
365
366 s_RenderTargets.push_back(
367 nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
368 );
369
370 bool isPerspectiveShadow = true;
371
372 // Ortho カメラの場合は r 値による除算を行わないようにします。
373 if (s_CameraKind == ORTHO_CAMERA)
374 {
375 isPerspectiveShadow = false;
376 }
377
378 // シャドウマップ用のテクスチャを生成します。
379 s_ShadowTexture =
380 nw::gfx::ResShadowTexture::DynamicBuilder()
381 .Width(s_ShadowTextureSize)
382 .Height(s_ShadowTextureSize)
383 .LocationFlag(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP)
384 .ExecutingMemoryFill(true)
385 .PerspectiveShadow(isPerspectiveShadow)
386 .ShadowZBias(s_ShadowBias * s_ShadowNear / (s_ShadowFar - s_ShadowNear))
387 .Create(&s_DeviceAllocator);
388 s_ShadowTexture.Setup(&s_DeviceAllocator, nw::gfx::ResGraphicsFile(NULL));
389
390 // オフスクリーンバッファを作成します。
391 nw::gfx::IRenderTarget* offScreenTarget =
392 nw::gfx::IRenderTarget::CreateOffScreenBuffer(&s_DeviceAllocator, s_ShadowTexture);
393
394 s_RenderTargets.push_back(offScreenTarget);
395
396 NW_ASSERT(!s_RenderTargets.empty());
397 s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets[0]);
398
399 // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
400 nw::demo::SceneSystem::Description sceneDescription;
401 s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
402
403 // デモ用の最遠景モデルをレンダリングシステムに設定します。
404 // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
405 s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
406
407 NW_GL_ASSERT();
408 }
409
410 /*!--------------------------------------------------------------------------*
411 @brief グラフィックス関連の後始末をします。
412 *---------------------------------------------------------------------------*/
413 void
TerminateGraphics()414 TerminateGraphics()
415 {
416 s_ShadowTexture.Cleanup();
417 if (s_ShadowTexture.IsValid())
418 {
419 s_ShadowTexture.DynamicDestroy();
420 }
421
422 nw::gfx::SafeDestroy(s_LeftCamera);
423
424 nw::gfx::SafeDestroy(s_RightCamera);
425
426 nw::gfx::SafeDestroy(s_SceneSystem);
427
428 nw::gfx::SafeDestroyAll(s_RenderTargets);
429
430 s_GraphicsDrawing.Finalize();
431
432 nw::gfx::SafeDestroy(s_RenderSystem);
433
434 NW_GL_ASSERT();
435 }
436
437 /*!--------------------------------------------------------------------------*
438 @brief ファイルからトランスフォームアニメーション評価を生成します。
439
440 @param[in] maxBones 最大メンバ数です。
441 @param[in] translateAnimEnabled 移動アニメーションが有効かどうかです。
442 @param[in] filePath トランスフォームアニメーションファイルのフルパスです。
443
444 @return トランスフォームアニメーション評価です。
445 *---------------------------------------------------------------------------*/
446 nw::gfx::TransformAnimEvaluator*
CreateTransformAnimEvaluator(const int maxMembers,const bool translateAnimEnabled,const wchar_t * filePath)447 CreateTransformAnimEvaluator(
448 const int maxMembers,
449 const bool translateAnimEnabled,
450 const wchar_t* filePath
451 )
452 {
453 //----------------------------------------
454 // アニメーションリソースを生成します。
455 nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, filePath, &s_DeviceAllocator);
456 if (resourceSet->resource.GetSkeletalAnimsCount() == 0)
457 {
458 return NULL;
459 }
460 nw::anim::ResAnim resAnim = resourceSet->resource.GetSkeletalAnims(0);
461
462 if (!resAnim.IsValid())
463 {
464 return NULL;
465 }
466
467 //----------------------------------------
468 // トランスフォームアニメーション評価を生成します。
469 //
470 // アニメーションを1つのモデルにのみ適用する場合や、
471 // コマ形式データの場合は、 AllocCache を false にすると処理負荷が下がります。
472 nw::gfx::TransformAnimEvaluator* evaluator = nw::gfx::TransformAnimEvaluator::Builder()
473 .AnimData(resAnim)
474 .MaxMembers(maxMembers)
475 .AllocCache(false)
476 .Create(&s_DeviceAllocator);
477
478 // 移動アニメーションの無効化フラグを設定します。
479 evaluator->SetIsTranslateDisabled(!translateAnimEnabled);
480
481 return evaluator;
482 }
483
484 /*!--------------------------------------------------------------------------*
485 @brief スケルタルアニメーションを初期化します。
486
487 @param[in] model スケルタルモデルです。
488 *---------------------------------------------------------------------------*/
489 void
InitializeSkeletalAnim(nw::gfx::SkeletalModel * model)490 InitializeSkeletalAnim(nw::gfx::SkeletalModel* model)
491 {
492 nw::gfx::AnimGroup* animGroup = model->GetSkeletalAnimGroup();
493 if (animGroup == NULL) // スケルタルアニメーション用のアニメーショングループがありません。
494 {
495 return;
496 }
497
498 nw::gfx::ResSkeletalModel resModel = model->GetResSkeletalModel();
499 nw::gfx::ResSkeleton resSkeleton = resModel.GetSkeleton();
500 const int maxBones = resSkeleton.GetBonesCount();
501 const bool translateAnimEnabled =
502 nw::ut::CheckFlag(resSkeleton.GetFlags(), nw::gfx::ResSkeletonData::FLAG_TRANSLATE_ANIMATION_ENABLED);
503
504 //----------------------------------------
505 // アニメーション評価を生成します。
506 nw::gfx::TransformAnimEvaluator* evaluator = CreateTransformAnimEvaluator(
507 maxBones, translateAnimEnabled, SKELETAL_ANIM_RESOURCE_FILE);
508 if (evaluator == NULL)
509 {
510 return;
511 }
512
513 // アニメーションをバインドします。
514 bool bindResult = evaluator->Bind(animGroup);
515
516 //----------------------------------------
517 // アニメーションをモデルに登録します。
518 model->SetSkeletalAnimObject(evaluator);
519 s_AnimObjects.PushBack(evaluator);
520 }
521
522 /*!--------------------------------------------------------------------------*
523 @brief アニメーションの後始末をします。
524 *---------------------------------------------------------------------------*/
525 void
TerminateAnim(void)526 TerminateAnim(void)
527 {
528 for (int animIdx = 0; animIdx < s_AnimObjects.Size(); ++animIdx)
529 {
530 nw::gfx::SafeDestroy(s_AnimObjects[animIdx]);
531 }
532 s_AnimObjects.clear();
533 }
534
535 /*!--------------------------------------------------------------------------*
536 @brief ルートノード関連の構築をします。
537 *---------------------------------------------------------------------------*/
538 void
BuildRootNodes()539 BuildRootNodes()
540 {
541 NW_ASSERT(s_SceneRoot == NULL);
542 s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
543 .IsFixedSizeMemory(false)
544 .Create(&s_DeviceAllocator);
545 NW_NULL_ASSERT(s_SceneRoot);
546
547 NW_ASSERT(s_ModelRoot == NULL);
548 s_ModelRoot = nw::gfx::TransformNode::DynamicBuilder()
549 .IsFixedSizeMemory(false)
550 .Create(&s_DeviceAllocator);
551 s_SceneRoot->AttachChild(s_ModelRoot);
552 NW_NULL_ASSERT(s_ModelRoot);
553
554 NW_ASSERT(s_LightRoot == NULL);
555 s_LightRoot = nw::gfx::TransformNode::DynamicBuilder()
556 .IsFixedSizeMemory(false)
557 .Create(&s_DeviceAllocator);
558 s_SceneRoot->AttachChild(s_LightRoot);
559 NW_NULL_ASSERT(s_LightRoot);
560 }
561
562 /*!--------------------------------------------------------------------------*
563 @brief カメラ関連の構築をします。
564 *---------------------------------------------------------------------------*/
565 void
BuildCameras()566 BuildCameras()
567 {
568 nw::demo::Utility::CreateStereoCameras(
569 &s_BaseCamera,
570 &s_LeftCamera,
571 &s_RightCamera,
572 &s_DeviceAllocator,
573 nw::math::VEC3(20.0f, 15.0f, 20.0f),
574 nw::math::VEC3(0.0f, 10.0f, 0.0f),
575 s_fNearPlane,
576 s_fFarPlane
577 );
578 s_SceneRoot->AttachChild(s_BaseCamera);
579 s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
580
581 // シャドウ用のカメラを作成します。
582 switch (s_CameraKind)
583 {
584 case PERSPECTIVE_CAMERA:
585 {
586 s_ShadowCamera =
587 nw::demo::Utility::CreateCamera(
588 &s_DeviceAllocator,
589 nw::math::VEC3(20.0f, 15.0f, 20.0f),
590 nw::math::VEC3(0.0f, 10.0f, 0.0f),
591 s_ShadowNear,
592 s_ShadowFar,
593 NW_MATH_DEG_TO_RAD(45.0f),
594 nw::math::PIVOT_NONE,
595 1.0f / s_ShadowFar);
596 }
597 break;
598 case FRUSTUM_CAMERA:
599 {
600 s_ShadowCamera =
601 nw::demo::Utility::CreateFrustumCamera(
602 &s_DeviceAllocator,
603 nw::math::VEC3(20.0f, 15.0f, 20.0f),
604 nw::math::VEC3(0.0f, 10.0f, 0.0f),
605 s_ShadowNear,
606 s_ShadowFar,
607 nw::math::VEC2(0.0f, 0.0f),
608 1.0f,
609 nw::math::PIVOT_NONE,
610 1.0f / s_ShadowFar);
611 }
612 break;
613 case ORTHO_CAMERA:
614 {
615 s_ShadowCamera =
616 nw::demo::Utility::CreateOrthoCamera(
617 &s_DeviceAllocator,
618 nw::math::VEC3(20.0f, 15.0f, 20.0f),
619 nw::math::VEC3(0.0f, 10.0f, 0.0f),
620 s_ShadowNear,
621 s_ShadowFar,
622 nw::math::VEC2(0.0f, 0.0f),
623 s_OrthoCameraHeight,
624 nw::math::PIVOT_NONE);
625 }
626 break;
627 default:
628 {
629 NW_FATAL_ERROR("Unsupported camera type.");
630 }
631 break;
632 }
633
634 NW_NULL_ASSERT(s_ShadowCamera);
635
636 s_SceneRoot->AttachChild(s_ShadowCamera);
637 }
638
639 /*!--------------------------------------------------------------------------*
640 @brief シャドウ用のテクスチャコンバイナ関連の構築をします。
641 *---------------------------------------------------------------------------*/
642 void
SetupShadowMaterial(nw::gfx::ResMaterial resMaterial)643 SetupShadowMaterial(nw::gfx::ResMaterial resMaterial)
644 {
645 NW_ASSERT(resMaterial.GetTextureCoordinatorsCount() != 0);
646
647 resMaterial.SetTextureCoordinatorsHash(0x0);
648 resMaterial.SetTextureMappersHash(0x0);
649 resMaterial.SetTextureCombinersHash(0x0);
650 resMaterial.SetMaterialColorHash(0x0);
651
652 nw::gfx::ResTextureCoordinator resTexCoord = resMaterial.GetTextureCoordinators(0);
653
654 // シャドウマップ用のカメラのインデクスとシャドウマップ用のテクスチャマトリクス計算法を設定します。
655 resTexCoord.SetReferenceCamera(1);
656 resTexCoord.SetMappingMethod(nw::gfx::ResTextureCoordinator::MAPPINGMETHOD_SHADOW);
657
658 NW_ASSERT(resMaterial.GetTextureMappersCount() != 0);
659 nw::gfx::ResPixelBasedTextureMapper resTextureMapper = resMaterial.GetTextureMappers(0);
660
661 // ダミーテクスチャとシャドウ用テクスチャを差し替えます。
662 nw::gfx::ResTexture dummyTexture = resTextureMapper.GetTexture().Dereference();
663 dummyTexture.Cleanup();
664 resTextureMapper.SetTexture(s_ShadowTexture);
665
666 nw::gfx::ResFragmentShader resFragmentShader = resMaterial.GetFragmentShader();
667
668 // シャドウを表示するためのコンバイナ設定を行います。
669 nw::gfx::ResTextureCombiner combiner0 = resFragmentShader.GetTextureCombiners(0);
670 combiner0.SetSourceRgb(0, nw::gfx::ResTextureCombiner::SOURCE_TEXTURE0);
671 combiner0.SetSourceRgb(1, nw::gfx::ResTextureCombiner::SOURCE_CONSTANT);
672 combiner0.SetOperandRgb(0, nw::gfx::ResTextureCombiner::OPERANDRGB_ONE_MINUS_SRC_COLOR);
673 combiner0.SetOperandRgb(1, nw::gfx::ResTextureCombiner::OPERANDRGB_SRC_COLOR);
674 combiner0.SetCombineRgb(nw::gfx::ResTextureCombiner::COMBINE_MODULATE);
675
676 nw::gfx::ResTextureCombiner combiner1 = resFragmentShader.GetTextureCombiners(1);
677 combiner1.SetSourceRgb(0, nw::gfx::ResTextureCombiner::SOURCE_TEXTURE1);
678 combiner1.SetSourceRgb(1, nw::gfx::ResTextureCombiner::SOURCE_PREVIOUS);
679 combiner1.SetOperandRgb(0, nw::gfx::ResTextureCombiner::OPERANDRGB_SRC_COLOR);
680 combiner1.SetOperandRgb(1, nw::gfx::ResTextureCombiner::OPERANDRGB_ONE_MINUS_SRC_COLOR);
681 combiner1.SetCombineRgb(nw::gfx::ResTextureCombiner::COMBINE_MODULATE);
682
683 nw::gfx::ResTextureCombiner combiner2 = resFragmentShader.GetTextureCombiners(2);
684 combiner2.SetSourceRgb(0, nw::gfx::ResTextureCombiner::SOURCE_FRAGMENT_PRIMARY_COLOR);
685 combiner2.SetSourceRgb(1, nw::gfx::ResTextureCombiner::SOURCE_PREVIOUS);
686 combiner2.SetSourceRgb(2, nw::gfx::ResTextureCombiner::SOURCE_FRAGMENT_SECONDARY_COLOR);
687 combiner2.SetOperandRgb(0, nw::gfx::ResTextureCombiner::OPERANDRGB_SRC_COLOR);
688 combiner2.SetOperandRgb(1, nw::gfx::ResTextureCombiner::OPERANDRGB_SRC_COLOR);
689 combiner2.SetOperandRgb(2, nw::gfx::ResTextureCombiner::OPERANDRGB_SRC_COLOR);
690 combiner2.SetCombineRgb(nw::gfx::ResTextureCombiner::COMBINE_MULT_ADD);
691
692 // 影の色を設定します。
693 nw::gfx::ResMaterialColor color = resMaterial.GetMaterialColor();
694 color.SetConstant0(1.0f - s_ShadowIntensity, 1.0f - s_ShadowIntensity, 1.0f - s_ShadowIntensity);
695 }
696
697 /*!--------------------------------------------------------------------------*
698 @brief リソース関連の構築をします。
699 *---------------------------------------------------------------------------*/
700 void
BuildResources(nw::demo::ResourceSet * resourceSet)701 BuildResources(nw::demo::ResourceSet* resourceSet)
702 {
703 resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
704 resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
705 resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
706
707 nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
708 if (result.IsFailure())
709 {
710 NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
711 }
712
713 nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(&s_DeviceAllocator);
714
715 nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
716 nw::gfx::ResModelArray::iterator modelsEnd = models.end();
717 for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
718 modelResource != modelsEnd; ++modelResource)
719 {
720 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
721 &s_DeviceAllocator,
722 (*modelResource)
723 );
724
725 // plane の Texture0 にオフスクリーンバッファをテクスチャとしてセットする
726 if (::std::strcmp((*modelResource).GetName(), "Plane") == 0)
727 {
728 nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(node);
729 NW_ASSERT(model->GetMaterialCount() != 0);
730
731 nw::gfx::Material* material = model->GetMaterial(0);
732 nw::gfx::ResMaterial resMaterial = material->GetOriginal();
733 NW_ASSERT(resMaterial.IsValid());
734 SetupShadowMaterial(resMaterial);
735 }
736 else if (::std::strcmp((*modelResource).GetName(), "Male") == 0)
737 {
738 nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(node);
739 s_AnimModel = skeletalModel;
740
741 nw::gfx::Material* material = skeletalModel->GetMaterial(0);
742 NW_ASSERT(skeletalModel->GetMaterialCount() != 0);
743
744 nw::gfx::ResMaterial resMaterial = material->GetOriginal();
745 NW_ASSERT(resMaterial.IsValid());
746 SetupShadowMaterial(resMaterial);
747
748 // 影を生成するモデルにフラグを設定します。
749 skeletalModel->SetUserParameter(SHADOW_CASTER);
750 }
751
752 sceneNodeArray.push_back(node);
753 }
754
755 nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
756 nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
757 for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
758 lightResource != lightsEnd; ++lightResource)
759 {
760 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
761 &s_DeviceAllocator,
762 (*lightResource)
763 );
764
765 if (::std::strcmp((*lightResource).GetName(), "SpotLight") == 0)
766 {
767 s_SpotLight = nw::ut::DynamicCast<nw::gfx::FragmentLight*>(node);
768 s_LightRoot->AttachChild(s_SpotLight);
769 }
770
771 sceneNodeArray.push_back(node);
772 }
773
774 // 親子付け参照関係を解決
775 nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
776
777 // モデルをシーンに追加
778 nw::gfx::SceneHelper::ForeachRootNodes(
779 sceneNodeArray.Begin(),
780 sceneNodeArray.End(),
781 nw::gfx::AttachNode(s_ModelRoot)
782 );
783
784 nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
785 nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
786 for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
787 settingResource != settingsEnd; ++settingResource)
788 {
789 nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
790 .Resource(*settingResource)
791 .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
792
793 nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
794 nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
795
796 NW_NULL_ASSERT(sceneEnvironmentSetting);
797 s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
798 }
799 }
800
801 /*!--------------------------------------------------------------------------*
802 @brief シーンを初期化します。
803 *---------------------------------------------------------------------------*/
804 void
InitializeScenes()805 InitializeScenes()
806 {
807 BuildRootNodes();
808
809 BuildCameras();
810
811 NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
812 {
813 BuildResources(nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator));
814 }
815
816 if (s_AnimModel != NULL)
817 {
818 InitializeSkeletalAnim(s_AnimModel);
819 }
820
821 // シーンツリーを巡回して初期化を行います。
822 s_SceneSystem->InitializeScene(s_SceneRoot);
823 s_SceneSystem->UpdateScene();
824
825 // シーン環境の参照解決を行い設定します。
826 s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
827
828 // カメラを設定します。
829 nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
830 sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
831 sceneEnvironment.SetCamera(s_ShadowCameraIndex, s_ShadowCamera);
832 nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
833
834 // シャドウ用のマテリアルとシェーダーを含むモデルを読み込みます。
835 nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, SHADOW_MATERIAL_FILE_NAME, &s_DeviceAllocator);
836 nw::gfx::ResModel resShadowModel = resourceSet->resource.GetModels("ShadowModel");
837 nw::gfx::Result result = resShadowModel.Setup(&s_DeviceAllocator, resourceSet->resource);
838 NW_ASSERT(result.IsSuccess());
839 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
840 &s_DeviceAllocator,
841 resShadowModel
842 );
843 s_ShadowDummyModel = nw::ut::DynamicCast<nw::gfx::Model*>(node);
844 NW_NULL_ASSERT(s_ShadowDummyModel);
845
846 NW_ASSERT(s_ShadowDummyModel->GetMaterialCount() != 0);
847
848 // シャドウ用のマテリアルにシャドウモードを設定します。
849 // シャドウマップにシャドウ強度とデプス情報を書き込むために必要となります。
850 nw::gfx::ResFragmentOperation fragmentOperation = s_ShadowDummyModel->GetMaterial(0)->GetOriginal().GetFragmentOperation();
851 fragmentOperation.SetFragmentOperationMode(nw::gfx::ResFragmentOperation::FRAGMENT_OPERATION_MODE_SHADOW);
852
853 // シャドウオブジェクトの色を設定します。
854 // シャドウマップでは必ず黒(0.0f, 0.0f, 0.0f ,0.0f) に設定する必要があります。
855 // 影の色の設定ははコンバイナでコンスタントカラーによって行っています。
856 nw::gfx::ResMaterialColor materialColor = s_ShadowDummyModel->GetMaterial(0)->GetOriginal().GetMaterialColor();
857 materialColor.SetDiffuse(0.0f, 0.0f, 0.0f, 0.0f);
858
859 nw::demo::CommandListSwapper* commandListSwapper = s_RenderSystem->GetCommandListSwapper();
860 NW_ASSERT(s_ShadowDummyModel->GetMaterialCount() != 0);
861 nw::gfx::Material* shadowMaterial = s_ShadowDummyModel->GetMaterial(0);
862
863 // レンダーコマンドを作成します。
864 void* startShadowCommandMemory = s_DeviceAllocator.Alloc(sizeof(StartShadowRenderCommand));
865 NW_NULL_ASSERT(startShadowCommandMemory);
866 s_StartShadowRenderCommand = new(startShadowCommandMemory) StartShadowRenderCommand(
867 commandListSwapper,
868 s_RenderTargets[1],
869 s_ShadowCameraIndex,
870 shadowMaterial);
871
872 void* endShadowCommandMemory = s_DeviceAllocator.Alloc(sizeof(EndShadowRenderCommand));
873 NW_NULL_ASSERT(endShadowCommandMemory);
874 s_EndShadowRenderCommand = new(endShadowCommandMemory) EndShadowRenderCommand(commandListSwapper, s_StartShadowRenderCommand);
875
876 void* startCommandMemory = s_DeviceAllocator.Alloc(sizeof(StartRenderCommand));
877 NW_NULL_ASSERT(startCommandMemory);
878 s_StartRenderCommand = new(startCommandMemory) StartRenderCommand(s_RenderSystem, s_RenderTargets[0], s_BaseCameraIndex);
879
880 void* endCommandMemory = s_DeviceAllocator.Alloc(sizeof(EndRenderCommand));
881 NW_NULL_ASSERT(endCommandMemory);
882 s_EndRenderCommand = new(endCommandMemory) EndRenderCommand(s_RenderSystem, s_LeftCamera, s_RightCamera, s_StartRenderCommand);
883
884 NW_GL_ASSERT();
885
886 s_FrameCount = 0;
887 }
888
889 /*!--------------------------------------------------------------------------*
890 @brief シーン関連の後始末をします。
891 *---------------------------------------------------------------------------*/
892 void
TerminateScenes()893 TerminateScenes()
894 {
895 s_DeviceAllocator.Free(s_EndRenderCommand);
896 s_DeviceAllocator.Free(s_StartRenderCommand);
897 s_DeviceAllocator.Free(s_EndShadowRenderCommand);
898 s_DeviceAllocator.Free(s_StartShadowRenderCommand);
899
900 nw::ut::SafeDestroy(s_ShadowDummyModel);
901 nw::gfx::SafeDestroyBranch(s_SceneRoot);
902 nw::demo::SafeCleanupResources(s_Resources);
903 nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings);
904 TerminateAnim();
905
906 NW_GL_ASSERT();
907
908 s_Resources.clear();
909 s_SceneEnvironmentSettings.clear();
910 s_ModelRoot = NULL;
911 s_LightRoot = NULL;
912 }
913
914 /*!--------------------------------------------------------------------------*
915 @brief シーンを更新します。
916 *---------------------------------------------------------------------------*/
917 void
UpdateScene()918 UpdateScene()
919 {
920 float radian = static_cast<float>((s_FrameCount) % (314 * 2)) * 0.01f;
921
922 // ライトルートがY軸中心に回転します。
923 nw::gfx::TransformNode* lightNode =
924 nw::ut::DynamicCast<nw::gfx::TransformNode*>(s_LightRoot);
925 NW_NULL_ASSERT(lightNode);
926
927 lightNode->Transform().SetRotateXYZ(0.0f, radian, 0.0f);
928
929 s_SceneSystem->GetCameraController()->Update();
930
931 s_SceneSystem->UpdateScene();
932
933 s_BaseCamera->UpdateCameraMatrix();
934
935 s_RenderSystem->CalcStereoCamera(s_LeftCamera, s_RightCamera, s_BaseCamera, s_fNearPlane + 5.0f);
936
937 // シャドウの描画をライト方向から行うために、カメラの位置と方向をライトに追従させます。
938 nw::math::VEC3 translate;
939 translate.x = s_SpotLight->WorldMatrix().m[0][3];
940 translate.y = s_SpotLight->WorldMatrix().m[1][3];
941 translate.z = s_SpotLight->WorldMatrix().m[2][3];
942
943 s_ShadowCamera->WorldMatrix().m[0][3] = translate.x;
944 s_ShadowCamera->WorldMatrix().m[1][3] = translate.y;
945 s_ShadowCamera->WorldMatrix().m[2][3] = translate.z;
946
947 const nw::math::VEC3& direction = s_SpotLight->Direction();
948 s_ShadowCamera->SetTargetPosition(translate + direction);
949
950 s_ShadowCamera->UpdateCameraMatrix();
951
952 ++s_FrameCount;
953 }
954
955 /*!--------------------------------------------------------------------------*
956 @brief レンダーキューにレンダーエレメントを追加します。
957 *---------------------------------------------------------------------------*/
958 void
SubmitView()959 SubmitView()
960 {
961 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
962 nw::gfx::SceneEnvironment& sceneEnvironment = renderContext->GetSceneEnvironment();
963 nw::gfx::SceneContext* sceneContext = s_SceneSystem->GetSceneContext();
964
965 nw::gfx::RenderQueue* renderQueue = s_RenderSystem->GetRenderQueue();
966
967 renderQueue->Reset();
968
969 // 描画対象とレンダーコマンドをレンダーキューに追加します。
970 // 分かりやすくするために処理される順に Submit or Enqueue を行います。
971
972 // シャドウ用の設定を行うコマンドをレイヤー0の後に実行するコールバックに追加します。
973 s_RenderSystem->EnqueueRenderCommand(
974 s_StartShadowRenderCommand, nw::gfx::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 0, 0);
975
976 // シャドウキャスターとして指定されたモデルのみを レイヤー1としてレンダーキューに追加します。
977 s_SceneSystem->GetSceneUpdater()->SubmitView(
978 renderQueue,
979 sceneContext,
980 *s_ShadowCamera,
981 1,
982 1,
983 &s_ShadowCasterModel,
984 s_RenderSystem->GetRenderSortMode());
985
986 // シャドウの後処理を行うコマンドをレイヤー1の後に実行するコールバックに追加します。
987 s_RenderSystem->EnqueueRenderCommand(
988 s_EndShadowRenderCommand, nw::gfx::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 0, 1);
989
990 // ステレオ描画の前処理の設定を行うコマンドをレイヤー1の後に実行するコールバックに追加します。
991 s_RenderSystem->EnqueueRenderCommand(
992 s_StartRenderCommand, nw::gfx::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 1, 1);
993
994 // シーンコンテキストの全てのモデルをレイヤー2でレンダーキューに追加します。
995 s_SceneSystem->GetSceneUpdater()->SubmitView(
996 renderQueue,
997 sceneContext,
998 *s_BaseCamera,
999 2,
1000 s_RenderSystem->GetRenderSortMode());
1001
1002 // ステレオ描画の後処理の設定を行うコマンドをレイヤー2の後に実行するコールバックに追加します。
1003 s_RenderSystem->EnqueueRenderCommand(
1004 s_EndRenderCommand, nw::gfx::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 0, 2);
1005
1006 std::sort(
1007 renderQueue->Begin(),
1008 renderQueue->End(),
1009 nw::gfx::RenderElementCompare());
1010 }
1011
1012 //----------------------------------------
1013 struct RenderSceneInternalFunctor
1014 : public std::unary_function<nw::gfx::RenderElement&, void>
1015 {
1016 nw::gfx::RenderContext* m_RenderContext;
1017 nw::gfx::MeshRenderer* m_MeshRenderer;
1018
RenderSceneInternalFunctor__anon96b649ca0111::RenderSceneInternalFunctor1019 RenderSceneInternalFunctor(nw::gfx::RenderContext* renderContext, nw::gfx::MeshRenderer* meshRenderer)
1020 : m_RenderContext(renderContext), m_MeshRenderer(meshRenderer)
1021 {
1022 NW_NULL_ASSERT(renderContext);
1023 NW_NULL_ASSERT(meshRenderer);
1024 }
1025
operator ()__anon96b649ca0111::RenderSceneInternalFunctor1026 void operator()(nw::gfx::RenderElement& element)
1027 {
1028 if (element.IsCommand())
1029 {
1030 nw::gfx::RenderCommand* command = element.GetCommand();
1031 NW_NULL_ASSERT(command);
1032 command->Invoke(this->m_RenderContext);
1033 }
1034 else
1035 {
1036 nw::gfx::ResMesh mesh = element.GetMesh();
1037 nw::gfx::Model* model = element.GetModel();
1038 model->PreRenderSignal()(model, mesh, this->m_RenderContext);
1039 this->m_MeshRenderer->RenderMesh(mesh, model);
1040 model->PostRenderSignal()(model, mesh, this->m_RenderContext);
1041 }
1042 NW_GL_ASSERT();
1043 }
1044 };
1045
1046 /*!--------------------------------------------------------------------------*
1047 @brief レンダーキューに基づいて描画を行います。
1048 *---------------------------------------------------------------------------*/
1049 void
RenderScene()1050 RenderScene()
1051 {
1052 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
1053 nw::gfx::RenderQueue* renderQueue = s_RenderSystem->GetRenderQueue();
1054 nw::gfx::MeshRenderer* meshRenderer = s_RenderSystem->GetMeshRenderer();
1055
1056 std::for_each(
1057 renderQueue->Begin(),
1058 renderQueue->End(),
1059 RenderSceneInternalFunctor(renderContext, meshRenderer));
1060
1061 NW_GL_ASSERT();
1062 }
1063
1064 /*!--------------------------------------------------------------------------*
1065 @brief 負荷表示やテスト機能の処理をおこないます。
1066 *---------------------------------------------------------------------------*/
1067 void
ReportDemo()1068 ReportDemo()
1069 {
1070 NW_PROFILE("ReportDemo");
1071
1072 // 負荷表示からはこれらの負荷は除きます。
1073 s_RenderSystem->SuspendLoadMeter();
1074
1075 s_RenderSystem->AddLoadMeterCommandSize(
1076 s_EndShadowRenderCommand->GetCommandSize() - s_StartShadowRenderCommand->GetCommandSize());
1077
1078 nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
1079
1080 s_GraphicsDrawing.BeginDrawingShape();
1081
1082 nw::demo::DebugUtility::DrawLoadMeter(
1083 s_RenderSystem,
1084 &s_GraphicsDrawing
1085 );
1086
1087 s_GraphicsDrawing.EndDrawingShape();
1088
1089 s_GraphicsDrawing.BeginDrawingString();
1090
1091 nw::demo::DebugUtility::DrawLoadMeterText(
1092 s_RenderSystem,
1093 &s_GraphicsDrawing
1094 );
1095
1096 s_GraphicsDrawing.EndDrawingString();
1097
1098 s_RenderSystem->ResumeLoadMeter();
1099 }
1100
1101 /*!--------------------------------------------------------------------------*
1102 @brief シーンをデモンストレーションします。
1103 *---------------------------------------------------------------------------*/
1104 void
DemoScene()1105 DemoScene()
1106 {
1107 NW_ASSERT(!s_RenderTargets.empty());
1108
1109 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
1110
1111 InitializeScenes();
1112
1113 nw::demo::DebugUtility::PostInitializeScenes();
1114
1115 bool isContinuing = true;
1116
1117 while ( isContinuing )
1118 {
1119 nw::demo::DebugUtility::AdvanceAutoTestFrame();
1120
1121 nw::demo::PadFactory::GetPad()->Update();
1122
1123 UpdateScene();
1124
1125 SubmitView();
1126
1127 RenderScene();
1128
1129 s_RenderSystem->ClearBySkyModel(s_BaseCamera);
1130 ReportDemo();
1131 s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
1132
1133 s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
1134
1135 renderContext->ResetState();
1136
1137 if (nw::demo::Utility::IsTerminating())
1138 {
1139 isContinuing = false;
1140 }
1141 }
1142
1143 nw::demo::DebugUtility::PreTerminateScenes();
1144
1145 TerminateScenes();
1146 }
1147
1148 } // namespace
1149
1150 /*!--------------------------------------------------------------------------*
1151 @brief メイン関数です。
1152 *---------------------------------------------------------------------------*/
1153 void
nnMain()1154 nnMain()
1155 {
1156 nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
1157
1158 nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
1159
1160 NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
1161 {
1162
1163 InitializeGraphics();
1164
1165 DemoScene();
1166
1167 TerminateGraphics();
1168
1169 }
1170
1171 nw::demo::PadFactory::Finalize();
1172
1173 nw::demo::FinalizeGraphicsSystem();
1174 }
1175