1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: DynamicMaterialDemo.cpp
4
5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain proprietary
8 information of Nintendo and/or its licensed developers and are protected by
9 national and international copyright laws. They may not be disclosed to third
10 parties or copied or duplicated in any form, in whole or in part, without the
11 prior written consent of Nintendo.
12
13 The content herein is highly confidential and should be handled accordingly.
14
15 $Revision: 31311 $
16 *---------------------------------------------------------------------------*/
17
18 #define NW_DEBUG_CHECK_MEMORY_LEAK
19
20 #include <nn/os.h>
21 #include <nn/fs.h>
22
23 #include <nw/types.h>
24
25 #include <nw/demo.h>
26 #include <nw/dev.h>
27 #include <nw/gfx.h>
28 #include <nw/ut.h>
29 #include <nw/anim.h>
30
31 namespace
32 {
33
34 //----------------------------------------
35 // マテリアル関係
36 // マテリアルの状態を表す UserFlag です
37 enum UserFlags
38 {
39 MATERIAL_DEFAULT_SHIFT,
40 MATERIAL_CHANGE_SHIFT,
41
42 MATERIAL_DEFAULT = 0x1 << MATERIAL_DEFAULT_SHIFT,
43 MATERIAL_CHANGE = 0x1 << MATERIAL_CHANGE_SHIFT
44 };
45
46 // Material の default が指定されたモデルのみを描画要素に加える関数オブジェクトです。
47 class IsMaterialDefaultModelFunctor : public nw::gfx::ISceneUpdater::IsVisibleModelFunctor
48 {
49 public:
IsVisible(const nw::gfx::Model * model)50 virtual bool IsVisible(const nw::gfx::Model* model)
51 {
52 return nw::ut::CheckFlag(model->GetUserParameter<u32>(), MATERIAL_DEFAULT);
53 }
54 };
55
56 // Material の change が指定されたモデルのみを描画要素に加える関数オブジェクトです。
57 class IsMaterialChangeModelFunctor : public nw::gfx::ISceneUpdater::IsVisibleModelFunctor
58 {
59 public:
IsVisible(const nw::gfx::Model * model)60 virtual bool IsVisible(const nw::gfx::Model* model)
61 {
62 return nw::ut::CheckFlag(model->GetUserParameter<u32>(), MATERIAL_CHANGE);
63 }
64 };
65
66 IsMaterialDefaultModelFunctor s_MaterialDefaultModel;
67 IsMaterialChangeModelFunctor s_MaterialChangeModel;
68
69 // マテリアルの差し替え設定を行うレンダーコマンドです。
70 class StartMaterialChangeRenderCommand : public nw::gfx::RenderCommand
71 {
72 NW_DISALLOW_COPY_AND_ASSIGN(StartMaterialChangeRenderCommand);
73
74 public:
StartMaterialChangeRenderCommand(nw::gfx::Material * changeMaterial)75 StartMaterialChangeRenderCommand(nw::gfx::Material* changeMaterial)
76 : m_ChangeMaterial(changeMaterial)
77 {}
~StartMaterialChangeRenderCommand()78 virtual ~StartMaterialChangeRenderCommand() {}
79
Invoke(nw::gfx::RenderContext * renderContext)80 virtual void Invoke(nw::gfx::RenderContext* renderContext)
81 {
82 // マテリアルを差し替えます。
83 renderContext->SetMaterial(m_ChangeMaterial);
84 renderContext->ActivateContext();
85
86 // RENDERMODE_IGNORE_MATERIAL を用いて以降のマテリアル設定を行いません。
87 renderContext->SetRenderMode(nw::gfx::RenderContext::RENDERMODE_IGNORE_MATERIAL);
88 }
89
90 private:
91 nw::gfx::Material* m_ChangeMaterial;
92 };
93
94 // マテリアルの差し替えの後処理を行うレンダーコマンドです。
95 class EndMaterialChangeRenderCommand : public nw::gfx::RenderCommand
96 {
97 NW_DISALLOW_COPY_AND_ASSIGN(EndMaterialChangeRenderCommand);
98
99 public:
EndMaterialChangeRenderCommand()100 EndMaterialChangeRenderCommand()
101 {}
~EndMaterialChangeRenderCommand()102 virtual ~EndMaterialChangeRenderCommand() {}
103
Invoke(nw::gfx::RenderContext * renderContext)104 virtual void Invoke(nw::gfx::RenderContext* renderContext)
105 {
106 renderContext->SetRenderMode(nw::gfx::RenderContext::RENDERMODE_DEFAULT);
107 }
108 };
109
110 StartMaterialChangeRenderCommand* s_StartMaterialChangeRenderCommand = NULL;
111 EndMaterialChangeRenderCommand* s_EndMaterialChangeRenderCommand = NULL;
112
113 //----------------------------------------
114 // メモリ関係
115
116 // デバイスメモリを確保するためのアロケータです。
117 nw::demo::DemoAllocator s_DeviceAllocator;
118
119 //----------------------------------------
120 // ファイル名の定義です。
121 const wchar_t* SKY_SPHERE_FILE_NAME = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
122
123 const wchar_t* MODEL_RESOURCE_FILES[] =
124 {
125 NW_DEMO_FILE_PATH(L"DynamicMaterial.bcmdl"),
126 NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
127 NW_DEMO_FILE_PATH(L"FragmentLight.bcenv"),
128 };
129
130 //----------------------------------------
131 // 描画関係
132 const int RENDER_TARGET_COUNT = 1;
133 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
134
135 RenderTargetArray s_RenderTargets;
136 nw::demo::SceneSystem* s_SceneSystem = NULL;
137 nw::demo::RenderSystem* s_RenderSystem = NULL;
138
139 nw::demo::GraphicsDrawing s_GraphicsDrawing;
140
141 //----------------------------------------
142 // リソース関係
143 nw::demo::ResourceArray s_Resources;
144 nw::demo::ResourceSet s_LutResource;
145 nw::demo::ResourceSet s_TextureResource;
146
147 static const wchar_t* LUT_RESOURCE_FILE = NW_DEMO_FILE_PATH(L"Lutset.bclts");
148 static const wchar_t* TEXTURE_RESOURCE_FILE = NW_DEMO_FILE_PATH(L"Texture2.bctex");
149
150 //----------------------------------------
151 // シーン関係
152 const int SCENE_NODE_COUNT = 7;
153 nw::gfx::SceneNode* s_SceneRoot = NULL;
154 nw::gfx::SceneNode* s_ModelRoot = NULL;
155 s32 s_FrameCount = 0;
156 s32 s_ChangeFrameCount = 0;
157 const s32 s_ChangeFrame = 100;
158 bool s_ChangeMaterial = false;
159 nw::gfx::Camera* s_BaseCamera = NULL;
160 nw::gfx::Camera* s_LeftCamera = NULL;
161 nw::gfx::Camera* s_RightCamera = NULL;
162 const f32 s_fNearPlane = 0.1f;
163 f32 s_TorusTranslate = 0.0f;
164
165 nw::gfx::Model* s_BufferTorus = NULL;
166 nw::gfx::Model* s_LutTorus = NULL;
167 nw::gfx::Model* s_TextureTorus = NULL;
168 nw::gfx::Material* s_EdgeMaterial = NULL;
169
170 nw::gfx::res::ResTexture s_ChangedTexture;
171 nw::gfx::res::ResLookupTable s_ChangedLut;
172 nw::ut::FloatColor s_DiffuseColor(1.0f, 0.0f, 0.0f, 1.0f);
173
174 //----------------------------------------
175 // シーン環境関係
176 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
177
178 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
179 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
180
181 const s32 s_BaseCameraIndex = 0;
182
183 /*!--------------------------------------------------------------------------*
184 @brief グラフィックス関連の初期化を行います。
185 *---------------------------------------------------------------------------*/
186 void
InitializeGraphics()187 InitializeGraphics()
188 {
189 nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
190
191 // renderDescriptionへステレオの設定を行います。
192 nw::demo::RenderSystem::Description renderDescription;
193
194 renderDescription.reusableCommandBufferSize = 0x100000;
195 renderDescription.reusableCommandRequestCount = 512;
196 renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
197
198 s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
199
200 s_GraphicsDrawing.SetScreenSize(
201 renderDescription.lowerScreenDescription.width,
202 renderDescription.lowerScreenDescription.height
203 );
204
205 nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
206
207 s_RenderTargets.push_back(
208 nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
209 );
210 NW_ASSERT(!s_RenderTargets.empty());
211 s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
212
213 // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
214 nw::demo::SceneSystem::Description sceneDescription;
215 sceneDescription.isFixedSizeMemory = true;
216 s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
217
218 // デモ用の最遠景モデルをレンダリングシステムに設定します。
219 // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
220 s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
221
222 NW_GL_ASSERT();
223 }
224
225 /*!--------------------------------------------------------------------------*
226 @brief グラフィックス関連の後始末をします。
227 *---------------------------------------------------------------------------*/
228 void
TerminateGraphics()229 TerminateGraphics()
230 {
231 nw::gfx::SafeDestroy(s_LeftCamera);
232
233 nw::gfx::SafeDestroy(s_RightCamera);
234
235 nw::gfx::SafeDestroy(s_SceneSystem);
236
237 nw::gfx::SafeDestroyAll(s_RenderTargets);
238
239 s_GraphicsDrawing.Finalize();
240
241 nw::gfx::SafeDestroy(s_RenderSystem);
242
243 NW_GL_ASSERT();
244 }
245
246 /*!--------------------------------------------------------------------------*
247 @brief ルートノード関連の構築をします。
248 *---------------------------------------------------------------------------*/
249 void
BuildRootNodes()250 BuildRootNodes()
251 {
252 NW_ASSERT(s_SceneRoot == NULL);
253 s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
254 .Create(&s_DeviceAllocator);
255 NW_NULL_ASSERT(s_SceneRoot);
256
257 NW_ASSERT(s_ModelRoot == NULL);
258 s_ModelRoot = nw::gfx::TransformNode::DynamicBuilder()
259 .Create(&s_DeviceAllocator);
260 s_SceneRoot->AttachChild(s_ModelRoot);
261 NW_NULL_ASSERT(s_ModelRoot);
262 }
263
264 /*!--------------------------------------------------------------------------*
265 @brief カメラ関連の構築をします。
266 *---------------------------------------------------------------------------*/
267 void
BuildCameras()268 BuildCameras()
269 {
270 nw::demo::Utility::CreateStereoCameras(
271 &s_BaseCamera,
272 &s_LeftCamera,
273 &s_RightCamera,
274 &s_DeviceAllocator,
275 nw::math::VEC3(0.0f, 2.25f, 10.0f),
276 nw::math::VEC3(0.0f, 2.25f, 0.0f),
277 s_fNearPlane
278 );
279
280 s_SceneRoot->AttachChild(s_BaseCamera);
281 s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
282 }
283
284 /*!--------------------------------------------------------------------------*
285 @brief リソース関連の構築をします。
286 *---------------------------------------------------------------------------*/
287 void
BuildResources(nw::demo::ResourceSet * resourceSet)288 BuildResources(nw::demo::ResourceSet* resourceSet)
289 {
290 resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
291 resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
292 resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
293
294 nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
295 if (result.IsFailure())
296 {
297 if (result.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT)
298 {
299 // 参照テーブルが見つからなかったときは、外部ファイルを指定して再びセットアップします。
300 result = resourceSet->resource.Setup(&s_DeviceAllocator, s_LutResource.resource);
301 }
302
303 if (result.IsFailure())
304 {
305 NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
306 }
307 }
308
309 nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(SCENE_NODE_COUNT, &s_DeviceAllocator);
310
311 nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
312 nw::gfx::ResModelArray::iterator modelsEnd = models.end();
313 for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
314 modelResource != modelsEnd; ++modelResource)
315 {
316 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
317 &s_DeviceAllocator,
318 (*modelResource),
319 false
320 );
321 NW_NULL_ASSERT(node);
322
323 nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(node);
324 NW_NULL_ASSERT(model);
325
326 if (::std::strcmp(model->GetName(), "Edge") == 0)
327 {
328 model->SetVisible(false);
329 s_EdgeMaterial = model->GetMaterial(0);
330 }
331 else if(::std::strcmp(model->GetName(), "LutTorus") == 0)
332 {
333 model->Transform().SetTranslate(0.0f, s_TorusTranslate, 0.0f);
334 model->SetUserParameter(MATERIAL_DEFAULT);
335 s_TorusTranslate += 1.5f;
336 s_LutTorus = model;
337 }
338 else if(::std::strcmp(model->GetName(), "TextureTorus") == 0)
339 {
340 model->Transform().SetTranslate(0.0f, s_TorusTranslate, 0.0f);
341 model->SetUserParameter(MATERIAL_DEFAULT);
342 s_TorusTranslate += 1.5f;
343 s_TextureTorus = model;
344 }
345 else if(::std::strcmp(model->GetName(), "Torus") == 0)
346 {
347 nw::gfx::Model* changeModel = nw::ut::DynamicCast<nw::gfx::Model*>(node);
348 NW_NULL_ASSERT(changeModel);
349
350 changeModel->Transform().SetTranslate(0.0f, s_TorusTranslate, 0.0f);
351 s_TorusTranslate += 1.5f;
352 changeModel->SetUserParameter(MATERIAL_CHANGE);
353
354 // バッファオプションを指定してモデルを生成します。
355 nw::gfx::SceneNode* bufferNode = nw::demo::Utility::CreateSceneNode(
356 &s_DeviceAllocator,
357 (*modelResource),
358 false,
359 nw::gfx::Model::FLAG_BUFFER_MATERIAL_COLOR
360 );
361 NW_NULL_ASSERT(bufferNode);
362
363 nw::gfx::Model* bufferModel = nw::ut::DynamicCast<nw::gfx::Model*>(bufferNode);
364 NW_NULL_ASSERT(bufferModel);
365
366 bufferModel->Transform().SetTranslate(0.0f, s_TorusTranslate, 0.0f);
367 s_TorusTranslate += 1.5f;
368 s_BufferTorus = bufferModel;
369 bufferModel->SetUserParameter(MATERIAL_DEFAULT);
370 sceneNodeArray.push_back(bufferNode);
371 }
372
373 sceneNodeArray.push_back(node);
374 }
375
376 nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
377 nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
378 for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
379 lightResource != lightsEnd; ++lightResource)
380 {
381 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
382 &s_DeviceAllocator,
383 (*lightResource)
384 );
385 NW_NULL_ASSERT(node);
386 sceneNodeArray.push_back(node);
387 }
388
389 // 親子付け参照関係を解決
390 nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
391
392 // モデルをシーンに追加
393 nw::gfx::SceneHelper::ForeachRootNodes(
394 sceneNodeArray.Begin(),
395 sceneNodeArray.End(),
396 nw::gfx::AttachNode(s_ModelRoot)
397 );
398
399 nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
400 nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
401 for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
402 settingResource != settingsEnd; ++settingResource)
403 {
404 nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
405 .Resource(*settingResource)
406 .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
407
408 nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
409 nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
410
411 NW_NULL_ASSERT(sceneEnvironmentSetting);
412 s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
413 }
414 }
415
416 /*!--------------------------------------------------------------------------*
417 @brief シーンを初期化します。
418 *---------------------------------------------------------------------------*/
419 void
InitializeScenes()420 InitializeScenes()
421 {
422 // ファイルから LUT Set を読み込みます。
423 s_LutResource.buffer = nw::demo::Utility::LoadFile(&s_DeviceAllocator , LUT_RESOURCE_FILE);
424 NW_NULL_ASSERT(s_LutResource.buffer);
425 s_LutResource.resource = nw::gfx::ResGraphicsFile(&(s_LutResource.buffer.front()));
426 s_LutResource.resource.Setup(&s_DeviceAllocator);
427 s_ChangedLut = s_LutResource.resource.GetLutSets(0).GetSamplers("toon_reflectance");
428
429 s_TextureResource.buffer = nw::demo::Utility::LoadFile(&s_DeviceAllocator, TEXTURE_RESOURCE_FILE);
430 NW_NULL_ASSERT(s_TextureResource.buffer);
431 s_TextureResource.resource = nw::gfx::ResGraphicsFile(&(s_TextureResource.buffer.front()));
432 s_TextureResource.resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
433 s_TextureResource.resource.Setup(&s_DeviceAllocator);
434 s_ChangedTexture = s_TextureResource.resource.GetTextures(0);
435
436 BuildRootNodes();
437
438 BuildCameras();
439
440 s_TorusTranslate = 0.0f;
441 NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
442 {
443 BuildResources(nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator));
444 }
445
446 // シーンツリーを巡回して初期化を行います。
447 s_SceneSystem->InitializeScene(s_SceneRoot);
448 s_SceneSystem->UpdateScene();
449
450 // シーン環境の参照解決を行い設定します。
451 s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
452
453 // カメラを設定します。
454 nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
455 sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
456 nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
457
458 // レンダーコマンドを作成します。
459 void* startMaterialChangeCommandMemory = s_DeviceAllocator.Alloc(sizeof(StartMaterialChangeRenderCommand));
460 NW_NULL_ASSERT(startMaterialChangeCommandMemory);
461 s_StartMaterialChangeRenderCommand =
462 new(startMaterialChangeCommandMemory) StartMaterialChangeRenderCommand(s_EdgeMaterial);
463
464 void* endMaterialChangeCommandMemory = s_DeviceAllocator.Alloc(sizeof(EndMaterialChangeRenderCommand));
465 NW_NULL_ASSERT(endMaterialChangeCommandMemory);
466 s_EndMaterialChangeRenderCommand =
467 new(endMaterialChangeCommandMemory) EndMaterialChangeRenderCommand();
468
469 NW_GL_ASSERT();
470
471 s_FrameCount = 0;
472 }
473
474 /*!--------------------------------------------------------------------------*
475 @brief シーン関連の後始末をします。
476 *---------------------------------------------------------------------------*/
477 void
TerminateScenes()478 TerminateScenes()
479 {
480 s_DeviceAllocator.Free(s_EndMaterialChangeRenderCommand);
481 s_EndMaterialChangeRenderCommand = NULL;
482 s_DeviceAllocator.Free(s_StartMaterialChangeRenderCommand);
483 s_StartMaterialChangeRenderCommand = NULL;
484
485 s_LutTorus = NULL;
486 s_TextureTorus = NULL;
487 s_EdgeMaterial = NULL;
488 s_BufferTorus = NULL;
489
490 nw::gfx::SafeDestroyBranch(s_SceneRoot);
491 nw::demo::SafeCleanupResources(s_Resources);
492 nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings);
493
494 nw::ut::SafeCleanup(s_TextureResource.resource);
495 nw::ut::SafeCleanup(s_LutResource.resource);
496
497 NW_GL_ASSERT();
498
499 s_TextureResource.buffer = nw::ut::MoveArray<u8>();
500 s_LutResource.buffer = nw::ut::MoveArray<u8>();
501
502 s_Resources.clear();
503 s_SceneEnvironmentSettings.clear();
504
505 s_ModelRoot = NULL;
506 }
507
508 /*!--------------------------------------------------------------------------*
509 @brief シーンを更新します。
510 それぞのモデルのマテリアルの変更を行います。
511 *---------------------------------------------------------------------------*/
512 void
ChangeMaterial()513 ChangeMaterial()
514 {
515 if (s_ChangeFrameCount > s_ChangeFrame)
516 {
517 // torus のマテリアルカラーを変更します。
518 // マテリアルバッファを用いているためにベースとなる torus の色は変更されません。
519 {
520 nw::gfx::res::ResMaterial resTorusMaterial = s_BufferTorus->GetMaterial(0)->GetMaterialColorResMaterial();
521 NW_ASSERT(resTorusMaterial.IsValid());
522 nw::gfx::res::ResMaterialColor resMaterialColor = resTorusMaterial.GetMaterialColor();
523 nw::ut::FloatColor floatColor = resMaterialColor.GetDiffuse();
524 resMaterialColor.SetDiffuse(s_DiffuseColor);
525 s_DiffuseColor = floatColor;
526
527 // NOTE: マテリアルバッファはハッシュが無効になっていますので、0x0 を設定する必要はありません。
528 // resTorusMaterial.SetMaterialColorHash(0x0);
529 }
530
531 // texture_torus のテクスチャを差し替えます。
532 {
533 nw::gfx::res::ResMaterial resTorusMaterial = s_TextureTorus->GetMaterial(0)->GetTextureMapperResMaterial();
534 NW_ASSERT(resTorusMaterial.IsValid());
535 nw::gfx::res::ResTextureMapper resTextureMapper = resTorusMaterial.GetTextureMappers(0);
536 nw::gfx::res::ResTexture resTexture = resTextureMapper.GetTexture().Dereference();
537 resTextureMapper.SetTexture(s_ChangedTexture);
538 s_ChangedTexture = resTexture;
539
540 // テクスチャを変更した場合はテクスチャマッパーのハッシュを0に設定します。
541 resTorusMaterial.SetTextureMappersHash(0x0);
542 }
543
544 // lut_torus の参照テーブルを差し替えます。
545 {
546 nw::gfx::res::ResMaterial resTorusMaterial = s_LutTorus->GetMaterial(0)->GetFragmentLightingTableResMaterial();
547 NW_ASSERT(resTorusMaterial.IsValid());
548 nw::gfx::res::ResFragmentLightingTable resFragmentLightingLut = resTorusMaterial.GetFragmentShader().GetFragmentLightingTable();
549 nw::gfx::res::ResLightingLookupTable resLightingLut = resFragmentLightingLut.GetReflectanceRSampler();
550 nw::gfx::res::ResLookupTable resLut = resLightingLut.GetSampler().Dereference();
551 resLightingLut.SetSampler(s_ChangedLut);
552 s_ChangedLut = resLut;
553
554 // 参照テーブルを変更した場合はフラグメントライティングテーブルのハッシュを0に設定します。
555 resTorusMaterial.SetFragmentLightingTableHash(0x0);
556 }
557 }
558 }
559
560 /*!--------------------------------------------------------------------------*
561 @brief レンダーキューにモデルの追加を行います。
562 独自マテリアルでの描画を行うためにコールバックの設定をします。
563 *---------------------------------------------------------------------------*/
564 void
SubmitView()565 SubmitView()
566 {
567 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
568 nw::gfx::SceneEnvironment& sceneEnvironment = renderContext->GetSceneEnvironment();
569 nw::gfx::SceneContext* sceneContext = s_SceneSystem->GetSceneContext();
570
571 nw::gfx::RenderQueue* renderQueue = s_RenderSystem->GetRenderQueue();
572
573 renderQueue->Reset();
574
575 s_SceneSystem->GetSceneUpdater()->SubmitView(
576 renderQueue,
577 sceneContext,
578 *s_BaseCamera,
579 0,
580 1,
581 &s_MaterialDefaultModel,
582 s_RenderSystem->GetRenderSortMode());
583
584 if (s_ChangeMaterial)
585 {
586 // マテリアルの変更を行うコマンドをレイヤー1の後に実行するコールバックに追加します。
587 s_RenderSystem->EnqueueRenderCommand(
588 s_StartMaterialChangeRenderCommand, nw::gfx::res::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 0, 1);
589 }
590
591 s_SceneSystem->GetSceneUpdater()->SubmitView(
592 renderQueue,
593 sceneContext,
594 *s_BaseCamera,
595 2,
596 2,
597 &s_MaterialChangeModel,
598 s_RenderSystem->GetRenderSortMode());
599
600 if (s_ChangeMaterial)
601 {
602 // マテリアルの変更の後処理行うコマンドをレイヤー2の後に実行するコールバックに追加します。
603 s_RenderSystem->EnqueueRenderCommand(
604 s_EndMaterialChangeRenderCommand, nw::gfx::res::ResMaterial::TRANSLUCENCY_KIND_OPAQUE, 0, 2);
605 }
606
607 // レンダーキューをソートします。
608 // RenderElementCompare() やレンダーキーファクトリーをカスタマイズすることで
609 // 描画順を変更することができます。
610 // 詳しくは最適化TIPSを参照してください。
611 std::sort(
612 renderQueue->Begin(),
613 renderQueue->End(),
614 nw::gfx::RenderElementCompare());
615 }
616
617 /*!--------------------------------------------------------------------------*
618 @brief シーンを更新します。
619 *---------------------------------------------------------------------------*/
620 void
UpdateScene()621 UpdateScene()
622 {
623 s_SceneSystem->GetCameraController()->Update();
624
625 s_SceneSystem->UpdateScene();
626
627 s_BaseCamera->UpdateCameraMatrix();
628
629 s_RenderSystem->CalcStereoCamera(s_LeftCamera, s_RightCamera, s_BaseCamera, s_fNearPlane + 5.0f);
630
631 ++s_FrameCount;
632 }
633
634 /*!--------------------------------------------------------------------------*
635 @brief 負荷表示やテスト機能の処理をおこないます。
636 *---------------------------------------------------------------------------*/
637 void
ReportDemo()638 ReportDemo()
639 {
640 NW_PROFILE("ReportDemo");
641
642 // 負荷表示からはこれらの負荷は除きます。
643 s_RenderSystem->SuspendLoadMeter();
644
645 nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
646
647 s_GraphicsDrawing.BeginDrawingShape();
648
649 nw::demo::DebugUtility::DrawLoadMeter(
650 s_RenderSystem,
651 &s_GraphicsDrawing
652 );
653
654 s_GraphicsDrawing.EndDrawingShape();
655
656 s_GraphicsDrawing.BeginDrawingString();
657
658 nw::demo::DebugUtility::DrawLoadMeterText(
659 s_RenderSystem,
660 &s_GraphicsDrawing
661 );
662
663 s_GraphicsDrawing.EndDrawingString();
664
665 s_RenderSystem->ResumeLoadMeter();
666 }
667
668 /*!--------------------------------------------------------------------------*
669 @brief シーンをデモンストレーションします。
670 *---------------------------------------------------------------------------*/
671 void
DemoScene()672 DemoScene()
673 {
674 NW_ASSERT(!s_RenderTargets.empty());
675
676 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
677
678 InitializeScenes();
679
680 nw::demo::DebugUtility::PostInitializeScenes();
681
682 bool isContinuing = true;
683
684 while ( isContinuing )
685 {
686 nw::demo::DebugUtility::AdvanceAutoTestFrame();
687
688 nw::demo::PadFactory::GetPad()->Update();
689
690 UpdateScene();
691
692 // マテリアルの変更を行います。
693 ChangeMaterial();
694
695 renderContext->SetActiveCamera(s_BaseCameraIndex);
696
697 // レンダーキューへのモデルの追加を行います。
698 // 独自マテリアルでの描画を行うためにカスタマイズします。
699 SubmitView();
700
701 s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
702 s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
703
704 s_RenderSystem->ClearBySkyModel(s_BaseCamera);
705 ReportDemo();
706 s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
707
708 s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
709
710 renderContext->ResetState();
711
712 if (nw::demo::Utility::IsTerminating())
713 {
714 isContinuing = false;
715 }
716
717 if (s_ChangeFrameCount > s_ChangeFrame)
718 {
719 s_ChangeMaterial = !s_ChangeMaterial;
720 s_ChangeFrameCount = 0;
721 }
722
723 ++s_ChangeFrameCount;
724 }
725
726 nw::demo::DebugUtility::PreTerminateScenes();
727
728 TerminateScenes();
729 }
730
731 } // namespace
732
733 /*!--------------------------------------------------------------------------*
734 @brief メイン関数です。
735 *---------------------------------------------------------------------------*/
736 void
nnMain()737 nnMain()
738 {
739 nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
740
741 nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
742
743 NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
744 {
745 InitializeGraphics();
746
747 DemoScene();
748
749 TerminateGraphics();
750 }
751
752 nw::demo::PadFactory::Finalize();
753
754 nw::demo::FinalizeGraphicsSystem();
755 }
756