CSEngine
Loading...
Searching...
No Matches
SMaterial.cpp
1#include "SMaterial.h"
2
3#include "../Loader/XML/XML.h"
4#include "../Loader/XML/XMLParser.h"
5#include "ShaderUtil.h"
6#include "../../Manager/LightMgr.h"
7#include "../Settings.h"
8
9using namespace CSE;
10
11SMaterial::SMaterial() {
12 m_lightMgr = CORE->GetCore(LightMgr);
13}
14
15SMaterial::SMaterial(const SMaterial* material) : SResource(material, false) {
16
17 if (material == nullptr) throw -1;
18
19 m_refHash = material->m_hash;
20
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));
28 }
29 m_mode = material->m_mode;
30 m_shaders = material->m_shaders;
31 m_orderLayer = material->m_orderLayer;
32 m_textureLayout = material->m_textureLayout;
33
34 InitElements(m_elements, m_shaders);
35 m_lightMgr = CORE->GetCore(LightMgr);
36}
37
38SMaterial::~SMaterial() {
39 ReleaseElements();
40}
41
42void SMaterial::Exterminate() {
43 ReleaseElements();
44}
45
46void SMaterial::ReleaseElements() {
47 for (const auto& pair : m_elements) {
48 auto* element = pair.second;
49 SAFE_DELETE(element);
50 }
51 m_elements.clear();
52}
53
54void SMaterial::AttachElement() const {
55 m_textureLayout = m_lightMgr->GetShadowCount();
56
57 for (const auto& element_pair : m_elements) {
58 const auto& element = element_pair.second;
59 if (element->id < 0) continue;
60 element->attachFunc();
61 }
62}
63
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;
70
71 const auto& handleElement = handle->UniformLocation(element_name);
72 if (handleElement == nullptr) continue;
73
74 element->id = handleElement->id;
75 SetBindFuncByType(element);
76 }
77// std::string str = PrintMaterial();
78// std::string path = GetAssetReference(m_refHash)->path;
79// SaveTxtFile(path, str);
80}
81
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);
86}
87
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);
92}
93
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);
98}
99
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);
104}
105
106void SMaterial::Init(const AssetMgr::AssetReference* asset) {
107 const XNode* root;
108
109 try {
110 root = XFILE(asset->name_path.c_str()).getRoot();
111 }
112 catch (int e) {
113 return;
114 }
115
116 XNode cse_mat = root->getChild("CSEMAT");
117 XNode shader_node = cse_mat.getChild("shader");
118
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;
124
125 if (shader_node.hasAttribute("deferred")) {
126 auto get_deferred = std::stoi(shader_node.getAttribute("deferred").value);
127 if (get_deferred == 1) {
128 m_mode = DEFERRED;
129 }
130 }
131
132 for (const auto& node : var_nodes) {
133
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;
139
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));
145 }
146 SAFE_DELETE(root);
147}
148
149void SMaterial::SetBindFuncByType(Element* element) {
150 const GLenum type = element->type;
151 switch (type) {
152 case FLOAT:
153 SetFloatFunc(element, XMLParser::parseFloat(element->valueStr[0].c_str()));
154 break;
155 case INT:
156 SetIntFunc(element, XMLParser::parseInt(element->valueStr[0].c_str()));
157 break;
158 // case SType::MAT4:
159 // SetMat4Func(element, XMLParser::parseMat4(element->valueStr));
160 // break;
161 // case SType::MAT3:
162 // SetMat3Func(element, XMLParser::parseMat3(element->valueStr));
163 // break;
164 case VEC4:
165 SetVec4Func(element, XMLParser::parseVec4(element->valueStr));
166 break;
167 case VEC3:
168 SetVec3Func(element, XMLParser::parseVec3(element->valueStr));
169 break;
170 case TEXTURE:
171 SetTextureFunc(element, XMLParser::parseTexture(element->valueStr[0].c_str()));
172 break;
173 }
174}
175
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);
181 };
182}
183
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);
189 };
190}
191
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);
197 };
198}
199
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());
204 };
205}
206
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());
211 };
212}
213
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());
218 };
219}
220
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());
228 };
229}
230
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());
238 };
239}
240
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());
247 };
248}
249
250void SMaterial::SetTextureFunc(Element* element, SResource* texture) {
251 if (element == nullptr || texture == nullptr) return;
252 auto value = static_cast<STexture*>(texture);
253 // element->count = m_textureLayout++;
254 auto* texture_layout = &m_textureLayout;
255 ++m_textureCount;
256 element->raw = texture->GetHash();
257 element->attachFunc = [element, value, texture_layout]() {
258 value->Bind(element->id, *texture_layout);
259 ++(*texture_layout);
260 };
261}
262
263short SMaterial::GetOrderLayer() const {
264 return m_orderLayer;
265}
266
267void SMaterial::SetOrderLayer(int orderLayer) {
268 m_orderLayer = orderLayer;
269}
270
271SShaderGroup* SMaterial::GetShaders() const {
272 return m_shaders;
273}
274
275SMaterial::SMaterialMode SMaterial::GetMode() const {
276 return m_mode;
277}
278
279void SMaterial::SetMode(SMaterialMode mode) {
280 m_mode = mode;
281}
282
283int SMaterial::GetTextureCount() const {
284 return m_textureLayout;
285}
286
287SMaterial* SMaterial::GenerateMaterial(SShaderGroup* shaders) {
288 if (shaders == nullptr) return nullptr;
289 const auto& handle = shaders->GetHandleByMode(SMaterialMode::NORMAL);
290
291 const auto& uniformList = handle->GetUniformsList();
292 auto material = new SMaterial();
293 material->m_shaders = shaders;
294
295 for (const auto& uniform_pair : uniformList) {
296 const auto& name = uniform_pair.first;
297 const auto& gl_element = uniform_pair.second;
298
299 auto element = new Element;
300 element->id = gl_element->id;
301 element->type = XMLParser::GetType(gl_element->type);
302
303 material->m_elements.insert(std::pair<std::string, Element*>(name, element));
304 }
305 material->InitElements(material->m_elements, shaders);
306
307 return material;
308}
309
310std::string SMaterial::PrintMaterial() const {
311 std::string result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
312 "<CSEMAT version=\"1.0.0\">\n";
313
314 if(m_mode == DEFERRED) {
315 result += "<shader id=\"" + m_shaders->GetHash() + "\" deferred=\"1\">\n";
316 }
317 else {
318 result += "<shader id=\"" + m_shaders->GetHash() + "\">\n";
319 }
320
321 for (const auto& var : m_elements) {
322 const auto& element = var.second;
323 if(element->raw.empty()) continue;
324
325 result += "<var name=\"" + var.first
326 + "\" type=\"" + XMLParser::ToString(element->type)
327 + "\" count=\"1\">"
328 + element->raw + "</var>\n";
329 }
330 result += "</shader>\n</CSEMAT>";
331 return result;
332}
int GetShadowCount() const
Definition LightMgr.h:56
Definition XML.h:77
Definition XML.h:43