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: 25777 $
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 }
203 if (resFragmentLightingTable.GetReflectanceGSampler().IsValid())
204 {
205 bufferSize += sizeof(ResLightingLookupTableData);
206 }
207 if (resFragmentLightingTable.GetReflectanceBSampler().IsValid())
208 {
209 bufferSize += sizeof(ResLightingLookupTableData);
210 }
211 if (resFragmentLightingTable.GetDistribution0Sampler().IsValid())
212 {
213 bufferSize += sizeof(ResLightingLookupTableData);
214 }
215 if (resFragmentLightingTable.GetDistribution1Sampler().IsValid())
216 {
217 bufferSize += sizeof(ResLightingLookupTableData);
218 }
219 if (resFragmentLightingTable.GetFresnelSampler().IsValid())
220 {
221 bufferSize += sizeof(ResLightingLookupTableData);
222 }
223 }
224 }
225 }
226 }
227
228 bufferSize *= bufferCount;
229 size += bufferSize.GetSizeWithPadding(size.GetAlignment());
230 }
231 }
232
233 //----------------------------------------
~Material()234 Material::~Material()
235 {
236 std::for_each(
237 m_Buffers.begin(), m_Buffers.end(), ResMaterialDestroyer(&this->GetAllocator()));
238 }
239
240 //----------------------------------------
241 bool
CanUseBuffer(u32 objectType) const242 Material::CanUseBuffer(u32 objectType) const
243 {
244 if (0 < m_BufferCount)
245 {
246 bit32 option = this->GetOwnerModel()->GetBufferOption();
247 switch (objectType)
248 {
249 case anim::ResAnimGroupMember::OBJECT_TYPE_MATERIAL_COLOR:
250 return ut::CheckFlag(option, Model::FLAG_BUFFER_MATERIAL_COLOR);
251 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_SAMPLER:
252 return ut::CheckFlag(option, Model::FLAG_BUFFER_TEXTURE_MAPPER);
253 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_MAPPER:
254 return ut::CheckFlag(option, Model::FLAG_BUFFER_TEXTURE_MAPPER);
255 case anim::ResAnimGroupMember::OBJECT_TYPE_BLEND_OPERATION:
256 return ut::CheckFlag(option, Model::FLAG_BUFFER_FRAGMENT_OPERATION);
257 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_COORDINATOR:
258 return ut::CheckFlag(option, Model::FLAG_BUFFER_TEXTURE_COORDINATOR);
259 default:
260 NW_ASSERT(false);
261 }
262 }
263 return false;
264 }
265
266 //-----------------------------------------
267 Result
CreateBuffers(os::IAllocator * allocator)268 Material::CreateBuffers(os::IAllocator* allocator)
269 {
270 Result result = INITIALIZE_RESULT_OK;
271
272 NW_NULL_ASSERT(this->m_Owner);
273 bit32 bufferOption = m_Owner->GetBufferOption();
274
275 if (m_BufferCount != 0)
276 {
277 void* memory = allocator->Alloc(sizeof(ResMaterial) * m_BufferCount);
278 if (memory == NULL)
279 {
280 result |= Result::MASK_FAIL_BIT;
281 }
282
283 NW_ENSURE_AND_RETURN(result);
284
285 m_Buffers = ResMaterialArray(memory, m_BufferCount, allocator);
286
287 for (int bufferIndex = 0; bufferIndex < m_BufferCount; bufferIndex++)
288 {
289 NW_ENSURE_AND_RETURN(result);
290 ::std::pair<ResMaterial, Result> copyResult = this->CopyResMaterial(allocator, bufferOption);
291
292 if (copyResult.second.IsSuccess())
293 {
294 m_Buffers.push_back(copyResult.first);
295 }
296 else
297 {
298 DestroyResMaterial(allocator, copyResult.first);
299 result |= Result::MASK_FAIL_BIT;
300 }
301 }
302 }
303
304 return result;
305 }
306
307 //-----------------------------------------
308 ::std::pair<ResMaterial, Result>
CopyResMaterial(os::IAllocator * allocator,bit32 bufferOption)309 Material::CopyResMaterial(
310 os::IAllocator* allocator,
311 bit32 bufferOption)
312 {
313 Result result = INITIALIZE_RESULT_OK;
314
315 ResMaterial resMaterial = this->GetOriginal();
316
317 void* materialMemory = allocator->Alloc(sizeof(ResMaterialData));
318 if (materialMemory == NULL)
319 {
320 result |= Result::MASK_FAIL_BIT;
321 return ::std::make_pair(ResMaterial(NULL), result);
322 }
323
324 ResMaterialData* buffer =
325 new(materialMemory) ResMaterialData(this->GetOriginal().ref());
326
327 ResMaterial copyMaterial = ResMaterial(buffer);
328
329 // 判定に用いるために NULL でクリアしておく
330 buffer->toName.set_ptr(NULL);
331 buffer->toShader.set_ptr(NULL);
332 buffer->m_ShaderParametersTableCount = 0;
333 buffer->toShaderParametersTable.set_ptr(NULL);
334 buffer->toTextureMappers[0].set_ptr(NULL);
335 buffer->toTextureMappers[1].set_ptr(NULL);
336 buffer->toTextureMappers[2].set_ptr(NULL);
337 buffer->toProceduralTextureMapper.set_ptr(NULL);
338 buffer->toFragmentShader.set_ptr(NULL);
339
340 // ハッシュ無効化
341 buffer->m_AlphaTestHash = 0x0;
342 buffer->m_FragmentLightingHash = 0x0;
343 buffer->m_FragmentLightingTableHash = 0x0;
344 buffer->m_FragmentLightingTableParametersHash = 0x0;
345 buffer->m_FragmentOperationHash = 0x0;
346 buffer->m_MaterialColorHash = 0x0;
347 buffer->m_RasterizationHash = 0x0;
348 buffer->m_ShaderParametersHash = 0x0;
349 buffer->m_ShadingParameterHash = 0x0;
350 buffer->m_TextureCombinersHash = 0x0;
351 buffer->m_TextureCoordinatorsHash = 0x0;
352 buffer->m_TextureMappersHash = 0x0;
353 buffer->m_TextureSamplersHash = 0x0;
354
355 // シェーダーパラメータのコピー
356 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_SHADER_PARAMETER))
357 {
358 buffer->m_ShaderParametersTableCount = resMaterial.GetShaderParametersCount();
359
360 ut::Offset* offsets = NULL;
361 if (buffer->m_ShaderParametersTableCount != 0)
362 {
363 offsets = allocator->AllocAndConstruct<ut::Offset>(resMaterial.GetShaderParametersCount());
364
365 if (offsets == NULL)
366 {
367 result |= Result::MASK_FAIL_BIT;
368 return ::std::make_pair(copyMaterial, result);
369 }
370
371 buffer->toShaderParametersTable.set_ptr(offsets);
372 }
373
374 // メモリ解放を容易にするために NULL で初期化しておく
375 for (int i = 0; i < resMaterial.GetShaderParametersCount(); i++)
376 {
377 offsets[i].set_ptr(NULL);
378 }
379
380 for (int i = 0; i < resMaterial.GetShaderParametersCount(); i++)
381 {
382 ResShaderParameter resShaderParameter = resMaterial.GetShaderParameters(i);
383 ResShaderParameterValue resShaderParameterValue = resShaderParameter.GetParameter();
384
385 const int parameterLength = resShaderParameter.GetParameterLength();
386
387 // sizeof(ResShaderParameterData)で32ビット分の Value の領域が確保されるので-1をする。
388 void* parameterMemory = allocator->Alloc(sizeof(ResShaderParameterData) + sizeof(f32) * (parameterLength - 1));
389 if (parameterMemory == NULL)
390 {
391 result |= Result::MASK_FAIL_BIT;
392 return ::std::make_pair(copyMaterial, result);
393 }
394
395 ResShaderParameterData* shaderParameter = static_cast<ResShaderParameterData*>(parameterMemory);
396 *shaderParameter = ResShaderParameterData(resShaderParameter.ref());
397
398 for (int j = 0; j < parameterLength; ++j)
399 {
400 shaderParameter->m_Parameter.m_Value[j] = resShaderParameterValue.ref().m_Value[j];
401 }
402
403 offsets[i].set_ptr(shaderParameter);
404 }
405 }
406
407 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_TEXTURE_MAPPER))
408 {
409 for (int i = 0; i < resMaterial.GetTextureMappersCount(); i++)
410 {
411 ResPixelBasedTextureMapper resTextureMapper = resMaterial.GetTextureMappers(i);
412 if (resTextureMapper.IsValid())
413 {
414 ResTextureMapper textureMapper = resTextureMapper.CloneDynamic(allocator);
415
416 if (!textureMapper.IsValid())
417 {
418 result |= Result::MASK_FAIL_BIT;
419 return ::std::make_pair(copyMaterial, result);
420 }
421
422 buffer->toTextureMappers[i].set_ptr(textureMapper.ptr());
423 }
424 }
425 }
426
427 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_PROCEDURAL_TEXTURE_MAPPER))
428 {
429 ResProceduralTextureMapper resTextureMapper = resMaterial.GetProceduralTextureMapper();
430 if (resTextureMapper.IsValid())
431 {
432 ResTextureMapper textureMapper = resTextureMapper.CloneDynamic(allocator);
433
434 if (!textureMapper.IsValid())
435 {
436 result |= Result::MASK_FAIL_BIT;
437 return ::std::make_pair(copyMaterial, result);
438 }
439
440 buffer->toProceduralTextureMapper.set_ptr(textureMapper.ptr());
441 }
442 }
443
444 if (ut::CheckFlagOr(bufferOption, Model::MULTI_FLAG_BUFFER_FRAGMENT_SHADER))
445 {
446 ResFragmentShader resFragmentShader = resMaterial.GetFragmentShader();
447 if (resFragmentShader.IsValid())
448 {
449 void* shaderMemory = allocator->Alloc(sizeof(ResFragmentShaderData));
450
451 if (shaderMemory == NULL)
452 {
453 result |= Result::MASK_FAIL_BIT;
454 return ::std::make_pair(copyMaterial, result);
455 }
456
457 ResFragmentShaderData* fragmentShader =
458 new(shaderMemory) ResFragmentShaderData(resFragmentShader.ref());
459
460 buffer->toFragmentShader.set_ptr(fragmentShader);
461
462 // 判定に用いるために NULL でクリアしておく
463 fragmentShader->toFragmentLightingTable.set_ptr(NULL);
464
465 if (ut::CheckFlag(bufferOption, Model::FLAG_BUFFER_FRAGMENT_LIGHTING_TABLE))
466 {
467 ResFragmentLightingTable resFragmentLightingTable =
468 resFragmentShader.GetFragmentLightingTable();
469 if (resFragmentLightingTable.IsValid())
470 {
471 ::std::pair<ResFragmentLightingTable, Result> copyResult =
472 this->CopyResFragmentLightingTable(allocator, resFragmentLightingTable);
473
474 fragmentShader->toFragmentLightingTable.set_ptr(copyResult.first.ptr());
475
476 if (copyResult.second.IsFailure())
477 {
478 result |= Result::MASK_FAIL_BIT;
479 return ::std::make_pair(copyMaterial, result);
480 }
481 }
482 }
483 }
484 }
485
486 return ::std::make_pair(copyMaterial, result);
487 }
488
489 //-----------------------------------------
490 void
DestroyResMaterial(os::IAllocator * allocator,ResMaterial resMaterial)491 Material::DestroyResMaterial(os::IAllocator* allocator, ResMaterial resMaterial)
492 {
493 NW_NULL_ASSERT( allocator );
494 if (resMaterial.IsValid())
495 {
496 resMaterial.Cleanup();
497
498 DestroyResFragmentShader(allocator, resMaterial.GetFragmentShader());
499
500 if (resMaterial.GetProceduralTextureMapper().IsValid())
501 {
502 resMaterial.GetProceduralTextureMapper().DestroyDynamic();
503 }
504
505 for (int i = 0; i < resMaterial.GetTextureMappersCount(); i++)
506 {
507 if (resMaterial.GetTextureMappers(i).IsValid())
508 {
509 resMaterial.GetTextureMappers(i).DestroyDynamic();
510 }
511 }
512
513 // シェーダーパラメータのメモリ解放
514 if (resMaterial.ref().toShaderParametersTable.to_ptr() != NULL)
515 {
516 for (int i = 0; i < resMaterial.GetShaderParametersCount(); i++)
517 {
518 DestroyResShaderParameter(allocator, resMaterial.GetShaderParameters(i));
519 }
520 allocator->Free(resMaterial.ref().toShaderParametersTable.to_ptr());
521 }
522
523 allocator->Free(resMaterial.ptr());
524 }
525 }
526
527 //-----------------------------------------
528 void
DestroyResFragmentShader(os::IAllocator * allocator,ResFragmentShader resFragmentShader)529 Material::DestroyResFragmentShader(
530 os::IAllocator* allocator,
531 ResFragmentShader resFragmentShader)
532 {
533 if (resFragmentShader.IsValid())
534 {
535 ResFragmentLightingTable resFragmentLightingTable = resFragmentShader.GetFragmentLightingTable();
536
537 if (resFragmentLightingTable.IsValid())
538 {
539 if (resFragmentLightingTable.GetReflectanceRSampler().IsValid())
540 {
541 allocator->Free(resFragmentLightingTable.GetReflectanceRSampler().ptr());
542 }
543
544 if (resFragmentLightingTable.GetReflectanceGSampler().IsValid())
545 {
546 allocator->Free(resFragmentLightingTable.GetReflectanceGSampler().ptr());
547 }
548
549 if (resFragmentLightingTable.GetReflectanceBSampler().IsValid())
550 {
551 allocator->Free(resFragmentLightingTable.GetReflectanceBSampler().ptr());
552 }
553
554 if (resFragmentLightingTable.GetDistribution0Sampler().IsValid())
555 {
556 allocator->Free(resFragmentLightingTable.GetDistribution0Sampler().ptr());
557 }
558
559 if (resFragmentLightingTable.GetDistribution1Sampler().IsValid())
560 {
561 allocator->Free(resFragmentLightingTable.GetDistribution1Sampler().ptr());
562 }
563
564 if (resFragmentLightingTable.GetFresnelSampler().IsValid())
565 {
566 allocator->Free(resFragmentLightingTable.GetFresnelSampler().ptr());
567 }
568
569 allocator->Free(resFragmentLightingTable.ptr());
570 }
571
572 allocator->Free(resFragmentShader.ptr());
573 }
574 }
575
576 //-----------------------------------------
577 void
DestroyResShaderParameter(os::IAllocator * allocator,ResShaderParameter resShaderParameter)578 Material::DestroyResShaderParameter(
579 os::IAllocator* allocator,
580 ResShaderParameter resShaderParameter)
581 {
582 if (resShaderParameter.IsValid())
583 {
584 allocator->Free(resShaderParameter.ptr());
585 }
586 }
587
588 //-----------------------------------------
589 ::std::pair<ResFragmentLightingTable, Result>
CopyResFragmentLightingTable(os::IAllocator * allocator,ResFragmentLightingTable resFragmentLightingTable)590 Material::CopyResFragmentLightingTable(
591 os::IAllocator* allocator,
592 ResFragmentLightingTable resFragmentLightingTable)
593 {
594 Result result = INITIALIZE_RESULT_OK;
595
596 void* tableMemory = allocator->Alloc(sizeof(ResFragmentLightingTableData));
597 if (tableMemory == NULL)
598 {
599 result |= Result::MASK_FAIL_BIT;
600 return ::std::make_pair(ResFragmentLightingTable(NULL), result);
601 }
602
603 ResFragmentLightingTableData* fragmentLightingTable =
604 new(tableMemory) ResFragmentLightingTableData(resFragmentLightingTable.ref());
605
606 fragmentLightingTable->toReflectanceRSampler.set_ptr(NULL);
607 fragmentLightingTable->toReflectanceGSampler.set_ptr(NULL);
608 fragmentLightingTable->toReflectanceBSampler.set_ptr(NULL);
609 fragmentLightingTable->toDistribution0Sampler.set_ptr(NULL);
610 fragmentLightingTable->toDistribution1Sampler.set_ptr(NULL);
611 fragmentLightingTable->toFresnelSampler.set_ptr(NULL);
612
613 if (resFragmentLightingTable.GetReflectanceRSampler().IsValid() && result.IsSuccess())
614 {
615 ::std::pair<ResLightingLookupTable, Result> copyResult =
616 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetReflectanceRSampler());
617
618 fragmentLightingTable->toReflectanceRSampler.set_ptr(copyResult.first.ptr());
619
620 result |= copyResult.second;
621 }
622
623 if (resFragmentLightingTable.GetReflectanceGSampler().IsValid() && result.IsSuccess())
624 {
625 ::std::pair<ResLightingLookupTable, Result> copyResult =
626 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetReflectanceGSampler());
627
628 fragmentLightingTable->toReflectanceGSampler.set_ptr(copyResult.first.ptr());
629
630 result |= copyResult.second;
631 }
632
633 if (resFragmentLightingTable.GetReflectanceBSampler().IsValid() && result.IsSuccess())
634 {
635 ::std::pair<ResLightingLookupTable, Result> copyResult =
636 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetReflectanceBSampler());
637
638 fragmentLightingTable->toReflectanceBSampler.set_ptr(copyResult.first.ptr());
639
640 result |= copyResult.second;
641 }
642
643 if (resFragmentLightingTable.GetDistribution0Sampler().IsValid() && result.IsSuccess())
644 {
645 ::std::pair<ResLightingLookupTable, Result> copyResult =
646 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetDistribution0Sampler());
647
648 fragmentLightingTable->toDistribution0Sampler.set_ptr(copyResult.first.ptr());
649
650 result |= copyResult.second;
651 }
652
653 if (resFragmentLightingTable.GetDistribution1Sampler().IsValid() && result.IsSuccess())
654 {
655 ::std::pair<ResLightingLookupTable, Result> copyResult =
656 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetDistribution1Sampler());
657
658 fragmentLightingTable->toDistribution1Sampler.set_ptr(copyResult.first.ptr());
659
660 result |= copyResult.second;
661 }
662
663 if (resFragmentLightingTable.GetFresnelSampler().IsValid() && result.IsSuccess())
664 {
665 ::std::pair<ResLightingLookupTable, Result> copyResult =
666 this->CopyResLightingLookupTable(allocator, resFragmentLightingTable.GetFresnelSampler());
667
668 fragmentLightingTable->toFresnelSampler.set_ptr(copyResult.first.ptr());
669
670 result |= copyResult.second;
671 }
672
673 return ::std::make_pair(ResFragmentLightingTable(fragmentLightingTable), result);
674 }
675
676 //-----------------------------------------
677 ::std::pair<ResLightingLookupTable, Result>
CopyResLightingLookupTable(os::IAllocator * allocator,ResLightingLookupTable resLightingLookupTable)678 Material::CopyResLightingLookupTable(
679 os::IAllocator* allocator,
680 ResLightingLookupTable resLightingLookupTable)
681 {
682 Result result = INITIALIZE_RESULT_OK;
683
684 void* tableMemory = allocator->Alloc(sizeof(ResLightingLookupTableData));
685
686 if (tableMemory == NULL)
687 {
688 result |= Result::MASK_FAIL_BIT;
689 return ::std::make_pair(ResLightingLookupTable(NULL), result);
690 }
691
692 ResLightingLookupTableData* lightingLookupTable =
693 new(tableMemory) ResLightingLookupTableData(resLightingLookupTable.ref());
694
695 lightingLookupTable->m_Input = resLightingLookupTable.GetInput();
696 lightingLookupTable->m_Scale = resLightingLookupTable.GetScale();
697 lightingLookupTable->toSampler.set_ptr(resLightingLookupTable.GetSampler().ptr());
698
699 return ::std::make_pair(ResLightingLookupTable(lightingLookupTable), result);
700 }
701
702 //-----------------------------------------
703 void*
GetAnimTargetObject(const anim::ResAnimGroupMember & anim,const ResMaterial resMaterial)704 Material::GetAnimTargetObject(const anim::ResAnimGroupMember& anim, const ResMaterial resMaterial)
705 {
706 u32 objectType = anim.GetObjectType();
707 ResMaterial mat = resMaterial;
708
709 switch (objectType)
710 {
711 case anim::ResAnimGroupMember::OBJECT_TYPE_MATERIAL_COLOR:
712 {
713 anim::ResMaterialColorMember member = ResStaticCast<anim::ResMaterialColorMember>(anim);
714 const char* matName = member.GetMaterialName();
715
716 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
717 ResMaterialColorData* ptr = mat.GetMaterialColor().ptr();
718 return ptr;
719 }
720
721 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_SAMPLER:
722 {
723 anim::ResTextureSamplerMember member = ResStaticCast<anim::ResTextureSamplerMember>(anim);
724 const char* matName = member.GetMaterialName();
725 int mapperIndex = member.GetTextureMapperIndex();
726
727 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
728
729 //ResMaterial mat = GetMaterialOrBuffer(model, matName);
730 //member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
731 // Samplerの変更を反映させるにはMapperのSetSampler()を呼ぶ必要があるので、
732 // Mapperのポインタを返す
733 ResPixelBasedTextureMapperData* ptr = mat.GetTextureMappers(mapperIndex).ptr();
734 return ptr;
735 }
736
737 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_MAPPER:
738 {
739 anim::ResTextureMapperMember member = ResStaticCast<anim::ResTextureMapperMember>(anim);
740 const char* matName = member.GetMaterialName();
741 int mapperIndex = member.GetTextureMapperIndex();
742
743 //ResMaterial mat = GetMaterialOrBuffer(model, matName);
744 //member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
745
746 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
747 ResPixelBasedTextureMapperData* ptr = mat.GetTextureMappers(mapperIndex).ptr();
748 return ptr;
749 }
750
751 case anim::ResAnimGroupMember::OBJECT_TYPE_BLEND_OPERATION:
752 {
753 anim::ResBlendOperationMember member = ResStaticCast<anim::ResBlendOperationMember>(anim);
754 const char* matName = member.GetMaterialName();
755
756 //ResMaterial mat = GetMaterialOrBuffer(model, matName);
757 //member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
758
759 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
760 ResBlendOperationData* ptr = mat.GetFragmentOperation().GetBlendOperation().ptr();
761 return ptr;
762 }
763
764 case anim::ResAnimGroupMember::OBJECT_TYPE_TEXTURE_COORDINATOR:
765 {
766 anim::ResTextureCoordinatorMember member = ResStaticCast<anim::ResTextureCoordinatorMember>(anim);
767 const char* matName = member.GetMaterialName();
768 int coordinatorIndex = member.GetTextureCoordinatorIndex();
769
770 //ResMaterial mat = GetMaterialOrBuffer(model, matName);
771 //member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
772
773 member.SetResMaterialPtr(NW_ANY_TO_PTR_VALUE(mat.ptr()));
774 ResTextureCoordinatorData* ptr =mat.GetTextureCoordinators(coordinatorIndex).ptr();
775 return ptr;
776 }
777
778 default:
779 NW_ASSERT(false);
780 return NULL;
781 }
782 }
783
784 //-----------------------------------------
785 Result
Initialize(os::IAllocator * allocator)786 Material::Initialize(os::IAllocator* allocator)
787 {
788 Result result = INITIALIZE_RESULT_OK;
789
790 result |= CreateBuffers(allocator);
791 NW_ENSURE_AND_RETURN(result);
792
793 return result;
794 }
795
796 } // namespace gfx
797 } // namespace nw
798