CSEngine
Loading...
Searching...
No Matches
SMaterial.cpp
1#include "SMaterial.h"
2
3#include <utility>
4
5#include "../Loader/XML/XML.h"
6#include "../Loader/XML/XMLParser.h"
7#include "ShaderUtil.h"
8#include "../../Manager/LightMgr.h"
9#include "../Settings.h"
10
11using namespace CSE;
12
13RESOURCE_CONSTRUCTOR(SMaterial) {
14 m_lightMgr = CORE->GetCore(LightMgr);
15}
16
17SMaterial::SMaterial(const SMaterial* material) : SResource(material, false) {
18
19 if (material == nullptr) throw -1;
20
21 m_refHash = material->m_hash;
22
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));
30 }
31 m_mode = material->m_mode;
32 m_shaders = material->m_shaders;
33 m_orderLayer = material->m_orderLayer;
34 m_textureLayout = material->m_textureLayout;
35
36 InitElements(m_elements, m_shaders);
37 m_lightMgr = CORE->GetCore(LightMgr);
38}
39
40SMaterial::~SMaterial() {
41 ReleaseElements();
42}
43
44void SMaterial::Exterminate() {
45 ReleaseElements();
46}
47
48void SMaterial::ReleaseElements() {
49 for (const auto& pair : m_elements) {
50 auto* element = pair.second;
51 SAFE_DELETE(element);
52 }
53 m_elements.clear();
54}
55
56int SMaterial::AttachElement(int textureLayout) const {
57 m_textureLayout = textureLayout;
58
59 for (const auto& element_pair : m_elements) {
60 const auto& element = element_pair.second;
61 if (element->id < 0) continue;
62 element->attachFunc();
63 }
64 return m_textureLayout - textureLayout;
65}
66
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;
71}
72
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;
79
80 const auto& handleElement = handle->UniformLocation(element_name);
81 if (handleElement == nullptr) continue;
82
83 element->id = handleElement->id;
84 SetBindFuncByType(element);
85 }
86// std::string str = PrintMaterial();
87// std::string path = GetAssetReference(m_refHash)->path;
88// SaveTxtFile(path, str);
89}
90
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);
95}
96
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);
101}
102
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);
107}
108
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);
113}
114
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);
120}
121
122void SMaterial::Init(const AssetMgr::AssetReference* asset) {
123 const XNode* root;
124
125 try {
126 root = XFILE(asset->name_path.c_str()).getRoot();
127 }
128 catch (int e) {
129 return;
130 }
131
132 XNode cse_mat = root->getChild("CSEMAT");
133 XNode shader_node = cse_mat.getChild("shader");
134
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;
140
141 if (shader_node.hasAttribute("deferred")) {
142 auto get_deferred = std::stoi(shader_node.getAttribute("deferred").value);
143 if (get_deferred == 1) {
144 m_mode = DEFERRED;
145 }
146 }
147
148 for (const auto& node : var_nodes) {
149
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;
155
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));
161 }
162 SAFE_DELETE(root);
163}
164
165void SMaterial::SetBindFuncByType(Element* element) {
166 const GLenum type = element->type;
167 switch (type) {
168 case FLOAT:
169 SetFloatFunc(element, XMLParser::parseFloat(element->valueStr[0].c_str()));
170 break;
171 case INT:
172 SetIntFunc(element, XMLParser::parseInt(element->valueStr[0].c_str()));
173 break;
174 // case SType::MAT4:
175 // SetMat4Func(element, XMLParser::parseMat4(element->valueStr));
176 // break;
177 // case SType::MAT3:
178 // SetMat3Func(element, XMLParser::parseMat3(element->valueStr));
179 // break;
180 case VEC4:
181 SetVec4Func(element, XMLParser::parseVec4(element->valueStr));
182 break;
183 case VEC3:
184 SetVec3Func(element, XMLParser::parseVec3(element->valueStr));
185 break;
186 case TEXTURE:
187 SetTextureFunc(element, XMLParser::parseTexture(element->valueStr[0].c_str()));
188 break;
189 }
190}
191
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);
197 };
198}
199
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);
205 };
206}
207
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);
213 };
214}
215
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());
220 };
221}
222
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());
227 };
228}
229
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());
234 };
235}
236
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());
244 };
245}
246
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());
254 };
255}
256
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());
263 };
264}
265
266void SMaterial::SetTextureFunc(Element* element, SResource* texture) {
267 if (element == nullptr || texture == nullptr) return;
268 auto value = static_cast<STexture*>(texture);
269 // element->count = m_textureLayout++;
270 auto* texture_layout = &m_textureLayout;
271 // auto texture_layout = m_textureLayout++;
272 element->raw = texture->GetHash();
273 element->attachFunc = [element, value, texture_layout]() {
274 value->Bind(element->id, *texture_layout);
275 ++(*texture_layout);
276 };
277}
278
279short SMaterial::GetOrderLayer() const {
280 return m_orderLayer;
281}
282
283void SMaterial::SetOrderLayer(int orderLayer) {
284 m_orderLayer = orderLayer;
285}
286
287SShaderGroup* SMaterial::GetShaders() const {
288 return m_shaders;
289}
290
291SMaterial::SMaterialMode SMaterial::GetMode() const {
292 return m_mode;
293}
294
295void SMaterial::SetMode(SMaterialMode mode) {
296 m_mode = mode;
297}
298
299int SMaterial::GetTextureCount() const {
300 return m_textureLayout;
301}
302
303SMaterial* SMaterial::GenerateMaterial(SShaderGroup* shaders) {
304 if (shaders == nullptr) return nullptr;
305 const auto& handle = shaders->GetHandleByMode(SMaterialMode::FORWARD);
306
307 const auto& uniformList = handle->GetUniformsList();
308 auto material = new SMaterial();
309 material->m_shaders = shaders;
310
311 for (const auto& uniform_pair : uniformList) {
312 const auto& name = uniform_pair.first;
313 const auto& gl_element = uniform_pair.second;
314
315 auto element = new Element;
316 element->id = gl_element->id;
317 element->type = XMLParser::GetType(gl_element->type);
318
319 material->m_elements.insert(std::pair<std::string, Element*>(name, element));
320 }
321 material->InitElements(material->m_elements, shaders);
322
323 return material;
324}
325
326std::string SMaterial::PrintMaterial() const {
327 std::string result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
328 "<CSEMAT version=\"1.0.0\">\n";
329
330 if(m_mode == DEFERRED) {
331 result += "<shader id=\"" + m_shaders->GetHash() + "\" deferred=\"1\">\n";
332 }
333 else {
334 result += "<shader id=\"" + m_shaders->GetHash() + "\">\n";
335 }
336
337 for (const auto& var : m_elements) {
338 const auto& element = var.second;
339 if(element->raw.empty()) continue;
340
341 result += "<var name=\"" + var.first
342 + "\" type=\"" + XMLParser::ToString(element->type)
343 + "\" count=\"1\">"
344 + element->raw + "</var>\n";
345 }
346 result += "</shader>\n</CSEMAT>";
347 return result;
348}
349
350void SMaterial::SetValue(std::string name_str, VariableBinder::Arguments value) {
351
352}
353
354std::string SMaterial::PrintValue() const {
355 return {};
356}
void SetValue(std::string name_str, Arguments value) override
Definition XML.h:77
Definition XML.h:43