Loading...
Searching...
No Matches
Material.h
Go to the documentation of this file.
1#pragma once
2#include <iostream>
3#include <string>
4#include <unordered_map>
5#include <unordered_set>
6#include <variant>
7#include <optional>
8#include <glm/glm.hpp>
9#include <nlohmann/json.hpp>
10
12#include "hellfire/graphics/texture/Texture.h"
13
14namespace hellfire {
15 class MaterialInstance;
16 class Application;
17 class ShaderManager;
18}
19
20namespace hellfire {
22 public:
23 enum class PropertyType {
25 };
26
27 struct Property {
29 std::string name;
30 std::variant<float, glm::vec2, glm::vec3, glm::vec4, Texture *, bool, int, glm::mat3, glm::mat4> value;
31
32 std::string uniform_name;
33
34 Property() = default;
35
36 Property(const std::string &name, float value, const std::string &uniform = "") : type(PropertyType::FLOAT),
37 name(name), value(value), uniform_name(uniform.empty() ? name : uniform) {
38 }
39
40 Property(const std::string &name, const glm::vec2 &value,
41 const std::string &uniform = "") : type(PropertyType::VEC2), value(value),
42 uniform_name(uniform.empty() ? name : uniform), name(name) {
43 }
44
45 Property(const std::string &name, const glm::vec3 &value,
46 const std::string &uniform = "") : type(PropertyType::VEC3), value(value),
47 uniform_name(uniform.empty() ? name : uniform), name(name) {
48 }
49
50 Property(const std::string &name, const glm::vec3 &value, PropertyType type,
51 const std::string &uniform = "")
52 : type(type), name(name), value(value),
53 uniform_name(uniform.empty() ? name : uniform) {
54 }
55
56 Property(const std::string &name, const glm::vec4 &value, PropertyType type,
57 const std::string &uniform = "")
58 : type(type), name(name), value(value),
59 uniform_name(uniform.empty() ? name : uniform) {
60 }
61
62 Property(const std::string &name, const glm::vec4 &value, const std::string &uniform = "") : name(name),
63 type(PropertyType::VEC4), value(value), uniform_name(uniform.empty() ? name : uniform) {
64 }
65
66 Property(const std::string &name, Texture *value, const std::string &uniform = "") : name(name),
67 type(PropertyType::TEXTURE), value(value), uniform_name(uniform.empty() ? name : uniform) {
68 }
69
70 Property(const std::string &name, bool value, const std::string &uniform = "") : name(name),
71 type(PropertyType::BOOL), value(value), uniform_name(uniform.empty() ? name : uniform) {
72 }
73
74 Property(const std::string &name, int value, const std::string &uniform = "") : name(name),
75 type(PropertyType::INT), value(value), uniform_name(uniform.empty() ? name : uniform) {
76 }
77
78 Property(const std::string &name, const glm::mat3 &value, const std::string &uniform = "") : name(name),
79 type(PropertyType::MAT3), value(value), uniform_name(uniform.empty() ? name : uniform) {
80 }
81
82 Property(const std::string &name, const glm::mat4 &value, const std::string &uniform = "") : name(name),
83 type(PropertyType::MAT4), value(value), uniform_name(uniform.empty() ? name : uniform) {
84 }
85 };
86
87 struct ShaderInfo {
88 std::string vertex_path;
89 std::string fragment_path;
90 std::optional<std::string> geometry_path;
92 std::unordered_map<std::string, std::string> uniform_mappings; // Property name -> uniform name
93
94 bool is_valid() const {
95 return !vertex_path.empty() && !fragment_path.empty();
96 }
97 };
98
99 private:
100 std::string name_;
104
105 // Instancing support
106 std::shared_ptr<Material> base_material_;
109
110 public:
111 explicit Material(const std::string &name) : name_(name) {}
112
113 // Generic Property Setters
114 template<typename T>
115 void set_property(const std::string &name, const T &value, PropertyType type,
116 const std::string &uniform_name = "") {
117 properties_[name] = Property(name, value, type, uniform_name);
118 }
119
120 template<typename T>
121 void set_property(const std::string &name, const T &value, const std::string &uniform_name = "") {
122 properties_[name] = Property(name, value, uniform_name);
123 }
124
125 // Generic Property Getter
126 template<typename T>
127 T get_property(const std::string &name, const T &default_value = T{}) const {
128 if (const auto it = properties_.find(name); it != properties_.end()) {
129 if (auto *val = std::get_if<T>(&it->second.value)) {
130 return *val;
131 }
132 }
133 return default_value;
134 }
135
136 // Texture Management
137 Material& set_texture(const std::string &path, TextureType type, int texture_slot = 0) {
138 auto* texture = new Texture(path, type);
139 return set_texture_internal(texture, type, texture_slot);
140 }
141
142 Material& set_texture(const std::shared_ptr<Texture> &texture, int texture_slot = 0) {
143 return set_texture_internal(texture.get(), texture->get_type(), texture_slot);
144 }
145
146 Material& set_texture(Texture* texture, int texture_slot = 0) {
147 return set_texture_internal(texture, texture->get_type(), texture_slot);
148 }
149
150 // Color Setters
151 void set_diffuse_color(const glm::vec3 &color) {
153 }
154
155 void set_ambient_color(const glm::vec3 &color) {
157 }
158
159 void set_specular_color(const glm::vec3 &color) {
161 }
162
163 void set_emissive_color(const glm::vec3 &color) {
165 }
166
167 // Material Property Setters
168 void set_shininess(float shininess) {
169 set_property(MaterialConstants::SHININESS, shininess);
170 }
171
172 void set_metallic(float metallic) {
173 set_property(MaterialConstants::METALLIC, metallic);
174 }
175
176 void set_roughness(float roughness) {
177 set_property(MaterialConstants::ROUGHNESS, roughness);
178 }
179
180 void set_opacity(float opacity) {
181 set_property(MaterialConstants::OPACITY, glm::clamp(opacity, 0.0f, 1.0f));
182 }
183
184 bool is_transparent() const {
185 return get_property<float>(MaterialConstants::OPACITY, 1.0f) < 1.0f;
186 }
187
188 // UV Transform
189 void set_uv_tiling(const glm::vec2 &tiling) {
190 set_property(MaterialConstants::UV_TILING, tiling);
191 }
192
193 void set_uv_tiling(float x, float y) {
194 set_uv_tiling(glm::vec2(x, y));
195 }
196
197 void set_uv_offset(const glm::vec2 &offset) {
198 set_property(MaterialConstants::UV_OFFSET, offset);
199 }
200
201 void set_uv_rotation(float rotation) {
202 set_property(MaterialConstants::UV_ROTATION, rotation);
203 }
204
205 // Custom Shader Support
206 void set_custom_shader(const std::string &vertex_path, const std::string &fragment_path) {
207 custom_shader_info_ = ShaderInfo{vertex_path, fragment_path};
208 }
209
210 void set_custom_shader(const ShaderInfo &shader_info) {
211 custom_shader_info_ = shader_info;
212 }
213
214 void add_shader_define(const std::string &define) {
215 if (custom_shader_info_) {
216 custom_shader_info_->defines.insert(define);
217 }
218 }
219
220 void set_uniform_mapping(const std::string &property_name, const std::string &uniform_name) {
221 if (custom_shader_info_) {
222 custom_shader_info_->uniform_mappings[property_name] = uniform_name;
223 }
224 }
225
226 bool has_custom_shader() const {
227 return custom_shader_info_ && custom_shader_info_->is_valid();
228 }
229
231 return custom_shader_info_ ? &*custom_shader_info_ : nullptr;
232 }
233
234 void set_compiled_shader_id(uint32_t shader_id) {
235 compiled_shader_id_ = shader_id;
236 }
237
238 uint32_t get_compiled_shader_id() const {
239 return compiled_shader_id_;
240 }
241
242 /// Used to bind a Material for rendering
243 void bind() const;
244 void unbind() const;
245
246 void unbind_all_textures() const;
247
248 // Getters
249 const auto &get_properties() const { return properties_; }
250 const std::string &get_name() const { return name_; }
251 void set_name(const std::string &name) { name_ = name; }
252 private:
254
255 Material& set_texture_internal(Texture* texture, TextureType type, int texture_slot) {
256 const char* uniform_name = MaterialConstants::get_texture_uniform_name(type);
257 const char* flag_name = MaterialConstants::get_texture_flag_name(type);
258
259 if (!uniform_name || !flag_name) {
260 std::cerr << "Warning: Unsupported texture type" << std::endl;
261 return *this;
262 }
263
264 if (texture_slot >= 0) {
265 texture->set_slot(texture_slot);
266 set_property(uniform_name + std::string("Slot"), texture_slot);
267 }
268
269 set_property(uniform_name, texture, uniform_name);
270 set_property(flag_name, texture != nullptr);
271
272 return *this;
273 }
274
275 void bind_all_properties(uint32_t shader_program, int &texture_unit) const;
276
277 bool has_property(const std::string &name) const {
278 return properties_.find(name) != properties_.end();
279 }
280
281 Property get_property_object(const std::string &name) const {
282 if (const auto it = properties_.find(name); it != properties_.end()) {
283 return it->second;
284 }
285 return Property{}; // Return default property
286 }
287 };
288
290 public:
291 static std::shared_ptr<Material> create(const std::string &name);
292 static std::shared_ptr<Material> create_custom(const std::string &name,
293 const std::string &vertex_path,
294 const std::string &fragment_path);
295 private:
296 static void compile_shader_from_material(Material &material);
297 };
298}
Definition IB.h:7
void pass_data(const T *data, size_t count) const
Definition IB.h:18
IB()
Definition IB.cpp:6
void pass_data(const std::vector< T > &data) const
Definition IB.h:24
uint32_t m_renderer_id_
Definition IB.h:8
void unbind()
Definition IB.cpp:21
~IB()
Definition IB.cpp:11
void bind()
Definition IB.cpp:16
Definition VA.h:7
void bind() const
Definition VA.cpp:16
uint32_t m_renderer_id_
Definition VA.h:8
~VA()
Definition VA.cpp:11
VA()
Definition VA.cpp:6
uint32_t get_id() const
Definition VA.cpp:25
void unbind()
Definition VA.cpp:20
Definition VB.h:7
void pass_data(const std::vector< T > &data) const
Definition VB.h:22
void unbind()
Definition VB.cpp:19
~VB()
Definition VB.cpp:9
void pass_dynamic_data(const std::vector< T > &data) const
Definition VB.h:28
uint32_t m_renderer_id_
Definition VB.h:8
void pass_data(const T *data, size_t count) const
Definition VB.h:16
void bind()
Definition VB.cpp:14
VB()
Definition VB.cpp:4
size_t get_loaded_mesh_count() const
std::unordered_map< AssetID, std::shared_ptr< Texture > > texture_cache_
AssetManager(AssetRegistry &registry)
std::shared_ptr< Mesh > get_mesh(AssetID id)
size_t get_loaded_material_count() const
void unload(AssetID id)
AssetRegistry & registry_
std::shared_ptr< Texture > get_texture(AssetID id, TextureType type)
std::unordered_map< AssetID, std::shared_ptr< Material > > material_cache_
size_t get_loaded_texture_count() const
std::shared_ptr< Material > get_material(AssetID id)
std::unordered_map< AssetID, std::shared_ptr< Mesh > > mesh_cache_
Registry for storing assets.
const std::filesystem::path & get_project_root()
std::optional< AssetID > get_uuid_by_path(const std::filesystem::path &filepath)
AssetID generate_uuid(const std::filesystem::path &filepath)
void unregister_asset(AssetID uuid)
bool has_asset_changed(AssetID uuid) const
void set_project_root(const std::filesystem::path &project_root)
std::filesystem::path get_absolute_path(AssetID uuid)
std::unordered_map< std::filesystem::path, AssetID > path_to_uuid_
std::filesystem::path registry_file_
AssetID register_asset(const std::filesystem::path &filepath, AssetType type)
std::unordered_map< AssetID, AssetMetadata > assets_
std::filesystem::path to_absolute_path(const std::filesystem::path &relative_path) const
static AssetType get_type_from_extension(const std::filesystem::path &filepath)
std::filesystem::path to_relative_path(const std::filesystem::path &absolute_path) const
AssetID register_asset(const std::filesystem::path &filepath)
std::vector< AssetID > register_directory(const std::filesystem::path &directory_path, bool recursive)
std::vector< AssetMetadata > get_assets_by_type(AssetType type)
std::filesystem::path get_relative_path(AssetID uuid)
bool asset_exists(AssetID uuid) const
size_t get_asset_count() const
std::vector< AssetID > get_modified_assets() const
AssetRegistry(const std::filesystem::path &registry_file, const std::filesystem::path &project_root)
std::optional< AssetMetadata > get_asset(AssetID uuid) const
std::filesystem::path project_root_
std::vector< AssetMetadata > get_all_assets() const
uint64_t get_file_last_modified(const std::filesystem::path &filepath) const
static void compile_shader_from_material(Material &material)
Definition Material.cpp:96
static std::optional< MaterialData > load(const std::filesystem::path &filepath)
void set_ambient_color(const glm::vec3 &color)
Definition Material.h:155
void bind_all_properties(uint32_t shader_program, int &texture_unit) const
Definition Material.cpp:40
Material & set_texture(Texture *texture, int texture_slot=0)
Definition Material.h:146
std::map< std::string, Property > properties_
Definition Material.h:101
std::shared_ptr< Material > base_material_
Definition Material.h:106
std::string name_
Definition Material.h:100
std::vector< int > bound_texture_units_
Definition Material.h:253
Material & set_texture_internal(Texture *texture, TextureType type, int texture_slot)
Definition Material.h:255
void set_uv_offset(const glm::vec2 &offset)
Definition Material.h:197
void bind() const
Used to bind a Material for rendering.
Definition Material.cpp:11
bool is_transparent() const
Definition Material.h:184
uint32_t get_compiled_shader_id() const
Definition Material.h:238
void unbind_all_textures() const
Definition Material.cpp:31
std::unordered_map< std::string, Property > overrides_
Definition Material.h:107
void set_uv_tiling(float x, float y)
Definition Material.h:193
const std::string & get_name() const
Definition Material.h:250
void set_roughness(float roughness)
Definition Material.h:176
const auto & get_properties() const
Definition Material.h:249
void set_specular_color(const glm::vec3 &color)
Definition Material.h:159
std::optional< ShaderInfo > custom_shader_info_
Definition Material.h:102
std::unordered_set< std::string > touched_uniforms_
Definition Material.h:108
void set_uv_rotation(float rotation)
Definition Material.h:201
void set_compiled_shader_id(uint32_t shader_id)
Definition Material.h:234
Material & set_texture(const std::shared_ptr< Texture > &texture, int texture_slot=0)
Definition Material.h:142
void set_metallic(float metallic)
Definition Material.h:172
void set_uv_tiling(const glm::vec2 &tiling)
Definition Material.h:189
void set_diffuse_color(const glm::vec3 &color)
Definition Material.h:151
void set_opacity(float opacity)
Definition Material.h:180
uint32_t compiled_shader_id_
Definition Material.h:103
bool has_custom_shader() const
Definition Material.h:226
void set_emissive_color(const glm::vec3 &color)
Definition Material.h:163
void set_custom_shader(const ShaderInfo &shader_info)
Definition Material.h:210
void unbind() const
Definition Material.cpp:24
const ShaderInfo * get_shader_info() const
Definition Material.h:230
void set_shininess(float shininess)
Definition Material.h:168
static std::shared_ptr< Mesh > load(const std::filesystem::path &filepath)
bool is_wireframe
Definition Mesh.h:32
Mesh(const std::vector< Vertex > &vertices, const std::vector< unsigned int > &indices)
Definition Mesh.cpp:11
int get_index_count() const
Definition Mesh.cpp:96
void bind() const
Definition Mesh.cpp:22
std::unique_ptr< VA > vao_
Definition Mesh.h:41
void build()
Definition Mesh.cpp:30
std::unique_ptr< IB > ibo_
Definition Mesh.h:43
void create_mesh()
Definition Mesh.cpp:34
std::vector< Vertex > vertices
Definition Mesh.h:29
bool is_built() const
Definition Mesh.h:26
void draw() const
Definition Mesh.cpp:83
void unbind() const
Definition Mesh.cpp:26
Mesh(const std::vector< Vertex > &vertices, const std::vector< unsigned int > &indices, bool defer_build)
Definition Mesh.cpp:16
std::unique_ptr< VB > vbo_
Definition Mesh.h:42
std::vector< unsigned int > indices
Definition Mesh.h:30
void draw_instanced(size_t amount) const
Definition Mesh.cpp:89
int index_count_
Definition Mesh.h:45
TextureType get_type() const
Definition Texture.h:113
void set_slot(int slot)
Definition Texture.h:118
TextureType
Definition Texture.h:13
constexpr AssetID INVALID_ASSET_ID
Definition Vertex.h:5
glm::vec3 position
Definition Vertex.h:6
glm::vec3 color
Definition Vertex.h:8
glm::vec3 normal
Definition Vertex.h:7
glm::vec3 tangent
Definition Vertex.h:10
glm::vec3 bitangent
Definition Vertex.h:11
glm::vec2 texCoords
Definition Vertex.h:9
std::filesystem::path filepath
static constexpr const char * EMISSIVE_COLOR
static constexpr const char * UV_ROTATION
static constexpr const char * SPECULAR_COLOR
static constexpr const char * METALLIC
static const char * get_texture_flag_name(TextureType type)
static constexpr const char * ROUGHNESS
static constexpr const char * SHININESS
static constexpr const char * DIFFUSE_COLOR
static constexpr const char * AMBIENT_COLOR
static constexpr const char * UV_TILING
static constexpr const char * UV_OFFSET
static const char * get_texture_uniform_name(TextureType type)
static constexpr const char * OPACITY
std::variant< float, glm::vec2, glm::vec3, glm::vec4, Texture *, bool, int, glm::mat3, glm::mat4 > value
Definition Material.h:30
std::unordered_map< std::string, std::string > uniform_mappings
Definition Material.h:92
std::unordered_set< std::string > defines
Definition Material.h:91
std::optional< std::string > geometry_path
Definition Material.h:90