diff --git a/Deer/Include/DeerCore/Serialization/WorldSettings.h b/Deer/Include/DeerCore/Serialization/WorldSettings.h index 6401735..8aa58c5 100644 --- a/Deer/Include/DeerCore/Serialization/WorldSettings.h +++ b/Deer/Include/DeerCore/Serialization/WorldSettings.h @@ -4,6 +4,7 @@ #ifdef DEER_RENDER #include "DeerRender/Mesh.h" #include "DeerRender/Shader.h" +#include "DeerRender/Resource.h" #include "DeerRender/Tools/Memory.h" #include @@ -15,8 +16,8 @@ namespace Deer { bool includeServer = false; bool includeClient = true; - std::function(StorageType)> meshLoadingFunction = nullptr; - std::function(StorageType)> shaderLoadingFunction = nullptr; + std::function(StorageType)> meshLoadingFunction = nullptr; + std::function(StorageType)> shaderLoadingFunction = nullptr; #else bool includeServer = true; bool includeClient = false; diff --git a/Deer/Include/DeerRender/Resource.h b/Deer/Include/DeerRender/Resource.h index 0a4bca3..40bb6a6 100644 --- a/Deer/Include/DeerRender/Resource.h +++ b/Deer/Include/DeerRender/Resource.h @@ -80,7 +80,7 @@ namespace Deer { data = ResourceBuilder::buildResource(*baseData.get()); Resource resource = Resource::unsafeFromId(resources.size()); - resources.push_back(); + resources.push_back({}); ResourceData& rd = resources.back(); rd.data = std::move(data); diff --git a/Deer/src/DeerRender/Scripting/ResourcesRegistry.cpp b/Deer/src/DeerRender/Scripting/ResourcesRegistry.cpp index 13c72dd..3b8caf0 100644 --- a/Deer/src/DeerRender/Scripting/ResourcesRegistry.cpp +++ b/Deer/src/DeerRender/Scripting/ResourcesRegistry.cpp @@ -25,6 +25,8 @@ namespace Deer { } // namespace Scripting void Scripting::registerResourceStructs() { + AS_CHECK(scriptEngine->RegisterObjectType("StorageId", sizeof(StorageType), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits())); + AS_CHECK(scriptEngine->RegisterObjectType("GPUMesh", sizeof(Resource), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits>())); AS_CHECK(scriptEngine->RegisterObjectType("Shader", sizeof(Resource), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits>())); AS_CHECK(scriptEngine->RegisterObjectType("Texture", sizeof(Resource), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits>())); diff --git a/DeerStudio/headers/DeerStudio/ResourceStorageBackend.h b/DeerStudio/headers/DeerStudio/ResourceStorageBackend.h deleted file mode 100644 index 43085e3..0000000 --- a/DeerStudio/headers/DeerStudio/ResourceStorageBackend.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include "DeerRender/Resource.h" -#include "DeerRender/Tools/Path.h" - -namespace Deer { - class EditorDataSource; - - class MeshData; - class ShaderData; - class TextureData; - - template <> - class StorageBackend { - public: - template - static Scope load(StorageType storageId); - - template <> - static Scope load(StorageType storageId); - template <> - static Scope load(StorageType storageId); - template <> - static Scope load(StorageType storageId); - }; -} // namespace Deer \ No newline at end of file diff --git a/DeerStudio/headers/DeerStudio/StudioAPI.h b/DeerStudio/headers/DeerStudio/StudioAPI.h index 30400f6..f5ae7ab 100644 --- a/DeerStudio/headers/DeerStudio/StudioAPI.h +++ b/DeerStudio/headers/DeerStudio/StudioAPI.h @@ -1,5 +1,5 @@ #pragma once -#include "DeerRender/Resource.h" +#include "DeerStudio/StudioResources.h" #include @@ -8,13 +8,6 @@ class CScriptDictionary; namespace Deer { class Texture; - enum class ResourceType : int { - NONE = 0, - MESH = 1, - SHADER = 2, - TEXTURE = 3 - }; - namespace StudioAPI { int32_t getResourceFolder(std::string&); diff --git a/DeerStudio/headers/DeerStudio/StudioResources.h b/DeerStudio/headers/DeerStudio/StudioResources.h index 0b4be23..3f1ab41 100644 --- a/DeerStudio/headers/DeerStudio/StudioResources.h +++ b/DeerStudio/headers/DeerStudio/StudioResources.h @@ -1,9 +1,18 @@ #pragma once +#include "DeerRender/Resource.h" +#include "DeerRender/Tools/Path.h" #include "cereal/cereal.hpp" + #include namespace Deer { + class EditorDataSource; + + class MeshData; + class ShaderData; + class TextureData; + enum class ResourceType : int { NONE = 0, MESH = 1, @@ -38,4 +47,19 @@ namespace Deer { void scanResources(); } // namespace StudioResources -} // namespace Deer \ No newline at end of file + + + template <> + class StorageBackend { + public: + template + static Scope load(StorageType storageId); + + template <> + Scope load(StorageType storageId); + template <> + Scope load(StorageType storageId); + template <> + Scope load(StorageType storageId); + }; +} // namespace Deer diff --git a/DeerStudio/src/DeerStudio/DeerStudio.cpp b/DeerStudio/src/DeerStudio/DeerStudio.cpp index 53ee8fa..696fead 100644 --- a/DeerStudio/src/DeerStudio/DeerStudio.cpp +++ b/DeerStudio/src/DeerStudio/DeerStudio.cpp @@ -7,7 +7,6 @@ #include "DeerRender/Universe.h" #include "DeerRender/World.h" -#include "DeerStudio/ResourceStorageBackend.h" #include "DeerStudio/StudioResources.h" // TMP diff --git a/DeerStudio/src/DeerStudio/EditorDataImporter/MeshData.cpp b/DeerStudio/src/DeerStudio/EditorDataImporter/MeshData.cpp index 903e70b..3d55865 100644 --- a/DeerStudio/src/DeerStudio/EditorDataImporter/MeshData.cpp +++ b/DeerStudio/src/DeerStudio/EditorDataImporter/MeshData.cpp @@ -1,7 +1,6 @@ #include "DeerRender/Log.h" #include "DeerRender/Mesh.h" -#include "DeerStudio/ResourceStorageBackend.h" #include "DeerStudio/StudioResources.h" #include "assimp/Importer.hpp" @@ -22,8 +21,8 @@ namespace Deer { return Scope(); Assimp::Importer importer; - const aiScene* scene = importer.ReadFileFromMemory(data.get(), size, aiProcess_Triangulate, extension_char); // aiProcess_JoinIdenticalVertices aiProcess_GenNormals | - + const aiScene* scene = importer.ReadFile(info->fullPath, aiProcess_Triangulate); + if (scene == nullptr) { DEER_CORE_ERROR("Error processing assimp"); return Scope(); diff --git a/DeerStudio/src/DeerStudio/EditorDataImporter/ShaderData.cpp b/DeerStudio/src/DeerStudio/EditorDataImporter/ShaderData.cpp index 39fa5bd..405ba5e 100644 --- a/DeerStudio/src/DeerStudio/EditorDataImporter/ShaderData.cpp +++ b/DeerStudio/src/DeerStudio/EditorDataImporter/ShaderData.cpp @@ -1,5 +1,7 @@ #include "DeerRender/Shader.h" -#include "DeerStudio/EditorDataImporter.h" +#include "DeerStudio/StudioResources.h" + +#include namespace Deer { static std::unordered_map preProcess(const std::string& source) { @@ -30,8 +32,16 @@ namespace Deer { } template <> - Scope StorageData::deserialize() { - std::string str_data((char*)data.get(), size); + Scope StorageBackend::load(StorageType storageId) { + ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId); + if (!info) + return Scope(); + + std::ifstream file(info->fullPath); + std::ostringstream ss; + ss << file.rdbuf(); + + std::string str_data = ss.str(); std::unordered_map types = preProcess(str_data); diff --git a/DeerStudio/src/DeerStudio/EditorDataImporter/TextureData.cpp b/DeerStudio/src/DeerStudio/EditorDataImporter/TextureData.cpp index 8aab701..53dd080 100644 --- a/DeerStudio/src/DeerStudio/EditorDataImporter/TextureData.cpp +++ b/DeerStudio/src/DeerStudio/EditorDataImporter/TextureData.cpp @@ -1,20 +1,25 @@ #include "DeerRender/Log.h" #include "DeerRender/Texture.h" -#include "DeerStudio/EditorDataImporter.h" #include "stb_image.h" +#include "DeerStudio/StudioResources.h" + #include namespace Deer { template <> - Scope StorageData::deserialize() { + Scope StorageBackend::load(StorageType storageId) { + ResourceInformation* info = StudioResources::getResourceInfoFromId(storageId); + if (!info) + return Scope(); + stbi_set_flip_vertically_on_load(true); int width, height, channels; - stbi_uc* data = stbi_load_from_memory(getData(), size, &width, &height, &channels, 0); + stbi_uc* data = stbi_load(info->fullPath.c_str(), &width, &height, &channels, 0); if (!data) { - DEER_CORE_ERROR("Error loading {}", getMetadata()["storageId"].c_str()); + DEER_CORE_ERROR("Error loading {}", info->resourcePath.c_str()); return nullptr; } @@ -30,7 +35,7 @@ namespace Deer { format = R8; break; default: - DEER_CORE_ERROR("Error loading {}, invalid chanel count {}", getMetadata()["storageId"].c_str(), channels); + DEER_CORE_ERROR("Error loading {}, invalid chanel count {}", info->resourcePath.c_str(), channels); return nullptr; } diff --git a/DeerStudio/src/DeerStudio/ResourceDataSource.cpp b/DeerStudio/src/DeerStudio/ResourceDataSource.cpp deleted file mode 100644 index 149205f..0000000 --- a/DeerStudio/src/DeerStudio/ResourceDataSource.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "DeerStudio/ResourceDataSource.h" -#include "DeerRender/Log.h" - -#include -#include -#include - -namespace Deer { - StorageData StorageBackend::loadData(const std::string& location) { - Path path = Path("Resources") / location; - std::ifstream file(path, std::ios::binary | std::ios::ate); - if (!file.is_open()) { - DEER_CORE_ERROR("Failed to open file '{}'", location.c_str()); - return StorageData(); - } - - auto size = file.tellg(); - if (size <= 0) { - DEER_CORE_ERROR("File '{}' is empty or has invalid size", location.c_str()); - return StorageData(); - } - - StorageData data = StorageData(size); - uint8_t* data_raw = data.getData(); - file.seekg(0, std::ios::beg); - - if (!file.read(reinterpret_cast(data_raw), size)) { - DEER_CORE_ERROR("Failed to read full file '{}'", location.c_str()); - return StorageData(); - } - - return data; - } - - void StorageBackend::saveData(const std::string& location, const StorageData& data) { - Path path = Path("Resources") / location; - std::ofstream file(path, std::ios::binary); - if (!file.is_open()) { - DEER_CORE_ERROR("Failed to open file '{}' for writing", location.c_str()); - return; - } - - const uint8_t* data_raw = data.getData(); - size_t size = data.getSize(); - - if (!file.write(reinterpret_cast(data_raw), size)) { - DEER_CORE_ERROR("Failed to write full data to file '{}'", location.c_str()); - return; - } - - file.flush(); - } - - StorageMetadata StorageBackend::loadMetadata(const std::string& location) { - Path path = Path("Resources") / (location + ".meta"); - StorageMetadata metadata; - - if (!std::filesystem::exists(path)) { - return metadata; - } - - std::ifstream file(path); - if (!file.is_open()) { - DEER_CORE_TRACE("Failed to open metadata file '{}' for reading", path.string().c_str()); - return metadata; - } - - std::string line; - while (std::getline(file, line)) { - // Skip empty lines or comments - if (line.empty() || line[0] == '#') - continue; - - auto pos = line.find(" : "); - if (pos == std::string::npos) - continue; - - std::string key = line.substr(0, pos); - std::string value = line.substr(pos + 3); // skip " : " - - // Trim whitespace if needed - auto trim = [](std::string& s) { - s.erase(0, s.find_first_not_of(" \t\r\n")); - s.erase(s.find_last_not_of(" \t\r\n") + 1); - }; - trim(key); - trim(value); - - metadata[key] = value; - } - - return metadata; - } - - void StorageBackend::saveMetadata(const StorageMetadata& metadata, const std::string& location) { - Path path = Path("Resources") / (location + ".meta"); - - std::stringstream metadataBuilder; - metadataBuilder << "#Metadata file for resource " << location << "\n"; - - for (const auto& part : metadata) { - metadataBuilder << part.first << " : " << part.second << "\n"; - } - - std::ofstream file(path, std::ios::out | std::ios::trunc); - if (!file.is_open()) { - DEER_CORE_TRACE("Failed to open metadata file '{}' for writing", path.string().c_str()); - return; - } - - file << metadataBuilder.str(); - } -} // namespace Deer \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/StudioAPI.cpp b/DeerStudio/src/DeerStudio/StudioAPI.cpp index 2f2457f..30aa0d6 100644 --- a/DeerStudio/src/DeerStudio/StudioAPI.cpp +++ b/DeerStudio/src/DeerStudio/StudioAPI.cpp @@ -4,21 +4,12 @@ #include "DeerRender/Shader.h" #include "DeerRender/Texture.h" -#include "DeerStudio/EditorDataImporter.h" -#include "DeerStudio/EditorDataSource.h" -#include "DeerStudio/ResourceDataSource.h" - #include "angelscript.h" #include "scriptany.h" #include "scriptarray.h" #include "scriptdictionary.h" namespace Deer { - Resource StudioAPI::getIcon(std::string& icon) { - Path iconPath = Path("Icons") / icon; - return ResourceManager::loadResource(iconPath); - } - ResourceType StudioAPI::getResourceType(std::string& dir) { Path path(dir); std::string extension = path.extension().string(); diff --git a/DeerStudio/src/DeerStudio/StudioScripting.cpp b/DeerStudio/src/DeerStudio/StudioScripting.cpp index 5c9e34c..2179521 100644 --- a/DeerStudio/src/DeerStudio/StudioScripting.cpp +++ b/DeerStudio/src/DeerStudio/StudioScripting.cpp @@ -1,32 +1,30 @@ #include "DeerStudio/StudioScripting.h" #include "DeerRender/Scripting.h" -#include "DeerStudio/ResourceDataSource.h" #include "DeerStudio/StudioAPI.h" +#include "DeerStudio/StudioResources.h" + #include "DeerRender/Mesh.h" #include "DeerRender/Shader.h" #include "DeerRender/Texture.h" + #include "angelscript.h" namespace Deer { void StudioScripting::registerStudioScripting() { asIScriptEngine* scriptEngine = Scripting::getScriptEngine(); - scriptEngine->RegisterEnum("ResourceType"); + scriptEngine->RegisterEnum("Resources"); scriptEngine->RegisterEnumValue("ResourceType", "None", (int)ResourceType::NONE); scriptEngine->RegisterEnumValue("ResourceType", "Mesh", (int)ResourceType::MESH); scriptEngine->RegisterEnumValue("ResourceType", "Shader", (int)ResourceType::SHADER); scriptEngine->RegisterEnumValue("ResourceType", "Texture", (int)ResourceType::TEXTURE); + scriptEngine->SetDefaultNamespace(""); - scriptEngine->SetDefaultNamespace("StudioAPI"); - scriptEngine->RegisterGlobalFunction("Texture loadIcon(string&in)", asFUNCTION(StudioAPI::getIcon), asCALL_CDECL); - scriptEngine->RegisterGlobalFunction("GPUMesh loadGPUMesh(string&in path)", asFUNCTION(ResourceManager::loadResource), asCALL_CDECL); - scriptEngine->RegisterGlobalFunction("Shader loadShader(string&in path)", asFUNCTION(ResourceManager::loadResource), asCALL_CDECL); - scriptEngine->RegisterGlobalFunction("Texture loadTexture(string&in path)", asFUNCTION(ResourceManager::loadResource), asCALL_CDECL); - - scriptEngine->RegisterGlobalFunction("array@ getResourceFolders(string&in path)", asFUNCTION(StudioAPI::getResourceFolders), asCALL_CDECL); - scriptEngine->RegisterGlobalFunction("array@ getResourceFiles(string&in path)", asFUNCTION(StudioAPI::getResourceFiles), asCALL_CDECL); - scriptEngine->RegisterGlobalFunction("ResourceType getResourceType(string&in path)", asFUNCTION(StudioAPI::getResourceType), asCALL_CDECL); + scriptEngine->SetDefaultNamespace("StudioResources"); + scriptEngine->RegisterGlobalFunction("GPUMesh loadGPUMesh(StorageId)", asFUNCTION(ResourceManager::loadResource), asCALL_CDECL); + scriptEngine->RegisterGlobalFunction("Shader loadShader(StorageId)", asFUNCTION(ResourceManager::loadResource), asCALL_CDECL); + scriptEngine->RegisterGlobalFunction("Texture loadTexture(StorageId)", asFUNCTION(ResourceManager::loadResource), asCALL_CDECL); scriptEngine->SetDefaultNamespace(""); } } // namespace Deer \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/WorldManager.cpp b/DeerStudio/src/DeerStudio/WorldManager.cpp index 4df2be2..35517b4 100644 --- a/DeerStudio/src/DeerStudio/WorldManager.cpp +++ b/DeerStudio/src/DeerStudio/WorldManager.cpp @@ -2,8 +2,7 @@ #include "DeerCore/Tools/Memory.h" #include "DeerCore/Universe.h" -#include "DeerStudio/EditorDataImporter.h" -#include "DeerStudio/EditorDataSource.h" +#include "DeerStudio/StudioResources.h" #include "DeerStudio/StudioPanel.h" #include "DeerCore/World.h" @@ -11,12 +10,6 @@ #include "imgui.h" namespace Deer { - template - Scope loadResourceData(const Path& storageId) { - StorageData storageData = StorageBackend::loadData(storageId); - return storageData.deserialize(); - } - void DeerStudio::worldManagerMenu() { if (ImGui::MenuItem("Save world")) { WorldSerializationSettings serializationSettings{ @@ -37,8 +30,9 @@ namespace Deer { }; WorldSerializationSettings serializationSettings{ - .meshLoadingFunction = loadResourceData, - .shaderLoadingFunction = loadResourceData}; + .meshLoadingFunction = ResourceManager::loadResource, + .shaderLoadingFunction = ResourceManager::loadResource + }; World* world_new = Universe::loadWorldFromJson(worldSettings, serializationSettings, "Worlds/world.json"); world = world_new; diff --git a/imgui.ini b/imgui.ini index 64012ac..7838a10 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,6 +1,6 @@ [Window][DockSpace Demo] Pos=0,0 -Size=2560,1371 +Size=1440,749 Collapsed=0 [Window][Debug##Default] @@ -69,7 +69,7 @@ Collapsed=0 DockId=0x00000009,2 [Docking][Data] -DockSpace ID=0x0AC2E849 Window=0xD0388BC8 Pos=0,28 Size=2560,1343 Split=Y +DockSpace ID=0x0AC2E849 Window=0xD0388BC8 Pos=0,26 Size=1440,723 Split=Y DockNode ID=0x00000003 Parent=0x0AC2E849 SizeRef=1920,662 Split=X DockNode ID=0x00000001 Parent=0x00000003 SizeRef=399,985 Selected=0x16E3C1E7 DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1519,985 Split=X