diff --git a/.gitmodules b/.gitmodules index 31079c7..2f603ba 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ [submodule "external/ktx"] path = external/ktx url = https://github.com/KhronosGroup/KTX-Software +[submodule "external/ttf-parser"] + path = external/ttf-parser + url = git@github.com:kv01/ttf-parser.git diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 511fc50..5de037a 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -15,6 +15,7 @@ "configurationProvider": "ms-vscode.cmake-tools", "cppStandard": "c++20", "browse": { + "limitSymbolsToIncludedHeaders": true, "path": [ "${workspaceFolder}/src/**" ] @@ -26,7 +27,6 @@ "includePath": [ "${workspaceFolder}/src/**", "${workspaceFolder}/external/**" - ], "defines": [ "_DEBUG", diff --git a/.vscode/settings.json b/.vscode/settings.json index f0d45b3..eb2460b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -128,12 +128,12 @@ "cmake.configureArgs": [ "-Wno-dev" ], - "C_Cpp.default.cppStandard": "c++20", "files.watcherExclude": { - "**/target": true + "**/target": true, + "bin/**": true, + "external/**": true }, "git.ignoreSubmodules": true, "cmake.configureOnOpen": true, - "cmake.parallelJobs": 0, - "C_Cpp.intelliSenseEngineFallback": "Enabled" + "cmake.parallelJobs": 15 } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c683d0..4970c11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ set(GLFW_ROOT ${EXTERNAL_ROOT}/glfw) set(JSON_ROOT ${EXTERNAL_ROOT}/json) set(KTX_ROOT ${EXTERNAL_ROOT}/ktx) set(STB_ROOT ${EXTERNAL_ROOT}/stb) +set(TTFPARSER_ROOT ${EXTERNAL_ROOT}/ttf-parser) set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross) set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath) @@ -49,38 +50,43 @@ find_package(Threads REQUIRED) find_package(Assimp REQUIRED) find_package(JSON REQUIRED) find_package(GLFW REQUIRED) +find_package(TTFParser REQUIRED) find_package(GLM REQUIRED) find_package(KTX REQUIRED) find_package(STB REQUIRED) find_package(SLANG REQUIRED) find_package(Aftermath REQUIRED) -include_directories(${GLM_INCLUDE_DIRS}) -include_directories(${KTX_INCLUDE_DIRS}) -include_directories(${STB_INCLUDE_DIRS}) -include_directories(${Vulkan_INCLUDE_DIR}) -include_directories(${Boost_INCLUDE_DIRS}) -include_directories(${GLFW_INCLUDE_DIRS}) -include_directories(${SLANG_INCLUDE_DIRS}) -include_directories(${ASSIMP_INCLUDE_DIRS}) -include_directories(${JSON_INCLUDE_DIRS}) -include_directories(${NSAM_INCLUDE_DIRS}) -include_directories(${ENGINE_ROOT}) -include_directories(src/Engine) add_definitions(${Vulkan_DEFINITIONS}) add_definitions(${Boost_DEFINITIONS}) add_compile_definitions(GLFW_WINDOWS) if(WIN32) - add_compile_definitions(USE_EXTENSIONS) + add_compile_definitions(USE_EXTENSIONS) endif() if(CMAKE_DEBUG_POSTFIX) add_compile_definitions(ENABLE_VALIDATION) add_compile_definitions(SEELE_DEBUG) endif() add_executable(Engine "") +target_include_directories(Engine PRIVATE ${GLM_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${KTX_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${STB_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${Vulkan_INCLUDE_DIR}) +target_include_directories(Engine PRIVATE ${Boost_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${GLFW_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${FREETYPE_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${SLANG_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${ASSIMP_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${JSON_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${NSAM_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${TTFPARSER_INCLUDE_DIRS}) +target_include_directories(Engine PRIVATE ${ENGINE_ROOT}) +target_include_directories(Engine PRIVATE src/Engine) + target_link_libraries(Engine ${Vulkan_LIBRARY}) target_link_libraries(Engine ${Boost_LIBRARIES}) target_link_libraries(Engine ${GLFW_LIBRARIES}) +target_link_libraries(Engine ${FREETYPE_LIBRARIES}) target_link_libraries(Engine ${SLANG_LIBRARIES}) target_link_libraries(Engine ${ASSIMP_LIBRARIES}) target_link_libraries(Engine ${NSAM_LIBRARIES}) @@ -111,7 +117,7 @@ add_subdirectory(src/) if(MSVC) set(_CRT_SECURE_NO_WARNINGS) - target_compile_options(Engine PRIVATE /Zi /MP /DEBUG:FASTLINK) + target_compile_options(Engine PRIVATE -Zi -MP -DEBUG) else() target_compile_options(Engine PRIVATE -g -Wall -Wextra -Wno-delete-incomplete -pedantic -fcoroutines) endif() diff --git a/cmake/FindFreeType.cmake b/cmake/FindFreeType.cmake new file mode 100644 index 0000000..18fcda4 --- /dev/null +++ b/cmake/FindFreeType.cmake @@ -0,0 +1,89 @@ +# +# Find FREETYPE +# +# Try to find FREETYPE library. +# This module defines the following variables: +# - FREETYPE_INCLUDE_DIRS +# - FREETYPE_LIBRARIES +# - FREETYPE_FOUND +# +# The following variables can be set as arguments for the module. +# - FREETYPE_ROOT : Root library directory of FREETYPE +# - FREETYPE_USE_STATIC_LIBS : Specifies to use static version of FREETYPE library (Windows only) +# +# References: +# - https://github.com/progschj/OpenGL-Examples/blob/master/cmake_modules/FindFREETYPE.cmake +# - https://bitbucket.org/Ident8/cegui-mk2-opengl3-renderer/src/befd47200265/cmake/FindFREETYPE.cmake +# + +# Additional modules +include(FindPackageHandleStandardArgs) + +if (WIN32) + # Find include files + find_path( + FREETYPE_INCLUDE_DIR + NAMES freetype/freetype.h + PATHS + $ENV{PROGRAMFILES}/include + ${FREETYPE_ROOT}/include + DOC "The directory where FREETYPE/glfw.h resides") + + # Find library files + find_library( + FREETYPE_LIBRARY + NAMES freetype${CMAKE_DEBUG_POSTFIX}.lib + PATHS + $ENV{PROGRAMFILES}/lib + ${FREETYPE_ROOT}/lib + ${FREETYPE_ROOT} + PATH_SUFFIXES Debug Release) + + + find_file( + FREETYPE_BINARY + NAMES freetype${CMAKE_DEBUG_POSTFIX}.dll + PATHS + $ENV{PROGRAMFILES}/bin + ${CMAKE_BINARY_DIR} + ${FREETYPE_ROOT}/src + ${FREETYPE_ROOT} + PATH_SUFFIXES Debug Release) +else() + # Find include files + find_path( + FREETYPE_INCLUDE_DIR + NAMES FREETYPE/glfw3.h + PATHS + /usr/include + /usr/local/include + /sw/include + /opt/local/include + DOC "The directory where GL/glfw.h resides") + + # Find library files + find_file( + FREETYPE_LIBRARY + NAMES libglfw${CMAKE_DEBUG_POSTFIX}.so + PATHS + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /sw/lib + /opt/local/lib + ${FREETYPE_ROOT}/src + ) +endif() + +# Handle REQUIRD argument, define *_FOUND variable +find_package_handle_standard_args(FREETYPE DEFAULT_MSG FREETYPE_INCLUDE_DIR FREETYPE_LIBRARY FREETYPE_BINARY) + +# Define FREETYPE_LIBRARIES and FREETYPE_INCLUDE_DIRS +if (FREETYPE_FOUND) + set(FREETYPE_LIBRARIES ${FREETYPE_LIBRARY}) + set(FREETYPE_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIR}) +endif() + +# Hide some variables +mark_as_advanced(FREETYPE_INCLUDE_DIR FREETYPE_LIBRARY) \ No newline at end of file diff --git a/cmake/FindTTFParser.cmake b/cmake/FindTTFParser.cmake new file mode 100644 index 0000000..a13f268 --- /dev/null +++ b/cmake/FindTTFParser.cmake @@ -0,0 +1,68 @@ +# +# Find TTFPARSER +# +# Try to find TTFPARSER library. +# This module defines the following variables: +# - TTFPARSER_INCLUDE_DIRS +# - TTFPARSER_LIBRARIES +# - TTFPARSER_FOUND +# +# The following variables can be set as arguments for the module. +# - TTFPARSER_ROOT : Root library directory of TTFPARSER +# - TTFPARSER_USE_STATIC_LIBS : Specifies to use static version of TTFPARSER library (Windows only) +# +# References: +# - https://github.com/progschj/OpenGL-Examples/blob/master/cmake_modules/FindTTFPARSER.cmake +# - https://bitbucket.org/Ident8/cegui-mk2-opengl3-renderer/src/befd47200265/cmake/FindTTFPARSER.cmake +# + +# Additional modules +include(FindPackageHandleStandardArgs) + +if (WIN32) + # Find include files + find_path( + TTFPARSER_INCLUDE_DIR + NAMES ttfParser.h + PATHS + $ENV{PROGRAMFILES}/include + ${TTFPARSER_ROOT}/src + DOC "The directory where TTFPARSER/glfw.h resides") + +else() + # Find include files + find_path( + TTFPARSER_INCLUDE_DIR + NAMES TTFPARSER/glfw3.h + PATHS + /usr/include + /usr/local/include + /sw/include + /opt/local/include + DOC "The directory where GL/glfw.h resides") + + # Find library files + find_file( + TTFPARSER_LIBRARY + NAMES libglfw${CMAKE_DEBUG_POSTFIX}.so + PATHS + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /sw/lib + /opt/local/lib + ${TTFPARSER_ROOT}/src + ) +endif() + +# Handle REQUIRD argument, define *_FOUND variable +find_package_handle_standard_args(TTFPARSER DEFAULT_MSG TTFPARSER_INCLUDE_DIR) + +# Define TTFPARSER_LIBRARIES and TTFPARSER_INCLUDE_DIRS +if (TTFPARSER_FOUND) + set(TTFPARSER_INCLUDE_DIRS ${TTFPARSER_INCLUDE_DIR}) +endif() + +# Hide some variables +mark_as_advanced(TTFPARSER_INCLUDE_DIR) \ No newline at end of file diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index 33cfdf4..d7d98e4 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -61,6 +61,11 @@ set(GLFW_VULKAN_STATIC OFF CACHE BOOL "GLFW vulkan static") add_subdirectory(${GLFW_ROOT} ${GLFW_ROOT}) +#--------------FreeType------------------------------ +#list(APPEND DEPENDENCIES freetype) + +#add_subdirectory(${FREETYPE_ROOT} ${FREETYPE_ROOT}) + #--------------SLang------------------------------ list(APPEND DEPENDENCIES slang) string(TOLOWER release_${CMAKE_PLATFORM} SLANG_CONFIG) diff --git a/compile_commands.json b/compile_commands.json deleted file mode 120000 index f2b5938..0000000 --- a/compile_commands.json +++ /dev/null @@ -1 +0,0 @@ -bin/Debug/compile_commands.json \ No newline at end of file diff --git a/external/ttf-parser b/external/ttf-parser new file mode 160000 index 0000000..065fcd9 --- /dev/null +++ b/external/ttf-parser @@ -0,0 +1 @@ +Subproject commit 065fcd9db7c2d7256b1ae77480a269db1f689d8e diff --git a/res/fonts/GILBI___.TTF b/res/fonts/GILBI___.TTF new file mode 100644 index 0000000..97c6bbb Binary files /dev/null and b/res/fonts/GILBI___.TTF differ diff --git a/res/fonts/GILB____.TTF b/res/fonts/GILB____.TTF new file mode 100644 index 0000000..1cad3fd Binary files /dev/null and b/res/fonts/GILB____.TTF differ diff --git a/res/fonts/GILC____.TTF b/res/fonts/GILC____.TTF new file mode 100644 index 0000000..0dca98a Binary files /dev/null and b/res/fonts/GILC____.TTF differ diff --git a/res/fonts/GILI____.TTF b/res/fonts/GILI____.TTF new file mode 100644 index 0000000..35d0fe8 Binary files /dev/null and b/res/fonts/GILI____.TTF differ diff --git a/res/fonts/GIL_____.TTF b/res/fonts/GIL_____.TTF new file mode 100644 index 0000000..bb58254 Binary files /dev/null and b/res/fonts/GIL_____.TTF differ diff --git a/res/fonts/GLSNECB.TTF b/res/fonts/GLSNECB.TTF new file mode 100644 index 0000000..211982c Binary files /dev/null and b/res/fonts/GLSNECB.TTF differ diff --git a/res/fonts/Gill Sans MT Condensed Bold.ttf b/res/fonts/Gill Sans MT Condensed Bold.ttf new file mode 100644 index 0000000..d7b0a30 Binary files /dev/null and b/res/fonts/Gill Sans MT Condensed Bold.ttf differ diff --git a/res/fonts/Gill Sans MT Light Italic.ttf b/res/fonts/Gill Sans MT Light Italic.ttf new file mode 100644 index 0000000..6c74c9e Binary files /dev/null and b/res/fonts/Gill Sans MT Light Italic.ttf differ diff --git a/res/fonts/Gill Sans MT Light.ttf b/res/fonts/Gill Sans MT Light.ttf new file mode 100644 index 0000000..7cc7a57 Binary files /dev/null and b/res/fonts/Gill Sans MT Light.ttf differ diff --git a/src/Engine/Asset/Asset.cpp b/src/Engine/Asset/Asset.cpp index 9ae4201..d6b7b9e 100644 --- a/src/Engine/Asset/Asset.cpp +++ b/src/Engine/Asset/Asset.cpp @@ -40,24 +40,14 @@ Asset::~Asset() { } -std::ifstream &Asset::getReadStream() +std::ifstream Asset::getReadStream() const { - if(inStream.is_open()) - { - return inStream; - } - inStream.open(fullPath); - return inStream; + return std::ifstream(fullPath); } -std::ofstream &Asset::getWriteStream() +std::ofstream Asset::getWriteStream() const { - if(outStream.is_open()) - { - return outStream; - } - outStream.open(fullPath); - return outStream; + return std::ofstream(fullPath); } std::string Asset::getFileName() const diff --git a/src/Engine/Asset/Asset.h b/src/Engine/Asset/Asset.h index 5fa86bb..fc0f9e5 100644 --- a/src/Engine/Asset/Asset.h +++ b/src/Engine/Asset/Asset.h @@ -38,8 +38,8 @@ public: } protected: std::mutex lock; - std::ifstream& getReadStream(); - std::ofstream& getWriteStream(); + std::ifstream getReadStream() const; + std::ofstream getWriteStream() const; private: // Path relative to the project root std::filesystem::path fullPath; @@ -48,8 +48,6 @@ private: std::filesystem::path extension; Status status; uint32 byteSize; - std::ifstream inStream; - std::ofstream outStream; }; DEFINE_REF(Asset) } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index 9a6d037..7a532f3 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -1,6 +1,8 @@ #include "AssetRegistry.h" #include "MeshAsset.h" +#include "FontAsset.h" #include "TextureAsset.h" +#include "FontLoader.h" #include "TextureLoader.h" #include "MaterialLoader.h" #include "MeshLoader.h" @@ -37,6 +39,10 @@ void AssetRegistry::importFile(const std::string &filePath) { get().importTexture(fsPath); } + if(extension.compare(".ttf") == 0) + { + get().importFont(fsPath); + } if (extension.compare(".asset") == 0) { get().importMaterial(fsPath); @@ -55,6 +61,11 @@ PTextureAsset AssetRegistry::findTexture(const std::string &filePath) return get().textures[filePath]; } +PFontAsset AssetRegistry::findFont(const std::string& name) +{ + return get().fonts[name]; +} + PMaterialAsset AssetRegistry::findMaterial(const std::string &filePath) { return get().materials[filePath]; @@ -84,6 +95,7 @@ void AssetRegistry::init(const std::filesystem::path &rootFolder, Gfx::PGraphics { AssetRegistry ® = get(); reg.rootFolder = rootFolder; + reg.fontLoader = new FontLoader(graphics); reg.meshLoader = new MeshLoader(graphics); reg.textureLoader = new TextureLoader(graphics); reg.materialLoader = new MaterialLoader(graphics); @@ -104,6 +116,11 @@ void AssetRegistry::importTexture(const std::filesystem::path &filePath) textureLoader->importAsset(filePath); } +void AssetRegistry::importFont(const std::filesystem::path& filePath) +{ + fontLoader->importAsset(filePath); +} + void AssetRegistry::importMaterial(const std::filesystem::path &filePath) { materialLoader->importAsset(filePath); @@ -131,6 +148,11 @@ void AssetRegistry::registerTexture(PTextureAsset texture) textures[texture->getFileName()] = texture; } +void AssetRegistry::registerFont(PFontAsset font) +{ + fonts[font->getFileName()] = font; +} + void AssetRegistry::registerMaterial(PMaterialAsset material) { materials[material->getFileName()] = material; diff --git a/src/Engine/Asset/AssetRegistry.h b/src/Engine/Asset/AssetRegistry.h index 9e53d05..c0b785c 100644 --- a/src/Engine/Asset/AssetRegistry.h +++ b/src/Engine/Asset/AssetRegistry.h @@ -7,9 +7,11 @@ namespace Seele { DECLARE_REF(TextureLoader) +DECLARE_REF(FontLoader) DECLARE_REF(MeshLoader) DECLARE_REF(MaterialLoader) DECLARE_REF(TextureAsset) +DECLARE_REF(FontAsset) DECLARE_REF(MeshAsset) DECLARE_REF(MaterialAsset) DECLARE_NAME_REF(Gfx, Graphics) @@ -25,6 +27,7 @@ public: static PMeshAsset findMesh(const std::string& filePath); static PTextureAsset findTexture(const std::string& filePath); + static PFontAsset findFont(const std::string& name); static PMaterialAsset findMaterial(const std::string& filePath); static std::ofstream createWriteStream(const std::string& relativePath, std::ios_base::openmode openmode = std::ios::out); @@ -37,10 +40,12 @@ private: void importMesh(const std::filesystem::path& filePath); void importTexture(const std::filesystem::path& filePath); + void importFont(const std::filesystem::path& filePath); void importMaterial(const std::filesystem::path& filePath); void registerMesh(PMeshAsset mesh); void registerTexture(PTextureAsset texture); + void registerFont(PFontAsset font); void registerMaterial(PMaterialAsset material); std::ofstream internalCreateWriteStream(const std::string& relativePath, std::ios_base::openmode openmode = std::ios::out); @@ -49,12 +54,15 @@ private: std::filesystem::path rootFolder; //Todo: Seele::Map doesn't really work with strings for some reason, so just use std::map for now std::map textures; + std::map fonts; std::map meshes; std::map materials; UPTextureLoader textureLoader; + UPFontLoader fontLoader; UPMeshLoader meshLoader; UPMaterialLoader materialLoader; friend class TextureLoader; + friend class FontLoader; friend class MaterialLoader; friend class MeshLoader; }; diff --git a/src/Engine/Asset/CMakeLists.txt b/src/Engine/Asset/CMakeLists.txt index c5c7eae..2e3e90a 100644 --- a/src/Engine/Asset/CMakeLists.txt +++ b/src/Engine/Asset/CMakeLists.txt @@ -4,6 +4,10 @@ target_sources(Engine Asset.cpp AssetRegistry.h AssetRegistry.cpp + FontAsset.h + FontAsset.cpp + FontLoader.h + FontLoader.cpp MaterialLoader.h MaterialLoader.cpp MeshAsset.h diff --git a/src/Engine/Asset/FontAsset.cpp b/src/Engine/Asset/FontAsset.cpp new file mode 100644 index 0000000..fc4ef72 --- /dev/null +++ b/src/Engine/Asset/FontAsset.cpp @@ -0,0 +1,50 @@ +#include "FontAsset.h" +#include "Graphics/GraphicsResources.h" +#define TTF_FONT_PARSER_IMPLEMENTATION +#include "ttfParser.h" + +using namespace Seele; + +FontAsset::FontAsset() +{ +} + +FontAsset::FontAsset(const std::string& directory, const std::string& name) + : Asset(directory, name) +{ +} + +FontAsset::FontAsset(const std::filesystem::path& fullPath) + : Asset(fullPath) +{ +} + +FontAsset::~FontAsset() +{ + +} + +void FontAsset::save() +{ + assert(false && "Cannot save font files"); +} + +void FontAsset::load() +{ + TTFFontParser::FontData font_data; + int8_t error = TTFFontParser::parse_file(getFullPath().c_str(), &font_data, [](void*, void*, int){}, nullptr); + assert(!error); + for(auto pair : font_data.glyphs) + { + const TTFFontParser::Glyph& glyphData = pair.second; + Glyph& glyph = glyphs[pair.first]; + glyph.advance = glyphData.advance_width; + std::memcpy(glyph.boundingBox, glyphData.bounding_box, sizeof(glyphData.bounding_box)); + glyph.center = Vector2(glyphData.glyph_center.x, glyphData.glyph_center.y); + glyph.index = glyphData.glyph_index; + glyph.leftSideBearing = glyphData.left_side_bearing; + glyph.numContours = glyphData.num_contours; + Array curveTextureData; + + } +} \ No newline at end of file diff --git a/src/Engine/Asset/FontAsset.h b/src/Engine/Asset/FontAsset.h new file mode 100644 index 0000000..4a2ac73 --- /dev/null +++ b/src/Engine/Asset/FontAsset.h @@ -0,0 +1,31 @@ +#pragma once +#include "Asset.h" + +namespace Seele +{ +DECLARE_NAME_REF(Gfx, Texture2D) +class FontAsset : public Asset +{ +public: + FontAsset(); + FontAsset(const std::string& directory, const std::string& name); + FontAsset(const std::filesystem::path& fullPath); + virtual ~FontAsset(); + virtual void save() override; + virtual void load() override; +private: + struct Glyph + { + int16 index; + int16 numContours; + uint16 advance; + int16 leftSideBearing; + int16 boundingBox[4]; + Vector2 center; + Gfx::PTexture2D curveTexture; + Gfx::PTexture2D bandTexture; + }; + Map glyphs; +}; +DECLARE_REF(FontAsset) +} // namespace Seele diff --git a/src/Engine/Asset/FontLoader.cpp b/src/Engine/Asset/FontLoader.cpp new file mode 100644 index 0000000..35744e2 --- /dev/null +++ b/src/Engine/Asset/FontLoader.cpp @@ -0,0 +1,34 @@ +#include "FontLoader.h" +#include "Graphics/Graphics.h" +#include "FontAsset.h" +#include "AssetRegistry.h" + +using namespace Seele; + +FontLoader::FontLoader(Gfx::PGraphics graphics) + : graphics(graphics) +{ + +} + +FontLoader::~FontLoader() +{ +} + +void FontLoader::importAsset(const std::filesystem::path& filePath) +{ + std::filesystem::path assetPath = filePath.filename(); + assetPath.replace_extension("asset"); + PFontAsset asset = new FontAsset(assetPath.generic_string()); + std::error_code code; + std::filesystem::copy_file(filePath, asset->getFullPath(), code); + asset->setStatus(Asset::Status::Loading); + AssetRegistry::get().registerFont(asset); + import(filePath, asset); +} + +void FontLoader::import(std::filesystem::path path, PFontAsset asset) +{ + asset->load(); + AssetRegistry::get().registerFont(asset); +} \ No newline at end of file diff --git a/src/Engine/Asset/FontLoader.h b/src/Engine/Asset/FontLoader.h new file mode 100644 index 0000000..331ada5 --- /dev/null +++ b/src/Engine/Asset/FontLoader.h @@ -0,0 +1,22 @@ +#pragma once +#include "MinimalEngine.h" +#include "Containers/List.h" +#include "ThreadPool.h" +#include + +namespace Seele +{ +DECLARE_REF(FontAsset) +DECLARE_NAME_REF(Gfx, Graphics) +class FontLoader +{ +public: + FontLoader(Gfx::PGraphics graphic); + ~FontLoader(); + void importAsset(const std::filesystem::path& filePath); +private: + void import(std::filesystem::path path, PFontAsset asset); + Gfx::PGraphics graphics; +}; +DEFINE_REF(FontLoader) +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Asset/MaterialLoader.h b/src/Engine/Asset/MaterialLoader.h index 7deb336..b011a08 100644 --- a/src/Engine/Asset/MaterialLoader.h +++ b/src/Engine/Asset/MaterialLoader.h @@ -2,8 +2,6 @@ #include "MinimalEngine.h" #include "Containers/List.h" #include "ThreadPool.h" -#include -#include #include namespace Seele @@ -20,7 +18,6 @@ public: private: void import(std::filesystem::path filePath, PMaterialAsset asset); Gfx::PGraphics graphics; - List> futures; PMaterialAsset placeholderMaterial; }; DEFINE_REF(MaterialLoader) diff --git a/src/Engine/Asset/MeshLoader.h b/src/Engine/Asset/MeshLoader.h index d97abf3..e313931 100644 --- a/src/Engine/Asset/MeshLoader.h +++ b/src/Engine/Asset/MeshLoader.h @@ -2,8 +2,6 @@ #include "MinimalEngine.h" #include "Containers/List.h" #include "ThreadPool.h" -#include -#include #include struct aiScene; @@ -27,7 +25,6 @@ private: void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels); void import(std::filesystem::path path, PMeshAsset meshAsset); - List> futures; Gfx::PGraphics graphics; }; DEFINE_REF(MeshLoader) diff --git a/src/Engine/Asset/TextureLoader.h b/src/Engine/Asset/TextureLoader.h index c49145f..5a7ea5d 100644 --- a/src/Engine/Asset/TextureLoader.h +++ b/src/Engine/Asset/TextureLoader.h @@ -2,8 +2,6 @@ #include "MinimalEngine.h" #include "Containers/List.h" #include "ThreadPool.h" -#include -#include #include namespace Seele @@ -21,7 +19,6 @@ public: private: void import(std::filesystem::path path, PTextureAsset asset); Gfx::PGraphics graphics; - List> futures; PTextureAsset placeholderAsset; }; DEFINE_REF(TextureLoader) diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 8642ef5..83c7abd 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #ifndef DEFAULT_ALLOC_SIZE @@ -103,7 +104,7 @@ public: markIteratorDirty(); } - constexpr explicit Array(const allocator_type& alloc) + constexpr explicit Array(const allocator_type& alloc) noexcept : arraySize(0) , allocated(DEFAULT_ALLOC_SIZE) , allocator(alloc) @@ -169,7 +170,7 @@ public: other.arraySize = 0; markIteratorDirty(); } - Array &operator=(const Array &other) noexcept + Array &operator=(const Array &other) { if (this != &other) { @@ -197,7 +198,8 @@ public: } return *this; } - Array &operator=(Array &&other) noexcept + Array &operator=(Array &&other) noexcept(std::allocator_traits::propagate_on_container_move_assignment::value + || std::allocator_traits::is_always_equal::value) { if (this != &other) { @@ -217,24 +219,14 @@ public: } return *this; } - ~Array() + constexpr ~Array() { clear(); } - - constexpr bool operator==(const Array &other) + [[nodiscard]] + constexpr iterator find(const value_type &item) noexcept { - return _data == other._data; - } - - constexpr bool operator!=(const Array &other) - { - return !(*this == other); - } - - constexpr iterator find(const value_type &item) - { - for (uint32 i = 0; i < arraySize; ++i) + for (size_type i = 0; i < arraySize; ++i) { if (_data[i] == item) { @@ -243,9 +235,10 @@ public: } return endIt; } - constexpr iterator find(value_type&& item) + [[nodiscard]] + constexpr iterator find(value_type&& item) noexcept { - for (uint32 i = 0; i < arraySize; ++i) + for (size_type i = 0; i < arraySize; ++i) { if (_data[i] == item) { @@ -254,23 +247,36 @@ public: } return endIt; } - constexpr allocator_type get_allocator() const + //template Pred> + template + constexpr iterator find(Pred pred) const noexcept + { + for (size_type i = 0; i < arraySize; ++i) + { + if(pred(_data[i])) + { + return iterator(&_data[i]); + } + } + return endIt; + } + constexpr allocator_type get_allocator() const noexcept { return allocator; } - constexpr iterator begin() const + constexpr iterator begin() const noexcept { return beginIt; } - constexpr iterator end() const + constexpr iterator end() const noexcept { return endIt; } - constexpr const_iterator cbegin() const + constexpr const_iterator cbegin() const noexcept { return beginIt; } - constexpr const_iterator cend() const + constexpr const_iterator cend() const noexcept { return endIt; } @@ -316,6 +322,19 @@ public: markIteratorDirty(); return _data[arraySize - 1]; } + template + constexpr void remove_if(Pred pred, bool keepOrder = true) + { + remove(find(pred), keepOrder); + } + constexpr void remove(const value_type& element, bool keepOrder = true) + { + remove(find(element), keepOrder); + } + constexpr void remove(value_type&& element, bool keepOrder = true) + { + remove(find(element), keepOrder); + } constexpr void remove(iterator it, bool keepOrder = true) { remove(it - beginIt, keepOrder); @@ -324,7 +343,7 @@ public: { if (keepOrder) { - for(uint32 i = index; i < arraySize-1; ++i) + for(size_type i = index; i < arraySize-1; ++i) { _data[i] = std::move(_data[i+1]); } @@ -344,7 +363,7 @@ public: { resizeInternal(newSize, value); } - constexpr void clear() + constexpr void clear() noexcept { if(_data == nullptr) { @@ -360,59 +379,71 @@ public: allocated = 0; markIteratorDirty(); } - inline size_type indexOf(iterator iterator) + constexpr size_type indexOf(iterator iterator) { return iterator - beginIt; } - inline size_type indexOf(const_iterator iterator) const + constexpr size_type indexOf(const_iterator iterator) const { return iterator.p - beginIt.p; } - inline size_type indexOf(T& t) + constexpr size_type indexOf(T& t) { return indexOf(find(t)); } - inline size_type indexOf(const T& t) const + constexpr size_type indexOf(const T& t) const { return indexOf(find(t)); } - inline size_type size() const + constexpr size_type size() const noexcept { return arraySize; } - inline size_type empty() const + [[nodiscard]] + constexpr bool empty() const noexcept { return arraySize == 0; } - inline size_type capacity() const + constexpr void reserve(size_type new_cap) + { + if(new_cap > allocated) + { + T* temp = allocateArray(new_cap); + std::uninitialized_move_n(beginIt, arraySize, temp); + _data = temp; + markIteratorDirty(); + } + allocated = new_cap; + } + constexpr size_type capacity() const noexcept { return allocated; } - inline pointer data() const + constexpr pointer data() const noexcept { return _data; } - inline reference front() const + constexpr reference front() const { assert(arraySize > 0); return _data[0]; } - inline reference back() const + constexpr reference back() const { assert(arraySize > 0); return _data[arraySize - 1]; } - void pop() + constexpr void pop() { std::allocator_traits::destroy(allocator, &_data[--arraySize]); markIteratorDirty(); } - constexpr inline reference operator[](size_type index) + constexpr reference operator[](size_type index) { assert(index < arraySize); return _data[index]; } - constexpr inline const reference operator[](size_type index) const + constexpr const reference operator[](size_type index) const { assert(index < arraySize); return _data[index]; @@ -441,6 +472,7 @@ private: beginIt = Iterator(_data); endIt = Iterator(_data + arraySize); } + [[nodiscard]] T* allocateArray(size_type size) { T* result = allocator.allocate(size); @@ -452,7 +484,7 @@ private: allocator.deallocate(ptr, size); } template - T& addInternal(Type&& t) + T& addInternal(Type&& t) noexcept { if (arraySize == allocated) { @@ -471,7 +503,7 @@ private: return _data[arraySize - 1]; } template - void resizeInternal(size_type newSize, Type&& value) + void resizeInternal(size_type newSize, Type&& value) noexcept { if (newSize <= allocated) { @@ -534,6 +566,30 @@ private: allocator_type allocator; }; + +template +constexpr bool operator==(const Array &lhs, const Array& rhs) +{ + if(lhs.size() != rhs.size()) + { + return false; + } + for(auto it1 = lhs.begin(), it2 = rhs.begin(); it1 != lhs.end() && it2 != rhs.end(); ++it1, ++it2) + { + if(*it1 != *it2) + { + return false; + } + } + return true; +} + +template +constexpr auto operator<=>(const Array& lhs, const Array& rhs) +{ + return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +} + template struct StaticArray { diff --git a/src/Engine/Containers/RingBuffer.h b/src/Engine/Containers/RingBuffer.h deleted file mode 100644 index f75d0aa..0000000 --- a/src/Engine/Containers/RingBuffer.h +++ /dev/null @@ -1,414 +0,0 @@ -#pragma once -#include "MinimalEngine.h" -#include "Array.h" - -namespace Seele -{ -template> -class RingBuffer -{ -public: - template - class IteratorBase - { - public: - using iterator_category = std::random_access_iterator_tag; - using value_type = X; - using difference_type = std::ptrdiff_t; - using reference = X&; - using pointer = X*; - - IteratorBase(Array& arr, size_t index) - : arr(arr) - , index(index) - { - } - reference operator*() const - { - return arr[index]; - } - pointer operator->() const - { - return &arr[index]; - } - inline bool operator!=(const IteratorBase &other) const - { - return arr != other.arr && index != other.index; - } - inline bool operator==(const IteratorBase &other) const - { - return arr == other.arr && index == other.index; - } - inline int operator-(const IteratorBase &other) const - { - return (int)(index - other.index); - } - IteratorBase &operator++() - { - index = (index + 1) % arr.size(); - return *this; - } - IteratorBase &operator--() - { - index = (index + 1) % arr.size(); - return *this; - } - IteratorBase operator++(int) - { - IteratorBase tmp(*this); - ++*this; - return tmp; - } - IteratorBase operator--(int) - { - IteratorBase tmp(*this); - --*this; - return tmp; - } - - private: - Array& arr; - size_t index; - }; - - using value_type = T; - using allocator_type = Allocator; - using size_type = std::size_t; - using difference_type = std::ptrdiff_t; - using pointer = T*; - using const_pointer = const T*; - using reference = value_type&; - using const_reference = const value_type&; - - using Iterator = IteratorBase; - using ConstIterator = IteratorBase; - using iterator = Iterator; - using const_iterator = ConstIterator; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - - constexpr RingBuffer() noexcept(noexcept(Allocator())) - { - refreshIterators(); - } - - constexpr explicit RingBuffer(const allocator_type& alloc) - : data(alloc) - { - refreshIterators(); - } - constexpr RingBuffer(size_type size, const value_type& value, const allocator_type& alloc = allocator_type()) - : data(size, value, alloc) - , end(size) - { - refreshIterators(); - } - constexpr explicit RingBuffer(size_type size, const allocator_type& alloc = allocator_type()) - : arraySize(size) - , allocated(size) - , allocator(alloc) - { - _data = allocateRingBuffer(size); - assert(_data != nullptr); - for (size_type i = 0; i < size; ++i) - { - std::allocator_traits::construct(allocator, &_data[i]); - } - markIteratorDirty(); - } - constexpr RingBuffer(std::initializer_list init, const allocator_type& alloc = allocator_type()) - : arraySize(init.size()) - , allocated(init.size()) - , allocator(alloc) - { - _data = allocateRingBuffer(init.size()); - assert(_data != nullptr); - markIteratorDirty(); - std::uninitialized_copy(init.begin(), init.end(), begin()); - } - RingBuffer(const RingBuffer &other) - : arraySize(other.arraySize) - , allocated(other.allocated) - , allocator(std::allocator_traits::select_on_container_copy_construction(other.allocator)) - { - _data = allocateRingBuffer(other.allocated); - assert(_data != nullptr); - markIteratorDirty(); - std::uninitialized_copy(other.begin(), other.end(), begin()); - } - RingBuffer(RingBuffer &&other) noexcept - : arraySize(std::move(other.arraySize)) - , allocated(std::move(other.allocated)) - , allocator(std::move(other.allocator)) - { - _data = other._data; - other._data = nullptr; - other.allocated = 0; - other.arraySize = 0; - markIteratorDirty(); - } - RingBuffer &operator=(const RingBuffer &other) noexcept - { - if (this != &other) - { - if constexpr (std::allocator_traits::propagate_on_container_copy_assignment::value ) - { - if (!std::allocator_traits::is_always_equal::value - && allocator != other.allocator) - { - clear(); - } - allocator = other.allocator; - } - if (other.arraySize > allocated) - { - clear(); - } - if(_data == nullptr) - { - _data = allocateRingBuffer(other.allocated); - allocated = other.allocated; - } - arraySize = other.arraySize; - markIteratorDirty(); - std::uninitialized_copy(other.begin(), other.end(), begin()); - } - return *this; - } - RingBuffer &operator=(RingBuffer &&other) noexcept - { - if (this != &other) - { - if constexpr (std::allocator_traits::propagate_on_container_move_assignment::value) - { - allocator = std::move(other.allocator); - } - if (_data != nullptr) - { - clear(); - } - allocated = std::move(other.allocated); - arraySize = std::move(other.arraySize); - _data = other._data; - other._data = nullptr; - markIteratorDirty(); - } - return *this; - } - ~RingBuffer() - { - clear(); - } - - constexpr bool operator==(const RingBuffer &other) - { - return _data == other._data; - } - - constexpr bool operator!=(const RingBuffer &other) - { - return !(*this == other); - } - - constexpr iterator find(const value_type &item) - { - for (uint32 i = 0; i < arraySize; ++i) - { - if (_data[i] == item) - { - return iterator(&_data[i]); - } - } - return endIt; - } - constexpr iterator find(value_type&& item) - { - for (uint32 i = 0; i < arraySize; ++i) - { - if (_data[i] == item) - { - return iterator(&_data[i]); - } - } - return endIt; - } - constexpr allocator_type get_allocator() const - { - return allocator; - } - constexpr iterator begin() const - { - return beginIt; - } - constexpr iterator end() const - { - return endIt; - } - constexpr const_iterator cbegin() const - { - return beginIt; - } - constexpr const_iterator cend() const - { - return endIt; - } - constexpr reference add(const value_type &item = value_type()) - { - return addInternal(item); - } - constexpr reference add(value_type&& item) - { - return addInternal(std::forward(item)); - } - constexpr void addAll(RingBuffer other) - { - for(auto value : other) - { - addInternal(value); - } - } - constexpr reference addUnique(const value_type &item = value_type()) - { - iterator it; - if((it = std::move(find(item))) != endIt) - { - return *it; - } - return addInternal(item); - } - template - constexpr reference emplace(args... arguments) - { - if (arraySize == allocated) - { - size_type newSize = arraySize + 1; - allocated = calculateGrowth(newSize); - T *tempRingBuffer = allocateRingBuffer(allocated); - assert(tempRingBuffer != nullptr); - - std::uninitialized_move(begin(), end(), Iterator(tempRingBuffer)); - deallocateRingBuffer(_data, arraySize); - _data = tempRingBuffer; - } - std::allocator_traits::construct(allocator, &_data[arraySize++], arguments...); - markIteratorDirty(); - return _data[arraySize - 1]; - } - constexpr void remove(iterator it, bool keepOrder = true) - { - remove(it - beginIt, keepOrder); - } - constexpr void remove(size_type index, bool keepOrder = true) - { - if (keepOrder) - { - for(uint32 i = index; i < arraySize-1; ++i) - { - _data[i] = std::move(_data[i+1]); - } - } - else - { - _data[index] = std::move(_data[arraySize - 1]); - } - std::allocator_traits::destroy(allocator, &_data[--arraySize]); - markIteratorDirty(); - } - constexpr void resize(size_type newSize) - { - resizeInternal(newSize, std::move(T())); - } - constexpr void resize(size_type newSize, const value_type& value) - { - resizeInternal(newSize, value); - } - constexpr void clear() - { - if(_data == nullptr) - { - return; - } - for(size_type i = 0; i < arraySize; ++i) - { - std::allocator_traits::destroy(allocator, &_data[i]); - } - deallocateRingBuffer(_data, allocated); - _data = nullptr; - arraySize = 0; - allocated = 0; - markIteratorDirty(); - } - inline size_type indexOf(iterator iterator) - { - return iterator - beginIt; - } - inline size_type indexOf(const_iterator iterator) const - { - return iterator.p - beginIt.p; - } - inline size_type indexOf(T& t) - { - return indexOf(find(t)); - } - inline size_type indexOf(const T& t) const - { - return indexOf(find(t)); - } - inline size_type size() const - { - return arraySize; - } - inline size_type empty() const - { - return arraySize == 0; - } - inline size_type capacity() const - { - return allocated; - } - inline pointer data() const - { - return _data; - } - inline reference front() const - { - assert(arraySize > 0); - return _data[0]; - } - inline reference back() const - { - assert(arraySize > 0); - return _data[arraySize - 1]; - } - void pop() - { - std::allocator_traits::destroy(allocator, &_data[--arraySize]); - markIteratorDirty(); - } - constexpr inline reference operator[](size_type index) - { - assert(index < arraySize); - return _data[index]; - } - constexpr inline const reference operator[](size_type index) const - { - assert(index < arraySize); - return _data[index]; - } -private: - void refreshIterators() - { - beginIt = Iterator(data, begin); - endIt = Iterator(data, end); - } - size_type begin = 0; - size_type end = 0; - iterator beginIt; - iterator endIt; - Array data; -}; -class StaticRingBuffer -{ - -}; -} // namespace Seele diff --git a/src/Engine/Material/MaterialAsset.cpp b/src/Engine/Material/MaterialAsset.cpp index 051fb9d..ae22592 100644 --- a/src/Engine/Material/MaterialAsset.cpp +++ b/src/Engine/Material/MaterialAsset.cpp @@ -42,7 +42,7 @@ void MaterialAsset::save() void MaterialAsset::load() { setStatus(Status::Loading); - auto& stream = getReadStream(); + auto stream = getReadStream(); json j; stream >> j; materialName = j["name"].get(); diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 4848c94..5cec2fb 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -104,15 +104,15 @@ template > class RefPtr { public: - RefPtr() + constexpr RefPtr() noexcept { object = nullptr; } - RefPtr(nullptr_t) + constexpr RefPtr(nullptr_t) noexcept { object = nullptr; } - RefPtr(T *ptr, Deleter deleter = Deleter()) + constexpr RefPtr(T *ptr, Deleter deleter = Deleter()) { std::scoped_lock l(registeredObjectsLock); auto registeredObj = registeredObjects.find(ptr); @@ -129,12 +129,15 @@ public: object->addRef(); } } - explicit RefPtr(RefObject *other) + constexpr explicit RefPtr(RefObject *other) noexcept : object(other) { - object->addRef(); + if(object != nullptr) + { + object->addRef(); + } } - inline RefPtr(const RefPtr &other) + constexpr RefPtr(const RefPtr &other) noexcept : object(other.object) { if (object != nullptr) @@ -142,14 +145,14 @@ public: object->addRef(); } } - RefPtr(RefPtr &&rhs) + constexpr RefPtr(RefPtr &&rhs) noexcept : object(std::move(rhs.object)) { rhs.object = nullptr; //Dont change references, they stay the same } template - RefPtr(const RefPtr &other) + constexpr RefPtr(const RefPtr &other) { F *f = other.getObject()->getHandle(); assert(static_cast(f)); @@ -158,7 +161,7 @@ public: } template > - RefPtr cast() + constexpr RefPtr cast() { T *t = object->getHandle(); F *f = dynamic_cast(t); @@ -171,7 +174,7 @@ public: } template > - const RefPtr cast() const + constexpr const RefPtr cast() const { T *t = object->getHandle(); F *f = dynamic_cast(t); @@ -183,7 +186,7 @@ public: return RefPtr(newObject); } - RefPtr &operator=(const RefPtr &other) + constexpr RefPtr &operator=(const RefPtr &other) { if (this != &other) { @@ -199,7 +202,7 @@ public: } return *this; } - RefPtr &operator=(RefPtr &&rhs) + constexpr RefPtr &operator=(RefPtr &&rhs) { if (this != &rhs) { @@ -212,44 +215,44 @@ public: } return *this; } - ~RefPtr() + constexpr ~RefPtr() { if (object != nullptr) { object->removeRef(); } } - bool operator==(const RefPtr& rhs) const + constexpr bool operator==(const RefPtr& rhs) const noexcept { return object == rhs.object; } - auto operator<=>(const RefPtr &rhs) const + constexpr auto operator<=>(const RefPtr &rhs) const noexcept { return object <=> rhs.object; } - inline T *operator->() + constexpr T *operator->() { assert(object != nullptr); return object->handle; } - inline const T *operator->() const + constexpr const T *operator->() const { assert(object != nullptr); return object->handle; } - RefObject *getObject() const + constexpr RefObject *getObject() const noexcept { return object; } - inline T *getHandle() + constexpr T *getHandle() { return object->getHandle(); } - inline const T *getHandle() const + constexpr const T *getHandle() const { return object->getHandle(); } - RefPtr clone() + constexpr RefPtr clone() { return RefPtr(new T(*getHandle())); } diff --git a/src/Engine/Scene/Actor/Actor.cpp b/src/Engine/Scene/Actor/Actor.cpp index 12e14ce..97b02fb 100644 --- a/src/Engine/Scene/Actor/Actor.cpp +++ b/src/Engine/Scene/Actor/Actor.cpp @@ -60,6 +60,10 @@ PScene Actor::getScene() void Actor::setParent(PActor newParent) { + if(parent != nullptr) + { + parent->removeChild(this); + } parent = newParent; } void Actor::addChild(PActor child) @@ -68,7 +72,7 @@ void Actor::addChild(PActor child) child->setParent(this); child->notifySceneAttach(owningScene); } -void Actor::detachChild(PActor child) +void Actor::removeChild(PActor child) { children.remove(children.find(child), false); child->setParent(nullptr); diff --git a/src/Engine/Scene/Actor/Actor.h b/src/Engine/Scene/Actor/Actor.h index e257ab2..f3e2941 100644 --- a/src/Engine/Scene/Actor/Actor.h +++ b/src/Engine/Scene/Actor/Actor.h @@ -24,7 +24,7 @@ public: PActor getParent(); void addChild(PActor child); - void detachChild(PActor child); + void removeChild(PActor child); Array getChildren(); //void setAbsoluteLocation(Vector location); //void setAbsoluteRotation(Quaternion rotation); diff --git a/src/Engine/Scene/Scene.cpp b/src/Engine/Scene/Scene.cpp index 59c4284..e1fcb86 100644 --- a/src/Engine/Scene/Scene.cpp +++ b/src/Engine/Scene/Scene.cpp @@ -41,7 +41,7 @@ void Scene::start() } } -static float lastUpdate; +static int64 lastUpdate; static uint64 numUpdates; Job Scene::beginUpdate(double deltaTime) @@ -55,12 +55,12 @@ Job Scene::beginUpdate(double deltaTime) } //co_await Job::all(std::move(jobs)); auto endTime = std::chrono::high_resolution_clock::now(); - float delta = std::chrono::duration_cast(endTime - startTime).count(); + int64 delta = (endTime - startTime).count(); lastUpdate += delta; numUpdates++; - if(lastUpdate > 1000.0f) + if(lastUpdate > 1000) { - lastUpdate -= 1000.0f; + lastUpdate -= 1000; std::cout << numUpdates << " updates per second" << std::endl; numUpdates = 0; } diff --git a/src/Engine/UI/Elements/Element.cpp b/src/Engine/UI/Elements/Element.cpp index cc0bc2b..b76f323 100644 --- a/src/Engine/UI/Elements/Element.cpp +++ b/src/Engine/UI/Elements/Element.cpp @@ -14,6 +14,15 @@ Element::~Element() { } +void Element::setParent(PElement element) +{ + if(parent != nullptr) + { + parent->removeChild(this); + } + parent = element; +} + PElement Element::getParent() const { return parent; @@ -24,6 +33,11 @@ void Element::addChild(PElement element) children.add(element); } +void Element::removeChild(PElement element) +{ + children.remove(element, false); +} + const Array Element::getChildren() { return children; @@ -34,11 +48,6 @@ void Element::clear() children.clear(); } -void Element::remove(PElement element) -{ - children.remove(children.find(element)); -} - void Element::setEnabled(bool newEnabled) { enabled = newEnabled; diff --git a/src/Engine/UI/Elements/Element.h b/src/Engine/UI/Elements/Element.h index 2870377..ada0271 100644 --- a/src/Engine/UI/Elements/Element.h +++ b/src/Engine/UI/Elements/Element.h @@ -16,9 +16,9 @@ public: void setParent(PElement element); PElement getParent() const; void addChild(PElement element); + void removeChild(PElement element); const Array getChildren(); void clear(); - void remove(PElement element); void setEnabled(bool newEnabled); bool isEnabled() const; // maybe not the healthiest inteface diff --git a/src/Engine/UI/RenderHierarchy.cpp b/src/Engine/UI/RenderHierarchy.cpp index a94ac56..d9fc6a3 100644 --- a/src/Engine/UI/RenderHierarchy.cpp +++ b/src/Engine/UI/RenderHierarchy.cpp @@ -5,18 +5,26 @@ using namespace Seele::UI; void AddElementRenderHierarchyUpdate::apply(Array& elements) { - for(auto element : elements) - { - if(element.parent == parent) - { - - } - } + auto parentIt = elements.find([this](RenderElement e){return e.parent == parent;}); + parentIt->referencedElement->addChild(addedElement); + addedElement->setParent(parentIt->referencedElement); + + elements.emplace(parentIt->referencedElement, addedElement); } void RemoveElementRenderHierarchyUpdate::apply(Array& elements) { - + auto elementIt = elements.find([this](RenderElement e){return e.referencedElement == element;}); + if(!removeChildren) + { + for(auto child : elementIt->referencedElement->getChildren()) + { + child->setParent(elementIt->referencedElement->getParent()); + } + } + elementIt->referencedElement->setParent(nullptr); + + elements.remove(elementIt); } RenderHierarchy::RenderHierarchy() diff --git a/src/Engine/UI/RenderHierarchy.h b/src/Engine/UI/RenderHierarchy.h index b0d0374..adc9486 100644 --- a/src/Engine/UI/RenderHierarchy.h +++ b/src/Engine/UI/RenderHierarchy.h @@ -1,18 +1,40 @@ #pragma once #include "Elements/Element.h" #include "Containers/List.h" +#include "Graphics/GraphicsResources.h" namespace Seele { namespace UI { -DECLARE_NAME_REF(Gfx, RenderCommand); +struct RenderElementStyle +{ + Vector2 position; + Vector2 dimensions; + Vector backgroundColor; + uint32 backgroundImageIndex; + Vector4 borderBottomColor; + Vector4 borderLeftColor; + Vector4 borderRightColor; + Vector4 borderTopColor; + float borderBottomLeftRadius; + float borderBottomRightRadius; + float borderTopLeftRadius; + float borderTopRightRadius; + Vector4 fontColor; + float fontSize; + float opacity; +}; +static_assert(sizeof(RenderElementStyle) == 34*4); class RenderElement { public: RenderElement() = default; + RenderElement(Element* parent, Element* referencedElement) + : parent(parent) + , referencedElement(referencedElement) + {} ~RenderElement() = default; - uint32 hierarchyIndex; Element* parent; Element* referencedElement; }; @@ -36,12 +58,13 @@ struct AddElementRenderHierarchyUpdate : public RenderHierarchyUpdate struct RemoveElementRenderHierarchyUpdate : public RenderHierarchyUpdate { Element* element; - RemoveElementRenderHierarchyUpdate(Element* elementToRemove) + bool removeChildren; + RemoveElementRenderHierarchyUpdate(Element* elementToRemove, bool removeChildren = false) : element(elementToRemove) + , removeChildren(removeChildren) {} virtual void apply(Array& elements) override; }; - class RenderHierarchy { public: @@ -58,6 +81,9 @@ private: static_assert(std::is_trivially_copyable_v); // List of all drawable elements in draw order Array drawElements; + // Shader data used for styling elements + Array elementStyles; + Array usedTextures; List updates; std::mutex updateLock; diff --git a/src/Engine/Window/SceneView.cpp b/src/Engine/Window/SceneView.cpp index e0ea849..dd7bdfa 100644 --- a/src/Engine/Window/SceneView.cpp +++ b/src/Engine/Window/SceneView.cpp @@ -20,6 +20,7 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo { scene = new Scene(graphics); scene->addActor(activeCamera); + AssetRegistry::importFile("./fonts/GLSNECB.ttf"); AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png"); AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png"); AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png"); @@ -169,7 +170,7 @@ void SceneView::mouseButtonCallback(MouseButton button, InputAction action, KeyM void SceneView::scrollCallback(double, double yOffset) { - activeCamera->getCameraComponent()->mouseScroll(yOffset); + activeCamera->getCameraComponent()->mouseScroll(static_cast(yOffset)); } void SceneView::fileCallback(int, const char**)