diff --git a/CMakeLists.txt b/CMakeLists.txt index 2da817d2..799b0d9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,10 @@ if (NOT LAUNCHER_ONLY) # Editor is here # add_subdirectory (Tetragrama) + + # Entry point is here + # + add_subdirectory (Obelisk) endif () # Launcher is here @@ -105,7 +109,7 @@ add_custom_target (AssembleContent ALL ) if (NOT LAUNCHER_ONLY) - add_dependencies(AssembleContent zEngineLib tetragrama) + add_dependencies(AssembleContent zEngineLib tetragrama Obelisk) endif () if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") diff --git a/Obelisk/CMakeLists.txt b/Obelisk/CMakeLists.txt new file mode 100644 index 00000000..488cb8d2 --- /dev/null +++ b/Obelisk/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required (VERSION 3.17) + +project (Obelisk + VERSION 1.0 + DESCRIPTION "Obelisk, The game application entry point" + LANGUAGES CXX +) + +set (CMAKE_CXX_STANDARD_REQUIRED ON) +set (CMAKE_CXX_STANDARD 20) + +set (TARGET_NAME Obelisk) + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + add_executable (${TARGET_NAME} WIN32) +else() + add_executable (${TARGET_NAME}) +endif() + +target_sources(${TARGET_NAME} PUBLIC EntryPoint.cpp) + +# We set this debugger directory to find assets and resources file +# after being copied to Debug and Release output directories +# +if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + set_target_properties(${TARGET_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "$(ProjectDir)$(Configuration)") +endif () + +include(${EXTERNAL_DIR}/externals.cmake) + +target_include_directories (${TARGET_NAME} + PRIVATE + . + ${ENLISTMENT_ROOT} + ${ENLISTMENT_ROOT}/ZEngine +) + +target_precompile_headers(${TARGET_NAME} PRIVATE pch.h) + +target_compile_definitions(${TARGET_NAME} + PRIVATE + NOMINMAX + UNICODE + _UNICODE +) + +target_link_libraries(${TARGET_NAME} PRIVATE + zEngineLib + tetragrama + imported::External_obeliskLibs +) \ No newline at end of file diff --git a/Tetragrama/EntryPoint.cpp b/Obelisk/EntryPoint.cpp similarity index 54% rename from Tetragrama/EntryPoint.cpp rename to Obelisk/EntryPoint.cpp index 2f557fea..4f27798a 100644 --- a/Tetragrama/EntryPoint.cpp +++ b/Obelisk/EntryPoint.cpp @@ -3,37 +3,54 @@ #include #include #include -#include "Editor.h" +#include + +#include #ifdef ZENGINE_PLATFORM using namespace ZEngine; using namespace ZEngine::Logging; using namespace ZEngine::Core::Memory; +using namespace ZEngine::Applications; int applicationEntryPoint(int argc, char* argv[]) { - CLI::App app{"ZEngine Editor"}; - argv = app.ensure_utf8(argv); - - std::string editor_cfg_file{""}; - app.add_option("--projectConfigFile", editor_cfg_file, "The project config file"); - - CLI11_PARSE(app, argc, argv); - MemoryManager manager = {}; - MemoryConfiguration config = {.DefaultSize = ZGiga(2u)}; + MemoryConfiguration config = {.DefaultSize = ZGiga(3u)}; manager.Initialize(config); auto arena = &(manager.ArenaAllocator); LoggerConfiguration logger_cfg = {}; Logger::Initialize(arena, logger_cfg); - auto editor = ZPushStruct(arena, Tetragrama::Editor); - editor->Initialize(arena, editor_cfg_file.c_str()); - editor->Run(); - editor->Dispose(); + GameApplicationPtr app = nullptr; + + + CLI::App cli{"ObeliskCLI"}; + argv = cli.ensure_utf8(argv); + + std::string config_file = ""; + bool launch_editor = false; + cli.add_option("--projectConfigFile", config_file, "The project config file"); + cli.add_option("--launchEditor", launch_editor, "The project config file"); + + CLI11_PARSE(cli, argc, argv); + + + if (launch_editor) + { + app = ZPushStructCtor(arena, Tetragrama::Editor); + app->EnableRenderOverlay = true; + } + + app->ConfigFile = config_file.c_str(); + + app->Initialize(arena); + app->Run(); + app->Shutdown(); + Logger::Dispose(); manager.Shutdowm(); diff --git a/Obelisk/pch.cpp b/Obelisk/pch.cpp new file mode 100644 index 00000000..8781bfd8 --- /dev/null +++ b/Obelisk/pch.cpp @@ -0,0 +1 @@ +#include diff --git a/Obelisk/pch.h b/Obelisk/pch.h new file mode 100644 index 00000000..86fbdd5d --- /dev/null +++ b/Obelisk/pch.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/Panzerfaust/Service/EngineService.cs b/Panzerfaust/Service/EngineService.cs index b7c02b1e..b44634c0 100644 --- a/Panzerfaust/Service/EngineService.cs +++ b/Panzerfaust/Service/EngineService.cs @@ -13,9 +13,10 @@ public class EngineService : IEngineService string _enginePath = string.Empty; string _workingDirectory = string.Empty; - const string _editorAppName = "zEngineEditor"; + const string _launcherCLIAppName = "Obelisk"; const string _configJsonFilename = "projectConfig.json"; - const string _engineCommandLineArgs = "--projectConfigFile"; + const string _projectFileCommandLineArgs = "--projectConfigFile"; + const string _editorCommandLineArgs = "--launchEditor 1"; public EngineService() { @@ -23,13 +24,13 @@ public EngineService() #if _WIN32 engineExtension = ".exe"; #endif - _enginePath = Path.Combine(Environment.CurrentDirectory, "Editor", $"{_editorAppName}{engineExtension}"); + _enginePath = Path.Combine(Environment.CurrentDirectory, "Editor", $"{_launcherCLIAppName}{engineExtension}"); _workingDirectory = Path.Combine(Environment.CurrentDirectory, "Editor"); } public async Task StartAsync(string path) { - List engineArgs = new() { _engineCommandLineArgs, Path.Combine(path, _configJsonFilename) }; + List engineArgs = new() { _editorCommandLineArgs, _projectFileCommandLineArgs, Path.Combine(path, _configJsonFilename) }; var processStartInfo = new ProcessStartInfo(_enginePath, string.Join(" ", engineArgs)) { diff --git a/Scripts/PostBuild.ps1 b/Scripts/PostBuild.ps1 index 0b23bb2d..b8f98422 100644 --- a/Scripts/PostBuild.ps1 +++ b/Scripts/PostBuild.ps1 @@ -61,16 +61,16 @@ $ContentsToProcess = @( Contents = @( switch ($SystemName) { "Windows" { - @{ From = "$RepoRoot\Resources\Shaders"; To = "$OuputBuildDirectory\Tetragrama\$Configurations\Shaders"} - @{ From = "$RepoRoot\Resources\Editor\Settings"; To = "$OuputBuildDirectory\Tetragrama\$Configurations\Settings"} + @{ From = "$RepoRoot\Resources\Shaders"; To = "$OuputBuildDirectory\Obelisk\$Configurations\Shaders"} + @{ From = "$RepoRoot\Resources\Editor\Settings"; To = "$OuputBuildDirectory\Obelisk\$Configurations\Settings"} } "Darwin" { - @{ From = "$RepoRoot\Resources\Shaders"; To = "$OuputBuildDirectory\Tetragrama\$Configurations\Shaders"} - @{ From = "$RepoRoot\Resources\Editor\Settings"; To = "$OuputBuildDirectory\Tetragrama\$Configurations\Settings"} + @{ From = "$RepoRoot\Resources\Shaders"; To = "$OuputBuildDirectory\Obelisk\$Configurations\Shaders"} + @{ From = "$RepoRoot\Resources\Editor\Settings"; To = "$OuputBuildDirectory\Obelisk\$Configurations\Settings"} } "Linux" { - @{ From = "$RepoRoot\Resources\Shaders"; To = "$OuputBuildDirectory\Tetragrama\Shaders"} - @{ From = "$RepoRoot\Resources\Editor\Settings"; To = "$OuputBuildDirectory\Tetragrama\Settings"} + @{ From = "$RepoRoot\Resources\Shaders"; To = "$OuputBuildDirectory\Obelisk\Shaders"} + @{ From = "$RepoRoot\Resources\Editor\Settings"; To = "$OuputBuildDirectory\Obelisk\Settings"} } Default { throw 'This system is not supported' @@ -79,23 +79,23 @@ $ContentsToProcess = @( ) }, @{ - Name = "Tetragrama" + Name = "Obelisk" IsDirectory = $true Contents = @( switch ($SystemName) { "Windows" { - @{ From = "$OuputBuildDirectory\Tetragrama\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\Editor"} - @{ From = "$OuputBuildDirectory\Tetragrama\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\publish\Editor"} + @{ From = "$OuputBuildDirectory\Obelisk\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\Editor"} + @{ From = "$OuputBuildDirectory\Obelisk\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\publish\Editor"} } "Darwin" { switch ($Architectures) { "osx-x64" { - @{ From = "$OuputBuildDirectory\Tetragrama\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\Editor"} - @{ From = "$OuputBuildDirectory\Tetragrama\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\publish\Editor"} + @{ From = "$OuputBuildDirectory\Obelisk\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\Editor"} + @{ From = "$OuputBuildDirectory\Obelisk\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\publish\Editor"} } "osx-arm64" { - @{ From = "$OuputBuildDirectory\Tetragrama\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\Editor"} - @{ From = "$OuputBuildDirectory\Tetragrama\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\publish\Editor"} + @{ From = "$OuputBuildDirectory\Obelisk\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\Editor"} + @{ From = "$OuputBuildDirectory\Obelisk\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\$Architectures\publish\Editor"} } Default { throw 'This architecture is not supported' @@ -103,7 +103,7 @@ $ContentsToProcess = @( } } "Linux" { - @{ From = "$OuputBuildDirectory\Tetragrama\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\Editor"} + @{ From = "$OuputBuildDirectory\Obelisk\$Configurations"; To = "$OuputBuildDirectory\Panzerfaust\$Configurations\$TargetFramework\Editor"} } Default { throw 'This system is not supported' diff --git a/Tetragrama/CMakeLists.txt b/Tetragrama/CMakeLists.txt index e8e64d2b..a0d2e1e0 100644 --- a/Tetragrama/CMakeLists.txt +++ b/Tetragrama/CMakeLists.txt @@ -16,11 +16,7 @@ source_group (TREE ${PROJECT_SOURCE_DIR} PREFIX "Source Files" FILES ${HEADER_FI set (TARGET_NAME tetragrama) -if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - add_executable (${TARGET_NAME} WIN32) -else() - add_executable (${TARGET_NAME}) -endif() +add_library (${TARGET_NAME}) target_sources(${TARGET_NAME} PUBLIC ${HEADER_FILES} ${CPP_FILES}) @@ -34,7 +30,7 @@ endif () include(${EXTERNAL_DIR}/externals.cmake) target_include_directories (${TARGET_NAME} - PRIVATE + PUBLIC . ./Components ./Components/Events @@ -50,6 +46,7 @@ target_include_directories (${TARGET_NAME} ) target_precompile_headers(${TARGET_NAME} PRIVATE pch.h) + target_compile_definitions(${TARGET_NAME} PRIVATE NOMINMAX @@ -57,9 +54,4 @@ target_compile_definitions(${TARGET_NAME} _UNICODE ) -target_link_libraries(${TARGET_NAME} PRIVATE - zEngineLib - imported::External_editorLibs -) - -set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "zEngineEditor") \ No newline at end of file +target_link_libraries(${TARGET_NAME} PRIVATE zEngineLib) \ No newline at end of file diff --git a/Tetragrama/Components/DockspaceUIComponent.cpp b/Tetragrama/Components/DockspaceUIComponent.cpp index bc152653..03bf4be5 100644 --- a/Tetragrama/Components/DockspaceUIComponent.cpp +++ b/Tetragrama/Components/DockspaceUIComponent.cpp @@ -35,22 +35,20 @@ namespace Tetragrama::Components parent->LocalArena.CreateSubArena(ZMega(1), &LocalArena); - m_asset_importer = ZPushStructCtor(parent->Arena, Importers::AssimpImporter); + m_asset_importer = ZPushStructCtor(parent->Arena, ZEngine::Importers::AssimpImporter); m_editor_serializer = ZPushStructCtor(parent->Arena, Serializers::EditorSceneSerializer); m_editor_serializer->Initialize(parent->Arena); m_asset_importer->Initialize(parent->Arena); - m_dockspace_node_flag = ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_PassthruCentralNode; - m_window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; + m_dockspace_node_flag = ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_PassthruCentralNode; + m_window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; - auto context = reinterpret_cast(ParentLayer->ParentContext); - m_editor_serializer->Context = context; - m_asset_importer->Context = context; + auto app = reinterpret_cast(ParentLayer->CurrentApp); + m_editor_serializer->Context = app; + m_asset_importer->Context = app; - const auto& editor_config = *context->ConfigurationPtr; - - auto editor_serializer_default_output = fmt::format("{0}{1}{2}", editor_config.WorkingSpacePath.c_str(), PLATFORM_OS_BACKSLASH, editor_config.ScenePath.c_str()); + auto editor_serializer_default_output = fmt::format("{0}{1}{2}", app->Configuration->WorkingSpacePath.c_str(), PLATFORM_OS_BACKSLASH, app->Configuration->ScenePath.c_str()); m_editor_serializer->SetDefaultOutput(editor_serializer_default_output); m_editor_serializer->SetOnProgressCallback(OnEditorSceneSerializerProgress); @@ -127,13 +125,6 @@ namespace Tetragrama::Components RenderExitPopup(); ImGui::End(); - - auto ctx = reinterpret_cast(ParentLayer->ParentContext); - // if (ctx->CurrentScenePtr && ctx->CurrentScenePtr->RenderScene->IsDrawDataDirty) - //{ - // ctx->CurrentScenePtr->RenderScene->InitOrResetDrawBuffer(renderer->Device, renderer->RenderGraph, - // renderer->AsyncLoader); - // } } void DockspaceUIComponent::RenderImporter() @@ -167,9 +158,9 @@ namespace Tetragrama::Components if (ImGui::Button("...", ImVec2(50, 0)) && is_import_button_enabled) { Helpers::UIDispatcher::RunAsync([this]() -> std::future { - if (ParentLayer && ParentLayer->ParentWindow) + if (ParentLayer && ParentLayer->CurrentApp) { - auto window = ParentLayer->ParentWindow; + auto window = ParentLayer->CurrentApp->CurrentWindow; std::vector filters{".obj", ".gltf"}; std::string filename = co_await window->OpenFileDialogAsync(filters); @@ -343,9 +334,10 @@ namespace Tetragrama::Components if (ImGui::Button("Save", ImVec2(80, 0)) && is_save_button_enabled) { - auto context = reinterpret_cast(ParentLayer->ParentContext); - context->CurrentScenePtr->Name = s_save_as_input_buffer; - m_editor_serializer->Serialize(context->CurrentScenePtr); + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto editor_scene = reinterpret_cast(app->CurrentScene); + editor_scene->Name = s_save_as_input_buffer; + m_editor_serializer->Serialize(editor_scene); m_open_save_scene_as = false; m_open_save_scene = true; @@ -378,8 +370,9 @@ namespace Tetragrama::Components m_pending_shutdown = true; - auto context = reinterpret_cast(ParentLayer->ParentContext); - auto current_scene = context->CurrentScenePtr; + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto current_scene = reinterpret_cast(app->CurrentScene); + if (!current_scene->HasPendingChange()) { Helpers::UIDispatcher::RunAsync([this] { OnExitAsync(); }); @@ -436,13 +429,14 @@ namespace Tetragrama::Components ZEngine::Helpers::secure_memset(s_save_as_input_buffer, 0, IM_ARRAYSIZE(s_save_as_input_buffer), IM_ARRAYSIZE(s_save_as_input_buffer)); } - void DockspaceUIComponent::OnAssetImporterComplete(void* const context, ZEngine::Core::Containers::ArrayView result) + void DockspaceUIComponent::OnAssetImporterComplete(void* const context, ZEngine::Core::Containers::ArrayView result) { - auto ctx = reinterpret_cast(context); + auto app = reinterpret_cast(context); + auto current_scene = reinterpret_cast(app->CurrentScene); for (unsigned i = 0; i < result.size(); ++i) { - ctx->CurrentScenePtr->PushAssetFile(result[i]); + current_scene->PushAssetFile(result[i]); } s_asset_importer_report_msg_color = {0.0f, 1.0f, 0.0f, 1.0f}; @@ -501,10 +495,11 @@ namespace Tetragrama::Components m_open_save_scene = true; m_request_save_scene_ui_close = true; Helpers::UIDispatcher::RunAsync([this] { - if (ParentLayer->ParentContext) + if (ParentLayer->CurrentApp) { - auto ctx = reinterpret_cast(ParentLayer->ParentContext); - m_editor_serializer->Serialize(ctx->CurrentScenePtr); + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto current_scene = reinterpret_cast(app->CurrentScene); + m_editor_serializer->Serialize(current_scene); } }); } @@ -536,29 +531,31 @@ namespace Tetragrama::Components void DockspaceUIComponent::OnEditorSceneSerializerComplete(void* const context) { - auto ctx = reinterpret_cast(context); - ctx->CurrentScenePtr->HasPendingChanges.store(false, std::memory_order_release); + auto app = reinterpret_cast(context); + auto current_scene = reinterpret_cast(app->CurrentScene); + current_scene->HasPendingChanges.store(false, std::memory_order_release); } void DockspaceUIComponent::OnEditorSceneSerializerDeserializeComplete(void* const context, EditorScene&& scene) { - auto ctx = reinterpret_cast(context); + auto app = reinterpret_cast(context); + auto current_scene = reinterpret_cast(app->CurrentScene); // Todo : Ensure no data race on CurrentScenePtr - ctx->ConfigurationPtr->ActiveSceneName.clear(); - ctx->ConfigurationPtr->ActiveSceneName.append(scene.Name); + app->Configuration->ActiveSceneName.clear(); + app->Configuration->ActiveSceneName.append(scene.Name); - ctx->CurrentScenePtr->MarkDirty(true); - ctx->SelectedSceneNode.store(-1, std::memory_order_release); - ctx->CurrentScenePtr->Reset(); - ctx->CurrentScenePtr->ExtractAsync(scene); + current_scene->MarkDirty(true); + current_scene->SelectedSceneNode.store(-1, std::memory_order_release); + current_scene->Reset(); + current_scene->ExtractAsync(scene); - ctx->CurrentScenePtr->Name = ctx->ConfigurationPtr->ActiveSceneName.c_str(); + current_scene->Name = app->Configuration->ActiveSceneName.c_str(); - ctx->CurrentScenePtr->MarkDirty(false); + current_scene->MarkDirty(false); { - auto msg = fmt::format("Scene {} deserialized successfully", ctx->CurrentScenePtr->Name); + auto msg = fmt::format("Scene {} deserialized successfully", current_scene->Name); ZEngine::Helpers::secure_strcpy(s_scene_serializer_log, DEFAULT_STR_BUFFER, msg.data()); ZENGINE_CORE_INFO("{}", msg.c_str()) @@ -574,16 +571,16 @@ namespace Tetragrama::Components std::future DockspaceUIComponent::OnOpenSceneAsync() { - if (ParentLayer && ParentLayer->ParentWindow) + if (ParentLayer && ParentLayer->CurrentApp->CurrentWindow) { - auto window = ParentLayer->ParentWindow; + auto window = ParentLayer->CurrentApp->CurrentWindow; std::vector filters = {".zescene"}; std::string scene_filename = co_await window->OpenFileDialogAsync(filters); if (!scene_filename.empty()) { s_is_scene_loading = true; - m_editor_serializer->Deserialize(scene_filename); + m_editor_serializer->Deserialize(scene_filename.c_str()); } } co_return; @@ -603,15 +600,18 @@ namespace Tetragrama::Components std::future DockspaceUIComponent::OnOpenMeshRequestAsync(const char* filename) { - Importers::AssetMeshFileHeader header; - if (Importers::IAssetImporter::ReadAssetMeshFileHeader(filename, header)) + ZEngine::Importers::AssetMeshFileHeader header; + if (ZEngine::Importers::IAssetImporter::ReadAssetMeshFileHeader(filename, header)) { - auto asset_mesh = Managers::AssetManager::GetAsset(header.Id); + auto asset_mesh = ZEngine::Managers::AssetManager::GetAsset(header.Id); if (asset_mesh) { - auto ctx = reinterpret_cast(ParentLayer->ParentContext); - auto handle_ref = ctx->AssetManagerPtr->GetMeshNodeHierarchyHandle(asset_mesh->MeshUUID); - ctx->PendingOnLoadHierarchies->Enqueue(handle_ref); + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto current_scene = reinterpret_cast(app->CurrentScene); + auto asset_manager = ZEngine::Managers::AssetManager::Instance(); + + auto handle_ref = asset_manager->GetMeshNodeHierarchyHandle(asset_mesh->MeshUUID); + current_scene->PendingOnLoadHierarchies->Enqueue(handle_ref); } } co_return; @@ -626,14 +626,15 @@ namespace Tetragrama::Components LocalArena.Clear(); - auto context = reinterpret_cast(ParentLayer->ParentContext); + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto arena = &LocalArena; - const auto& editor_config = *context->ConfigurationPtr; + const auto& editor_config = *(app->Configuration); auto parent_path = std::filesystem::path(filename).parent_path().string(); auto asset_name = fs::path(filename).filename().replace_extension().string(); auto output_asset_file = fmt::format("{}.zemesh", asset_name.c_str()); - auto config = ZPushStruct(arena, Importers::ImportConfiguration); + auto config = ZPushStruct(arena, ZEngine::Importers::ImportConfiguration); config->OutputWorkingSpacePath.init(arena, editor_config.WorkingSpacePath.c_str()); config->OutputTextureFilesPath.init(arena, editor_config.DefaultImportTexturePath.c_str()); config->OutputAssetsPath.init(arena, editor_config.SceneDataPath.c_str()); diff --git a/Tetragrama/Components/DockspaceUIComponent.h b/Tetragrama/Components/DockspaceUIComponent.h index ba5c9ecd..40189a1c 100644 --- a/Tetragrama/Components/DockspaceUIComponent.h +++ b/Tetragrama/Components/DockspaceUIComponent.h @@ -29,7 +29,7 @@ namespace Tetragrama::Components */ void RenderImporter(); void ResetImporterBuffers(); - static void OnAssetImporterComplete(void* const context, ZEngine::Core::Containers::ArrayView result); + static void OnAssetImporterComplete(void* const context, ZEngine::Core::Containers::ArrayView result); static void OnAssetImporterProgress(void* const, float value); static void OnAssetImporterError(void* const, std::string_view); static void OnAssetImporterLog(void* const, std::string_view); @@ -61,16 +61,16 @@ namespace Tetragrama::Components static float s_editor_scene_serializer_progress; private: - bool m_open_asset_importer{false}; - bool m_open_exit{false}; - bool m_pending_shutdown{false}; - bool m_open_save_scene{false}; - bool m_open_save_scene_as{false}; - bool m_request_save_scene_ui_close{false}; - ImGuiDockNodeFlags m_dockspace_node_flag; - ImGuiWindowFlags m_window_flags; - Importers::ImportConfiguration m_default_import_configuration; - ZRawPtr(Importers::IAssetImporter) m_asset_importer; + bool m_open_asset_importer{false}; + bool m_open_exit{false}; + bool m_pending_shutdown{false}; + bool m_open_save_scene{false}; + bool m_open_save_scene_as{false}; + bool m_request_save_scene_ui_close{false}; + ImGuiDockNodeFlags m_dockspace_node_flag; + ImGuiWindowFlags m_window_flags; + ZEngine::Importers::ImportConfiguration m_default_import_configuration; + ZRawPtr(ZEngine::Importers::IAssetImporter) m_asset_importer; ZRawPtr(Serializers::EditorSceneSerializer) m_editor_serializer; }; } // namespace Tetragrama::Components diff --git a/Tetragrama/Components/HierarchyViewUIComponent.cpp b/Tetragrama/Components/HierarchyViewUIComponent.cpp index b65e40ed..f3c4ec5e 100644 --- a/Tetragrama/Components/HierarchyViewUIComponent.cpp +++ b/Tetragrama/Components/HierarchyViewUIComponent.cpp @@ -1,12 +1,13 @@ #include +#include #include #include #include -#include -#include -#include +#include #include #include +#include +#include #include #include @@ -14,8 +15,6 @@ using namespace ZEngine; using namespace ZEngine::Helpers; using namespace ZEngine::Windows::Inputs; using namespace ZEngine::Rendering::Scenes; -using namespace Tetragrama::Inputs; -using namespace Tetragrama::Controllers; namespace Tetragrama::Components { @@ -36,32 +35,34 @@ namespace Tetragrama::Components return; } - if (ParentLayer->ParentWindow) + if (ParentLayer->CurrentApp) { - auto window = ParentLayer->ParentWindow; - if (IDevice::As()->IsKeyPressed(ZENGINE_KEY_T, window)) + auto window = ParentLayer->CurrentApp->CurrentWindow; + auto keyboard = IDevice::As(); + + if (keyboard && keyboard->IsKeyPressed(ZENGINE_KEY_T, window)) { m_gizmo_operation = ImGuizmo::OPERATION::TRANSLATE; } - if (IDevice::As()->IsKeyPressed(ZENGINE_KEY_R, window)) + if (keyboard && keyboard->IsKeyPressed(ZENGINE_KEY_R, window)) { m_gizmo_operation = ImGuizmo::OPERATION::ROTATE; } - if (IDevice::As()->IsKeyPressed(ZENGINE_KEY_S, window)) + if (keyboard && keyboard->IsKeyPressed(ZENGINE_KEY_S, window)) { m_gizmo_operation = ImGuizmo::OPERATION::SCALE; } } - if (ParentLayer->ParentContext) + if (ParentLayer->CurrentApp) { - auto ctx = reinterpret_cast(ParentLayer->ParentContext); - auto current_scene = ctx->CurrentScenePtr; + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto current_scene = reinterpret_cast(app->CurrentScene); Managers::AssetManager::AssetHandle handle = {}; - if (ctx->PendingOnLoadHierarchies->Pop(handle)) + if (current_scene->PendingOnLoadHierarchies->Pop(handle)) { Importers::AssetNodeHierarchy* mesh_node_hierarchy = Managers::AssetManager::GetAsset(handle); if (!mesh_node_hierarchy) @@ -76,7 +77,9 @@ namespace Tetragrama::Components int node_id = -1; }; - Importers::AssetMesh* mesh = ctx->AssetManagerPtr->GetMeshAsset(mesh_node_hierarchy->MeshUUID); + auto asset_mgr = ZEngine::Managers::AssetManager::Instance(); + + Importers::AssetMesh* mesh = asset_mgr->GetMeshAsset(mesh_node_hierarchy->MeshUUID); const auto& mesh_alloc = current_scene->CreateOrGetMeshAllocation(mesh); for (int i = 0; i < mesh_node_hierarchy->Hierarchies.size(); ++i) @@ -109,7 +112,7 @@ namespace Tetragrama::Components { const auto& submesh_id = mesh_node_hierarchy->NodeMeshes.at(entry.node_id); const auto& sub_mesh = mesh->SubMeshes[submesh_id]; - auto material_handle = ctx->AssetManagerPtr->GetMaterialHandleFromUUID(sub_mesh.MaterialUUID); + auto material_handle = asset_mgr->GetMaterialHandleFromUUID(sub_mesh.MaterialUUID); auto material_index = Managers::AssetManager::ReadAssetHandleIndex(material_handle); current_scene->NodeSubMeshesAllocations[scene_node_id].TransformId = scene_node_id; @@ -155,8 +158,8 @@ namespace Tetragrama::Components void HierarchyViewUIComponent::Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) { - auto ctx = reinterpret_cast(ParentLayer->ParentContext); - auto current_scene = ctx->CurrentScenePtr; + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto current_scene = reinterpret_cast(app->CurrentScene); ImGui::Begin(Name, (CanBeClosed ? &CanBeClosed : NULL), ImGuiWindowFlags_NoCollapse); if (ImGui::BeginPopupContextWindow(Name)) @@ -173,7 +176,7 @@ namespace Tetragrama::Components // 0 means left buttom if (ImGui::IsMouseDown(0) && ImGui::IsWindowHovered()) { - ctx->SelectedSceneNode.store(-1, std::memory_order_release); + current_scene->SelectedSceneNode.store(-1, std::memory_order_release); // Messengers::IMessenger::SendAsync(EDITOR_COMPONENT_HIERARCHYVIEW_NODE_UNSELECTED, Messengers::EmptyMessage{}); } @@ -185,8 +188,8 @@ namespace Tetragrama::Components void HierarchyViewUIComponent::RenderTreeNodes() { - auto ctx = reinterpret_cast(ParentLayer->ParentContext); - auto current_scene = ctx->CurrentScenePtr; + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto current_scene = reinterpret_cast(app->CurrentScene); if (current_scene->IsDirty()) { @@ -197,30 +200,30 @@ namespace Tetragrama::Components { if (!current_scene->IsSceneNodeDeleted(i) && current_scene->Hierarchies[i].Parent == -1) { - RenderNode(current_scene, i, ctx->SelectedSceneNode); + RenderNode(current_scene, i, current_scene->SelectedSceneNode); } } } void HierarchyViewUIComponent::RenderGuizmo() { - auto ctx = reinterpret_cast(ParentLayer->ParentContext); - auto current_scene = ctx->CurrentScenePtr; + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto current_scene = reinterpret_cast(app->CurrentScene); if (current_scene->IsDirty()) { return; } - int selected_node = ctx->SelectedSceneNode.load(std::memory_order_acquire); + int selected_node = current_scene->SelectedSceneNode.load(std::memory_order_acquire); if (selected_node == -1) { return; } - if (auto active_editor_camera = ctx->CameraControllerPtr) + if (app->CameraController) { - auto camera = active_editor_camera->GetCamera(); + auto camera = app->CameraController->GetCamera(); const auto camera_projection = camera->GetPerspectiveMatrix(); const auto camera_view_matrix = camera->GetViewMatrix(); @@ -228,14 +231,15 @@ namespace Tetragrama::Components auto initial_transform = global_transform; auto& local_transform = current_scene->LocalTransforms[selected_node]; - if (camera && IDevice::As()->IsKeyPressed(ZENGINE_KEY_F, Engine::GetWindow())) + if (camera && IDevice::As()->IsKeyPressed(ZENGINE_KEY_F, app->CurrentWindow)) { + auto active_editor_camera = reinterpret_cast(app->CameraController); active_editor_camera->SetTarget(glm::vec3(global_transform[0][3], global_transform[1][3], global_transform[2][3])); } // snapping float snap_value = 0.5f; - bool is_snap_operation = IDevice::As()->IsKeyPressed(ZENGINE_KEY_LEFT_CONTROL, Engine::GetWindow()); + bool is_snap_operation = IDevice::As()->IsKeyPressed(ZENGINE_KEY_LEFT_CONTROL, app->CurrentWindow); if (is_snap_operation && static_cast(m_gizmo_operation) == ImGuizmo::ROTATE) { snap_value = 45.0f; diff --git a/Tetragrama/Components/InspectorViewUIComponent.cpp b/Tetragrama/Components/InspectorViewUIComponent.cpp index 5ce846b0..487a8e0e 100644 --- a/Tetragrama/Components/InspectorViewUIComponent.cpp +++ b/Tetragrama/Components/InspectorViewUIComponent.cpp @@ -1,21 +1,15 @@ #include +#include #include #include #include #include -#include -#include -#include -#include +#include #define GLM_ENABLE_EXPERIMENTAL -#include #include -using namespace ZEngine::Rendering::Materials; using namespace ZEngine::Rendering::Textures; -using namespace ZEngine::Rendering::Lights; -using namespace ZEngine::Rendering::Components; using namespace ZEngine::Helpers; namespace Tetragrama::Components @@ -36,14 +30,16 @@ namespace Tetragrama::Components { ImGui::Begin(Name, (CanBeClosed ? &CanBeClosed : NULL), ImGuiWindowFlags_NoCollapse); - if (ParentLayer && ParentLayer->ParentContext) + if (ParentLayer && ParentLayer->CurrentApp) { - auto ctx = reinterpret_cast(ParentLayer->ParentContext); - auto idx = ctx->SelectedSceneNode.load(std::memory_order_acquire); + auto app = reinterpret_cast(ParentLayer->CurrentApp); + + auto current_scene = reinterpret_cast(app->CurrentScene); + auto idx = current_scene->SelectedSceneNode.load(std::memory_order_acquire); if (idx != -1) { - auto name_idx = ctx->CurrentScenePtr->NodeNames[idx]; - auto& name = ctx->CurrentScenePtr->Names[name_idx]; + auto name_idx = current_scene->NodeNames[idx]; + auto& name = current_scene->Names[name_idx]; ImGui::Dummy(ImVec2(0, 3)); Helpers::DrawInputTextControl("Name", name.c_str(), [&](std::string_view value) { diff --git a/Tetragrama/Components/ProjectViewUIComponent.cpp b/Tetragrama/Components/ProjectViewUIComponent.cpp index e9e94739..b0674655 100644 --- a/Tetragrama/Components/ProjectViewUIComponent.cpp +++ b/Tetragrama/Components/ProjectViewUIComponent.cpp @@ -17,23 +17,24 @@ namespace Tetragrama::Components { UIComponent::Initialize(parent, name, visibility, closed); parent->LocalArena.CreateSubArena(ZMega(1), &m_local_arena); - auto context = reinterpret_cast(ParentLayer->ParentContext); - m_assets_directory = context->ConfigurationPtr->WorkingSpacePath.c_str(); - m_current_directory = m_assets_directory; + + m_assets_directory = ParentLayer->CurrentApp->WorkingSpacePath; + m_current_directory = m_assets_directory; + + auto asset_mgr = ZEngine::Managers::AssetManager::Instance(); + + const auto current_directoy = std::filesystem::current_path(); + const auto directory_icon_path = fmt::format("{0}{1}{2}", current_directoy.string(), PLATFORM_OS_BACKSLASH, "Settings/Icons/DirectoryIcon.png"); + const auto file_icon_path = fmt::format("{0}{1}{2}", current_directoy.string(), PLATFORM_OS_BACKSLASH, "Settings/Icons/FileIcon.png"); + + m_directory_icon = asset_mgr->LoadTextureFileAsAsset(directory_icon_path.c_str(), true); + m_file_icon = asset_mgr->LoadTextureFileAsAsset(file_icon_path.c_str(), true); } void ProjectViewUIComponent::Update(ZEngine::Core::TimeStep dt) {} void ProjectViewUIComponent::Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) { - if (!m_textures_loaded) - { - m_directory_icon = renderer->AsyncLoader->LoadTextureFile("Settings/Icons/DirectoryIcon.png"); - m_file_icon = renderer->AsyncLoader->LoadTextureFile("Settings/Icons/FileIcon.png"); - - m_textures_loaded = true; - } - ImGui::Begin(Name, (CanBeClosed ? &CanBeClosed : NULL), ImGuiWindowFlags_NoCollapse); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); @@ -120,7 +121,7 @@ namespace Tetragrama::Components ImGui::PushID(name.c_str()); - ImTextureID icon = entry.is_directory() ? (ImTextureID) m_directory_icon.Index : (ImTextureID) m_file_icon.Index; + ImTextureID icon = entry.is_directory() ? (ImTextureID) m_directory_icon->Handle.Index : (ImTextureID) m_file_icon->Handle.Index; const float margin = 5.0f; ImVec2 cursorPos = ImGui::GetCursorPos(); diff --git a/Tetragrama/Components/ProjectViewUIComponent.h b/Tetragrama/Components/ProjectViewUIComponent.h index 5f22982f..c1dec4c6 100644 --- a/Tetragrama/Components/ProjectViewUIComponent.h +++ b/Tetragrama/Components/ProjectViewUIComponent.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace Tetragrama::Components { @@ -57,16 +58,15 @@ namespace Tetragrama::Components void MakeRelative(const std::filesystem::path& path, const std::filesystem::path& base, char* output); private: - ZEngine::Core::Memory::ArenaAllocator m_local_arena = {}; - std::filesystem::path m_assets_directory; - std::filesystem::path m_current_directory; - PopupType m_active_popup = PopupType::None; - std::filesystem::path m_popup_target_path; + ZEngine::Core::Memory::ArenaAllocator m_local_arena = {}; + std::filesystem::path m_assets_directory; + std::filesystem::path m_current_directory; + PopupType m_active_popup = PopupType::None; + std::filesystem::path m_popup_target_path; - ZEngine::Rendering::Textures::TextureHandle m_directory_icon; - ZEngine::Rendering::Textures::TextureHandle m_file_icon; - bool m_textures_loaded = false; - static constexpr float m_thumbnail_size = 64.0f; - char m_search_buffer[MAX_FILE_PATH_COUNT] = ""; + ZEngine::Importers::AssetTexture* m_directory_icon; + ZEngine::Importers::AssetTexture* m_file_icon; + static constexpr float m_thumbnail_size = 64.0f; + char m_search_buffer[MAX_FILE_PATH_COUNT] = ""; }; } // namespace Tetragrama::Components diff --git a/Tetragrama/Components/SceneViewportUIComponent.cpp b/Tetragrama/Components/SceneViewportUIComponent.cpp index 81f1d66f..e4dd48d2 100644 --- a/Tetragrama/Components/SceneViewportUIComponent.cpp +++ b/Tetragrama/Components/SceneViewportUIComponent.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -52,19 +53,21 @@ namespace Tetragrama::Components } } - auto ctx = reinterpret_cast(ParentLayer->ParentContext); + auto app = reinterpret_cast(ParentLayer->CurrentApp); + auto camera_controller = reinterpret_cast(app->CameraController); + if (m_request_renderer_resize) { - ctx->CameraControllerPtr->SetViewport(m_viewport_size.x, m_viewport_size.y); + camera_controller->SetViewport(m_viewport_size.x, m_viewport_size.y); } if (m_is_window_hovered && m_is_window_focused) { - ctx->CameraControllerPtr->ResumeEventProcessing(); + camera_controller->ResumeEventProcessing(); } else { - ctx->CameraControllerPtr->PauseEventProcessing(); + camera_controller->PauseEventProcessing(); } if (m_is_window_clicked && m_is_window_hovered && m_is_window_focused) @@ -81,6 +84,8 @@ namespace Tetragrama::Components void SceneViewportUIComponent::Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) { + auto app = reinterpret_cast(ParentLayer->CurrentApp); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::Begin(Name, (CanBeClosed ? &CanBeClosed : NULL), ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); @@ -93,7 +98,7 @@ namespace Tetragrama::Components // Scene texture representation if (!m_scene_texture || m_refresh_texture_handle) { - m_scene_texture = renderer->GetFrameOutput(); + m_scene_texture = app->RenderPipeline->SceneRenderer->GetFrameOutput(); m_refresh_texture_handle = false; } @@ -125,11 +130,11 @@ namespace Tetragrama::Components auto file_ext = std::filesystem::path(buf).extension().string(); if (file_ext == ".zescene") { - Messengers::IMessenger::SendAsync>(EDITOR_COMPONENT_DOCKSPACE_REQUEST_OPENSCENE, Messengers::GenericMessage(buf)); + Messengers::IMessenger::SendAsync>(EDITOR_COMPONENT_DOCKSPACE_REQUEST_OPENSCENE, Messengers::GenericMessage(buf)); } else if (file_ext == ".zemesh") { - Messengers::IMessenger::SendAsync>(EDITOR_COMPONENT_DOCKSPACE_REQUEST_OPENMESH, Messengers::GenericMessage(buf)); + Messengers::IMessenger::SendAsync>(EDITOR_COMPONENT_DOCKSPACE_REQUEST_OPENMESH, Messengers::GenericMessage(buf)); } } } @@ -142,7 +147,7 @@ namespace Tetragrama::Components if (m_request_renderer_resize) { - renderer->EnqueuedResizeRequests.Emplace({.Width = (uint32_t) m_viewport_size.x, .Height = (uint32_t) m_viewport_size.y}); + app->State->RenderTargetResizeRequests.Emplace({.Width = (uint32_t) m_viewport_size.x, .Height = (uint32_t) m_viewport_size.y}); m_refresh_texture_handle = true; m_request_renderer_resize = false; } diff --git a/Tetragrama/Components/UIComponent.h b/Tetragrama/Components/UIComponent.h index 58932d9b..b2deaf02 100644 --- a/Tetragrama/Components/UIComponent.h +++ b/Tetragrama/Components/UIComponent.h @@ -16,7 +16,7 @@ namespace Tetragrama::Components UIComponent() = default; virtual ~UIComponent() = default; - virtual void Initialize(Layers::ImguiLayer* parent, const char* name, bool visibility, bool closed) + virtual void Initialize(Layers::ImguiLayer* parent, cstring name, bool visibility, bool closed) { ParentLayer = parent; Name = name; @@ -24,11 +24,12 @@ namespace Tetragrama::Components CanBeClosed = closed; } - bool IsVisible = true; - bool CanBeClosed = false; - const char* Name = ""; - uint32_t ChildrenCount = 0; - Tetragrama::Layers::ImguiLayer* ParentLayer = nullptr; - ZEngine::Core::Containers::Array Children = {}; + bool IsVisible = true; + bool CanBeClosed = false; + cstring Name = ""; + uint32_t ChildrenCount = 0; + Tetragrama::Layers::ImguiLayer* ParentLayer = nullptr; + ZEngine::Core::Containers::Array Children = {}; }; + ZDEFINE_PTR(UIComponent); } // namespace Tetragrama::Components diff --git a/Tetragrama/Controllers/EditorCameraController.cpp b/Tetragrama/Controllers/EditorCameraController.cpp index 9f4ea24a..1806f231 100644 --- a/Tetragrama/Controllers/EditorCameraController.cpp +++ b/Tetragrama/Controllers/EditorCameraController.cpp @@ -9,7 +9,7 @@ namespace Tetragrama::Controllers { m_position = {0.0f, 0.0f, 1.5f}; m_process_event = true; - m_controller_type = Controllers::CameraControllerType::PERSPECTIVE_CONTROLLER; + m_controller_type = ZEngine::Controllers::CameraControllerType::PERSPECTIVE_CONTROLLER; m_window = window; m_perspective_camera = ZPushStructCtor(arena, PerspectiveCamera); diff --git a/Tetragrama/Controllers/EditorCameraController.h b/Tetragrama/Controllers/EditorCameraController.h index 9e91c014..4a742bbf 100644 --- a/Tetragrama/Controllers/EditorCameraController.h +++ b/Tetragrama/Controllers/EditorCameraController.h @@ -1,13 +1,14 @@ #pragma once -#include +#include namespace Tetragrama::Controllers { - struct EditorCameraController : public Controllers::PerspectiveCameraController + struct EditorCameraController : public ZEngine::Controllers::PerspectiveCameraController { EditorCameraController() = default; virtual ~EditorCameraController() = default; void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Windows::CoreWindow* window, double distance, float yaw_degree, float pitch_degree); }; + ZDEFINE_PTR(EditorCameraController); } // namespace Tetragrama::Controllers diff --git a/Tetragrama/Controllers/IController.h b/Tetragrama/Controllers/IController.h deleted file mode 100644 index 2d310ddc..00000000 --- a/Tetragrama/Controllers/IController.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace Tetragrama::Controllers -{ - struct IController : public ZEngine::Core::IUpdatable, public ZEngine::Core::IEventable - { - IController() = default; - ~IController() = default; - }; -} // namespace Tetragrama::Controllers diff --git a/Tetragrama/Editor.cpp b/Tetragrama/Editor.cpp index 9f56bdb4..aff80d22 100644 --- a/Tetragrama/Editor.cpp +++ b/Tetragrama/Editor.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -10,74 +11,77 @@ using namespace ZEngine::Core::Containers; using namespace ZEngine::Core::Memory; using namespace ZEngine::Helpers; using namespace Tetragrama::Layers; -using namespace Tetragrama::Messengers; -using namespace Tetragrama::Controllers; -using namespace Tetragrama::Managers; namespace Tetragrama { - void Editor::Initialize(ArenaAllocator* arena, const char* file) + void Editor::OnInitializing() { + Configuration = ZPushStructCtor(Arena, EditorConfiguration); - Context = ZPushStruct(arena, EditorContext); - Context->Arena = arena; - - Context->ConfigurationPtr = ZPushStructCtor(Context->Arena, EditorConfiguration); - Context->CameraControllerPtr = ZPushStructCtor(Context->Arena, EditorCameraController); - Context->PendingOnLoadHierarchies = CreateRef>(); - UILayer = ZPushStructCtor(Context->Arena, ImguiLayer); - CanvasLayer = ZPushStructCtor(Context->Arena, RenderLayer); - - UILayer->ParentContext = reinterpret_cast(Context); - CanvasLayer->ParentContext = reinterpret_cast(Context); + if (ZEngine::Helpers::secure_strlen(ConfigFile)) + { + Configuration->ReadConfig(Arena, ConfigFile); + } - const char* scene_name = ""; - if (ZEngine::Helpers::secure_strlen(file)) + if (Configuration->ActiveSceneName.empty()) { - Context->ConfigurationPtr->ReadConfig(arena, file); + ZENGINE_CORE_WARN("Editor Scene name is empty") - if (!Context->ConfigurationPtr->ActiveSceneName.empty()) - { - scene_name = Context->ConfigurationPtr->ActiveSceneName.c_str(); - } + cstring active_scene = ""; + Configuration->ActiveSceneName.clear(); + Configuration->ActiveSceneName.append(active_scene); } + WorkingSpacePath = Configuration->WorkingSpacePath.c_str(); + } - std::string title = fmt::format("{0} - Active Scene : {1}", Context->ConfigurationPtr->ProjectName.c_str(), scene_name); - Windows::WindowConfiguration window_conf = {.EnableVsync = true}; - window_conf.Title.init(Context->Arena, title.c_str()); - window_conf.RenderingLayerCollection.init(Context->Arena, 1); - window_conf.OverlayLayerCollection.init(Context->Arena, 1); - - window_conf.RenderingLayerCollection.push(CanvasLayer); - window_conf.OverlayLayerCollection.push(UILayer); + void Editor::OverrideWindowConfiguration() + { + std::string title = fmt::format("{0} - Active Scene : {1}", Configuration->ProjectName.c_str(), Configuration->ActiveSceneName.c_str()); + WindowCfg.EnableVsync = true; + WindowCfg.Title.init(Arena, title.c_str()); + } - Window = ZEngine::Windows::Create(Context->Arena, window_conf); + void Editor::OnInitialized() + { + auto editor_scene = ZPushStructCtor(Arena, EditorScene); + auto editor_cam_controller = ZPushStructCtor(Arena, Controllers::EditorCameraController); + UILayer = ZPushStructCtor(Arena, ImguiLayer); - Context->CameraControllerPtr->Initialize(Context->Arena, Window, 150.0, 0.f, 45.f); + UILayer->Initialize(Arena, this); + editor_cam_controller->Initialize(Arena, CurrentWindow, 150.0, 0.f, 45.f); + editor_scene->Initialize(Arena, Configuration->ActiveSceneName.c_str()); - ZEngine::Engine::Initialize(arena, Window); + CameraController = editor_cam_controller; + CurrentScene = editor_scene; + } - auto device = ZEngine::Engine::GetDevice(); - auto resource_loader = ZEngine::Engine::GetAsyncResourceLoader(); - AssetManager::Initialize(arena, device, resource_loader, Context->ConfigurationPtr->WorkingSpacePath.c_str()); + void Editor::OnUpdate(float dt) + { + CHECK_AND_ESCAPE_NULL(UILayer) - Context->AssetManagerPtr = AssetManager::Instance(); - Context->CurrentScenePtr = ZPushStructCtor(Context->Arena, EditorScene); - Context->CurrentScenePtr->Initialize(Context->Arena, device, scene_name); + UILayer->Update(dt); } - void Editor::Dispose() + void Editor::OnEvent(Core::CoreEvent& e) { - Engine::Dispose(); - AssetManager::Shutdown(); + CHECK_AND_ESCAPE_NULL(UILayer) + + UILayer->OnEvent(e); } - void Editor::Run() + void Editor::OnPreRender() {} + + void Editor::OnPostRender() {} + + void Editor::OnRenderUI() { - AssetManager::Run(); - Engine::Run(); + UILayer->Render(nullptr, nullptr); } + void Editor::OnClosing() {} + + void Editor::OnClosed() {} + void EditorConfiguration::ReadConfig(ZEngine::Core::Memory::ArenaAllocator* arena, const char* file) { std::ifstream f(file); diff --git a/Tetragrama/Editor.h b/Tetragrama/Editor.h index 31e5e838..14462730 100644 --- a/Tetragrama/Editor.h +++ b/Tetragrama/Editor.h @@ -1,16 +1,9 @@ #pragma once -#include -#include #include -#include #include -#include -#include -#include +#include #include -#include -#include -#include +#include namespace Tetragrama::Serializers { @@ -32,30 +25,31 @@ namespace Tetragrama void ReadConfig(ZEngine::Core::Memory::ArenaAllocator* arena, const char* file); }; + ZDEFINE_PTR(EditorConfiguration); - struct EditorContext + struct Editor : public ZEngine::Applications::GameApplication { - ZEngine::Core::Memory::ArenaAllocator* Arena = nullptr; - std::atomic_int SelectedSceneNode = -1; - ZRawPtr(EditorConfiguration) ConfigurationPtr = nullptr; - ZRawPtr(EditorScene) CurrentScenePtr = nullptr; - ZRawPtr(Controllers::EditorCameraController) CameraControllerPtr = nullptr; - ZRawPtr(Managers::AssetManager) AssetManagerPtr = nullptr; - ZEngine::Helpers::Ref> PendingOnLoadHierarchies = nullptr; - }; - struct Editor - { - ~Editor() {} + EditorConfigurationPtr Configuration = nullptr; + + virtual ~Editor() {} + + ZRawPtr(Layers::ImguiLayer) UILayer = nullptr; + + virtual void OnInitializing() override; + virtual void OverrideWindowConfiguration() override; + virtual void OnInitialized() override; + + virtual void OnUpdate(float dt) override; + virtual void OnEvent(ZEngine::Core::CoreEvent&) override; - ZRawPtr(EditorContext) Context = nullptr; - ZRawPtr(Layers::ImguiLayer) UILayer = nullptr; - ZRawPtr(Layers::RenderLayer) CanvasLayer = nullptr; - ZRawPtr(ZEngine::Windows::CoreWindow) Window = nullptr; + virtual void OnPreRender() override; + virtual void OnPostRender() override; + virtual void OnRenderUI() override; - void Initialize(ZEngine::Core::Memory::ArenaAllocator*, const char*); - void Dispose(); - void Run(); + virtual void OnClosing() override; + virtual void OnClosed() override; }; + ZDEFINE_PTR(Editor); } // namespace Tetragrama diff --git a/Tetragrama/EditorScene.cpp b/Tetragrama/EditorScene.cpp index 7a412a23..24a9ef45 100644 --- a/Tetragrama/EditorScene.cpp +++ b/Tetragrama/EditorScene.cpp @@ -1,24 +1,28 @@ #include #include -#include +#include #include using namespace ZEngine::Rendering::Meshes; using namespace ZEngine::Core::Containers; +using namespace ZEngine::Managers; +using namespace ZEngine::Helpers; namespace Tetragrama { - void EditorScene::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Hardwares::VulkanDevice* device, const char* name) + void EditorScene::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, cstring name) { arena->CreateSubArena(ZMega(200), &LocalArena); - Name = name; - Device = device; + Name = name; + + PendingOnLoadHierarchies = CreateRef>(); AssetFiles.init(&LocalArena, 500); HashToAssetFile.init(&LocalArena, 500); Hierarchies.init(&LocalArena, 1000); + HierarchiesNodeRef.init(&LocalArena, 1000); Names.init(&LocalArena, 1000); LocalTransforms.init(&LocalArena, 1000); GlobalTransforms.init(&LocalArena, 1000); @@ -51,14 +55,15 @@ namespace Tetragrama return -1; } - int node_id = static_cast(Hierarchies.size()); + int node_id = static_cast(Hierarchies.size()); // Create new node - EditorSceneNodeHierarchy new_node = {}; - new_node.Parent = parent; - new_node.DepthLevel = depth; + ZEngine::Helpers::NodeHierarchy new_node = {}; + new_node.Parent = parent; + new_node.DepthLevel = depth; Hierarchies.push(new_node); + HierarchiesNodeRef.push({}); LocalTransforms.push(glm::mat4(1.0f)); GlobalTransforms.push(glm::mat4(1.0f)); @@ -85,7 +90,7 @@ namespace Tetragrama return node_id; } - int EditorScene::CreateSceneNode(int parent, int depth, const Importers::AssetNodeRef& metadata) + int EditorScene::CreateSceneNode(int parent, int depth, const ZEngine::Importers::AssetNodeRef& metadata) { int node_id = AddHierarchyNode(parent, depth); if (node_id < 0) @@ -94,13 +99,13 @@ namespace Tetragrama return node_id; } - Hierarchies[node_id].NodeRef = metadata; + HierarchiesNodeRef[node_id] = metadata; - NodeNames[node_id] = Names.size(); - auto& name = Names.push_use({}); - cstring name_val = "Empty entity"; + NodeNames[node_id] = Names.size(); + auto& name = Names.push_use({}); + cstring name_val = "Empty entity"; - if (Hierarchies[node_id].NodeRef.IsValid()) + if (HierarchiesNodeRef[node_id].IsValid()) { if (ZEngine::Helpers::secure_strlen(metadata.Name) > 0) { @@ -226,7 +231,7 @@ namespace Tetragrama return Hierarchies[node].Parent == -2; } - const ZEngine::Rendering::Meshes::MeshAllocation& EditorScene::CreateOrGetMeshAllocation(Importers::AssetMesh* const mesh) + const ZEngine::Rendering::Meshes::MeshAllocation& EditorScene::CreateOrGetMeshAllocation(ZEngine::Importers::AssetMesh* const mesh) { if (MeshAllocations.contains(mesh->MeshUUID)) { @@ -267,9 +272,9 @@ namespace Tetragrama return MeshAllocations.at(mesh->MeshUUID); } - void EditorScene::PushAssetFile(const Importers::AssetImporterOutput& data) + void EditorScene::PushAssetFile(const ZEngine::Importers::AssetImporterOutput& data) { - if (data.Type == Importers::AssetFileType::UNKNOWN) + if (data.Type == ZEngine::Importers::AssetFileType::UNKNOWN) { ZENGINE_CORE_WARN("{} : Invalid operation, unknown asset file type", __FUNCTION__) return; @@ -310,6 +315,7 @@ namespace Tetragrama HashToAssetFile.clear(); Hierarchies.clear(); + HierarchiesNodeRef.clear(); Names.clear(); LocalTransforms.clear(); GlobalTransforms.clear(); @@ -327,7 +333,8 @@ namespace Tetragrama LocalTransforms.push(glm::mat4(1.0f)); GlobalTransforms.push(glm::mat4(1.0f)); - auto& node = Hierarchies.push_use(EditorSceneNodeHierarchy{}); + auto& node = Hierarchies.push_use({}); + HierarchiesNodeRef.push({}); node.DepthLevel = 0; } @@ -351,6 +358,7 @@ namespace Tetragrama for (const auto& h : scene.Hierarchies) { Hierarchies.push(h); + HierarchiesNodeRef.push({}); } for (const auto& lt : scene.LocalTransforms) @@ -368,11 +376,11 @@ namespace Tetragrama NodeNames.insert(k, v); } - auto asset_manager = Managers::AssetManager::Instance(); + auto asset_manager = AssetManager::Instance(); for (const auto& file : AssetFiles) { - asset_manager->LoadAssetFile(Importers::AssetImporterOutput{.Type = file.Type, .Path = file.Path.c_str(), .RootPath = file.RootPath.c_str()}); + asset_manager->LoadAssetFile(ZEngine::Importers::AssetImporterOutput{.Type = file.Type, .Path = file.Path.c_str(), .RootPath = file.RootPath.c_str()}); } } } // namespace Tetragrama \ No newline at end of file diff --git a/Tetragrama/EditorScene.h b/Tetragrama/EditorScene.h index 907c8482..43fe507b 100644 --- a/Tetragrama/EditorScene.h +++ b/Tetragrama/EditorScene.h @@ -1,15 +1,9 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include -#include -#include namespace Tetragrama::Serializers { @@ -20,72 +14,52 @@ namespace Tetragrama { struct EditorAssetSceneFiles { - Importers::AssetFileType Type = Importers::AssetFileType::UNKNOWN; + ZEngine::Importers::AssetFileType Type = ZEngine::Importers::AssetFileType::UNKNOWN; uint64_t Hash = {}; ZEngine::Core::Containers::String Path = {}; ZEngine::Core::Containers::String RootPath = {}; }; - struct EditorSceneNodeHierarchy : public Helpers::NodeHierarchy + struct EditorScene : public ZEngine::Rendering::Scenes::RenderScene { - /* - * NodeRef serves as a mapping between Scene NodeHierarchy & Asset NodeHierarchy - */ - Importers::AssetNodeRef NodeRef = {}; - }; - - struct EditorScene - { - std::atomic_bool Dirty = false; - std::atomic_bool MeshAllocationDirty[3] = {false, false, false}; - std::atomic_bool TransformBufferDirty[3] = {false, false, false}; - std::atomic_bool HasPendingChanges = false; - - uint32_t CurrentTransformOffset = 0; - uint32_t CurrentVertexOffset = 0; - uint32_t CurrentIndexOffset = 0; - - const char* Name = ""; - ZEngine::Core::Containers::Array Hierarchies = {}; - ZEngine::Core::Containers::Array Names = {}; - ZEngine::Core::Containers::Array LocalTransforms = {}; - ZEngine::Core::Containers::Array GlobalTransforms = {}; - ZEngine::Core::Containers::HashMap NodeNames = {}; - - ZEngine::Core::Containers::Array Vertices = {}; - ZEngine::Core::Containers::Array Indices = {}; - ZEngine::Core::Containers::HashMap MeshAllocations = {}; - ZEngine::Core::Containers::HashMap NodeSubMeshesAllocations = {}; + std::atomic_bool Dirty = false; + std::atomic_bool HasPendingChanges = false; - ZEngine::Core::Containers::HashMap HashToAssetFile = {}; - ZEngine::Core::Containers::Array AssetFiles = {}; + cstring Name = ""; + std::atomic_int SelectedSceneNode = -1; + ZEngine::Core::Containers::Array HierarchiesNodeRef = {}; + ZEngine::Core::Containers::Array Names = {}; + ZEngine::Core::Containers::HashMap NodeNames = {}; - ZEngine::Core::Memory::ArenaAllocator LocalArena = {}; + ZEngine::Helpers::Ref> PendingOnLoadHierarchies = nullptr; + ZEngine::Core::Containers::HashMap HashToAssetFile = {}; + ZEngine::Core::Containers::Array AssetFiles = {}; - ZEngine::Hardwares::VulkanDevice* Device = nullptr; + ZEngine::Core::Memory::ArenaAllocator LocalArena = {}; - void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Hardwares::VulkanDevice* device, const char* scene_name = ""); + void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, cstring scene_name = ""); - bool HasPendingChange() const; + bool HasPendingChange() const; - int AddHierarchyNode(int parent, int depth); + int AddHierarchyNode(int parent, int depth); - int CreateSceneNode(int parent = 0, int depth = 1, const Importers::AssetNodeRef& = {}); - void RemoveSceneNode(int node_id); - void ReparentNode(int node_id, int new_parent); - bool IsSceneNodeDeleted(int node_id); + int CreateSceneNode(int parent = 0, int depth = 1, const ZEngine::Importers::AssetNodeRef& = {}); + void RemoveSceneNode(int node_id); + void ReparentNode(int node_id, int new_parent); + bool IsSceneNodeDeleted(int node_id); - const ZEngine::Rendering::Meshes::MeshAllocation& CreateOrGetMeshAllocation(Importers::AssetMesh* const); + const ZEngine::Rendering::Meshes::MeshAllocation& CreateOrGetMeshAllocation(ZEngine::Importers::AssetMesh* const); - void PushAssetFile(const Importers::AssetImporterOutput&); + void PushAssetFile(const ZEngine::Importers::AssetImporterOutput&); - void MarkDirty(bool value); - bool IsDirty(); + void MarkDirty(bool value); + bool IsDirty(); - void Reset(); - void InitRootNode(); + void Reset(); + void InitRootNode(); - void ExtractAsync(const EditorScene& scene); + void ExtractAsync(const EditorScene& scene); }; + ZDEFINE_PTR(EditorScene); } // namespace Tetragrama \ No newline at end of file diff --git a/Tetragrama/EditorWindow.h b/Tetragrama/EditorWindow.h deleted file mode 100644 index 98e34cf7..00000000 --- a/Tetragrama/EditorWindow.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once -#define GLFW_INCLUDE_VULKAN -#include -#include -#include -#include -#include -#include - -namespace Tetragrama -{ - class EditorWindow : public ZEngine::Windows::CoreWindow - { - public: - EditorWindow() {} - virtual ~EditorWindow(); - - uint32_t GetHeight() const override; - uint32_t GetWidth() const override; - ZEngine::Core::Containers::StringView GetTitle() const override; - bool IsMinimized() const override; - void SetTitle(ZEngine::Core::Containers::StringView title) override; - bool IsVSyncEnable() const override; - void SetVSync(bool value) override; - void SetCallbackFunction(const EventCallbackFn& callback) override; - void* GetNativeWindow() const override; - virtual const ZEngine::Windows::WindowProperty& GetWindowProperty() const override; - - virtual void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, const ZEngine::Windows::WindowConfiguration& cfg); - - virtual void Deinitialize() override; - virtual void PollEvent() override; - virtual float GetTime() override; - virtual float GetDeltaTime() override; - virtual void Update(ZEngine::Core::TimeStep delta_time) override; - virtual void Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) override; - - virtual std::future OpenFileDialogAsync(std::span type_filters = {}) override; - - virtual bool CreateSurface(void* instance, void** out_window_surface) override; - - public: - bool OnEvent(ZEngine::Core::CoreEvent& event) override; - - protected: - virtual bool OnKeyPressed(ZEngine::Windows::Events::KeyPressedEvent&) override; - virtual bool OnKeyReleased(ZEngine::Windows::Events::KeyReleasedEvent&) override; - - virtual bool OnMouseButtonPressed(ZEngine::Windows::Events::MouseButtonPressedEvent&) override; - virtual bool OnMouseButtonReleased(ZEngine::Windows::Events::MouseButtonReleasedEvent&) override; - virtual bool OnMouseButtonMoved(ZEngine::Windows::Events::MouseButtonMovedEvent&) override; - virtual bool OnMouseButtonWheelMoved(ZEngine::Windows::Events::MouseButtonWheelEvent&) override; - - virtual bool OnTextInputRaised(ZEngine::Windows::Events::TextInputEvent&) override; - - virtual bool OnWindowClosed(ZEngine::Windows::Events::WindowClosedEvent&) override; - virtual bool OnWindowResized(ZEngine::Windows::Events::WindowResizedEvent&) override; - virtual bool OnWindowMinimized(ZEngine::Windows::Events::WindowMinimizedEvent&) override; - virtual bool OnWindowMaximized(ZEngine::Windows::Events::WindowMaximizedEvent&) override; - virtual bool OnWindowRestored(ZEngine::Windows::Events::WindowRestoredEvent&) override; - - static void __OnGlfwWindowClose(GLFWwindow*); - static void __OnGlfwWindowResized(GLFWwindow*, int width, int height); - static void __OnGlfwWindowMaximized(GLFWwindow*, int maximized); - static void __OnGlfwWindowMinimized(GLFWwindow*, int minimized); - - static void __OnGlfwMouseButtonRaised(GLFWwindow*, int button, int action, int mods); - static void __OnGlfwMouseScrollRaised(GLFWwindow*, double xoffset, double yoffset); - static void __OnGlfwCursorMoved(GLFWwindow*, double xpos, double ypos); - static void __OnGlfwTextInputRaised(GLFWwindow*, unsigned int character); - - static void __OnGlfwKeyboardRaised(GLFWwindow*, int key, int scancode, int action, int mods); - - static void __OnGlfwFrameBufferSizeChanged(GLFWwindow*, int width, int height); - - private: - GLFWwindow* m_native_window = nullptr; - }; - -} // namespace Tetragrama diff --git a/Tetragrama/Helpers/SerializerCommonHelper.cpp b/Tetragrama/Helpers/SerializerCommonHelper.cpp deleted file mode 100644 index 3589fac9..00000000 --- a/Tetragrama/Helpers/SerializerCommonHelper.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include -#include - -using namespace ZEngine::Core::Containers; - -namespace Tetragrama::Helpers -{ -} // namespace Tetragrama::Helpers \ No newline at end of file diff --git a/Tetragrama/Helpers/UIComponentDrawerHelper.cpp b/Tetragrama/Helpers/UIComponentDrawerHelper.cpp index 15acb6ce..4f077d32 100644 --- a/Tetragrama/Helpers/UIComponentDrawerHelper.cpp +++ b/Tetragrama/Helpers/UIComponentDrawerHelper.cpp @@ -506,30 +506,30 @@ namespace Tetragrama::Helpers ImGui::PopStyleColor(); } - void DrawEntityControl(std::string_view component_name, ZEngine::Rendering::Scenes::SceneEntity& entity, ImGuiTreeNodeFlags flags, std::function callback) - { - if (entity.GetNode() <= 0) - { - return; - } - - ImVec2 content_region_available = ImGui::GetContentRegionAvail(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{2, 2}); - float line_height = GImGui->Font->FontSize + GImGui->Style.FramePadding.y * 2.0f; - - bool opened = ImGui::TreeNodeEx(fmt::format("SceneEntity_{0}_cmpnt{1}", entity.GetNode(), component_name).c_str(), flags, "%s", component_name.data()); - ImGui::PopStyleVar(); - - if (opened) - { - if (callback) - { - callback(); - } - ImGui::TreePop(); - } - - ImGui::Dummy(ImVec2(0, 5)); - ImGui::Separator(); - } + // void DrawEntityControl(std::string_view component_name, ZEngine::Rendering::Scenes::SceneEntity& entity, ImGuiTreeNodeFlags flags, std::function callback) + //{ + // if (entity.GetNode() <= 0) + // { + // return; + // } + + // ImVec2 content_region_available = ImGui::GetContentRegionAvail(); + // ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{2, 2}); + // float line_height = GImGui->Font->FontSize + GImGui->Style.FramePadding.y * 2.0f; + + // bool opened = ImGui::TreeNodeEx(fmt::format("SceneEntity_{0}_cmpnt{1}", entity.GetNode(), component_name).c_str(), flags, "%s", component_name.data()); + // ImGui::PopStyleVar(); + + // if (opened) + // { + // if (callback) + // { + // callback(); + // } + // ImGui::TreePop(); + // } + + // ImGui::Dummy(ImVec2(0, 5)); + // ImGui::Separator(); + //} } // namespace Tetragrama::Helpers diff --git a/Tetragrama/Helpers/UIComponentDrawerHelper.h b/Tetragrama/Helpers/UIComponentDrawerHelper.h index a0f3b64f..e324bbe4 100644 --- a/Tetragrama/Helpers/UIComponentDrawerHelper.h +++ b/Tetragrama/Helpers/UIComponentDrawerHelper.h @@ -23,59 +23,59 @@ namespace Tetragrama::Helpers void DrawColoredTextLine(const char* start, const char* end, const ImVec4& color); - void DrawEntityControl(std::string_view component_name, ZEngine::Rendering::Scenes::SceneEntity& entity, ImGuiTreeNodeFlags flags, std::function callback); - - template - void DrawEntityComponentControl(std::string_view component_name, ZEngine::Rendering::Scenes::SceneEntity& entity, ImGuiTreeNodeFlags flags, bool enable_removal_option, std::function component_definition_func) - { - if (entity.HasComponent()) - { - - ImVec2 content_region_available = ImGui::GetContentRegionAvail(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{2, 2}); - float line_height = GImGui->Font->FontSize + GImGui->Style.FramePadding.y * 2.0f; - - bool opened = ImGui::TreeNodeEx(reinterpret_cast(typeid(TComponent).hash_code()), flags, "%s", component_name.data()); - ImGui::PopStyleVar(); - - ImGui::SameLine(content_region_available.x - line_height * 0.5f); - if (ImGui::Button("...", ImVec2{line_height, line_height})) - { - ImGui::OpenPopup("ComponentSettings"); - } - - bool request_component_removal = false; - if (ImGui::BeginPopup("ComponentSettings")) - { - if (enable_removal_option) - { - if (ImGui::MenuItem("Remove Component")) - { - request_component_removal = true; - ImGui::CloseCurrentPopup(); - } - } - - ImGui::EndPopup(); - } - - if (opened) - { - auto& component = entity.GetComponent(); - if (component_definition_func) - { - component_definition_func(component); - } - ImGui::TreePop(); - } - - if (request_component_removal) - { - entity.RemoveComponent(); - } - - ImGui::Dummy(ImVec2(0, 5)); - ImGui::Separator(); - } - } + // void DrawEntityControl(std::string_view component_name, ZEngine::Rendering::Scenes::SceneEntity& entity, ImGuiTreeNodeFlags flags, std::function callback); + + // template + // void DrawEntityComponentControl(std::string_view component_name, ZEngine::Rendering::Scenes::SceneEntity& entity, ImGuiTreeNodeFlags flags, bool enable_removal_option, std::function component_definition_func) + //{ + // if (entity.HasComponent()) + // { + + // ImVec2 content_region_available = ImGui::GetContentRegionAvail(); + // ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{2, 2}); + // float line_height = GImGui->Font->FontSize + GImGui->Style.FramePadding.y * 2.0f; + + // bool opened = ImGui::TreeNodeEx(reinterpret_cast(typeid(TComponent).hash_code()), flags, "%s", component_name.data()); + // ImGui::PopStyleVar(); + + // ImGui::SameLine(content_region_available.x - line_height * 0.5f); + // if (ImGui::Button("...", ImVec2{line_height, line_height})) + // { + // ImGui::OpenPopup("ComponentSettings"); + // } + + // bool request_component_removal = false; + // if (ImGui::BeginPopup("ComponentSettings")) + // { + // if (enable_removal_option) + // { + // if (ImGui::MenuItem("Remove Component")) + // { + // request_component_removal = true; + // ImGui::CloseCurrentPopup(); + // } + // } + + // ImGui::EndPopup(); + // } + + // if (opened) + // { + // auto& component = entity.GetComponent(); + // if (component_definition_func) + // { + // component_definition_func(component); + // } + // ImGui::TreePop(); + // } + + // if (request_component_removal) + // { + // entity.RemoveComponent(); + // } + + // ImGui::Dummy(ImVec2(0, 5)); + // ImGui::Separator(); + // } + //} } // namespace Tetragrama::Helpers diff --git a/Tetragrama/Importers/AssetTypes.h b/Tetragrama/Importers/AssetTypes.h deleted file mode 100644 index 83f3d035..00000000 --- a/Tetragrama/Importers/AssetTypes.h +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include - -namespace Tetragrama::Importers -{ - enum AssetFileType : uint8_t - { - UNKNOWN = 0, - MESH, - MATERIAL, - TEXTURES - }; - - struct AssetSubMesh - { - uuids::uuid MaterialUUID = {}; - uint32_t VertexCount = 0; - uint32_t IndexCount = 0; - uint32_t VertexOffset = 0; - uint32_t IndexOffset = 0; - uint32_t StreamOffset = 0; - uint32_t IndexStreamOffset = 0; - uint32_t VertexUnitStreamSize = 0; - uint32_t IndexUnitStreamSize = 0; - uint32_t TotalByteSize = 0; - }; - - struct AssetMesh - { - uuids::uuid MeshUUID = {}; - ZEngine::Core::Containers::Array Vertices = {}; - ZEngine::Core::Containers::Array Indices = {}; - ZEngine::Core::Containers::Array SubMeshes = {}; - }; - - struct AssetMaterial - { - ZEngine::Core::Containers::String Name = {}; - uuids::uuid MaterialUUID = {}; - uuids::uuid AlbedoTexUUID = {}; - uuids::uuid EmissiveTexUUID = {}; - uuids::uuid NormalTexUUID = {}; - uuids::uuid OpacityTexUUID = {}; - uuids::uuid SpecularTexUUID = {}; - float AmbientColor[4] = {0}; - float AlbedoColor[4] = {0}; - float EmissiveColor[4] = {0}; - float RoughnessColor[4] = {0}; - float SpecularColor[4] = {0}; - float Factors[4] = {0}; - }; - - struct AssetTexture - { - ZEngine::Rendering::Textures::TextureHandle Handle = {}; - uuids::uuid TextureUUID = {}; - ZEngine::Core::Containers::String Path = {}; - }; - - struct AssetNodeHierarchy - { - uuids::uuid NodeHierarchyUUID = {}; - uuids::uuid MeshUUID = {}; - ZEngine::Core::Containers::Array Hierarchies = {}; - ZEngine::Core::Containers::Array LocalTransforms = {}; - ZEngine::Core::Containers::Array GlobalTransforms = {}; - ZEngine::Core::Containers::Array Names = {}; - ZEngine::Core::Containers::Array MaterialNames = {}; - ZEngine::Core::Containers::HashMap NodeNames = {}; - ZEngine::Core::Containers::HashMap NodeMeshes = {}; - ZEngine::Core::Containers::HashMap NodeMaterials = {}; - }; - - struct AssetNodeRef - { - int NodeHierarchyIndex = -1; - uint32_t AssetNodeHandle = 0xFFFFFFFF; - cstring Name = nullptr; - uuids::uuid AssetMeshUUID = {}; - - bool IsValid() const - { - return (AssetNodeHandle != 0xFFFFFFFF) && (NodeHierarchyIndex != -1); - } - }; - - struct AssetFile - { - const char* Name = nullptr; - AssetNodeHierarchy Hierarchy = {}; - AssetMesh Mesh = {}; - ZEngine::Core::Containers::Array Materials = {}; - ZEngine::Core::Containers::Array Textures = {}; - }; -} // namespace Tetragrama::Importers diff --git a/Tetragrama/Importers/AssimpImporter.h b/Tetragrama/Importers/AssimpImporter.h deleted file mode 100644 index 7d048e52..00000000 --- a/Tetragrama/Importers/AssimpImporter.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include - -namespace Tetragrama::Importers -{ - class AssimpImporter; - struct AssimpProgressHandler; - - struct AssimpProgressHandler : public Assimp::ProgressHandler - { - void SetImporter(AssimpImporter* const importer); - bool Update(float percentage) override; - - private: - AssimpImporter* m_importer{nullptr}; - }; - - class AssimpImporter : public IAssetImporter - { - public: - AssimpImporter(); - virtual ~AssimpImporter(); - - virtual std::future ImportAsync(const char* filename, const ImportConfiguration& config) override; - void CopyTextureFiles(ZEngine::Core::Memory::ArenaAllocator*, ZEngine::Core::Containers::Array&, const ImportConfiguration&); - - private: - uint32_t m_flags; - AssimpProgressHandler m_progress_handler; - - friend struct AssimpProgressHandler; - - void ExtractMeshes(ZEngine::Core::Memory::ArenaAllocator*, const aiScene*, uuids::uuid_random_generator&, AssetMesh&); - void ExtractMaterials(ZEngine::Core::Memory::ArenaAllocator*, const aiScene*, uuids::uuid_random_generator&, ZEngine::Core::Containers::Array&, AssetNodeHierarchy&); - void ExtractTextures(ZEngine::Core::Memory::ArenaAllocator* arena, const aiScene*, uuids::uuid_random_generator&, ZEngine::Core::Containers::Array&, ZEngine::Core::Containers::Array&); - void CreateHierachy(ZEngine::Core::Memory::ArenaAllocator* arena, const aiScene*, uuids::uuid_random_generator&, AssetNodeHierarchy&, AssetMesh&, ZEngine::Core::Containers::Array&); - - void TraverseNode(ZEngine::Core::Memory::ArenaAllocator* arena, const aiScene*, const aiNode*, AssetNodeHierarchy&, AssetMesh&, ZEngine::Core::Containers::Array&, int parent_node_id, int depth_level); - glm::mat4 ConvertToMat4(const aiMatrix4x4& m); - }; -} // namespace Tetragrama::Importers \ No newline at end of file diff --git a/Tetragrama/Importers/IAssetImporter.h b/Tetragrama/Importers/IAssetImporter.h deleted file mode 100644 index d5b02471..00000000 --- a/Tetragrama/Importers/IAssetImporter.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define REPORT_LOG(ctx, msg) \ - { \ - if (m_log_callback) \ - { \ - m_log_callback(ctx, msg); \ - } \ - } - -namespace Tetragrama::Importers -{ - int AddNode(AssetNodeHierarchy& hierarchy, int parent, int depth); - - struct ImportConfiguration - { - ZEngine::Core::Containers::String AssetName; - ZEngine::Core::Containers::String OutputAssetFile; - ZEngine::Core::Containers::String OutputAssetsPath; - ZEngine::Core::Containers::String InputBaseAssetFilePath; - ZEngine::Core::Containers::String OutputWorkingSpacePath; - ZEngine::Core::Containers::String OutputTextureFilesPath; - }; - - struct AssetMeshFileHeader - { - uint32_t MagicNumber = 0xFFFFFF; - uint32_t Version = 0xFFFFFF; - uuids::uuid Id = {}; - }; - - struct AssetImporterOutput - { - AssetFileType Type = AssetFileType::UNKNOWN; - std::string Path = ""; - std::string RootPath = ""; - }; - - struct IAssetImporter - { - typedef void (*on_import_complete_fn)(void* const, ZEngine::Core::Containers::ArrayView result); - typedef void (*on_import_progress_fn)(void* const, float progress); - typedef void (*on_import_error_fn)(void* const, std::string_view error_message); - typedef void (*on_import_log_fn)(void* const, std::string_view log_message); - - on_import_complete_fn m_complete_callback = nullptr; - on_import_progress_fn m_progress_callback = nullptr; - on_import_error_fn m_error_callback = nullptr; - on_import_log_fn m_log_callback = nullptr; - - std::mutex m_mutex; - std::atomic_bool m_is_importing = false; - - ZEngine::Core::Memory::ArenaAllocator Arena = {}; - void* Context = nullptr; - - virtual ~IAssetImporter() {} - - void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena); - - virtual void SetOnCompleteCallback(on_import_complete_fn callback); - virtual void SetOnProgressCallback(on_import_progress_fn callback); - virtual void SetOnErrorCallback(on_import_error_fn callback); - virtual void SetOnLogCallback(on_import_log_fn callback); - virtual bool IsImporting(); - - virtual std::future ImportAsync(const char* filename, const ImportConfiguration& config) = 0; - - static AssetImporterOutput SerializeMeshAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, AssetMesh& data, AssetNodeHierarchy& hierarchies, const ImportConfiguration&); - static AssetImporterOutput SerializeMaterialAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, AssetMaterial& data, const ImportConfiguration&); - static AssetImporterOutput SerializeTextureAssetFiles(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Core::Containers::ArrayView data, const ImportConfiguration&); - - static void DeserializeMeshAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, const char* asset_file, AssetMesh&, AssetNodeHierarchy&); - static void DeserializeMaterialAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, const char* asset_file, AssetMaterial&); - static void DeserializeTextureAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, const char* asset_file, ZEngine::Core::Containers::Array&); - - static bool ReadAssetMeshFileHeader(cstring asset_file, AssetMeshFileHeader&); - }; -} // namespace Tetragrama::Importers diff --git a/Tetragrama/Inputs/Keyboard.h b/Tetragrama/Inputs/Keyboard.h deleted file mode 100644 index 20a5716f..00000000 --- a/Tetragrama/Inputs/Keyboard.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#include -#include - -namespace Tetragrama::Inputs -{ - - class Keyboard : public ZEngine::Windows::Inputs::IDevice - { - public: - Keyboard(const char* name = "keyboard_device") : ZEngine::Windows::Inputs::IDevice(name) {} - ~Keyboard() = default; - - virtual bool IsKeyPressed(ZENGINE_KEYCODE key, ZEngine::Windows::CoreWindow* const window) const override - { - auto state = glfwGetKey(reinterpret_cast(window->GetNativeWindow()), (int) key); - return state == GLFW_PRESS; - } - - virtual bool IsKeyReleased(ZENGINE_KEYCODE key, ZEngine::Windows::CoreWindow* const window) const override - { - auto state = glfwGetKey(reinterpret_cast(window->GetNativeWindow()), (int) key); - return state == GLFW_RELEASE; - } - }; -} // namespace Tetragrama::Inputs diff --git a/Tetragrama/Inputs/Mouse.h b/Tetragrama/Inputs/Mouse.h deleted file mode 100644 index ac77fb99..00000000 --- a/Tetragrama/Inputs/Mouse.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include -#include -#include - -namespace Tetragrama::Inputs -{ - - class Mouse : public ZEngine::Windows::Inputs::IDevice - { - public: - Mouse(const char* name = "mouse_device") : ZEngine::Windows::Inputs::IDevice(name) {} - - virtual bool IsKeyPressed(ZENGINE_KEYCODE key, ZEngine::Windows::CoreWindow* const window) const override - { - - auto state = glfwGetMouseButton(reinterpret_cast(window->GetNativeWindow()), (int) key); - return state == GLFW_PRESS; - } - - virtual bool IsKeyReleased(ZENGINE_KEYCODE key, ZEngine::Windows::CoreWindow* const window) const override - { - return !IsKeyPressed(key, window); - } - - std::array GetMousePosition(ZEngine::Windows::CoreWindow* const window) const - { - double x, y; - glfwGetCursorPos(reinterpret_cast(window->GetNativeWindow()), &x, &y); - return std::array{x, y}; - } - }; -} // namespace Tetragrama::Inputs diff --git a/Tetragrama/Layers/ImguiLayer.cpp b/Tetragrama/Layers/ImguiLayer.cpp index 955acb14..82df4726 100644 --- a/Tetragrama/Layers/ImguiLayer.cpp +++ b/Tetragrama/Layers/ImguiLayer.cpp @@ -26,9 +26,10 @@ namespace Tetragrama::Layers { ImguiLayer::~ImguiLayer() {} - void ImguiLayer::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena) + void ImguiLayer::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Applications::GameApplicationPtr app) { - Arena = arena; + Arena = arena; + CurrentApp = app; arena->CreateSubArena(ZMega(10), &LocalArena); NodeHierarchies.init(arena, 10, 0); @@ -332,7 +333,7 @@ namespace Tetragrama::Layers bool ImguiLayer::OnWindowClosed(WindowClosedEvent& event) { Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&ZEngine::Windows::CoreWindow::OnWindowClosed, ParentWindow, std::placeholders::_1)); + event_dispatcher.ForwardTo(std::bind(&ZEngine::Windows::CoreWindow::OnWindowClosed, CurrentApp->CurrentWindow, std::placeholders::_1)); return true; } diff --git a/Tetragrama/Layers/ImguiLayer.h b/Tetragrama/Layers/ImguiLayer.h index aa8d20c1..c9cce6d4 100644 --- a/Tetragrama/Layers/ImguiLayer.h +++ b/Tetragrama/Layers/ImguiLayer.h @@ -1,12 +1,12 @@ #pragma once -#include #include +#include #include #include #include #include +#include #include -#include namespace Tetragrama::Components { @@ -15,19 +15,17 @@ namespace Tetragrama::Components namespace Tetragrama::Layers { - class ImguiLayer : public ZEngine::Windows::Layers::Layer, public ZEngine::Windows::Inputs::IKeyboardEventCallback, public ZEngine::Windows::Inputs::IMouseEventCallback, public ZEngine::Windows::Inputs::ITextInputEventCallback, public ZEngine::Windows::Inputs::IWindowEventCallback + struct ImguiLayer : public ZEngine::Applications::Layer, public ZEngine::Windows::Inputs::IKeyboardEventCallback, public ZEngine::Windows::Inputs::IMouseEventCallback, public ZEngine::Windows::Inputs::ITextInputEventCallback, public ZEngine::Windows::Inputs::IWindowEventCallback { - - public: - ImguiLayer(const char* name = "ImGUI Layer") : Layer(name) {} + ImguiLayer(cstring name = "ImGUI Layer") : ZEngine::Applications::Layer(name) {} virtual ~ImguiLayer(); - ZEngine::Core::Containers::Array NodeHierarchies = {}; + ZEngine::Core::Containers::Array NodeHierarchies = {}; ZEngine::Core::Containers::Array NodeToRender = {}; - ZEngine::Core::Containers::HashMap NodeUIComponents = {}; + ZEngine::Core::Containers::HashMap NodeUIComponents = {}; ZEngine::Core::Containers::HashMap KeyEntries = {}; - virtual void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena) override; + virtual void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Applications::GameApplicationPtr app) override; virtual void Deinitialize() override; bool OnEvent(ZEngine::Core::CoreEvent& event) override; @@ -54,4 +52,5 @@ namespace Tetragrama::Layers bool OnWindowMaximized(ZEngine::Windows::Events::WindowMaximizedEvent&) override; bool OnWindowRestored(ZEngine::Windows::Events::WindowRestoredEvent&) override; }; + ZDEFINE_PTR(ImguiLayer); } // namespace Tetragrama::Layers diff --git a/Tetragrama/Layers/RenderLayer.cpp b/Tetragrama/Layers/RenderLayer.cpp deleted file mode 100644 index 3fb57af0..00000000 --- a/Tetragrama/Layers/RenderLayer.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include -#include -#include -#include - -using namespace ZEngine; -using namespace ZEngine::Rendering::Scenes; -using namespace ZEngine::Rendering::Renderers; -using namespace ZEngine::Windows; -using namespace ZEngine::Core; -using namespace ZEngine::Helpers; -using namespace ZEngine::Core::Containers; -using namespace ZEngine::Rendering::Meshes; -using namespace Tetragrama::Controllers; - -namespace Tetragrama::Layers -{ - - RenderLayer::RenderLayer(const char* name) : Layer(name) {} - - RenderLayer::~RenderLayer() {} - - void RenderLayer::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena) - { - arena->CreateSubArena(ZMega(30), &LocalArena); - - RenderableNodes.init(arena, 5000); - } - - void RenderLayer::Deinitialize() {} - - void RenderLayer::Update(TimeStep dt) - { - if (!ParentContext) - { - return; - } - - auto ctx = reinterpret_cast(ParentContext); - // ctx->CurrentScenePtr->RenderScene->ComputeAllTransforms(); - ctx->CameraControllerPtr->Update(dt); - } - - bool RenderLayer::OnEvent(CoreEvent& e) - { - if (ParentContext) - { - auto ctx = reinterpret_cast(ParentContext); - ctx->CameraControllerPtr->OnEvent(e); - } - return false; - } - - void RenderLayer::Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) - { - if (!ParentContext) - { - return; - } - - auto ctx = reinterpret_cast(ParentContext); - auto camera = ctx->CameraControllerPtr->GetCamera(); - auto device = renderer->Device; - auto gpu_scene_data = renderer->RenderSceneData; - - auto vtx_buffer_set = device->StorageBufferSetManager.Access(gpu_scene_data->VertexBufferHandle); - auto idx_buffer_set = device->StorageBufferSetManager.Access(gpu_scene_data->IndexBufferHandle); - auto transform_buffer_set = device->StorageBufferSetManager.Access(gpu_scene_data->TransformBufferHandle); - auto rd_buffer_set = device->StorageBufferSetManager.Access(gpu_scene_data->RenderDataBufferHandle); - auto material_buffer_set = device->StorageBufferSetManager.Access(gpu_scene_data->MaterialBufferHandle); - auto indirect_buffer_set = device->IndirectBufferSetManager.Access(gpu_scene_data->IndirectBufferHandle); - - auto vtx_buffer = vtx_buffer_set->At(device->CurrentFrameIndex); - auto idx_buffer = idx_buffer_set->At(device->CurrentFrameIndex); - auto transform_buffer = transform_buffer_set->At(device->CurrentFrameIndex); - auto rd_buffer = rd_buffer_set->At(device->CurrentFrameIndex); - auto indirect_buffer = indirect_buffer_set->At(device->CurrentFrameIndex); - auto material_buffer = material_buffer_set->At(device->CurrentFrameIndex); - - auto current_scene = ctx->CurrentScenePtr; - auto& suballocs = current_scene->NodeSubMeshesAllocations; - - if (current_scene->TransformBufferDirty[device->CurrentFrameIndex].load(std::memory_order_acquire) || current_scene->MeshAllocationDirty[device->CurrentFrameIndex].load(std::memory_order_acquire)) - { - - if (current_scene->TransformBufferDirty[device->CurrentFrameIndex].exchange(false, std::memory_order_acquire)) - { - auto transform_data_view = ArrayView{current_scene->GlobalTransforms}; - transform_buffer->Write(transform_data_view); - } - - if (current_scene->MeshAllocationDirty[device->CurrentFrameIndex].exchange(false, std::memory_order_acquire)) - { - auto scratch = ZGetScratch(&LocalArena); - - ZEngine::Core::Containers::Array SubMeshAllocations = {}; - ZEngine::Core::Containers::Array DrawIndirectCommands = {}; - SubMeshAllocations.init(scratch.Arena, suballocs.size()); - - for (const auto& [_, alloc] : suballocs) - { - SubMeshAllocations.push(alloc); - } - - DrawIndirectCommands.init(scratch.Arena, SubMeshAllocations.size()); - for (unsigned i = 0; i < SubMeshAllocations.size(); ++i) - { - DrawIndirectCommands.push({ - .vertexCount = SubMeshAllocations[i].IndexCount, - .instanceCount = SubMeshAllocations[i].InstanceCount, - .firstVertex = 0, - .firstInstance = i, - }); - } - - auto vertex_data_view = ArrayView{current_scene->Vertices}; - auto index_data_view = ArrayView{current_scene->Indices}; - auto material_data_view = ArrayView{ctx->AssetManagerPtr->GPUMeshMaterials}; - - auto sub_mesh_alloc_view = ArrayView{SubMeshAllocations}; - auto indirect_commands_view = ArrayView{DrawIndirectCommands}; - vtx_buffer->Write(vertex_data_view); - idx_buffer->Write(index_data_view); - material_buffer->Write(material_data_view); - - rd_buffer->Write(sub_mesh_alloc_view); - - indirect_buffer->Write(indirect_commands_view); - - ZReleaseScratch(scratch); - } - } - - // Todo (Kernel) : When we'll start considering multithreaded support - // we might want to renderer->EnqueueAsync({command_buffer, {camera, frame_data} }) - renderer->DrawScene(command_buffer, camera); - } -} // namespace Tetragrama::Layers diff --git a/Tetragrama/Layers/RenderLayer.h b/Tetragrama/Layers/RenderLayer.h deleted file mode 100644 index b9ea9a54..00000000 --- a/Tetragrama/Layers/RenderLayer.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include - -namespace Tetragrama::Layers -{ - struct RenderLayer : public ZEngine::Windows::Layers::Layer - { - RenderLayer(const char* name = "Rendering layer"); - - virtual ~RenderLayer(); - - ZEngine::Core::Containers::HashMap> RenderableNodes = {}; - - virtual void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena) override; - virtual void Deinitialize() override; - virtual void Update(ZEngine::Core::TimeStep dt) override; - virtual void Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) override; - virtual bool OnEvent(ZEngine::Core::CoreEvent& e) override; - }; - -} // namespace Tetragrama::Layers diff --git a/Tetragrama/Managers/AssetManager.h b/Tetragrama/Managers/AssetManager.h deleted file mode 100644 index c4b61932..00000000 --- a/Tetragrama/Managers/AssetManager.h +++ /dev/null @@ -1,168 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Tetragrama::Managers -{ - enum class AssetType : uint8_t - { - MESH = 0, - MATERIAL, - TEXTURE, - MESH_HIERARCHY - }; - - struct AssetManager - { - using AssetHandle = uint32_t; - - ZEngine::Core::Memory::ArenaAllocator Arena = {}; - ZEngine::Core::Memory::ArenaAllocator ThreadLocalArena = {}; - - cstring CurrentWorkingSpacePath = ""; - - std::atomic_bool IsLoading = false; - std::atomic_bool RequestShutdown = false; - - ZEngine::Core::Containers::Array NodeHierarchies = {}; - ZEngine::Core::Containers::Array Meshes = {}; - ZEngine::Core::Containers::Array Materials = {}; - ZEngine::Core::Containers::Array Textures = {}; - - ZEngine::Core::Containers::Array GPUMeshMaterials = {}; - - ZEngine::Core::Containers::HashMap UUIDToHandle = {}; - ZEngine::Core::Containers::HashMap HandleToUUID = {}; - ZEngine::Core::Containers::HashMap MeshToNodeHierarchy = {}; - ZEngine::Core::Containers::HashMap NodeHierarchyToMesh = {}; - - ZEngine::Core::Containers::HashMap UUIDToTextureHandle = {}; - - ZEngine::Hardwares::StorageBufferSetHandle MaterialBufferHandle = {}; - - std::mutex Mut; - std::condition_variable Cond; - ZEngine::Helpers::ThreadSafeQueue PendingAssetFiles = {}; - - ZEngine::Helpers::ThreadSafeQueue PendingAssetMeshes = {}; - ZEngine::Helpers::ThreadSafeQueue PendingAssetNodeHierarchies = {}; - ZEngine::Helpers::ThreadSafeQueue PendingAssetMaterials = {}; - ZEngine::Helpers::ThreadSafeQueue> PendingAssetTextures = {}; - - ZEngine::Hardwares::VulkanDevice* Device = nullptr; - ZEngine::Rendering::Renderers::AsyncResourceLoader* ResourceLoader = nullptr; - - Importers::AssetMesh* GetMeshAsset(const uuids::uuid& id); - Importers::AssetNodeHierarchy* GetMeshNodeHierarchy(const uuids::uuid& id); - AssetHandle GetMeshNodeHierarchyHandle(const uuids::uuid& id); - AssetHandle GetMaterialHandleFromUUID(const uuids::uuid& material_uuid); - - static AssetManager* Instance(); - - static AssetHandle CreateHandle(uint32_t, AssetType); - static uint32_t ReadAssetHandleIndex(AssetHandle); - static AssetType ReadAssetHandleType(AssetHandle); - - static void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Hardwares::VulkanDevice* device, ZEngine::Rendering::Renderers::AsyncResourceLoader* async_loader, cstring working_space_path); - static void Run(); - static void Shutdown(); - - static bool IsLoadingAsset(); - static AssetHandle RegisterAsset(AssetType type, const uuids::uuid& uid, uint32_t asset_id); - - static void LoadAssetFile(const Importers::AssetImporterOutput& file); - - template - static T* GetAsset(K key) - { - return nullptr; - } - - private: - void __Run(); - }; - - template <> - inline Importers::AssetMesh* AssetManager::GetAsset(AssetManager::AssetHandle key) - { - uint32_t index = ReadAssetHandleIndex(key); - if (index < Instance()->Meshes.size()) - { - return &Instance()->Meshes[index]; - } - return nullptr; - } - - template <> - inline Importers::AssetMaterial* AssetManager::GetAsset(AssetManager::AssetHandle key) - { - uint32_t index = ReadAssetHandleIndex(key); - if (index < Instance()->Materials.size()) - { - return &Instance()->Materials[index]; - } - return nullptr; - } - - template <> - inline Importers::AssetTexture* AssetManager::GetAsset(AssetManager::AssetHandle key) - { - uint32_t index = ReadAssetHandleIndex(key); - if (index < Instance()->Textures.size()) - { - return &Instance()->Textures[index]; - } - return nullptr; - } - - template <> - inline Importers::AssetNodeHierarchy* AssetManager::GetAsset(AssetManager::AssetHandle key) - { - uint32_t index = ReadAssetHandleIndex(key); - if (index < Instance()->NodeHierarchies.size()) - { - return &Instance()->NodeHierarchies[index]; - } - return nullptr; - } - - template <> - inline Importers::AssetMesh* AssetManager::GetAsset(uuids::uuid id) - { - if (Instance()->UUIDToHandle.contains(id)) - { - const auto& handle = Instance()->UUIDToHandle.at(id); - return GetAsset(handle); - } - return nullptr; - } - - template <> - inline Importers::AssetMaterial* AssetManager::GetAsset(uuids::uuid id) - { - if (Instance()->UUIDToHandle.contains(id)) - { - const auto& handle = Instance()->UUIDToHandle.at(id); - return GetAsset(handle); - } - return nullptr; - } - - template <> - inline Importers::AssetTexture* AssetManager::GetAsset(uuids::uuid id) - { - if (Instance()->UUIDToHandle.contains(id)) - { - const auto& handle = Instance()->UUIDToHandle.at(id); - return GetAsset(handle); - } - return nullptr; - } -} // namespace Tetragrama::Managers \ No newline at end of file diff --git a/Tetragrama/Serializers/EditorSceneSerializer.cpp b/Tetragrama/Serializers/EditorSceneSerializer.cpp index 3986045d..2fca9be3 100644 --- a/Tetragrama/Serializers/EditorSceneSerializer.cpp +++ b/Tetragrama/Serializers/EditorSceneSerializer.cpp @@ -1,15 +1,13 @@ #include -#include -#include +#include #include -#include #include +#include +#include #include using namespace ZEngine::Helpers; using namespace ZEngine::Core::Containers; -using namespace Tetragrama::Helpers; -using namespace Tetragrama::Importers; namespace Tetragrama::Serializers { @@ -77,7 +75,7 @@ namespace Tetragrama::Serializers }); } - void EditorSceneSerializer::Deserialize(std::string_view filename) + void EditorSceneSerializer::Deserialize(cstring filename) { ThreadPoolHelper::Submit([this, scene_filename = std::string(filename)] { std::unique_lock l(m_mutex); diff --git a/Tetragrama/Serializers/EditorSceneSerializer.h b/Tetragrama/Serializers/EditorSceneSerializer.h index e1cf0ef6..311a09d1 100644 --- a/Tetragrama/Serializers/EditorSceneSerializer.h +++ b/Tetragrama/Serializers/EditorSceneSerializer.h @@ -1,13 +1,13 @@ #pragma once -#include -#include -#include +#include +#include +#include namespace Tetragrama::Serializers { - struct EditorSceneSerializer : public Serializer + struct EditorSceneSerializer : public ZEngine::Serializers::Serializer { virtual void Serialize(ZRawPtr(EditorScene) const data) override; - virtual void Deserialize(std::string_view filename) override; + virtual void Deserialize(cstring filename) override; }; } // namespace Tetragrama::Serializers \ No newline at end of file diff --git a/ZEngine/ZEngine/Applications/AppRenderPipeline.cpp b/ZEngine/ZEngine/Applications/AppRenderPipeline.cpp new file mode 100644 index 00000000..158bb23c --- /dev/null +++ b/ZEngine/ZEngine/Applications/AppRenderPipeline.cpp @@ -0,0 +1,129 @@ +#include +#include +#include + +using namespace ZEngine::Core::Containers; + +namespace ZEngine::Applications +{ + void AppRenderPipeline::Initialize(Hardwares::VulkanDevicePtr device) + { + Device = device; + SceneRenderer = ZPushStructCtor(Device->Arena, Rendering::Renderers::GraphicRenderer); + ImguiRenderer = ZPushStructCtor(Device->Arena, Rendering::Renderers::ImGUIRenderer); + Device->Arena->CreateSubArena(ZMega(30), &LocalArena); + + SceneRenderer->Initialize(Device); + ImguiRenderer->Initialize(Device); + } + + void AppRenderPipeline::Shutdown() + { + SceneRenderer->Deinitialize(); + ImguiRenderer->Deinitialize(); + } + + void AppRenderPipeline::ResizeRenderTarget(uint32_t w, uint32_t h) + { + if (SceneRenderer && SceneRenderer->RenderGraph) + { + auto rendergraph = SceneRenderer->RenderGraph; + rendergraph->Resize(w, h); + } + } + + void AppRenderPipeline::BeginFrame() + { + Device->NewFrame(); + CurrentCmdBuf = Device->GetCommandBuffer(); + } + + void AppRenderPipeline::EndFrame() + { + Device->EnqueueCommandBuffer(CurrentCmdBuf); + Device->Present(); + } + + void AppRenderPipeline::RenderScene(Rendering::Cameras::CameraPtr camera, Rendering::Scenes::RenderScenePtr scene) + { + if (scene->TransformBufferDirty[Device->CurrentFrameIndex].load(std::memory_order_acquire) || scene->MeshAllocationDirty[Device->CurrentFrameIndex].load(std::memory_order_acquire)) + { + auto gpu_scene_data = SceneRenderer->RenderSceneData; + + auto vtx_buffer_set = Device->StorageBufferSetManager.Access(gpu_scene_data->VertexBufferHandle); + auto idx_buffer_set = Device->StorageBufferSetManager.Access(gpu_scene_data->IndexBufferHandle); + auto transform_buffer_set = Device->StorageBufferSetManager.Access(gpu_scene_data->TransformBufferHandle); + auto rd_buffer_set = Device->StorageBufferSetManager.Access(gpu_scene_data->RenderDataBufferHandle); + + auto indirect_buffer_set = Device->IndirectBufferSetManager.Access(gpu_scene_data->IndirectBufferHandle); + + auto vtx_buffer = vtx_buffer_set->At(Device->CurrentFrameIndex); + auto idx_buffer = idx_buffer_set->At(Device->CurrentFrameIndex); + auto transform_buffer = transform_buffer_set->At(Device->CurrentFrameIndex); + auto rd_buffer = rd_buffer_set->At(Device->CurrentFrameIndex); + auto indirect_buffer = indirect_buffer_set->At(Device->CurrentFrameIndex); + + auto& suballocs = scene->NodeSubMeshesAllocations; + + if (scene->TransformBufferDirty[Device->CurrentFrameIndex].exchange(false, std::memory_order_acquire)) + { + auto transform_data_view = ArrayView{scene->GlobalTransforms}; + transform_buffer->Write(transform_data_view); + } + + if (scene->MeshAllocationDirty[Device->CurrentFrameIndex].exchange(false, std::memory_order_acquire)) + { + auto scratch = ZGetScratch(&LocalArena); + + ZEngine::Core::Containers::Array SubMeshAllocations = {}; + ZEngine::Core::Containers::Array DrawIndirectCommands = {}; + SubMeshAllocations.init(scratch.Arena, suballocs.size()); + + for (const auto& [_, alloc] : suballocs) + { + SubMeshAllocations.push(alloc); + } + + DrawIndirectCommands.init(scratch.Arena, SubMeshAllocations.size()); + for (unsigned i = 0; i < SubMeshAllocations.size(); ++i) + { + DrawIndirectCommands.push({ + .vertexCount = SubMeshAllocations[i].IndexCount, + .instanceCount = SubMeshAllocations[i].InstanceCount, + .firstVertex = 0, + .firstInstance = i, + }); + } + + auto vertex_data_view = ArrayView{scene->Vertices}; + auto index_data_view = ArrayView{scene->Indices}; + + auto sub_mesh_alloc_view = ArrayView{SubMeshAllocations}; + auto indirect_commands_view = ArrayView{DrawIndirectCommands}; + + vtx_buffer->Write(vertex_data_view); + idx_buffer->Write(index_data_view); + + rd_buffer->Write(sub_mesh_alloc_view); + + indirect_buffer->Write(indirect_commands_view); + + ZReleaseScratch(scratch); + } + } + + // Todo (Kernel) : When we'll start considering multithreaded support + // we might want to renderer->EnqueueAsync({command_buffer, {camera, frame_data} }) + SceneRenderer->DrawScene(CurrentCmdBuf, camera); + } + + void AppRenderPipeline::BeginOverlayFrame() + { + ImguiRenderer->NewFrame(); + } + + void AppRenderPipeline::EndOverlayFrame() + { + ImguiRenderer->DrawFrame(CurrentCmdBuf); + } +} // namespace ZEngine::Applications \ No newline at end of file diff --git a/ZEngine/ZEngine/Applications/AppRenderPipeline.h b/ZEngine/ZEngine/Applications/AppRenderPipeline.h new file mode 100644 index 00000000..3b132860 --- /dev/null +++ b/ZEngine/ZEngine/Applications/AppRenderPipeline.h @@ -0,0 +1,32 @@ +#pragma once +#include +#include +#include + +namespace ZEngine::Applications +{ + struct AppRenderPipeline + { + Hardwares::VulkanDevicePtr Device = nullptr; + Rendering::Renderers::GraphicRendererPtr SceneRenderer = nullptr; + Rendering::Renderers::ImGUIRendererPtr ImguiRenderer = nullptr; + Hardwares::CommandBufferPtr CurrentCmdBuf = nullptr; + + ZEngine::Core::Memory::ArenaAllocator LocalArena = {}; + + void Initialize(Hardwares::VulkanDevicePtr device); + void Shutdown(); + + void ResizeRenderTarget(uint32_t w, uint32_t h); + + void BeginFrame(); + void EndFrame(); + + void RenderScene(Rendering::Cameras::CameraPtr camera, Rendering::Scenes::RenderScenePtr scene); + + void BeginOverlayFrame(); + void EndOverlayFrame(); + }; + ZDEFINE_PTR(AppRenderPipeline); + +} // namespace ZEngine::Applications diff --git a/ZEngine/ZEngine/Applications/GameApplication.cpp b/ZEngine/ZEngine/Applications/GameApplication.cpp new file mode 100644 index 00000000..f58b9d5e --- /dev/null +++ b/ZEngine/ZEngine/Applications/GameApplication.cpp @@ -0,0 +1,83 @@ +#include +#include +#include + +namespace ZEngine::Applications +{ + void GameApplication::Initialize(Core::Memory::ArenaAllocator* arena) + { + Arena = arena; + + State = ZPushStructCtor(Arena, ApplicationState); + + OnInitializing(); + OverrideWindowConfiguration(); + + Engine::Initialize(Arena, &WindowCfg, this); + + OnInitialized(); + } + + void GameApplication::Run() + { + Engine::Run(); + } + + void GameApplication::Update(Core::TimeStep dt) + { + if (CameraController) + { + CameraController->Update(dt); + } + + OnUpdate(dt); + } + + void GameApplication::ProcessEvent(Core::CoreEvent& e) + { + if (CurrentWindow) + { + CurrentWindow->OnEvent(e); + } + + if (CameraController) + { + CameraController->OnEvent(e); + } + + OnEvent(e); + } + + void GameApplication::Render() + { + RenderTargetResizeRequest request = {}; + if (State->RenderTargetResizeRequests.Pop(request)) + { + RenderPipeline->ResizeRenderTarget(request.Width, request.Height); + } + + RenderPipeline->BeginFrame(); + + OnPreRender(); + RenderPipeline->RenderScene(CameraController->GetCamera(), CurrentScene); + OnPostRender(); + + if (EnableRenderOverlay) + { + RenderPipeline->BeginOverlayFrame(); + OnRenderUI(); + RenderPipeline->EndOverlayFrame(); + } + + RenderPipeline->EndFrame(); + } + + void GameApplication::Shutdown() + { + OnClosing(); + + Engine::Dispose(); + + OnClosed(); + } +} // namespace ZEngine::Applications \ No newline at end of file diff --git a/ZEngine/ZEngine/Applications/GameApplication.h b/ZEngine/ZEngine/Applications/GameApplication.h new file mode 100644 index 00000000..0f6e5c2e --- /dev/null +++ b/ZEngine/ZEngine/Applications/GameApplication.h @@ -0,0 +1,65 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ZEngine::Applications +{ + struct RenderTargetResizeRequest + { + uint32_t Width = 0; + uint32_t Height = 0; + }; + + struct ApplicationState + { + Helpers::ThreadSafeQueue RenderTargetResizeRequests = {}; + }; + + ZDEFINE_PTR(ApplicationState); + + struct GameApplication + { + + bool EnableRenderOverlay = false; + cstring ConfigFile = nullptr; + cstring WorkingSpacePath = nullptr; + Windows::WindowConfiguration WindowCfg = {}; + + Core::Memory::ArenaAllocator* Arena = nullptr; + Windows::CoreWindowPtr CurrentWindow = nullptr; + ApplicationStatePtr State = nullptr; + AppRenderPipelinePtr RenderPipeline = nullptr; + Controllers::ICameraControllerPtr CameraController = nullptr; + Rendering::Scenes::RenderScenePtr CurrentScene = nullptr; + + void Initialize(Core::Memory::ArenaAllocator* arena); + void Update(Core::TimeStep dt); + void ProcessEvent(Core::CoreEvent&); + void Run(); + void Render(); + void Shutdown(); + + virtual void OverrideWindowConfiguration() = 0; + + virtual void OnInitializing() = 0; + virtual void OnInitialized() = 0; + + virtual void OnEvent(Core::CoreEvent&) = 0; + virtual void OnUpdate(float dt) = 0; + + virtual void OnPreRender() = 0; + virtual void OnPostRender() = 0; + virtual void OnRenderUI() = 0; + + virtual void OnClosing() = 0; + virtual void OnClosed() = 0; + }; + ZDEFINE_PTR(GameApplication); + +} // namespace ZEngine::Applications diff --git a/ZEngine/ZEngine/Applications/Layer.h b/ZEngine/ZEngine/Applications/Layer.h new file mode 100644 index 00000000..e78c7766 --- /dev/null +++ b/ZEngine/ZEngine/Applications/Layer.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +namespace ZEngine::Applications +{ + + struct Layer : public Core::IUpdatable, public Core::IEventable, public Core::IRenderable + { + Layer(cstring name = "default_layer") + { + Name = name; + } + + virtual ~Layer() = default; + + ZEngine::Core::Memory::ArenaAllocator LocalArena = {}; + ZEngine::Core::Memory::ArenaAllocator* Arena = nullptr; + cstring Name = nullptr; + + GameApplicationPtr CurrentApp = nullptr; + + virtual void Initialize(Core::Memory::ArenaAllocator* arena, GameApplicationPtr app) = 0; + virtual void Deinitialize() {}; + }; +} // namespace ZEngine::Applications diff --git a/ZEngine/ZEngine/CMakeLists.txt b/ZEngine/ZEngine/CMakeLists.txt index 70dad617..5242a54e 100644 --- a/ZEngine/ZEngine/CMakeLists.txt +++ b/ZEngine/ZEngine/CMakeLists.txt @@ -21,6 +21,7 @@ add_library (zEngineLib target_include_directories (zEngineLib PUBLIC . + ./Applications ./Core ./Core/Maths ./Core/Memory @@ -28,6 +29,9 @@ target_include_directories (zEngineLib ./Hardwares ./Helpers ./Layers + ./Managers + ./Importers + ./Controllers ./Logging ./Rendering ./Rendering/Entities diff --git a/Tetragrama/Controllers/CameraControllerTypeEnums.h b/ZEngine/ZEngine/Controllers/CameraControllerTypeEnums.h similarity index 75% rename from Tetragrama/Controllers/CameraControllerTypeEnums.h rename to ZEngine/ZEngine/Controllers/CameraControllerTypeEnums.h index 32c189b3..713c01e7 100644 --- a/Tetragrama/Controllers/CameraControllerTypeEnums.h +++ b/ZEngine/ZEngine/Controllers/CameraControllerTypeEnums.h @@ -1,6 +1,6 @@ #pragma once -namespace Tetragrama::Controllers +namespace ZEngine::Controllers { enum class CameraControllerType { @@ -10,4 +10,4 @@ namespace Tetragrama::Controllers ORTHOGRAPHIC_CONTROLLER, UNDEFINED }; -} // namespace Tetragrama::Controllers +} // namespace ZEngine::Controllers diff --git a/Tetragrama/Controllers/ICameraController.h b/ZEngine/ZEngine/Controllers/ICameraController.h similarity index 83% rename from Tetragrama/Controllers/ICameraController.h rename to ZEngine/ZEngine/Controllers/ICameraController.h index 11a8f703..5a118c39 100644 --- a/Tetragrama/Controllers/ICameraController.h +++ b/ZEngine/ZEngine/Controllers/ICameraController.h @@ -1,21 +1,21 @@ #pragma once #include #include -#include -#include +#include +#include -namespace Tetragrama::Controllers +namespace ZEngine::Controllers { struct ICameraController : public IController { ICameraController() {} - virtual ~ICameraController() = default; + virtual ~ICameraController() = default; - virtual glm::vec3 GetPosition() const = 0; - virtual void SetPosition(const glm::vec3& position) = 0; - virtual ZRawPtr(ZEngine::Rendering::Cameras::Camera) GetCamera() const = 0; - virtual void UpdateProjectionMatrix() = 0; + virtual glm::vec3 GetPosition() const = 0; + virtual void SetPosition(const glm::vec3& position) = 0; + virtual ZRawPtr(Rendering::Cameras::Camera) GetCamera() const = 0; + virtual void UpdateProjectionMatrix() = 0; float GetRotationAngle() const { @@ -82,6 +82,7 @@ namespace Tetragrama::Controllers float m_aspect_ratio{0.0f}; bool m_can_rotate{false}; CameraControllerType m_controller_type{CameraControllerType::UNDEFINED}; - ZRawPtr(ZEngine::Windows::CoreWindow) m_window = nullptr; + ZRawPtr(Windows::CoreWindow) m_window = nullptr; }; -} // namespace Tetragrama::Controllers + ZDEFINE_PTR(ICameraController); +} // namespace ZEngine::Controllers diff --git a/ZEngine/ZEngine/Controllers/IController.h b/ZEngine/ZEngine/Controllers/IController.h new file mode 100644 index 00000000..dff808ab --- /dev/null +++ b/ZEngine/ZEngine/Controllers/IController.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace ZEngine::Controllers +{ + struct IController : public Core::IUpdatable, public Core::IEventable + { + IController() = default; + ~IController() = default; + }; +} // namespace ZEngine::Controllers diff --git a/Tetragrama/Controllers/PerspectiveCameraController.cpp b/ZEngine/ZEngine/Controllers/PerspectiveCameraController.cpp similarity index 96% rename from Tetragrama/Controllers/PerspectiveCameraController.cpp rename to ZEngine/ZEngine/Controllers/PerspectiveCameraController.cpp index c9e70f53..eff498d1 100644 --- a/Tetragrama/Controllers/PerspectiveCameraController.cpp +++ b/ZEngine/ZEngine/Controllers/PerspectiveCameraController.cpp @@ -1,18 +1,17 @@ #include #include +#include #include #include #include #include -#include using namespace ZEngine; using namespace ZEngine::Helpers; using namespace ZEngine::Windows::Inputs; using namespace ZEngine::Windows::Events; -using namespace Tetragrama::Inputs; -namespace Tetragrama::Controllers +namespace ZEngine::Controllers { PerspectiveCameraController::PerspectiveCameraController() {} void PerspectiveCameraController::Update(Core::TimeStep dt) @@ -129,4 +128,4 @@ namespace Tetragrama::Controllers return false; } -} // namespace Tetragrama::Controllers +} // namespace ZEngine::Controllers diff --git a/Tetragrama/Controllers/PerspectiveCameraController.h b/ZEngine/ZEngine/Controllers/PerspectiveCameraController.h similarity index 82% rename from Tetragrama/Controllers/PerspectiveCameraController.h rename to ZEngine/ZEngine/Controllers/PerspectiveCameraController.h index 354c65a0..189b1daa 100644 --- a/Tetragrama/Controllers/PerspectiveCameraController.h +++ b/ZEngine/ZEngine/Controllers/PerspectiveCameraController.h @@ -1,23 +1,23 @@ #pragma once #include -#include -#include -#include +#include +#include +#include #include -namespace Tetragrama::Controllers +namespace ZEngine::Controllers { - class PerspectiveCameraController : public ICameraController, public ZEngine::Windows::Inputs::IMouseEventCallback + class PerspectiveCameraController : public ICameraController, public Windows::Inputs::IMouseEventCallback { public: PerspectiveCameraController(); virtual ~PerspectiveCameraController() = default; - void Update(ZEngine::Core::TimeStep) override; - bool OnEvent(ZEngine::Core::CoreEvent&) override; + void Update(Core::TimeStep) override; + bool OnEvent(Core::CoreEvent&) override; - ZRawPtr(ZEngine::Rendering::Cameras::Camera) GetCamera() const override; + ZRawPtr(Rendering::Cameras::Camera) GetCamera() const override; void UpdateProjectionMatrix() override; @@ -66,4 +66,4 @@ namespace Tetragrama::Controllers std::recursive_mutex m_event_mutex = {}; ZRawPtr(ZEngine::Rendering::Cameras::PerspectiveCamera) m_perspective_camera = nullptr; }; -} // namespace Tetragrama::Controllers +} // namespace ZEngine::Controllers diff --git a/ZEngine/ZEngine/Core/Containers/HashMap.h b/ZEngine/ZEngine/Core/Containers/HashMap.h index c2d3e840..5d349a7d 100644 --- a/ZEngine/ZEngine/Core/Containers/HashMap.h +++ b/ZEngine/ZEngine/Core/Containers/HashMap.h @@ -146,7 +146,7 @@ namespace ZEngine::Core::Containers size_type index = probe_for_insert(key); auto& entry = m_entries[index]; - if (entry.state == EntryState::Occupied && entry.key == key) + if (entry.state == EntryState::Occupied && key_equals(entry.key, key)) { entry.value = value; // Update existing key return; @@ -344,6 +344,19 @@ namespace ZEngine::Core::Containers } } + // Compare keys, specialized for const char* + bool key_equals(const K& a, const K& b) const + { + if constexpr (std::is_same_v) + { + return Helpers::secure_strcmp(a, b) == 0; + } + else + { + return a == b; + } + } + // Rehashes the hash map to a new capacity, reinserting all occupied entries. // @param new_capacity The new number of slots. // @note Moves the old entries to avoid copying and skips Deleted entries. @@ -384,7 +397,7 @@ namespace ZEngine::Core::Containers { return size_type(-1); } - if (entry.state == EntryState::Occupied && entry.key == key) + if (entry.state == EntryState::Occupied && key_equals(entry.key, key)) { return index; } @@ -418,7 +431,7 @@ namespace ZEngine::Core::Containers { first_deleted = index; } - else if (entry.state == EntryState::Occupied && entry.key == key) + else if (entry.state == EntryState::Occupied && key_equals(entry.key, key)) { return index; } @@ -451,7 +464,14 @@ namespace ZEngine::Core::Containers // @return The hash value. size_type hash(const K& key) const { - return rapidhash(&key, sizeof(key)); + if constexpr (std::is_same_v) + { + return rapidhash(key, Helpers::secure_strlen(key)); + } + else + { + return rapidhash(&key, sizeof(K)); + } } // Computes a secondary hash for double hashing to determine probe step size. diff --git a/ZEngine/ZEngine/Engine.cpp b/ZEngine/ZEngine/Engine.cpp index e0820876..337973fd 100644 --- a/ZEngine/ZEngine/Engine.cpp +++ b/ZEngine/ZEngine/Engine.cpp @@ -1,24 +1,39 @@ #include +#include +#include #include #include -#include +#include +#include namespace ZEngine { - static bool s_request_terminate = false; - static std::shared_mutex g_mutex = {}; - static ZRawPtr(Windows::CoreWindow) g_current_window = nullptr; - static ZRawPtr(Rendering::Renderers::GraphicRenderer) g_renderer = nullptr; - static ZRawPtr(Hardwares::VulkanDevice) g_device = nullptr; + static bool s_request_terminate = false; + static std::shared_mutex g_mutex = {}; + static EngineContextPtr g_engine_ctx = nullptr; + static Applications::GameApplicationPtr g_app = nullptr; + static Applications::AppRenderPipelinePtr g_appRenderPipeline = nullptr; - void Engine::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZRawPtr(ZEngine::Windows::CoreWindow) const window) + void Engine::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, Windows::WindowConfigurationPtr window_cfg_ptr, Applications::GameApplicationPtr app) { - g_current_window = window; - g_device = ZPushStructCtor(arena, Hardwares::VulkanDevice); - g_renderer = ZPushStructCtor(arena, Rendering::Renderers::GraphicRenderer); + g_engine_ctx = ZPushStruct(arena, EngineContext); + g_engine_ctx->Device = ZPushStructCtor(arena, Hardwares::VulkanDevice); + auto window = ZPushStructCtor(arena, Windows::GameWindow); - g_device->Initialize(arena, window); - g_renderer->Initialize(g_device); + window->SetCallbackFunction(std::bind(&Applications::GameApplication::ProcessEvent, app, std::placeholders::_1)); + window->Initialize(arena, *window_cfg_ptr); + g_engine_ctx->Window = window; + + g_appRenderPipeline = ZPushStruct(arena, Applications::AppRenderPipeline); + + g_engine_ctx->Device->Initialize(arena, window); + g_appRenderPipeline->Initialize(g_engine_ctx->Device); + + Managers::AssetManager::Initialize(arena, g_engine_ctx->Device, app->WorkingSpacePath); + + app->RenderPipeline = g_appRenderPipeline; + app->CurrentWindow = g_engine_ctx->Window; + g_app = app; ZENGINE_CORE_INFO("Engine initialized") } @@ -26,19 +41,22 @@ namespace ZEngine void Engine::Deinitialize() { std::unique_lock l(g_mutex); - if (g_current_window) + + if (g_engine_ctx->Window) { - g_current_window->Deinitialize(); + g_engine_ctx->Window->Deinitialize(); } - g_renderer->Deinitialize(); - g_device->Deinitialize(); + g_appRenderPipeline->Shutdown(); + + g_engine_ctx->Device->Deinitialize(); } void Engine::Dispose() { s_request_terminate = false; - g_device->Dispose(); + Managers::AssetManager::Shutdown(); + g_engine_ctx->Device->Dispose(); ZENGINE_CORE_INFO("Engine destroyed") } @@ -51,49 +69,30 @@ namespace ZEngine void Engine::Run() { + Managers::AssetManager::Run(); + s_request_terminate = false; - while (g_current_window) + while (auto window = g_engine_ctx->Window) { if (s_request_terminate) { break; } - float dt = g_current_window->GetDeltaTime(); + float dt = window->GetDeltaTime(); - g_current_window->PollEvent(); + window->PollEvent(); - if (g_current_window->IsMinimized()) + if (window->IsMinimized()) { continue; } /*On Update*/ - g_current_window->Update(dt); - - g_device->Update(); - if (g_renderer->EnqueuedResizeRequests.Size()) - { - Rendering::Renderers::ResizeRequest req; - if (g_renderer->EnqueuedResizeRequests.Pop(req)) - { - g_renderer->RenderGraph->Resize(req.Width, req.Height); - continue; - } - } + g_app->Update(dt); /*On Render*/ - g_device->NewFrame(); - g_renderer->ImguiRenderer->NewFrame(); - auto buffer = g_device->GetCommandBuffer(); - { - - g_current_window->Render(g_renderer, buffer); - - g_renderer->ImguiRenderer->DrawFrame(g_device->CurrentFrameIndex, buffer); - } - g_device->EnqueueCommandBuffer(buffer); - g_device->Present(); + g_app->Render(); } if (s_request_terminate) @@ -101,22 +100,4 @@ namespace ZEngine Deinitialize(); } } - - Windows::CoreWindow* Engine::GetWindow() - { - std::shared_lock l(g_mutex); - return g_current_window; - } - - ZEngine::Hardwares::VulkanDevice* Engine::GetDevice() - { - std::shared_lock l(g_mutex); - return g_device; - } - - Rendering::Renderers::AsyncResourceLoader* Engine::GetAsyncResourceLoader() - { - std::shared_lock l(g_mutex); - return g_renderer->AsyncLoader; - } } // namespace ZEngine diff --git a/ZEngine/ZEngine/Engine.h b/ZEngine/ZEngine/Engine.h index 9be1ef85..1ab740a7 100644 --- a/ZEngine/ZEngine/Engine.h +++ b/ZEngine/ZEngine/Engine.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -6,20 +7,25 @@ namespace ZEngine { + struct EngineContext + { + Hardwares::VulkanDevicePtr Device = nullptr; + Windows::CoreWindowPtr Window = nullptr; + }; + ZDEFINE_PTR(EngineContext); + struct Engine { - static void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZRawPtr(ZEngine::Windows::CoreWindow) const); - static void Run(); - static Windows::CoreWindow* GetWindow(); - static ZEngine::Hardwares::VulkanDevice* GetDevice(); - static Rendering::Renderers::AsyncResourceLoader* GetAsyncResourceLoader(); - static void Deinitialize(); - static void Dispose(); - static bool OnEngineClosed(Event::EngineClosedEvent&); + static void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, Windows::WindowConfigurationPtr window_cfg_ptr, Applications::GameApplicationPtr app); + static void Run(); + static void Deinitialize(); + static void Dispose(); + static bool OnEngineClosed(Event::EngineClosedEvent&); private: Engine() = delete; Engine(const Engine&) = delete; ~Engine() = delete; }; + ZDEFINE_PTR(Engine); } // namespace ZEngine diff --git a/ZEngine/ZEngine/Hardwares/AsyncResourceLoader.cpp b/ZEngine/ZEngine/Hardwares/AsyncResourceLoader.cpp new file mode 100644 index 00000000..f609332c --- /dev/null +++ b/ZEngine/ZEngine/Hardwares/AsyncResourceLoader.cpp @@ -0,0 +1,326 @@ +#include +#include +#include +#include +#include + +#define STB_IMAGE_IMPLEMENTATION +#ifdef __GNUC__ +#define STBI_NO_SIMD +#endif +#include + +#define STB_IMAGE_WRITE_IMPLEMENTATION +#define STB_IMAGE_RESIZE_IMPLEMENTATION +#include +#include + +using namespace ZEngine::Helpers; +using namespace ZEngine::Rendering::Specifications; +using namespace ZEngine::Rendering; + +namespace ZEngine::Hardwares +{ + void AsyncResourceLoader::Initialize(VulkanDevice* device) + { + Device = device; + BufferManager = ZPushStructCtor(Device->Arena, CommandBufferManager); + + BufferManager->Initialize(Device); + Helpers::ThreadPoolHelper::Submit([this] { Run(); }); + } + + Textures::TextureHandle AsyncResourceLoader::LoadTextureFile(cstring filename) + { + std::unique_lock l(m_mutex_2); + + auto abs_filename = std::filesystem::absolute(filename).string(); + + int w, h, ch; + if (!stbi_info(abs_filename.c_str(), &w, &h, &ch)) + { + return {}; + } + + const std::set known_cubmap_file_ext = {".hdr", ".exr"}; + auto file_ext = std::filesystem::path(filename).extension().string(); + + Specifications::TextureSpecification spec{.Width = (uint32_t) w, .Height = (uint32_t) h, .Format = Specifications::ImageFormat::R8G8B8A8_SRGB}; + + if (known_cubmap_file_ext.contains(file_ext)) + { + int face_size = w / 4; + + spec.IsCubemap = true; + spec.LayerCount = 6; + spec.Format = Specifications::ImageFormat::R32G32B32A32_SFLOAT; + + spec.Width = face_size; + spec.Height = face_size; + } + + TextureFileRequest tex_file_req = {}; + tex_file_req.Filename = filename; + tex_file_req.TextureSpec = spec; + tex_file_req.TextureSpec.BytePerPixel = Specifications::BytePerChannelMap[VALUE_FROM_SPEC_MAP(spec.Format)]; + tex_file_req.Handle = Device->CreateTexture(tex_file_req.TextureSpec); + + m_file_requests.Enqueue(tex_file_req); + m_cond.notify_one(); + + return tex_file_req.Handle; + } + + void AsyncResourceLoader::Run() + { + while (true) + { + std::unique_lock l(m_mutex); + m_cond.wait(l, [this] { return !m_file_requests.Empty() || !m_update_texture_request.Empty() || !m_upload_requests.Empty() || m_cancellation_token.load() == true; }); + + if (m_cancellation_token.load() == true) + { + break; + } + + // Processing update requests + if (m_update_texture_request.Size()) + { + UpdateTextureRequest tr; + if (m_update_texture_request.Pop(tr)) + { + auto texture = Device->GlobalTextures.Access(tr.Handle); + auto img_buf = Device->Image2DBufferManager.Access(texture->BufferHandle); + auto& spec = texture->Specification; + auto image_handle = img_buf->GetHandle(); + uint32_t image_aspect = (texture->Specification.Format == Specifications::ImageFormat::DEPTH_STENCIL_FROM_DEVICE) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + + if (Device->HasSeperateTransfertQueueFamily) + { + Specifications::ImageMemoryBarrierSpecification barrier_spec_0 = {}; + barrier_spec_0.ImageHandle = image_handle; + barrier_spec_0.OldLayout = Specifications::ImageLayout::TRANSFER_DST_OPTIMAL; + barrier_spec_0.NewLayout = VkImageAspectFlagBits(image_aspect) == VK_IMAGE_ASPECT_DEPTH_BIT ? Specifications::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL : Specifications::ImageLayout::SHADER_READ_ONLY_OPTIMAL; + barrier_spec_0.ImageAspectMask = VkImageAspectFlagBits(image_aspect); + barrier_spec_0.SourceAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier_spec_0.DestinationAccessMask = VK_ACCESS_NONE; + barrier_spec_0.SourceStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; + barrier_spec_0.DestinationStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + barrier_spec_0.LayerCount = spec.LayerCount; + barrier_spec_0.SourceQueueFamily = Device->TransferFamilyIndex; + barrier_spec_0.DestinationQueueFamily = Device->GraphicFamilyIndex; + Primitives::ImageMemoryBarrier barrier_0{barrier_spec_0}; + auto command_buffer_0 = BufferManager->GetInstantCommandBuffer(QueueType::TRANSFER_QUEUE, Device->CurrentFrameIndex); + { + command_buffer_0->TransitionImageLayout(barrier_0); + img_buf->Layout = barrier_spec_0.NewLayout; + } + BufferManager->EndInstantCommandBuffer(command_buffer_0, Device); + } + + VkAccessFlags access_flag = Device->HasSeperateTransfertQueueFamily ? VK_ACCESS_NONE : VK_ACCESS_TRANSFER_WRITE_BIT; + VkPipelineStageFlagBits src_stage = Device->HasSeperateTransfertQueueFamily ? VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT : VK_PIPELINE_STAGE_TRANSFER_BIT; + + Specifications::ImageMemoryBarrierSpecification barrier_spec = {}; + barrier_spec.ImageHandle = image_handle; + barrier_spec.OldLayout = Specifications::ImageLayout::TRANSFER_DST_OPTIMAL; + barrier_spec.NewLayout = VkImageAspectFlagBits(image_aspect) == VK_IMAGE_ASPECT_DEPTH_BIT ? Specifications::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL : Specifications::ImageLayout::SHADER_READ_ONLY_OPTIMAL; + barrier_spec.ImageAspectMask = VkImageAspectFlagBits(image_aspect); + barrier_spec.SourceAccessMask = access_flag; + barrier_spec.DestinationAccessMask = VK_ACCESS_SHADER_READ_BIT; + barrier_spec.SourceStageMask = src_stage; + barrier_spec.DestinationStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + barrier_spec.LayerCount = spec.LayerCount; + barrier_spec.SourceQueueFamily = Device->TransferFamilyIndex; + barrier_spec.DestinationQueueFamily = Device->GraphicFamilyIndex; + Primitives::ImageMemoryBarrier barrier{barrier_spec}; + + auto command_buffer = BufferManager->GetInstantCommandBuffer(QueueType::GRAPHIC_QUEUE, Device->CurrentFrameIndex); + { + command_buffer->TransitionImageLayout(barrier); + img_buf->Layout = barrier_spec.NewLayout; + } + BufferManager->EndInstantCommandBuffer(command_buffer, Device); + + Device->TextureHandleToUpdates.Enqueue(tr.Handle); + } + } + + // Processing upload requests + if (m_upload_requests.Size()) + { + TextureUploadRequest upload_request; + if (m_upload_requests.Pop(upload_request)) + { + auto texture = Device->GlobalTextures.Access(upload_request.Handle); + auto img_buf = Device->Image2DBufferManager.Access(texture->BufferHandle); + uint32_t image_aspect = (texture->Specification.Format == Specifications::ImageFormat::DEPTH_STENCIL_FROM_DEVICE) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + + auto command_buffer = BufferManager->GetInstantCommandBuffer(QueueType::TRANSFER_QUEUE, Device->CurrentFrameIndex); + { + auto image_handle = img_buf->GetHandle(); + auto& image_buffer = img_buf->GetBuffer(); + + Specifications::ImageMemoryBarrierSpecification barrier_spec_0 = {}; + barrier_spec_0.ImageHandle = image_handle; + barrier_spec_0.OldLayout = img_buf->Layout; + barrier_spec_0.NewLayout = Specifications::ImageLayout::TRANSFER_DST_OPTIMAL; + barrier_spec_0.ImageAspectMask = VkImageAspectFlagBits(image_aspect); + barrier_spec_0.SourceAccessMask = 0; + barrier_spec_0.DestinationAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier_spec_0.SourceStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + barrier_spec_0.DestinationStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; + barrier_spec_0.LayerCount = upload_request.TextureSpec.LayerCount; + barrier_spec_0.SourceQueueFamily = Device->TransferFamilyIndex; + barrier_spec_0.DestinationQueueFamily = Device->TransferFamilyIndex; + + Primitives::ImageMemoryBarrier barrier_0{barrier_spec_0}; + command_buffer->TransitionImageLayout(barrier_0); + + img_buf->Layout = barrier_spec_0.NewLayout; + + Device->WriteTextureData(command_buffer, upload_request.Handle, upload_request.Buffer.data()); + } + BufferManager->EndInstantCommandBuffer(command_buffer, Device, VK_PIPELINE_STAGE_TRANSFER_BIT); + + UpdateTextureRequest tr = {.Handle = upload_request.Handle}; + + m_update_texture_request.Emplace(std::move(tr)); + } + } + + // Processing file requests + TextureFileRequest file_request; + if (m_file_requests.Pop(file_request)) + { + TextureUploadRequest upload_req = {}; + + int width = 0, height = 0, channel = 0; + stbi_set_flip_vertically_on_load(1); + + if (file_request.TextureSpec.IsCubemap) + { + const float* image_data = stbi_loadf(file_request.Filename.data(), &width, &height, &channel, 4); + if (!image_data) + { + ZENGINE_CORE_ERROR("Failed to load texture file : {0}", file_request.Filename.data()) + continue; + } + + bool perform_convert_rgb_to_rgba = (channel == STBI_rgb); + + std::vector output_buffer = {}; + if (perform_convert_rgb_to_rgba) + { + size_t total_pixel = width * height; + size_t buffer_size = total_pixel * 4; + output_buffer.resize(buffer_size); + stbir_resize_float(image_data, width, height, 0, output_buffer.data(), width, height, 0, 4); + + for (int i = 0; i < total_pixel; ++i) + { + int offset = i * 4; // RGBA format (4 channels) + + if (channel == 1) + { + output_buffer[offset + 3] = 255; + } + else if (channel == 2) + { + output_buffer[offset + 3] = image_data[i * 2 + 1]; + } + else if (channel == 3) + { + output_buffer[offset + 3] = 255; + } + } + } + else + { + size_t total_pixel = width * height; + size_t buffer_size = total_pixel * channel; + output_buffer.resize(buffer_size); + Helpers::secure_memset(output_buffer.data(), 0.f, buffer_size, buffer_size); + } + + stbi_image_free((void*) image_data); + + Buffers::Bitmap in = {width, height, 4, Buffers::BitmapFormat::FLOAT, output_buffer.data()}; + Buffers::Bitmap vertical_cross = Buffers::Bitmap::EquirectangularMapToVerticalCross(in); + Buffers::Bitmap cubemap = Buffers::Bitmap::VerticalCrossToCubemap(vertical_cross); + + // spec.Width = cubemap.Width; + // spec.Height = cubemap.Height; + size_t buffer_size = cubemap.Buffer.size(); + size_t buffer_byte = buffer_size * sizeof(uint8_t); + upload_req.Buffer.resize(buffer_size); + Helpers::secure_memmove(upload_req.Buffer.data(), buffer_byte, cubemap.Buffer.data(), buffer_byte); + } + else + { + + stbi_uc* image_data = stbi_load(file_request.Filename.data(), &width, &height, &channel, STBI_rgb_alpha); + if (!image_data) + { + ZENGINE_CORE_ERROR("Failed to load texture file : {0}", file_request.Filename.data()) + continue; + } + + bool perform_convert_rgb_to_rgba = (channel <= STBI_rgb); + + if (perform_convert_rgb_to_rgba) + { + size_t total_pixel = width * height; + size_t buffer_size = total_pixel * 4; + upload_req.Buffer.resize(buffer_size); + stbir_resize_uint8(image_data, width, height, 0, upload_req.Buffer.data(), width, height, 0, 4); + + for (int i = 0; i < total_pixel; ++i) + { + int offset = i * 4; // RGBA format (4 channels) + + if (channel == 1) + { + upload_req.Buffer[offset + 3] = 255; + } + else if (channel == 2) + { + upload_req.Buffer[offset + 3] = image_data[i * 2 + 1]; + } + else if (channel == 3) + { + upload_req.Buffer[offset + 3] = 255; + } + } + } + else + { + size_t total_pixel = width * height; + size_t buffer_size = total_pixel * channel; + upload_req.Buffer.resize(buffer_size, 0); + Helpers::secure_memmove(upload_req.Buffer.data(), buffer_size, image_data, buffer_size); + } + + stbi_image_free(image_data); + } + + upload_req.BufferSize = (upload_req.Buffer.size() * sizeof(uint8_t)); + upload_req.Handle = file_request.Handle; + upload_req.TextureSpec = file_request.TextureSpec; + + m_upload_requests.Emplace(std::move(upload_req)); + } + } + } + + void AsyncResourceLoader::Shutdown() + { + { + std::unique_lock l(m_mutex); + m_cancellation_token = true; + } + m_cond.notify_one(); + + BufferManager->Deinitialize(); + } +} // namespace ZEngine::Hardwares \ No newline at end of file diff --git a/ZEngine/ZEngine/Hardwares/AsyncResourceLoader.h b/ZEngine/ZEngine/Hardwares/AsyncResourceLoader.h new file mode 100644 index 00000000..0a3b21e2 --- /dev/null +++ b/ZEngine/ZEngine/Hardwares/AsyncResourceLoader.h @@ -0,0 +1,53 @@ +#pragma once +#include +#include +#include + +namespace ZEngine::Hardwares +{ + struct VulkanDevice; + struct CommandBufferManager; + + struct UpdateTextureRequest + { + Rendering::Textures::TextureHandle Handle; + Rendering::Textures::Texture* Texture; + }; + + struct TextureFileRequest + { + std::string Filename; + Rendering::Textures::TextureHandle Handle; + Rendering::Specifications::TextureSpecification TextureSpec; + }; + + struct TextureUploadRequest + { + size_t BufferSize = 0; + Rendering::Textures::TextureHandle Handle = {}; + Rendering::Specifications::TextureSpecification TextureSpec = {}; + std::vector Buffer = {}; + }; + + struct AsyncResourceLoader + { + VulkanDevice* Device = nullptr; + Hardwares::CommandBufferManager* BufferManager = nullptr; + + void Initialize(VulkanDevice* renderer); + void Run(); + void Shutdown(); + + Rendering::Textures::TextureHandle LoadTextureFile(cstring filename); + + private: + std::atomic_bool m_cancellation_token{false}; + std::mutex m_mutex; + std::mutex m_mutex_2; + std::condition_variable m_cond; + Helpers::ThreadSafeQueue m_update_texture_request; + Helpers::ThreadSafeQueue m_file_requests; + Helpers::ThreadSafeQueue m_upload_requests; + }; + ZDEFINE_PTR(AsyncResourceLoader); +} // namespace ZEngine::Hardwares diff --git a/ZEngine/ZEngine/Hardwares/VulkanDevice.cpp b/ZEngine/ZEngine/Hardwares/VulkanDevice.cpp index 3421fcc5..055bb0dd 100644 --- a/ZEngine/ZEngine/Hardwares/VulkanDevice.cpp +++ b/ZEngine/ZEngine/Hardwares/VulkanDevice.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include using namespace std::chrono_literals; @@ -27,8 +28,9 @@ namespace ZEngine::Hardwares { void VulkanDevice::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, Windows::CoreWindow* const window) { - Arena = arena; - CurrentWindow = window; + Arena = arena; + CurrentWindow = window; + AsyncResLoader = ZPushStructCtor(Arena, AsyncResourceLoader); DefaultDepthFormats.init(Arena, 3); DefaultDepthFormats.push(VK_FORMAT_D32_SFLOAT); @@ -404,6 +406,8 @@ namespace ZEngine::Hardwares } CreateSwapchain(); + AsyncResLoader->Initialize(this); + ThreadPoolHelper::Submit([this] { DirtyCollector(); }); } @@ -416,6 +420,8 @@ namespace ZEngine::Hardwares } DirtyCollectorCond.notify_one(); + AsyncResLoader->Shutdown(); + GlobalTextures.Dispose(); Image2DBufferManager.Dispose(); VertexBufferSetManager.Dispose(); diff --git a/ZEngine/ZEngine/Hardwares/VulkanDevice.h b/ZEngine/ZEngine/Hardwares/VulkanDevice.h index 6ef5e527..e251d900 100644 --- a/ZEngine/ZEngine/Hardwares/VulkanDevice.h +++ b/ZEngine/ZEngine/Hardwares/VulkanDevice.h @@ -18,6 +18,7 @@ #include #include #include +#include #include // clang-format on @@ -586,6 +587,7 @@ namespace ZEngine::Hardwares std::mutex Mutex = {}; Windows::CoreWindow* CurrentWindow = nullptr; ZEngine::Core::Memory::ArenaAllocator* Arena = nullptr; + AsyncResourceLoaderPtr AsyncResLoader = nullptr; void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, Windows::CoreWindow* const window); void Deinitialize(); diff --git a/Tetragrama/Helpers/NodeHierarchyHelper.h b/ZEngine/ZEngine/Helpers/NodeHierarchyHelper.h similarity index 78% rename from Tetragrama/Helpers/NodeHierarchyHelper.h rename to ZEngine/ZEngine/Helpers/NodeHierarchyHelper.h index c3624ffd..1a535537 100644 --- a/Tetragrama/Helpers/NodeHierarchyHelper.h +++ b/ZEngine/ZEngine/Helpers/NodeHierarchyHelper.h @@ -1,6 +1,6 @@ #pragma once -namespace Tetragrama::Helpers +namespace ZEngine::Helpers { struct NodeHierarchy { @@ -10,4 +10,4 @@ namespace Tetragrama::Helpers int RightSibling = -1; int DepthLevel = -1; }; -} // namespace Tetragrama::Helpers \ No newline at end of file +} // namespace ZEngine::Helpers \ No newline at end of file diff --git a/ZEngine/ZEngine/Helpers/SerializerCommonHelper.cpp b/ZEngine/ZEngine/Helpers/SerializerCommonHelper.cpp new file mode 100644 index 00000000..0b32f859 --- /dev/null +++ b/ZEngine/ZEngine/Helpers/SerializerCommonHelper.cpp @@ -0,0 +1,9 @@ +#include +#include +#include + +using namespace ZEngine::Core::Containers; + +namespace ZEngine::Helpers +{ +} // namespace ZEngine::Helpers \ No newline at end of file diff --git a/Tetragrama/Helpers/SerializerCommonHelper.h b/ZEngine/ZEngine/Helpers/SerializerCommonHelper.h similarity index 94% rename from Tetragrama/Helpers/SerializerCommonHelper.h rename to ZEngine/ZEngine/Helpers/SerializerCommonHelper.h index 6afaec4d..b750b13b 100644 --- a/Tetragrama/Helpers/SerializerCommonHelper.h +++ b/ZEngine/ZEngine/Helpers/SerializerCommonHelper.h @@ -1,13 +1,13 @@ #pragma once -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include -namespace Tetragrama::Helpers +namespace ZEngine::Helpers { template static void WriteBinary(std::ostream& writer, const T& data) @@ -138,7 +138,7 @@ namespace Tetragrama::Helpers { size_t size = 0; ReadBinary(in, size); - map.init(arena, size); + map.init(arena, (size > 32) ? size : 32); for (uint32_t i = 0; i < size; ++i) { @@ -165,4 +165,4 @@ namespace Tetragrama::Helpers map.insert(key, val); } } -} // namespace Tetragrama::Helpers \ No newline at end of file +} // namespace ZEngine::Helpers \ No newline at end of file diff --git a/ZEngine/ZEngine/Importers/AssetTypes.h b/ZEngine/ZEngine/Importers/AssetTypes.h new file mode 100644 index 00000000..42bc5e7a --- /dev/null +++ b/ZEngine/ZEngine/Importers/AssetTypes.h @@ -0,0 +1,101 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include + +namespace ZEngine::Importers +{ + enum AssetFileType : uint8_t + { + UNKNOWN = 0, + MESH, + MATERIAL, + TEXTURES + }; + + struct AssetSubMesh + { + uuids::uuid MaterialUUID = {}; + uint32_t VertexCount = 0; + uint32_t IndexCount = 0; + uint32_t VertexOffset = 0; + uint32_t IndexOffset = 0; + uint32_t StreamOffset = 0; + uint32_t IndexStreamOffset = 0; + uint32_t VertexUnitStreamSize = 0; + uint32_t IndexUnitStreamSize = 0; + uint32_t TotalByteSize = 0; + }; + + struct AssetMesh + { + uuids::uuid MeshUUID = {}; + Core::Containers::Array Vertices = {}; + Core::Containers::Array Indices = {}; + Core::Containers::Array SubMeshes = {}; + }; + + struct AssetMaterial + { + Core::Containers::String Name = {}; + uuids::uuid MaterialUUID = {}; + uuids::uuid AlbedoTexUUID = {}; + uuids::uuid EmissiveTexUUID = {}; + uuids::uuid NormalTexUUID = {}; + uuids::uuid OpacityTexUUID = {}; + uuids::uuid SpecularTexUUID = {}; + float AmbientColor[4] = {0}; + float AlbedoColor[4] = {0}; + float EmissiveColor[4] = {0}; + float RoughnessColor[4] = {0}; + float SpecularColor[4] = {0}; + float Factors[4] = {0}; + }; + + struct AssetTexture + { + Rendering::Textures::TextureHandle Handle = {}; + uuids::uuid TextureUUID = {}; + Core::Containers::String Path = {}; + }; + + struct AssetNodeHierarchy + { + uuids::uuid NodeHierarchyUUID = {}; + uuids::uuid MeshUUID = {}; + Core::Containers::Array Hierarchies = {}; + Core::Containers::Array LocalTransforms = {}; + Core::Containers::Array GlobalTransforms = {}; + Core::Containers::Array Names = {}; + Core::Containers::Array MaterialNames = {}; + Core::Containers::HashMap NodeNames = {}; + Core::Containers::HashMap NodeMeshes = {}; + Core::Containers::HashMap NodeMaterials = {}; + }; + + struct AssetNodeRef + { + int NodeHierarchyIndex = -1; + uint32_t AssetNodeHandle = 0xFFFFFFFF; + cstring Name = nullptr; + uuids::uuid AssetMeshUUID = {}; + + bool IsValid() const + { + return (AssetNodeHandle != 0xFFFFFFFF) && (NodeHierarchyIndex != -1); + } + }; + + struct AssetFile + { + const char* Name = nullptr; + AssetNodeHierarchy Hierarchy = {}; + AssetMesh Mesh = {}; + Core::Containers::Array Materials = {}; + Core::Containers::Array Textures = {}; + }; +} // namespace ZEngine::Importers diff --git a/Tetragrama/Importers/AssimpImporter.cpp b/ZEngine/ZEngine/Importers/AssimpImporter.cpp similarity index 93% rename from Tetragrama/Importers/AssimpImporter.cpp rename to ZEngine/ZEngine/Importers/AssimpImporter.cpp index ca4ed7de..34df0d08 100644 --- a/Tetragrama/Importers/AssimpImporter.cpp +++ b/ZEngine/ZEngine/Importers/AssimpImporter.cpp @@ -7,7 +7,6 @@ #include using namespace ZEngine::Helpers; -using namespace Tetragrama::Helpers; using namespace ZEngine::Rendering::Meshes; using namespace ZEngine::Rendering::Scenes; using namespace ZEngine::Core::Containers; @@ -15,7 +14,7 @@ using namespace uuids; namespace fs = std::filesystem; -namespace Tetragrama::Importers +namespace ZEngine::Importers { AssimpImporter::AssimpImporter() : m_progress_handler{}, m_flags{aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_SortByPType} { @@ -104,7 +103,7 @@ namespace Tetragrama::Importers co_return; } - void AssimpImporter::ExtractMeshes(ZEngine::Core::Memory::ArenaAllocator* arena, const aiScene* scene, uuids::uuid_random_generator& generator, AssetMesh& mesh) + void AssimpImporter::ExtractMeshes(Core::Memory::ArenaAllocator* arena, const aiScene* scene, uuids::uuid_random_generator& generator, AssetMesh& mesh) { if ((!scene) || (!scene->HasMeshes())) { @@ -190,7 +189,7 @@ namespace Tetragrama::Importers } } - void AssimpImporter::ExtractMaterials(ZEngine::Core::Memory::ArenaAllocator* arena, const aiScene* scene, uuids::uuid_random_generator& generator, ZEngine::Core::Containers::Array& materials, AssetNodeHierarchy& model) + void AssimpImporter::ExtractMaterials(Core::Memory::ArenaAllocator* arena, const aiScene* scene, uuids::uuid_random_generator& generator, Core::Containers::Array& materials, AssetNodeHierarchy& model) { if (!scene) { @@ -283,7 +282,7 @@ namespace Tetragrama::Importers } } - void AssimpImporter::ExtractTextures(ZEngine::Core::Memory::ArenaAllocator* arena, const aiScene* scene, uuids::uuid_random_generator& generator, ZEngine::Core::Containers::Array& materials, ZEngine::Core::Containers::Array& textures) + void AssimpImporter::ExtractTextures(Core::Memory::ArenaAllocator* arena, const aiScene* scene, uuids::uuid_random_generator& generator, Core::Containers::Array& materials, Core::Containers::Array& textures) { if (!scene) { @@ -363,7 +362,7 @@ namespace Tetragrama::Importers } } - void AssimpImporter::CreateHierachy(ZEngine::Core::Memory::ArenaAllocator* arena, const aiScene* scene, uuids::uuid_random_generator& generator, AssetNodeHierarchy& AssetNode, AssetMesh& asset_mesh, ZEngine::Core::Containers::Array& materials) + void AssimpImporter::CreateHierachy(Core::Memory::ArenaAllocator* arena, const aiScene* scene, uuids::uuid_random_generator& generator, AssetNodeHierarchy& AssetNode, AssetMesh& asset_mesh, Core::Containers::Array& materials) { if (!scene || !(scene->mRootNode)) { @@ -384,7 +383,7 @@ namespace Tetragrama::Importers TraverseNode(arena, scene, scene->mRootNode, AssetNode, asset_mesh, materials, -1, 0); } - void AssimpImporter::TraverseNode(ZEngine::Core::Memory::ArenaAllocator* arena, const aiScene* ai_scene, const aiNode* node, AssetNodeHierarchy& hierarchy, AssetMesh& asset_mesh, ZEngine::Core::Containers::Array& materials, int parent_node_id, int depth_level) + void AssimpImporter::TraverseNode(Core::Memory::ArenaAllocator* arena, const aiScene* ai_scene, const aiNode* node, AssetNodeHierarchy& hierarchy, AssetMesh& asset_mesh, Core::Containers::Array& materials, int parent_node_id, int depth_level) { auto node_id = AddNode(hierarchy, parent_node_id, depth_level); hierarchy.NodeNames[node_id] = hierarchy.Names.size(); @@ -421,7 +420,7 @@ namespace Tetragrama::Importers } } - void AssimpImporter::CopyTextureFiles(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Core::Containers::Array& textures, const ImportConfiguration& config) + void AssimpImporter::CopyTextureFiles(Core::Memory::ArenaAllocator* arena, Core::Containers::Array& textures, const ImportConfiguration& config) { /* * Normalize file naming @@ -529,4 +528,4 @@ namespace Tetragrama::Importers } return true; } -} // namespace Tetragrama::Importers \ No newline at end of file +} // namespace ZEngine::Importers \ No newline at end of file diff --git a/ZEngine/ZEngine/Importers/AssimpImporter.h b/ZEngine/ZEngine/Importers/AssimpImporter.h new file mode 100644 index 00000000..9bd455eb --- /dev/null +++ b/ZEngine/ZEngine/Importers/AssimpImporter.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +namespace ZEngine::Importers +{ + class AssimpImporter; + struct AssimpProgressHandler; + + struct AssimpProgressHandler : public Assimp::ProgressHandler + { + void SetImporter(AssimpImporter* const importer); + bool Update(float percentage) override; + + private: + AssimpImporter* m_importer{nullptr}; + }; + + class AssimpImporter : public IAssetImporter + { + public: + AssimpImporter(); + virtual ~AssimpImporter(); + + virtual std::future ImportAsync(const char* filename, const ImportConfiguration& config) override; + void CopyTextureFiles(Core::Memory::ArenaAllocator*, Core::Containers::Array&, const ImportConfiguration&); + + private: + uint32_t m_flags; + AssimpProgressHandler m_progress_handler; + + friend struct AssimpProgressHandler; + + void ExtractMeshes(Core::Memory::ArenaAllocator*, const aiScene*, uuids::uuid_random_generator&, AssetMesh&); + void ExtractMaterials(Core::Memory::ArenaAllocator*, const aiScene*, uuids::uuid_random_generator&, Core::Containers::Array&, AssetNodeHierarchy&); + void ExtractTextures(Core::Memory::ArenaAllocator* arena, const aiScene*, uuids::uuid_random_generator&, Core::Containers::Array&, Core::Containers::Array&); + void CreateHierachy(Core::Memory::ArenaAllocator* arena, const aiScene*, uuids::uuid_random_generator&, AssetNodeHierarchy&, AssetMesh&, Core::Containers::Array&); + + void TraverseNode(Core::Memory::ArenaAllocator* arena, const aiScene*, const aiNode*, AssetNodeHierarchy&, AssetMesh&, Core::Containers::Array&, int parent_node_id, int depth_level); + glm::mat4 ConvertToMat4(const aiMatrix4x4& m); + }; +} // namespace ZEngine::Importers \ No newline at end of file diff --git a/Tetragrama/Importers/IAssetImporter.cpp b/ZEngine/ZEngine/Importers/IAssetImporter.cpp similarity index 90% rename from Tetragrama/Importers/IAssetImporter.cpp rename to ZEngine/ZEngine/Importers/IAssetImporter.cpp index c97f2fdd..5b11237b 100644 --- a/Tetragrama/Importers/IAssetImporter.cpp +++ b/ZEngine/ZEngine/Importers/IAssetImporter.cpp @@ -1,14 +1,13 @@ #include +#include #include #include -#include using namespace uuids; using namespace ZEngine::Helpers; -using namespace Tetragrama::Helpers; using namespace ZEngine::Core::Containers; -namespace Tetragrama::Importers +namespace ZEngine::Importers { int AddNode(AssetNodeHierarchy& hierarchy, int parent, int depth) { @@ -55,9 +54,9 @@ namespace Tetragrama::Importers return node_id; } - void IAssetImporter::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena) + void IAssetImporter::Initialize(Core::Memory::ArenaAllocator* arena) { - arena->CreateSubArena(ZMega(200), &Arena); + arena->CreateSubArena(ZMega(350), &Arena); } void IAssetImporter::SetOnCompleteCallback(on_import_complete_fn callback) @@ -85,7 +84,7 @@ namespace Tetragrama::Importers return m_is_importing.load(std::memory_order_acquire); } - AssetImporterOutput IAssetImporter::SerializeMeshAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, AssetMesh& mesh, AssetNodeHierarchy& hierarchies, const ImportConfiguration& config) + AssetImporterOutput IAssetImporter::SerializeMeshAssetFile(Core::Memory::ArenaAllocator* arena, AssetMesh& mesh, AssetNodeHierarchy& hierarchies, const ImportConfiguration& config) { AssetImporterOutput output = {}; @@ -150,7 +149,7 @@ namespace Tetragrama::Importers return output; } - AssetImporterOutput IAssetImporter::SerializeMaterialAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, AssetMaterial& material, const ImportConfiguration& config) + AssetImporterOutput IAssetImporter::SerializeMaterialAssetFile(Core::Memory::ArenaAllocator* arena, AssetMaterial& material, const ImportConfiguration& config) { AssetImporterOutput output = {}; @@ -195,7 +194,7 @@ namespace Tetragrama::Importers return output; } - AssetImporterOutput IAssetImporter::SerializeTextureAssetFiles(ZEngine::Core::Memory::ArenaAllocator* arena, ArrayView textures, const ImportConfiguration& config) + AssetImporterOutput IAssetImporter::SerializeTextureAssetFiles(Core::Memory::ArenaAllocator* arena, ArrayView textures, const ImportConfiguration& config) { AssetImporterOutput output = {}; @@ -233,9 +232,9 @@ namespace Tetragrama::Importers return output; } - void IAssetImporter::DeserializeMeshAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, const char* asset_file, AssetMesh& mesh, AssetNodeHierarchy& hierarchies) + void IAssetImporter::DeserializeMeshAssetFile(Core::Memory::ArenaAllocator* arena, const char* asset_file, AssetMesh& mesh, AssetNodeHierarchy& hierarchies) { - if (!ZEngine::Helpers::secure_strlen(asset_file)) + if (!Helpers::secure_strlen(asset_file)) { return; } @@ -303,9 +302,9 @@ namespace Tetragrama::Importers in.close(); } - void IAssetImporter::DeserializeMaterialAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, const char* asset_file, AssetMaterial& material) + void IAssetImporter::DeserializeMaterialAssetFile(Core::Memory::ArenaAllocator* arena, const char* asset_file, AssetMaterial& material) { - if (!ZEngine::Helpers::secure_strlen(asset_file)) + if (!Helpers::secure_strlen(asset_file)) { return; } @@ -351,9 +350,9 @@ namespace Tetragrama::Importers in.close(); } - void IAssetImporter::DeserializeTextureAssetFile(ZEngine::Core::Memory::ArenaAllocator* arena, const char* asset_file, ZEngine::Core::Containers::Array& textures) + void IAssetImporter::DeserializeTextureAssetFile(Core::Memory::ArenaAllocator* arena, const char* asset_file, Core::Containers::Array& textures) { - if (!ZEngine::Helpers::secure_strlen(asset_file)) + if (!Helpers::secure_strlen(asset_file)) { return; } @@ -398,7 +397,7 @@ namespace Tetragrama::Importers bool IAssetImporter::ReadAssetMeshFileHeader(cstring asset_file, AssetMeshFileHeader& header) { bool output = false; - if (!ZEngine::Helpers::secure_strlen(asset_file)) + if (!Helpers::secure_strlen(asset_file)) { return output; } @@ -431,4 +430,4 @@ namespace Tetragrama::Importers in.close(); return output; } -} // namespace Tetragrama::Importers \ No newline at end of file +} // namespace ZEngine::Importers \ No newline at end of file diff --git a/ZEngine/ZEngine/Importers/IAssetImporter.h b/ZEngine/ZEngine/Importers/IAssetImporter.h new file mode 100644 index 00000000..8f0ee079 --- /dev/null +++ b/ZEngine/ZEngine/Importers/IAssetImporter.h @@ -0,0 +1,89 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define REPORT_LOG(ctx, msg) \ + { \ + if (m_log_callback) \ + { \ + m_log_callback(ctx, msg); \ + } \ + } + +namespace ZEngine::Importers +{ + int AddNode(AssetNodeHierarchy& hierarchy, int parent, int depth); + + struct ImportConfiguration + { + Core::Containers::String AssetName; + Core::Containers::String OutputAssetFile; + Core::Containers::String OutputAssetsPath; + Core::Containers::String InputBaseAssetFilePath; + Core::Containers::String OutputWorkingSpacePath; + Core::Containers::String OutputTextureFilesPath; + }; + + struct AssetMeshFileHeader + { + uint32_t MagicNumber = 0xFFFFFF; + uint32_t Version = 0xFFFFFF; + uuids::uuid Id = {}; + }; + + struct AssetImporterOutput + { + AssetFileType Type = AssetFileType::UNKNOWN; + std::string Path = ""; + std::string RootPath = ""; + }; + + struct IAssetImporter + { + typedef void (*on_import_complete_fn)(void* const, Core::Containers::ArrayView result); + typedef void (*on_import_progress_fn)(void* const, float progress); + typedef void (*on_import_error_fn)(void* const, std::string_view error_message); + typedef void (*on_import_log_fn)(void* const, std::string_view log_message); + + on_import_complete_fn m_complete_callback = nullptr; + on_import_progress_fn m_progress_callback = nullptr; + on_import_error_fn m_error_callback = nullptr; + on_import_log_fn m_log_callback = nullptr; + + std::mutex m_mutex; + std::atomic_bool m_is_importing = false; + + Core::Memory::ArenaAllocator Arena = {}; + void* Context = nullptr; + + virtual ~IAssetImporter() {} + + void Initialize(Core::Memory::ArenaAllocator* arena); + + virtual void SetOnCompleteCallback(on_import_complete_fn callback); + virtual void SetOnProgressCallback(on_import_progress_fn callback); + virtual void SetOnErrorCallback(on_import_error_fn callback); + virtual void SetOnLogCallback(on_import_log_fn callback); + virtual bool IsImporting(); + + virtual std::future ImportAsync(const char* filename, const ImportConfiguration& config) = 0; + + static AssetImporterOutput SerializeMeshAssetFile(Core::Memory::ArenaAllocator* arena, AssetMesh& data, AssetNodeHierarchy& hierarchies, const ImportConfiguration&); + static AssetImporterOutput SerializeMaterialAssetFile(Core::Memory::ArenaAllocator* arena, AssetMaterial& data, const ImportConfiguration&); + static AssetImporterOutput SerializeTextureAssetFiles(Core::Memory::ArenaAllocator* arena, Core::Containers::ArrayView data, const ImportConfiguration&); + + static void DeserializeMeshAssetFile(Core::Memory::ArenaAllocator* arena, const char* asset_file, AssetMesh&, AssetNodeHierarchy&); + static void DeserializeMaterialAssetFile(Core::Memory::ArenaAllocator* arena, const char* asset_file, AssetMaterial&); + static void DeserializeTextureAssetFile(Core::Memory::ArenaAllocator* arena, const char* asset_file, Core::Containers::Array&); + + static bool ReadAssetMeshFileHeader(cstring asset_file, AssetMeshFileHeader&); + }; +} // namespace ZEngine::Importers diff --git a/Tetragrama/Managers/AssetManager.cpp b/ZEngine/ZEngine/Managers/AssetManager.cpp similarity index 80% rename from Tetragrama/Managers/AssetManager.cpp rename to ZEngine/ZEngine/Managers/AssetManager.cpp index 9b838879..96925cce 100644 --- a/Tetragrama/Managers/AssetManager.cpp +++ b/ZEngine/ZEngine/Managers/AssetManager.cpp @@ -1,15 +1,14 @@ #include #include +#include +#include #include -#include -#include -#include -#include +#include using namespace ZEngine::Core::Containers; -using namespace Tetragrama::Importers; +using namespace ZEngine::Importers; -namespace Tetragrama::Managers +namespace ZEngine::Managers { static AssetManager* s_Instance = nullptr; @@ -33,14 +32,13 @@ namespace Tetragrama::Managers return AssetType((h >> 28) & 0xF); } - void AssetManager::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Hardwares::VulkanDevice* device, ZEngine::Rendering::Renderers::AsyncResourceLoader* async_loader, cstring working_space_path) + void AssetManager::Initialize(Core::Memory::ArenaAllocator* arena, Hardwares::VulkanDevice* device, cstring working_space_path) { s_Instance = ZPushStructCtor(arena, AssetManager); arena->CreateSubArena(ZMega(100), &(s_Instance->ThreadLocalArena)); arena->CreateSubArena(ZMega(70), &(s_Instance->Arena)); s_Instance->Device = device; - s_Instance->ResourceLoader = async_loader; s_Instance->CurrentWorkingSpacePath = working_space_path; s_Instance->NodeHierarchies.init(&(s_Instance->Arena), 5000); @@ -58,7 +56,7 @@ namespace Tetragrama::Managers void AssetManager::Run() { - ZEngine::Helpers::ThreadPoolHelper::Submit([instance = s_Instance]() { instance->__Run(); }); + Helpers::ThreadPoolHelper::Submit([instance = s_Instance]() { instance->__Run(); }); } void AssetManager::Shutdown() @@ -179,6 +177,33 @@ namespace Tetragrama::Managers return handle; } + Importers::AssetTexture* AssetManager::LoadTextureFileAsAsset(cstring file, bool absolute) + { + if (!Helpers::secure_strlen(file)) + { + return nullptr; + } + + auto asset_id = (uint32_t) Textures.size(); + + auto& new_tex = Textures.push_use({}); + + std::random_device rd; + std::mt19937 generator(rd()); + uuids::uuid_random_generator gen(&generator); + new_tex.TextureUUID = gen(); + + const auto tex_absolute_path = absolute ? std::string(file) : fmt::format("{0}{1}{2}", s_Instance->CurrentWorkingSpacePath, PLATFORM_OS_BACKSLASH, file); + new_tex.Handle = s_Instance->Device->AsyncResLoader->LoadTextureFile(tex_absolute_path.c_str()); + new_tex.Path.init(&(s_Instance->Arena), file); + + RegisterAsset(AssetType::TEXTURE, new_tex.TextureUUID, asset_id); + + UUIDToTextureHandle.insert(new_tex.TextureUUID, new_tex.Handle); + + return &new_tex; + } + void AssetManager::__Run() { while (true) @@ -214,8 +239,8 @@ namespace Tetragrama::Managers m.Vertices.init(&(s_Instance->Arena), mesh.Vertices.size(), mesh.Vertices.size()); m.Indices.init(&(s_Instance->Arena), mesh.Indices.size(), mesh.Indices.size()); - ZEngine::Helpers::secure_memcpy(m.Vertices.data(), m.Vertices.size() * sizeof(float), mesh.Vertices.data(), mesh.Vertices.size() * sizeof(float)); - ZEngine::Helpers::secure_memcpy(m.Indices.data(), m.Indices.size() * sizeof(uint32_t), mesh.Indices.data(), mesh.Indices.size() * sizeof(uint32_t)); + Helpers::secure_memcpy(m.Vertices.data(), m.Vertices.size() * sizeof(float), mesh.Vertices.data(), mesh.Vertices.size() * sizeof(float)); + Helpers::secure_memcpy(m.Indices.data(), m.Indices.size() * sizeof(uint32_t), mesh.Indices.data(), mesh.Indices.size() * sizeof(uint32_t)); for (auto& submesh : mesh.SubMeshes) { @@ -244,9 +269,9 @@ namespace Tetragrama::Managers h.NodeMeshes.init(&(s_Instance->Arena), hierarchies.NodeMeshes.size() > 32 ? hierarchies.NodeMeshes.size() * 2 : 64); h.NodeMaterials.init(&(s_Instance->Arena), hierarchies.NodeMaterials.size() > 32 ? hierarchies.NodeMaterials.size() * 2 : 64); - ZEngine::Helpers::secure_memcpy(h.Hierarchies.data(), h.Hierarchies.size() * sizeof(AssetNodeHierarchy), hierarchies.Hierarchies.data(), hierarchies.Hierarchies.size() * sizeof(AssetNodeHierarchy)); - ZEngine::Helpers::secure_memcpy(h.LocalTransforms.data(), h.LocalTransforms.size() * sizeof(glm::mat4), hierarchies.LocalTransforms.data(), hierarchies.LocalTransforms.size() * sizeof(glm::mat4)); - ZEngine::Helpers::secure_memcpy(h.GlobalTransforms.data(), h.GlobalTransforms.size() * sizeof(glm::mat4), hierarchies.GlobalTransforms.data(), hierarchies.GlobalTransforms.size() * sizeof(glm::mat4)); + Helpers::secure_memcpy(h.Hierarchies.data(), h.Hierarchies.size() * sizeof(AssetNodeHierarchy), hierarchies.Hierarchies.data(), hierarchies.Hierarchies.size() * sizeof(AssetNodeHierarchy)); + Helpers::secure_memcpy(h.LocalTransforms.data(), h.LocalTransforms.size() * sizeof(glm::mat4), hierarchies.LocalTransforms.data(), hierarchies.LocalTransforms.size() * sizeof(glm::mat4)); + Helpers::secure_memcpy(h.GlobalTransforms.data(), h.GlobalTransforms.size() * sizeof(glm::mat4), hierarchies.GlobalTransforms.data(), hierarchies.GlobalTransforms.size() * sizeof(glm::mat4)); for (auto& name : hierarchies.Names) { @@ -289,7 +314,7 @@ namespace Tetragrama::Managers new_tex.TextureUUID = tex.TextureUUID; const auto tex_absolute_path = fmt::format("{0}{1}{2}", s_Instance->CurrentWorkingSpacePath, PLATFORM_OS_BACKSLASH, tex.Path.c_str()); - new_tex.Handle = s_Instance->ResourceLoader->LoadTextureFile(tex_absolute_path); + new_tex.Handle = s_Instance->Device->AsyncResLoader->LoadTextureFile(tex_absolute_path.c_str()); new_tex.Path.init(&(s_Instance->Arena), tex.Path.c_str()); RegisterAsset(AssetType::TEXTURE, new_tex.TextureUUID, asset_id); @@ -308,13 +333,13 @@ namespace Tetragrama::Managers RegisterAsset(AssetType::MATERIAL, material.MaterialUUID, asset_id); - ZEngine::Rendering::Meshes::MeshMaterial& gpu_mesh_mat = GPUMeshMaterials.push_use({}); - gpu_mesh_mat.AlbedoColor = material.AlbedoColor; - gpu_mesh_mat.EmissiveColor = material.EmissiveColor; - gpu_mesh_mat.RoughnessColor = material.RoughnessColor; - gpu_mesh_mat.SpecularColor = material.SpecularColor; - gpu_mesh_mat.AmbientColor = material.AmbientColor; - gpu_mesh_mat.Factors = material.Factors; + Rendering::Meshes::MeshMaterial& gpu_mesh_mat = GPUMeshMaterials.push_use({}); + gpu_mesh_mat.AlbedoColor = material.AlbedoColor; + gpu_mesh_mat.EmissiveColor = material.EmissiveColor; + gpu_mesh_mat.RoughnessColor = material.RoughnessColor; + gpu_mesh_mat.SpecularColor = material.SpecularColor; + gpu_mesh_mat.AmbientColor = material.AmbientColor; + gpu_mesh_mat.Factors = material.Factors; if (!material.AlbedoTexUUID.is_nil()) { @@ -376,4 +401,4 @@ namespace Tetragrama::Managers } } } -} // namespace Tetragrama::Managers +} // namespace ZEngine::Managers diff --git a/ZEngine/ZEngine/Managers/AssetManager.h b/ZEngine/ZEngine/Managers/AssetManager.h new file mode 100644 index 00000000..685c85c1 --- /dev/null +++ b/ZEngine/ZEngine/Managers/AssetManager.h @@ -0,0 +1,169 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ZEngine::Managers +{ + enum class AssetType : uint8_t + { + MESH = 0, + MATERIAL, + TEXTURE, + MESH_HIERARCHY + }; + + struct AssetManager + { + using AssetHandle = uint32_t; + + Core::Memory::ArenaAllocator Arena = {}; + Core::Memory::ArenaAllocator ThreadLocalArena = {}; + + cstring CurrentWorkingSpacePath = ""; + + std::atomic_bool IsLoading = false; + std::atomic_bool RequestShutdown = false; + + Core::Containers::Array NodeHierarchies = {}; + Core::Containers::Array Meshes = {}; + Core::Containers::Array Materials = {}; + Core::Containers::Array Textures = {}; + + Core::Containers::Array GPUMeshMaterials = {}; + + Core::Containers::HashMap UUIDToHandle = {}; + Core::Containers::HashMap HandleToUUID = {}; + Core::Containers::HashMap MeshToNodeHierarchy = {}; + Core::Containers::HashMap NodeHierarchyToMesh = {}; + + Core::Containers::HashMap UUIDToTextureHandle = {}; + + Hardwares::StorageBufferSetHandle MaterialBufferHandle = {}; + + std::mutex Mut; + std::condition_variable Cond; + Helpers::ThreadSafeQueue PendingAssetFiles = {}; + + Helpers::ThreadSafeQueue PendingAssetMeshes = {}; + Helpers::ThreadSafeQueue PendingAssetNodeHierarchies = {}; + Helpers::ThreadSafeQueue PendingAssetMaterials = {}; + Helpers::ThreadSafeQueue> PendingAssetTextures = {}; + + Hardwares::VulkanDevice* Device = nullptr; + + Importers::AssetMesh* GetMeshAsset(const uuids::uuid& id); + Importers::AssetNodeHierarchy* GetMeshNodeHierarchy(const uuids::uuid& id); + AssetHandle GetMeshNodeHierarchyHandle(const uuids::uuid& id); + AssetHandle GetMaterialHandleFromUUID(const uuids::uuid& material_uuid); + + Importers::AssetTexture* LoadTextureFileAsAsset(cstring file, bool absolute); + + static AssetManager* Instance(); + + static AssetHandle CreateHandle(uint32_t, AssetType); + static uint32_t ReadAssetHandleIndex(AssetHandle); + static AssetType ReadAssetHandleType(AssetHandle); + + static void Initialize(Core::Memory::ArenaAllocator* arena, Hardwares::VulkanDevice* device, cstring working_space_path); + static void Run(); + static void Shutdown(); + + static bool IsLoadingAsset(); + static AssetHandle RegisterAsset(AssetType type, const uuids::uuid& uid, uint32_t asset_id); + + static void LoadAssetFile(const Importers::AssetImporterOutput& file); + + template + static T* GetAsset(K key) + { + return nullptr; + } + + private: + void __Run(); + }; + + template <> + inline Importers::AssetMesh* AssetManager::GetAsset(AssetManager::AssetHandle key) + { + uint32_t index = ReadAssetHandleIndex(key); + if (index < Instance()->Meshes.size()) + { + return &Instance()->Meshes[index]; + } + return nullptr; + } + + template <> + inline Importers::AssetMaterial* AssetManager::GetAsset(AssetManager::AssetHandle key) + { + uint32_t index = ReadAssetHandleIndex(key); + if (index < Instance()->Materials.size()) + { + return &Instance()->Materials[index]; + } + return nullptr; + } + + template <> + inline Importers::AssetTexture* AssetManager::GetAsset(AssetManager::AssetHandle key) + { + uint32_t index = ReadAssetHandleIndex(key); + if (index < Instance()->Textures.size()) + { + return &Instance()->Textures[index]; + } + return nullptr; + } + + template <> + inline Importers::AssetNodeHierarchy* AssetManager::GetAsset(AssetManager::AssetHandle key) + { + uint32_t index = ReadAssetHandleIndex(key); + if (index < Instance()->NodeHierarchies.size()) + { + return &Instance()->NodeHierarchies[index]; + } + return nullptr; + } + + template <> + inline Importers::AssetMesh* AssetManager::GetAsset(uuids::uuid id) + { + if (Instance()->UUIDToHandle.contains(id)) + { + const auto& handle = Instance()->UUIDToHandle.at(id); + return GetAsset(handle); + } + return nullptr; + } + + template <> + inline Importers::AssetMaterial* AssetManager::GetAsset(uuids::uuid id) + { + if (Instance()->UUIDToHandle.contains(id)) + { + const auto& handle = Instance()->UUIDToHandle.at(id); + return GetAsset(handle); + } + return nullptr; + } + + template <> + inline Importers::AssetTexture* AssetManager::GetAsset(uuids::uuid id) + { + if (Instance()->UUIDToHandle.contains(id)) + { + const auto& handle = Instance()->UUIDToHandle.at(id); + return GetAsset(handle); + } + return nullptr; + } +} // namespace ZEngine::Managers \ No newline at end of file diff --git a/ZEngine/ZEngine/Rendering/Cameras/Camera.h b/ZEngine/ZEngine/Rendering/Cameras/Camera.h index 61b95c79..3bfdfa28 100644 --- a/ZEngine/ZEngine/Rendering/Cameras/Camera.h +++ b/ZEngine/ZEngine/Rendering/Cameras/Camera.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include #define GLM_FORCE_RADIANS #define GLM_FORCE_DEPTH_ZERO_TO_ONE @@ -9,7 +9,7 @@ namespace ZEngine::Rendering::Cameras { - struct Camera : public Helpers::RefCounted + struct Camera { float Fov = 0.0f; float AspectRatio = 0.0f; @@ -39,4 +39,5 @@ namespace ZEngine::Rendering::Cameras virtual glm::mat4 GetPerspectiveMatrix() const = 0; virtual glm::vec3 GetPosition() const = 0; }; + ZDEFINE_PTR(Camera); } // namespace ZEngine::Rendering::Cameras diff --git a/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.cpp b/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.cpp index c2e04798..b746b3b2 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.cpp @@ -1,28 +1,15 @@ #include -#include -#include +#include #include -#include #include #include #include -#define STB_IMAGE_IMPLEMENTATION -#ifdef __GNUC__ -#define STBI_NO_SIMD -#endif -#include - -#define STB_IMAGE_WRITE_IMPLEMENTATION -#define STB_IMAGE_RESIZE_IMPLEMENTATION -#include -#include - using namespace ZEngine::Hardwares; -using namespace ZEngine::Rendering::Specifications; using namespace ZEngine::Rendering::Renderers::Contracts; using namespace ZEngine::Helpers; using namespace ZEngine::Rendering::Specifications; +using namespace ZEngine::Core::Containers; namespace ZEngine::Rendering::Renderers { @@ -31,35 +18,33 @@ namespace ZEngine::Rendering::Renderers void GraphicRenderer::Initialize(Hardwares::VulkanDevicePtr device) { - Device = device; - RenderGraph = ZPushStructCtorArgs(Device->Arena, Renderers::RenderGraph); - AsyncLoader = ZPushStructCtor(Device->Arena, AsyncResourceLoader); - ImguiRenderer = ZPushStructCtor(Device->Arena, ImGUIRenderer); - RenderSceneData = ZPushStructCtor(Device->Arena, Scenes::SceneData); + Device = device; + RenderGraph = ZPushStructCtorArgs(Device->Arena, Renderers::RenderGraph); + RenderSceneData = ZPushStructCtor(Device->Arena, Scenes::SceneData); /* * Shared Buffers */ - SceneCameraBufferHandle = Device->CreateUniformBufferSet(); + RenderSceneData->SceneCameraBufferHandle = Device->CreateUniformBufferSet(); - RenderSceneData->VertexBufferHandle = Device->CreateStorageBufferSet(); - RenderSceneData->IndexBufferHandle = Device->CreateStorageBufferSet(); - RenderSceneData->TransformBufferHandle = Device->CreateStorageBufferSet(); - RenderSceneData->RenderDataBufferHandle = Device->CreateStorageBufferSet(); - RenderSceneData->MaterialBufferHandle = Device->CreateStorageBufferSet(); - RenderSceneData->IndirectBufferHandle = Device->CreateIndirectBufferSet(); + RenderSceneData->VertexBufferHandle = Device->CreateStorageBufferSet(); + RenderSceneData->IndexBufferHandle = Device->CreateStorageBufferSet(); + RenderSceneData->TransformBufferHandle = Device->CreateStorageBufferSet(); + RenderSceneData->RenderDataBufferHandle = Device->CreateStorageBufferSet(); + RenderSceneData->MaterialBufferHandle = Device->CreateStorageBufferSet(); + RenderSceneData->IndirectBufferHandle = Device->CreateIndirectBufferSet(); - auto scene_camera = Device->UniformBufferSetManager.Access(SceneCameraBufferHandle); + auto scene_camera = Device->UniformBufferSetManager.Access(RenderSceneData->SceneCameraBufferHandle); - auto vtx_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->VertexBufferHandle); - auto idx_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->IndexBufferHandle); - auto tranform_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->TransformBufferHandle); - auto rd_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->RenderDataBufferHandle); - auto material_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->MaterialBufferHandle); - auto indirect_buffer_set = Device->IndirectBufferSetManager.Access(RenderSceneData->IndirectBufferHandle); + auto vtx_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->VertexBufferHandle); + auto idx_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->IndexBufferHandle); + auto tranform_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->TransformBufferHandle); + auto rd_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->RenderDataBufferHandle); + auto material_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->MaterialBufferHandle); + auto indirect_buffer_set = Device->IndirectBufferSetManager.Access(RenderSceneData->IndirectBufferHandle); for (int i = 0; i < Device->SwapchainImageCount; ++i) { - scene_camera->At(i)->Allocate(sizeof(UBOCameraLayout), SceneCameraBufferName); + scene_camera->At(i)->Allocate(sizeof(UBOCameraLayout), RendererResourceName::SceneCameraBufferName); vtx_buffer_set->At(i)->Allocate(DefaultBufferSize, VertexBufferName); idx_buffer_set->At(i)->Allocate(DefaultBufferSize, IndexBufferName); @@ -83,21 +68,17 @@ namespace ZEngine::Rendering::Renderers FrameDepthRenderTarget = Device->CreateTexture({.PerformTransition = false, .Width = 1280, .Height = 780, .Format = ImageFormat::DEPTH_STENCIL_FROM_DEVICE}); Device->TextureHandleToUpdates.Enqueue(FrameColorRenderTarget); - /* - * Subsystems initialization - */ - RenderGraph->Initialize(Device->Arena, this); - AsyncLoader->Initialize(this); - ImguiRenderer->Initialize(Device, this->RenderGraph->RenderPassBuilder); /* * Render Graph definition */ - RenderGraph->Builder->AttachRenderTarget(FrameDepthRenderTargetName, FrameDepthRenderTarget); - RenderGraph->Builder->AttachRenderTarget(FrameColorRenderTargetName, FrameColorRenderTarget); + RenderGraph->Initialize(Device, RenderSceneData); - RenderGraph->Builder->CreateBufferSet("g_scene_directional_light_buffer"); - RenderGraph->Builder->CreateBufferSet("g_scene_point_light_buffer"); - RenderGraph->Builder->CreateBufferSet("g_scene_spot_light_buffer"); + RenderGraph->ResourceBuilder->AttachRenderTarget(RendererResourceName::FrameDepthRenderTargetName, FrameDepthRenderTarget); + RenderGraph->ResourceBuilder->AttachRenderTarget(RendererResourceName::FrameColorRenderTargetName, FrameColorRenderTarget); + + RenderGraph->ResourceBuilder->CreateBufferSet("g_scene_directional_light_buffer"); + RenderGraph->ResourceBuilder->CreateBufferSet("g_scene_point_light_buffer"); + RenderGraph->ResourceBuilder->CreateBufferSet("g_scene_spot_light_buffer"); RenderGraph->AddCallbackPass("Initial Pass", initial_pass); RenderGraph->AddCallbackPass("Depth Pre-Pass", scene_depth_prepass); @@ -112,332 +93,30 @@ namespace ZEngine::Rendering::Renderers void GraphicRenderer::Deinitialize() { - AsyncLoader->Shutdown(); - RenderGraph->Dispose(); Device->GlobalTextures.Remove(FrameColorRenderTarget); Device->GlobalTextures.Remove(FrameDepthRenderTarget); - - ImguiRenderer->Deinitialize(); } - void GraphicRenderer::DrawScene(Hardwares::CommandBufferPtr const cb, Cameras::Camera* const camera) + void GraphicRenderer::DrawScene(Hardwares::CommandBufferPtr const cb, Cameras::CameraPtr const camera) { - auto ubo_camera_data = UBOCameraLayout{.View = camera->GetViewMatrix(), .Projection = camera->GetPerspectiveMatrix(), .Position = glm::vec4(camera->GetPosition(), 1.0f)}; + auto asset_manager = Managers::AssetManager::Instance(); + auto ubo_camera_data = UBOCameraLayout{.View = camera->GetViewMatrix(), .Projection = camera->GetPerspectiveMatrix(), .Position = glm::vec4(camera->GetPosition(), 1.0f)}; - auto buffer_set = Device->UniformBufferSetManager.Access(SceneCameraBufferHandle); - auto camera_buf = buffer_set->At(Device->CurrentFrameIndex); + auto material_buffer_set = Device->StorageBufferSetManager.Access(RenderSceneData->MaterialBufferHandle); + auto camera_buffer_set = Device->UniformBufferSetManager.Access(RenderSceneData->SceneCameraBufferHandle); + auto camera_buf = camera_buffer_set->At(Device->CurrentFrameIndex); + auto material_buffer = material_buffer_set->At(Device->CurrentFrameIndex); + + material_buffer->Write(ArrayView{asset_manager->GPUMeshMaterials}); camera_buf->Write(reinterpret_cast(&ubo_camera_data), sizeof(UBOCameraLayout)); - RenderGraph->Execute(cb, RenderSceneData); + RenderGraph->Execute(cb); } Textures::TextureHandle GraphicRenderer::GetFrameOutput() { - return RenderGraph->GetRenderTarget(FrameColorRenderTargetName); - } - - // AsyncResourceLoader - // - void AsyncResourceLoader::Initialize(GraphicRenderer* renderer) - { - Renderer = renderer; - m_buffer_manager.Initialize(Renderer->Device); - Helpers::ThreadPoolHelper::Submit([this] { Run(); }); - } - - Textures::TextureHandle AsyncResourceLoader::LoadTextureFile(std::string_view filename) - { - std::unique_lock l(m_mutex_2); - - auto abs_filename = std::filesystem::absolute(filename).string(); - - int w, h, ch; - if (!stbi_info(abs_filename.c_str(), &w, &h, &ch)) - { - return {}; - } - - const std::set known_cubmap_file_ext = {".hdr", ".exr"}; - auto file_ext = std::filesystem::path(filename).extension().string(); - - Specifications::TextureSpecification spec{.Width = (uint32_t) w, .Height = (uint32_t) h, .Format = Specifications::ImageFormat::R8G8B8A8_SRGB}; - - if (known_cubmap_file_ext.contains(file_ext)) - { - int face_size = w / 4; - - spec.IsCubemap = true; - spec.LayerCount = 6; - spec.Format = Specifications::ImageFormat::R32G32B32A32_SFLOAT; - - spec.Width = face_size; - spec.Height = face_size; - } - - TextureFileRequest tex_file_req = {}; - tex_file_req.Filename = filename.data(); - tex_file_req.TextureSpec = spec; - tex_file_req.TextureSpec.BytePerPixel = Specifications::BytePerChannelMap[VALUE_FROM_SPEC_MAP(spec.Format)]; - tex_file_req.Handle = Renderer->Device->CreateTexture(tex_file_req.TextureSpec); - - m_file_requests.Enqueue(tex_file_req); - m_cond.notify_one(); - - return tex_file_req.Handle; - } - - void AsyncResourceLoader::Run() - { - while (true) - { - std::unique_lock l(m_mutex); - m_cond.wait(l, [this] { return !m_file_requests.Empty() || !m_update_texture_request.Empty() || !m_upload_requests.Empty() || m_cancellation_token.load() == true; }); - - if (m_cancellation_token.load() == true) - { - break; - } - - // Processing update requests - if (m_update_texture_request.Size()) - { - UpdateTextureRequest tr; - if (m_update_texture_request.Pop(tr)) - { - auto texture = Renderer->Device->GlobalTextures.Access(tr.Handle); - auto img_buf = Renderer->Device->Image2DBufferManager.Access(texture->BufferHandle); - auto& spec = texture->Specification; - auto image_handle = img_buf->GetHandle(); - uint32_t image_aspect = (texture->Specification.Format == Specifications::ImageFormat::DEPTH_STENCIL_FROM_DEVICE) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; - - if (Renderer->Device->HasSeperateTransfertQueueFamily) - { - Specifications::ImageMemoryBarrierSpecification barrier_spec_0 = {}; - barrier_spec_0.ImageHandle = image_handle; - barrier_spec_0.OldLayout = Specifications::ImageLayout::TRANSFER_DST_OPTIMAL; - barrier_spec_0.NewLayout = VkImageAspectFlagBits(image_aspect) == VK_IMAGE_ASPECT_DEPTH_BIT ? Specifications::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL : Specifications::ImageLayout::SHADER_READ_ONLY_OPTIMAL; - barrier_spec_0.ImageAspectMask = VkImageAspectFlagBits(image_aspect); - barrier_spec_0.SourceAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier_spec_0.DestinationAccessMask = VK_ACCESS_NONE; - barrier_spec_0.SourceStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; - barrier_spec_0.DestinationStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - barrier_spec_0.LayerCount = spec.LayerCount; - barrier_spec_0.SourceQueueFamily = Renderer->Device->TransferFamilyIndex; - barrier_spec_0.DestinationQueueFamily = Renderer->Device->GraphicFamilyIndex; - Primitives::ImageMemoryBarrier barrier_0{barrier_spec_0}; - auto command_buffer_0 = m_buffer_manager.GetInstantCommandBuffer(QueueType::TRANSFER_QUEUE, Renderer->Device->CurrentFrameIndex); - { - command_buffer_0->TransitionImageLayout(barrier_0); - img_buf->Layout = barrier_spec_0.NewLayout; - } - m_buffer_manager.EndInstantCommandBuffer(command_buffer_0, Renderer->Device); - } - - VkAccessFlags access_flag = Renderer->Device->HasSeperateTransfertQueueFamily ? VK_ACCESS_NONE : VK_ACCESS_TRANSFER_WRITE_BIT; - VkPipelineStageFlagBits src_stage = Renderer->Device->HasSeperateTransfertQueueFamily ? VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT : VK_PIPELINE_STAGE_TRANSFER_BIT; - - Specifications::ImageMemoryBarrierSpecification barrier_spec = {}; - barrier_spec.ImageHandle = image_handle; - barrier_spec.OldLayout = Specifications::ImageLayout::TRANSFER_DST_OPTIMAL; - barrier_spec.NewLayout = VkImageAspectFlagBits(image_aspect) == VK_IMAGE_ASPECT_DEPTH_BIT ? Specifications::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL : Specifications::ImageLayout::SHADER_READ_ONLY_OPTIMAL; - barrier_spec.ImageAspectMask = VkImageAspectFlagBits(image_aspect); - barrier_spec.SourceAccessMask = access_flag; - barrier_spec.DestinationAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier_spec.SourceStageMask = src_stage; - barrier_spec.DestinationStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - barrier_spec.LayerCount = spec.LayerCount; - barrier_spec.SourceQueueFamily = Renderer->Device->TransferFamilyIndex; - barrier_spec.DestinationQueueFamily = Renderer->Device->GraphicFamilyIndex; - Primitives::ImageMemoryBarrier barrier{barrier_spec}; - - auto command_buffer = m_buffer_manager.GetInstantCommandBuffer(QueueType::GRAPHIC_QUEUE, Renderer->Device->CurrentFrameIndex); - { - command_buffer->TransitionImageLayout(barrier); - img_buf->Layout = barrier_spec.NewLayout; - } - m_buffer_manager.EndInstantCommandBuffer(command_buffer, Renderer->Device); - - Renderer->Device->TextureHandleToUpdates.Enqueue(tr.Handle); - } - } - - // Processing upload requests - if (m_upload_requests.Size()) - { - TextureUploadRequest upload_request; - if (m_upload_requests.Pop(upload_request)) - { - auto texture = Renderer->Device->GlobalTextures.Access(upload_request.Handle); - auto img_buf = Renderer->Device->Image2DBufferManager.Access(texture->BufferHandle); - uint32_t image_aspect = (texture->Specification.Format == Specifications::ImageFormat::DEPTH_STENCIL_FROM_DEVICE) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; - - auto command_buffer = m_buffer_manager.GetInstantCommandBuffer(QueueType::TRANSFER_QUEUE, Renderer->Device->CurrentFrameIndex); - { - auto image_handle = img_buf->GetHandle(); - auto& image_buffer = img_buf->GetBuffer(); - - Specifications::ImageMemoryBarrierSpecification barrier_spec_0 = {}; - barrier_spec_0.ImageHandle = image_handle; - barrier_spec_0.OldLayout = img_buf->Layout; - barrier_spec_0.NewLayout = Specifications::ImageLayout::TRANSFER_DST_OPTIMAL; - barrier_spec_0.ImageAspectMask = VkImageAspectFlagBits(image_aspect); - barrier_spec_0.SourceAccessMask = 0; - barrier_spec_0.DestinationAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier_spec_0.SourceStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - barrier_spec_0.DestinationStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; - barrier_spec_0.LayerCount = upload_request.TextureSpec.LayerCount; - barrier_spec_0.SourceQueueFamily = Renderer->Device->TransferFamilyIndex; - barrier_spec_0.DestinationQueueFamily = Renderer->Device->TransferFamilyIndex; - - Primitives::ImageMemoryBarrier barrier_0{barrier_spec_0}; - command_buffer->TransitionImageLayout(barrier_0); - - img_buf->Layout = barrier_spec_0.NewLayout; - - Renderer->Device->WriteTextureData(command_buffer, upload_request.Handle, upload_request.Buffer.data()); - } - m_buffer_manager.EndInstantCommandBuffer(command_buffer, Renderer->Device, VK_PIPELINE_STAGE_TRANSFER_BIT); - - UpdateTextureRequest tr = {.Handle = upload_request.Handle}; - - m_update_texture_request.Emplace(std::move(tr)); - } - } - - // Processing file requests - TextureFileRequest file_request; - if (m_file_requests.Pop(file_request)) - { - TextureUploadRequest upload_req = {}; - - int width = 0, height = 0, channel = 0; - stbi_set_flip_vertically_on_load(1); - - if (file_request.TextureSpec.IsCubemap) - { - const float* image_data = stbi_loadf(file_request.Filename.data(), &width, &height, &channel, 4); - if (!image_data) - { - ZENGINE_CORE_ERROR("Failed to load texture file : {0}", file_request.Filename.data()) - continue; - } - - bool perform_convert_rgb_to_rgba = (channel == STBI_rgb); - - std::vector output_buffer = {}; - if (perform_convert_rgb_to_rgba) - { - size_t total_pixel = width * height; - size_t buffer_size = total_pixel * 4; - output_buffer.resize(buffer_size); - stbir_resize_float(image_data, width, height, 0, output_buffer.data(), width, height, 0, 4); - - for (int i = 0; i < total_pixel; ++i) - { - int offset = i * 4; // RGBA format (4 channels) - - if (channel == 1) - { - output_buffer[offset + 3] = 255; - } - else if (channel == 2) - { - output_buffer[offset + 3] = image_data[i * 2 + 1]; - } - else if (channel == 3) - { - output_buffer[offset + 3] = 255; - } - } - } - else - { - size_t total_pixel = width * height; - size_t buffer_size = total_pixel * channel; - output_buffer.resize(buffer_size); - Helpers::secure_memset(output_buffer.data(), 0.f, buffer_size, buffer_size); - } - - stbi_image_free((void*) image_data); - - Buffers::Bitmap in = {width, height, 4, Buffers::BitmapFormat::FLOAT, output_buffer.data()}; - Buffers::Bitmap vertical_cross = Buffers::Bitmap::EquirectangularMapToVerticalCross(in); - Buffers::Bitmap cubemap = Buffers::Bitmap::VerticalCrossToCubemap(vertical_cross); - - // spec.Width = cubemap.Width; - // spec.Height = cubemap.Height; - size_t buffer_size = cubemap.Buffer.size(); - size_t buffer_byte = buffer_size * sizeof(uint8_t); - upload_req.Buffer.resize(buffer_size); - Helpers::secure_memmove(upload_req.Buffer.data(), buffer_byte, cubemap.Buffer.data(), buffer_byte); - } - else - { - - stbi_uc* image_data = stbi_load(file_request.Filename.data(), &width, &height, &channel, STBI_rgb_alpha); - if (!image_data) - { - ZENGINE_CORE_ERROR("Failed to load texture file : {0}", file_request.Filename.data()) - continue; - } - - bool perform_convert_rgb_to_rgba = (channel <= STBI_rgb); - - if (perform_convert_rgb_to_rgba) - { - size_t total_pixel = width * height; - size_t buffer_size = total_pixel * 4; - upload_req.Buffer.resize(buffer_size); - stbir_resize_uint8(image_data, width, height, 0, upload_req.Buffer.data(), width, height, 0, 4); - - for (int i = 0; i < total_pixel; ++i) - { - int offset = i * 4; // RGBA format (4 channels) - - if (channel == 1) - { - upload_req.Buffer[offset + 3] = 255; - } - else if (channel == 2) - { - upload_req.Buffer[offset + 3] = image_data[i * 2 + 1]; - } - else if (channel == 3) - { - upload_req.Buffer[offset + 3] = 255; - } - } - } - else - { - size_t total_pixel = width * height; - size_t buffer_size = total_pixel * channel; - upload_req.Buffer.resize(buffer_size, 0); - Helpers::secure_memmove(upload_req.Buffer.data(), buffer_size, image_data, buffer_size); - } - - stbi_image_free(image_data); - } - - upload_req.BufferSize = (upload_req.Buffer.size() * sizeof(uint8_t)); - upload_req.Handle = file_request.Handle; - upload_req.TextureSpec = file_request.TextureSpec; - - m_upload_requests.Emplace(std::move(upload_req)); - } - } - } - - void AsyncResourceLoader::Shutdown() - { - { - std::unique_lock l(m_mutex); - m_cancellation_token = true; - } - m_cond.notify_one(); - - m_buffer_manager.Deinitialize(); + return RenderGraph->ResourceInspector->GetRenderTarget(RendererResourceName::FrameColorRenderTargetName); } } // namespace ZEngine::Rendering::Renderers diff --git a/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.h b/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.h index eabf7e4d..925e5a20 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.h +++ b/ZEngine/ZEngine/Rendering/Renderers/GraphicRenderer.h @@ -1,99 +1,28 @@ #pragma once #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace ZEngine::Rendering::Renderers { - struct ResizeRequest - { - uint32_t Width; - uint32_t Height; - }; - - struct UpdateTextureRequest - { - Textures::TextureHandle Handle; - Textures::Texture* Texture; - }; - - struct TextureFileRequest - { - std::string Filename; - Textures::TextureHandle Handle; - Specifications::TextureSpecification TextureSpec; - }; - - struct TextureUploadRequest - { - size_t BufferSize = 0; - Textures::TextureHandle Handle = {}; - Specifications::TextureSpecification TextureSpec = {}; - std::vector Buffer = {}; - }; - - struct AsyncResourceLoader; - struct GraphicRenderer + struct GraphicRenderer : public IRenderer { GraphicRenderer(); ~GraphicRenderer(); - cstring FrameDepthRenderTargetName = "g_frame_depth_render_target"; - cstring FrameColorRenderTargetName = "g_frame_color_render_target"; - - cstring SceneCameraBufferName = "SceneCamera"; - cstring VertexBufferName = "VertexStorageBuffer"; - cstring IndexBufferName = "IndexStorageBuffer"; - cstring TransformBufferName = "TransformStorageBuffer"; - cstring RenderDataBufferName = "RenderDataStorageBuffer"; - cstring MaterialBufferName = "MaterialStorageBuffer"; - - const size_t DefaultBufferSize = ZMega(10); - - Hardwares::UniformBufferSetHandle SceneCameraBufferHandle = {}; - Textures::TextureHandle FrameColorRenderTarget = {}; - Textures::TextureHandle FrameDepthRenderTarget = {}; - - Scenes::SceneDataPtr RenderSceneData = nullptr; - - Hardwares::VulkanDevicePtr Device = nullptr; - Renderers::ImGUIRendererPtr ImguiRenderer = nullptr; - ZRawPtr(Renderers::RenderGraph) RenderGraph = nullptr; - ZRawPtr(Renderers::AsyncResourceLoader) AsyncLoader = nullptr; - Helpers::ThreadSafeQueue EnqueuedResizeRequests = {}; - - void Initialize(Hardwares::VulkanDevicePtr device); - void Deinitialize(); - void DrawScene(Hardwares::CommandBufferPtr const cb, Cameras::Camera* const camera); - Textures::TextureHandle GetFrameOutput(); - }; - - struct AsyncResourceLoader - { - GraphicRenderer* Renderer = nullptr; - - void Initialize(GraphicRenderer* renderer); - void Run(); - void Shutdown(); + cstring VertexBufferName = "VertexStorageBuffer"; + cstring IndexBufferName = "IndexStorageBuffer"; + cstring TransformBufferName = "TransformStorageBuffer"; + cstring RenderDataBufferName = "RenderDataStorageBuffer"; + cstring MaterialBufferName = "MaterialStorageBuffer"; - Textures::TextureHandle LoadTextureFile(std::string_view filename); + Textures::TextureHandle FrameColorRenderTarget = {}; + Textures::TextureHandle FrameDepthRenderTarget = {}; - private: - std::atomic_bool m_cancellation_token{false}; - std::mutex m_mutex; - std::mutex m_mutex_2; - std::condition_variable m_cond; - Hardwares::CommandBufferManager m_buffer_manager{}; - Helpers::ThreadSafeQueue m_update_texture_request; - Helpers::ThreadSafeQueue m_file_requests; - Helpers::ThreadSafeQueue m_upload_requests; + void Initialize(Hardwares::VulkanDevicePtr device) override; + void Deinitialize() override; + void DrawScene(Hardwares::CommandBufferPtr const cb, Cameras::CameraPtr const camera); + Textures::TextureHandle GetFrameOutput(); }; + ZDEFINE_PTR(GraphicRenderer); } // namespace ZEngine::Rendering::Renderers diff --git a/ZEngine/ZEngine/Rendering/Renderers/IRenderer.h b/ZEngine/ZEngine/Rendering/Renderers/IRenderer.h new file mode 100644 index 00000000..5914c062 --- /dev/null +++ b/ZEngine/ZEngine/Rendering/Renderers/IRenderer.h @@ -0,0 +1,25 @@ +#pragma once +#include + +namespace ZEngine::Rendering::Renderers +{ + struct RendererResourceName + { + inline static cstring FrameDepthRenderTargetName = "g_frame_depth_render_target"; + inline static cstring FrameColorRenderTargetName = "g_frame_color_render_target"; + + inline static cstring SceneCameraBufferName = "SceneCamera"; + }; + + struct IRenderer + { + Hardwares::VulkanDevicePtr Device = nullptr; + Renderers::RenderGraphPtr RenderGraph = nullptr; + Scenes::SceneDataPtr RenderSceneData = nullptr; + + const size_t DefaultBufferSize = ZMega(10); + + virtual void Initialize(Hardwares::VulkanDevicePtr device) = 0; + virtual void Deinitialize() = 0; + }; +} // namespace ZEngine::Rendering::Renderers \ No newline at end of file diff --git a/ZEngine/ZEngine/Rendering/Renderers/ImGUIRenderer.cpp b/ZEngine/ZEngine/Rendering/Renderers/ImGUIRenderer.cpp index ad419ab3..7b6eadd1 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/ImGUIRenderer.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/ImGUIRenderer.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -15,10 +14,12 @@ using namespace ZEngine::Core::Containers; namespace ZEngine::Rendering::Renderers { - void ImGUIRenderer::Initialize(Hardwares::VulkanDevicePtr device, RenderPasses::RenderPassBuilder* pass_builder) + void ImGUIRenderer::Initialize(Hardwares::VulkanDevicePtr device) { - Device = device; - auto current_window = Device->CurrentWindow->GetNativeWindow(); + Device = device; + RenderGraph = ZPushStructCtorArgs(Device->Arena, Renderers::RenderGraph); + + RenderGraph->Initialize(Device); IMGUI_CHECKVERSION(); ImGui::CreateContext(); @@ -51,6 +52,8 @@ namespace ZEngine::Rendering::Renderers io.FontDefault = io.Fonts->AddFontFromFileTTF("Settings/Fonts/OpenSans/OpenSans-Regular.ttf", 17.f); + auto current_window = Device->CurrentWindow->GetNativeWindow(); + ImGui_ImplGlfw_InitForVulkan(reinterpret_cast(current_window), false); m_vertex_buffer_handle = Device->CreateVertexBufferSet(); @@ -64,6 +67,7 @@ namespace ZEngine::Rendering::Renderers idx_buffer_set->At(i)->Allocate(ZMega(5), "ImguiIndexBuffer"); } + auto pass_builder = RenderGraph->RenderPassBuilder; pass_builder->SetName("Imgui Pass") .SetPipelineName("Imgui-Pipeline") .EnablePipelineBlending(true) @@ -224,7 +228,7 @@ namespace ZEngine::Rendering::Renderers ImGuizmo::BeginFrame(); } - void ImGUIRenderer::DrawFrame(uint32_t frame_index, Hardwares::CommandBuffer* const command_buffer) + void ImGUIRenderer::DrawFrame(Hardwares::CommandBufferPtr const command_buffer) { ImGui::Render(); ImDrawData* draw_data = ImGui::GetDrawData(); @@ -276,21 +280,25 @@ namespace ZEngine::Rendering::Renderers index_data_ptr += cmd_list->IdxBuffer.Size; } - auto vertex_buffer = Device->VertexBufferSetManager.Access(m_vertex_buffer_handle); - auto index_buffer = Device->IndexBufferSetManager.Access(m_index_buffer_handle); + auto vtx_data_view = ArrayView{vertex_data}; + auto idx_data_view = ArrayView{index_data}; + + auto vertex_buffer_set = Device->VertexBufferSetManager.Access(m_vertex_buffer_handle); + auto index_buffer_set = Device->IndexBufferSetManager.Access(m_index_buffer_handle); + + auto vertex_buffer = vertex_buffer_set->At(Device->CurrentFrameIndex); + auto index_buffer = index_buffer_set->At(Device->CurrentFrameIndex); - auto vtx_data_view = ArrayView{vertex_data}; - auto idx_data_view = ArrayView{index_data}; - vertex_buffer->At(frame_index)->Write(vtx_data_view); - index_buffer->At(frame_index)->Write(idx_data_view); + vertex_buffer->Write(vtx_data_view); + index_buffer->Write(idx_data_view); ZReleaseScratch(scratch); auto current_framebuffer = Device->SwapchainFramebuffers[Device->CurrentFrameIndex]; command_buffer->BeginRenderPass(m_ui_pass, current_framebuffer); - command_buffer->BindVertexBuffer(*vertex_buffer->At(frame_index)); - command_buffer->BindIndexBuffer(*index_buffer->At(frame_index), sizeof(ImDrawIdx) == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); + command_buffer->BindVertexBuffer(*vertex_buffer); + command_buffer->BindIndexBuffer(*index_buffer, sizeof(ImDrawIdx) == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); // Setup scale and translation: // Our visible imgui space lies from draw_data->DisplayPps (top left) to @@ -341,7 +349,7 @@ namespace ZEngine::Rendering::Renderers pc_data.TextureId = (uint32_t) (intptr_t) pcmd->TextureId; command_buffer->PushConstants(VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstantData), &pc_data); - command_buffer->BindDescriptorSets(frame_index); + command_buffer->BindDescriptorSets(Device->CurrentFrameIndex); command_buffer->DrawIndexed(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); } } diff --git a/ZEngine/ZEngine/Rendering/Renderers/ImGUIRenderer.h b/ZEngine/ZEngine/Rendering/Renderers/ImGUIRenderer.h index 9bd940b0..0909111d 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/ImGUIRenderer.h +++ b/ZEngine/ZEngine/Rendering/Renderers/ImGUIRenderer.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include #include @@ -12,18 +12,15 @@ namespace ZEngine::Rendering::Renderers uint32_t TextureId = 0xFFFFFFFFu; }; - struct GraphicRenderer; - struct ImGUIRenderer + struct ImGUIRenderer : public IRenderer { - Hardwares::VulkanDevicePtr Device = nullptr; + void Initialize(Hardwares::VulkanDevicePtr device) override; + void Deinitialize() override; - void Initialize(Hardwares::VulkanDevicePtr device, RenderPasses::RenderPassBuilder* pass_builder); - void Deinitialize(); + void StyleDarkTheme(); - void StyleDarkTheme(); - - void NewFrame(); - void DrawFrame(uint32_t frame_index, Hardwares::CommandBuffer* const command_buffer); + void NewFrame(); + void DrawFrame(Hardwares::CommandBuffer* const command_buffer); private: Hardwares::VertexBufferSetHandle m_vertex_buffer_handle; diff --git a/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.cpp b/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.cpp index 84e37e36..5c76facf 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.cpp @@ -1,148 +1,56 @@ #include -#include -#include +#include +#include using namespace ZEngine::Core::Containers; - using namespace ZEngine::Helpers; namespace ZEngine::Rendering::Renderers { - RenderGraphResource& RenderGraphBuilder::AttachBuffer(const char* name, const Hardwares::StorageBufferSetHandle& buffer) - { - m_graph.m_resource_map[name].Name = name; - m_graph.m_resource_map[name].Type = RenderGraphResourceType::BUFFER_SET; - m_graph.m_resource_map[name].ResourceInfo.StorageBufferSetHandle = buffer; - m_graph.m_resource_map[name].ResourceInfo.External = true; - return m_graph.m_resource_map[name]; - } - - RenderGraphResource& RenderGraphBuilder::AttachBuffer(const char* name, const Hardwares::UniformBufferSetHandle& buffer) - { - m_graph.m_resource_map[name].Name = name; - m_graph.m_resource_map[name].Type = RenderGraphResourceType::BUFFER_SET; - m_graph.m_resource_map[name].ResourceInfo.UniformBufferSetHandle = buffer; - m_graph.m_resource_map[name].ResourceInfo.External = true; - return m_graph.m_resource_map[name]; - } - - RenderGraphResource& RenderGraphBuilder::AttachTexture(const char* name, const Textures::TextureHandle& handle) - { - auto texture = m_graph.Renderer->Device->GlobalTextures.Access(handle); - m_graph.m_resource_map[name].Name = name; - m_graph.m_resource_map[name].Type = RenderGraphResourceType::TEXTURE; - m_graph.m_resource_map[name].ResourceInfo.TextureHandle = handle; - m_graph.m_resource_map[name].ResourceInfo.TextureSpec = texture->Specification; - m_graph.m_resource_map[name].ResourceInfo.External = true; - return m_graph.m_resource_map[name]; - } - - RenderGraphResource& RenderGraphBuilder::AttachRenderTarget(const char* name, const Textures::TextureHandle& handle) - { - auto texture = m_graph.Renderer->Device->GlobalTextures.Access(handle); - m_graph.m_resource_map[name].Name = name; - m_graph.m_resource_map[name].Type = RenderGraphResourceType::ATTACHMENT; - m_graph.m_resource_map[name].ResourceInfo.TextureHandle = handle; - m_graph.m_resource_map[name].ResourceInfo.TextureSpec = texture->Specification; - m_graph.m_resource_map[name].ResourceInfo.External = true; - return m_graph.m_resource_map[name]; - } - - RenderGraphResource& RenderGraphBuilder::CreateTexture(const char* name, const Specifications::TextureSpecification& spec) - { - m_graph.m_resource_map[name].Name = name; - m_graph.m_resource_map[name].Type = RenderGraphResourceType::TEXTURE; - m_graph.m_resource_map[name].ResourceInfo.TextureSpec = spec; - return m_graph.m_resource_map[name]; - } - - RenderGraphResource& RenderGraphBuilder::CreateTexture(const char* name, const char* filename) - { - m_graph.m_resource_map[name].Name = name; - m_graph.m_resource_map[name].Type = RenderGraphResourceType::TEXTURE; - m_graph.m_resource_map[name].ResourceInfo.TextureHandle = m_graph.Renderer->AsyncLoader->LoadTextureFile(filename); - return m_graph.m_resource_map[name]; - } - - RenderGraphResource& RenderGraphBuilder::CreateRenderTarget(const char* name, const Specifications::TextureSpecification& spec) - { - m_graph.m_resource_map[name].Name = name; - m_graph.m_resource_map[name].Type = RenderGraphResourceType::ATTACHMENT; - m_graph.m_resource_map[name].ResourceInfo.TextureSpec = spec; - return m_graph.m_resource_map[name]; - } - - void RenderGraphBuilder::CreateRenderPassNode(const RenderGraphRenderPassCreation& creation) - { - m_graph.m_node[creation.Name].Creation = creation; - for (const auto& output : m_graph.m_node.at(creation.Name).Creation.Outputs) - { - if (output.Type == RenderGraphResourceType::ATTACHMENT) - { - RenderGraphResource& resource = m_graph.m_resource_map[output.Name]; - resource.ProducerNodeName = creation.Name; - } - } - } - - RenderGraphResource& RenderGraphBuilder::CreateBufferSet(const char* name, BufferSetCreationType type) + void RenderGraph::Initialize(Hardwares::VulkanDevicePtr device, Scenes::SceneDataPtr data) { - m_graph.m_resource_map[name].Name = name; - m_graph.m_resource_map[name].Type = RenderGraphResourceType::BUFFER_SET; - switch (type) - { - case BufferSetCreationType::INDIRECT: - m_graph.m_resource_map[name].ResourceInfo.IndirectBufferSetHandle = m_graph.Renderer->Device->CreateIndirectBufferSet(); - break; - case BufferSetCreationType::UNIFORM: - m_graph.m_resource_map[name].ResourceInfo.UniformBufferSetHandle = m_graph.Renderer->Device->CreateUniformBufferSet(); - break; - case BufferSetCreationType::STORAGE: - m_graph.m_resource_map[name].ResourceInfo.StorageBufferSetHandle = m_graph.Renderer->Device->CreateStorageBufferSet(); - break; - case BufferSetCreationType::INDEX: - m_graph.m_resource_map[name].ResourceInfo.IndexBufferSetHandle = m_graph.Renderer->Device->CreateIndexBufferSet(); - break; - case BufferSetCreationType::VERTEX: - m_graph.m_resource_map[name].ResourceInfo.VertexBufferSetHandle = m_graph.Renderer->Device->CreateVertexBufferSet(); - break; - } - m_graph.m_resource_map[name].ResourceInfo.External = false; - return m_graph.m_resource_map[name]; + Device = device; + SceneData = data; + ResourceBuilder = ZPushStruct(Device->Arena, RenderGraphResourceBuilder); + ResourceInspector = ZPushStruct(Device->Arena, RenderGraphResourceInspector); + RenderPassBuilder = ZPushStructCtorArgs(Device->Arena, RenderPasses::RenderPassBuilder); + + SortedNodesMap.init(Device->Arena, 16); + NodeMap.init(Device->Arena); + ResourceMap.init(Device->Arena); + RenderPassBuilder->Initialize(Device->Arena); + + ResourceBuilder->Initialize(this); + ResourceInspector->Initialize(this); } - void RenderGraph::Initialize(Core::Memory::ArenaAllocator* arena, GraphicRenderer* renderer) + void RenderGraph::AddCallbackPass(cstring pass_name, IRenderGraphCallbackPass* const pass_callback, bool enabled) { - Renderer = renderer; - Builder = ZPushStructCtorArgs(arena, RenderGraphBuilder, *this); - RenderPassBuilder = ZPushStructCtorArgs(arena, RenderPasses::RenderPassBuilder); - RenderPassBuilder->Initialize(arena); - m_sorted_nodes.init(arena, 7); - m_node.init(arena); - m_resource_map.init(arena); + NodeMap[pass_name].Enabled = enabled; + NodeMap[pass_name].CallbackPass = pass_callback; } void RenderGraph::Setup() { - for (auto [name, node] : m_node) + for (auto [name, node] : NodeMap) { - node.EdgeNodes.init(Renderer->Device->Arena, 5); - node.CallbackPass->Setup(name, this); + node.EdgeNodes.init(Device->Arena, 5); + node.CallbackPass->Setup(Device, name, ResourceBuilder, ResourceInspector); } } void RenderGraph::Compile() { - for (auto pass : m_node) + for (auto pass : NodeMap) { for (uint32_t i = 0; i < pass.second.Creation.Inputs.size(); ++i) { - if (m_resource_map.contains(pass.second.Creation.Inputs[i].Name)) + if (ResourceMap.contains(pass.second.Creation.Inputs[i].Name)) { - RenderGraphResource& resource = m_resource_map[pass.second.Creation.Inputs[i].Name]; - if (m_node.contains(resource.ProducerNodeName)) + RenderGraphResource& resource = ResourceMap[pass.second.Creation.Inputs[i].Name]; + if (NodeMap.contains(resource.ProducerNodeName)) { - RenderGraphNode& producer_node = m_node[resource.ProducerNodeName]; + RenderGraphNode& producer_node = NodeMap[resource.ProducerNodeName]; producer_node.EdgeNodes.push(pass.first); } } @@ -154,17 +62,17 @@ namespace ZEngine::Rendering::Renderers /* * Topological Sorting */ - auto scratch = ZGetScratch(Renderer->Device->Arena); + auto scratch = ZGetScratch(Device->Arena); - Array sorted_nodes = {}; - HashMap visited_nodes = {}; - Array stack = {}; + Array sorted_nodes = {}; + HashMap visited_nodes = {}; + Array stack = {}; sorted_nodes.init(scratch.Arena, 6); stack.init(scratch.Arena, 6); visited_nodes.init(scratch.Arena); - for (auto node : m_node) + for (auto node : NodeMap) { stack.push(node.first); while (!stack.empty()) @@ -185,7 +93,7 @@ namespace ZEngine::Rendering::Renderers } visited_nodes[node_name] = 1; - auto& graph_node = m_node[node_name]; + auto& graph_node = NodeMap[node_name]; if (graph_node.EdgeNodes.empty()) { continue; @@ -205,7 +113,7 @@ namespace ZEngine::Rendering::Renderers auto end = std::prev(sorted_nodes.end()); while (end >= begin) { - m_sorted_nodes.push(*end); + SortedNodesMap.push(*end); end = std::prev(end); } @@ -214,15 +122,15 @@ namespace ZEngine::Rendering::Renderers /* * Reading sorting graph node in reverse order and Create resource and RenderPass Node */ - for (const char* node_name : m_sorted_nodes) + for (cstring node_name : SortedNodesMap) { - auto& node = m_node[node_name]; + auto& node = NodeMap[node_name]; RenderPassBuilder->SetName(node.Creation.Name); for (auto& output : node.Creation.Outputs) { - auto& resource = m_resource_map[output.Name]; + auto& resource = ResourceMap[output.Name]; if (resource.ResourceInfo.External) { @@ -233,7 +141,7 @@ namespace ZEngine::Rendering::Renderers if (output.Type == RenderGraphResourceType::ATTACHMENT) { resource.ResourceInfo.TextureSpec.PerformTransition = false; - resource.ResourceInfo.TextureHandle = Renderer->Device->CreateTexture(resource.ResourceInfo.TextureSpec); + resource.ResourceInfo.TextureHandle = Device->CreateTexture(resource.ResourceInfo.TextureSpec); RenderPassBuilder->UseRenderTarget(resource.ResourceInfo.TextureHandle); } @@ -241,7 +149,7 @@ namespace ZEngine::Rendering::Renderers for (auto& input : node.Creation.Inputs) { - auto& resource = m_resource_map[input.Name]; + auto& resource = ResourceMap[input.Name]; if (input.Type == RenderGraphResourceType::ATTACHMENT) { @@ -253,27 +161,27 @@ namespace ZEngine::Rendering::Renderers } } - node.CallbackPass->Compile(&(node.Handle), this); + node.CallbackPass->Compile(Device, SceneData, RenderPassBuilder, ResourceInspector, &(node.Handle)); } - for (const char* name : m_sorted_nodes) + for (cstring name : SortedNodesMap) { - auto& node = m_node[name]; + auto& node = NodeMap[name]; Specifications::FrameBufferSpecificationVNext framebuffer_spec = {.Width = node.Handle->RenderAreaWidth, .Height = node.Handle->RenderAreaHeight, .RenderTargets = node.Handle->RenderTargets, .Attachment = node.Handle->Attachment}; - node.Framebuffer = ZPushStructCtorArgs(Renderer->Device->Arena, Buffers::FramebufferVNext, Renderer->Device, framebuffer_spec); + node.Framebuffer = ZPushStructCtorArgs(Device->Arena, Buffers::FramebufferVNext, Device, framebuffer_spec); } } - void RenderGraph::Execute(Hardwares::CommandBuffer* const command_buffer, Rendering::Scenes::SceneData* const scene) + void RenderGraph::Execute(Hardwares::CommandBufferPtr const command_buffer) { ZENGINE_VALIDATE_ASSERT(command_buffer, "Command Buffer can't be null") command_buffer->ClearColor(0.1f, 0.1f, 0.1f, 1.0f); command_buffer->ClearDepth(1.0f, 0); - for (auto& node_name : m_sorted_nodes) + for (auto& node_name : SortedNodesMap) { - auto& node = m_node[node_name]; + auto& node = NodeMap[node_name]; if (!node.Enabled) { @@ -284,15 +192,15 @@ namespace ZEngine::Rendering::Renderers { if (input.Type == RenderGraphResourceType::TEXTURE) { - auto& resource = m_resource_map[input.Name]; + auto& resource = ResourceMap[input.Name]; /* * The input texture can from an attachment that should read as Shader Sampler2D data * So we need ensure the right config for transition */ bool is_resource_attachment = resource.Type == RenderGraphResourceType::ATTACHMENT; - auto texture = Renderer->Device->GlobalTextures.Access(resource.ResourceInfo.TextureHandle); - auto img_buf = Renderer->Device->Image2DBufferManager.Access(texture->BufferHandle); + auto texture = Device->GlobalTextures.Access(resource.ResourceInfo.TextureHandle); + auto img_buf = Device->Image2DBufferManager.Access(texture->BufferHandle); auto& buffer = img_buf->GetBuffer(); Specifications::ImageMemoryBarrierSpecification barrier_spec = {}; @@ -319,11 +227,11 @@ namespace ZEngine::Rendering::Renderers continue; } - auto& resource = m_resource_map[output.Name]; + auto& resource = ResourceMap[output.Name]; ZENGINE_VALIDATE_ASSERT(resource.Type == RenderGraphResourceType::ATTACHMENT, "RenderPass Output should be an Attachment") - auto texture = Renderer->Device->GlobalTextures.Access(resource.ResourceInfo.TextureHandle); - auto img_buf = Renderer->Device->Image2DBufferManager.Access(texture->BufferHandle); + auto texture = Device->GlobalTextures.Access(resource.ResourceInfo.TextureHandle); + auto img_buf = Device->Image2DBufferManager.Access(texture->BufferHandle); auto& buffer = img_buf->GetBuffer(); Specifications::ImageMemoryBarrierSpecification barrier_spec = {}; @@ -364,16 +272,15 @@ namespace ZEngine::Rendering::Renderers } } - node.CallbackPass->Execute(scene, node.Handle, command_buffer, this); - node.CallbackPass->Render(scene, node.Handle, node.Framebuffer, command_buffer, this); + node.CallbackPass->Execute(Device, SceneData, node.Handle, node.Framebuffer, command_buffer); } } void RenderGraph::Resize(uint32_t width, uint32_t height) { - for (auto& node_name : m_sorted_nodes) + for (auto& node_name : SortedNodesMap) { - auto& node = m_node[node_name]; + auto& node = NodeMap[node_name]; auto& pass_spec = node.Handle->Specification; @@ -383,34 +290,34 @@ namespace ZEngine::Rendering::Renderers for (auto& output : node.Creation.Outputs) { - auto& resource = m_resource_map[output.Name]; + auto& resource = ResourceMap[output.Name]; if (output.Type == RenderGraphResourceType::REFERENCE) { continue; } - auto temp_handle = Renderer->Device->GlobalTextures.Create(); - auto texture_to_dispose = Renderer->Device->GlobalTextures.Access(resource.ResourceInfo.TextureHandle); - Renderer->Device->GlobalTextures.Update(temp_handle, *texture_to_dispose); - Renderer->Device->TextureHandleToDispose.Enqueue(temp_handle); + auto temp_handle = Device->GlobalTextures.Create(); + auto texture_to_dispose = Device->GlobalTextures.Access(resource.ResourceInfo.TextureHandle); + Device->GlobalTextures.Update(temp_handle, *texture_to_dispose); + Device->TextureHandleToDispose.Enqueue(temp_handle); // We invalidate ResourceInfo.TextureHandle, so it can be recycle for another texture allocation - Renderer->Device->GlobalTextures.Remove(resource.ResourceInfo.TextureHandle); + Device->GlobalTextures.Remove(resource.ResourceInfo.TextureHandle); resource.ResourceInfo.TextureSpec.Width = width; resource.ResourceInfo.TextureSpec.Height = height; - resource.ResourceInfo.TextureHandle = Renderer->Device->CreateTexture(resource.ResourceInfo.TextureSpec); + resource.ResourceInfo.TextureHandle = Device->CreateTexture(resource.ResourceInfo.TextureSpec); - if ((output.Name == Renderer->FrameColorRenderTargetName) || (output.Name == Renderer->FrameDepthRenderTargetName)) + if ((output.Name == RendererResourceName::FrameColorRenderTargetName) || (output.Name == RendererResourceName::FrameDepthRenderTargetName)) { - Renderer->Device->TextureHandleToUpdates.Enqueue(resource.ResourceInfo.TextureHandle); + Device->TextureHandleToUpdates.Enqueue(resource.ResourceInfo.TextureHandle); } pass_spec.ExternalOutputs.push(resource.ResourceInfo.TextureHandle); } for (auto& input : node.Creation.Inputs) { - auto& resource = m_resource_map[input.Name]; + auto& resource = ResourceMap[input.Name]; if (resource.Type == RenderGraphResourceType::ATTACHMENT && input.Type == RenderGraphResourceType::ATTACHMENT) { @@ -430,22 +337,22 @@ namespace ZEngine::Rendering::Renderers node.Handle->UpdateInputBinding(); Specifications::FrameBufferSpecificationVNext framebuffer_spec = {.Width = node.Handle->RenderAreaWidth, .Height = node.Handle->RenderAreaHeight, .RenderTargets = node.Handle->RenderTargets, .Attachment = node.Handle->Attachment}; - node.Framebuffer = ZPushStructCtorArgs(Renderer->Device->Arena, Buffers::FramebufferVNext, Renderer->Device, framebuffer_spec); + node.Framebuffer = ZPushStructCtorArgs(Device->Arena, Buffers::FramebufferVNext, Device, framebuffer_spec); } } void RenderGraph::Dispose() { - for (auto& node_name : m_sorted_nodes) + for (auto& node_name : SortedNodesMap) { - auto& node = m_node[node_name]; + auto& node = NodeMap[node_name]; node.Handle->Dispose(); node.Framebuffer->Dispose(); } - for (auto resource : m_resource_map) + for (auto resource : ResourceMap) { - auto& value = m_resource_map[resource.first]; + auto& value = ResourceMap[resource.first]; if (value.ResourceInfo.External) { continue; @@ -453,42 +360,155 @@ namespace ZEngine::Rendering::Renderers if (value.Type == RenderGraphResourceType::ATTACHMENT || value.Type == RenderGraphResourceType::TEXTURE) { - Renderer->Device->GlobalTextures.Remove(value.ResourceInfo.TextureHandle); + Device->GlobalTextures.Remove(value.ResourceInfo.TextureHandle); } else if (value.Type == RenderGraphResourceType::BUFFER_SET) { // We are safe to call Remove(...) even if Handle is invalid - Renderer->Device->StorageBufferSetManager.Remove(value.ResourceInfo.StorageBufferSetHandle); - Renderer->Device->UniformBufferSetManager.Remove(value.ResourceInfo.UniformBufferSetHandle); - Renderer->Device->IndirectBufferSetManager.Remove(value.ResourceInfo.IndirectBufferSetHandle); - Renderer->Device->VertexBufferSetManager.Remove(value.ResourceInfo.VertexBufferSetHandle); - Renderer->Device->IndexBufferSetManager.Remove(value.ResourceInfo.IndexBufferSetHandle); + Device->StorageBufferSetManager.Remove(value.ResourceInfo.StorageBufferSetHandle); + Device->UniformBufferSetManager.Remove(value.ResourceInfo.UniformBufferSetHandle); + Device->IndirectBufferSetManager.Remove(value.ResourceInfo.IndirectBufferSetHandle); + Device->VertexBufferSetManager.Remove(value.ResourceInfo.VertexBufferSetHandle); + Device->IndexBufferSetManager.Remove(value.ResourceInfo.IndexBufferSetHandle); } } } - RenderGraphResource& RenderGraph::GetResource(const char* name) + RenderGraphResource& RenderGraphResourceBuilder::AttachBuffer(cstring name, const Hardwares::StorageBufferSetHandle& buffer) + { + Graph->ResourceMap[name].Name = name; + Graph->ResourceMap[name].Type = RenderGraphResourceType::BUFFER_SET; + Graph->ResourceMap[name].ResourceInfo.StorageBufferSetHandle = buffer; + Graph->ResourceMap[name].ResourceInfo.External = true; + return Graph->ResourceMap[name]; + } + + RenderGraphResource& RenderGraphResourceBuilder::AttachBuffer(cstring name, const Hardwares::UniformBufferSetHandle& buffer) + { + Graph->ResourceMap[name].Name = name; + Graph->ResourceMap[name].Type = RenderGraphResourceType::BUFFER_SET; + Graph->ResourceMap[name].ResourceInfo.UniformBufferSetHandle = buffer; + Graph->ResourceMap[name].ResourceInfo.External = true; + return Graph->ResourceMap[name]; + } + + RenderGraphResource& RenderGraphResourceBuilder::AttachTexture(cstring name, const Textures::TextureHandle& handle) { - if (!m_resource_map.contains(name)) + auto texture = Graph->Device->GlobalTextures.Access(handle); + Graph->ResourceMap[name].Name = name; + Graph->ResourceMap[name].Type = RenderGraphResourceType::TEXTURE; + Graph->ResourceMap[name].ResourceInfo.TextureHandle = handle; + Graph->ResourceMap[name].ResourceInfo.TextureSpec = texture->Specification; + Graph->ResourceMap[name].ResourceInfo.External = true; + return Graph->ResourceMap[name]; + } + + RenderGraphResource& RenderGraphResourceBuilder::AttachRenderTarget(cstring name, const Textures::TextureHandle& handle) + { + auto texture = Graph->Device->GlobalTextures.Access(handle); + Graph->ResourceMap[name].Name = name; + Graph->ResourceMap[name].Type = RenderGraphResourceType::ATTACHMENT; + Graph->ResourceMap[name].ResourceInfo.TextureHandle = handle; + Graph->ResourceMap[name].ResourceInfo.TextureSpec = texture->Specification; + Graph->ResourceMap[name].ResourceInfo.External = true; + return Graph->ResourceMap[name]; + } + + void RenderGraphResourceBuilder::Initialize(RenderGraphPtr graph) + { + Graph = graph; + } + + RenderGraphResource& RenderGraphResourceBuilder::CreateTexture(cstring name, const Specifications::TextureSpecification& spec) + { + Graph->ResourceMap[name].Name = name; + Graph->ResourceMap[name].Type = RenderGraphResourceType::TEXTURE; + Graph->ResourceMap[name].ResourceInfo.TextureSpec = spec; + return Graph->ResourceMap[name]; + } + + RenderGraphResource& RenderGraphResourceBuilder::CreateTexture(cstring name, cstring filename) + { + Graph->ResourceMap[name].Name = name; + Graph->ResourceMap[name].Type = RenderGraphResourceType::TEXTURE; + Graph->ResourceMap[name].ResourceInfo.TextureHandle = Graph->Device->AsyncResLoader->LoadTextureFile(filename); + return Graph->ResourceMap[name]; + } + + RenderGraphResource& RenderGraphResourceBuilder::CreateRenderTarget(cstring name, const Specifications::TextureSpecification& spec) + { + Graph->ResourceMap[name].Name = name; + Graph->ResourceMap[name].Type = RenderGraphResourceType::ATTACHMENT; + Graph->ResourceMap[name].ResourceInfo.TextureSpec = spec; + return Graph->ResourceMap[name]; + } + + void RenderGraphResourceBuilder::CreateRenderPassNode(const RenderGraphRenderPassCreation& creation) + { + Graph->NodeMap[creation.Name].Creation = creation; + for (const auto& output : Graph->NodeMap.at(creation.Name).Creation.Outputs) { - m_resource_map[name].Name = name; + if (output.Type == RenderGraphResourceType::ATTACHMENT) + { + RenderGraphResource& resource = Graph->ResourceMap[output.Name]; + resource.ProducerNodeName = creation.Name; + } } - return m_resource_map[name]; } - Textures::TextureHandle RenderGraph::GetRenderTarget(const char* name) + RenderGraphResource& RenderGraphResourceBuilder::CreateBufferSet(cstring name, BufferSetCreationType type) + { + Graph->ResourceMap[name].Name = name; + Graph->ResourceMap[name].Type = RenderGraphResourceType::BUFFER_SET; + switch (type) + { + case BufferSetCreationType::INDIRECT: + Graph->ResourceMap[name].ResourceInfo.IndirectBufferSetHandle = Graph->Device->CreateIndirectBufferSet(); + break; + case BufferSetCreationType::UNIFORM: + Graph->ResourceMap[name].ResourceInfo.UniformBufferSetHandle = Graph->Device->CreateUniformBufferSet(); + break; + case BufferSetCreationType::STORAGE: + Graph->ResourceMap[name].ResourceInfo.StorageBufferSetHandle = Graph->Device->CreateStorageBufferSet(); + break; + case BufferSetCreationType::INDEX: + Graph->ResourceMap[name].ResourceInfo.IndexBufferSetHandle = Graph->Device->CreateIndexBufferSet(); + break; + case BufferSetCreationType::VERTEX: + Graph->ResourceMap[name].ResourceInfo.VertexBufferSetHandle = Graph->Device->CreateVertexBufferSet(); + break; + } + Graph->ResourceMap[name].ResourceInfo.External = false; + return Graph->ResourceMap[name]; + } + + void RenderGraphResourceInspector::Initialize(RenderGraphPtr graph) + { + Graph = graph; + } + + RenderGraphResource& RenderGraphResourceInspector::GetResource(cstring name) + { + if (!Graph->ResourceMap.contains(name)) + { + Graph->ResourceMap[name].Name = name; + } + return Graph->ResourceMap[name]; + } + + Textures::TextureHandle RenderGraphResourceInspector::GetRenderTarget(cstring name) { Textures::TextureHandle output = {}; - if (!m_resource_map.contains(name)) + if (!Graph->ResourceMap.contains(name)) { - m_resource_map[name].Name = name; + Graph->ResourceMap[name].Name = name; } - if (m_resource_map[name].Type != RenderGraphResourceType::ATTACHMENT) + if (Graph->ResourceMap[name].Type != RenderGraphResourceType::ATTACHMENT) { ZENGINE_CORE_WARN("{} isn't a valid Attachement Resource", name) } - auto handle = m_resource_map[name].ResourceInfo.TextureHandle; + auto handle = Graph->ResourceMap[name].ResourceInfo.TextureHandle; if (handle.Valid()) { output = handle; @@ -496,20 +516,20 @@ namespace ZEngine::Rendering::Renderers return output; } - Textures::TextureHandle RenderGraph::GetTexture(const char* name) + Textures::TextureHandle RenderGraphResourceInspector::GetTexture(cstring name) { Textures::TextureHandle output = {}; - if (!m_resource_map.contains(name)) + if (!Graph->ResourceMap.contains(name)) { - m_resource_map[name].Name = name; + Graph->ResourceMap[name].Name = name; } - if (m_resource_map[name].Type != RenderGraphResourceType::TEXTURE) + if (Graph->ResourceMap[name].Type != RenderGraphResourceType::TEXTURE) { ZENGINE_CORE_WARN("{} isn't a valid Texture Resource", name) } - auto handle = m_resource_map[name].ResourceInfo.TextureHandle; + auto handle = Graph->ResourceMap[name].ResourceInfo.TextureHandle; if (handle.Valid()) { output = handle; @@ -517,60 +537,54 @@ namespace ZEngine::Rendering::Renderers return output; } - Hardwares::StorageBufferSetHandle RenderGraph::GetStorageBufferSet(const char* name) + Hardwares::StorageBufferSetHandle RenderGraphResourceInspector::GetStorageBufferSet(cstring name) { - if (!m_resource_map.contains(name)) + if (!Graph->ResourceMap.contains(name)) { - m_resource_map[name].Name = name; + Graph->ResourceMap[name].Name = name; } - return m_resource_map[name].ResourceInfo.StorageBufferSetHandle; + return Graph->ResourceMap[name].ResourceInfo.StorageBufferSetHandle; } - Hardwares::VertexBufferSetHandle RenderGraph::GetVertexBufferSet(const char* name) + Hardwares::VertexBufferSetHandle RenderGraphResourceInspector::GetVertexBufferSet(cstring name) { - if (!m_resource_map.contains(name)) + if (!Graph->ResourceMap.contains(name)) { - m_resource_map[name].Name = name; + Graph->ResourceMap[name].Name = name; } - return m_resource_map[name].ResourceInfo.VertexBufferSetHandle; + return Graph->ResourceMap[name].ResourceInfo.VertexBufferSetHandle; } - Hardwares::IndexBufferSetHandle RenderGraph::GetIndexBufferSet(const char* name) + Hardwares::IndexBufferSetHandle RenderGraphResourceInspector::GetIndexBufferSet(cstring name) { - if (!m_resource_map.contains(name)) + if (!Graph->ResourceMap.contains(name)) { - m_resource_map[name].Name = name; + Graph->ResourceMap[name].Name = name; } - return m_resource_map[name].ResourceInfo.IndexBufferSetHandle; + return Graph->ResourceMap[name].ResourceInfo.IndexBufferSetHandle; } - Hardwares::UniformBufferSetHandle RenderGraph::GetBufferUniformSet(const char* name) + Hardwares::UniformBufferSetHandle RenderGraphResourceInspector::GetBufferUniformSet(cstring name) { - if (!m_resource_map.contains(name)) + if (!Graph->ResourceMap.contains(name)) { - m_resource_map[name].Name = name; + Graph->ResourceMap[name].Name = name; } - return m_resource_map[name].ResourceInfo.UniformBufferSetHandle; + return Graph->ResourceMap[name].ResourceInfo.UniformBufferSetHandle; } - Hardwares::IndirectBufferSetHandle RenderGraph::GetIndirectBufferSet(const char* name) + Hardwares::IndirectBufferSetHandle RenderGraphResourceInspector::GetIndirectBufferSet(cstring name) { - if (!m_resource_map.contains(name)) + if (!Graph->ResourceMap.contains(name)) { - m_resource_map[name].Name = name; + Graph->ResourceMap[name].Name = name; } - return m_resource_map[name].ResourceInfo.IndirectBufferSetHandle; - } - - RenderGraphNode& RenderGraph::GetNode(const char* name) - { - ZENGINE_VALIDATE_ASSERT(m_node.contains(name), "Node Pass should be created first") - return m_node[name]; + return Graph->ResourceMap[name].ResourceInfo.IndirectBufferSetHandle; } - void RenderGraph::AddCallbackPass(const char* pass_name, IRenderGraphCallbackPass* const pass_callback, bool enabled) + RenderGraphNode& RenderGraphResourceInspector::GetNode(cstring name) { - m_node[pass_name].Enabled = enabled; - m_node[pass_name].CallbackPass = pass_callback; + ZENGINE_VALIDATE_ASSERT(Graph->NodeMap.contains(name), "Node Pass should be created first") + return Graph->NodeMap[name]; } } // namespace ZEngine::Rendering::Renderers diff --git a/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.h b/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.h index b862da01..e6bba5d8 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.h +++ b/ZEngine/ZEngine/Rendering/Renderers/RenderGraph.h @@ -9,14 +9,19 @@ #include #include #include -#include namespace ZEngine::Rendering::Renderers { - struct GraphicRenderer; - struct RenderGraphBuilder; + struct RenderGraphResourceBuilder; + struct RenderGraphResourceInspector; struct RenderGraphNode; struct RenderGraph; + struct IRenderGraphCallbackPass; + + ZDEFINE_PTR(RenderGraphResourceBuilder); + ZDEFINE_PTR(RenderGraphResourceInspector); + ZDEFINE_PTR(RenderGraph); + ZDEFINE_PTR(IRenderGraphCallbackPass); enum RenderGraphResourceType { @@ -54,97 +59,103 @@ namespace ZEngine::Rendering::Renderers struct RenderGraphResource { - const char* Name; - const char* ProducerNodeName; + cstring Name; + cstring ProducerNodeName; RenderGraphResourceType Type; RenderGraphResourceInfo ResourceInfo; }; struct RenderGraphRenderPassInputOutputInfo { - const char* Name; - const char* BindingInputKeyName; + cstring Name; + cstring BindingInputKeyName; RenderGraphResourceType Type = RenderGraphResourceType::ATTACHMENT; }; struct RenderGraphRenderPassCreation { - const char* Name; + cstring Name; Core::Containers::Array Inputs; Core::Containers::Array Outputs; }; struct IRenderGraphCallbackPass { - virtual void Setup(std::string_view name, RenderGraph* const graph) = 0; - virtual void Compile(RenderPasses::RenderPass** const pass, RenderGraph* const graph) = 0; - virtual void Execute(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) = 0; - virtual void Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) = 0; + virtual void Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) = 0; + virtual void Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) = 0; + virtual void Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) = 0; }; struct RenderGraphNode { - bool Enabled = true; - RenderGraphRenderPassCreation Creation = {}; - Core::Containers::Array EdgeNodes = {}; + bool Enabled = true; + RenderGraphRenderPassCreation Creation = {}; + Core::Containers::Array EdgeNodes = {}; ZRawPtr(RenderPasses::RenderPass) Handle = nullptr; ZRawPtr(Buffers::FramebufferVNext) Framebuffer = nullptr; - ZRawPtr(IRenderGraphCallbackPass) CallbackPass = nullptr; + IRenderGraphCallbackPassPtr CallbackPass = nullptr; }; - class RenderGraph + struct RenderGraph { - public: RenderGraph() {} ~RenderGraph() {} - bool MarkAsDirty = false; - GraphicRenderer* Renderer = nullptr; - RenderGraphBuilder* Builder = nullptr; - RenderPasses::RenderPassBuilder* RenderPassBuilder = nullptr; - - void Initialize(Core::Memory::ArenaAllocator* arena, GraphicRenderer* renderer); - - void Setup(); - void Compile(); - void Execute(Hardwares::CommandBuffer* const command_buffer, Rendering::Scenes::SceneData* const scene_data); - void Resize(uint32_t width, uint32_t height); - void Dispose(); - RenderGraphResource& GetResource(const char*); - Textures::TextureHandle GetRenderTarget(const char*); - Textures::TextureHandle GetTexture(const char*); - Hardwares::StorageBufferSetHandle GetStorageBufferSet(const char*); - Hardwares::VertexBufferSetHandle GetVertexBufferSet(const char*); - Hardwares::IndexBufferSetHandle GetIndexBufferSet(const char*); - Hardwares::UniformBufferSetHandle GetBufferUniformSet(const char*); - Hardwares::IndirectBufferSetHandle GetIndirectBufferSet(const char*); - RenderGraphNode& GetNode(const char*); - void AddCallbackPass(const char* pass_name, IRenderGraphCallbackPass* const pass_callback, bool enabled = true); - - private: - Core::Containers::Array m_sorted_nodes; - Core::Containers::HashMap m_node; - Core::Containers::HashMap m_resource_map; - friend struct RenderGraphBuilder; + Hardwares::VulkanDevicePtr Device = nullptr; + + Core::Containers::Array SortedNodesMap = {}; + Core::Containers::HashMap NodeMap = {}; + Core::Containers::HashMap ResourceMap = {}; + + RenderGraphResourceBuilderPtr ResourceBuilder = nullptr; + RenderGraphResourceInspectorPtr ResourceInspector = nullptr; + RenderPasses::RenderPassBuilder* RenderPassBuilder = nullptr; + + Scenes::SceneDataPtr SceneData = nullptr; + + void Initialize(Hardwares::VulkanDevicePtr device, Scenes::SceneDataPtr data = nullptr); + + void Setup(); + void Compile(); + void Execute(Hardwares::CommandBufferPtr const command_buffer); + void Resize(uint32_t width, uint32_t height); + void Dispose(); + void AddCallbackPass(cstring pass_name, IRenderGraphCallbackPass* const pass_callback, bool enabled = true); }; - struct RenderGraphBuilder + struct RenderGraphResourceInspector { - RenderGraphBuilder(RenderGraph& graph) : m_graph(graph) {} - - RenderGraphResource& CreateTexture(const char* name, const Specifications::TextureSpecification& spec); - RenderGraphResource& CreateTexture(const char* name, const char* filename); - RenderGraphResource& CreateRenderTarget(const char* name, const Specifications::TextureSpecification& spec); - RenderGraphResource& AttachBuffer(const char* name, const Hardwares::StorageBufferSetHandle& buffer); - RenderGraphResource& AttachBuffer(const char* name, const Hardwares::UniformBufferSetHandle& buffer); - RenderGraphResource& AttachTexture(const char* name, const Textures::TextureHandle& texture); - RenderGraphResource& AttachRenderTarget(const char* name, const Textures::TextureHandle& texture); - void CreateRenderPassNode(const RenderGraphRenderPassCreation&); + RenderGraphPtr Graph = nullptr; + + void Initialize(RenderGraphPtr graph); + + RenderGraphResource& GetResource(cstring name); + Textures::TextureHandle GetRenderTarget(cstring name); + Textures::TextureHandle GetTexture(cstring name); + Hardwares::StorageBufferSetHandle GetStorageBufferSet(cstring name); + Hardwares::VertexBufferSetHandle GetVertexBufferSet(cstring name); + Hardwares::IndexBufferSetHandle GetIndexBufferSet(cstring name); + Hardwares::UniformBufferSetHandle GetBufferUniformSet(cstring name); + Hardwares::IndirectBufferSetHandle GetIndirectBufferSet(cstring name); + RenderGraphNode& GetNode(cstring name); + }; + + struct RenderGraphResourceBuilder + { + RenderGraphPtr Graph = nullptr; + + void Initialize(RenderGraphPtr graph); - RenderGraphResource& CreateBuffer(const char* name) = delete; - RenderGraphResource& CreateBufferSet(const char* name, BufferSetCreationType type = BufferSetCreationType::STORAGE); + RenderGraphResource& CreateTexture(cstring name, const Specifications::TextureSpecification& spec); + RenderGraphResource& CreateTexture(cstring name, cstring filename); + RenderGraphResource& CreateRenderTarget(cstring name, const Specifications::TextureSpecification& spec); + RenderGraphResource& AttachBuffer(cstring name, const Hardwares::StorageBufferSetHandle& buffer); + RenderGraphResource& AttachBuffer(cstring name, const Hardwares::UniformBufferSetHandle& buffer); + RenderGraphResource& AttachTexture(cstring name, const Textures::TextureHandle& texture); + RenderGraphResource& AttachRenderTarget(cstring name, const Textures::TextureHandle& texture); + void CreateRenderPassNode(const RenderGraphRenderPassCreation&); - private: - RenderGraph& m_graph; + RenderGraphResource& CreateBuffer(cstring name) = delete; + RenderGraphResource& CreateBufferSet(cstring name, BufferSetCreationType type = BufferSetCreationType::STORAGE); }; } // namespace ZEngine::Rendering::Renderers \ No newline at end of file diff --git a/ZEngine/ZEngine/Rendering/Renderers/RendererPasses.cpp b/ZEngine/ZEngine/Rendering/Renderers/RendererPasses.cpp index 37091bed..7358963e 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/RendererPasses.cpp +++ b/ZEngine/ZEngine/Rendering/Renderers/RendererPasses.cpp @@ -8,369 +8,347 @@ using namespace ZEngine::Core::Containers; namespace ZEngine::Rendering::Renderers { - void InitialPass::Setup(std::string_view name, RenderGraph* const graph) + void InitialPass::Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) { - auto& builder = graph->Builder; - auto& renderer = graph->Renderer; - auto arena = renderer->Device->Arena; + VertexData.init(device->Arena, 3, make_initializer_list(device->Arena, 0.0f, 0.0f, 0.0f)); - m_vertex_data.init(arena, 3, make_initializer_list(arena, 0.0f, 0.0f, 0.0f)); + auto& vb_res = res_builder->CreateBufferSet("initial_vertex_buffer", BufferSetCreationType::VERTEX); + VBHandle = vb_res.ResourceInfo.VertexBufferSetHandle; - auto& vb_res = builder->CreateBufferSet("initial_vertex_buffer", BufferSetCreationType::VERTEX); - m_vb_handle = vb_res.ResourceInfo.VertexBufferSetHandle; + auto vb_view = ArrayView{VertexData}; - auto buffer_set = renderer->Device->VertexBufferSetManager.Access(m_vb_handle); - for (unsigned i = 0; i < renderer->Device->SwapchainImageCount; ++i) + auto buffer_set = device->VertexBufferSetManager.Access(VBHandle); + for (unsigned i = 0; i < device->SwapchainImageCount; ++i) { - buffer_set->At(i)->Allocate(ZKilo(8), "initial_vertex_buffer"); + auto buffer = buffer_set->At(i); + buffer->Allocate(vb_view.size_bytes(), "initial_vertex_buffer"); + buffer->Write(vb_view); } - RenderGraphRenderPassCreation pass_node = {.Name = name.data()}; + RenderGraphRenderPassCreation pass_node = {.Name = name}; - pass_node.Inputs.init(arena, 1); - pass_node.Outputs.init(arena, 2); - pass_node.Outputs.push(RenderGraphRenderPassInputOutputInfo{.Name = renderer->FrameDepthRenderTargetName}); - pass_node.Outputs.push(RenderGraphRenderPassInputOutputInfo{.Name = renderer->FrameColorRenderTargetName}); + pass_node.Inputs.init(device->Arena, 1); + pass_node.Outputs.init(device->Arena, 2); + pass_node.Outputs.push(RenderGraphRenderPassInputOutputInfo{.Name = RendererResourceName::FrameDepthRenderTargetName}); + pass_node.Outputs.push(RenderGraphRenderPassInputOutputInfo{.Name = RendererResourceName::FrameColorRenderTargetName}); - builder->CreateRenderPassNode(pass_node); + res_builder->CreateRenderPassNode(pass_node); } - void InitialPass::Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) + void InitialPass::Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) { - auto& builder = graph->RenderPassBuilder; - auto& renderer = graph->Renderer; - - if (pass && !(*pass)) + if (output_pass && !(*output_pass)) { - auto pass_spec = builder->SetPipelineName("Initial-Pipeline").SetInputBindingCount(1).SetStride(0, sizeof(float) * 3).SetRate(0, VK_VERTEX_INPUT_RATE_VERTEX).SetInputAttributeCount(1).SetLocation(0, 0).SetBinding(0, 0).SetFormat(0, Specifications::ImageFormat::R32G32B32_SFLOAT).SetOffset(0, 0).EnablePipelineDepthTest(true).UseShader("initial").Detach(); - *pass = renderer->Device->CreateRenderPass(pass_spec); - (*pass)->Bake(); + auto pass_spec = pass_builder->SetPipelineName("Initial-Pipeline") + .SetInputBindingCount(1) + .SetStride(0, sizeof(float) * 3) + .SetRate(0, VK_VERTEX_INPUT_RATE_VERTEX) + .SetInputAttributeCount(1) + .SetLocation(0, 0) + + .SetBinding(0, 0) + .SetFormat(0, Specifications::ImageFormat::R32G32B32_SFLOAT) + .SetOffset(0, 0) + + .EnablePipelineDepthTest(true) + .UseShader("initial") + .Detach(); + *output_pass = device->CreateRenderPass(pass_spec); + (*output_pass)->Bake(); } } - void InitialPass::Execute(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) - { - auto renderer = graph->Renderer; - auto buffer_set = renderer->Device->VertexBufferSetManager.Access(m_vb_handle); - auto vertex_buffer = buffer_set->At(scene->FrameIndex); - - auto view = ArrayView{m_vertex_data}; - vertex_buffer->Write(view); - } - - void InitialPass::Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) + void InitialPass::Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { - auto renderer = graph->Renderer; - auto buffer_set = renderer->Device->VertexBufferSetManager.Access(m_vb_handle); - auto vtx_buffer = buffer_set->At(scene->FrameIndex); + auto buffer_set = device->VertexBufferSetManager.Access(VBHandle); + auto vertex_buffer = buffer_set->At(device->CurrentFrameIndex); command_buffer->BeginRenderPass(pass, framebuffer->Handle); - command_buffer->BindVertexBuffer(*vtx_buffer); - command_buffer->BindDescriptorSets(scene->FrameIndex); + command_buffer->BindVertexBuffer(*vertex_buffer); + command_buffer->BindDescriptorSets(device->CurrentFrameIndex); command_buffer->Draw(1, 1, 0, 0); command_buffer->EndRenderPass(); } - void DepthPrePass::Setup(std::string_view name, RenderGraph* const graph) + void DepthPrePass::Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) { - auto& builder = graph->Builder; - auto& renderer = graph->Renderer; - RenderGraphRenderPassCreation pass_node = {.Name = name.data()}; + RenderGraphRenderPassCreation pass_node = {.Name = name}; - pass_node.Inputs.init(graph->Renderer->Device->Arena, 1); - pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = renderer->FrameDepthRenderTargetName}); + pass_node.Inputs.init(device->Arena, 1); + pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = RendererResourceName::FrameDepthRenderTargetName}); - builder->CreateRenderPassNode(pass_node); + res_builder->CreateRenderPassNode(pass_node); } - void DepthPrePass::Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) + void DepthPrePass::Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) { - if (!pass) - { - return; - } + CHECK_AND_ESCAPE_NULL(output_pass) - auto& builder = graph->RenderPassBuilder; - auto& renderer = graph->Renderer; - - if (pass && !(*pass)) + if (output_pass && !(*output_pass)) { - auto pass_spec = builder->SetPipelineName("Depth-Prepass-Pipeline").EnablePipelineDepthTest(true).UseShader("depth_prepass_scene").Detach(); - - *pass = renderer->Device->CreateRenderPass(pass_spec); - (*pass)->Bake(); - } + auto pass_spec = pass_builder->SetPipelineName("Depth-Prepass-Pipeline") + .EnablePipelineDepthTest(true) - (*pass)->SetInput("UBCamera", renderer->SceneCameraBufferHandle); + .UseShader("depth_prepass_scene") + .Detach(); - (*pass)->SetInput("VertexSB", renderer->RenderSceneData->VertexBufferHandle); - (*pass)->SetInput("IndexSB", renderer->RenderSceneData->IndexBufferHandle); - (*pass)->SetInput("DrawDataSB", renderer->RenderSceneData->RenderDataBufferHandle); - (*pass)->SetInput("TransformSB", renderer->RenderSceneData->TransformBufferHandle); + *output_pass = device->CreateRenderPass(pass_spec); + (*output_pass)->Bake(); + } - (*pass)->Verify(); - } + if (scene) + { + (*output_pass)->SetInput("UBCamera", scene->SceneCameraBufferHandle); - void DepthPrePass::Execute(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* pass, Hardwares::CommandBuffer* command_buffer, RenderGraph* const graph) - { - /* - * Composing Transform Data - */ - // if (!scene || !(scene->TransformBufferHandle)) - //{ - // return; - // } - // auto transfor_buffer = graph->Renderer->Device->StorageBufferSetManager.Access(scene->TransformBufferHandle); - // transfor_buffer->SetData(frame_index, scene->GlobalTransforms); + (*output_pass)->SetInput("VertexSB", scene->VertexBufferHandle); + (*output_pass)->SetInput("IndexSB", scene->IndexBufferHandle); + (*output_pass)->SetInput("DrawDataSB", scene->RenderDataBufferHandle); + (*output_pass)->SetInput("TransformSB", scene->TransformBufferHandle); + (*output_pass)->Verify(); + } } - void DepthPrePass::Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* pass, Buffers::FramebufferVNext* framebuffer, Hardwares::CommandBuffer* command_buffer, RenderGraph* graph) + void DepthPrePass::Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { if (!scene || !scene->IndirectBufferHandle) { return; } - auto renderer = graph->Renderer; - auto indirect_buffer = renderer->Device->IndirectBufferSetManager.Access(scene->IndirectBufferHandle); + auto indirect_buffer = device->IndirectBufferSetManager.Access(scene->IndirectBufferHandle); command_buffer->BeginRenderPass(pass, framebuffer->Handle); - command_buffer->BindDescriptorSets(scene->FrameIndex); - command_buffer->DrawIndirect(*indirect_buffer->At(scene->FrameIndex)); + command_buffer->BindDescriptorSets(device->CurrentFrameIndex); + command_buffer->DrawIndirect(*indirect_buffer->At(device->CurrentFrameIndex)); command_buffer->EndRenderPass(); } - void SkyboxPass::Setup(std::string_view name, RenderGraph* const graph) + void SkyboxPass::Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) { - auto& builder = graph->Builder; - auto& renderer = graph->Renderer; - auto arena = renderer->Device->Arena; - - m_index_data.init(arena, 36, make_initializer_list(arena, 0, 1, 2, 2, 3, 0, 1, 5, 6, 6, 2, 1, 5, 4, 7, 7, 6, 5, 4, 0, 3, 3, 7, 4, 3, 2, 6, 6, 7, 3, 4, 5, 1, 1, 0, 4)); - m_vertex_data.init(arena, 24, make_initializer_list(arena, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f)); + m_index_data.init(device->Arena, 36, make_initializer_list(device->Arena, 0, 1, 2, 2, 3, 0, 1, 5, 6, 6, 2, 1, 5, 4, 7, 7, 6, 5, 4, 0, 3, 3, 7, 4, 3, 2, 6, 6, 7, 3, 4, 5, 1, 1, 0, 4)); + m_vertex_data.init(device->Arena, 24, make_initializer_list(device->Arena, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f)); - auto env_map_res = builder->CreateTexture("skybox_env_map", "Settings/EnvironmentMaps/bergen_4k.hdr"); + auto env_map_res = res_builder->CreateTexture("skybox_env_map", "Settings/EnvironmentMaps/bergen_4k.hdr"); m_env_map = env_map_res.ResourceInfo.TextureHandle; - m_vb_handle = renderer->Device->CreateVertexBufferSet(); - m_ib_handle = renderer->Device->CreateIndexBufferSet(); + m_vb_handle = device->CreateVertexBufferSet(); + m_ib_handle = device->CreateIndexBufferSet(); - auto& output_skybox = builder->CreateRenderTarget("skybox_render_target", {.Width = 1280, .Height = 780, .Format = ImageFormat::R8G8B8A8_UNORM}); - RenderGraphRenderPassCreation pass_node = {.Name = name.data()}; + auto& output_skybox = res_builder->CreateRenderTarget("skybox_render_target", {.Width = 1280, .Height = 780, .Format = ImageFormat::R8G8B8A8_UNORM}); + RenderGraphRenderPassCreation pass_node = {.Name = name}; - pass_node.Inputs.init(graph->Renderer->Device->Arena, 2); - pass_node.Outputs.init(graph->Renderer->Device->Arena, 1); + pass_node.Inputs.init(device->Arena, 2); + pass_node.Outputs.init(device->Arena, 1); - pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = renderer->FrameDepthRenderTargetName}); - pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = renderer->FrameColorRenderTargetName}); + pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = RendererResourceName::FrameDepthRenderTargetName}); + pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = RendererResourceName::FrameColorRenderTargetName}); pass_node.Outputs.push(RenderGraphRenderPassInputOutputInfo{.Name = output_skybox.Name}); - builder->CreateRenderPassNode(pass_node); + res_builder->CreateRenderPassNode(pass_node); } - void SkyboxPass::Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) + void SkyboxPass::Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) { - if (!pass) - { - return; - } - - auto& builder = graph->RenderPassBuilder; - auto& renderer = graph->Renderer; + CHECK_AND_ESCAPE_NULL(output_pass) - if (pass && !(*pass)) + if (output_pass && !(*output_pass)) { - auto pass_spec = builder->SetPipelineName("Skybox-Pipeline").SetInputBindingCount(1).SetStride(0, sizeof(float) * 3).SetRate(0, VK_VERTEX_INPUT_RATE_VERTEX).SetInputAttributeCount(1).SetLocation(0, 0).SetBinding(0, 0).SetFormat(0, Specifications::ImageFormat::R32G32B32_SFLOAT).SetOffset(0, 0).EnablePipelineDepthTest(true).EnablePipelineDepthWrite(false).UseShader("skybox").Detach(); - *pass = renderer->Device->CreateRenderPass(pass_spec); - (*pass)->Bake(); + auto pass_spec = pass_builder->SetPipelineName("Skybox-Pipeline") + .SetInputBindingCount(1) + .SetStride(0, sizeof(float) * 3) + .SetRate(0, VK_VERTEX_INPUT_RATE_VERTEX) + .SetInputAttributeCount(1) + .SetLocation(0, 0) + + .SetBinding(0, 0) + .SetFormat(0, Specifications::ImageFormat::R32G32B32_SFLOAT) + .SetOffset(0, 0) + .EnablePipelineDepthTest(true) + .EnablePipelineDepthWrite(false) + + .UseShader("skybox") + .Detach(); + + *output_pass = device->CreateRenderPass(pass_spec); + (*output_pass)->Bake(); } - auto vertex_buffer = renderer->Device->VertexBufferSetManager.Access(m_vb_handle); - auto index_buffer = renderer->Device->IndexBufferSetManager.Access(m_ib_handle); - - auto count = renderer->Device->SwapchainImageCount; - for (auto i = 0; i < count; ++i) + if (scene) { - vertex_buffer->SetData(i, m_vertex_data); - index_buffer->SetData(i, m_index_data); + (*output_pass)->SetInput("UBCamera", scene->SceneCameraBufferHandle); + (*output_pass)->SetInput("EnvMap", m_env_map); } - (*pass)->SetInput("UBCamera", renderer->SceneCameraBufferHandle); - (*pass)->SetInput("EnvMap", m_env_map); - (*pass)->Verify(); + (*output_pass)->Verify(); } - void SkyboxPass::Execute(Rendering::Scenes::SceneData* const scene_data, RenderPasses::RenderPass* pass, Hardwares::CommandBuffer* command_buffer, RenderGraph* const graph) {} - - void SkyboxPass::Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* pass, Buffers::FramebufferVNext* framebuffer, Hardwares::CommandBuffer* command_buffer, RenderGraph* graph) + void SkyboxPass::Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { - auto renderer = graph->Renderer; - auto vertex_buffer = renderer->Device->VertexBufferSetManager.Access(m_vb_handle); - auto index_buffer = renderer->Device->IndexBufferSetManager.Access(m_ib_handle); + auto vertex_buffer = device->VertexBufferSetManager.Access(m_vb_handle); + auto index_buffer = device->IndexBufferSetManager.Access(m_ib_handle); command_buffer->BeginRenderPass(pass, framebuffer->Handle); - command_buffer->BindVertexBuffer(*vertex_buffer->At(scene->FrameIndex)); - command_buffer->BindIndexBuffer(*index_buffer->At(scene->FrameIndex), VK_INDEX_TYPE_UINT16); - command_buffer->BindDescriptorSets(scene->FrameIndex); + command_buffer->BindVertexBuffer(*vertex_buffer->At(device->CurrentFrameIndex)); + command_buffer->BindIndexBuffer(*index_buffer->At(device->CurrentFrameIndex), VK_INDEX_TYPE_UINT16); + command_buffer->BindDescriptorSets(device->CurrentFrameIndex); command_buffer->DrawIndexed(36, 1, 0, 0, 0); command_buffer->EndRenderPass(); } - void GridPass::Setup(std::string_view name, RenderGraph* const graph) + void GridPass::Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) { - auto& builder = graph->Builder; - auto& renderer = graph->Renderer; - auto arena = renderer->Device->Arena; + auto arena = device->Arena; m_index_data.init(arena, 6, make_initializer_list(arena, 0, 1, 2, 2, 3, 0)); m_vertex_data.init(arena, 12, make_initializer_list(arena, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f)); - m_vb_handle = renderer->Device->CreateVertexBufferSet(); - m_ib_handle = renderer->Device->CreateIndexBufferSet(); + m_vb_handle = device->CreateVertexBufferSet(); + m_ib_handle = device->CreateIndexBufferSet(); + + auto count = device->SwapchainImageCount; + auto vtx_buffer_set = device->VertexBufferSetManager.Access(m_vb_handle); + auto idx_buffer_set = device->IndexBufferSetManager.Access(m_ib_handle); + + auto vtx_buf_view = ArrayView{m_vertex_data}; + auto idx_buf_view = ArrayView{m_index_data}; + + for (int i = 0; i < count; ++i) + { + auto vertex_buffer = vtx_buffer_set->At(i); + auto index_buffer = idx_buffer_set->At(i); + + vertex_buffer->Allocate(vtx_buf_view.size_bytes(), "GridPassVtx"); + index_buffer->Allocate(idx_buf_view.size_bytes(), "GridPassIdx"); + + vertex_buffer->Write(vtx_buf_view); + index_buffer->Write(idx_buf_view); + } - auto& output_grid = builder->CreateRenderTarget("grid_render_target", {.Width = 1280, .Height = 780, .Format = ImageFormat::R8G8B8A8_UNORM}); - RenderGraphRenderPassCreation pass_node = {.Name = name.data()}; + auto& output_grid = res_builder->CreateRenderTarget("grid_render_target", {.Width = 1280, .Height = 780, .Format = ImageFormat::R8G8B8A8_UNORM}); + RenderGraphRenderPassCreation pass_node = {.Name = name}; - pass_node.Inputs.init(graph->Renderer->Device->Arena, 2); - pass_node.Outputs.init(graph->Renderer->Device->Arena, 1); + pass_node.Inputs.init(arena, 2); + pass_node.Outputs.init(arena, 1); - pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = renderer->FrameDepthRenderTargetName}); - pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = renderer->FrameColorRenderTargetName}); + pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = RendererResourceName::FrameDepthRenderTargetName}); + pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = RendererResourceName::FrameColorRenderTargetName}); pass_node.Outputs.push(RenderGraphRenderPassInputOutputInfo{.Name = output_grid.Name}); - builder->CreateRenderPassNode(pass_node); + res_builder->CreateRenderPassNode(pass_node); } - void GridPass::Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) + void GridPass::Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) { - if (!pass) - { - return; - } + CHECK_AND_ESCAPE_NULL(output_pass) - auto& builder = graph->RenderPassBuilder; - auto& renderer = graph->Renderer; - - if (pass && !(*pass)) + if (output_pass && !(*output_pass)) { - auto pass_spec = builder->SetPipelineName("Infinite-Grid-Pipeline").SetInputBindingCount(1).SetStride(0, sizeof(float) * 3).SetRate(0, VK_VERTEX_INPUT_RATE_VERTEX).SetInputAttributeCount(1).SetLocation(0, 0).SetBinding(0, 0).SetFormat(0, Specifications::ImageFormat::R32G32B32_SFLOAT).SetOffset(0, 0).EnablePipelineDepthTest(true).UseShader("infinite_grid").Detach(); - *pass = graph->Renderer->Device->CreateRenderPass(pass_spec); - (*pass)->Bake(); + auto pass_spec = pass_builder->SetPipelineName("Infinite-Grid-Pipeline") + .SetInputBindingCount(1) + .SetStride(0, sizeof(float) * 3) + .SetRate(0, VK_VERTEX_INPUT_RATE_VERTEX) + .SetInputAttributeCount(1) + .SetLocation(0, 0) + + .SetBinding(0, 0) + .SetFormat(0, Specifications::ImageFormat::R32G32B32_SFLOAT) + .SetOffset(0, 0) + + .EnablePipelineDepthTest(true) + .UseShader("infinite_grid") + .Detach(); + *output_pass = device->CreateRenderPass(pass_spec); + (*output_pass)->Bake(); } - (*pass)->SetInput("UBCamera", renderer->SceneCameraBufferHandle); - (*pass)->Verify(); - - auto count = renderer->Device->SwapchainImageCount; - auto vtx_buffer_set = renderer->Device->VertexBufferSetManager.Access(m_vb_handle); - auto idx_buffer_set = renderer->Device->IndexBufferSetManager.Access(m_ib_handle); - for (int i = 0; i < count; ++i) + if (scene) { - auto vertex_buffer = vtx_buffer_set->At(i); - auto index_buffer = idx_buffer_set->At(i); - - vertex_buffer->Allocate(ZKilo(100), "GridPassVtx"); - index_buffer->Allocate(ZKilo(100), "GridPassIdx"); - - auto vtx_buf_view = ArrayView{m_vertex_data}; - auto idx_buf_view = ArrayView{m_index_data}; - vertex_buffer->Upload(vtx_buf_view.data(), vtx_buf_view.size_bytes()); - index_buffer->Upload(idx_buf_view.data(), idx_buf_view.size_bytes()); + (*output_pass)->SetInput("UBCamera", scene->SceneCameraBufferHandle); + (*output_pass)->Verify(); } } - void GridPass::Execute(Rendering::Scenes::SceneData* const scene_data, RenderPasses::RenderPass* pass, Hardwares::CommandBuffer* command_buffer, RenderGraph* const graph) {} - - void GridPass::Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* pass, Buffers::FramebufferVNext* framebuffer, Hardwares::CommandBuffer* command_buffer, RenderGraph* graph) + void GridPass::Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { - auto renderer = graph->Renderer; - auto vertex_buffer = renderer->Device->VertexBufferSetManager.Access(m_vb_handle); - auto index_buffer = renderer->Device->IndexBufferSetManager.Access(m_ib_handle); + auto vtx_buffer_set = device->VertexBufferSetManager.Access(m_vb_handle); + auto idx_buffer_set = device->IndexBufferSetManager.Access(m_ib_handle); + + auto vertex_buffer = vtx_buffer_set->At(device->CurrentFrameIndex); + auto index_buffer = idx_buffer_set->At(device->CurrentFrameIndex); command_buffer->BeginRenderPass(pass, framebuffer->Handle); - command_buffer->BindVertexBuffer(*vertex_buffer->At(scene->FrameIndex)); - command_buffer->BindIndexBuffer(*index_buffer->At(scene->FrameIndex), VK_INDEX_TYPE_UINT16); - command_buffer->BindDescriptorSets(scene->FrameIndex); + command_buffer->BindVertexBuffer(*vertex_buffer); + command_buffer->BindIndexBuffer(*index_buffer, VK_INDEX_TYPE_UINT16); + command_buffer->BindDescriptorSets(device->CurrentFrameIndex); command_buffer->DrawIndexed(6, 1, 0, 0, 0); command_buffer->EndRenderPass(); } - void GbufferPass::Setup(std::string_view name, RenderGraph* const graph) + void GbufferPass::Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) { - auto& builder = graph->Builder; - auto& renderer = graph->Renderer; - Specifications::TextureSpecification normal_output_spec = {.IsUsageStorage = true, .Width = 1280, .Height = 780, .Format = ImageFormat::R16G16B16A16_SFLOAT}; Specifications::TextureSpecification position_output_spec = {.IsUsageStorage = true, .Width = 1280, .Height = 780, .Format = ImageFormat::R16G16B16A16_SFLOAT}; Specifications::TextureSpecification specular_output_spec = {.IsUsageStorage = true, .Width = 1280, .Height = 780, .Format = ImageFormat::R8G8B8A8_UNORM}; Specifications::TextureSpecification colour_output_spec = {.IsUsageStorage = true, .Width = 1280, .Height = 780, .Format = ImageFormat::R8G8B8A8_UNORM}; - auto& gbuffer_albedo = builder->CreateRenderTarget("gbuffer_albedo_render_target", colour_output_spec); - auto& gbuffer_specular = builder->CreateRenderTarget("gbuffer_specular_render_target", specular_output_spec); - auto& gbuffer_normals = builder->CreateRenderTarget("gbuffer_normals_render_target", normal_output_spec); - auto& gbuffer_position = builder->CreateRenderTarget("gbuffer_position_render_target", position_output_spec); + auto& gbuffer_albedo = res_builder->CreateRenderTarget("gbuffer_albedo_render_target", colour_output_spec); + auto& gbuffer_specular = res_builder->CreateRenderTarget("gbuffer_specular_render_target", specular_output_spec); + auto& gbuffer_normals = res_builder->CreateRenderTarget("gbuffer_normals_render_target", normal_output_spec); + auto& gbuffer_position = res_builder->CreateRenderTarget("gbuffer_position_render_target", position_output_spec); - RenderGraphRenderPassCreation pass_node = {.Name = name.data()}; + RenderGraphRenderPassCreation pass_node = {.Name = name}; - pass_node.Inputs.init(graph->Renderer->Device->Arena, 2); - pass_node.Outputs.init(graph->Renderer->Device->Arena, 4); + pass_node.Inputs.init(device->Arena, 2); + pass_node.Outputs.init(device->Arena, 4); - pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = renderer->FrameDepthRenderTargetName}); - pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = renderer->FrameColorRenderTargetName}); + pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = RendererResourceName::FrameDepthRenderTargetName}); + pass_node.Inputs.push(RenderGraphRenderPassInputOutputInfo{.Name = RendererResourceName::FrameColorRenderTargetName}); pass_node.Outputs.push({.Name = gbuffer_albedo.Name}); pass_node.Outputs.push({.Name = gbuffer_specular.Name}); pass_node.Outputs.push({.Name = gbuffer_normals.Name}); pass_node.Outputs.push({.Name = gbuffer_position.Name}); - builder->CreateRenderPassNode(pass_node); + res_builder->CreateRenderPassNode(pass_node); } - void GbufferPass::Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) + void GbufferPass::Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) { - if (!pass) - { - return; - } - - auto& builder = graph->RenderPassBuilder; - auto& renderer = graph->Renderer; + CHECK_AND_ESCAPE_NULL(output_pass) - if (pass && !(*pass)) + if (output_pass && !(*output_pass)) { - auto pass_spec = builder->SetPipelineName("GBuffer-Pipeline").EnablePipelineDepthTest(true).UseShader("g_buffer").Detach(); - *pass = renderer->Device->CreateRenderPass(pass_spec); - (*pass)->Bake(); + auto pass_spec = pass_builder->SetPipelineName("GBuffer-Pipeline").EnablePipelineDepthTest(true).UseShader("g_buffer").Detach(); + *output_pass = device->CreateRenderPass(pass_spec); + (*output_pass)->Bake(); } - (*pass)->SetInput("UBCamera", renderer->SceneCameraBufferHandle); + if (scene) + { + (*output_pass)->SetInput("UBCamera", scene->SceneCameraBufferHandle); - (*pass)->SetInput("VertexSB", renderer->RenderSceneData->VertexBufferHandle); - (*pass)->SetInput("IndexSB", renderer->RenderSceneData->IndexBufferHandle); - (*pass)->SetInput("DrawDataSB", renderer->RenderSceneData->RenderDataBufferHandle); - (*pass)->SetInput("TransformSB", renderer->RenderSceneData->TransformBufferHandle); - (*pass)->SetInput("MatSB", renderer->RenderSceneData->MaterialBufferHandle); + (*output_pass)->SetInput("VertexSB", scene->VertexBufferHandle); + (*output_pass)->SetInput("IndexSB", scene->IndexBufferHandle); + (*output_pass)->SetInput("DrawDataSB", scene->RenderDataBufferHandle); + (*output_pass)->SetInput("TransformSB", scene->TransformBufferHandle); + (*output_pass)->SetInput("MatSB", scene->MaterialBufferHandle); - (*pass)->SetBindlessInput("TextureArray"); - (*pass)->Verify(); + (*output_pass)->SetBindlessInput("TextureArray"); + (*output_pass)->Verify(); + } } - void GbufferPass::Execute(Rendering::Scenes::SceneData* const scene_data, RenderPasses::RenderPass* pass, Hardwares::CommandBuffer* command_buffer, RenderGraph* const graph) {} - - void GbufferPass::Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* pass, Buffers::FramebufferVNext* framebuffer, Hardwares::CommandBuffer* command_buffer, RenderGraph* graph) + void GbufferPass::Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { - if (!scene || !scene->IndirectBufferHandle) - { - return; - } + CHECK_AND_ESCAPE_NULL(scene) + CHECK_AND_ESCAPE_NULL(scene->IndirectBufferHandle) - auto renderer = graph->Renderer; - auto indirect_buffer = renderer->Device->IndirectBufferSetManager.Access(scene->IndirectBufferHandle); + auto indirect_buffer = device->IndirectBufferSetManager.Access(scene->IndirectBufferHandle); command_buffer->BeginRenderPass(pass, framebuffer->Handle); - command_buffer->BindDescriptorSets(scene->FrameIndex); - command_buffer->DrawIndirect(*indirect_buffer->At(scene->FrameIndex)); + command_buffer->BindDescriptorSets(device->CurrentFrameIndex); + command_buffer->DrawIndirect(*indirect_buffer->At(device->CurrentFrameIndex)); command_buffer->EndRenderPass(); } - void LightingPass::Setup(std::string_view name, RenderGraph* const graph) + void LightingPass::Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) { // auto& builder = graph->Builder; // auto& renderer = graph->Renderer; @@ -392,7 +370,7 @@ namespace ZEngine::Rendering::Renderers // builder->CreateRenderPassNode(pass_node); } - void LightingPass::Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) + void LightingPass::Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) { // if (!pass) //{ @@ -428,7 +406,7 @@ namespace ZEngine::Rendering::Renderers //(*pass)->Verify(); } - void LightingPass::Execute(Rendering::Scenes::SceneData* const scene_data, RenderPasses::RenderPass* pass, Hardwares::CommandBuffer* command_buffer, RenderGraph* const graph) + void LightingPass::Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) { // auto directional_light_buffer_handle = graph->GetStorageBufferSet("g_scene_directional_light_buffer"); // auto point_light_buffer_handle = graph->GetStorageBufferSet("g_scene_point_light_buffer"); @@ -447,10 +425,7 @@ namespace ZEngine::Rendering::Renderers // directional_light_buffer->SetData(frame_index, dir_light_data); // point_light_buffer->SetData(frame_index, point_light_data); // spot_light_buffer->SetData(frame_index, spot_light_data); - } - void LightingPass::Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* pass, Buffers::FramebufferVNext* framebuffer, Hardwares::CommandBuffer* command_buffer, RenderGraph* graph) - { // if (!scene->IndirectBufferHandle) //{ // return; diff --git a/ZEngine/ZEngine/Rendering/Renderers/RendererPasses.h b/ZEngine/ZEngine/Rendering/Renderers/RendererPasses.h index 20a3761c..0c185305 100644 --- a/ZEngine/ZEngine/Rendering/Renderers/RendererPasses.h +++ b/ZEngine/ZEngine/Rendering/Renderers/RendererPasses.h @@ -16,30 +16,26 @@ namespace ZEngine::Rendering::Renderers struct InitialPass : public IRenderGraphCallbackPass { - virtual void Setup(std::string_view name, RenderGraph* const graph) override; - virtual void Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) override; - virtual void Execute(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; - virtual void Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; + Core::Containers::Array VertexData = {}; + Hardwares::VertexBufferSetHandle VBHandle = {}; - private: - Core::Containers::Array m_vertex_data = {}; - Hardwares::VertexBufferSetHandle m_vb_handle = {}; + virtual void Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) override; + virtual void Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) override; + virtual void Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) override; }; struct DepthPrePass : public IRenderGraphCallbackPass { - virtual void Setup(std::string_view name, RenderGraph* const graph) override; - virtual void Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) override; - virtual void Execute(Rendering::Scenes::SceneData* const scene_data, RenderPasses::RenderPass* const pass, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; - virtual void Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; + virtual void Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) override; + virtual void Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) override; + virtual void Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) override; }; struct SkyboxPass : public IRenderGraphCallbackPass { - virtual void Setup(std::string_view name, RenderGraph* const graph) override; - virtual void Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) override; - virtual void Execute(Rendering::Scenes::SceneData* const scene_data, RenderPasses::RenderPass* const pass, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; - virtual void Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; + virtual void Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) override; + virtual void Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) override; + virtual void Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) override; private: Hardwares::VertexBufferSetHandle m_vb_handle = {}; @@ -51,10 +47,9 @@ namespace ZEngine::Rendering::Renderers struct GridPass : public IRenderGraphCallbackPass { - virtual void Setup(std::string_view name, RenderGraph* const graph) override; - virtual void Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) override; - virtual void Execute(Rendering::Scenes::SceneData* const scene_data, RenderPasses::RenderPass* const pass, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; - virtual void Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; + virtual void Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) override; + virtual void Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) override; + virtual void Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) override; private: Core::Containers::Array m_index_data = {}; @@ -65,18 +60,16 @@ namespace ZEngine::Rendering::Renderers struct GbufferPass : public IRenderGraphCallbackPass { - virtual void Setup(std::string_view name, RenderGraph* const graph) override; - virtual void Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) override; - virtual void Execute(Rendering::Scenes::SceneData* const scene_data, RenderPasses::RenderPass* const pass, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; - virtual void Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; + virtual void Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) override; + virtual void Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) override; + virtual void Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) override; }; struct LightingPass : public IRenderGraphCallbackPass { - virtual void Setup(std::string_view name, RenderGraph* const graph) override; - virtual void Compile(RenderPasses::RenderPass** pass, RenderGraph* const graph) override; - virtual void Execute(Rendering::Scenes::SceneData* const scene_data, RenderPasses::RenderPass* const pass, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; - virtual void Render(Rendering::Scenes::SceneData* const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBuffer* const command_buffer, RenderGraph* const graph) override; + virtual void Setup(Hardwares::VulkanDevicePtr const device, cstring name, RenderGraphResourceBuilderPtr const res_builder, RenderGraphResourceInspectorPtr res_inspector) override; + virtual void Compile(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPassBuilder* pass_builder, RenderGraphResourceInspectorPtr res_inspector, RenderPasses::RenderPass** const output_pass) override; + virtual void Execute(Hardwares::VulkanDevicePtr const device, Rendering::Scenes::SceneDataPtr const scene, RenderPasses::RenderPass* const pass, Buffers::FramebufferVNext* const framebuffer, Hardwares::CommandBufferPtr const command_buffer) override; }; } // namespace ZEngine::Rendering::Renderers \ No newline at end of file diff --git a/ZEngine/ZEngine/Rendering/Scenes/GraphicScene.cpp b/ZEngine/ZEngine/Rendering/Scenes/GraphicScene.cpp index 1a151b48..e9f7363d 100644 --- a/ZEngine/ZEngine/Rendering/Scenes/GraphicScene.cpp +++ b/ZEngine/ZEngine/Rendering/Scenes/GraphicScene.cpp @@ -14,6 +14,7 @@ using namespace ZEngine::Helpers; namespace ZEngine::Rendering::Scenes { +#if 0 static entt::registry g_sceneEntityRegistry; entt::registry& GetEntityRegistry() @@ -757,4 +758,5 @@ namespace ZEngine::Rendering::Scenes // } return camera_entity; } +#endif } // namespace ZEngine::Rendering::Scenes diff --git a/ZEngine/ZEngine/Rendering/Scenes/GraphicScene.h b/ZEngine/ZEngine/Rendering/Scenes/GraphicScene.h index 68cc723e..f3db2b56 100644 --- a/ZEngine/ZEngine/Rendering/Scenes/GraphicScene.h +++ b/ZEngine/ZEngine/Rendering/Scenes/GraphicScene.h @@ -1,42 +1,48 @@ #pragma once #include -#include +#include #include #include #include #include #include -#include -#include -#include -#include - -namespace ZEngine::Serializers -{ - class GraphicScene3DSerializer; -} - -namespace ZEngine::Rendering::Renderers -{ - struct AsyncResourceLoader; - struct GraphicRenderer; - class RenderGraph; -} // namespace ZEngine::Rendering::Renderers namespace ZEngine::Rendering::Scenes { struct SceneData { - uint32_t FrameIndex = {}; - Hardwares::StorageBufferSetHandle TransformBufferHandle = {}; - Hardwares::StorageBufferSetHandle MaterialBufferHandle = {}; - Hardwares::StorageBufferSetHandle VertexBufferHandle = {}; - Hardwares::StorageBufferSetHandle IndexBufferHandle = {}; - Hardwares::StorageBufferSetHandle RenderDataBufferHandle = {}; - Hardwares::IndirectBufferSetHandle IndirectBufferHandle = {}; + Hardwares::UniformBufferSetHandle SceneCameraBufferHandle = {}; + + Hardwares::StorageBufferSetHandle TransformBufferHandle = {}; + Hardwares::StorageBufferSetHandle MaterialBufferHandle = {}; + Hardwares::StorageBufferSetHandle VertexBufferHandle = {}; + Hardwares::StorageBufferSetHandle IndexBufferHandle = {}; + Hardwares::StorageBufferSetHandle RenderDataBufferHandle = {}; + Hardwares::IndirectBufferSetHandle IndirectBufferHandle = {}; }; ZDEFINE_PTR(SceneData); + struct RenderScene + { + std::atomic_bool MeshAllocationDirty[3] = {false, false, false}; + std::atomic_bool TransformBufferDirty[3] = {false, false, false}; + + uint32_t CurrentTransformOffset = 0; + uint32_t CurrentVertexOffset = 0; + uint32_t CurrentIndexOffset = 0; + + Core::Containers::Array Hierarchies = {}; + Core::Containers::Array LocalTransforms = {}; + Core::Containers::Array GlobalTransforms = {}; + + Core::Containers::Array Vertices = {}; + Core::Containers::Array Indices = {}; + Core::Containers::HashMap MeshAllocations = {}; + Core::Containers::HashMap NodeSubMeshesAllocations = {}; + }; + ZDEFINE_PTR(RenderScene); + +#if 0 /* * This internal defragmented storage represents SceneNode struct with a DoD (Data-Oriented Design) approach * The access is index based. @@ -247,4 +253,5 @@ namespace ZEngine::Rendering::Scenes std::recursive_mutex m_mutex = {}; friend class ZEngine::Serializers::GraphicScene3DSerializer; }; +#endif } // namespace ZEngine::Rendering::Scenes diff --git a/ZEngine/ZEngine/Serializers/GraphicScene3DSerializer.cpp b/ZEngine/ZEngine/Serializers/GraphicScene3DSerializer.cpp index 6d372be9..a835a873 100644 --- a/ZEngine/ZEngine/Serializers/GraphicScene3DSerializer.cpp +++ b/ZEngine/ZEngine/Serializers/GraphicScene3DSerializer.cpp @@ -77,9 +77,9 @@ namespace YAML namespace ZEngine::Serializers { - GraphicScene3DSerializer::GraphicScene3DSerializer(const Helpers::Ref& scene) : GraphicSceneSerializer() + GraphicScene3DSerializer::GraphicScene3DSerializer(/*const Helpers::Ref& scene*/) : GraphicSceneSerializer() { - m_scene = scene; + // m_scene = scene; auto directory = fmt::format("{0}/{1}", std::filesystem::current_path().string(), "Scenes"); m_default_scene_directory_path = std::filesystem::path(directory); } @@ -144,200 +144,201 @@ namespace ZEngine::Serializers return SerializeInformation{false, "Unable to load the Scene file"}; } - if (auto scene = m_scene.lock()) - { - SerializeInformation deserialization_info{}; - // try - //{ - // ZENGINE_CORE_INFO("Deserializing Scene file: {0}", filename) - - // auto entities = scene_data["Entities"]; - // if (entities) - // { - // for (auto entity : entities) - // { - // GraphicSceneEntity scene_entity; - - // // UUIComponent - // auto entity_uuid = entity["Entity"].as(); - - // // NameComponent - // std::string name; - // auto name_component = entity["NameComponent"]; - // if (name_component) - // { - // name = name_component["Name"].as(); - // } - - // scene_entity = scene->CreateEntity(entity_uuid, name); - - // // TransformComponent - // auto transform_component = entity["TransformComponent"]; - // if (transform_component) - // { - // auto& component = scene_entity.GetComponent(); - // component.SetPosition(transform_component["Position"].as()); - // component.SetRotationEulerAngles(transform_component["Rotation"].as()); - // component.SetScaleSize(transform_component["Scale"].as()); - // } - - // // GeometryComponent - // auto geometry_component = entity["GeometryComponent"]; - // if (geometry_component) - // { - // auto geometry_type = geometry_component["GeometryType"].as(); - // if (geometry_type == static_cast(Rendering::Geometries::GeometryType::CUBE)) - // { - // int32_t mesh_id{-1}; - // auto cube_mesh = - // ZEngine::Helpers::CreateBuiltInMesh(ZEngine::Rendering::Meshes::MeshType::CUBE); - // mesh_id = scene->AddMesh(std::move(cube_mesh)); - // scene_entity.AddComponent(mesh_id); - // } - // } - - // // MaterialComponent - // auto material_component = entity["MaterialComponent"]; - // if (material_component) - // { - // auto material_shader_type = material_component["MaterialShaderType"].as(); - // if (material_shader_type == - // static_cast(Rendering::Shaders::ShaderBuiltInType::STANDARD)) - // { - // Ref standard_material = CreateRef(); - // standard_material->SetShininess(material_component["Shininess"].as()); - // standard_material->SetTileFactor(material_component["TileFactor"].as()); - // standard_material->SetDiffuseTintColor(material_component["DiffuseTintColor"].as()); - // standard_material->SetSpecularTintColor(material_component["SpecularTintColor"].as()); - - // auto diffuse_map = material_component["DiffuseMap"]; - // if (diffuse_map["FromFile"].as()) - // { - // auto texture_path = diffuse_map["TexturePath"].as(); - // auto texture = ZEngine::Managers::TextureManager::Load(texture_path); - // standard_material->SetDiffuseMap(std::move(texture)); - // } - // else - // { - // auto texture_color = diffuse_map["TextureColor"].as(); - // auto texture = - // Ref(Rendering::Textures::CreateTexture(1, 1)); - // texture->SetData(texture_color.r, texture_color.g, texture_color.b, - // texture_color.a); standard_material->SetDiffuseMap(std::move(texture)); - // } - - // auto specular_map = material_component["SpecularMap"]; - // if (specular_map["FromFile"].as()) - // { - // auto texture_path = specular_map["TexturePath"].as(); - // auto texture = ZEngine::Managers::TextureManager::Load(texture_path); - // standard_material->SetSpecularMap(std::move(texture)); - // } - // else - // { - // auto texture_color = specular_map["TextureColor"].as(); - // auto texture = - // Ref(Rendering::Textures::CreateTexture(1, 1)); - // texture->SetData(texture_color.r, texture_color.g, texture_color.b, - // texture_color.a); standard_material->SetSpecularMap(std::move(texture)); - // } - - // scene_entity.AddComponent(std::move(standard_material)); - // } - // else if (material_shader_type == - // static_cast(Rendering::Shaders::ShaderBuiltInType::BASIC)) - // { - // scene_entity.AddComponent(CreateRef()); - // } - // } - - // // LightComponent - // auto light_component = entity["LightComponent"]; - // if (light_component) - // { - // auto light_type = light_component["LightType"].as(); - // if (light_type == - // static_cast(ZEngine::Rendering::Lights::LightType::DIRECTIONAL_LIGHT)) - // { - // auto direction = light_component["Direction"].as(); - // auto ambient_color = light_component["AmbientColor"].as(); - // auto diffuse_color = light_component["DiffuseColor"].as(); - // auto specular_color = light_component["SpecularColor"].as(); - - // auto directional_light = CreateRef(); - // directional_light->SetAmbientColor(ambient_color); - // directional_light->SetDiffuseColor(diffuse_color); - // directional_light->SetSpecularColor(specular_color); - // directional_light->SetDirection(direction); - // scene_entity.AddComponent(std::move(directional_light)); - // } - // } - - // // CameraComponent - // auto camera_component = entity["CameraComponent"]; - // if (camera_component) - // { - // auto is_primary = camera_component["IsPrimary"].as(); - // auto camera_type = camera_component["CameraType"].as(); - - // if (camera_type == static_cast(Rendering::Cameras::CameraType::PERSPECTIVE)) - // { - // auto aspect_ratio = camera_component["AspectRatio"].as(); - // auto field_of_view_degree = camera_component["FielOfViewDegree"].as(); - // auto camera_clipping_near = camera_component["Near"].as(); - // auto camera_clipping_far = camera_component["Far"].as(); - - // auto camera_controller_type = camera_component["CameraControllerType"]; - // if (!camera_controller_type) - // { - // // missing CameraControllerType .. report error - // } - - // auto controller_type = camera_controller_type["ControllerType"].as(); - // if (controller_type == - // static_cast(ZEngine::Controllers::CameraControllerType::PERSPECTIVE_ORBIT_CONTROLLER)) - // { - // auto radius = camera_controller_type["Radius"].as(); - // auto yaw_angle_degree = camera_controller_type["YawAngleDegree"].as(); - // auto pitch_angle_degree = camera_controller_type["PitchAngleDegree"].as(); - // auto position = camera_controller_type["Position"].as(); - - // auto window_parent = scene->m_parent_window.lock(); - // auto orbit_controller = - // CreateRef(window_parent, position, - // yaw_angle_degree, pitch_angle_degree); - // //orbit_controller->SetAspectRatio(scene->m_last_scene_requested_size.first / - // scene->m_last_scene_requested_size.second); - // orbit_controller->SetNear(camera_clipping_near); - // orbit_controller->SetFar(camera_clipping_far); - // orbit_controller->SetFieldOfView(Maths::radians(field_of_view_degree)); - - // auto camera = orbit_controller->GetCamera(); - // auto const orbit_camera = - // reinterpret_cast(camera.get()); - // orbit_camera->SetRadius(radius); - - // auto& component = - // scene_entity.AddComponent(std::move(orbit_controller)); - // component.IsPrimaryCamera = is_primary; - // } - // } - // } - // } - // } - //} - // catch (const std::exception& e) - //{ - // deserialization_info.IsSuccess = false; - // deserialization_info.ErrorMessage = e.what(); - //} + // if (auto scene = m_scene.lock()) + //{ + // SerializeInformation deserialization_info{}; + // // try + // //{ + // // ZENGINE_CORE_INFO("Deserializing Scene file: {0}", filename) + + // // auto entities = scene_data["Entities"]; + // // if (entities) + // // { + // // for (auto entity : entities) + // // { + // // GraphicSceneEntity scene_entity; + + // // // UUIComponent + // // auto entity_uuid = entity["Entity"].as(); + + // // // NameComponent + // // std::string name; + // // auto name_component = entity["NameComponent"]; + // // if (name_component) + // // { + // // name = name_component["Name"].as(); + // // } + + // // scene_entity = scene->CreateEntity(entity_uuid, name); + + // // // TransformComponent + // // auto transform_component = entity["TransformComponent"]; + // // if (transform_component) + // // { + // // auto& component = scene_entity.GetComponent(); + // // component.SetPosition(transform_component["Position"].as()); + // // component.SetRotationEulerAngles(transform_component["Rotation"].as()); + // // component.SetScaleSize(transform_component["Scale"].as()); + // // } + + // // // GeometryComponent + // // auto geometry_component = entity["GeometryComponent"]; + // // if (geometry_component) + // // { + // // auto geometry_type = geometry_component["GeometryType"].as(); + // // if (geometry_type == static_cast(Rendering::Geometries::GeometryType::CUBE)) + // // { + // // int32_t mesh_id{-1}; + // // auto cube_mesh = + // // ZEngine::Helpers::CreateBuiltInMesh(ZEngine::Rendering::Meshes::MeshType::CUBE); + // // mesh_id = scene->AddMesh(std::move(cube_mesh)); + // // scene_entity.AddComponent(mesh_id); + // // } + // // } + + // // // MaterialComponent + // // auto material_component = entity["MaterialComponent"]; + // // if (material_component) + // // { + // // auto material_shader_type = material_component["MaterialShaderType"].as(); + // // if (material_shader_type == + // // static_cast(Rendering::Shaders::ShaderBuiltInType::STANDARD)) + // // { + // // Ref standard_material = CreateRef(); + // // standard_material->SetShininess(material_component["Shininess"].as()); + // // standard_material->SetTileFactor(material_component["TileFactor"].as()); + // // standard_material->SetDiffuseTintColor(material_component["DiffuseTintColor"].as()); + // // standard_material->SetSpecularTintColor(material_component["SpecularTintColor"].as()); + + // // auto diffuse_map = material_component["DiffuseMap"]; + // // if (diffuse_map["FromFile"].as()) + // // { + // // auto texture_path = diffuse_map["TexturePath"].as(); + // // auto texture = ZEngine::Managers::TextureManager::Load(texture_path); + // // standard_material->SetDiffuseMap(std::move(texture)); + // // } + // // else + // // { + // // auto texture_color = diffuse_map["TextureColor"].as(); + // // auto texture = + // // Ref(Rendering::Textures::CreateTexture(1, 1)); + // // texture->SetData(texture_color.r, texture_color.g, texture_color.b, + // // texture_color.a); standard_material->SetDiffuseMap(std::move(texture)); + // // } + + // // auto specular_map = material_component["SpecularMap"]; + // // if (specular_map["FromFile"].as()) + // // { + // // auto texture_path = specular_map["TexturePath"].as(); + // // auto texture = ZEngine::Managers::TextureManager::Load(texture_path); + // // standard_material->SetSpecularMap(std::move(texture)); + // // } + // // else + // // { + // // auto texture_color = specular_map["TextureColor"].as(); + // // auto texture = + // // Ref(Rendering::Textures::CreateTexture(1, 1)); + // // texture->SetData(texture_color.r, texture_color.g, texture_color.b, + // // texture_color.a); standard_material->SetSpecularMap(std::move(texture)); + // // } + + // // scene_entity.AddComponent(std::move(standard_material)); + // // } + // // else if (material_shader_type == + // // static_cast(Rendering::Shaders::ShaderBuiltInType::BASIC)) + // // { + // // scene_entity.AddComponent(CreateRef()); + // // } + // // } + + // // // LightComponent + // // auto light_component = entity["LightComponent"]; + // // if (light_component) + // // { + // // auto light_type = light_component["LightType"].as(); + // // if (light_type == + // // static_cast(ZEngine::Rendering::Lights::LightType::DIRECTIONAL_LIGHT)) + // // { + // // auto direction = light_component["Direction"].as(); + // // auto ambient_color = light_component["AmbientColor"].as(); + // // auto diffuse_color = light_component["DiffuseColor"].as(); + // // auto specular_color = light_component["SpecularColor"].as(); + + // // auto directional_light = CreateRef(); + // // directional_light->SetAmbientColor(ambient_color); + // // directional_light->SetDiffuseColor(diffuse_color); + // // directional_light->SetSpecularColor(specular_color); + // // directional_light->SetDirection(direction); + // // scene_entity.AddComponent(std::move(directional_light)); + // // } + // // } + + // // // CameraComponent + // // auto camera_component = entity["CameraComponent"]; + // // if (camera_component) + // // { + // // auto is_primary = camera_component["IsPrimary"].as(); + // // auto camera_type = camera_component["CameraType"].as(); + + // // if (camera_type == static_cast(Rendering::Cameras::CameraType::PERSPECTIVE)) + // // { + // // auto aspect_ratio = camera_component["AspectRatio"].as(); + // // auto field_of_view_degree = camera_component["FielOfViewDegree"].as(); + // // auto camera_clipping_near = camera_component["Near"].as(); + // // auto camera_clipping_far = camera_component["Far"].as(); + + // // auto camera_controller_type = camera_component["CameraControllerType"]; + // // if (!camera_controller_type) + // // { + // // // missing CameraControllerType .. report error + // // } + + // // auto controller_type = camera_controller_type["ControllerType"].as(); + // // if (controller_type == + // // static_cast(ZEngine::Controllers::CameraControllerType::PERSPECTIVE_ORBIT_CONTROLLER)) + // // { + // // auto radius = camera_controller_type["Radius"].as(); + // // auto yaw_angle_degree = camera_controller_type["YawAngleDegree"].as(); + // // auto pitch_angle_degree = camera_controller_type["PitchAngleDegree"].as(); + // // auto position = camera_controller_type["Position"].as(); + + // // auto window_parent = scene->m_parent_window.lock(); + // // auto orbit_controller = + // // CreateRef(window_parent, position, + // // yaw_angle_degree, pitch_angle_degree); + // // //orbit_controller->SetAspectRatio(scene->m_last_scene_requested_size.first / + // // scene->m_last_scene_requested_size.second); + // // orbit_controller->SetNear(camera_clipping_near); + // // orbit_controller->SetFar(camera_clipping_far); + // // orbit_controller->SetFieldOfView(Maths::radians(field_of_view_degree)); + + // // auto camera = orbit_controller->GetCamera(); + // // auto const orbit_camera = + // // reinterpret_cast(camera.get()); + // // orbit_camera->SetRadius(radius); + + // // auto& component = + // // scene_entity.AddComponent(std::move(orbit_controller)); + // // component.IsPrimaryCamera = is_primary; + // // } + // // } + // // } + // // } + // // } + // //} + // // catch (const std::exception& e) + // //{ + // // deserialization_info.IsSuccess = false; + // // deserialization_info.ErrorMessage = e.what(); + // //} - return deserialization_info; - } - else - { - return SerializeInformation{false, "Unable to continue the deserialization process because the scene ref is no longer valid"}; - } + // return deserialization_info; + //} + // else + //{ + // return SerializeInformation{false, "Unable to continue the deserialization process because the scene ref is no longer valid"}; + //} + return SerializeInformation{false, "Unable to continue the deserialization process because the scene ref is no longer valid"}; } void GraphicScene3DSerializer::SerializeSceneEntity(YAML::Emitter& emitter, const GraphicSceneEntity& entity) @@ -363,14 +364,14 @@ namespace ZEngine::Serializers }); SerializeSceneEntityComponent(emitter, entity, [this](YAML::Emitter& emitter, MeshComponent& component) { - if (auto scene = m_scene.lock()) - { - // const auto& mesh = scene->GetMesh(component.GetMeshID()); - // emitter << YAML::Key << "GeometryComponent"; - // emitter << YAML::BeginMap; - // emitter << YAML::Key << "GeometryType" << YAML::Value << static_cast(mesh.Type); - // emitter << YAML::EndMap; - } + // if (auto scene = m_scene.lock()) + //{ + // // const auto& mesh = scene->GetMesh(component.GetMeshID()); + // // emitter << YAML::Key << "GeometryComponent"; + // // emitter << YAML::BeginMap; + // // emitter << YAML::Key << "GeometryType" << YAML::Value << static_cast(mesh.Type); + // // emitter << YAML::EndMap; + // } }); SerializeSceneEntityComponent(emitter, entity, [](YAML::Emitter& emitter, MaterialComponent& component) { diff --git a/ZEngine/ZEngine/Serializers/GraphicScene3DSerializer.h b/ZEngine/ZEngine/Serializers/GraphicScene3DSerializer.h index 9783fe28..772c71e0 100644 --- a/ZEngine/ZEngine/Serializers/GraphicScene3DSerializer.h +++ b/ZEngine/ZEngine/Serializers/GraphicScene3DSerializer.h @@ -32,7 +32,7 @@ namespace ZEngine::Serializers class GraphicScene3DSerializer : public GraphicSceneSerializer { public: - GraphicScene3DSerializer(const Helpers::Ref& scene); + GraphicScene3DSerializer(/*const Helpers::Ref& scene*/); virtual ~GraphicScene3DSerializer() = default; Core::SerializeInformation Serialize(std::string_view filename) override; diff --git a/ZEngine/ZEngine/Serializers/GraphicSceneSerializer.h b/ZEngine/ZEngine/Serializers/GraphicSceneSerializer.h index 68de7391..151f20ce 100644 --- a/ZEngine/ZEngine/Serializers/GraphicSceneSerializer.h +++ b/ZEngine/ZEngine/Serializers/GraphicSceneSerializer.h @@ -12,7 +12,7 @@ namespace ZEngine::Serializers virtual ~GraphicSceneSerializer() = default; protected: - std::filesystem::path m_default_scene_directory_path; - Helpers::WeakRef m_scene; + std::filesystem::path m_default_scene_directory_path; + // Helpers::WeakRef m_scene; }; } // namespace ZEngine::Serializers \ No newline at end of file diff --git a/Tetragrama/Serializers/Serializer.h b/ZEngine/ZEngine/Serializers/Serializer.h similarity index 94% rename from Tetragrama/Serializers/Serializer.h rename to ZEngine/ZEngine/Serializers/Serializer.h index a3952c97..40a3cf19 100644 --- a/Tetragrama/Serializers/Serializer.h +++ b/ZEngine/ZEngine/Serializers/Serializer.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include #include #include @@ -22,7 +22,7 @@ } \ } -namespace Tetragrama::Serializers +namespace ZEngine::Serializers { template struct Serializer @@ -95,6 +95,6 @@ namespace Tetragrama::Serializers } virtual void Serialize(ZRawPtr(TSerializerData) const data) = 0; - virtual void Deserialize(std::string_view filename) = 0; + virtual void Deserialize(cstring filename) = 0; }; -} // namespace Tetragrama::Serializers \ No newline at end of file +} // namespace ZEngine::Serializers \ No newline at end of file diff --git a/ZEngine/ZEngine/Windows/CoreWindow.cpp b/ZEngine/ZEngine/Windows/CoreWindow.cpp index c0ee86f6..408b10f6 100644 --- a/ZEngine/ZEngine/Windows/CoreWindow.cpp +++ b/ZEngine/ZEngine/Windows/CoreWindow.cpp @@ -1,7 +1,6 @@ #include #include -using namespace ZEngine::Windows::Layers; using namespace ZEngine::Helpers; namespace ZEngine::Windows @@ -9,25 +8,4 @@ namespace ZEngine::Windows CoreWindow::CoreWindow(const WindowConfiguration& cfg) : m_configuration(cfg) {} CoreWindow::~CoreWindow() {} - - void CoreWindow::ForwardEventToLayers(Core::CoreEvent& event) - { - for (auto layer : m_configuration.OverlayLayerCollection) - { - if (event.IsHandled()) - { - break; - } - layer->OnEvent(event); - } - - for (auto layer : m_configuration.RenderingLayerCollection) - { - if (event.IsHandled()) - { - break; - } - layer->OnEvent(event); - } - } } // namespace ZEngine::Windows diff --git a/ZEngine/ZEngine/Windows/CoreWindow.h b/ZEngine/ZEngine/Windows/CoreWindow.h index 801823b1..1325638b 100644 --- a/ZEngine/ZEngine/Windows/CoreWindow.h +++ b/ZEngine/ZEngine/Windows/CoreWindow.h @@ -5,26 +5,17 @@ #include #include #include -#include -#include #include #include -#include #include -#include #include #include #include #include -namespace ZEngine::Windows::Layers -{ - class Layer; -} // namespace ZEngine::Windows::Layers - namespace ZEngine::Windows { - class CoreWindow : public Inputs::IKeyboardEventCallback, public Inputs::IMouseEventCallback, public Inputs::ITextInputEventCallback, public Inputs::IWindowEventCallback, public Core::IUpdatable, public Core::IRenderable, public Core::IEventable + class CoreWindow : public Inputs::IWindowEventCallback, public Core::IEventable { public: @@ -57,8 +48,6 @@ namespace ZEngine::Windows virtual float GetTime() = 0; virtual float GetDeltaTime() = 0; - virtual void ForwardEventToLayers(Core::CoreEvent& event); - virtual void Deinitialize() {} protected: @@ -66,6 +55,5 @@ namespace ZEngine::Windows WindowProperty m_property; WindowConfiguration m_configuration; }; - - CoreWindow* Create(Core::Memory::ArenaAllocator* arena, const WindowConfiguration& cfg); + ZDEFINE_PTR(CoreWindow); } // namespace ZEngine::Windows diff --git a/Tetragrama/EditorWindow.cpp b/ZEngine/ZEngine/Windows/GameWindow.cpp similarity index 52% rename from Tetragrama/EditorWindow.cpp rename to ZEngine/ZEngine/Windows/GameWindow.cpp index ac6a523e..4c8c8e1a 100644 --- a/Tetragrama/EditorWindow.cpp +++ b/ZEngine/ZEngine/Windows/GameWindow.cpp @@ -1,11 +1,11 @@ #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #ifdef _WIN32 #define GLFW_EXPOSE_NATIVE_WIN32 @@ -32,35 +32,35 @@ using namespace ZEngine::Helpers; using namespace ZEngine::Hardwares; using namespace ZEngine::Rendering::Renderers; -namespace Tetragrama +namespace ZEngine::Windows { - uint32_t EditorWindow::GetWidth() const + uint32_t GameWindow::GetWidth() const { return m_property.Width; } - ZEngine::Core::Containers::StringView EditorWindow::GetTitle() const + Core::Containers::StringView GameWindow::GetTitle() const { return m_property.Title; } - bool EditorWindow::IsMinimized() const + bool GameWindow::IsMinimized() const { return m_property.IsMinimized; } - void EditorWindow::SetTitle(ZEngine::Core::Containers::StringView title) + void GameWindow::SetTitle(Core::Containers::StringView title) { m_property.Title = title.data(); glfwSetWindowTitle(m_native_window, m_property.Title); } - bool EditorWindow::IsVSyncEnable() const + bool GameWindow::IsVSyncEnable() const { return m_property.VSync; } - void EditorWindow::SetVSync(bool value) + void GameWindow::SetVSync(bool value) { m_property.VSync = value; if (value) @@ -73,22 +73,22 @@ namespace Tetragrama } } - void EditorWindow::SetCallbackFunction(const EventCallbackFn& callback) + void GameWindow::SetCallbackFunction(const EventCallbackFn& callback) { m_property.CallbackFn = callback; } - void* EditorWindow::GetNativeWindow() const + void* GameWindow::GetNativeWindow() const { return reinterpret_cast(m_native_window); } - const WindowProperty& EditorWindow::GetWindowProperty() const + const WindowProperty& GameWindow::GetWindowProperty() const { return m_property; } - void EditorWindow::Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, const ZEngine::Windows::WindowConfiguration& cfg) + void GameWindow::Initialize(Core::Memory::ArenaAllocator* arena, const WindowConfiguration& cfg) { m_configuration = cfg; @@ -146,71 +146,41 @@ namespace Tetragrama ZENGINE_CORE_INFO("Window created, Width = {0}, Height = {1}", m_property.Width, m_property.Height) - // Initialize in reverse order, so overlay layers can be initialize first - // this give us opportunity to initialize UI-like layers before graphic render-like layers - - for (auto layer : m_configuration.OverlayLayerCollection) - { - layer->ParentWindow = this; - layer->Initialize(arena); - } - - for (auto layer : m_configuration.RenderingLayerCollection) - { - layer->ParentWindow = this; - layer->Initialize(arena); - } - - ZENGINE_CORE_INFO("Windows layers initialized") - // Initialize Input Devices (Keyboard, Mouse) - ZEngine::Windows::Inputs::IDevice::Initialize(arena); + Inputs::IDevice::Initialize(arena); ZENGINE_CORE_INFO("Input devices initialized") glfwSetWindowUserPointer(m_native_window, &m_property); - glfwSetFramebufferSizeCallback(m_native_window, EditorWindow::__OnGlfwFrameBufferSizeChanged); + glfwSetFramebufferSizeCallback(m_native_window, GameWindow::__OnGlfwFrameBufferSizeChanged); - glfwSetWindowCloseCallback(m_native_window, EditorWindow::__OnGlfwWindowClose); - glfwSetWindowSizeCallback(m_native_window, EditorWindow::__OnGlfwWindowResized); - glfwSetWindowMaximizeCallback(m_native_window, EditorWindow::__OnGlfwWindowMaximized); - glfwSetWindowIconifyCallback(m_native_window, EditorWindow::__OnGlfwWindowMinimized); + glfwSetWindowCloseCallback(m_native_window, GameWindow::__OnGlfwWindowClose); + glfwSetWindowSizeCallback(m_native_window, GameWindow::__OnGlfwWindowResized); + glfwSetWindowMaximizeCallback(m_native_window, GameWindow::__OnGlfwWindowMaximized); + glfwSetWindowIconifyCallback(m_native_window, GameWindow::__OnGlfwWindowMinimized); - glfwSetMouseButtonCallback(m_native_window, EditorWindow::__OnGlfwMouseButtonRaised); - glfwSetScrollCallback(m_native_window, EditorWindow::__OnGlfwMouseScrollRaised); - glfwSetKeyCallback(m_native_window, EditorWindow::__OnGlfwKeyboardRaised); + glfwSetMouseButtonCallback(m_native_window, GameWindow::__OnGlfwMouseButtonRaised); + glfwSetScrollCallback(m_native_window, GameWindow::__OnGlfwMouseScrollRaised); + glfwSetKeyCallback(m_native_window, GameWindow::__OnGlfwKeyboardRaised); - glfwSetCursorPosCallback(m_native_window, EditorWindow::__OnGlfwCursorMoved); - glfwSetCharCallback(m_native_window, EditorWindow::__OnGlfwTextInputRaised); + glfwSetCursorPosCallback(m_native_window, GameWindow::__OnGlfwCursorMoved); + glfwSetCharCallback(m_native_window, GameWindow::__OnGlfwTextInputRaised); glfwMaximizeWindow(m_native_window); } - void EditorWindow::Deinitialize() - { - for (auto layer : m_configuration.OverlayLayerCollection) - { - layer->Deinitialize(); - } - - for (auto layer : m_configuration.RenderingLayerCollection) - { - layer->Deinitialize(); - } - } - - void EditorWindow::PollEvent() + void GameWindow::PollEvent() { glfwPollEvents(); } - float EditorWindow::GetTime() + float GameWindow::GetTime() { return (float) glfwGetTime(); } - float EditorWindow::GetDeltaTime() + float GameWindow::GetDeltaTime() { static float last_frame_time = 0.f; @@ -220,7 +190,7 @@ namespace Tetragrama return m_delta_time; } - void EditorWindow::__OnGlfwFrameBufferSizeChanged(GLFWwindow* window, int width, int height) + void GameWindow::__OnGlfwFrameBufferSizeChanged(GLFWwindow* window, int width, int height) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (property) @@ -232,7 +202,7 @@ namespace Tetragrama } } - void EditorWindow::__OnGlfwWindowClose(GLFWwindow* window) + void GameWindow::__OnGlfwWindowClose(GLFWwindow* window) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (property) @@ -242,7 +212,7 @@ namespace Tetragrama } } - void EditorWindow::__OnGlfwWindowResized(GLFWwindow* window, int width, int height) + void GameWindow::__OnGlfwWindowResized(GLFWwindow* window, int width, int height) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (property) @@ -252,7 +222,7 @@ namespace Tetragrama } } - void EditorWindow::__OnGlfwWindowMaximized(GLFWwindow* window, int maximized) + void GameWindow::__OnGlfwWindowMaximized(GLFWwindow* window, int maximized) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (property) @@ -269,7 +239,7 @@ namespace Tetragrama } } - void EditorWindow::__OnGlfwWindowMinimized(GLFWwindow* window, int minimized) + void GameWindow::__OnGlfwWindowMinimized(GLFWwindow* window, int minimized) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (property) @@ -285,7 +255,7 @@ namespace Tetragrama } } - void EditorWindow::__OnGlfwMouseButtonRaised(GLFWwindow* window, int button, int action, int mods) + void GameWindow::__OnGlfwMouseButtonRaised(GLFWwindow* window, int button, int action, int mods) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (property) @@ -302,7 +272,7 @@ namespace Tetragrama } } - void EditorWindow::__OnGlfwMouseScrollRaised(GLFWwindow* window, double xoffset, double yoffset) + void GameWindow::__OnGlfwMouseScrollRaised(GLFWwindow* window, double xoffset, double yoffset) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (property) @@ -312,7 +282,7 @@ namespace Tetragrama } } - void EditorWindow::__OnGlfwCursorMoved(GLFWwindow* window, double xoffset, double yoffset) + void GameWindow::__OnGlfwCursorMoved(GLFWwindow* window, double xoffset, double yoffset) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (property) @@ -322,7 +292,7 @@ namespace Tetragrama } } - void EditorWindow::__OnGlfwTextInputRaised(GLFWwindow* window, unsigned int character) + void GameWindow::__OnGlfwTextInputRaised(GLFWwindow* window, unsigned int character) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (property) @@ -334,7 +304,7 @@ namespace Tetragrama } } - void EditorWindow::__OnGlfwKeyboardRaised(GLFWwindow* window, int key, int scancode, int action, int mods) + void GameWindow::__OnGlfwKeyboardRaised(GLFWwindow* window, int key, int scancode, int action, int mods) { WindowProperty* property = reinterpret_cast(glfwGetWindowUserPointer(window)); if (!property) @@ -367,33 +337,7 @@ namespace Tetragrama } } - void EditorWindow::Update(Core::TimeStep delta_time) - { - for (auto layer : m_configuration.RenderingLayerCollection) - { - layer->Update(delta_time); - } - - for (auto layer : m_configuration.OverlayLayerCollection) - { - layer->Update(delta_time); - } - } - - void EditorWindow::Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) - { - for (auto layer : m_configuration.RenderingLayerCollection) - { - layer->Render(renderer, command_buffer); - } - - for (auto layer : m_configuration.OverlayLayerCollection) - { - layer->Render(renderer, command_buffer); - } - } - - std::future EditorWindow::OpenFileDialogAsync(std::span type_filters) + std::future GameWindow::OpenFileDialogAsync(std::span type_filters) { std::string path{""}; #ifdef _WIN32 @@ -426,7 +370,7 @@ namespace Tetragrama co_return path; } - bool EditorWindow::CreateSurface(void* instance, void** out_window_surface) + bool GameWindow::CreateSurface(void* instance, void** out_window_surface) { if (!instance || !out_window_surface) { @@ -438,19 +382,19 @@ namespace Tetragrama return (result == VK_SUCCESS); } - EditorWindow::~EditorWindow() + GameWindow::~GameWindow() { glfwSetErrorCallback(NULL); glfwDestroyWindow(m_native_window); glfwTerminate(); } - uint32_t EditorWindow::GetHeight() const + uint32_t GameWindow::GetHeight() const { return m_property.Height; } - bool EditorWindow::OnWindowClosed(WindowClosedEvent& event) + bool GameWindow::OnWindowClosed(WindowClosedEvent& event) { glfwSetWindowShouldClose(m_native_window, GLFW_TRUE); ZENGINE_CORE_INFO("Window has been closed") @@ -461,124 +405,47 @@ namespace Tetragrama return true; } - bool EditorWindow::OnWindowResized(WindowResizedEvent& event) + bool GameWindow::OnWindowResized(WindowResizedEvent& event) { ZENGINE_CORE_INFO("Window has been resized") - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); return false; } - bool EditorWindow::OnWindowMinimized(WindowMinimizedEvent& event) + bool GameWindow::OnWindowMinimized(WindowMinimizedEvent& event) { ZENGINE_CORE_INFO("Window has been minimized") m_property.IsMinimized = true; - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); return false; } - bool EditorWindow::OnWindowMaximized(WindowMaximizedEvent& event) + bool GameWindow::OnWindowMaximized(WindowMaximizedEvent& event) { ZENGINE_CORE_INFO("Window has been maximized") - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); + m_property.IsMinimized = false; return false; } - bool EditorWindow::OnWindowRestored(WindowRestoredEvent& event) + bool GameWindow::OnWindowRestored(WindowRestoredEvent& event) { ZENGINE_CORE_INFO("Window has been restored") m_property.IsMinimized = false; - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); return false; } - bool EditorWindow::OnEvent(Core::CoreEvent& event) + bool GameWindow::OnEvent(Core::CoreEvent& event) { Core::EventDispatcher event_dispatcher(event); - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnWindowClosed, this, std::placeholders::_1)); - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnWindowResized, this, std::placeholders::_1)); - - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnKeyPressed, this, std::placeholders::_1)); - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnKeyReleased, this, std::placeholders::_1)); - - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnMouseButtonPressed, this, std::placeholders::_1)); - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnMouseButtonReleased, this, std::placeholders::_1)); - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnMouseButtonMoved, this, std::placeholders::_1)); - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnMouseButtonWheelMoved, this, std::placeholders::_1)); - - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnTextInputRaised, this, std::placeholders::_1)); + event_dispatcher.Dispatch(std::bind(&GameWindow::OnWindowClosed, this, std::placeholders::_1)); + event_dispatcher.Dispatch(std::bind(&GameWindow::OnWindowResized, this, std::placeholders::_1)); - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnWindowMinimized, this, std::placeholders::_1)); - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnWindowMaximized, this, std::placeholders::_1)); - event_dispatcher.Dispatch(std::bind(&EditorWindow::OnWindowRestored, this, std::placeholders::_1)); + event_dispatcher.Dispatch(std::bind(&GameWindow::OnWindowMinimized, this, std::placeholders::_1)); + event_dispatcher.Dispatch(std::bind(&GameWindow::OnWindowMaximized, this, std::placeholders::_1)); + event_dispatcher.Dispatch(std::bind(&GameWindow::OnWindowRestored, this, std::placeholders::_1)); return true; } - - bool EditorWindow::OnKeyPressed(KeyPressedEvent& event) - { - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); - return true; - } - - bool EditorWindow::OnKeyReleased(KeyReleasedEvent& event) - { - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); - return true; - } - - bool EditorWindow::OnMouseButtonPressed(MouseButtonPressedEvent& event) - { - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); - return true; - } - - bool EditorWindow::OnMouseButtonReleased(MouseButtonReleasedEvent& event) - { - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); - return true; - } - - bool EditorWindow::OnMouseButtonMoved(MouseButtonMovedEvent& event) - { - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); - return true; - } - - bool EditorWindow::OnMouseButtonWheelMoved(MouseButtonWheelEvent& event) - { - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); - return true; - } - - bool EditorWindow::OnTextInputRaised(TextInputEvent& event) - { - Core::EventDispatcher event_dispatcher(event); - event_dispatcher.ForwardTo(std::bind(&CoreWindow::ForwardEventToLayers, this, std::placeholders::_1)); - return true; - } -} // namespace Tetragrama - -namespace ZEngine::Windows -{ - CoreWindow* Create(Core::Memory::ArenaAllocator* arena, const WindowConfiguration& cfg) - { - auto core_window = ZPushStructCtor(arena, Tetragrama::EditorWindow); - core_window->SetCallbackFunction(std::bind(&CoreWindow::OnEvent, core_window, std::placeholders::_1)); - core_window->Initialize(arena, cfg); - return core_window; - } } // namespace ZEngine::Windows diff --git a/ZEngine/ZEngine/Windows/GameWindow.h b/ZEngine/ZEngine/Windows/GameWindow.h new file mode 100644 index 00000000..326e9473 --- /dev/null +++ b/ZEngine/ZEngine/Windows/GameWindow.h @@ -0,0 +1,66 @@ +#pragma once +#define GLFW_INCLUDE_VULKAN +#include +#include +#include +#include +#include + +namespace ZEngine::Windows +{ + class GameWindow : public CoreWindow + { + public: + GameWindow() {} + virtual ~GameWindow(); + + uint32_t GetHeight() const override; + uint32_t GetWidth() const override; + Core::Containers::StringView GetTitle() const override; + bool IsMinimized() const override; + void SetTitle(Core::Containers::StringView title) override; + bool IsVSyncEnable() const override; + void SetVSync(bool value) override; + void SetCallbackFunction(const EventCallbackFn& callback) override; + void* GetNativeWindow() const override; + virtual const WindowProperty& GetWindowProperty() const override; + + virtual void Initialize(Core::Memory::ArenaAllocator* arena, const WindowConfiguration& cfg); + + virtual void PollEvent() override; + virtual float GetTime() override; + virtual float GetDeltaTime() override; + + virtual std::future OpenFileDialogAsync(std::span type_filters = {}) override; + + virtual bool CreateSurface(void* instance, void** out_window_surface) override; + + public: + bool OnEvent(Core::CoreEvent& event) override; + + protected: + virtual bool OnWindowClosed(Events::WindowClosedEvent&) override; + virtual bool OnWindowResized(Events::WindowResizedEvent&) override; + virtual bool OnWindowMinimized(Events::WindowMinimizedEvent&) override; + virtual bool OnWindowMaximized(Events::WindowMaximizedEvent&) override; + virtual bool OnWindowRestored(Events::WindowRestoredEvent&) override; + + static void __OnGlfwWindowClose(GLFWwindow*); + static void __OnGlfwWindowResized(GLFWwindow*, int width, int height); + static void __OnGlfwWindowMaximized(GLFWwindow*, int maximized); + static void __OnGlfwWindowMinimized(GLFWwindow*, int minimized); + + static void __OnGlfwMouseButtonRaised(GLFWwindow*, int button, int action, int mods); + static void __OnGlfwMouseScrollRaised(GLFWwindow*, double xoffset, double yoffset); + static void __OnGlfwCursorMoved(GLFWwindow*, double xpos, double ypos); + static void __OnGlfwTextInputRaised(GLFWwindow*, unsigned int character); + + static void __OnGlfwKeyboardRaised(GLFWwindow*, int key, int scancode, int action, int mods); + + static void __OnGlfwFrameBufferSizeChanged(GLFWwindow*, int width, int height); + + private: + GLFWwindow* m_native_window = nullptr; + }; + +} // namespace ZEngine::Windows diff --git a/ZEngine/ZEngine/Windows/Inputs/Keyboard.h b/ZEngine/ZEngine/Windows/Inputs/Keyboard.h new file mode 100644 index 00000000..085b7a25 --- /dev/null +++ b/ZEngine/ZEngine/Windows/Inputs/Keyboard.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +namespace ZEngine::Windows::Inputs +{ + + struct Keyboard : public IDevice + { + Keyboard(const char* name = "keyboard_device") : IDevice(name) {} + ~Keyboard() = default; + + virtual bool IsKeyPressed(ZENGINE_KEYCODE key, CoreWindow* const window) const override + { + auto state = glfwGetKey(reinterpret_cast(window->GetNativeWindow()), (int) key); + return state == GLFW_PRESS; + } + + virtual bool IsKeyReleased(ZENGINE_KEYCODE key, CoreWindow* const window) const override + { + auto state = glfwGetKey(reinterpret_cast(window->GetNativeWindow()), (int) key); + return state == GLFW_RELEASE; + } + }; +} // namespace ZEngine::Windows::Inputs diff --git a/ZEngine/ZEngine/Windows/Inputs/Mouse.h b/ZEngine/ZEngine/Windows/Inputs/Mouse.h new file mode 100644 index 00000000..897a73c3 --- /dev/null +++ b/ZEngine/ZEngine/Windows/Inputs/Mouse.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include +#include + +namespace ZEngine::Windows::Inputs +{ + + struct Mouse : public IDevice + { + Mouse(const char* name = "mouse_device") : IDevice(name) {} + + virtual bool IsKeyPressed(ZENGINE_KEYCODE key, CoreWindow* const window) const override + { + auto state = glfwGetMouseButton(reinterpret_cast(window->GetNativeWindow()), (int) key); + return state == GLFW_PRESS; + } + + virtual bool IsKeyReleased(ZENGINE_KEYCODE key, CoreWindow* const window) const override + { + return !IsKeyPressed(key, window); + } + + std::array GetMousePosition(CoreWindow* const window) const + { + double x, y; + glfwGetCursorPos(reinterpret_cast(window->GetNativeWindow()), &x, &y); + return std::array{x, y}; + } + }; +} // namespace ZEngine::Windows::Inputs diff --git a/ZEngine/ZEngine/Windows/Layers/Layer.h b/ZEngine/ZEngine/Windows/Layers/Layer.h deleted file mode 100644 index c1b21a7a..00000000 --- a/ZEngine/ZEngine/Windows/Layers/Layer.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace ZEngine::Windows -{ - class CoreWindow; -} - -namespace ZEngine::Windows::Layers -{ - - struct Layer : public Core::IUpdatable, public Core::IEventable, public Core::IRenderable - { - Layer(const char* name = "default_layer") - { - Name = name; - } - - virtual ~Layer() = default; - - virtual void Initialize(Core::Memory::ArenaAllocator* arena) = 0; - virtual void Deinitialize() {}; - - ZEngine::Core::Memory::ArenaAllocator LocalArena = {}; - ZEngine::Core::Memory::ArenaAllocator* Arena = nullptr; - const char* Name = nullptr; - void* ParentContext = nullptr; - ZRawPtr(ZEngine::Windows::CoreWindow) ParentWindow = nullptr; - }; -} // namespace ZEngine::Windows::Layers diff --git a/ZEngine/ZEngine/Windows/WindowConfiguration.h b/ZEngine/ZEngine/Windows/WindowConfiguration.h index f762d6d3..9e3010dd 100644 --- a/ZEngine/ZEngine/Windows/WindowConfiguration.h +++ b/ZEngine/ZEngine/Windows/WindowConfiguration.h @@ -1,24 +1,15 @@ #pragma once -#include #include -#include - -namespace ZEngine::Windows::Layers -{ - class Layer; -} namespace ZEngine::Windows { struct WindowConfiguration { - uint32_t Width = 1500; - uint32_t Height = 800; - bool EnableVsync = true; - Core::Containers::String Title; - - Core::Containers::Array RenderingLayerCollection; - Core::Containers::Array OverlayLayerCollection; + uint32_t Width = 1500; + uint32_t Height = 800; + bool EnableVsync = true; + Core::Containers::String Title; }; + ZDEFINE_PTR(WindowConfiguration); } // namespace ZEngine::Windows diff --git a/ZEngine/ZEngine/ZEngineDef.h b/ZEngine/ZEngine/ZEngineDef.h index 7da8597e..8d91b115 100644 --- a/ZEngine/ZEngine/ZEngineDef.h +++ b/ZEngine/ZEngine/ZEngineDef.h @@ -55,6 +55,12 @@ #define ZRawPtr(X) X* #define ZDEFINE_PTR(X) typedef ZRawPtr(X) X##Ptr +#define CHECK_AND_ESCAPE_NULL(handle) \ + if (!handle) \ + { \ + return; \ + } + /* * Allocator and Memory Macros */ diff --git a/__externals/externals.cmake b/__externals/externals.cmake index 35f6d663..e90d7436 100644 --- a/__externals/externals.cmake +++ b/__externals/externals.cmake @@ -33,10 +33,10 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") endif() add_library (imported::External_libs INTERFACE IMPORTED) -add_library(imported::External_editorLibs INTERFACE IMPORTED) +add_library (imported::External_obeliskLibs INTERFACE IMPORTED) -target_link_libraries(imported::External_editorLibs INTERFACE +target_link_libraries(imported::External_obeliskLibs INTERFACE CLI11::CLI11 )