1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_Material.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: 29206 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/gfx/gfx_Material.h>
19 #include <nw/gfx/gfx_Model.h>
20 #include <nw/gfx/res/gfx_ResMaterial.h>
21 #include <nw/gfx/res/gfx_ResShader.h>
22 #include <nw/gfx/gfx_AnimObject.h>
23
24 namespace
25 {
GetAvailableResMaterial(nw::gfx::Material * material,nw::gfx::Model::BufferOption bufferOption)26 nw::gfx::ResMaterial GetAvailableResMaterial(
27 nw::gfx::Material* material, nw::gfx::Model::BufferOption bufferOption)
28 {
29 return nw::ut::CheckFlag(material->GetOwnerModel()->GetBufferOption(), bufferOption)
30 ? material->GetBuffer()
31 : material->GetOriginal();
32 }
33 }
34
35 namespace nw
36 {
37 namespace gfx
38 {
39
40 NW_UT_RUNTIME_TYPEINFO_DEFINITION(Material, SceneObject);
41
42 //----------------------------------------
Material(os::IAllocator * allocator,ResMaterial resMaterial,s32 bufferCount,Model * owner)43 Material::Material(
44 os::IAllocator* allocator,
45 ResMaterial resMaterial,
46 s32 bufferCount,
47 Model* owner)
48 : SceneObject(
49 allocator,
50 resMaterial),
51 m_Owner(owner),
52 m_BufferCount(bufferCount)
53 {
54 ResBinaryShader resShader = resMaterial.GetShader().Dereference();
55
56 NW_ASSERT(resShader.IsValid());
57 m_ProgramDescription =
58 resShader.GetDescriptions(resMaterial.GetShaderProgramDescriptionIndex());
59 }
60
61 //----------------------------------------
62 Material*
Create(ResMaterial resource,s32 bufferCount,Model * parent,os::IAllocator * allocator)63 Material::Create(
64 ResMaterial resource,
65 s32 bufferCount,
66 Model* parent,
67 os::IAllocator* allocator
68 )
69 {
70 NW_NULL_ASSERT(allocator);
71 NW_ASSERT(resource.IsValid());
72
73 // マテリアルバッファは1つのみ作成可能です。
74 NW_ASSERTMSG(bufferCount <= 1, "Material Buffer Count must be 0 or 1.");
75
76 void* memory = allocator->Alloc(sizeof(Material));
77 if (memory == NULL)
78 {
79 return NULL;
80 }
81
82 Material* material = new(memory) Material(
83 allocator,
84 resource,
85 bufferCount,
86 parent);
87
88 Result result = material->Initialize(allocator);
89 if (result.IsSuccess())
90 {
91 material->m_ShaderParameterResMaterial =
92 GetAvailableResMaterial(material, Model::FLAG_BUFFER_SHADER_PARAMETER);
93 material->m_ShadingParameterResMaterial =
94 GetAvailableResMaterial(material, Model::FLAG_BUFFER_SHADING_PARAMETER);
95 material->m_MaterialColorResMaterial =
96 GetAvailableResMaterial(material, Model::FLAG_BUFFER_MATERIAL_COLOR);
97 material->m_RasterizationResMaterial =
98 GetAvailableResMaterial(material, Model::FLAG_BUFFER_RASTERIZATION);
99 material->m_TextureCoordinatorResMaterial =
100 GetAvailableResMaterial(material, Model::FLAG_BUFFER_TEXTURE_COORDINATOR);
101 material->m_TextureMapperResMaterial =
102 GetAvailableResMaterial(material, Model::FLAG_BUFFER_TEXTURE_MAPPER);
103 material->m_FragmentLightingResMaterial =
104 GetAvailableResMaterial(material, Model::FLAG_BUFFER_FRAGMENT_LIGHTING);
105 material->m_FragmentLightingTableResMaterial =
106 GetAvailableResMaterial(material, Model::FLAG_BUFFER_FRAGMENT_LIGHTING_TABLE);
107 material->m_TextureCombinerResMaterial =
108 GetAvailableResMaterial(material, Model::FLAG_BUFFER_TEXTURE_COMBINER);
109 material->m_AlphaTestResMaterial =
110 GetAvailableResMaterial(material, Model::FLAG_BUFFER_ALPHA_TEST);
111 material->m_FragmentOperationResMaterial =
112 GetAvailableResMaterial(material, Model::FLAG_BUFFER_FRAGMENT_OPERATION);
113 material->m_SceneEnvironmentResMaterial =
114 GetAvailableResMaterial(material, Model::FLAG_BUFFER_SCENE_ENVIRONMENT);
115 return material;
116 }
117 else
118 {
119 SafeDestroy(material);
120 return NULL;
121 }
122 }
123
124 //----------------------------------------
125 void
GetMemorySizeInternal(os::MemorySizeCalculator * pSize,ResMaterial resMaterial,s32 bufferCount,bit32 bufferOption)126 Material::GetMemorySizeInternal(
127 os::MemorySizeCalculator* pSize,
128 ResMaterial resMaterial,
129 s32 bufferCount,
130 bit32 bufferOption)
131 {
132 os::MemorySizeCalculator& size = *pSize;
133
134 // Material::Create
135 size += sizeof(Material);
136
137 // Material::Initialize
138
139 // Material::CreateBuffers
140 size += sizeof(ResMaterial) * bufferCount;
141 if (bufferCount > 0)
142 {
143 // TODO: 要検証
144 // Material::CopyResMaterial
145 os::MemorySizeCalculator bufferSize(size.GetAlignment());
146
147 bufferSize += sizeof(ResMaterialData);
148
149 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_SHADER_PARAMETER))
150 {
151 bufferSize += sizeof(ut::Offset) * resMaterial.GetShaderParametersCount();
152
153 for (int i = 0; i < resMaterial.GetShaderParametersCount(); ++i)
154 {
155 const int parameterLength = resMaterial.GetShaderParameters(i).GetParameterLength();
156
157 bufferSize += sizeof(ResShaderParameterData) + sizeof(f32) * (parameterLength - 1);
158 }
159 }
160
161 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_TEXTURE_MAPPER))
162 {
163 for (int i = 0; i < resMaterial.GetTextureMappersCount(); i++)
164 {
165 ResPixelBasedTextureMapper resTextureMapper = resMaterial.GetTextureMappers(i);
166 if (resTextureMapper.IsValid())
167 {
168 resTextureMapper.GetMemorySizeForCloneInternal(&bufferSize);
169 }
170 }
171 }
172
173 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_PROCEDURAL_TEXTURE_MAPPER))
174 {
175 ResProceduralTextureMapper resTextureMapper = resMaterial.GetProceduralTextureMapper();
176 if (resTextureMapper.IsValid())
177 {
178 resTextureMapper.GetMemorySizeForCloneInternal(&bufferSize);
179 }
180 }
181
182 if (ut::CheckFlagOr(bufferOption, Model::MULTI_FLAG_BUFFER_FRAGMENT_SHADER))
183 {
184 if (resMaterial.GetFragmentShader().IsValid())
185 {
186 bufferSize += sizeof(ResFragmentShaderData);
187
188 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_FRAGMENT_LIGHTING_TABLE))
189 {
190 // Material::CopyResFragmentLightingTable
191 ResFragmentShader resFragmentShader = resMaterial.GetFragmentShader();
192
193 if (resFragmentShader.GetFragmentLightingTable().IsValid())
194 {
195 ResFragmentLightingTable resFragmentLightingTable =
196 resFragmentShader.GetFragmentLightingTable();
197
198 bufferSize += sizeof(ResFragmentLightingTableData);
199 if (resFragmentLightingTable.GetReflectanceRSampler().IsValid())
200 {
201 bufferSize += sizeof(ResLightingLookupTableData);
202 bufferSize += sizeof(ResReferenceLookupTableData);
203 }
204 if (resFragmentLightingTable.GetReflectanceGSampler().IsValid())
205 {
206 bufferSize += sizeof(ResLightingLookupTableData);
207 bufferSize += sizeof(ResReferenceLookupTableData);
208 }
209 if (resFragmentLightingTable.GetReflectanceBSampler().IsValid())
210 {
211 bufferSize += sizeof(ResLightingLookupTableData);
212 bufferSize += sizeof(ResReferenceLookupTableData);
213 }
214 if (resFragmentLightingTable.GetDistribution0Sampler().IsValid())
215 {
216 bufferSize += sizeof(ResLightingLookupTableData);
217 bufferSize += sizeof(ResReferenceLookupTableData);
218 }
219 if (resFragmentLightingTable.GetDistribution1Sampler().IsValid())
220 {
221 bufferSize += sizeof(ResLightingLookupTableData);
222 bufferSize += sizeof(ResReferenceLookupTableData);
223 }
224 if (resFragmentLightingTable.GetFresnelSampler().IsValid())
225 {
226 bufferSize += sizeof(ResLightingLookupTableData);
227 bufferSize += sizeof(ResReferenceLookupTableData);
228 }
229 }
230 }
231 }
232 }
233
234 bufferSize *= bufferCount;
235 size += bufferSize.GetSizeWithPadding(size.GetAlignment());
236 }
237 }
238
239 //----------------------------------------
~Material()240 Material::~Material()
241 {
242 std::for_each(
243 m_Buffers.begin(), m_Buffers.end(), ResMaterialDestroyer(&this->GetAllocator()));
244 }
245
246 //----------------------------------------
247 bool
CanUseBuffer(u32 objectType) const248 Material::CanUseBuffer(u32 objectType) const
249 {
250 if (0 < m_BufferCount)
251 {
252 bit32 option = this->GetOwnerModel()->GetBufferOption();
253 switch (objectType)
254 {
255 case anim::ResAnimGroupMember::OBJECT_TYPE_MATERIAL_COLOR:
256 return ut::CheckFlag(option, Model::FLAG_BUFFER_MATERIAL_COLOR);
257 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_SAMPLER:
258 return ut::CheckFlag(option, Model::FLAG_BUFFER_TEXTURE_MAPPER);
259 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_MAPPER:
260 return ut::CheckFlag(option, Model::FLAG_BUFFER_TEXTURE_MAPPER);
261 case anim::ResAnimGroupMember::OBJECT_TYPE_BLEND_OPERATION:
262 return ut::CheckFlag(option, Model::FLAG_BUFFER_FRAGMENT_OPERATION);
263 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_COORDINATOR:
264 return ut::CheckFlag(option, Model::FLAG_BUFFER_TEXTURE_COORDINATOR);
265 default:
266 NW_ASSERT(false);
267 }
268 }
269 return false;
270 }
271
272 //-----------------------------------------
273 Result
CreateBuffers(os::IAllocator * allocator)274 Material::CreateBuffers(os::IAllocator* allocator)
275 {
276 Result result = INITIALIZE_RESULT_OK;
277
278 NW_NULL_ASSERT(this->m_Owner);
279 bit32 bufferOption = m_Owner->GetBufferOption();
280
281 if (m_BufferCount != 0)
282 {
283 void* memory = allocator->Alloc(sizeof(ResMaterial) * m_BufferCount);
284 if (memory == NULL)
285 {
286 result |= Result::MASK_FAIL_BIT;
287 }
288
289 NW_ENSURE_AND_RETURN(result);
290
291 m_Buffers = ResMaterialArray(memory, m_BufferCount, allocator);
292
293 for (int bufferIndex = 0; bufferIndex < m_BufferCount; bufferIndex++)
294 {
295 NW_ENSURE_AND_RETURN(result);
296 ::std::pair<ResMaterial, Result> copyResult = this->CopyResMaterial(allocator, bufferOption);
297
298 if (copyResult.second.IsSuccess())
299 {
300 m_Buffers.PushBackFast(copyResult.first);
301 }
302 else
303 {
304 DestroyResMaterial(allocator, copyResult.first);
305 result |= Result::MASK_FAIL_BIT;
306 }
307 }
308 }
309
310 return result;
311 }
312
313 //-----------------------------------------
314 ::std::pair<ResMaterial, Result>
CopyResMaterial(os::IAllocator * allocator,bit32 bufferOption)315 Material::CopyResMaterial(
316 os::IAllocator* allocator,
317 bit32 bufferOption)
318 {
319 Result result = INITIALIZE_RESULT_OK;
320
321 ResMaterial resMaterial = this->GetOriginal();
322
323 void* materialMemory = allocator->Alloc(sizeof(ResMaterialData));
324 if (materialMemory == NULL)
325 {
326 result |= Result::MASK_FAIL_BIT;
327 return ::std::make_pair(ResMaterial(NULL), result);
328 }
329
330 ResMaterialData* buffer =
331 new(materialMemory) ResMaterialData(this->GetOriginal().ref());
332
333 ResMaterial copyMaterial = ResMaterial(buffer);
334
335 // 判定に用いるために NULL でクリアしておく
336 buffer->toName.set_ptr(NULL);
337 buffer->toShader.set_ptr(NULL);
338 buffer->m_ShaderParametersTableCount = 0;
339 buffer->toShaderParametersTable.set_ptr(NULL);
340 buffer->toTextureMappers[0].set_ptr(NULL);
341 buffer->toTextureMappers[1].set_ptr(NULL);
342 buffer->toTextureMappers[2].set_ptr(NULL);
343 buffer->toProceduralTextureMapper.set_ptr(NULL);
344 buffer->toFragmentShader.set_ptr(NULL);
345
346 // ハッシュ無効化
347 buffer->m_AlphaTestHash = 0x0;
348 buffer->m_FragmentLightingHash = 0x0;
349 buffer->m_FragmentLightingTableHash = 0x0;
350 buffer->m_FragmentLightingTableParametersHash = 0x0;
351 buffer->m_FragmentOperationHash = 0x0;
352 buffer->m_MaterialColorHash = 0x0;
353 buffer->m_RasterizationHash = 0x0;
354 buffer->m_ShaderParametersHash = 0x0;
355 buffer->m_ShadingParameterHash = 0x0;
356 buffer->m_TextureCombinersHash = 0x0;
357 buffer->m_TextureCoordinatorsHash = 0x0;
358 buffer->m_TextureMappersHash = 0x0;
359 buffer->m_TextureSamplersHash = 0x0;
360
361 // シェーダーパラメータのコピー
362 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_SHADER_PARAMETER))
363 {
364 buffer->m_ShaderParametersTableCount = resMaterial.GetShaderParametersCount();
365
366 ut::Offset* offsets = NULL;
367 if (buffer->m_ShaderParametersTableCount != 0)
368 {
369 offsets = allocator->AllocAndConstruct<ut::Offset>(resMaterial.GetShaderParametersCount());
370
371 if (offsets == NULL)
372 {
373 result |= Result::MASK_FAIL_BIT;
374 return ::std::make_pair(copyMaterial, result);
375 }
376
377 buffer->toShaderParametersTable.set_ptr(offsets);
378 }
379
380 // メモリ解放を容易にするために NULL で初期化しておく
381 for (int i = 0; i < resMaterial.GetShaderParametersCount(); i++)
382 {
383 offsets[i].set_ptr(NULL);
384 }
385
386 for (int i = 0; i < resMaterial.GetShaderParametersCount(); i++)
387 {
388 ResShaderParameter resShaderParameter = resMaterial.GetShaderParameters(i);
389 ResShaderParameterValue resShaderParameterValue = resShaderParameter.GetParameter();
390
391 const int parameterLength = resShaderParameter.GetParameterLength();
392
393 // sizeof(ResShaderParameterData)で32ビット分の Value の領域が確保されるので-1をする。
394 void* parameterMemory = allocator->Alloc(sizeof(ResShaderParameterData) + sizeof(f32) * (parameterLength - 1));
395 if (parameterMemory == NULL)
396 {
397 result |= Result::MASK_FAIL_BIT;
398 return ::std::make_pair(copyMaterial, result);
399 }
400
401 ResShaderParameterData* shaderParameter = static_cast<ResShaderParameterData*>(parameterMemory);
402 *shaderParameter = ResShaderParameterData(resShaderParameter.ref());
403
404 for (int j = 0; j < parameterLength; ++j)
405 {
406 shaderParameter->m_Parameter.m_Value[j] = resShaderParameterValue.ref().m_Value[j];
407 }
408
409 offsets[i].set_ptr(shaderParameter);
410 }
411 }
412
413 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_TEXTURE_MAPPER))
414 {
415 for (int i = 0; i < resMaterial.GetTextureMappersCount(); i++)
416 {
417 ResPixelBasedTextureMapper resTextureMapper = resMaterial.GetTextureMappers(i);
418 if (resTextureMapper.IsValid())
419 {
420 ResTextureMapper textureMapper = resTextureMapper.CloneDynamic(allocator);
421
422 if (!textureMapper.IsValid())
423 {
424 result |= Result::MASK_FAIL_BIT;
425 return ::std::make_pair(copyMaterial, result);
426 }
427
428 buffer->toTextureMappers[i].set_ptr(textureMapper.ptr());
429 }
430 }
431 }
432
433 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_PROCEDURAL_TEXTURE_MAPPER))
434 {
435 ResProceduralTextureMapper resTextureMapper = resMaterial.GetProceduralTextureMapper();
436 if (resTextureMapper.IsValid())
437 {
438 ResTextureMapper textureMapper = resTextureMapper.CloneDynamic(allocator);
439
440 if (!textureMapper.IsValid())
441 {
442 result |= Result::MASK_FAIL_BIT;
443 return ::std::make_pair(copyMaterial, result);
444 }
445
446 buffer->toProceduralTextureMapper.set_ptr(textureMapper.ptr());
447 }
448 }
449
450 if (ut::CheckFlagOr(bufferOption, Model::MULTI_FLAG_BUFFER_FRAGMENT_SHADER))
451 {
452 ResFragmentShader resFragmentShader = resMaterial.GetFragmentShader();
453 if (resFragmentShader.IsValid())
454 {
455 void* shaderMemory = allocator->Alloc(sizeof(ResFragmentShaderData));
456
457 if (shaderMemory == NULL)
458 {
459 result |= Result::MASK_FAIL_BIT;
460 return ::std::make_pair(copyMaterial, result);
461 }
462
463 ResFragmentShaderData* fragmentShader =
464 new(shaderMemory) ResFragmentShaderData(resFragmentShader.ref());
465
466 buffer->toFragmentShader.set_ptr(fragmentShader);
467
468 // 判定に用いるために NULL でクリアしておく
469 fragmentShader->toFragmentLightingTable.set_ptr(NULL);
470
471 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_FRAGMENT_LIGHTING_TABLE))
472 {
473 ResFragmentLightingTable resFragmentLightingTable =
474 resFragmentShader.GetFragmentLightingTable();
475 if (resFragmentLightingTable.IsValid())
476 {
477 ::std::pair<ResFragmentLightingTable, Result> copyResult =
478 this->CopyResFragmentLightingTable(allocator, resFragmentLightingTable);
479
480 fragmentShader->toFragmentLightingTable.set_ptr(copyResult.first.ptr());
481
482 if (copyResult.second.IsFailure())
483 {
484 result |= Result::MASK_FAIL_BIT;
485 return ::std::make_pair(copyMaterial, result);
486 }
487 }
488 }
489 }
490 }
491
492 return ::std::make_pair(copyMaterial, result);
493 }
494
495 //-----------------------------------------
496 void
DestroyResMaterial(os::IAllocator * allocator,ResMaterial resMaterial)497 Material::DestroyResMaterial(os::IAllocator* allocator, ResMaterial resMaterial)
498 {
499 NW_NULL_ASSERT( allocator );
500 if (resMaterial.IsValid())
501 {
502 resMaterial.Cleanup();
503
504 DestroyResFragmentShader(allocator, resMaterial.GetFragmentShader());
505
506 if (resMaterial.GetProceduralTextureMapper().IsValid())
507 {
508 resMaterial.GetProceduralTextureMapper().DestroyDynamic();
509 }
510
511 for (int i = 0; i < resMaterial.GetTextureMappersCount(); i++)
512 {
513 if (resMaterial.GetTextureMappers(i).IsValid())
514 {
515 resMaterial.GetTextureMappers(i).DestroyDynamic();
516 }
517 }
518
519 // シェーダーパラメータのメモリ解放
520 if (resMaterial.ref().toShaderParametersTable.to_ptr() != NULL)
521 {
522 for (int i = 0; i < resMaterial.GetShaderParametersCount(); i++)
523 {
524 DestroyResShaderParameter(allocator, resMaterial.GetShaderParameters(i));
525 }
526 allocator->Free(resMaterial.ref().toShaderParametersTable.to_ptr());
527 }
528
529 allocator->Free(resMaterial.ptr());
530 }
531 }
532
533 //-----------------------------------------
534 void
DestroyResFragmentShader(os::IAllocator * allocator,ResFragmentShader resFragmentShader)535 Material::DestroyResFragmentShader(
536 os::IAllocator* allocator,
537 ResFragmentShader resFragmentShader)
538 {
539 if (resFragmentShader.IsValid())
540 {
541 ResFragmentLightingTable resFragmentLightingTable = resFragmentShader.GetFragmentLightingTable();
542
543 if (resFragmentLightingTable.IsValid())
544 {
545 if (resFragmentLightingTable.GetReflectanceRSampler().IsValid())
546 {
547 allocator->Free(resFragmentLightingTable.GetReflectanceRSampler().GetSampler().ptr());
548 allocator->Free(resFragmentLightingTable.GetReflectanceRSampler().ptr());
549 }
550
551 if (resFragmentLightingTable.GetReflectanceGSampler().IsValid())
552 {
553 allocator->Free(resFragmentLightingTable.GetReflectanceGSampler().GetSampler().ptr());
554 allocator->Free(resFragmentLightingTable.GetReflectanceGSampler().ptr());
555 }
556
557 if (resFragmentLightingTable.GetReflectanceBSampler().IsValid())
558 {
559 allocator->Free(resFragmentLightingTable.GetReflectanceBSampler().GetSampler().ptr());
560 allocator->Free(resFragmentLightingTable.GetReflectanceBSampler().ptr());
561 }
562
563 if (resFragmentLightingTable.GetDistribution0Sampler().IsValid())
564 {
565 allocator->Free(resFragmentLightingTable.GetDistribution0Sampler().GetSampler().ptr());
566 allocator->Free(resFragmentLightingTable.GetDistribution0Sampler().ptr());
567 }
568
569 if (resFragmentLightingTable.GetDistribution1Sampler().IsValid())
570 {
571 allocator->Free(resFragmentLightingTable.GetDistribution1Sampler().GetSampler().ptr());
572 allocator->Free(resFragmentLightingTable.GetDistribution1Sampler().ptr());
573 }
574
575 if (resFragmentLightingTable.GetFresnelSampler().IsValid())
576 {
577 allocator->Free(resFragmentLightingTable.GetFresnelSampler().GetSampler().ptr());
578 allocator->Free(resFragmentLightingTable.GetFresnelSampler().ptr());
579 }
580
581 allocator->Free(resFragmentLightingTable.ptr());
582 }
583
584 allocator->Free(resFragmentShader.ptr());
585 }
586 }
587
588 //-----------------------------------------
589 void
DestroyResShaderParameter(os::IAllocator * allocator,ResShaderParameter resShaderParameter)590 Material::DestroyResShaderParameter(
591 os::IAllocator* allocator,
592 ResShaderParameter resShaderParameter)
593 {
594 if (resShaderParameter.IsValid())
595 {
596 allocator->Free(resShaderParameter.ptr());
597 }
598 }
599
600 //-----------------------------------------
601 ::std::pair<ResFragmentLightingTable, Result>
CopyResFragmentLightingTable(os::IAllocator * allocator,ResFragmentLightingTable resFragmentLightingTable)602 Material::CopyResFragmentLightingTable(
603 os::IAllocator* allocator,
604 ResFragmentLightingTable resFragmentLightingTable)
605 {
606 Result result = INITIALIZE_RESULT_OK;
607
608 void* tableMemory = allocator->Alloc(sizeof(ResFragmentLightingTableData));
609 if (tableMemory == NULL)
610 {
611 result |= Result::MASK_FAIL_BIT;
612 return ::std::make_pair(ResFragmentLightingTable(NULL), result);
613 }
614
615 ResFragmentLightingTableData* fragmentLightingTable =
616 new(tableMemory) ResFragmentLightingTableData(resFragmentLightingTable.ref());
617
618 fragmentLightingTable->toReflectanceRSampler.set_ptr(NULL);
619 fragmentLightingTable->toReflectanceGSampler.set_ptr(NULL);
620 fragmentLightingTable->toReflectanceBSampler.set_ptr(NULL);
621 fragmentLightingTable->toDistribution0Sampler.set_ptr(NULL);
622 fragmentLightingTable->toDistribution1Sampler.set_ptr(NULL);
623 fragmentLightingTable->toFresnelSampler.set_ptr(NULL);
624
625 if (resFragmentLightingTable.GetReflectanceRSampler().IsValid() && result.IsSuccess())
626 {
627 ::std::pair<ResLightingLookupTable, Result> copyResult =
628 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetReflectanceRSampler());
629
630 fragmentLightingTable->toReflectanceRSampler.set_ptr(copyResult.first.ptr());
631
632 result |= copyResult.second;
633 }
634
635 if (resFragmentLightingTable.GetReflectanceGSampler().IsValid() && result.IsSuccess())
636 {
637 ::std::pair<ResLightingLookupTable, Result> copyResult =
638 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetReflectanceGSampler());
639
640 fragmentLightingTable->toReflectanceGSampler.set_ptr(copyResult.first.ptr());
641
642 result |= copyResult.second;
643 }
644
645 if (resFragmentLightingTable.GetReflectanceBSampler().IsValid() && result.IsSuccess())
646 {
647 ::std::pair<ResLightingLookupTable, Result> copyResult =
648 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetReflectanceBSampler());
649
650 fragmentLightingTable->toReflectanceBSampler.set_ptr(copyResult.first.ptr());
651
652 result |= copyResult.second;
653 }
654
655 if (resFragmentLightingTable.GetDistribution0Sampler().IsValid() && result.IsSuccess())
656 {
657 ::std::pair<ResLightingLookupTable, Result> copyResult =
658 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetDistribution0Sampler());
659
660 fragmentLightingTable->toDistribution0Sampler.set_ptr(copyResult.first.ptr());
661
662 result |= copyResult.second;
663 }
664
665 if (resFragmentLightingTable.GetDistribution1Sampler().IsValid() && result.IsSuccess())
666 {
667 ::std::pair<ResLightingLookupTable, Result> copyResult =
668 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetDistribution1Sampler());
669
670 fragmentLightingTable->toDistribution1Sampler.set_ptr(copyResult.first.ptr());
671
672 result |= copyResult.second;
673 }
674
675 if (resFragmentLightingTable.GetFresnelSampler().IsValid() && result.IsSuccess())
676 {
677 ::std::pair<ResLightingLookupTable, Result> copyResult =
678 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetFresnelSampler());
679
680 fragmentLightingTable->toFresnelSampler.set_ptr(copyResult.first.ptr());
681
682 result |= copyResult.second;
683 }
684
685 return ::std::make_pair(ResFragmentLightingTable(fragmentLightingTable), result);
686 }
687
688 //-----------------------------------------
689 ::std::pair<ResLightingLookupTable, Result>
CopyResLightingLookupTable(os::IAllocator * allocator,ResLightingLookupTable resLightingLookupTable)690 Material::CopyResLightingLookupTable(
691 os::IAllocator* allocator,
692 ResLightingLookupTable resLightingLookupTable)
693 {
694 Result result = INITIALIZE_RESULT_OK;
695
696 void* tableMemory = allocator->Alloc(sizeof(ResLightingLookupTableData));
697
698 if (tableMemory == NULL)
699 {
700 result |= Result::MASK_FAIL_BIT;
701 return ::std::make_pair(ResLightingLookupTable(NULL), result);
702 }
703
704 ResLightingLookupTableData* lightingLookupTable =
705 new(tableMemory) ResLightingLookupTableData(resLightingLookupTable.ref());
706
707 void* referenceTableMemory = allocator->Alloc(sizeof(ResReferenceLookupTableData));
708
709 if (referenceTableMemory == NULL)
710 {
711 result |= Result::MASK_FAIL_BIT;
712 allocator->Free(lightingLookupTable);
713 return ::std::make_pair(ResLightingLookupTable(NULL), result);
714 }
715
716 ResReferenceLookupTable sampler =
717 ut::ResStaticCast<ResReferenceLookupTable>(resLightingLookupTable.GetSampler());
718
719 // TYPE_INFO などをコピーする。
720 ResReferenceLookupTableData* referenceLookupTable =
721 new (referenceTableMemory) ResReferenceLookupTableData(sampler.ref());
722
723 referenceLookupTable->toTargetLut.set_ptr(sampler.GetTargetLut().ptr());
724 referenceLookupTable->toPath.set_ptr(sampler.GetPath());
725 referenceLookupTable->toTableName.set_ptr(sampler.GetTableName());
726
727 ResReferenceLookupTable rLut(referenceLookupTable);
728
729 lightingLookupTable->m_Input = resLightingLookupTable.GetInput();
730 lightingLookupTable->m_Scale = resLightingLookupTable.GetScale();
731 lightingLookupTable->toSampler.set_ptr(referenceLookupTable);
732
733 return ::std::make_pair(ResLightingLookupTable(lightingLookupTable), result);
734 }
735
736 //-----------------------------------------
737 void*
GetAnimTargetObject(const anim::ResAnimGroupMember & anim,const ResMaterial resMaterial)738 Material::GetAnimTargetObject(const anim::ResAnimGroupMember& anim, const ResMaterial resMaterial)
739 {
740 u32 objectType = anim.GetObjectType();
741 ResMaterial mat = resMaterial;
742
743 switch (objectType)
744 {
745 case anim::ResAnimGroupMember::OBJECT_TYPE_MATERIAL_COLOR:
746 {
747 anim::ResMaterialColorMember member = ResStaticCast<anim::ResMaterialColorMember>(anim);
748 const char* matName = member.GetMaterialName();
749
750 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
751 ResMaterialColorData* ptr = mat.GetMaterialColor().ptr();
752 return ptr;
753 }
754
755 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_SAMPLER:
756 {
757 anim::ResTextureSamplerMember member = ResStaticCast<anim::ResTextureSamplerMember>(anim);
758 const char* matName = member.GetMaterialName();
759 int mapperIndex = member.GetTextureMapperIndex();
760
761 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
762
763 //ResMaterial mat = GetMaterialOrBuffer(model, matName);
764 //member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
765 // Samplerの変更を反映させるにはMapperのSetSampler()を呼ぶ必要があるので、
766 // Mapperのポインタを返す
767 ResPixelBasedTextureMapperData* ptr = mat.GetTextureMappers(mapperIndex).ptr();
768 return ptr;
769 }
770
771 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_MAPPER:
772 {
773 anim::ResTextureMapperMember member = ResStaticCast<anim::ResTextureMapperMember>(anim);
774 const char* matName = member.GetMaterialName();
775 int mapperIndex = member.GetTextureMapperIndex();
776
777 //ResMaterial mat = GetMaterialOrBuffer(model, matName);
778 //member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
779
780 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
781 ResPixelBasedTextureMapperData* ptr = mat.GetTextureMappers(mapperIndex).ptr();
782 return ptr;
783 }
784
785 case anim::ResAnimGroupMember::OBJECT_TYPE_BLEND_OPERATION:
786 {
787 anim::ResBlendOperationMember member = ResStaticCast<anim::ResBlendOperationMember>(anim);
788 const char* matName = member.GetMaterialName();
789
790 //ResMaterial mat = GetMaterialOrBuffer(model, matName);
791 //member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
792
793 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
794 ResBlendOperationData* ptr = mat.GetFragmentOperation().GetBlendOperation().ptr();
795 return ptr;
796 }
797
798 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_COORDINATOR:
799 {
800 anim::ResTextureCoordinatorMember member = ResStaticCast<anim::ResTextureCoordinatorMember>(anim);
801 const char* matName = member.GetMaterialName();
802 int coordinatorIndex = member.GetTextureCoordinatorIndex();
803
804 //ResMaterial mat = GetMaterialOrBuffer(model, matName);
805 //member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
806
807 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
808 ResTextureCoordinatorData* ptr =mat.GetTextureCoordinators(coordinatorIndex).ptr();
809 return ptr;
810 }
811
812 default:
813 NW_ASSERT(false);
814 return NULL;
815 }
816 }
817
818 //-----------------------------------------
819 Result
Initialize(os::IAllocator * allocator)820 Material::Initialize(os::IAllocator* allocator)
821 {
822 Result result = INITIALIZE_RESULT_OK;
823
824 result |= CreateBuffers(allocator);
825 NW_ENSURE_AND_RETURN(result);
826
827 return result;
828 }
829
830 } // namespace gfx
831 } // namespace nw
832