SleakEngine 0.1.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
Material.cpp
Go to the documentation of this file.
5
6namespace Sleak {
7
8namespace {
9void AdoptTexture(RefPtr<Texture>& slot, Texture* texture) {
10 if (slot.get() != texture) slot = RefPtr<Texture>(texture);
11}
12} // namespace
13
14 Material::Material() : Object("Material") {}
15
16 Material::~Material() = default;
17
18 /// Lazily allocates the material's constant buffer on first use.
20 if (!m_materialBuffer) {
21 m_materialBuffer = ObjectPtr<RenderEngine::BufferBase>(
25 nullptr));
26 m_materialBuffer->SetSlot(1);
27 }
28 }
29
30 /// Binds shader, all set textures, and uploads the packed material CB for a forward draw.
32 if (m_shader) {
33 m_shader->bind();
34 }
35
36 if (m_diffuseTexture)
37 m_diffuseTexture->Bind(TEXTURE_SLOT_DIFFUSE);
38 if (m_normalTexture)
39 m_normalTexture->Bind(TEXTURE_SLOT_NORMAL);
40 if (m_specularTexture)
41 m_specularTexture->Bind(TEXTURE_SLOT_SPECULAR);
42 if (m_roughnessTexture)
43 m_roughnessTexture->Bind(TEXTURE_SLOT_ROUGHNESS);
44 if (m_metallicTexture)
45 m_metallicTexture->Bind(TEXTURE_SLOT_METALLIC);
46 if (m_aoTexture)
47 m_aoTexture->Bind(TEXTURE_SLOT_AO);
48 if (m_emissiveTexture)
49 m_emissiveTexture->Bind(TEXTURE_SLOT_EMISSIVE);
50
51 if (m_materialBuffer) {
52 RenderEngine::MaterialGPUData data = BuildGPUData();
53 m_materialBuffer->Update(&data, sizeof(data));
54 m_materialBuffer->Update();
55 }
56 }
57
58 /// Packs texture-presence flags and material scalars into the GPU constant buffer layout.
59 RenderEngine::MaterialGPUData Material::BuildGPUData() const {
61
62 data.HasDiffuseMap = m_diffuseTexture.IsValid() ? 1u : 0u;
63 data.HasNormalMap = m_normalTexture.IsValid() ? 1u : 0u;
64 data.HasSpecularMap = m_specularTexture.IsValid() ? 1u : 0u;
65 data.HasRoughnessMap = m_roughnessTexture.IsValid() ? 1u : 0u;
66 data.HasMetallicMap = m_metallicTexture.IsValid() ? 1u : 0u;
67 data.HasAOMap = m_aoTexture.IsValid() ? 1u : 0u;
68 data.HasEmissiveMap = m_emissiveTexture.IsValid() ? 1u : 0u;
69 data._pad0 = 0;
70
71 Math::Vector4D diffNorm = m_diffuseColor.normalize();
72 data.DiffuseR = diffNorm.GetX();
73 data.DiffuseG = diffNorm.GetY();
74 data.DiffuseB = diffNorm.GetZ();
75 data.DiffuseA = diffNorm.GetW();
76
77 Math::Vector4D specNorm = m_specularColor.normalize();
78 data.SpecularR = specNorm.GetX();
79 data.SpecularG = specNorm.GetY();
80 data.SpecularB = specNorm.GetZ();
81 data.Shininess = m_shininess;
82
83 Math::Vector4D emitNorm = m_emissiveColor.normalize();
84 data.EmissiveR = emitNorm.GetX();
85 data.EmissiveG = emitNorm.GetY();
86 data.EmissiveB = emitNorm.GetZ();
87 data.EmissiveIntensity = m_emissiveIntensity;
88
89 data.Metallic = m_metallic;
90 data.Roughness = m_roughness;
91 data.AO = m_ao;
92 data.NormalIntensity = m_normalIntensity;
93
94 data.TilingX = m_tilingX;
95 data.TilingY = m_tilingY;
96 data.OffsetX = m_offsetX;
97 data.OffsetY = m_offsetY;
98
99 data.Opacity = m_opacity;
100 data.AlphaCutoff = m_alphaCutoff;
101 data._pad1 = 0.0f;
102 data._pad2 = 0.0f;
103
104 return data;
105 }
106
107 /// True when this material must skip the GBuffer and render in the forward transparent pass.
109 return m_renderMode == MaterialRenderMode::Transparent
110 || m_opacity < 1.0f;
111 }
112
113 /// Binds textures and uploads the material CB for the deferred geometry pass, skipping the shader bind.
115 // Same as Bind() but without shader->bind() — geometry pass overrides the shader.
116 if (m_diffuseTexture) m_diffuseTexture->Bind(TEXTURE_SLOT_DIFFUSE);
117 if (m_normalTexture) m_normalTexture->Bind(TEXTURE_SLOT_NORMAL);
118 if (m_specularTexture) m_specularTexture->Bind(TEXTURE_SLOT_SPECULAR);
119 if (m_roughnessTexture) m_roughnessTexture->Bind(TEXTURE_SLOT_ROUGHNESS);
120 if (m_metallicTexture) m_metallicTexture->Bind(TEXTURE_SLOT_METALLIC);
121 if (m_aoTexture) m_aoTexture->Bind(TEXTURE_SLOT_AO);
122 if (m_emissiveTexture) m_emissiveTexture->Bind(TEXTURE_SLOT_EMISSIVE);
123
124 if (m_materialBuffer) {
125 RenderEngine::MaterialGPUData data = BuildGPUData();
126 m_materialBuffer->Update(&data, sizeof(data));
127 m_materialBuffer->Update();
128 }
129 }
130
132 m_shader = ObjectPtr<RenderEngine::Shader>(shader);
133 }
134
135 void Material::SetShader(const std::string& shaderPath) {
136 auto* shader =
138 if (shader)
139 m_shader = ObjectPtr<RenderEngine::Shader>(shader);
140 }
141
143 return m_shader.IsValid() ? m_shader.operator->() : nullptr;
144 }
145
147 m_diffuseTexture = texture;
148 }
149
151 AdoptTexture(m_diffuseTexture, texture);
152 }
153
154 void Material::SetDiffuseTexture(const std::string& path) {
155 m_diffuseTexture =
157 }
158
160 return m_diffuseTexture.get();
161 }
162
164 return m_diffuseTexture.IsValid();
165 }
166
168 m_normalTexture = texture;
169 }
170
172 AdoptTexture(m_normalTexture, texture);
173 }
174
175 void Material::SetNormalTexture(const std::string& path) {
176 m_normalTexture =
178 }
179
181 return m_normalTexture.get();
182 }
183
185 return m_normalTexture.IsValid();
186 }
187
189 m_specularTexture = texture;
190 }
191
193 AdoptTexture(m_specularTexture, texture);
194 }
195
196 void Material::SetSpecularTexture(const std::string& path) {
197 m_specularTexture =
199 }
200
202 return m_specularTexture.get();
203 }
204
206 return m_specularTexture.IsValid();
207 }
208
210 m_roughnessTexture = texture;
211 }
212
214 AdoptTexture(m_roughnessTexture, texture);
215 }
216
217 void Material::SetRoughnessTexture(const std::string& path) {
218 m_roughnessTexture =
220 }
221
223 return m_roughnessTexture.get();
224 }
225
227 return m_roughnessTexture.IsValid();
228 }
229
231 m_metallicTexture = texture;
232 }
233
235 AdoptTexture(m_metallicTexture, texture);
236 }
237
238 void Material::SetMetallicTexture(const std::string& path) {
239 m_metallicTexture =
241 }
242
244 return m_metallicTexture.get();
245 }
246
248 return m_metallicTexture.IsValid();
249 }
250
252 m_aoTexture = texture;
253 }
254
256 AdoptTexture(m_aoTexture, texture);
257 }
258
259 void Material::SetAOTexture(const std::string& path) {
260 m_aoTexture =
262 }
263
264 Texture* Material::GetAOTexture() const { return m_aoTexture.get(); }
265
267 return m_aoTexture.IsValid();
268 }
269
271 m_emissiveTexture = texture;
272 }
273
275 AdoptTexture(m_emissiveTexture, texture);
276 }
277
278 void Material::SetEmissiveTexture(const std::string& path) {
279 m_emissiveTexture =
281 }
282
284 return m_emissiveTexture.get();
285 }
286
288 return m_emissiveTexture.IsValid();
289 }
290
292 m_diffuseColor = color;
293 }
294
295 void Material::SetDiffuseColor(uint8_t r, uint8_t g, uint8_t b,
296 uint8_t a) {
297 m_diffuseColor = Math::Color(r, g, b, a);
298 }
299
300 void Material::SetDiffuseColor(float r, float g, float b, float a) {
301 m_diffuseColor = Math::Color(
302 static_cast<uint8_t>(r * 255.0f),
303 static_cast<uint8_t>(g * 255.0f),
304 static_cast<uint8_t>(b * 255.0f),
305 static_cast<uint8_t>(a * 255.0f));
306 }
307
308 Math::Color Material::GetDiffuseColor() const { return m_diffuseColor; }
309
311 m_specularColor = color;
312 }
313
314 void Material::SetSpecularColor(uint8_t r, uint8_t g, uint8_t b,
315 uint8_t a) {
316 m_specularColor = Math::Color(r, g, b, a);
317 }
318
320 return m_specularColor;
321 }
322
324 m_emissiveColor = color;
325 }
326
327 void Material::SetEmissiveColor(uint8_t r, uint8_t g, uint8_t b) {
328 m_emissiveColor = Math::Color(r, g, b, 255);
329 }
330
331 void Material::SetEmissiveColor(float r, float g, float b) {
332 m_emissiveColor = Math::Color(
333 static_cast<uint8_t>(r * 255.0f),
334 static_cast<uint8_t>(g * 255.0f),
335 static_cast<uint8_t>(b * 255.0f), 255);
336 }
337
339 return m_emissiveColor;
340 }
341
342 void Material::SetShininess(float shininess) {
343 m_shininess = shininess;
344 }
345
346 float Material::GetShininess() const { return m_shininess; }
347
348 void Material::SetMetallic(float metallic) {
349 m_metallic = metallic;
350 }
351
352 float Material::GetMetallic() const { return m_metallic; }
353
354 void Material::SetRoughness(float roughness) {
355 m_roughness = roughness;
356 }
357
358 float Material::GetRoughness() const { return m_roughness; }
359
360 void Material::SetAO(float ao) { m_ao = ao; }
361
362 float Material::GetAO() const { return m_ao; }
363
364 void Material::SetNormalIntensity(float intensity) {
365 m_normalIntensity = intensity;
366 }
367
368 float Material::GetNormalIntensity() const { return m_normalIntensity; }
369
370 void Material::SetEmissiveIntensity(float intensity) {
371 m_emissiveIntensity = intensity;
372 }
373
375 return m_emissiveIntensity;
376 }
377
378 void Material::SetOpacity(float opacity) { m_opacity = opacity; }
379
380 float Material::GetOpacity() const { return m_opacity; }
381
382 void Material::SetAlphaCutoff(float cutoff) {
383 m_alphaCutoff = cutoff;
384 }
385
386 float Material::GetAlphaCutoff() const { return m_alphaCutoff; }
387
388 void Material::SetTiling(float x, float y) {
389 m_tilingX = x;
390 m_tilingY = y;
391 }
392
394 m_tilingX = tiling.GetX();
395 m_tilingY = tiling.GetY();
396 }
397
399 return Math::Vector2D(m_tilingX, m_tilingY);
400 }
401
402 void Material::SetOffset(float x, float y) {
403 m_offsetX = x;
404 m_offsetY = y;
405 }
406
408 m_offsetX = offset.GetX();
409 m_offsetY = offset.GetY();
410 }
411
413 return Math::Vector2D(m_offsetX, m_offsetY);
414 }
415
417 m_renderMode = mode;
418 }
419
421 return m_renderMode;
422 }
423
424 void Material::SetTwoSided(bool twoSided) {
425 m_twoSided = twoSided;
426 }
427
428 bool Material::IsTwoSided() const { return m_twoSided; }
429
430}
#define TEXTURE_SLOT_DIFFUSE
Definition Material.hpp:15
#define TEXTURE_SLOT_METALLIC
Definition Material.hpp:19
#define TEXTURE_SLOT_NORMAL
Definition Material.hpp:16
#define TEXTURE_SLOT_SPECULAR
Definition Material.hpp:17
#define TEXTURE_SLOT_EMISSIVE
Definition Material.hpp:21
#define TEXTURE_SLOT_AO
Definition Material.hpp:20
#define TEXTURE_SLOT_ROUGHNESS
Definition Material.hpp:18
void SetRoughnessTexture(const RefPtr< Texture > &texture)
Definition Material.cpp:209
float GetAlphaCutoff() const
Definition Material.cpp:386
Math::Color GetEmissiveColor() const
Definition Material.cpp:338
Texture * GetRoughnessTexture() const
Definition Material.cpp:222
void SetShader(RenderEngine::Shader *shader)
Definition Material.cpp:131
Texture * GetMetallicTexture() const
Definition Material.cpp:243
bool HasNormalTexture() const
Definition Material.cpp:184
Math::Color GetSpecularColor() const
Definition Material.cpp:319
RenderEngine::Shader * GetShader() const
Definition Material.cpp:142
Texture * GetNormalTexture() const
Definition Material.cpp:180
void SetAOTexture(const RefPtr< Texture > &texture)
Definition Material.cpp:251
void SetAO(float ao)
Definition Material.cpp:360
void SetOpacity(float opacity)
Definition Material.cpp:378
Texture * GetDiffuseTexture() const
Definition Material.cpp:159
void SetMetallic(float metallic)
Definition Material.cpp:348
void SetShininess(float shininess)
Definition Material.cpp:342
void SetEmissiveTexture(const RefPtr< Texture > &texture)
Definition Material.cpp:270
bool HasEmissiveTexture() const
Definition Material.cpp:287
void SetOffset(float x, float y)
Definition Material.cpp:402
bool IsTwoSided() const
Definition Material.cpp:428
bool HasAOTexture() const
Definition Material.cpp:266
~Material() override
float GetOpacity() const
Definition Material.cpp:380
void SetDiffuseTexture(const RefPtr< Texture > &texture)
Definition Material.cpp:146
void SetNormalTexture(const RefPtr< Texture > &texture)
Definition Material.cpp:167
void SetSpecularColor(Math::Color color)
Definition Material.cpp:310
float GetShininess() const
Definition Material.cpp:346
Texture * GetEmissiveTexture() const
Definition Material.cpp:283
void SetRenderMode(MaterialRenderMode mode)
Definition Material.cpp:416
float GetAO() const
Definition Material.cpp:362
void SetAlphaCutoff(float cutoff)
Definition Material.cpp:382
void Initialize()
Lazily allocates the material's constant buffer on first use.
Definition Material.cpp:19
bool HasRoughnessTexture() const
Definition Material.cpp:226
void BindTexturesAndCB()
Binds textures and uploads the material CB for the deferred geometry pass, skipping the shader bind.
Definition Material.cpp:114
bool HasSpecularTexture() const
Definition Material.cpp:205
void SetSpecularTexture(const RefPtr< Texture > &texture)
Definition Material.cpp:188
Texture * GetSpecularTexture() const
Definition Material.cpp:201
Math::Vector2D GetTiling() const
Definition Material.cpp:398
Math::Color GetDiffuseColor() const
Definition Material.cpp:308
void SetMetallicTexture(const RefPtr< Texture > &texture)
Definition Material.cpp:230
void SetTwoSided(bool twoSided)
Definition Material.cpp:424
MaterialRenderMode GetRenderMode() const
Definition Material.cpp:420
bool HasDiffuseTexture() const
Definition Material.cpp:163
void SetNormalIntensity(float intensity)
Definition Material.cpp:364
Math::Vector2D GetOffset() const
Definition Material.cpp:412
void SetEmissiveColor(Math::Color color)
Definition Material.cpp:323
void SetDiffuseColor(Math::Color color)
Definition Material.cpp:291
void SetRoughness(float roughness)
Definition Material.cpp:354
bool IsForwardRendered() const
True when this material must skip the GBuffer and render in the forward transparent pass.
Definition Material.cpp:108
Texture * GetAOTexture() const
Definition Material.cpp:264
float GetNormalIntensity() const
Definition Material.cpp:368
float GetRoughness() const
Definition Material.cpp:358
void SetTiling(float x, float y)
Definition Material.cpp:388
float GetMetallic() const
Definition Material.cpp:352
void SetEmissiveIntensity(float intensity)
Definition Material.cpp:370
void Bind()
Binds shader, all set textures, and uploads the packed material CB for a forward draw.
Definition Material.cpp:31
float GetEmissiveIntensity() const
Definition Material.cpp:374
bool HasMetallicTexture() const
Definition Material.cpp:247
Vector4D normalize() const noexcept
Converts to a Vector4D with each channel in [0,1].
Definition Color.hpp:93
constexpr float GetY() const
Definition Vector.hpp:218
constexpr float GetX() const
Definition Vector.hpp:217
Object(const std::string &name="Object")
Definition Object.hpp:14
friend class RefPtr
Definition RefPtr.hpp:65
static Shader * CreateShader(const std::string &ShaderPath)
Compiles a shader via the currently registered backend factory.
static Sleak::Texture * CreateTexture(const std::string &TexturePath)
Loads a texture via the currently registered backend factory.
static BufferBase * CreateBuffer(BufferType Type, uint32_t Size, void *Data)
Creates a buffer via the currently registered backend factory.
Backend-agnostic compiled shader program.
Definition Shader.hpp:11
MaterialRenderMode
Definition Material.hpp:33
Root namespace for everything the engine exposes.
Definition Camera.hpp:10
Packed PBR material parameters uploaded to the material constant buffer.