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