more work on asset registry and importing process
This commit is contained in:
@@ -23,15 +23,13 @@ file(GLOB_RECURSE HEADERS ${CMAKE_SOURCE_DIR}/src/*.h)
|
|||||||
add_subdirectory(_ThirdParty/entt)
|
add_subdirectory(_ThirdParty/entt)
|
||||||
add_subdirectory(_ThirdParty/fmt)
|
add_subdirectory(_ThirdParty/fmt)
|
||||||
add_subdirectory(_ThirdParty/spdlog)
|
add_subdirectory(_ThirdParty/spdlog)
|
||||||
|
|
||||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||||
add_subdirectory(_ThirdParty/json)
|
add_subdirectory(_ThirdParty/json)
|
||||||
|
|
||||||
add_subdirectory(_ThirdParty/uuid)
|
add_subdirectory(_ThirdParty/uuid)
|
||||||
|
|
||||||
add_subdirectory(_ThirdParty/nfd)
|
add_subdirectory(_ThirdParty/nfd)
|
||||||
|
|
||||||
set (ASSIMP_INSTALL OFF)
|
set (ASSIMP_INSTALL OFF)
|
||||||
|
add_subdirectory(_ThirdParty/assimp)
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
find_path(UNZIP_PATH unzip.h PATHS
|
find_path(UNZIP_PATH unzip.h PATHS
|
||||||
/usr/include
|
/usr/include
|
||||||
@@ -40,11 +38,11 @@ if(UNIX)
|
|||||||
if(NOT UNZIP_PATH)
|
if(NOT UNZIP_PATH)
|
||||||
include_directories(/usr/include/minizip)
|
include_directories(/usr/include/minizip)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_compile_options(assimp PRIVATE
|
||||||
|
-Wno-unused-but-set-variable
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(_ThirdParty/assimp)
|
|
||||||
target_compile_options(assimp PRIVATE
|
|
||||||
-Wno-unused-but-set-variable
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME}
|
add_executable(${PROJECT_NAME}
|
||||||
${IMGUI_SOURCES}
|
${IMGUI_SOURCES}
|
||||||
@@ -54,13 +52,6 @@ add_executable(${PROJECT_NAME}
|
|||||||
src/ProjectManifestFile.cpp
|
src/ProjectManifestFile.cpp
|
||||||
src/ProjectManifestFile.h)
|
src/ProjectManifestFile.h)
|
||||||
|
|
||||||
add_custom_target(copy_resources
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/resources"
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/resources"
|
|
||||||
COMMENT "Copying resources..."
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} glfw spdlog assimp glm EnTT fmt nfd uuid)
|
target_link_libraries(${PROJECT_NAME} glfw spdlog assimp glm EnTT fmt nfd uuid)
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE ${ASSIMP_INCLUDE_INSTALL_DIR})
|
target_include_directories(${PROJECT_NAME} PRIVATE ${ASSIMP_INCLUDE_INSTALL_DIR})
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE _ThirdParty/json/single_include)
|
target_include_directories(${PROJECT_NAME} PRIVATE _ThirdParty/json/single_include)
|
||||||
|
|||||||
@@ -1 +1,5 @@
|
|||||||
# b_engine
|
# b_engine
|
||||||
|
|
||||||
|
### if on linux and using wayland:
|
||||||
|
```cd _ThirdParty/nfd```
|
||||||
|
```git submodule update --init```
|
||||||
@@ -3,13 +3,58 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "AssetRegistry.h"
|
#include "AssetRegistry.h"
|
||||||
|
#include "AssetRecord.h"
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include "ModelManager.h"
|
||||||
|
#include "TextureManager.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
|
#include "nlohmann/json.hpp"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
std::unordered_map<uuids::uuid, std::unique_ptr<AssetRegistry>> AssetRegistry::_registry;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
std::unordered_map<uuids::uuid, std::unique_ptr<AssetRecord>> AssetRegistry::_registry;
|
||||||
|
|
||||||
|
const std::unordered_set<std::string> TextureExtensions = {
|
||||||
|
".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".tiff"
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::unordered_set<std::string> ModelExtensions = {
|
||||||
|
".obj", ".fbx", ".gltf", ".glb"
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::unordered_set<std::string> ShaderExtensions = {
|
||||||
|
".vert", ".frag", ".glsl"
|
||||||
|
};
|
||||||
|
|
||||||
|
AssetType check_asset_type(const Path& path)
|
||||||
|
{
|
||||||
|
if (!path.has_extension()) {
|
||||||
|
return AssetType::UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs::is_directory(path)) {
|
||||||
|
return AssetType::DIRECTORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TextureExtensions.contains(path.extension().string())) {
|
||||||
|
return AssetType::TEXTURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModelExtensions.contains(path.extension().string())) {
|
||||||
|
return AssetType::MODEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShaderExtensions.contains(path.extension().string())) {
|
||||||
|
return AssetType::SHADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AssetType::UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
uuids::uuid generate_uuid()
|
uuids::uuid generate_uuid()
|
||||||
{
|
{
|
||||||
@@ -33,27 +78,40 @@ uuids::uuid generate_uuid()
|
|||||||
return gen();
|
return gen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetRegistry::read_source_folder(const std::string_view _folder) {
|
void AssetRegistry::read_directory(const Path& path) {
|
||||||
if (_folder.empty()) {
|
fs::recursive_directory_iterator directory{path};
|
||||||
return;
|
std::vector<fs::directory_entry> entries;
|
||||||
|
|
||||||
|
for (const auto& entry : directory) {
|
||||||
|
if (entry.exists()) {
|
||||||
|
entries.push_back(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Path path {_folder};
|
for (const auto& entry : entries) {
|
||||||
Directory directory {path};
|
if (entry.path().extension() == ".meta") {
|
||||||
for (const auto entry : directory) {
|
|
||||||
if (!entry.exists()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!generate_meta_file(entry.path())) {
|
||||||
|
spdlog::error("Failed to generate meta file for {}", entry.path().string());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<AssetRecord> record = read_meta_file(entry.path());
|
||||||
|
if (!record)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_registry[record->uuid] = std::make_unique<AssetRecord>(*record);
|
||||||
|
AssetRecord* asset = _registry[record->uuid].get();
|
||||||
|
|
||||||
|
load_asset(asset);
|
||||||
|
|
||||||
if (entry.is_directory()) {
|
if (entry.is_directory()) {
|
||||||
read_source_folder(entry.path().c_str());
|
read_directory(entry.path());
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid_t uuid;
|
|
||||||
generate_meta_file(entry.path());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,18 +121,79 @@ bool AssetRegistry::does_meta_exist(const Path& path) {
|
|||||||
return fs::exists(meta);
|
return fs::exists(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetRegistry::generate_meta_file(const Path &path) {
|
std::optional<AssetRecord> AssetRegistry::read_meta_file(const Path &path) {
|
||||||
Path meta = path;
|
Path meta = path;
|
||||||
meta += ".meta";
|
meta += ".meta";
|
||||||
|
|
||||||
if (fs::exists(meta)) {
|
AssetRecord record;
|
||||||
return;
|
if (!fs::exists(meta) && !generate_meta_file(path)) {
|
||||||
|
return std::optional<AssetRecord>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetRecord record;
|
std::stringstream ss;
|
||||||
record.uuid = generate_uuid();
|
try {
|
||||||
record.sourcePath = path.c_str();
|
std::ifstream file {meta};
|
||||||
|
ss << file.rdbuf();
|
||||||
|
file.close();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("Failed to read meta file: {}", e.what());
|
||||||
|
return std::optional<AssetRecord>{};
|
||||||
|
}
|
||||||
|
|
||||||
std::ofstream file {meta};
|
std::string metaContent = ss.str();
|
||||||
file.close();
|
json metaJson = json::parse(metaContent);
|
||||||
|
|
||||||
|
auto uuidString = metaJson["uuid"].get<std::string>();
|
||||||
|
std::optional<uuids::uuid> uuid = uuids::uuid::from_string(uuidString);
|
||||||
|
if (!uuid)
|
||||||
|
{
|
||||||
|
return std::optional<AssetRecord>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
record.uuid = *uuid;
|
||||||
|
record.sourcePath = metaJson["sourcePath"].get<std::string>();
|
||||||
|
record.assetType = static_cast<AssetType>(metaJson["assetType"].get<int>());
|
||||||
|
|
||||||
|
return std::optional{record};
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
std::ofstream file {meta};
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << j.dump();
|
||||||
|
file << ss.str();
|
||||||
|
file.close();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
spdlog::error("File exception while generating meta file: {}", e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetRegistry::load_asset(AssetRecord* asset) {
|
||||||
|
switch (asset->assetType) {
|
||||||
|
case AssetType::SHADER:
|
||||||
|
break;
|
||||||
|
case AssetType::TEXTURE:
|
||||||
|
TextureManager::textures[asset->uuid] = TextureManager::load_from_file(asset->sourcePath);
|
||||||
|
break;
|
||||||
|
case AssetType::MODEL:
|
||||||
|
ModelManager::models[asset->uuid] = ModelManager::load_from_file(asset->sourcePath);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,14 +6,12 @@
|
|||||||
#define B_ENGINE_ASSETREGISTRY_H
|
#define B_ENGINE_ASSETREGISTRY_H
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <uuid/uuid.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include "AssetRecord.h"
|
#include "AssetRecord.h"
|
||||||
|
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
@@ -23,15 +21,17 @@ using Path = fs::path;
|
|||||||
|
|
||||||
class AssetRegistry {
|
class AssetRegistry {
|
||||||
public:
|
public:
|
||||||
static void read_source_folder(std::string_view _folder);
|
static void read_directory(const Path& path);
|
||||||
|
|
||||||
static std::vector<AssetRegistry*> get_records();
|
static std::vector<AssetRecord*> get_records();
|
||||||
static AssetRegistry* get_record(uuid_t uuid);
|
static AssetRecord* get_record(uuids::uuid uuid);
|
||||||
private:
|
private:
|
||||||
static std::unordered_map<uuids::uuid, std::unique_ptr<AssetRegistry>> _registry;
|
static std::unordered_map<uuids::uuid, std::unique_ptr<AssetRecord>> _registry;
|
||||||
|
|
||||||
static bool does_meta_exist(const Path& path);
|
static bool does_meta_exist(const Path& path);
|
||||||
static void generate_meta_file(const Path& path);
|
static std::optional<AssetRecord> read_meta_file(const Path& path);
|
||||||
|
static bool generate_meta_file(const Path& path);
|
||||||
|
static void load_asset(AssetRecord* asset);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,15 +15,14 @@
|
|||||||
#include "TextureManager.h"
|
#include "TextureManager.h"
|
||||||
#include "glm/ext/matrix_transform.hpp"
|
#include "glm/ext/matrix_transform.hpp"
|
||||||
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<Model>> ModelManager::models;
|
std::unordered_map<uuids::uuid, std::unique_ptr<Model>> ModelManager::models;
|
||||||
|
|
||||||
void process_ai_node(aiNode* node, const aiScene* scene, glm::mat4 transform, ModelNode& model);
|
void process_ai_node(aiNode* node, const aiScene* scene, glm::mat4 transform, ModelNode& model);
|
||||||
|
|
||||||
void process_ai_mesh(const aiMesh* aiMesh, Mesh& mesh);
|
void process_ai_mesh(const aiMesh* aiMesh, Mesh& mesh);
|
||||||
|
|
||||||
void process_ai_material(const aiMaterial* aiMat, Material& mat, const std::filesystem::path& modelDirectory);
|
/*void process_ai_material(const aiMaterial* aiMat, Material& mat, const std::filesystem::path& modelDirectory);
|
||||||
void process_ai_material_diffuse(const aiMaterial *aiMat, Material& mat, const std::filesystem::path& modelDirectory);
|
void process_ai_material_diffuse(const aiMaterial *aiMat, Material& mat, const std::filesystem::path& modelDirectory);
|
||||||
void process_ai_material_specular(const aiMaterial *aiMat, Material& mat, const std::filesystem::path& modelDirectory);
|
void process_ai_material_specular(const aiMaterial *aiMat, Material& mat, const std::filesystem::path& modelDirectory);*/
|
||||||
|
|
||||||
auto zUpMatrix = glm::mat4(
|
auto zUpMatrix = glm::mat4(
|
||||||
1.0f, 0.0f, 0.0f, 0.0f, // Column 0
|
1.0f, 0.0f, 0.0f, 0.0f, // Column 0
|
||||||
@@ -32,7 +31,7 @@ auto zUpMatrix = glm::mat4(
|
|||||||
0.0f, 0.0f, 0.0f, 1.0f // Column 3
|
0.0f, 0.0f, 0.0f, 1.0f // Column 3
|
||||||
);
|
);
|
||||||
|
|
||||||
std::shared_ptr<Model> ModelManager::load_from_file(std::string_view _path, bool zUp)
|
std::unique_ptr<Model> ModelManager::load_from_file(std::string_view _path, bool zUp)
|
||||||
{
|
{
|
||||||
Assimp::Importer importer;
|
Assimp::Importer importer;
|
||||||
|
|
||||||
@@ -47,10 +46,10 @@ std::shared_ptr<Model> ModelManager::load_from_file(std::string_view _path, bool
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto model = std::make_shared<Model>();
|
auto model = std::make_unique<Model>();
|
||||||
|
|
||||||
const std::filesystem::path modelPath = {_path};
|
const std::filesystem::path modelPath = {_path};
|
||||||
for (unsigned int i = 0; i < scene->mNumMaterials; i++) {
|
/*for (unsigned int i = 0; i < scene->mNumMaterials; i++) {
|
||||||
aiMaterial* aiMat = scene->mMaterials[i];
|
aiMaterial* aiMat = scene->mMaterials[i];
|
||||||
aiString matName;
|
aiString matName;
|
||||||
if (aiMat->Get(AI_MATKEY_NAME, matName) && strcmp(matName.data, "DefaultMaterial") == 0) {
|
if (aiMat->Get(AI_MATKEY_NAME, matName) && strcmp(matName.data, "DefaultMaterial") == 0) {
|
||||||
@@ -59,7 +58,7 @@ std::shared_ptr<Model> ModelManager::load_from_file(std::string_view _path, bool
|
|||||||
Material mat{};
|
Material mat{};
|
||||||
process_ai_material(aiMat, mat, modelPath.parent_path());
|
process_ai_material(aiMat, mat, modelPath.parent_path());
|
||||||
model->materials.push_back(std::make_shared<Material>(mat));
|
model->materials.push_back(std::make_shared<Material>(mat));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
|
for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
|
||||||
aiMesh* aiMesh = scene->mMeshes[i];
|
aiMesh* aiMesh = scene->mMeshes[i];
|
||||||
@@ -148,7 +147,7 @@ void process_ai_mesh(const aiMesh* aiMesh, Mesh& mesh)
|
|||||||
mesh = {positions, uvs, normals, indices};
|
mesh = {positions, uvs, normals, indices};
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_ai_material(const aiMaterial* aiMat, Material& mat, const std::filesystem::path& modelDirectory) {
|
/*void process_ai_material(const aiMaterial* aiMat, Material& mat, const std::filesystem::path& modelDirectory) {
|
||||||
aiString matName;
|
aiString matName;
|
||||||
aiReturn ret = aiMat->Get(AI_MATKEY_NAME, matName);
|
aiReturn ret = aiMat->Get(AI_MATKEY_NAME, matName);
|
||||||
if (ret != AI_SUCCESS) {
|
if (ret != AI_SUCCESS) {
|
||||||
@@ -193,9 +192,9 @@ void process_ai_material(const aiMaterial* aiMat, Material& mat, const std::file
|
|||||||
mat.phong.diffuse = glm::vec3{diffuseColor.r, diffuseColor.g, diffuseColor.b};
|
mat.phong.diffuse = glm::vec3{diffuseColor.r, diffuseColor.g, diffuseColor.b};
|
||||||
mat.phong.specular = glm::vec3{specularColor.r, specularColor.g, specularColor.b};
|
mat.phong.specular = glm::vec3{specularColor.r, specularColor.g, specularColor.b};
|
||||||
mat.phong.shininess = shininess;
|
mat.phong.shininess = shininess;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void process_ai_material_diffuse(const aiMaterial *aiMat, Material& mat, const std::filesystem::path& modelDirectory) {
|
/*void process_ai_material_diffuse(const aiMaterial *aiMat, Material& mat, const std::filesystem::path& modelDirectory) {
|
||||||
aiString aiTextureName;
|
aiString aiTextureName;
|
||||||
aiMat->GetTexture(aiTextureType_DIFFUSE, 0, &aiTextureName);
|
aiMat->GetTexture(aiTextureType_DIFFUSE, 0, &aiTextureName);
|
||||||
std::string textureName = aiTextureName.C_Str();
|
std::string textureName = aiTextureName.C_Str();
|
||||||
@@ -259,4 +258,4 @@ void process_ai_material_specular(const aiMaterial *aiMat, Material& mat, const
|
|||||||
} else {
|
} else {
|
||||||
mat.specular = TextureManager::textures["default_specular"];
|
mat.specular = TextureManager::textures["default_specular"];
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
@@ -9,13 +9,14 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
#include "uuid.h"
|
||||||
|
|
||||||
class ModelManager
|
class ModelManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unordered_map<std::string, std::shared_ptr<Model>> models;
|
static std::unordered_map<uuids::uuid, std::unique_ptr<Model>> models;
|
||||||
|
|
||||||
static std::shared_ptr<Model> load_from_file(std::string_view _path, bool zUp = false);
|
static std::unique_ptr<Model> load_from_file(std::string_view _path, bool zUp = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,14 @@
|
|||||||
#define B_ENGINE_PROJECTMANIFEST_H
|
#define B_ENGINE_PROJECTMANIFEST_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string assetFolder;
|
std::string assetFolder;
|
||||||
|
|
||||||
|
std::filesystem::path projectDirectory;
|
||||||
} ProjectManifest;
|
} ProjectManifest;
|
||||||
|
|
||||||
#endif //B_ENGINE_PROJECTMANIFEST_H
|
#endif //B_ENGINE_PROJECTMANIFEST_H
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
void log_shader_compile_errors(GLuint shader, std::string_view shaderType);
|
void log_shader_compile_errors(GLuint shader, std::string_view shaderType);
|
||||||
void log_program_compile_errors(GLuint program);
|
void log_program_compile_errors(GLuint program);
|
||||||
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<ShaderProgram>> ShaderManager::shaders;
|
std::unordered_map<uuids::uuid, std::unique_ptr<ShaderProgram>> ShaderManager::shaders;
|
||||||
|
|
||||||
std::shared_ptr<ShaderProgram> ShaderManager::load(std::string_view vertexPath, std::string_view fragmentPath)
|
std::unique_ptr<ShaderProgram> ShaderManager::load(std::string_view vertexPath, std::string_view fragmentPath)
|
||||||
{
|
{
|
||||||
std::string vertexSource;
|
std::string vertexSource;
|
||||||
std::string fragmentSource;
|
std::string fragmentSource;
|
||||||
@@ -24,8 +24,7 @@ std::shared_ptr<ShaderProgram> ShaderManager::load(std::string_view vertexPath,
|
|||||||
std::ifstream vertexFile {};
|
std::ifstream vertexFile {};
|
||||||
std::ifstream fragmentFile {};
|
std::ifstream fragmentFile {};
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
vertexFile.open(vertexPath.data());
|
vertexFile.open(vertexPath.data());
|
||||||
fragmentFile.open(fragmentPath.data());
|
fragmentFile.open(fragmentPath.data());
|
||||||
|
|
||||||
@@ -39,8 +38,8 @@ std::shared_ptr<ShaderProgram> ShaderManager::load(std::string_view vertexPath,
|
|||||||
|
|
||||||
vertexFile.close();
|
vertexFile.close();
|
||||||
fragmentFile.close();
|
fragmentFile.close();
|
||||||
} catch (std::ifstream::failure& e) {
|
} catch (std::fstream::failure& e) {
|
||||||
spdlog::error("Failed to load shader program {}, {}: {}", vertexPath, fragmentPath, std::string(e.what()).c_str());
|
spdlog::error("Failed to load shader program {}, {}: {}", vertexPath, fragmentPath, e.what());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,13 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "ShaderProgram.h"
|
#include "ShaderProgram.h"
|
||||||
|
#include "uuid.h"
|
||||||
|
|
||||||
class ShaderManager {
|
class ShaderManager {
|
||||||
public:
|
public:
|
||||||
static std::unordered_map<std::string, std::shared_ptr<ShaderProgram>> shaders;
|
static std::unordered_map<uuids::uuid, std::unique_ptr<ShaderProgram>> shaders;
|
||||||
|
static std::unique_ptr<ShaderProgram> load(std::string_view vertexPath, std::string_view fragmentPath);
|
||||||
|
|
||||||
static std::shared_ptr<ShaderProgram> load(std::string_view vertexPath, std::string_view fragmentPath);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //B_ENGINE_SHADERMANAGER_H
|
#endif //B_ENGINE_SHADERMANAGER_H
|
||||||
@@ -5,14 +5,15 @@
|
|||||||
#include "TextureManager.h"
|
#include "TextureManager.h"
|
||||||
|
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
|
#include "uuid.h"
|
||||||
|
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
#include "glad/gl.h"
|
#include "glad/gl.h"
|
||||||
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<Texture>> TextureManager::textures;
|
std::unordered_map<uuids::uuid, std::unique_ptr<Texture>> TextureManager::textures;
|
||||||
|
|
||||||
std::shared_ptr<Texture> TextureManager::load_from_file(std::string_view filePath)
|
std::unique_ptr<Texture> TextureManager::load_from_file(const std::string_view filePath)
|
||||||
{
|
{
|
||||||
int width, height, channels;
|
int width, height, channels;
|
||||||
unsigned char *data = stbi_load(filePath.data(), &width, &height, &channels, 0);
|
unsigned char *data = stbi_load(filePath.data(), &width, &height, &channels, 0);
|
||||||
@@ -38,10 +39,10 @@ std::shared_ptr<Texture> TextureManager::load_from_file(std::string_view filePat
|
|||||||
|
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
|
|
||||||
return std::make_shared<Texture>(textureID, filePath, width, height, channels);
|
return std::make_unique<Texture>(textureID, filePath, width, height, channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Texture> TextureManager::load_from_data(unsigned char* data, int width, int height, int channels)
|
std::unique_ptr<Texture> TextureManager::load_from_data(unsigned char* data, int width, int height, int channels)
|
||||||
{
|
{
|
||||||
unsigned int textureID = 0;
|
unsigned int textureID = 0;
|
||||||
glGenTextures(1, &textureID);
|
glGenTextures(1, &textureID);
|
||||||
@@ -57,5 +58,5 @@ std::shared_ptr<Texture> TextureManager::load_from_data(unsigned char* data, int
|
|||||||
glTexImage2D(GL_TEXTURE_2D, 0, (GLint)format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
glTexImage2D(GL_TEXTURE_2D, 0, (GLint)format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
return std::make_shared<Texture>(textureID, "memory", width, height, channels);
|
return std::make_unique<Texture>(textureID, "memory", width, height, channels);
|
||||||
}
|
}
|
||||||
@@ -5,17 +5,19 @@
|
|||||||
#ifndef B_ENGINE_TEXTUREMANAGER_H
|
#ifndef B_ENGINE_TEXTUREMANAGER_H
|
||||||
#define B_ENGINE_TEXTUREMANAGER_H
|
#define B_ENGINE_TEXTUREMANAGER_H
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
#include "uuid.h"
|
||||||
|
|
||||||
class TextureManager {
|
class TextureManager {
|
||||||
public:
|
public:
|
||||||
static std::unordered_map<std::string, std::shared_ptr<Texture>> textures;
|
static std::unordered_map<uuids::uuid, std::unique_ptr<Texture>> textures;
|
||||||
|
|
||||||
static std::shared_ptr<Texture> load_from_file(std::string_view filePath);
|
static std::unique_ptr<Texture> load_from_file(std::string_view filePath);
|
||||||
static std::shared_ptr<Texture> load_from_data(unsigned char* data, int width, int height, int channels);
|
static std::unique_ptr<Texture> load_from_data(unsigned char* data, int width, int height, int channels);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //B_ENGINE_TEXTUREMANAGER_H
|
#endif //B_ENGINE_TEXTUREMANAGER_H
|
||||||
@@ -6,9 +6,11 @@
|
|||||||
#define B_ENGINE_TYPES_H
|
#define B_ENGINE_TYPES_H
|
||||||
|
|
||||||
enum class AssetType {
|
enum class AssetType {
|
||||||
SHADER = 0,
|
UNKNOWN = 0,
|
||||||
TEXTURE = 1,
|
DIRECTORY = 1,
|
||||||
MODEL = 2
|
SHADER = 2,
|
||||||
|
TEXTURE = 3,
|
||||||
|
MODEL = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //B_ENGINE_TYPES_H
|
#endif //B_ENGINE_TYPES_H
|
||||||
|
|||||||
91
src/main.cpp
91
src/main.cpp
@@ -7,6 +7,7 @@
|
|||||||
#include "glm/ext/matrix_clip_space.hpp"
|
#include "glm/ext/matrix_clip_space.hpp"
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "AssetRegistry.h"
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
|
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
@@ -28,6 +29,8 @@
|
|||||||
#include "ui/UISceneGraph.h"
|
#include "ui/UISceneGraph.h"
|
||||||
#include "ui/UISceneViewer.h"
|
#include "ui/UISceneViewer.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
const char* B_ENGINE_VERSION = "v0.0.3";
|
const char* B_ENGINE_VERSION = "v0.0.3";
|
||||||
|
|
||||||
GLFWwindow* gWindow = nullptr;
|
GLFWwindow* gWindow = nullptr;
|
||||||
@@ -43,10 +46,11 @@ float gMouseSensitivity = 0.1f;
|
|||||||
|
|
||||||
std::unique_ptr<ProjectManifest> gCurrentProject {nullptr};
|
std::unique_ptr<ProjectManifest> gCurrentProject {nullptr};
|
||||||
|
|
||||||
Camera gCamera {};
|
|
||||||
Scene gScene{};
|
Scene gScene{};
|
||||||
EditorContext gEditorCtx{};
|
EditorContext gEditorCtx{};
|
||||||
FreeCameraController gCameraController{};
|
|
||||||
|
Camera gCamera {};
|
||||||
|
FreeCameraController gEditorCameraController{};
|
||||||
|
|
||||||
void glfw_error_callback(int error, const char* description);
|
void glfw_error_callback(int error, const char* description);
|
||||||
void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||||
@@ -55,12 +59,8 @@ void glfw_framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
|||||||
void init_glfw();
|
void init_glfw();
|
||||||
void create_main_window();
|
void create_main_window();
|
||||||
void load_gl();
|
void load_gl();
|
||||||
void init_camera();
|
|
||||||
void init_scene();
|
|
||||||
void load_default_textures();
|
|
||||||
void load_shaders();
|
|
||||||
void load_inputs();
|
void load_inputs();
|
||||||
void load_default_models();
|
void init_editor_camera();
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
void create_entity(entt::entity parent);
|
void create_entity(entt::entity parent);
|
||||||
@@ -81,14 +81,8 @@ int main() {
|
|||||||
|
|
||||||
stbi_set_flip_vertically_on_load(true);
|
stbi_set_flip_vertically_on_load(true);
|
||||||
|
|
||||||
load_default_textures();
|
|
||||||
|
|
||||||
load_shaders();
|
|
||||||
|
|
||||||
load_inputs();
|
load_inputs();
|
||||||
|
|
||||||
load_default_models();
|
|
||||||
|
|
||||||
UIManager::init(gWindow);
|
UIManager::init(gWindow);
|
||||||
auto* menuBar = UIManager::add_ui_panel<UIMenuBar>("menu_bar");
|
auto* menuBar = UIManager::add_ui_panel<UIMenuBar>("menu_bar");
|
||||||
menuBar->create_entity = create_entity;
|
menuBar->create_entity = create_entity;
|
||||||
@@ -97,14 +91,11 @@ int main() {
|
|||||||
UIManager::add_ui_panel<UISceneGraph>("scene_graph");
|
UIManager::add_ui_panel<UISceneGraph>("scene_graph");
|
||||||
UIManager::add_ui_panel<UIEntityInspector>("entity_inspector");
|
UIManager::add_ui_panel<UIEntityInspector>("entity_inspector");
|
||||||
|
|
||||||
init_camera();
|
gEditorCameraController.set_camera(gCamera);
|
||||||
init_scene();
|
gEditorCameraController.look_sensitivity = 0.2;
|
||||||
|
gEditorCameraController.movement_speed = 0.2;
|
||||||
gCameraController.set_camera(gCamera);
|
|
||||||
gCameraController.look_sensitivity = 0.2;
|
|
||||||
gCameraController.movement_speed = 0.2;
|
|
||||||
InputManager::add_mouse_listener([](float xoff, float yoff) {
|
InputManager::add_mouse_listener([](float xoff, float yoff) {
|
||||||
gCameraController.on_mouse_delta(xoff, yoff);
|
gEditorCameraController.on_mouse_delta(xoff, yoff);
|
||||||
});
|
});
|
||||||
|
|
||||||
gEditorCtx.scene = &gScene;
|
gEditorCtx.scene = &gScene;
|
||||||
@@ -133,8 +124,7 @@ void glfw_framebuffer_size_callback(GLFWwindow *window, int width, int height) {
|
|||||||
gCamera.update_aspect_ratio(gAspectRatio);
|
gCamera.update_aspect_ratio(gAspectRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_glfw()
|
void init_glfw() {
|
||||||
{
|
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
spdlog::error("could not initialize glfw");
|
spdlog::error("could not initialize glfw");
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
@@ -163,10 +153,6 @@ void create_main_window()
|
|||||||
glfwSetCursorPosCallback(gWindow, InputManager::mouse_pos_callback);
|
glfwSetCursorPosCallback(gWindow, InputManager::mouse_pos_callback);
|
||||||
|
|
||||||
glfwSetFramebufferSizeCallback(gWindow, glfw_framebuffer_size_callback);
|
glfwSetFramebufferSizeCallback(gWindow, glfw_framebuffer_size_callback);
|
||||||
|
|
||||||
#ifndef GLFW_CONTEXT_DEBUG
|
|
||||||
glfwSetInputMode(gWindow, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_gl()
|
void load_gl()
|
||||||
@@ -187,45 +173,12 @@ void load_gl()
|
|||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_camera() {
|
void init_editor_camera() {
|
||||||
gCamera = {{10.f, 10.f, 10.f}, 0, 0, gAspectRatio};
|
gCamera = {{10.f, 10.f, 10.f}, 0, 0, gAspectRatio};
|
||||||
gCamera.rotate_yaw(-135.f);
|
gCamera.rotate_yaw(-135.f);
|
||||||
gCamera.rotate_pitch(-35.f);
|
gCamera.rotate_pitch(-35.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_scene() {
|
|
||||||
gScene.set_active_camera(&gCamera);
|
|
||||||
|
|
||||||
const auto defaultLight = gScene.create_game_object();
|
|
||||||
auto& [name] = gScene.fetch_component<Components::Tag>(defaultLight);
|
|
||||||
name = "Directional Light";
|
|
||||||
auto& [direction, ambient, diffuse, specular] = gScene.attach_component<Components::DirectionalLight>(defaultLight);
|
|
||||||
direction = glm::vec3(-1, -1, -1);
|
|
||||||
ambient = glm::vec3(0.3);
|
|
||||||
diffuse = glm::vec3(0.7);
|
|
||||||
specular = glm::vec3(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_default_textures() {
|
|
||||||
spdlog::info("creating default textures");
|
|
||||||
|
|
||||||
unsigned char defaultDiffuseData[4] = {static_cast<unsigned char>(255), 255, 255, 255};
|
|
||||||
TextureManager::textures["default_diffuse"] = TextureManager::load_from_data(reinterpret_cast<unsigned char*>(&defaultDiffuseData), 1, 1, 4);
|
|
||||||
|
|
||||||
unsigned char defaultSpecularData[4] = {static_cast<unsigned char>(64), 64, 64, 255};
|
|
||||||
TextureManager::textures["default_specular"] = TextureManager::load_from_data(reinterpret_cast<unsigned char*>(&defaultSpecularData), 1, 1, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_shaders() {
|
|
||||||
spdlog::info("compiling shaders");
|
|
||||||
ShaderManager::shaders["phong_shader"] = ShaderManager::load("./resources/standard.vert", "./resources/standard.frag");
|
|
||||||
if (ShaderManager::shaders["phong_shader"] == nullptr)
|
|
||||||
{
|
|
||||||
spdlog::error("failed to compile phong shader");
|
|
||||||
std::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_inputs() {
|
void load_inputs() {
|
||||||
InputManager::generate_input_action("move_forward", {{GLFW_KEY_W, KEY_DOWN}});
|
InputManager::generate_input_action("move_forward", {{GLFW_KEY_W, KEY_DOWN}});
|
||||||
InputManager::generate_input_action("move_backward", {{GLFW_KEY_S, KEY_DOWN}});
|
InputManager::generate_input_action("move_backward", {{GLFW_KEY_S, KEY_DOWN}});
|
||||||
@@ -235,13 +188,6 @@ void load_inputs() {
|
|||||||
InputManager::generate_input_action("move_down", {{GLFW_KEY_LEFT_SHIFT, KEY_DOWN}});
|
InputManager::generate_input_action("move_down", {{GLFW_KEY_LEFT_SHIFT, KEY_DOWN}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_default_models() {
|
|
||||||
spdlog::info("loading default models");
|
|
||||||
ModelManager::models["cube"] = ModelManager::load_from_file("./resources/cube.obj");
|
|
||||||
ModelManager::models["vette"] = ModelManager::load_from_file("./resources/c4/C4Fixed.obj");
|
|
||||||
ModelManager::models["male"] = ModelManager::load_from_file("./resources/male.obj");
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
while (!glfwWindowShouldClose(gWindow)) {
|
while (!glfwWindowShouldClose(gWindow)) {
|
||||||
// input
|
// input
|
||||||
@@ -249,7 +195,7 @@ void loop() {
|
|||||||
|
|
||||||
// update
|
// update
|
||||||
UIManager::update(gEditorCtx);
|
UIManager::update(gEditorCtx);
|
||||||
gCameraController.update(gEditorCtx);
|
gEditorCameraController.update(gEditorCtx);
|
||||||
|
|
||||||
if (gCamera.aspect_ratio() != gEditorCtx.viewportAspectRatio) {
|
if (gCamera.aspect_ratio() != gEditorCtx.viewportAspectRatio) {
|
||||||
gCamera.update_aspect_ratio(gEditorCtx.viewportAspectRatio);
|
gCamera.update_aspect_ratio(gEditorCtx.viewportAspectRatio);
|
||||||
@@ -266,8 +212,8 @@ void loop() {
|
|||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
const auto shader = ShaderManager::shaders["phong_shader"];
|
// const auto shader = ShaderManager::shaders["phong_shader"];
|
||||||
gScene.draw_scene(shader.get());
|
// gScene.draw_scene(shader.get());
|
||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
ShaderProgram::unbind();
|
ShaderProgram::unbind();
|
||||||
@@ -285,7 +231,12 @@ void create_entity(entt::entity parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void open_project(std::string_view _path) {
|
void open_project(std::string_view _path) {
|
||||||
|
const std::filesystem::path projectFilePath {_path};
|
||||||
gCurrentProject = ProjectManifestFile::load(_path);
|
gCurrentProject = ProjectManifestFile::load(_path);
|
||||||
|
gCurrentProject->projectDirectory = projectFilePath.parent_path();
|
||||||
|
|
||||||
|
std::filesystem::path assetPath = gCurrentProject->projectDirectory.append(gCurrentProject->assetFolder);
|
||||||
|
AssetRegistry::read_directory(assetPath);
|
||||||
|
|
||||||
const std::string title = fmt::format("project \"{}\" | b_engine {}", gCurrentProject->name, B_ENGINE_VERSION);
|
const std::string title = fmt::format("project \"{}\" | b_engine {}", gCurrentProject->name, B_ENGINE_VERSION);
|
||||||
glfwSetWindowTitle(gWindow, title.c_str());
|
glfwSetWindowTitle(gWindow, title.c_str());
|
||||||
|
|||||||
Reference in New Issue
Block a user