4#include <unordered_map>
5#include <unordered_set>
9#include <nlohmann/json.hpp>
12#include "hellfire/graphics/texture/Texture.h"
15 class MaterialInstance;
24 FLOAT,
VEC2,
VEC3,
COLOR3,
VEC4,
COLOR4,
TEXTURE,
TEXTURE_FLAG,
BOOL,
INT,
MAT3,
MAT4
41 Property(
const std::string &name,
const glm::vec2 &value,
46 Property(
const std::string &name,
const glm::vec3 &value,
51 Property(
const std::string &name,
const glm::vec3 &value,
PropertyType type,
52 const std::string &uniform =
"")
53 :
type(type),
name(name), value(value),
57 Property(
const std::string &name,
const glm::vec4 &value,
PropertyType type,
58 const std::string &uniform =
"")
59 :
type(type),
name(name), value(value),
63 Property(
const std::string &name,
const glm::vec4 &value,
const std::string &uniform =
"") :
name(name),
67 Property(
const std::string &name,
Texture *value,
const std::string &uniform =
"") :
name(name),
71 Property(
const std::string &name,
bool value,
const std::string &uniform =
"") :
name(name),
75 Property(
const std::string &name,
int value,
const std::string &uniform =
"") :
name(name),
79 Property(
const std::string &name,
const glm::mat3 &value,
const std::string &uniform =
"") :
name(name),
83 Property(
const std::string &name,
const glm::mat4 &value,
const std::string &uniform =
"") :
name(name),
112 explicit Material(
const std::string &name) :
name_(name) {}
116 void set_property(
const std::string &name,
const T &value,
PropertyType type,
117 const std::string &uniform_name =
"") {
118 properties_[name] = Property(name, value, type, uniform_name);
122 void set_property(
const std::string &name,
const T &value,
const std::string &uniform_name =
"") {
123 properties_[name] = Property(name, value, uniform_name);
128 T get_property(
const std::string &name,
const T &default_value = T{})
const {
129 if (
const auto it = properties_.find(name); it != properties_.end()) {
130 if (
auto *val = std::get_if<T>(&it->second.value)) {
134 return default_value;
139 auto* texture =
new Texture(path, type);
144 return set_texture_internal(texture.get(), texture->get_type(), texture_slot);
182 set_property(MaterialConstants::OPACITY, glm::clamp(opacity, 0.0f, 1.0f));
195 set_uv_tiling(glm::vec2(x, y));
207 void set_custom_shader(
const std::string &vertex_path,
const std::string &fragment_path) {
208 custom_shader_info_ = ShaderInfo{vertex_path, fragment_path};
212 custom_shader_info_ = shader_info;
215 void add_shader_define(
const std::string &define) {
216 if (custom_shader_info_) {
217 custom_shader_info_->defines.insert(define);
221 void set_uniform_mapping(
const std::string &property_name,
const std::string &uniform_name) {
222 if (custom_shader_info_) {
223 custom_shader_info_->uniform_mappings[property_name] = uniform_name;
228 return custom_shader_info_ && custom_shader_info_->is_valid();
232 return custom_shader_info_ ? &*custom_shader_info_ :
nullptr;
252 void set_name(
const std::string &name) {
name_ = name; }
260 if (!uniform_name || !flag_name) {
261 std::cerr <<
"Warning: Unsupported texture type" << std::endl;
265 if (texture_slot >= 0) {
267 set_property(uniform_name + std::string(
"Slot"), texture_slot);
270 set_property(uniform_name, texture, uniform_name);
271 set_property(flag_name, texture !=
nullptr);
278 bool has_property(
const std::string &name)
const {
279 return properties_.find(name) != properties_.end();
282 Property get_property_object(
const std::string &name)
const {
283 if (
const auto it = properties_.find(name); it != properties_.end()) {
292 static std::shared_ptr<
Material> create(
const std::string &name);
293 static std::shared_ptr<
Material> create_custom(
const std::string &name,
294 const std::string &vertex_path,
295 const std::string &fragment_path);
void pass_data(const T *data, size_t count) const
void pass_data(const std::vector< T > &data) const
void pass_data(const std::vector< T > &data) const
void pass_dynamic_data(const std::vector< T > &data) const
void pass_data(const T *data, size_t count) const
std::shared_ptr< Texture > get_texture(AssetID id)
size_t get_loaded_mesh_count() const
std::unordered_map< AssetID, std::shared_ptr< Texture > > texture_cache_
AssetManager(AssetRegistry ®istry)
std::shared_ptr< Mesh > get_mesh(AssetID id)
size_t get_loaded_material_count() const
AssetRegistry & registry_
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 ®istry_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)
static std::optional< MaterialData > load(const std::filesystem::path &filepath)
void set_ambient_color(const glm::vec3 &color)
void bind_all_properties(uint32_t shader_program, int &texture_unit) const
Material & set_texture(Texture *texture, int texture_slot=0)
std::map< std::string, Property > properties_
std::shared_ptr< Material > base_material_
std::vector< int > bound_texture_units_
Material & set_texture_internal(Texture *texture, TextureType type, int texture_slot)
void set_uv_offset(const glm::vec2 &offset)
void bind() const
Used to bind a Material for rendering.
bool is_transparent() const
uint32_t get_compiled_shader_id() const
void unbind_all_textures() const
std::unordered_map< std::string, Property > overrides_
void set_uv_tiling(float x, float y)
const std::string & get_name() const
void set_roughness(float roughness)
const auto & get_properties() const
void set_specular_color(const glm::vec3 &color)
std::optional< ShaderInfo > custom_shader_info_
std::unordered_set< std::string > touched_uniforms_
void set_uv_rotation(float rotation)
void set_compiled_shader_id(uint32_t shader_id)
Material & set_texture(const std::shared_ptr< Texture > &texture, int texture_slot=0)
void set_metallic(float metallic)
void set_uv_tiling(const glm::vec2 &tiling)
void set_diffuse_color(const glm::vec3 &color)
void set_opacity(float opacity)
uint32_t compiled_shader_id_
bool has_custom_shader() const
void set_emissive_color(const glm::vec3 &color)
void set_custom_shader(const ShaderInfo &shader_info)
const ShaderInfo * get_shader_info() const
void set_shininess(float shininess)
static std::shared_ptr< Mesh > load(const std::filesystem::path &filepath)
Mesh(const std::vector< Vertex > &vertices, const std::vector< unsigned int > &indices)
int get_index_count() const
std::unique_ptr< VA > vao_
std::unique_ptr< IB > ibo_
std::vector< Vertex > vertices
Mesh(const std::vector< Vertex > &vertices, const std::vector< unsigned int > &indices, bool defer_build)
std::unique_ptr< VB > vbo_
std::vector< unsigned int > indices
void draw_instanced(size_t amount) const
TextureType get_type() const
constexpr AssetID INVALID_ASSET_ID
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
std::string fragment_path
std::unordered_map< std::string, std::string > uniform_mappings
std::unordered_set< std::string > defines
std::optional< std::string > geometry_path