3#include "../Loader/XML/XML.h"
4#include "../Loader/XML/XMLParser.h"
6#include "../../Manager/LightMgr.h"
7#include "../Settings.h"
11SMaterial::SMaterial() {
12 m_lightMgr = CORE->GetCore(
LightMgr);
17 if (material ==
nullptr)
throw -1;
19 m_refHash = material->m_hash;
21 for (
const auto& element_pair : material->m_elements) {
22 const auto& element_src = element_pair.second;
23 auto element_copy =
new Element;
24 element_copy->count = element_src->count;
25 element_copy->type = element_src->type;
26 element_copy->valueStr = element_src->valueStr;
27 m_elements.insert(std::pair<std::string, Element*>(element_pair.first, element_copy));
29 m_mode = material->m_mode;
30 m_shaders = material->m_shaders;
31 m_orderLayer = material->m_orderLayer;
32 m_textureLayout = material->m_textureLayout;
34 InitElements(m_elements, m_shaders);
35 m_lightMgr = CORE->GetCore(
LightMgr);
38SMaterial::~SMaterial() {
42void SMaterial::Exterminate() {
46void SMaterial::ReleaseElements() {
47 for (
const auto& pair : m_elements) {
48 auto* element = pair.second;
54void SMaterial::AttachElement()
const {
57 for (
const auto& element_pair : m_elements) {
58 const auto& element = element_pair.second;
59 if (element->id < 0)
continue;
60 element->attachFunc();
64void SMaterial::InitElements(
const ElementsMap& elements,
SShaderGroup* shaders) {
65 const auto& handle = shaders->GetHandleByMode(m_mode);
66 for (
const auto& element_pair : elements) {
67 const auto& element_name = element_pair.first.c_str();
68 const auto& element = element_pair.second;
69 if (element->attachFunc !=
nullptr)
continue;
71 const auto& handleElement = handle->UniformLocation(element_name);
72 if (handleElement ==
nullptr)
continue;
74 element->id = handleElement->id;
75 SetBindFuncByType(element);
82void SMaterial::SetInt(
const std::string& name,
int value) {
83 auto find_iter = m_elements.find(name);
84 if (find_iter == m_elements.end())
return;
85 SetIntFunc(find_iter->second, value);
88void SMaterial::SetFloat(
const std::string& name,
float value) {
89 auto find_iter = m_elements.find(name);
90 if (find_iter == m_elements.end())
return;
91 SetFloatFunc(find_iter->second, value);
94void SMaterial::SetVec3(
const std::string& name,
const vec3& value) {
95 auto find_iter = m_elements.find(name);
96 if (find_iter == m_elements.end())
return;
97 SetVec3Func(find_iter->second, value);
100void SMaterial::SetTexture(
const std::string& name,
SResource* texture) {
101 auto find_iter = m_elements.find(name);
102 if (find_iter == m_elements.end())
return;
103 SetTextureFunc(find_iter->second, texture);
110 root =
XFILE(asset->name_path.c_str()).getRoot();
116 XNode cse_mat = root->getChild(
"CSEMAT");
117 XNode shader_node = cse_mat.getChild(
"shader");
119 auto var_nodes = shader_node.children;
120 auto shader_file_id = shader_node.getAttribute(
"id").value;
121 auto shaderGroup = Create<SShaderGroup>(shader_file_id);
122 if (shaderGroup ==
nullptr)
return;
123 m_shaders = shaderGroup;
125 if (shader_node.hasAttribute(
"deferred")) {
126 auto get_deferred = std::stoi(shader_node.getAttribute(
"deferred").value);
127 if (get_deferred == 1) {
132 for (
const auto& node : var_nodes) {
134 auto element_value = node.value.toStringVector();
135 auto element_type = node.getAttribute(
"type").value;
136 SType type = XMLParser::GetType(element_type);
137 auto element_name = node.getAttribute(
"name").value;
138 auto element_count = node.getAttribute(
"count").value;
140 auto element =
new Element;
141 element->type = type;
142 element->count = std::stoi(element_count);
143 element->valueStr = element_value;
144 m_elements.insert(std::pair<std::string, Element*>(element_name, element));
149void SMaterial::SetBindFuncByType(Element* element) {
150 const GLenum type = element->type;
153 SetFloatFunc(element, XMLParser::parseFloat(element->valueStr[0].c_str()));
156 SetIntFunc(element, XMLParser::parseInt(element->valueStr[0].c_str()));
165 SetVec4Func(element, XMLParser::parseVec4(element->valueStr));
168 SetVec3Func(element, XMLParser::parseVec3(element->valueStr));
171 SetTextureFunc(element, XMLParser::parseTexture(element->valueStr[0].c_str()));
176void SMaterial::SetIntFunc(Element* element,
int value) {
177 if (element ==
nullptr)
return;
178 element->raw = std::to_string(value);
179 element->attachFunc = [element, value]() {
180 glUniform1i(element->id, value);
184void SMaterial::SetFloatFunc(Element* element,
float value) {
185 if (element ==
nullptr)
return;
186 element->raw = std::to_string(value);
187 element->attachFunc = [element, value]() {
188 glUniform1f(element->id, value);
192void SMaterial::SetBoolFunc(Element* element,
bool value) {
193 if (element ==
nullptr)
return;
194 element->raw = std::to_string(value);
195 element->attachFunc = [element, value]() {
196 glUniform1i(element->id, value);
200void SMaterial::SetMat4Func(Element* element,
mat4 value) {
201 if (element ==
nullptr)
return;
202 element->attachFunc = [element, value]() {
203 glUniformMatrix4fv(element->id, element->count, 0, value.Pointer());
207void SMaterial::SetMat3Func(Element* element,
mat3 value) {
208 if (element ==
nullptr)
return;
209 element->attachFunc = [element, value]() {
210 glUniformMatrix3fv(element->id, element->count, 0, value.Pointer());
214void SMaterial::SetMat2Func(Element* element,
mat2 value) {
215 if (element ==
nullptr)
return;
216 element->attachFunc = [element, value]() {
217 glUniformMatrix2fv(element->id, element->count, 0, value.Pointer());
221void SMaterial::SetVec4Func(Element* element,
vec4 value) {
222 element->attachFunc = [element, value]() {
223 element->raw = std::to_string(value.x) +
" "
224 + std::to_string(value.y) +
" "
225 + std::to_string(value.z) +
" "
226 + std::to_string(value.w);
227 glUniform4fv(element->id, element->count, value.Pointer());
231void SMaterial::SetVec3Func(Element* element,
vec3 value) {
232 if (element ==
nullptr)
return;
233 element->raw = std::to_string(value.x) +
" "
234 + std::to_string(value.y) +
" "
235 + std::to_string(value.z);
236 element->attachFunc = [element, value]() {
237 glUniform3fv(element->id, element->count, value.Pointer());
241void SMaterial::SetVec2Func(Element* element,
vec2 value) {
242 if (element ==
nullptr)
return;
243 element->raw = std::to_string(value.x) +
" "
244 + std::to_string(value.y);
245 element->attachFunc = [element, value]() {
246 glUniform2fv(element->id, element->count, value.Pointer());
250void SMaterial::SetTextureFunc(Element* element,
SResource* texture) {
251 if (element ==
nullptr || texture ==
nullptr)
return;
252 auto value =
static_cast<STexture*
>(texture);
254 auto* texture_layout = &m_textureLayout;
256 element->raw = texture->GetHash();
257 element->attachFunc = [element, value, texture_layout]() {
258 value->Bind(element->id, *texture_layout);
263short SMaterial::GetOrderLayer()
const {
267void SMaterial::SetOrderLayer(
int orderLayer) {
268 m_orderLayer = orderLayer;
275SMaterial::SMaterialMode SMaterial::GetMode()
const {
279void SMaterial::SetMode(SMaterialMode mode) {
283int SMaterial::GetTextureCount()
const {
284 return m_textureLayout;
288 if (shaders ==
nullptr)
return nullptr;
289 const auto& handle = shaders->GetHandleByMode(SMaterialMode::NORMAL);
291 const auto& uniformList = handle->GetUniformsList();
293 material->m_shaders = shaders;
295 for (
const auto& uniform_pair : uniformList) {
296 const auto& name = uniform_pair.first;
297 const auto& gl_element = uniform_pair.second;
299 auto element =
new Element;
300 element->id = gl_element->id;
301 element->type = XMLParser::GetType(gl_element->type);
303 material->m_elements.insert(std::pair<std::string, Element*>(name, element));
305 material->InitElements(material->m_elements, shaders);
310std::string SMaterial::PrintMaterial()
const {
311 std::string result =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
312 "<CSEMAT version=\"1.0.0\">\n";
314 if(m_mode == DEFERRED) {
315 result +=
"<shader id=\"" + m_shaders->GetHash() +
"\" deferred=\"1\">\n";
318 result +=
"<shader id=\"" + m_shaders->GetHash() +
"\">\n";
321 for (
const auto& var : m_elements) {
322 const auto& element = var.second;
323 if(element->raw.empty())
continue;
325 result +=
"<var name=\"" + var.first
326 +
"\" type=\"" + XMLParser::ToString(element->type)
328 + element->raw +
"</var>\n";
330 result +=
"</shader>\n</CSEMAT>";
int GetShadowCount() const