1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     ProjectionShadowDemo.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::ResImageTexture s_ShadowTexture;
268 // シャドウテクスチャのサイズです。
269 const s32 s_ShadowTextureSize = 512;
270 // 影の強度(濃さ)です。
271 const f32 s_ShadowIntensity = 0.2f;
272 
273 //----------------------------------------
274 // メモリ関係
275 
276 // デバイスメモリを確保するためのアロケータです。
277 nw::demo::DemoAllocator s_DeviceAllocator;
278 
279 //----------------------------------------
280 // ファイル名の定義です。
281 const wchar_t* SKY_SPHERE_FILE_NAME  = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
282 
283 const wchar_t* MODEL_RESOURCE_FILES[] =
284 {
285     NW_DEMO_FILE_PATH(L"MaleShadow.bcmdl"),
286     NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
287     NW_DEMO_FILE_PATH(L"SpotLight.bcenv"),
288     NW_DEMO_FILE_PATH(L"AmbientLight.bcenv"),
289 };
290 
291 const wchar_t* SKELETAL_ANIM_RESOURCE_FILE = NW_DEMO_FILE_PATH(L"WalkAimAt.bcskla");
292 
293 const wchar_t* SHADOW_MATERIAL_FILE_NAME = NW_DEMO_FILE_PATH(L"ShadowModel.bcmdl");
294 
295 //----------------------------------------
296 // 描画関係
297 const int RENDER_TARGET_COUNT = 2;
298 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
299 
300 RenderTargetArray s_RenderTargets;
301 nw::demo::SceneSystem*  s_SceneSystem = NULL;
302 nw::demo::RenderSystem* s_RenderSystem = NULL;
303 
304 nw::demo::GraphicsDrawing  s_GraphicsDrawing;
305 
306 //----------------------------------------
307 // リソース関係
308 nw::demo::ResourceArray s_Resources;
309 
310 //----------------------------------------
311 // シーン関係
312 nw::gfx::SceneNode* s_SceneRoot = NULL;
313 nw::gfx::SceneNode* s_ModelRoot = NULL;
314 nw::gfx::TransformNode* s_LightRoot = NULL;
315 s32 s_FrameCount = 0;
316 nw::gfx::Camera* s_BaseCamera = NULL;
317 nw::gfx::Camera* s_LeftCamera = NULL;
318 nw::gfx::Camera* s_RightCamera = NULL;
319 nw::gfx::FragmentLight* s_SpotLight = NULL;
320 
321 const f32 s_fNearPlane = 0.1f;
322 const f32 s_fFarPlane = 1000.0f;
323 
324 //----------------------------------------
325 // シーン環境関係
326 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
327 
328 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
329 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
330 
331 const s32 s_BaseCameraIndex = 0;
332 const s32 s_ShadowCameraIndex = 1;
333 
334 //----------------------------------------
335 // アニメーション関係
336 nw::gfx::SkeletalModel* s_AnimModel = NULL;
337 const int MAX_ANIM_OBJECTS = 8;
338 nw::ut::FixedSizeArray<nw::gfx::AnimObject*, MAX_ANIM_OBJECTS> s_AnimObjects;
339 
340 /*!--------------------------------------------------------------------------*
341   @brief        グラフィックス関連の初期化を行います。
342  *---------------------------------------------------------------------------*/
343 void
InitializeGraphics()344 InitializeGraphics()
345 {
346     nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
347 
348     // renderDescriptionへステレオの設定を行います。
349     nw::demo::RenderSystem::Description renderDescription;
350 
351     renderDescription.reusableCommandBufferSize = 0x100000;
352     renderDescription.reusableCommandRequestCount      = 512;
353     renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
354 
355     s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
356 
357     s_GraphicsDrawing.SetScreenSize(
358         renderDescription.lowerScreenDescription.width,
359         renderDescription.lowerScreenDescription.height
360     );
361 
362     nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
363 
364     s_RenderTargets.push_back(
365         nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
366     );
367 
368     // シャドウ描画用のテクスチャを確保します。
369     // VRAM に配置して OffScreenBuffer として利用するので、
370     // LocationFlag(NN_GX_MEM_VRAMA), DynamicAllocation(false) とする。
371     s_ShadowTexture =
372         nw::gfx::ResImageTexture::DynamicBuilder()
373         .Width(s_ShadowTextureSize)
374         .Height(s_ShadowTextureSize)
375         .MipmapSize(1)
376         .LocationFlag(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP)
377         .Format(nw::gfx::ResPixelBasedTexture::FORMAT_HW_RGBA8)
378         .ExecutingMemoryFill(true)
379         .DynamicAllocation(false)
380         .Create(&s_DeviceAllocator);
381     s_ShadowTexture.Setup(&s_DeviceAllocator, nw::gfx::ResGraphicsFile(NULL));
382 
383     // オフスクリーンバッファを作成します。
384     nw::gfx::IRenderTarget* offScreenTarget =
385         nw::gfx::IRenderTarget::CreateOffScreenBuffer(&s_DeviceAllocator, s_ShadowTexture);
386 
387     s_RenderTargets.push_back(offScreenTarget);
388 
389     NW_ASSERT(!s_RenderTargets.empty());
390     s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets[0]);
391 
392     // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
393     nw::demo::SceneSystem::Description sceneDescription;
394     s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
395 
396     // デモ用の最遠景モデルをレンダリングシステムに設定します。
397     // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
398     s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
399 
400     NW_GL_ASSERT();
401 }
402 
403 /*!--------------------------------------------------------------------------*
404   @brief        グラフィックス関連の後始末をします。
405  *---------------------------------------------------------------------------*/
406 void
TerminateGraphics()407 TerminateGraphics()
408 {
409     s_ShadowTexture.Cleanup();
410     if (s_ShadowTexture.IsValid())
411     {
412         s_ShadowTexture.DynamicDestroy();
413     }
414 
415     nw::gfx::SafeDestroy(s_LeftCamera);
416 
417     nw::gfx::SafeDestroy(s_RightCamera);
418 
419     nw::gfx::SafeDestroy(s_SceneSystem);
420 
421     nw::gfx::SafeDestroyAll(s_RenderTargets);
422 
423     s_GraphicsDrawing.Finalize();
424 
425     nw::gfx::SafeDestroy(s_RenderSystem);
426 
427     NW_GL_ASSERT();
428 }
429 
430 /*!--------------------------------------------------------------------------*
431   @brief ファイルからトランスフォームアニメーション評価を生成します。
432 
433   @param[in] maxBones 最大メンバ数です。
434   @param[in] translateAnimEnabled 移動アニメーションが有効かどうかです。
435   @param[in] filePath トランスフォームアニメーションファイルのフルパスです。
436 
437   @return トランスフォームアニメーション評価です。
438  *---------------------------------------------------------------------------*/
439 nw::gfx::TransformAnimEvaluator*
CreateTransformAnimEvaluator(const int maxMembers,const bool translateAnimEnabled,const wchar_t * filePath)440 CreateTransformAnimEvaluator(
441     const int maxMembers,
442     const bool translateAnimEnabled,
443     const wchar_t* filePath
444 )
445 {
446     //----------------------------------------
447     // アニメーションリソースを生成します。
448     nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, filePath, &s_DeviceAllocator);
449     if (resourceSet->resource.GetSkeletalAnimsCount() == 0)
450     {
451         return NULL;
452     }
453     nw::anim::ResAnim resAnim = resourceSet->resource.GetSkeletalAnims(0);
454 
455     if (!resAnim.IsValid())
456     {
457         return NULL;
458     }
459 
460     //----------------------------------------
461     // トランスフォームアニメーション評価を生成します。
462     //
463     // アニメーションを1つのモデルにのみ適用する場合や、
464     // コマ形式データの場合は、 AllocCache を false にすると処理負荷が下がります。
465     nw::gfx::TransformAnimEvaluator* evaluator = nw::gfx::TransformAnimEvaluator::Builder()
466         .AnimData(resAnim)
467         .MaxMembers(maxMembers)
468         .AllocCache(false)
469         .Create(&s_DeviceAllocator);
470 
471     // 移動アニメーションの無効化フラグを設定します。
472     evaluator->SetIsTranslateDisabled(!translateAnimEnabled);
473 
474     return evaluator;
475 }
476 
477 /*!--------------------------------------------------------------------------*
478   @brief        スケルタルアニメーションを初期化します。
479 
480   @param[in]    model スケルタルモデルです。
481  *---------------------------------------------------------------------------*/
482 void
InitializeSkeletalAnim(nw::gfx::SkeletalModel * model)483 InitializeSkeletalAnim(nw::gfx::SkeletalModel* model)
484 {
485     nw::gfx::AnimGroup* animGroup = model->GetSkeletalAnimGroup();
486     if (animGroup == NULL) // スケルタルアニメーション用のアニメーショングループがありません。
487     {
488         return;
489     }
490 
491     nw::gfx::ResSkeletalModel resModel = model->GetResSkeletalModel();
492     nw::gfx::ResSkeleton resSkeleton = resModel.GetSkeleton();
493     const int maxBones = resSkeleton.GetBonesCount();
494     const bool translateAnimEnabled =
495         nw::ut::CheckFlag(resSkeleton.GetFlags(), nw::gfx::ResSkeletonData::FLAG_TRANSLATE_ANIMATION_ENABLED);
496 
497     //----------------------------------------
498     // アニメーション評価を生成します。
499     nw::gfx::TransformAnimEvaluator* evaluator = CreateTransformAnimEvaluator(
500         maxBones, translateAnimEnabled, SKELETAL_ANIM_RESOURCE_FILE);
501     if (evaluator == NULL)
502     {
503         return;
504     }
505 
506     // アニメーションをバインドします。
507     bool bindResult = evaluator->Bind(animGroup);
508 
509     //----------------------------------------
510     // アニメーションをモデルに登録します。
511     model->SetSkeletalAnimObject(evaluator);
512     s_AnimObjects.PushBack(evaluator);
513 }
514 
515 /*!--------------------------------------------------------------------------*
516   @brief        アニメーションの後始末をします。
517  *---------------------------------------------------------------------------*/
518 void
TerminateAnim(void)519 TerminateAnim(void)
520 {
521     for (int animIdx = 0; animIdx < s_AnimObjects.Size(); ++animIdx)
522     {
523         nw::gfx::SafeDestroy(s_AnimObjects[animIdx]);
524     }
525     s_AnimObjects.clear();
526 }
527 
528 /*!--------------------------------------------------------------------------*
529   @brief        ルートノード関連の構築をします。
530  *---------------------------------------------------------------------------*/
531 void
BuildRootNodes()532 BuildRootNodes()
533 {
534     NW_ASSERT(s_SceneRoot == NULL);
535     s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
536         .IsFixedSizeMemory(false)
537         .Create(&s_DeviceAllocator);
538     NW_NULL_ASSERT(s_SceneRoot);
539 
540     NW_ASSERT(s_ModelRoot == NULL);
541     s_ModelRoot = nw::gfx::TransformNode::DynamicBuilder()
542         .IsFixedSizeMemory(false)
543         .Create(&s_DeviceAllocator);
544     s_SceneRoot->AttachChild(s_ModelRoot);
545     NW_NULL_ASSERT(s_ModelRoot);
546 
547     NW_ASSERT(s_LightRoot == NULL);
548     s_LightRoot = nw::gfx::TransformNode::DynamicBuilder()
549         .IsFixedSizeMemory(false)
550         .Create(&s_DeviceAllocator);
551     s_SceneRoot->AttachChild(s_LightRoot);
552     NW_NULL_ASSERT(s_LightRoot);
553 }
554 
555 /*!--------------------------------------------------------------------------*
556   @brief        カメラ関連の構築をします。
557  *---------------------------------------------------------------------------*/
558 void
BuildCameras()559 BuildCameras()
560 {
561     nw::demo::Utility::CreateStereoCameras(
562         &s_BaseCamera,
563         &s_LeftCamera,
564         &s_RightCamera,
565         &s_DeviceAllocator,
566         nw::math::VEC3(20.0f, 15.0f, 20.0f),
567         nw::math::VEC3(0.0f, 10.0f, 0.0f),
568         s_fNearPlane,
569         s_fFarPlane
570     );
571     s_SceneRoot->AttachChild(s_BaseCamera);
572     s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
573 
574     // シャドウ用のカメラを作成します。
575     switch (s_CameraKind)
576     {
577         case PERSPECTIVE_CAMERA:
578             {
579                 s_ShadowCamera =
580                     nw::demo::Utility::CreateCamera(
581                         &s_DeviceAllocator,
582                         nw::math::VEC3(20.0f, 15.0f, 20.0f),
583                         nw::math::VEC3(0.0f, 10.0f, 0.0f),
584                         s_ShadowNear,
585                         s_ShadowFar,
586                         NW_MATH_DEG_TO_RAD(45.0f),
587                         nw::math::PIVOT_NONE);
588             }
589             break;
590         case FRUSTUM_CAMERA:
591             {
592                 s_ShadowCamera =
593                     nw::demo::Utility::CreateFrustumCamera(
594                         &s_DeviceAllocator,
595                         nw::math::VEC3(20.0f, 15.0f, 20.0f),
596                         nw::math::VEC3(0.0f, 10.0f, 0.0f),
597                         s_ShadowNear,
598                         s_ShadowFar,
599                         nw::math::VEC2(0.0f, 0.0f),
600                         1.0f,
601                         nw::math::PIVOT_NONE);
602             }
603             break;
604         case ORTHO_CAMERA:
605             {
606                 s_ShadowCamera =
607                     nw::demo::Utility::CreateOrthoCamera(
608                         &s_DeviceAllocator,
609                         nw::math::VEC3(20.0f, 15.0f, 20.0f),
610                         nw::math::VEC3(0.0f, 10.0f, 0.0f),
611                         s_ShadowNear,
612                         s_ShadowFar,
613                         nw::math::VEC2(0.0f, 0.0f),
614                         s_OrthoCameraHeight,
615                         nw::math::PIVOT_NONE);
616             }
617             break;
618         default:
619             {
620                 NW_FATAL_ERROR("Unsupported camera type.");
621             }
622             break;
623     }
624 
625     NW_NULL_ASSERT(s_ShadowCamera);
626 
627     s_SceneRoot->AttachChild(s_ShadowCamera);
628 }
629 
630 /*!--------------------------------------------------------------------------*
631   @brief        シャドウ用のテクスチャコンバイナ関連の構築をします。
632  *---------------------------------------------------------------------------*/
633 void
SetupShadowMaterial(nw::gfx::ResMaterial resMaterial)634 SetupShadowMaterial(nw::gfx::ResMaterial resMaterial)
635 {
636     nw::gfx::ResTextureCoordinator resTexCoord = resMaterial.GetTextureCoordinators(0);
637     resTexCoord.SetReferenceCamera(1);
638     nw::gfx::ResPixelBasedTextureMapper resTextureMapper = resMaterial.GetTextureMappers(0);
639     // ダミーのテクスチャをシャドウ用のテクスチャに差し替えます。
640     nw::gfx::ResTexture dummyTexture = resTextureMapper.GetTexture().Dereference();
641     dummyTexture.Cleanup();
642     resTextureMapper.SetTexture(s_ShadowTexture);
643 }
644 
645 /*!--------------------------------------------------------------------------*
646   @brief        リソース関連の構築をします。
647  *---------------------------------------------------------------------------*/
648 void
BuildResources(nw::demo::ResourceSet * resourceSet)649 BuildResources(nw::demo::ResourceSet* resourceSet)
650 {
651     resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
652     resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
653     resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
654 
655     nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
656     if (result.IsFailure())
657     {
658         NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
659     }
660 
661     nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(&s_DeviceAllocator);
662 
663     nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
664     nw::gfx::ResModelArray::iterator modelsEnd = models.end();
665     for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
666          modelResource != modelsEnd; ++modelResource)
667     {
668         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
669             &s_DeviceAllocator,
670             (*modelResource)
671         );
672 
673         // plane の Texture0 にオフスクリーンバッファをテクスチャとしてセットする
674         if (::std::strcmp((*modelResource).GetName(), "Plane") == 0)
675         {
676             nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(node);
677             NW_ASSERT(model->GetMaterialCount() != 0);
678 
679             nw::gfx::Material* material = model->GetMaterial(0);
680             nw::gfx::ResMaterial resMaterial = material->GetOriginal();
681             NW_ASSERT(resMaterial.IsValid());
682             SetupShadowMaterial(resMaterial);
683         }
684         else if (::std::strcmp((*modelResource).GetName(), "Male") == 0)
685         {
686             nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(node);
687             s_AnimModel = skeletalModel;
688 
689             // 影を生成するモデルにフラグを設定します。
690             skeletalModel->SetUserParameter(SHADOW_CASTER);
691         }
692 
693         sceneNodeArray.push_back(node);
694     }
695 
696     nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
697     nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
698     for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
699          lightResource != lightsEnd; ++lightResource)
700     {
701         nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
702             &s_DeviceAllocator,
703             (*lightResource)
704         );
705 
706         if (::std::strcmp((*lightResource).GetName(), "SpotLight") == 0)
707         {
708             s_SpotLight = nw::ut::DynamicCast<nw::gfx::FragmentLight*>(node);
709             s_LightRoot->AttachChild(s_SpotLight);
710         }
711 
712         sceneNodeArray.push_back(node);
713     }
714 
715     // 親子付け参照関係を解決
716     nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
717 
718     // モデルをシーンに追加
719     nw::gfx::SceneHelper::ForeachRootNodes(
720         sceneNodeArray.Begin(),
721         sceneNodeArray.End(),
722         nw::gfx::AttachNode(s_ModelRoot)
723     );
724 
725     nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
726     nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
727     for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
728         settingResource != settingsEnd; ++settingResource)
729     {
730         nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
731             .Resource(*settingResource)
732             .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
733 
734         nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
735             nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
736 
737         NW_NULL_ASSERT(sceneEnvironmentSetting);
738         s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
739     }
740 }
741 
742 /*!--------------------------------------------------------------------------*
743   @brief        シーンを初期化します。
744  *---------------------------------------------------------------------------*/
745 void
InitializeScenes()746 InitializeScenes()
747 {
748     BuildRootNodes();
749 
750     BuildCameras();
751 
752     NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
753     {
754         BuildResources(nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator));
755     }
756 
757     if (s_AnimModel != NULL)
758     {
759         InitializeSkeletalAnim(s_AnimModel);
760     }
761 
762     // シーンツリーを巡回して初期化を行います。
763     s_SceneSystem->InitializeScene(s_SceneRoot);
764     s_SceneSystem->UpdateScene();
765 
766     // シーン環境の参照解決を行い設定します。
767     s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
768 
769     // カメラを設定します。
770     nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
771     sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
772     sceneEnvironment.SetCamera(s_ShadowCameraIndex, s_ShadowCamera);
773     nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
774 
775     // シャドウ用のマテリアルとシェーダーを含むモデルを読み込みます。
776     nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, SHADOW_MATERIAL_FILE_NAME, &s_DeviceAllocator);
777     nw::gfx::ResModel resShadowModel = resourceSet->resource.GetModels("ShadowModel");
778     nw::gfx::Result result = resShadowModel.Setup(&s_DeviceAllocator, resourceSet->resource);
779     NW_ASSERT(result.IsSuccess());
780     nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
781         &s_DeviceAllocator,
782         resShadowModel
783     );
784     s_ShadowDummyModel = nw::ut::DynamicCast<nw::gfx::Model*>(node);
785     NW_NULL_ASSERT(s_ShadowDummyModel);
786 
787     NW_ASSERT(s_ShadowDummyModel->GetMaterialCount() != 0);
788 
789     // 影の強度(濃さ)を設定します。
790     nw::gfx::ResMaterialColor materialColor = s_ShadowDummyModel->GetMaterial(0)->GetOriginal().GetMaterialColor();
791     materialColor.SetDiffuse(s_ShadowIntensity, s_ShadowIntensity, s_ShadowIntensity);
792 
793     nw::demo::CommandListSwapper* commandListSwapper = s_RenderSystem->GetCommandListSwapper();
794     NW_ASSERT(s_ShadowDummyModel->GetMaterialCount() != 0);
795     nw::gfx::Material* shadowMaterial = s_ShadowDummyModel->GetMaterial(0);
796 
797     // レンダーコマンドを作成します。
798     void* startShadowCommandMemory = s_DeviceAllocator.Alloc(sizeof(StartShadowRenderCommand));
799     NW_NULL_ASSERT(startShadowCommandMemory);
800     s_StartShadowRenderCommand = new(startShadowCommandMemory) StartShadowRenderCommand(
801         commandListSwapper,
802         s_RenderTargets[1],
803         s_ShadowCameraIndex,
804         shadowMaterial);
805 
806     void* endShadowCommandMemory = s_DeviceAllocator.Alloc(sizeof(EndShadowRenderCommand));
807     NW_NULL_ASSERT(endShadowCommandMemory);
808     s_EndShadowRenderCommand = new(endShadowCommandMemory) EndShadowRenderCommand(commandListSwapper, s_StartShadowRenderCommand);
809 
810     void* startCommandMemory = s_DeviceAllocator.Alloc(sizeof(StartRenderCommand));
811     NW_NULL_ASSERT(startCommandMemory);
812     s_StartRenderCommand = new(startCommandMemory) StartRenderCommand(s_RenderSystem, s_RenderTargets[0], s_BaseCameraIndex);
813 
814     void* endCommandMemory = s_DeviceAllocator.Alloc(sizeof(EndRenderCommand));
815     NW_NULL_ASSERT(endCommandMemory);
816     s_EndRenderCommand = new(endCommandMemory) EndRenderCommand(s_RenderSystem, s_LeftCamera, s_RightCamera, s_StartRenderCommand);
817 
818     NW_GL_ASSERT();
819 
820     s_FrameCount = 0;
821 }
822 
823 /*!--------------------------------------------------------------------------*
824   @brief        シーン関連の後始末をします。
825  *---------------------------------------------------------------------------*/
826 void
TerminateScenes()827 TerminateScenes()
828 {
829     s_DeviceAllocator.Free(s_EndRenderCommand);
830     s_DeviceAllocator.Free(s_StartRenderCommand);
831     s_DeviceAllocator.Free(s_EndShadowRenderCommand);
832     s_DeviceAllocator.Free(s_StartShadowRenderCommand);
833 
834     nw::ut::SafeDestroy(s_ShadowDummyModel);
835     nw::gfx::SafeDestroyBranch(s_SceneRoot);
836     nw::demo::SafeCleanupResources(s_Resources);
837     nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings);
838     TerminateAnim();
839 
840     NW_GL_ASSERT();
841 
842     s_Resources.clear();
843     s_SceneEnvironmentSettings.clear();
844     s_ModelRoot = NULL;
845     s_LightRoot = NULL;
846 }
847 
848 /*!--------------------------------------------------------------------------*
849   @brief        シーンを更新します。
850  *---------------------------------------------------------------------------*/
851 void
UpdateScene()852 UpdateScene()
853 {
854     float radian = static_cast<float>((s_FrameCount) % (314 * 2)) * 0.01f;
855 
856     // ライトルートがY軸中心に回転します。
857     nw::gfx::TransformNode* lightNode =
858         nw::ut::DynamicCast<nw::gfx::TransformNode*>(s_LightRoot);
859     NW_NULL_ASSERT(lightNode);
860 
861     lightNode->Transform().SetRotateXYZ(0.0f, radian, 0.0f);
862 
863     s_SceneSystem->GetCameraController()->Update();
864 
865     s_SceneSystem->UpdateScene();
866 
867     s_BaseCamera->UpdateCameraMatrix();
868 
869     s_RenderSystem->CalcStereoCamera(s_LeftCamera, s_RightCamera, s_BaseCamera, s_fNearPlane + 5.0f);
870 
871     // シャドウの描画をライト方向から行うために、カメラの位置と方向をライトに追従させます。
872     nw::math::VEC3 translate;
873     translate.x = s_SpotLight->WorldMatrix().m[0][3];
874     translate.y = s_SpotLight->WorldMatrix().m[1][3];
875     translate.z = s_SpotLight->WorldMatrix().m[2][3];
876 
877     s_ShadowCamera->WorldMatrix().m[0][3] = translate.x;
878     s_ShadowCamera->WorldMatrix().m[1][3] = translate.y;
879     s_ShadowCamera->WorldMatrix().m[2][3] = translate.z;
880 
881     const nw::math::VEC3& direction = s_SpotLight->Direction();
882     s_ShadowCamera->SetTargetPosition(translate + direction);
883 
884     s_ShadowCamera->UpdateCameraMatrix();
885 
886     ++s_FrameCount;
887 }
888 
889 /*!--------------------------------------------------------------------------*
890   @brief        レンダーキューにレンダーエレメントを追加します。
891  *---------------------------------------------------------------------------*/
892 void
SubmitView()893 SubmitView()
894 {
895     nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
896     nw::gfx::SceneEnvironment& sceneEnvironment = renderContext->GetSceneEnvironment();
897     nw::gfx::SceneContext* sceneContext = s_SceneSystem->GetSceneContext();
898 
899     nw::gfx::RenderQueue* renderQueue = s_RenderSystem->GetRenderQueue();
900 
901     renderQueue->Reset();
902 
903     // 描画対象とレンダーコマンドをレンダーキューに追加します。
904     // 分かりやすくするために処理される順に Submit or Enqueue を行います。
905 
906     // シャドウ用の設定を行うコマンドをレイヤー0の後に実行するコールバックに追加します。
907     s_RenderSystem->EnqueueRenderCommand(
908         s_StartShadowRenderCommand, nw::gfx::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 0, 0);
909 
910     // シャドウキャスターとして指定されたモデルのみを レイヤー1としてレンダーキューに追加します。
911     s_SceneSystem->GetSceneUpdater()->SubmitView(
912         renderQueue,
913         sceneContext,
914         *s_ShadowCamera,
915         1,
916         1,
917         &s_ShadowCasterModel,
918         s_RenderSystem->GetRenderSortMode());
919 
920     // シャドウの後処理を行うコマンドをレイヤー1の後に実行するコールバックに追加します。
921     s_RenderSystem->EnqueueRenderCommand(
922         s_EndShadowRenderCommand, nw::gfx::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 0, 1);
923 
924     // ステレオ描画の前処理の設定を行うコマンドをレイヤー1の後に実行するコールバックに追加します。
925     s_RenderSystem->EnqueueRenderCommand(
926         s_StartRenderCommand, nw::gfx::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 1, 1);
927 
928     // シーンコンテキストの全てのモデルをレイヤー2でレンダーキューに追加します。
929     s_SceneSystem->GetSceneUpdater()->SubmitView(
930         renderQueue,
931         sceneContext,
932         *s_BaseCamera,
933         2,
934         s_RenderSystem->GetRenderSortMode());
935 
936     // ステレオ描画の後処理の設定を行うコマンドをレイヤー2の後に実行するコールバックに追加します。
937     s_RenderSystem->EnqueueRenderCommand(
938         s_EndRenderCommand, nw::gfx::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 0, 2);
939 
940     std::sort(
941         renderQueue->Begin(),
942         renderQueue->End(),
943         nw::gfx::RenderElementCompare());
944 }
945 
946 //----------------------------------------
947 struct RenderSceneInternalFunctor
948 : public std::unary_function<nw::gfx::RenderElement&, void>
949 {
950     nw::gfx::RenderContext* m_RenderContext;
951     nw::gfx::MeshRenderer* m_MeshRenderer;
952 
RenderSceneInternalFunctor__anond8ebf6880111::RenderSceneInternalFunctor953     RenderSceneInternalFunctor(nw::gfx::RenderContext* renderContext, nw::gfx::MeshRenderer* meshRenderer)
954     : m_RenderContext(renderContext), m_MeshRenderer(meshRenderer)
955     {
956         NW_NULL_ASSERT(renderContext);
957         NW_NULL_ASSERT(meshRenderer);
958     }
959 
operator ()__anond8ebf6880111::RenderSceneInternalFunctor960     void operator()(nw::gfx::RenderElement& element)
961     {
962         if (element.IsCommand())
963         {
964             nw::gfx::RenderCommand* command = element.GetCommand();
965             NW_NULL_ASSERT(command);
966             command->Invoke(this->m_RenderContext);
967         }
968         else
969         {
970             nw::gfx::ResMesh mesh = element.GetMesh();
971             nw::gfx::Model* model = element.GetModel();
972             model->PreRenderSignal()(model, mesh, this->m_RenderContext);
973             this->m_MeshRenderer->RenderMesh(mesh, model);
974             model->PostRenderSignal()(model, mesh, this->m_RenderContext);
975         }
976         NW_GL_ASSERT();
977     }
978 };
979 
980 /*!--------------------------------------------------------------------------*
981   @brief        レンダーキューに基づいて描画を行います。
982  *---------------------------------------------------------------------------*/
983 void
RenderScene()984 RenderScene()
985 {
986     nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
987     nw::gfx::RenderQueue* renderQueue = s_RenderSystem->GetRenderQueue();
988     nw::gfx::MeshRenderer* meshRenderer = s_RenderSystem->GetMeshRenderer();
989 
990     std::for_each(
991         renderQueue->Begin(),
992         renderQueue->End(),
993         RenderSceneInternalFunctor(renderContext, meshRenderer));
994 
995     NW_GL_ASSERT();
996 }
997 
998 /*!--------------------------------------------------------------------------*
999   @brief        負荷表示やテスト機能の処理をおこないます。
1000  *---------------------------------------------------------------------------*/
1001 void
ReportDemo()1002 ReportDemo()
1003 {
1004     NW_PROFILE("ReportDemo");
1005 
1006     // 負荷表示からはこれらの負荷は除きます。
1007     s_RenderSystem->SuspendLoadMeter();
1008 
1009     s_RenderSystem->AddLoadMeterCommandSize(
1010         s_EndShadowRenderCommand->GetCommandSize() - s_StartShadowRenderCommand->GetCommandSize());
1011 
1012     nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
1013 
1014     s_GraphicsDrawing.BeginDrawingShape();
1015 
1016     nw::demo::DebugUtility::DrawLoadMeter(
1017         s_RenderSystem,
1018         &s_GraphicsDrawing
1019     );
1020 
1021     s_GraphicsDrawing.EndDrawingShape();
1022 
1023     s_GraphicsDrawing.BeginDrawingString();
1024 
1025     nw::demo::DebugUtility::DrawLoadMeterText(
1026         s_RenderSystem,
1027         &s_GraphicsDrawing
1028     );
1029 
1030     s_GraphicsDrawing.EndDrawingString();
1031 
1032     s_RenderSystem->ResumeLoadMeter();
1033 }
1034 
1035 /*!--------------------------------------------------------------------------*
1036   @brief        シーンをデモンストレーションします。
1037  *---------------------------------------------------------------------------*/
1038 void
DemoScene()1039 DemoScene()
1040 {
1041     NW_ASSERT(!s_RenderTargets.empty());
1042 
1043     nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
1044 
1045     InitializeScenes();
1046 
1047     nw::demo::DebugUtility::PostInitializeScenes();
1048 
1049     bool isContinuing = true;
1050 
1051     while ( isContinuing )
1052     {
1053         nw::demo::DebugUtility::AdvanceAutoTestFrame();
1054 
1055         nw::demo::PadFactory::GetPad()->Update();
1056 
1057         UpdateScene();
1058 
1059         SubmitView();
1060 
1061         RenderScene();
1062 
1063         s_RenderSystem->ClearBySkyModel(s_BaseCamera);
1064         ReportDemo();
1065         s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
1066 
1067         s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
1068 
1069         renderContext->ResetState();
1070 
1071         if (nw::demo::Utility::IsTerminating())
1072         {
1073             isContinuing = false;
1074         }
1075     }
1076 
1077     nw::demo::DebugUtility::PreTerminateScenes();
1078 
1079     TerminateScenes();
1080 }
1081 
1082 } // namespace
1083 
1084 /*!--------------------------------------------------------------------------*
1085   @brief        メイン関数です。
1086  *---------------------------------------------------------------------------*/
1087 void
nnMain()1088 nnMain()
1089 {
1090     nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
1091 
1092     nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
1093 
1094     NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
1095     {
1096 
1097         InitializeGraphics();
1098 
1099         DemoScene();
1100 
1101         TerminateGraphics();
1102 
1103     }
1104 
1105     nw::demo::PadFactory::Finalize();
1106 
1107     nw::demo::FinalizeGraphicsSystem();
1108 }
1109