1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_RelativeHashMaterialIdGenerator.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: 22484 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 
18 #include <nw/gfx/gfx_RelativeHashMaterialIdGenerator.h>
19 #include <nw/gfx/gfx_Material.h>
20 
21 namespace nw
22 {
23 namespace gfx
24 {
25 
26 NW_UT_RUNTIME_TYPEINFO_ROOT_DEFINITION(RelativeHashMaterialIdGenerator);
27 
28 //! ライブラリで標準的に用いるマテリアルのハッシュ値となります。
29 const u32
30 RelativeHashMaterialIdGenerator::m_DefaultHashes[] =
31 {
32     0x3b75655e, //!< ShaderParameter
33     0x640102f8, //!< AlphaTest
34     0xa6eb8db7, //!< TextureSamplers
35     0x104f3679, //!< TextureCombiner
36     0xdbf039d1, //!< FragmentOperation
37     0x3b75655e, //!< FragmentLightingTableParameters
38     0xc06ac8f4, //!< Raterization
39     0x00000001, //!< ShadingParameter
40     0xf43df7f4, //!< TextureCoordinator
41     0xe9a0ea24, //!< MaterialColor
42     0x9be0aae3, //!< FragmentLighting
43 };
44 
45 
46 //----------------------------------------
47 IMaterialIdGenerator*
Create(os::IAllocator * allocator)48 RelativeHashMaterialIdGenerator::Builder::Create(
49     os::IAllocator* allocator
50 )
51 {
52     NW_NULL_ASSERT(allocator);
53 
54     void* memory = allocator->Alloc(sizeof(RelativeHashMaterialIdGenerator));
55     NW_NULL_ASSERT(memory);
56 
57     MaterialArray materials;
58     if (m_Description.isFixedSizeMemory)
59     {
60         materials = MaterialArray(m_Description.maxMaterials, allocator);
61     }
62     else
63     {
64         materials = MaterialArray(allocator);
65     }
66 
67     RelativeHashMaterialIdGenerator* generator =
68         new(memory) RelativeHashMaterialIdGenerator(
69         allocator,
70         m_Description.isForceGeneration,
71         materials);
72 
73     return generator;
74 }
75 
76 //----------------------------------------
77 u32
CompareHash(u32 materialHash,MaterialOrder order)78 RelativeHashMaterialIdGenerator::CompareHash(u32 materialHash, MaterialOrder order)
79 {
80     const u32 upperId = 0x1 << 0;
81     const u32 lowerId = 0x1 << 1;
82 
83     if (materialHash != m_DefaultHashes[order])
84     {
85         if (materialHash > m_DefaultHashes[order])
86         {
87             return upperId << (order * 2);
88         }
89         else
90         {
91             return lowerId << (order * 2);
92         }
93     }
94 
95     return 0;
96 }
97 
98 //----------------------------------------
99 void
Generate()100 RelativeHashMaterialIdGenerator::Generate()
101 {
102     MaterialArray::iterator materialEnd = m_Materials.end();
103     for (MaterialArray::iterator iter = m_Materials.begin();
104         iter != materialEnd;
105         ++iter)
106     {
107         ResMaterial resMaterial = (*iter)->GetOriginal();
108         NW_ASSERT(resMaterial.IsValid());
109 
110         if (resMaterial.GetMaterialId() == 0x0 || m_IsForceGeneration)
111         {
112             u32 materialId = 0x0;
113 
114             materialId |= CompareHash(resMaterial.GetShaderParametersHash(), MATERIAL_ORDER_SHADER_PARAMETERS);
115             materialId |= CompareHash(resMaterial.GetShadingParameterHash(), MATERIAL_ORDER_SHADING_PARMETER);
116             materialId |= CompareHash(resMaterial.GetMaterialColorHash(), MATERIAL_ORDER_MATERIAL_COLOR);
117             materialId |= CompareHash(resMaterial.GetRasterizationHash(), MATERIAL_ORDER_RASTERIZATION);
118             materialId |= CompareHash(resMaterial.GetTextureCoordinatorsHash(), MATERIAL_ORDER_TEXTURE_COORDINATORS);
119             materialId |= CompareHash(resMaterial.GetTextureSamplersHash(), MATERIAL_ORDER_TEXTURE_SAMPLERS);
120             materialId |= CompareHash(resMaterial.GetFragmentLightingHash(), MATERIAL_ORDER_FRAGMENT_LIGHTING);
121             materialId |= CompareHash(resMaterial.GetFragmentLightingTableParametersHash(), MATERIAL_ORDER_FRAGMENT_LIGHTING_TABLE_PARAMETERS);
122             materialId |= CompareHash(resMaterial.GetTextureCombinersHash(), MATERIAL_ORDER_TEXTURE_COMBINER);
123             materialId |= CompareHash(resMaterial.GetAlphaTestHash(), MATERIAL_ORDER_ALPHA_TEST);
124             materialId |= CompareHash(resMaterial.GetFragmentOperationHash(), MATERIAL_ORDER_FRAGMENT_OPERATION);
125 
126             resMaterial.SetMaterialId(materialId);
127         }
128     }
129 
130     // 生成後はマテリアルのリストを解放します。
131     m_Materials.clear();
132 }
133 
134 } // namespace gfx
135 } // namespace nw
136