5#include "../Loader/XML/XML.h"
6#include "../Loader/XML/XMLParser.h"
8#include "../../Manager/LightMgr.h"
9#include "../Settings.h"
14 m_lightMgr = CORE->GetCore(
LightMgr);
19 if (material ==
nullptr)
throw -1;
21 m_refHash = material->m_hash;
23 for (
const auto& element_pair : material->m_elements) {
24 const auto& element_src = element_pair.second;
25 auto element_copy = new Element;
26 element_copy->count = element_src->count;
27 element_copy->type = element_src->type;
28 element_copy->valueStr = element_src->valueStr;
29 m_elements.insert(std::pair<std::string, Element*>(element_pair.first, element_copy));
31 m_mode = material->m_mode;
32 m_shaders = material->m_shaders;
33 m_orderLayer = material->m_orderLayer;
34 m_textureLayout = material->m_textureLayout;
36 InitElements(m_elements, m_shaders);
37 m_lightMgr = CORE->GetCore(
LightMgr);
40SMaterial::~SMaterial() {
44void SMaterial::Exterminate() {
48void SMaterial::ReleaseElements() {
49 for (
const auto& pair : m_elements) {
50 auto* element = pair.second;
56int SMaterial::AttachElement(
int textureLayout)
const {
57 m_textureLayout = textureLayout;
59 for (
const auto& element_pair : m_elements) {
60 const auto& element = element_pair.second;
61 if (element->id < 0)
continue;
62 element->attachFunc();
64 return m_textureLayout - textureLayout;
67SMaterial::Element* SMaterial::GetElement(
const std::string& key)
const {
68 const auto& result = m_elements.find(key);
69 if(result == m_elements.end())
return nullptr;
70 return result->second;
73void SMaterial::InitElements(
const ElementsMap& elements,
SShaderGroup* shaders) {
74 const auto& handle = shaders->GetHandleByMode(m_mode);
75 for (
const auto& element_pair : elements) {
76 const auto& element_name = element_pair.first.c_str();
77 const auto& element = element_pair.second;
78 if (element->attachFunc !=
nullptr)
continue;
80 const auto& handleElement = handle->UniformLocation(element_name);
81 if (handleElement ==
nullptr)
continue;
83 element->id = handleElement->id;
84 SetBindFuncByType(element);
91void SMaterial::SetInt(
const std::string& name,
int value) {
92 auto find_iter = m_elements.find(name);
93 if (find_iter == m_elements.end())
return;
94 SetIntFunc(find_iter->second, value);
97void SMaterial::SetFloat(
const std::string& name,
float value) {
98 auto find_iter = m_elements.find(name);
99 if (find_iter == m_elements.end())
return;
100 SetFloatFunc(find_iter->second, value);
103void SMaterial::SetVec3(
const std::string& name,
const vec3& value) {
104 auto find_iter = m_elements.find(name);
105 if (find_iter == m_elements.end())
return;
106 SetVec3Func(find_iter->second, value);
109void SMaterial::SetTexture(
const std::string& name,
SResource* texture) {
110 auto find_iter = m_elements.find(name);
111 if (find_iter == m_elements.end())
return;
112 SetTextureFunc(find_iter->second, texture);
115void SMaterial::SetRawData(
const std::string& name, std::vector<std::string> raw) {
116 auto find_iter = m_elements.find(name);
117 if (find_iter == m_elements.end())
return;
118 find_iter->second->valueStr = std::move(raw);
119 SetBindFuncByType(find_iter->second);
126 root =
XFILE(asset->name_path.c_str()).getRoot();
132 XNode cse_mat = root->getChild(
"CSEMAT");
133 XNode shader_node = cse_mat.getChild(
"shader");
135 auto var_nodes = shader_node.children;
136 auto shader_file_id = shader_node.getAttribute(
"id").value;
137 auto shaderGroup = Create<SShaderGroup>(shader_file_id);
138 if (shaderGroup ==
nullptr)
return;
139 m_shaders = shaderGroup;
141 if (shader_node.hasAttribute(
"deferred")) {
142 auto get_deferred = std::stoi(shader_node.getAttribute(
"deferred").value);
143 if (get_deferred == 1) {
148 for (
const auto& node : var_nodes) {
150 auto element_value = node.value.toStringVector();
151 auto element_type = node.getAttribute(
"type").value;
152 SType type = XMLParser::GetType(element_type);
153 auto element_name = node.getAttribute(
"name").value;
154 auto element_count = node.getAttribute(
"count").value;
156 auto element =
new Element;
157 element->type = type;
158 element->count = std::stoi(element_count);
159 element->valueStr = element_value;
160 m_elements.insert(std::pair<std::string, Element*>(element_name, element));
165void SMaterial::SetBindFuncByType(Element* element) {
166 const GLenum type = element->type;
169 SetFloatFunc(element, XMLParser::parseFloat(element->valueStr[0].c_str()));
172 SetIntFunc(element, XMLParser::parseInt(element->valueStr[0].c_str()));
181 SetVec4Func(element, XMLParser::parseVec4(element->valueStr));
184 SetVec3Func(element, XMLParser::parseVec3(element->valueStr));
187 SetTextureFunc(element, XMLParser::parseTexture(element->valueStr[0].c_str()));
192void SMaterial::SetIntFunc(Element* element,
int 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::SetFloatFunc(Element* element,
float value) {
201 if (element ==
nullptr)
return;
202 element->raw = std::to_string(value);
203 element->attachFunc = [element, value]() {
204 glUniform1f(element->id, value);
208void SMaterial::SetBoolFunc(Element* element,
bool value) {
209 if (element ==
nullptr)
return;
210 element->raw = std::to_string(value);
211 element->attachFunc = [element, value]() {
212 glUniform1i(element->id, value);
216void SMaterial::SetMat4Func(Element* element,
mat4 value) {
217 if (element ==
nullptr)
return;
218 element->attachFunc = [element, value]() {
219 glUniformMatrix4fv(element->id, element->count, 0, value.Pointer());
223void SMaterial::SetMat3Func(Element* element,
mat3 value) {
224 if (element ==
nullptr)
return;
225 element->attachFunc = [element, value]() {
226 glUniformMatrix3fv(element->id, element->count, 0, value.Pointer());
230void SMaterial::SetMat2Func(Element* element,
mat2 value) {
231 if (element ==
nullptr)
return;
232 element->attachFunc = [element, value]() {
233 glUniformMatrix2fv(element->id, element->count, 0, value.Pointer());
237void SMaterial::SetVec4Func(Element* element,
vec4 value) {
238 element->attachFunc = [element, value]() {
239 element->raw = std::to_string(value.x) +
" "
240 + std::to_string(value.y) +
" "
241 + std::to_string(value.z) +
" "
242 + std::to_string(value.w);
243 glUniform4fv(element->id, element->count, value.Pointer());
247void SMaterial::SetVec3Func(Element* element,
vec3 value) {
248 if (element ==
nullptr)
return;
249 element->raw = std::to_string(value.x) +
" "
250 + std::to_string(value.y) +
" "
251 + std::to_string(value.z);
252 element->attachFunc = [element, value]() {
253 glUniform3fv(element->id, element->count, value.Pointer());
257void SMaterial::SetVec2Func(Element* element,
vec2 value) {
258 if (element ==
nullptr)
return;
259 element->raw = std::to_string(value.x) +
" "
260 + std::to_string(value.y);
261 element->attachFunc = [element, value]() {
262 glUniform2fv(element->id, element->count, value.Pointer());
266void SMaterial::SetTextureFunc(Element* element,
SResource* texture) {
267 if (element ==
nullptr || texture ==
nullptr)
return;
268 auto value =
static_cast<STexture*
>(texture);
270 auto* texture_layout = &m_textureLayout;
272 element->raw = texture->GetHash();
273 element->attachFunc = [element, value, texture_layout]() {
274 value->Bind(element->id, *texture_layout);
279short SMaterial::GetOrderLayer()
const {
283void SMaterial::SetOrderLayer(
int orderLayer) {
284 m_orderLayer = orderLayer;
291SMaterial::SMaterialMode SMaterial::GetMode()
const {
295void SMaterial::SetMode(SMaterialMode mode) {
299int SMaterial::GetTextureCount()
const {
300 return m_textureLayout;
304 if (shaders ==
nullptr)
return nullptr;
305 const auto& handle = shaders->GetHandleByMode(SMaterialMode::FORWARD);
307 const auto& uniformList = handle->GetUniformsList();
309 material->m_shaders = shaders;
311 for (
const auto& uniform_pair : uniformList) {
312 const auto& name = uniform_pair.first;
313 const auto& gl_element = uniform_pair.second;
315 auto element =
new Element;
316 element->id = gl_element->id;
317 element->type = XMLParser::GetType(gl_element->type);
319 material->m_elements.insert(std::pair<std::string, Element*>(name, element));
321 material->InitElements(material->m_elements, shaders);
326std::string SMaterial::PrintMaterial()
const {
327 std::string result =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
328 "<CSEMAT version=\"1.0.0\">\n";
330 if(m_mode == DEFERRED) {
331 result +=
"<shader id=\"" + m_shaders->GetHash() +
"\" deferred=\"1\">\n";
334 result +=
"<shader id=\"" + m_shaders->GetHash() +
"\">\n";
337 for (
const auto& var : m_elements) {
338 const auto& element = var.second;
339 if(element->raw.empty())
continue;
341 result +=
"<var name=\"" + var.first
342 +
"\" type=\"" + XMLParser::ToString(element->type)
344 + element->raw +
"</var>\n";
346 result +=
"</shader>\n</CSEMAT>";
354std::string SMaterial::PrintValue()
const {
void SetValue(std::string name_str, Arguments value) override