Monad Engine da02fba2
> Undercity Codex_
Loading...
Searching...
No Matches
Material.cpp
Go to the documentation of this file.
1#include <memory>
2
3#include "render/Material.h"
4
5#include <nlohmann/json.hpp>
6
7#include "Engine.h"
8#include "Log.h"
9#include "graphics/ShaderProgram.h"
10
11namespace mnd
12{
13
15{
16 return m_shaderProgram.get();
17}
18
19void Material::SetShaderProgram(const std::shared_ptr<ShaderProgram> &shaderProgram)
20{
21 m_shaderProgram = shaderProgram;
22}
23
24void Material::SetParam(const std::string &name, float value)
25{
26 m_floatParams[name] = value;
27}
28
29void Material::SetParam(const std::string &name, float v0, float v1)
30{
31 m_float2Params[name] = {v0, v1};
32}
33
34void Material::SetParam(const std::string &name, const vec3 &value)
35{
36 m_float3Params[name] = value;
37}
38
39void Material::SetParam(const std::string &name, const vec4 &value)
40{
41 m_float4Params[name] = value;
42}
43
44void Material::SetParam(const std::string &name, const std::shared_ptr<Texture> &texture)
45{
46 m_textures[name] = texture;
47}
48
49void Material::SetParam(const std::string &name, const std::vector<glm::mat4> &matrices)
50{
51 m_mat4ArrayParams[name] = matrices;
52}
53
54std::shared_ptr<Material> Material::Load(const str &path)
55{
56 auto contents = Engine::GetInstance().GetFileSystem().LoadAssetFileText(path);
57 if (contents.empty())
58 {
59 LOG_ERROR("Material::Load empty or missing file '%s'", path.c_str());
60 return nullptr;
61 }
62
63 nlohmann::json json;
64 try
65 {
66 json = nlohmann::json::parse(contents);
67 } catch (const nlohmann::json::parse_error &e)
68 {
69 LOG_ERROR("Material::Load JSON parse error in '%s': %s", path.c_str(), e.what());
70 return nullptr;
71 }
72 std::shared_ptr<Material> result;
73
74 if (json.contains("shader"))
75 {
76 auto shaderObj = json["shader"];
77 str vertexPath = shaderObj.value("vertex", "");
78 str fragmentPath = shaderObj.value("fragment", "");
79
81 auto vertexSource = fs.LoadAssetFileText(vertexPath);
82 auto fragmentSource = fs.LoadAssetFileText(fragmentPath);
83
84 auto &graphicsAPI = Engine::GetInstance().GetGraphicsAPI();
85 auto shaderProgram = graphicsAPI.CreateShaderProgram(vertexSource, fragmentSource);
86
87 if (!shaderProgram)
88 {
90 "Material::Load shader program creation failed (vert='%s' frag='%s')",
91 vertexPath.c_str(),
92 fragmentPath.c_str()
93 );
94 return nullptr;
95 }
96
97 result = std::make_shared<Material>();
98 result->SetShaderProgram(shaderProgram);
99 result->SetParam("color", vec3(1.0F));
100 }
101
102 if (json.contains("params"))
103 {
104 auto paramsObj = json["params"];
105
106 // Float
107 if (paramsObj.contains("float"))
108 {
109 for (auto &param : paramsObj["float"])
110 {
111 str name = param.value("name", "");
112 f32 value = param.value("value", 0.0f);
113 result->SetParam(name, value);
114 }
115 }
116
117 // Float 2
118 if (paramsObj.contains("float2"))
119 {
120 for (auto &param : paramsObj["float2"])
121 {
122 str name = param.value("name", "");
123 f32 v0 = param.value("value0", 0.0F);
124 f32 v1 = param.value("value1", 0.0F);
125
126 result->SetParam(name, v0, v1);
127 }
128 }
129
130 // Float 3
131 if (paramsObj.contains("float3"))
132 {
133 for (auto &param : paramsObj["float3"])
134 {
135 str name = param.value("name", "");
136 f32 v0 = param.value("value0", 0.0F);
137 f32 v1 = param.value("value1", 0.0F);
138 f32 v2 = param.value("value2", 0.0F);
139
140 result->SetParam(name, vec3(v0, v1, v2));
141 }
142 }
143
144 // Float 4
145 if (paramsObj.contains("float4"))
146 {
147 for (auto &param : paramsObj["float4"])
148 {
149 str name = param.value("name", "");
150 f32 v0 = param.value("value0", 0.0F);
151 f32 v1 = param.value("value1", 0.0F);
152 f32 v2 = param.value("value2", 0.0F);
153 f32 v3 = param.value("value3", 0.0F);
154
155 result->SetParam(name, vec4(v0, v1, v2, v3));
156 }
157 }
158
159 // Textures
160 if (paramsObj.contains("textures"))
161 {
162 for (auto &param : paramsObj["textures"])
163 {
164 str name = param.value("name", "");
165 str texPath = param.value("path", "");
166 auto texture = Texture::Load(texPath);
167
168 result->SetParam(name, texture);
169 }
170 }
171 }
172
173 return result;
174}
175
177{
178 if (!m_shaderProgram)
179 {
180 LOG_WARN("Material::Bind with no shader program set");
181 return;
182 }
183 m_shaderProgram->Bind();
184
185 for (const auto &param : m_floatParams)
186 {
187 m_shaderProgram->SetUniform(param.first, param.second);
188 }
189 for (const auto &param : m_float2Params)
190 {
191 auto &v = param.second;
192 m_shaderProgram->SetUniform(param.first, std::get<0>(v), std::get<1>(v));
193 }
194 for (const auto &param : m_float3Params)
195 {
196 auto &v = param.second;
197 m_shaderProgram->SetUniform(param.first, param.second);
198 }
199 for (const auto &param : m_float4Params)
200 {
201 auto &v = param.second;
202 m_shaderProgram->SetUniform(param.first, param.second);
203 }
204 for (const auto &tex : m_textures)
205 {
206 m_shaderProgram->SetTexture(tex.first, tex.second.get());
207 }
208 for (const auto &param : m_mat4ArrayParams)
209 {
210 m_shaderProgram->SetUniform(param.first, param.second.data(), param.second.size());
211 }
212}
213} // namespace mnd
Console logging macros for all engine and game code.
#define LOG_WARN(fmt,...)
Definition Log.h:80
#define LOG_ERROR(fmt,...)
Definition Log.h:81
GraphicsAPI & GetGraphicsAPI()
Returns the low-level OpenGL wrapper used for all draw calls.
Definition Engine.cpp:418
FileSystem & GetFileSystem()
Returns the file system helper for asset-relative path resolution.
Definition Engine.cpp:453
static Engine & GetInstance()
Returns the single Engine instance (created on first call).
Definition Engine.cpp:59
std::string LoadAssetFileText(const std::string &relativePath)
Load a text file from the assets directory into a string.
std::shared_ptr< ShaderProgram > CreateShaderProgram(const std::string &vertexSource, const std::string &fragmentSource)
Compile vertex + fragment GLSL source and link into a program.
void Bind()
Upload all stored parameters to the active ShaderProgram.
Definition Material.cpp:176
void SetShaderProgram(const std::shared_ptr< ShaderProgram > &shaderProgram)
Assign the GLSL program this material will use when drawn.
Definition Material.cpp:19
void SetParam(const std::string &name, float value)
Set a float uniform.
Definition Material.cpp:24
ShaderProgram * GetShaderProgram()
Returns the shader program assigned to this material.
Definition Material.cpp:14
static std::shared_ptr< Material > Load(const str &path)
Load a material from a descriptor file.
Definition Material.cpp:54
Linked GLSL program with cached uniform locations.
static std::shared_ptr< Texture > Load(const std::string &path)
Load a texture from a file path using stb_image.
Definition Texture.cpp:76
glm::vec4 vec4
4-component float vector (e.g. RGBA colour, homogeneous coords).
Definition Types.h:52
glm::vec3 vec3
3-component float vector (e.g. world position, RGB colour, normals).
Definition Types.h:51
std::string str
Convenience alias for std::string.
Definition Types.h:45
float f32
32-bit IEEE float — the standard GL scalar type.
Definition Types.h:40