diff --git a/src/AssetRegistry.cpp b/src/AssetRegistry.cpp index 2ececcd..3cbd399 100644 --- a/src/AssetRegistry.cpp +++ b/src/AssetRegistry.cpp @@ -32,8 +32,7 @@ const std::unordered_set ShaderExtensions = { ".vert", ".frag", ".glsl" }; -AssetType check_asset_type(const Path& path) -{ +AssetType check_asset_type(const Path& path) { if (!path.has_extension()) { return AssetType::UNKNOWN; } @@ -57,8 +56,7 @@ AssetType check_asset_type(const Path& path) return AssetType::UNKNOWN; } -uuids::uuid generate_uuid() -{ +uuids::uuid generate_uuid() { thread_local auto gen = [] { std::random_device rd; @@ -125,51 +123,50 @@ std::optional AssetRegistry::read_meta_file(const Path &path) { Path meta = path; meta += ".meta"; - AssetRecord record; if (!fs::exists(meta) && !generate_meta_file(path)) { return std::optional{}; } - std::stringstream ss; try { + AssetRecord record; + std::stringstream ss; std::ifstream file {meta}; ss << file.rdbuf(); file.close(); + + std::string metaContent = ss.str(); + json metaJson = json::parse(metaContent); + + auto uuidString = metaJson["uuid"].get(); + std::optional uuid = uuids::uuid::from_string(uuidString); + if (!uuid) + { + return std::optional{}; + } + + record.uuid = *uuid; + record.sourcePath = metaJson["sourcePath"].get(); + record.assetType = static_cast(metaJson["assetType"].get()); + + return std::optional{record}; } catch (const std::exception& e) { spdlog::error("Failed to read meta file: {}", e.what()); return std::optional{}; } - - std::string metaContent = ss.str(); - json metaJson = json::parse(metaContent); - - auto uuidString = metaJson["uuid"].get(); - std::optional uuid = uuids::uuid::from_string(uuidString); - if (!uuid) - { - return std::optional{}; - } - - record.uuid = *uuid; - record.sourcePath = metaJson["sourcePath"].get(); - record.assetType = static_cast(metaJson["assetType"].get()); - - return std::optional{record}; } -bool AssetRegistry::generate_meta_file(const Path& path) -{ +bool AssetRegistry::generate_meta_file(const Path& path) { Path meta = path; meta += ".meta"; if (fs::exists(meta)) return true; - nlohmann::json j; - j["uuid"] = uuids::to_string(generate_uuid()); - j["sourcePath"] = path.string(); - j["assetType"] = check_asset_type(path); - try { + nlohmann::json j; + j["uuid"] = uuids::to_string(generate_uuid()); + j["sourcePath"] = path.string(); + j["assetType"] = check_asset_type(path); + std::ofstream file {meta}; std::stringstream ss; ss << j.dump(); diff --git a/src/DefaultResourceHandle.cpp b/src/DefaultResourceHandle.cpp new file mode 100644 index 0000000..e2cc5ea --- /dev/null +++ b/src/DefaultResourceHandle.cpp @@ -0,0 +1,9 @@ +// +// Created by slinky on 5/18/26. +// + +#include "DefaultResourceHandles.h" + +ResourceHandle DefaultResourceHandles::DEFAULT_DIFFUSE_TEXTURE = ResourceHandle { uuids::uuid::from_string("").value(), 0 }; +ResourceHandle DefaultResourceHandles::DEFAULT_SPECULAR_TEXTURE = ResourceHandle { uuids::uuid::from_string("").value(), 0 }; +ResourceHandle DefaultResourceHandles::DEFAULT_SHADER = ResourceHandle { uuids::uuid::from_string("").value(), 0 }; \ No newline at end of file diff --git a/src/DefaultResourceHandles.h b/src/DefaultResourceHandles.h new file mode 100644 index 0000000..c96fa30 --- /dev/null +++ b/src/DefaultResourceHandles.h @@ -0,0 +1,16 @@ +// +// Created by slinky on 5/18/26. +// + +#ifndef B_ENGINE_DEFAULTRESOURCEHANDLES_H +#define B_ENGINE_DEFAULTRESOURCEHANDLES_H + +#include "ResourceHandle.h" + +struct DefaultResourceHandles { + static ResourceHandle DEFAULT_DIFFUSE_TEXTURE; + static ResourceHandle DEFAULT_SPECULAR_TEXTURE; + static ResourceHandle DEFAULT_SHADER; +}; + +#endif //B_ENGINE_DEFAULTRESOURCEHANDLES_H diff --git a/src/Material.h b/src/Material.h index 654c32e..446e311 100644 --- a/src/Material.h +++ b/src/Material.h @@ -9,21 +9,20 @@ #include "ResourceHandle.h" -typedef struct -{ +struct PhongProperties { glm::vec3 ambient; glm::vec3 diffuse; glm::vec3 specular; float shininess; -} PhongProperties; +}; -typedef struct -{ +struct Material{ ResourceHandle diffuse; ResourceHandle specular; ResourceHandle normal; - PhongProperties phong; -} Material; + PhongProperties phong{}; + ResourceHandle shader; +}; #endif //B_ENGINE_MATERIAL_H \ No newline at end of file diff --git a/src/MaterialFile.cpp b/src/MaterialFile.cpp new file mode 100644 index 0000000..3bad6c8 --- /dev/null +++ b/src/MaterialFile.cpp @@ -0,0 +1,93 @@ +// +// Created by slinky on 5/18/26. +// + +#include "MaterialFile.h" + +#include + +#include "DefaultResourceHandles.h" +#include "spdlog/spdlog.h" +#include "nlohmann/json.hpp" + +using json = nlohmann::json; + +std::optional read_resource_handle(const json& j) { + ResourceHandle handle; + + if (j.is_null()) { + return std::optional(); + } + + if (!j.contains("assetUUID")) { + return std::optional(); + } + + auto uuidStr = j["assetUUID"].get(); + auto uuid = uuids::uuid::from_string(uuidStr); + if (!uuid.has_value()) { + return std::optional(); + } + handle.assetUUID = *uuid; + + if (!j.contains("localId")) { + return std::optional(); + } + handle.localId = j["localId"].get(); + + return handle; +} + +std::optional MaterialFile::load(std::string_view _path) { + std::ifstream file; + file.open(_path.data(), std::ios::in); + if (!file.is_open()) { + spdlog::error("failed to open project file {}", _path); + return std::optional(); + } + + std::stringstream ss; + ss << file.rdbuf(); + + std::string fileData = ss.str(); + + try { + auto data = json::parse(fileData); + + + Material material; + + // --------------------------------- + // Texture/resource handles + // --------------------------------- + + material.diffuse = DefaultResourceHandles::DEFAULT_DIFFUSE_TEXTURE; + if (auto diffuse = read_resource_handle(data["diffuse"]); diffuse.has_value()) { + material.diffuse = *diffuse; + } + + material.normal = DefaultResourceHandles::DEFAULT_DIFFUSE_TEXTURE; + if (auto normal = read_resource_handle(data["normal"]); normal.has_value()) { + material.normal = *normal; + } + + material.specular = DefaultResourceHandles::DEFAULT_SPECULAR_TEXTURE; + if (auto specular = read_resource_handle(data["specular"]); specular.has_value()) { + material.specular = *specular; + } + + material.shader = DefaultResourceHandles::DEFAULT_SHADER; + if (auto shader = read_resource_handle(data["shader"]); shader.has_value()) { + material.shader = *shader; + } + + return material; + } catch (const std::exception& e) { + spdlog::error("Error reading material file: {}", e.what()); + return std::optional(); + } +} + +bool MaterialFile::save(std::string_view _path, Material *_project) { + return true; +} diff --git a/src/MaterialFile.h b/src/MaterialFile.h new file mode 100644 index 0000000..281ba42 --- /dev/null +++ b/src/MaterialFile.h @@ -0,0 +1,17 @@ +// +// Created by slinky on 5/18/26. +// + +#ifndef B_ENGINE_MATERIALFILE_H +#define B_ENGINE_MATERIALFILE_H + +#include "Material.h" + +class MaterialFile { +public: + static std::optional load(std::string_view _path); + static bool save(std::string_view _path, Material* _project); +}; + + +#endif //B_ENGINE_MATERIALFILE_H diff --git a/src/ResourceHandle.h b/src/ResourceHandle.h index 0dcd4fb..e899524 100644 --- a/src/ResourceHandle.h +++ b/src/ResourceHandle.h @@ -14,6 +14,10 @@ struct ResourceHandle { bool operator==(const ResourceHandle& other) const { return assetUUID == other.assetUUID && localId == other.localId; } + + ResourceHandle() = default; + + ResourceHandle(const uuids::uuid& uuid, int id) : assetUUID(uuid), localId(id) {} }; namespace std { diff --git a/src/Scene.cpp b/src/Scene.cpp index 27a14a6..6b28a99 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -8,6 +8,7 @@ #include "MeshManager.h" #include "MaterialManager.h" +#include "ShaderManager.h" #include "fmt/format.h" @@ -89,46 +90,44 @@ void Scene::update_transforms(entt::entity entity) { } void Scene::draw_scene() { - program->bind(); - program->setMat4("projection", activeCamera->projection()); - program->setMat4("view", activeCamera->view()); - program->setVec3("viewPosition", activeCamera->position()); - - auto dirLights = _registry.view(); - for (const auto e : dirLights) { - auto dirLight = dirLights.get(e); - program->setVec3("lightDirection", dirLight.direction); - program->setVec3("lightAmbient", dirLight.ambient); - program->setVec3("lightDiffuse", dirLight.diffuse); - program->setVec3("lightSpecular", dirLight.specular); - break; - } - auto view = _registry.view(); for (const auto e : view) { - const auto& transform = view.get(e); - program->setMat4("model", transform.model); - - const auto&[meshHandle] = view.get(e); - const auto* mesh = MeshManager::meshes[meshHandle].get(); - const auto&[matHandle] = view.get(e); const auto* mat = MaterialManager::materials[matHandle].get(); + auto* program = ShaderManager::shaders[mat->shader].get(); + + program->bind(); + program->setMat4("projection", activeCamera->projection()); + program->setMat4("view", activeCamera->view()); + program->setVec3("viewPosition", activeCamera->position()); + + auto dirLights = _registry.view(); + for (const auto e : dirLights) { + auto dirLight = dirLights.get(e); + program->setVec3("lightDirection", dirLight.direction); + program->setVec3("lightAmbient", dirLight.ambient); + program->setVec3("lightDiffuse", dirLight.diffuse); + program->setVec3("lightSpecular", dirLight.specular); + break; + } + program->setVec3("phongAmbient", mat->phong.ambient); program->setVec3("phongDiffuse", mat->phong.diffuse); program->setVec3("phongSpecular", mat->phong.specular); program->setFloat("phongShininess", mat->phong.shininess); glActiveTexture(GL_TEXTURE0); - const auto diffuse = mat->diffuse; - diffuse->bind(); - program->setInt("diffuseMap", 0); + const auto diffuseHandle = mat->diffuse; glActiveTexture(GL_TEXTURE1); - const auto specular = mat->specular; - specular->bind(); - program->setInt("specularMap", 1); + const auto specularHandle = mat->specular; + + const auto& transform = view.get(e); + program->setMat4("model", transform.model); + + const auto&[meshHandle] = view.get(e); + const auto* mesh = MeshManager::meshes[meshHandle].get(); glBindVertexArray(mesh->vao); glDrawElements(GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT, 0); diff --git a/src/main.cpp b/src/main.cpp index afe0530..188f030 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -212,7 +212,7 @@ void loop() { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - gScene.draw_scene(shader.get()); + gScene.draw_scene(); glBindVertexArray(0); ShaderProgram::unbind();