2 * Copyright (c) 2024 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-scene3d/public-api/loader/shader-option.h>
27 namespace Dali::Scene3D::Loader
31 static constexpr std::string_view OPTION_KEYWORD[] =
36 "METALLIC_ROUGHNESS_TEX",
42 "MATERIAL_SPECULAR_TEXTURE",
43 "MATERIAL_SPECULAR_COLOR_TEXTURE",
54 static constexpr uint32_t NUMBER_OF_OPTIONS = sizeof(OPTION_KEYWORD) / sizeof(OPTION_KEYWORD[0]);
55 static const char* ADD_EXTRA_SKINNING_ATTRIBUTES{"ADD_EXTRA_SKINNING_ATTRIBUTES"};
56 static const char* ADD_EXTRA_WEIGHTS{"ADD_EXTRA_WEIGHTS"};
58 inline void HashString(uint64_t& hash, const char* string)
61 while((c = *string++))
68 ShaderOption::ShaderOption(const ShaderOption& rhs)
70 mOptionHash = rhs.mOptionHash;
71 for(auto& macroDef : rhs.mMacros)
73 mMacros.emplace_back(macroDef);
77 ShaderOption& ShaderOption::operator=(const ShaderOption& rhs)
81 mOptionHash = rhs.mOptionHash;
82 for(auto& macroDef : rhs.mMacros)
84 mMacros.emplace_back(macroDef);
90 void ShaderOption::SetTransparency()
92 mOptionHash |= (1 << NUMBER_OF_OPTIONS);
95 void ShaderOption::AddOption(Type shaderOptionType)
97 mOptionHash |= (1 << static_cast<uint32_t>(shaderOptionType));
100 void ShaderOption::AddJointMacros(size_t numberOfJointSets)
102 // Add options for ADD_EXTRA_SKINNING_ATTRIBUTES and ADD_EXTRA_WEIGHTS:
103 if(numberOfJointSets > 1)
105 std::ostringstream attributes;
106 std::ostringstream weights;
107 for(size_t i = 1; i < numberOfJointSets; ++i)
109 attributes << "INPUT vec4 aJoints" << i << ";\n";
110 attributes << "INPUT vec4 aWeights" << i << ";\n";
112 weights << "bone +=\n"
113 << "uBone[int(aJoints" << i << ".x)] * aWeights" << i << ".x +\n"
114 << "uBone[int(aJoints" << i << ".y)] * aWeights" << i << ".y +\n"
115 << "uBone[int(aJoints" << i << ".z)] * aWeights" << i << ".z +\n"
116 << "uBone[int(aJoints" << i << ".w)] * aWeights" << i << ".w;\n";
118 AddMacroDefinition(ADD_EXTRA_SKINNING_ATTRIBUTES, attributes.str());
119 AddMacroDefinition(ADD_EXTRA_WEIGHTS, weights.str());
123 AddMacroDefinition(ADD_EXTRA_SKINNING_ATTRIBUTES, std::string{});
124 AddMacroDefinition(ADD_EXTRA_WEIGHTS, std::string{});
128 void ShaderOption::AddMacroDefinition(std::string macro, std::string definition)
130 auto iter = std::find_if(mMacros.begin(), mMacros.end(), [macro](ShaderOption::MacroDefinition& md) { return md.macro == macro; });
131 if(iter != mMacros.end())
133 iter->definition = definition;
137 mMacros.emplace_back(MacroDefinition{macro, definition});
141 const std::vector<ShaderOption::MacroDefinition>& ShaderOption::GetMacroDefinitions() const
146 uint64_t ShaderOption::GetOptionHash() const
148 uint64_t optionHash = mOptionHash;
151 uint64_t hash = 5381;
152 for(auto& macroDef : mMacros)
154 HashString(hash, macroDef.macro.c_str());
155 HashString(hash, macroDef.definition.c_str());
157 optionHash |= ((hash << 32) & 0xFFFFFFFF00000000);
162 void ShaderOption::GetDefines(std::vector<std::string>& defines) const
165 for(uint32_t i = 0; i < NUMBER_OF_OPTIONS; ++i)
167 if(mOptionHash & (1 << i))
169 defines.push_back(OPTION_KEYWORD[i].data());
174 std::string_view ShaderOption::GetDefineKeyword(Type shaderOptionType)
176 return OPTION_KEYWORD[static_cast<uint32_t>(shaderOptionType)];
179 } // namespace Dali::Scene3D::Loader