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