From 4e80031d2218ff0143ed54f5fcab36a662de6ec5 Mon Sep 17 00:00:00 2001 From: Aaron <56617292+SpinnerX@users.noreply.github.com> Date: Tue, 12 Nov 2024 23:55:46 -0800 Subject: [PATCH 1/2] Updated conanfile and cmake (#56) Updated cmake build to using updated cmake utils --- CMakeLists.txt | 122 +----------------------------------- Editor/CMakeLists.txt | 26 +------- Editor/Editor/Editor.cpp | 7 ++- Editor/Editor/Editor.hpp | 1 + Editor/conanfile.py | 26 +++++++- conanfile.py | 12 ++-- src/CMakeLists.txt | 10 +-- test_package/CMakeLists.txt | 12 +--- test_package/conanfile.py | 4 +- 9 files changed, 50 insertions(+), 170 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc8431f..7210c16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,126 +2,6 @@ cmake_minimum_required(VERSION 3.25) project(engine3d C CXX) set(CMAKE_CXX_STANDARD 23) +set(ENGINE_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/engine3d) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "") # works (in creating the compile_commands.json file) - -find_package(OpenGL REQUIRED) -find_package(glfw3 REQUIRED) - -find_package(Vulkan REQUIRED) -find_package(VulkanHeaders REQUIRED) - -if(LINUX) -find_package(VulkanLoader REQUIRED) -endif(LINUX) - -find_package(glm REQUIRED) -find_package(fmt REQUIRED) -find_package(spdlog REQUIRED) -find_package(yaml-cpp REQUIRED) -find_package(imguidocking REQUIRED) -find_package(box2d REQUIRED) -find_package(joltphysics REQUIRED) -find_package(EnTT REQUIRED) - -add_subdirectory(Editor) add_subdirectory(src) - -# Copy to compile_commands.json for .clangd -add_custom_target( - copy-compile-commands ALL - DEPENDS - ${CMAKE_SOURCE_DIR}/compile_commands.json -) - -add_custom_command( - OUTPUT ${CMAKE_CURRENT_LIST_DIR}/compile_commands.json - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_BINARY_DIR}/compile_commands.json - ${CMAKE_CURRENT_LIST_DIR}/compile_commands.json - DEPENDS - # Unlike "proper" targets like executables and libraries, - # custom command / target pairs will not set up source - # file dependencies, so we need to list file explicitly here - generate-compile-commands - ${CMAKE_BINARY_DIR}/compile_commands.json -) - -# Generate the compilation commands. Necessary so cmake knows where it came -# from and if for some reason you delete it. -add_custom_target(generate-compile-commands - DEPENDS - ${CMAKE_BINARY_DIR}/compile_commands.json -) - -add_custom_command( - OUTPUT ${CMAKE_BINARY_DIR}/compile_commands.json - COMMAND ${CMAKE_COMMAND} -B${CMAKE_BINARY_DIR} -S${CMAKE_SOURCE_DIR} -) - -# This is used because if we do not have this users systems may give them a linked error with oldnames.lib -# Usage - used to suppress that lld-link error and use the defaulted linked .library -if(MSVC) - target_compile_options(${PROJECT_NAME} PUBLIC "/Z1" "/NOD") -endif(MSVC) - -# target_include_directory is setting some private settings for differentiating what internal includes are privates and what should be includes should be exposed to the application-dev -target_include_directories(${PROJECT_NAME} PRIVATE engine3d/ engine3d/Core) -target_include_directories(${PROJECT_NAME} PUBLIC ${JoltPhysics_SOURCE_DIR} ${GLM_INCLUDE_DIR} ./engine3d) - -if(WIN32) -target_link_libraries( - ${PROJECT_NAME} - PRIVATE - glfw - ${OPENGL_LIBRARIES} - Vulkan::Vulkan - vulkan-headers::vulkan-headers - glm::glm - fmt::fmt - spdlog::spdlog - yaml-cpp::yaml-cpp - imguidocking::imguidocking - box2d::box2d - Jolt::Jolt - EnTT::EnTT -) -endif(WIN32) - -if(LINUX) -target_link_libraries( - ${PROJECT_NAME} - PRIVATE - glfw - ${OPENGL_LIBRARIES} - Vulkan::Loader - glm::glm - fmt::fmt - spdlog::spdlog - yaml-cpp::yaml-cpp - imguidocking::imguidocking - box2d::box2d - Jolt::Jolt - EnTT::EnTT -) -endif(LINUX) - -if(APPLE) -target_link_libraries( - ${PROJECT_NAME} - PRIVATE - glfw - ${OPENGL_LIBRARIES} - Vulkan::Vulkan - vulkan-headers::vulkan-headers - glm::glm - fmt::fmt - spdlog::spdlog - yaml-cpp::yaml-cpp - imguidocking::imguidocking - box2d::box2d - EnTT::EnTT -) -endif(APPLE) - -install(TARGETS ${PROJECT_NAME}) diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt index cc66ddf..35ed566 100644 --- a/Editor/CMakeLists.txt +++ b/Editor/CMakeLists.txt @@ -1,30 +1,8 @@ cmake_minimum_required(VERSION 3.15) project(Editor CXX) -set( - all_src +build_demos( + SOURCES Editor/Editor.hpp Editor/Editor.cpp ) - -find_package(spdlog REQUIRED) -find_package(glm REQUIRED) -find_package(yaml-cpp REQUIRED) -find_package(Vulkan REQUIRED) -# find_package(imguidocking REQUIRED) -# find_package(engine3d REQUIRED) - -add_executable(${PROJECT_NAME} ${all_src}) - -target_include_directories(${PROJECT_NAME} PRIVATE ../) - -target_link_libraries( - ${PROJECT_NAME} - spdlog::spdlog - glm::glm - yaml-cpp::yaml-cpp - Vulkan::Vulkan - # imguidocking::imguidocking - # engine3d::engine3d - engine3d -) \ No newline at end of file diff --git a/Editor/Editor/Editor.cpp b/Editor/Editor/Editor.cpp index 6e05969..d1b3e4b 100644 --- a/Editor/Editor/Editor.cpp +++ b/Editor/Editor/Editor.cpp @@ -1,8 +1,11 @@ #include "Editor.hpp" -#include "Core/Event/InputPoll.hpp" -#include "Core/Event/KeyCodes.hpp" +// #include "Core/Event/InputPoll.hpp" +// #include "Core/Event/KeyCodes.hpp" +#include +#include #include #include + namespace engine3d{ EditorApplication::EditorApplication(const std::string& p_DebugName) : ApplicationInstance(p_DebugName) { diff --git a/Editor/Editor/Editor.hpp b/Editor/Editor/Editor.hpp index 7f23388..dd9af2f 100644 --- a/Editor/Editor/Editor.hpp +++ b/Editor/Editor/Editor.hpp @@ -1,4 +1,5 @@ #pragma once +// #include #include namespace engine3d{ diff --git a/Editor/conanfile.py b/Editor/conanfile.py index cfc1cc8..849e679 100644 --- a/Editor/conanfile.py +++ b/Editor/conanfile.py @@ -12,8 +12,32 @@ class Editor(ConanFile): settings = "os", "compiler", "build_type", "arch" exports_sources = "CMakeLists.txt", "Editor/*" + def build_requirements(self): + self.tool_requires("make/4.4.1") + self.tool_requires("cmake/3.27.1") + self.tool_requires("engine3d-cmake-utils/1.0") + def requirements(self): + self.requires("glfw/3.4", transitive_headers=True) + self.requires("opengl/system", transitive_headers=True) + # These end in 1.0 because they are engine3d-customized conan packages + # Slighly modified of the conan packages and it's CMake generators to using "Unix Makefiles" + self.requires("fmt/10.2.1", transitive_headers=True) + self.requires("spdlog/1.14.1", transitive_headers=True) + self.requires("glm/1.0.1", transitive_headers=True) + self.requires("yaml-cpp/0.8.0", transitive_headers=True) + self.requires("box2d/2.4.2") self.requires("imguidocking/1.0") + self.requires("entt/3.13.2") + + + self.requires("joltphysics/1.0") + + self.requires("vulkan-headers/1.3.290.0") + if self.settings.os == "Linux": + self.requires("vulkan-loader/1.3.290.0") + print(f"OS = {self.settings.os}") + self.requires("engine3d/1.0") def generate(self): @@ -28,4 +52,4 @@ def build(self): cmake.build() def layout(self): - cmake_layout(self) + cmake_layout(self) diff --git a/conanfile.py b/conanfile.py index 9267f06..2322819 100644 --- a/conanfile.py +++ b/conanfile.py @@ -20,14 +20,18 @@ class engine3dRecipe(ConanFile): default_options = {"shared": False, "fPIC": True} # Sources are located in the same place as this recipe, copy them to the recipe - exports_sources = "CMakeLists.txt", "src/CMakeLists.txt", "Editor/CMakeLists.txt", "src/*", "engine3d/*", "Editor/*", "Testbed/*" + # exports_sources = "CMakeLists.txt", "src/CMakeLists.txt", "Editor/CMakeLists.txt", "src/*", "engine3d/*", "Editor/*", "Testbed/*" + exports_sources = "CMakeLists.txt", "src/CMakeLists.txt", "Editor/CMakeLists.txt", "src/*", "engine3d/*", - def requirements(self): - self.requires("make/4.4.1") + def build_requirements(self): + self.tool_requires("make/4.4.1") self.tool_requires("cmake/3.27.1") + self.tool_requires("engine3d-cmake-utils/1.0") + + def requirements(self): self.requires("glfw/3.4", transitive_headers=True) self.requires("opengl/system", transitive_headers=True) - + self.requires("engine3d-cmake-utils/1.0") # These end in 1.0 because they are engine3d-customized conan packages # Slighly modified of the conan packages and it's CMake generators to using "Unix Makefiles" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e3556e4..560ce71 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,9 +4,8 @@ set(ENGINE_SRC_DIR engine3d) set(VULKAN_INCLUDE_DIR ${ENGINE_INCLUDE_NAME}/Core/internal/VulkanCpp) set(VULKAN_SRC_DIR ${ENGINE_SRC_DIR}/Core/internal/VulkanCpp) -set( - all_headers - +build_library( + SOURCES ${ENGINE_INCLUDE_NAME}/Core/ApplicationInstance.hpp ${ENGINE_INCLUDE_NAME}/Core/EngineLogger.hpp @@ -30,10 +29,7 @@ set( # Renderer Includes ${ENGINE_INCLUDE_NAME}/Core/Renderer/Renderer.hpp -) -set( - all_src ${ENGINE_SRC_DIR}/Core/ApplicationInstance.cpp @@ -54,5 +50,3 @@ set( ${ENGINE_SRC_DIR}/Core/Renderer/Renderer.cpp ) - -add_library(${PROJECT_NAME} ${all_headers} ${all_src}) \ No newline at end of file diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 9eafbe9..fec9732 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -1,14 +1,8 @@ cmake_minimum_required(VERSION 3.15) project(example CXX) -find_package(Vulkan REQUIRED) +find_package(engine3d REQUIRED CONFIG) -find_package(engine3d CONFIG REQUIRED) -add_executable(example Application.hpp Application.cpp) +add_executable(${PROJECT_NAME} Application.hpp Application.cpp) -target_link_libraries(${PROJECT_NAME} - Vulkan::Vulkan - # vulkan-headers::vulkan-headers - # imguidocking::imguidocking - engine3d::engine3d -) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} engine3d::engine3d) \ No newline at end of file diff --git a/test_package/conanfile.py b/test_package/conanfile.py index 58f1b7b..9a4b3cd 100644 --- a/test_package/conanfile.py +++ b/test_package/conanfile.py @@ -2,13 +2,15 @@ from conan import ConanFile from conan.tools.cmake import CMake, cmake_layout from conan.tools.build import can_run + class engine3dTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" + def requirements(self): - # self.requires("engine3d/1.0") self.requires("vulkan-headers/1.3.290.0") self.requires(self.tested_reference_str) + def build(self): cmake = CMake(self) cmake.configure() From 3adf7fe1ce20b88c1fbdc54b60d29045f5df7bc2 Mon Sep 17 00:00:00 2001 From: Aaron <56617292+SpinnerX@users.noreply.github.com> Date: Sun, 17 Nov 2024 20:58:54 -0800 Subject: [PATCH 2/2] Updating by merging working Engine3D with features from thread manager and global/local update managers (#57) * Added clear comments on specific aspects of vulkan abstraction layers, modified header extensions to hpp, including adding in the event-system into this commit * Submitting bug fixes to the event system and made some changes by removing an update function from the window class that was only used for events into InputPoll::UpdateEvents instead * Updated cmake build to using cmake utils * Updated cmake build to using updated cmake utils * Working Vulkan Rendering Triangle with Better Design * Working colored triangle with updated shaders * working of rendering four triangles vertically with the color blue using push constants * Refactored Swapchain API for utilizing graphic swapchain instead of directly calling vulkan swapchain * Updated triangles to prettier colors and now got scaling, rotation, and translation matrices working using push constants stil * Merging big PR to engine3d for work TestApp and Editor application alongside threading and sync update managers --- CMakeLists.txt | 27 +- Editor/CMakeLists.txt | 53 +- Editor/Editor/Editor.cpp | 287 +++++++- Editor/Editor/Editor.hpp | 22 +- TestApp/Application.cpp | 19 + TestApp/CMakeLists.txt | 79 +++ .../Components/Bodies/BodyContainer.hpp | 11 + .../Components/Bodies/Shapes/BoxShaper.hpp | 6 + .../Components/Bodies/Shapes/SphereShaper.hpp | 6 + .../Components/Physics/PhysicsBody3D.hpp | 34 + .../Scenes/Assets/Components/testComp.hpp | 16 + .../SceneInstances/ShowCaseSceneInstance.hpp | 14 + .../Components/Bodies/BodyContainer.cpp | 6 + .../Components/Bodies/Shapes/BoxShaper.cpp | 19 + .../Components/Bodies/Shapes/SphereShaper.cpp | 21 + .../Components/Physics/PhysicsBody3D.cpp | 111 ++++ .../src/Scenes/Assets/Components/testComp.cpp | 49 ++ .../SceneInstances/ShowCaseSceneInstance.cpp | 41 ++ colorful_triangle/compile_shaders.sh | 2 + colorful_triangle/simple_shader.frag | 10 + colorful_triangle/simple_shader.frag.spv | Bin 0 -> 572 bytes colorful_triangle/simple_shader.vert | 17 + colorful_triangle/simple_shader.vert.spv | Bin 0 -> 1080 bytes conanfile.py | 2 +- cube_shader/cube_shader.frag | 8 + cube_shader/cube_shader.vert | 14 + engine3d/Core/{internal => }/API.hpp | 0 engine3d/Core/ApplicationInstance.hpp | 8 +- .../GameObjManager/UUID.hpp | 35 + engine3d/Core/ApplicationManager/Scene.hpp | 14 + .../Core/ApplicationManager/ThreadMngr.hpp | 29 + engine3d/Core/Core.hpp | 8 + engine3d/Core/Event/InputPoll.hpp | 3 + .../GraphicDrivers/GraphicContextDriver.hpp | 52 ++ .../GraphicDrivers/GraphicPhysicalDriver.hpp | 8 + .../Core/GraphicDrivers/GraphicSwapchain.hpp | 48 ++ engine3d/Core/GraphicDrivers/Shader.hpp | 17 + engine3d/Core/Renderer/Renderer.hpp | 13 + engine3d/Core/Scene/SceneObject.hpp | 68 ++ .../Components/GameComponent.hpp | 21 + .../Components/SPComps/Transform.hpp | 25 + .../SceneObjects/SceneObject.hpp | 85 +++ .../TimeManagement/GlobalUpdateManager.hpp | 89 +++ engine3d/Core/TimeManagement/Timer.hpp | 21 + .../ParallelFrameUpdateManager.hpp | 4 + .../UpdateManagers/SyncUpdateManager.hpp | 119 ++++ engine3d/Core/Window.hpp | 26 +- .../Shaders/ShaderPipelineConfig.hpp | 21 + .../Shaders/ShaderSpirvBins.hpp | 450 +++++++++++++ .../Vulkan2Showcase/Shaders/VulkanShader.hpp | 38 ++ .../Core/internal/Vulkan2Showcase/Vulkan.hpp | 13 + .../Vulkan2Showcase/VulkanContext.hpp | 27 + .../internal/Vulkan2Showcase/VulkanDriver.hpp | 23 + .../internal/Vulkan2Showcase/VulkanModel.hpp | 42 ++ .../Vulkan2Showcase/VulkanPhysicalDriver.hpp | 36 + .../Vulkan2Showcase/VulkanSwapchain.hpp | 97 +++ .../internal/Vulkan2Showcase/VulkanWindow.hpp | 44 ++ .../Vulkan2Showcase/helper_functions.hpp | 14 + engine3d/Core/internal/VulkanCpp/Vulkan.hpp | 21 - .../Core/internal/VulkanCpp/VulkanDevice.hpp | 14 - .../VulkanCpp/VulkanLogicalDevice.hpp | 37 -- .../VulkanCpp/VulkanPhysicalDevice.hpp | 65 -- .../internal/VulkanCpp/VulkanRenderer.hpp | 8 - .../internal/VulkanCpp/VulkanSwapchain.hpp | 70 -- .../Core/internal/VulkanCpp/VulkanWindow.hpp | 37 -- engine3d/Math/Interpolation.hpp | 62 ++ .../Engine3DActivationListener.hpp | 23 + .../Interaction/Engine3DContactListener.hpp | 36 + .../Interfaces/BPLayerInterfaceHandler.hpp | 65 ++ .../ObjectLayerPairFilterInterface.hpp | 25 + .../ObjectVsBPLayerFilterInterface.hpp | 27 + engine3d/Physics/JoltHandler.hpp | 71 ++ imgui.ini | 16 +- sim_shader_transforms/simple_shader.frag | 17 + sim_shader_transforms/simple_shader.frag.spv | Bin 0 -> 856 bytes sim_shader_transforms/simple_shader.vert | 18 + sim_shader_transforms/simple_shader.vert.spv | Bin 0 -> 1412 bytes simple_shader/compile_shaders.sh | 2 + simple_shader/simple_shader.frag | 16 + simple_shader/simple_shader.frag.spv | Bin 0 -> 756 bytes simple_shader/simple_shader.vert | 17 + simple_shader/simple_shader.vert.spv | Bin 0 -> 1224 bytes src/CMakeLists.txt | 80 ++- src/engine3d/Core/ApplicationInstance.cpp | 24 +- .../GameObjManager/UUID.cpp | 14 + .../Core/ApplicationManager/Scene.cpp | 9 + .../Core/ApplicationManager/ThreadMngr.cpp | 67 ++ .../Core/{internal => }/CoreInternal.cpp | 4 +- src/engine3d/Core/Event/InputPoll.cpp | 2 +- .../Core/GraphicDrivers/GraphicSwapchain.cpp | 59 ++ src/engine3d/Core/GraphicDrivers/Shader.cpp | 19 + src/engine3d/Core/Renderer/Renderer.cpp | 61 ++ src/engine3d/Core/Scene/SceneObject.cpp | 10 + .../Components/GameComponent.cpp | 9 + .../Components/SPComps/Transform.cpp | 48 ++ .../SceneObjects/SceneObject.cpp | 19 + .../TimeManagement/GlobalUpdateManager.cpp | 102 +++ src/engine3d/Core/TimeManagement/Timer.cpp | 34 + .../ParallelFrameUpdateManager.cpp | 0 .../UpdateManagers/SyncUpdateManager.cpp | 115 ++++ src/engine3d/Core/Window.cpp | 24 +- .../Vulkan2Showcase/Shaders/VulkanShader.cpp | 232 +++++++ .../Vulkan2Showcase/VulkanContext.cpp | 123 ++++ .../internal/Vulkan2Showcase/VulkanDriver.cpp | 73 ++ .../internal/Vulkan2Showcase/VulkanModel.cpp | 108 +++ .../Vulkan2Showcase/VulkanPhysicalDriver.cpp | 94 +++ .../Vulkan2Showcase/VulkanSwapchain.cpp | 629 ++++++++++++++++++ .../internal/Vulkan2Showcase/VulkanWindow.cpp | 40 ++ .../Vulkan2Showcase/helper_functions.cpp | 37 ++ .../Core/internal/VulkanCpp/Vulkan.cpp | 93 --- .../Core/internal/VulkanCpp/VulkanDevice.cpp | 41 -- .../VulkanCpp/VulkanLogicalDevice.cpp | 40 -- .../VulkanCpp/VulkanPhysicalDevice.cpp | 246 ------- .../internal/VulkanCpp/VulkanSwapchain.cpp | 462 ------------- .../Core/internal/VulkanCpp/VulkanWindow.cpp | 56 -- src/engine3d/Core/platforms/win32.cpp | 18 +- src/engine3d/Math/Interpolation.cpp | 2 + src/engine3d/Physics/JoltHandler.cpp | 129 ++++ 118 files changed, 4891 insertions(+), 1251 deletions(-) create mode 100644 TestApp/Application.cpp create mode 100644 TestApp/CMakeLists.txt create mode 100644 TestApp/SceneTest/Scenes/Assets/Components/Bodies/BodyContainer.hpp create mode 100644 TestApp/SceneTest/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.hpp create mode 100644 TestApp/SceneTest/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.hpp create mode 100644 TestApp/SceneTest/Scenes/Assets/Components/Physics/PhysicsBody3D.hpp create mode 100644 TestApp/SceneTest/Scenes/Assets/Components/testComp.hpp create mode 100644 TestApp/SceneTest/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.hpp create mode 100644 TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/BodyContainer.cpp create mode 100644 TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.cpp create mode 100644 TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.cpp create mode 100644 TestApp/SceneTest/src/Scenes/Assets/Components/Physics/PhysicsBody3D.cpp create mode 100644 TestApp/SceneTest/src/Scenes/Assets/Components/testComp.cpp create mode 100644 TestApp/SceneTest/src/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.cpp create mode 100644 colorful_triangle/compile_shaders.sh create mode 100644 colorful_triangle/simple_shader.frag create mode 100644 colorful_triangle/simple_shader.frag.spv create mode 100644 colorful_triangle/simple_shader.vert create mode 100644 colorful_triangle/simple_shader.vert.spv create mode 100644 cube_shader/cube_shader.frag create mode 100644 cube_shader/cube_shader.vert rename engine3d/Core/{internal => }/API.hpp (100%) create mode 100644 engine3d/Core/ApplicationManager/GameObjManager/UUID.hpp create mode 100644 engine3d/Core/ApplicationManager/Scene.hpp create mode 100644 engine3d/Core/ApplicationManager/ThreadMngr.hpp create mode 100644 engine3d/Core/GraphicDrivers/GraphicContextDriver.hpp create mode 100644 engine3d/Core/GraphicDrivers/GraphicPhysicalDriver.hpp create mode 100644 engine3d/Core/GraphicDrivers/GraphicSwapchain.hpp create mode 100644 engine3d/Core/GraphicDrivers/Shader.hpp create mode 100644 engine3d/Core/Scene/SceneObject.hpp create mode 100644 engine3d/Core/SceneManagment/Components/GameComponent.hpp create mode 100644 engine3d/Core/SceneManagment/Components/SPComps/Transform.hpp create mode 100644 engine3d/Core/SceneManagment/SceneObjects/SceneObject.hpp create mode 100644 engine3d/Core/TimeManagement/GlobalUpdateManager.hpp create mode 100644 engine3d/Core/TimeManagement/Timer.hpp create mode 100644 engine3d/Core/TimeManagement/UpdateManagers/ParallelFrameUpdateManager.hpp create mode 100644 engine3d/Core/TimeManagement/UpdateManagers/SyncUpdateManager.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/Shaders/ShaderPipelineConfig.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/Shaders/ShaderSpirvBins.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/Shaders/VulkanShader.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/Vulkan.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/VulkanContext.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/VulkanDriver.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/VulkanModel.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/VulkanPhysicalDriver.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/VulkanSwapchain.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/VulkanWindow.hpp create mode 100644 engine3d/Core/internal/Vulkan2Showcase/helper_functions.hpp delete mode 100644 engine3d/Core/internal/VulkanCpp/Vulkan.hpp delete mode 100644 engine3d/Core/internal/VulkanCpp/VulkanDevice.hpp delete mode 100644 engine3d/Core/internal/VulkanCpp/VulkanLogicalDevice.hpp delete mode 100644 engine3d/Core/internal/VulkanCpp/VulkanPhysicalDevice.hpp delete mode 100644 engine3d/Core/internal/VulkanCpp/VulkanRenderer.hpp delete mode 100644 engine3d/Core/internal/VulkanCpp/VulkanSwapchain.hpp delete mode 100644 engine3d/Core/internal/VulkanCpp/VulkanWindow.hpp create mode 100644 engine3d/Math/Interpolation.hpp create mode 100644 engine3d/Physics/Interaction/Engine3DActivationListener.hpp create mode 100644 engine3d/Physics/Interaction/Engine3DContactListener.hpp create mode 100644 engine3d/Physics/Interfaces/BPLayerInterfaceHandler.hpp create mode 100644 engine3d/Physics/Interfaces/ObjectLayerPairFilterInterface.hpp create mode 100644 engine3d/Physics/Interfaces/ObjectVsBPLayerFilterInterface.hpp create mode 100644 engine3d/Physics/JoltHandler.hpp create mode 100644 sim_shader_transforms/simple_shader.frag create mode 100644 sim_shader_transforms/simple_shader.frag.spv create mode 100644 sim_shader_transforms/simple_shader.vert create mode 100644 sim_shader_transforms/simple_shader.vert.spv create mode 100644 simple_shader/compile_shaders.sh create mode 100644 simple_shader/simple_shader.frag create mode 100644 simple_shader/simple_shader.frag.spv create mode 100644 simple_shader/simple_shader.vert create mode 100644 simple_shader/simple_shader.vert.spv create mode 100644 src/engine3d/Core/ApplicationManager/GameObjManager/UUID.cpp create mode 100644 src/engine3d/Core/ApplicationManager/Scene.cpp create mode 100644 src/engine3d/Core/ApplicationManager/ThreadMngr.cpp rename src/engine3d/Core/{internal => }/CoreInternal.cpp (83%) create mode 100644 src/engine3d/Core/GraphicDrivers/GraphicSwapchain.cpp create mode 100644 src/engine3d/Core/GraphicDrivers/Shader.cpp create mode 100644 src/engine3d/Core/Scene/SceneObject.cpp create mode 100644 src/engine3d/Core/SceneManagment/Components/GameComponent.cpp create mode 100644 src/engine3d/Core/SceneManagment/Components/SPComps/Transform.cpp create mode 100644 src/engine3d/Core/SceneManagment/SceneObjects/SceneObject.cpp create mode 100644 src/engine3d/Core/TimeManagement/GlobalUpdateManager.cpp create mode 100644 src/engine3d/Core/TimeManagement/Timer.cpp create mode 100644 src/engine3d/Core/TimeManagement/UpdateManagers/ParallelFrameUpdateManager.cpp create mode 100644 src/engine3d/Core/TimeManagement/UpdateManagers/SyncUpdateManager.cpp create mode 100644 src/engine3d/Core/internal/Vulkan2Showcase/Shaders/VulkanShader.cpp create mode 100644 src/engine3d/Core/internal/Vulkan2Showcase/VulkanContext.cpp create mode 100644 src/engine3d/Core/internal/Vulkan2Showcase/VulkanDriver.cpp create mode 100644 src/engine3d/Core/internal/Vulkan2Showcase/VulkanModel.cpp create mode 100644 src/engine3d/Core/internal/Vulkan2Showcase/VulkanPhysicalDriver.cpp create mode 100644 src/engine3d/Core/internal/Vulkan2Showcase/VulkanSwapchain.cpp create mode 100644 src/engine3d/Core/internal/Vulkan2Showcase/VulkanWindow.cpp create mode 100644 src/engine3d/Core/internal/Vulkan2Showcase/helper_functions.cpp delete mode 100644 src/engine3d/Core/internal/VulkanCpp/Vulkan.cpp delete mode 100644 src/engine3d/Core/internal/VulkanCpp/VulkanDevice.cpp delete mode 100644 src/engine3d/Core/internal/VulkanCpp/VulkanLogicalDevice.cpp delete mode 100644 src/engine3d/Core/internal/VulkanCpp/VulkanPhysicalDevice.cpp delete mode 100644 src/engine3d/Core/internal/VulkanCpp/VulkanSwapchain.cpp delete mode 100644 src/engine3d/Core/internal/VulkanCpp/VulkanWindow.cpp create mode 100644 src/engine3d/Math/Interpolation.cpp create mode 100644 src/engine3d/Physics/JoltHandler.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7210c16..4962928 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,32 @@ cmake_minimum_required(VERSION 3.25) -project(engine3d C CXX) +project(engine3d CXX) set(CMAKE_CXX_STANDARD 23) set(ENGINE_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/engine3d) +cmake_minimum_required(VERSION 3.25) +project(engine3d C CXX) + +set(CMAKE_CXX_STANDARD 23) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "") # works (in creating the compile_commands.json file) + +add_subdirectory(Editor) +add_subdirectory(TestApp) add_subdirectory(src) + +# # target_include_directory is setting some private settings for differentiating what internal includes are privates and what should be includes should be exposed to the application-dev +target_include_directories(${PROJECT_NAME} PUBLIC ${JoltPhysics_SOURCE_DIR} ${EnTT_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE engine3d/ engine3d/Core) +target_include_directories(${PROJECT_NAME} PUBLIC ${GLM_INCLUDE_DIR} ./engine3d) + +# #Set Compiler definitions +set(is_msvc_cl $) +set(dev_definitions + $<${is_msvc_cl}:JPH_FLOATING_POINT_EXCEPTIONS_ENABLED> + JPH_PROFILE_ENABLED + JPH_DEBUG_RENDERER + JPH_OBJECT_STREAM +) + +target_compile_definitions(${PROJECT_NAME} PRIVATE ${dev_definitions}) diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt index 35ed566..8053b84 100644 --- a/Editor/CMakeLists.txt +++ b/Editor/CMakeLists.txt @@ -1,8 +1,57 @@ cmake_minimum_required(VERSION 3.15) project(Editor CXX) -build_demos( - SOURCES +# build_demos( +# SOURCES +# Editor/Editor.hpp +# Editor/Editor.cpp +# ) + +set( + all_src Editor/Editor.hpp Editor/Editor.cpp ) + +add_executable(${PROJECT_NAME} ${all_src}) + +find_package(OpenGL REQUIRED) +find_package(glfw3 REQUIRED) + +find_package(Vulkan REQUIRED) +find_package(VulkanHeaders REQUIRED) + +if(LINUX) +find_package(VulkanLoader REQUIRED) +endif(LINUX) + +# target_include_directories(${PROJECT_NAME} PUBLIC ${ENGINE_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ../) +find_package(glm REQUIRED) +find_package(fmt REQUIRED) +find_package(spdlog REQUIRED) +find_package(yaml-cpp REQUIRED) +find_package(imguidocking REQUIRED) +find_package(box2d REQUIRED) +find_package(joltphysics REQUIRED) +find_package(EnTT REQUIRED) + + +target_link_libraries( + ${PROJECT_NAME} + PRIVATE + glfw + ${OPENGL_LIBRARIES} + Vulkan::Vulkan + vulkan-headers::vulkan-headers + glm::glm + fmt::fmt + spdlog::spdlog + yaml-cpp::yaml-cpp + imguidocking::imguidocking + box2d::box2d + Jolt::Jolt + EnTT::EnTT + engine3d +) + diff --git a/Editor/Editor/Editor.cpp b/Editor/Editor/Editor.cpp index d1b3e4b..ed64aad 100644 --- a/Editor/Editor/Editor.cpp +++ b/Editor/Editor/Editor.cpp @@ -1,22 +1,271 @@ #include "Editor.hpp" -// #include "Core/Event/InputPoll.hpp" -// #include "Core/Event/KeyCodes.hpp" -#include -#include -#include -#include +#include "Core/TimeManagement/GlobalUpdateManager.hpp" +// #include "internal/VulkanCpp/helper_functions.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#include +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#include +#include + namespace engine3d{ + struct SimplePushConstantData{ + glm::mat2 Transform{1.f}; + glm::vec2 Offsets; + alignas(16) glm::vec3 Color; + }; + EditorApplication::EditorApplication(const std::string& p_DebugName) : ApplicationInstance(p_DebugName) { // Renderer::Initialize(); // Renderer::SetBackgroundColor({1.0f, 0.0f, 0.0f, 0.0f}); + + // VulkanVertexBuffer vb = VulkanVertexBuffer({ + // {{-0.5f, -0.288f, 0.0f, 1.0f}, {0.0f, 0.0f}}, + // {{.5f, -.288f, 0.0f, 1.0f}, {1.0f, 0.0f}}, + // {{0.0f, .577f, 0.0f, 1.0f}, {0.5f, 1.0f}} + // }); + + //! @note Basics of command buffers. + + //! @note Initialize Push constant range + VkPushConstantRange push_const_range = { + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + .offset = 0, + .size = sizeof(SimplePushConstantData) + }; + + //! @note First initializing pipeline layout create info + VkPipelineLayoutCreateInfo pipeline_layout_create_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .setLayoutCount = 0, + .pSetLayouts = nullptr, + // .pushConstantRangeCount = 0, + // .pPushConstantRanges = nullptr, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &push_const_range + }; + + vk::vk_check(vkCreatePipelineLayout(vk::VulkanContext::GetDriver(), &pipeline_layout_create_info, nullptr, &m_PipelineLayout), "vkCreatePipelineLayout", __FILE__, __LINE__, __FUNCTION__); + + //! @note Setting up our pipeline. + auto pipeline_config = vk::VulkanShader::shader_configuration(ApplicationInstance::GetWindow().GetWidth(), ApplicationInstance::GetWindow().GetHeight()); + //! @note We are setting our shader pipeline to utilize our current window's swapchain + //! @note a TODO is to utilize different render passes utiization for shader pipelines, potentially. + pipeline_config.PipelineRenderPass = ApplicationInstance::GetWindow().GetCurrentSwapchain()->GetRenderPass(); + pipeline_config.PipelineLayout = m_PipelineLayout; + + // m_Shader = Shader::Create("simple_shader/simple_shader.vert.spv", "simple_shader/simple_shader.frag.spv", pipeline_config); + m_Shader = Shader::Create("sim_shader_transforms/simple_shader.vert.spv", "sim_shader_transforms/simple_shader.frag.spv", pipeline_config); + + + //! @note Initializing Command buffers. + m_CommandBuffers.resize(ApplicationInstance::GetWindow().GetCurrentSwapchain()->GetImagesSize()); + + //! @note Creating our pools of command buffer structs + VkCommandPoolCreateInfo pool_create_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .pNext = nullptr, + .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = vk::VulkanContext::GetPhysicalDriver().GetQueueIndices().Graphics + }; + + vk::vk_check(vkCreateCommandPool(vk::VulkanContext::GetDriver(), &pool_create_info, nullptr, &m_CommandPool), "vkCreateCommandPool", __FILE__, __LINE__, __FUNCTION__); + + //! @note Allocating our command buffers. + VkCommandBufferAllocateInfo cmd_buffer_alloc_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .commandPool = m_CommandPool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = static_cast(m_CommandBuffers.size()), + }; + + vk::vk_check(vkAllocateCommandBuffers(vk::VulkanContext::GetDriver(), &cmd_buffer_alloc_info, m_CommandBuffers.data()), "vkAllocateCommandBuffers", __FILE__, __LINE__, __FUNCTION__); + + ConsoleLogInfo("CommandBuffers Size === {}", m_CommandBuffers.size()); + + //-------------------------------------------- + //! @note Loading Game Objectts Here + //-------------------------------------------- + std::vector triangle_vertices = { + {.Position={0.0f, -0.5f}, .Color = {1.0f, 0.0f, 0.0f}}, + {.Position ={0.5f, 0.5f}, .Color = {0.0f, 1.0f, 0.0f}}, + {.Position ={-0.5f, 0.5f}, .Color = {0.0f, 0.0f, 1.0f}} + }; + // vk::VulkanModel model = vk::VulkanModel(triangle_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + auto model = CreateRef(triangle_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + auto triangle = SceneObject::Create(); + triangle.SetModel(model); + + //! @note Push Constants is pretty much how we can modify data without needing to record command buffers again. + + // triangle.SetColor({.1f, .8f, .1f}); + // triangle.SetColor({.1f, .8f, .1f}); + // triangle.SetColor({.1f, .8f, .1f}); + // Transform2DComponent transform; + // transform.Translation.x = .2f; + // transform.scale = {2.f, .5f}; + // transform.rotation = .25f * glm::two_pi(); + // triangle.SetTranslation(transform); + + // m_GameObjects.push_back(std::move(triangle)); + std::vector colors{ + {1.f, .7f, .73f}, + {1.f, .87f, .73f}, + {1.f, 1.f, .73f}, + {.73f, 1.f, .8f}, + {.73, .88f, 1.f} // + }; + + //! @note Loading 40 triangles. + for(int i = 0; i < 40; i++){ + auto triangle = SceneObject::Create(); + triangle.SetModel(model); + triangle.m_Transform2D.scale = glm::vec2(.5f) + i * 0.0025f; + triangle.m_Transform2D.rotation = glm::pi() * .00002f; + triangle.SetColor(colors[i % colors.size()]); + m_GameObjects.push_back(triangle); + } + + GlobalUpdateManager::GetInstance()->SubscribeApplicationUpdate(this, &EditorApplication::OnApplicationUpdate); + } EditorApplication::~EditorApplication() {} - void EditorApplication::UpdateThisApplicationInstance(){ - + void EditorApplication::OnRender(uint32_t image_index){ + + // for(uint32_t i = 0; i < m_CommandBuffers.size(); i++){ + VkCommandBufferBeginInfo cmd_buf_begin_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO + }; + + // START OF COMMAND BUFFER RECORD + vk::vk_check(vkBeginCommandBuffer(m_CommandBuffers[image_index], &cmd_buf_begin_info), "vkBeginCommandBuffer", __FILE__, __LINE__, __FUNCTION__); + + // starting render pass + VkRenderPassBeginInfo rp_begin_info = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderPass = ApplicationInstance::GetWindow().GetCurrentSwapchain()->GetRenderPass(), + .framebuffer = ApplicationInstance::GetWindow().GetCurrentSwapchain()->GetFramebuffer(image_index), // Specifying which framebuffer to render pass to. + .renderArea = { + .offset = {0, 0}, + .extent = {ApplicationInstance::GetWindow().GetWidth(), ApplicationInstance::GetWindow().GetHeight()} + } + }; + + std::array clearValues; + clearValues[0].color = {0.1f, 0.1f, 0.1f, 1.0f}; + clearValues[1].depthStencil = {1.0f, 0}; + + rp_begin_info.clearValueCount = static_cast(clearValues.size()); + rp_begin_info.pClearValues = clearValues.data(); + + /* + if(ApplicationInstance::GetWindow().GetCurrentSwapchain()->GetRenderPass() == VK_NULL_HANDLE){ + ConsoleLogInfo("Renderpass Read at index i = {} is not valid", i); + } + else{ + ConsoleLogInfo("Renderpass Read at index i = {} is valid", i); + } + + if(ApplicationInstance::GetWindow().GetCurrentSwapchain()->GetFramebuffer(i) == VK_NULL_HANDLE){ + ConsoleLogInfo("Framebuffer Read at index i = {} is not valid", i); + } + else{ + ConsoleLogInfo("Framebuffer Read at index i = {} is valid", i); + } + */ + + vkCmdBeginRenderPass(m_CommandBuffers[image_index], &rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); + + //! @note We can probably add this into Shader::Bind() + //! @note Usage: m_Shader.Bind(m_CommandBuffers[i]); + + //! @note Give some cool effects + int i = 0; + for(auto& obj : m_GameObjects){ + i += 1; + obj.m_Transform2D.rotation = glm::mod(obj.m_Transform2D.rotation + 0.001f * i, 2.f * glm::pi()); + // obj.m_Transform2D.Translation.x = glm::mod(obj.m_Transform2D.rotation + 0.00001f * i, 2.f * glm::pi()); + // obj.m_Transform2D.Translation.y = glm::mod(obj.m_Transform2D.rotation + 0.00001f * i, 2.f * glm::pi()); + + // obj.SetRotation(glm::mod(obj.m_Transform2D.rotation + 0.001f * i, 2.f * glm::pi())); + } + + + //! @note Essentially doing m_Pipeline->Bind(m_CommandBuffer[i]) + //! @note Starts when to start rendering!! + vkCmdBindPipeline(m_CommandBuffers[image_index], VK_PIPELINE_BIND_POINT_GRAPHICS, m_Shader->GetGraphicsPipeline()); + // vkCmdDraw(m_CommandBuffers[i], 3, 1, 0, 0); + // model->Bind(m_CommandBuffers[i]); + // model.Bind(m_CommandBuffers[i]); + + //! @note Only for testing purposes for mesh data. + /* + for(int j = 0; j < 4; j++){ + SimplePushConstantData push{ + .Offsets = {0.0f, -0.4f + j * 0.25f}, + .Color = {0.0f, 0.0f, 0.2f + 0.2f * j} + }; + + vkCmdPushConstants( + m_CommandBuffers[i], + m_PipelineLayout, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + 0, + sizeof(SimplePushConstantData), + &push + ); + + model->Draw(m_CommandBuffers[i]); + // model.Draw(m_CommandBuffers[i]); + } + */ + + //! @note + for(auto& obj : m_GameObjects){ + obj.m_Transform2D.rotation = glm::mod(obj.GetTransform().rotation + 0.001f, glm::two_pi()); + + SimplePushConstantData push = { + .Transform = obj.GetTransform().mat2(), + // .Transform = glm::mod(obj.GetTransform().rotation * 0.1f, glm::two_pi()), + .Offsets = obj.GetTransform().Translation, + .Color = obj.GetColor(), + }; + vkCmdPushConstants( + m_CommandBuffers[image_index], + m_PipelineLayout, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + 0, + sizeof(SimplePushConstantData), + &push + ); + + obj.GetModel()->Bind(m_CommandBuffers[image_index]); + obj.GetModel()->Draw(m_CommandBuffers[image_index]); + } + + vkCmdEndRenderPass(m_CommandBuffers[image_index]); + + // END OF COMMAND BUFFER RECORDING + vk::vk_check(vkEndCommandBuffer(m_CommandBuffers[image_index]), "vkEndCommandBuffer", __FILE__, __LINE__, __FUNCTION__); + } + + // void EditorApplication::UpdateThisApplicationInstance(){ + void EditorApplication::OnApplicationUpdate(){ //! @note Just testing to see if application still closes cleanly. // if(InputPoll::IsKeyPressed(ENGINE_KEY_ESCAPE)){ // exit(0); @@ -29,6 +278,28 @@ namespace engine3d{ // Renderer::Presentation(); // ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. // ImGui::End(); + + /* + @note This is going to be what we will implement next in the Renderer.hpp/.cpp once we can render the triangle. + @note The idea is in the application this the swapchain should not be called directly by the application developer. + @note Want to migrate to doing this so its easier for testability and submitting commands/drawcalls to vulkan's API. + @note Realistically we'll have VulkanRenderer that would be accepting these structures. + Renderer::Submit([](){ + vkCmdBeginRenderPass(m_CommandBuffers[i], &rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); + + vkCmdBindPipeline(m_CommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_Shader.GetGraphicsPipeline()); + vkCmdDraw(m_CommandBuffers[i], 3, 1, 0, 0); + + vkCmdEndRenderPass(m_CommandBuffers[i]); + + vk::vk_check(vkEndCommandBuffer(m_CommandBuffers[i]), "vkEndCommandBuffer", __FILE__, __LINE__, __FUNCTION__); + }); + */ + uint32_t image_index = ApplicationInstance::GetWindow().GetCurrentSwapchain()->AcquireNextImage(); + + OnRender(image_index); + + ApplicationInstance::GetWindow().GetCurrentSwapchain()->SubmitCommandBuffer(&m_CommandBuffers[image_index]); } ApplicationInstance* InitializeApplication(){ diff --git a/Editor/Editor/Editor.hpp b/Editor/Editor/Editor.hpp index dd9af2f..81925ee 100644 --- a/Editor/Editor/Editor.hpp +++ b/Editor/Editor/Editor.hpp @@ -1,6 +1,8 @@ #pragma once -// #include -#include +#include +#include +#include +#include namespace engine3d{ @@ -11,14 +13,26 @@ namespace engine3d{ public: EditorApplication(const std::string& debugName = "Engine3D Editor"); virtual ~EditorApplication(); - private: + //! @note TODO -- Probably have a cleanup handler for this //! @note Such as WorldCleanup() or some API to make sure we can cleanly deallocate and delete things... // void ShutdownEditor(); - void UpdateThisApplicationInstance() override; + // void UpdateThisApplicationInstance() override; + void OnApplicationUpdate(); + + private: + //! @note Basically to differentiate draw calls with initialization tasks + void OnRender(uint32_t image_index); private: //! @note Editor application, Engine, UI Layer. float m_LastFrameTime = 0.0f; + //! @note Essentially our VulkanShader is VkPipeline, ShaderModule all in one. + Ref m_Shader; + VkPipelineLayout m_PipelineLayout; + VkCommandPool m_CommandPool; + std::vector m_CommandBuffers; + + std::vector m_GameObjects; }; }; \ No newline at end of file diff --git a/TestApp/Application.cpp b/TestApp/Application.cpp new file mode 100644 index 0000000..d04d8eb --- /dev/null +++ b/TestApp/Application.cpp @@ -0,0 +1,19 @@ +#include "Core/EngineLogger.hpp" +#include +#include "SceneTest/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.hpp" +#include + +namespace engine3d{ + class TestbedApplication : public ApplicationInstance{ + public: + // TestbedApplication() = default; + TestbedApplication(const std::string& p_DebugName="Show Case") : ApplicationInstance(p_DebugName) {} + private: + ShowCaseSceneInstance m_SceneManager; + }; + + ApplicationInstance* InitializeApplication(){ + printf("getting application\n"); + return new TestbedApplication(); + } +}; \ No newline at end of file diff --git a/TestApp/CMakeLists.txt b/TestApp/CMakeLists.txt new file mode 100644 index 0000000..e923169 --- /dev/null +++ b/TestApp/CMakeLists.txt @@ -0,0 +1,79 @@ +cmake_minimum_required(VERSION 3.15) +project(TestApp CXX) + +# find_package(Vulkan REQUIRED) + +# find_package(engine3d CONFIG REQUIRED) +add_executable(${PROJECT_NAME} + Application.cpp + + #To Test + SceneTest/Scenes/Assets/Components/testComp.hpp + SceneTest/src/Scenes/Assets/Components/testComp.cpp + + #Physics + SceneTest/Scenes/Assets/Components/Physics/PhysicsBody3D.hpp + SceneTest/src/Scenes/Assets/Components/Physics/PhysicsBody3D.cpp + + SceneTest/Scenes/Assets/Components/Bodies/BodyContainer.hpp + SceneTest/src/Scenes/Assets/Components/Bodies/BodyContainer.cpp + + + #Body Shapes + SceneTest/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.hpp + SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.cpp + + SceneTest/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.hpp + SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.cpp + + #Scenes + SceneTest/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.hpp + SceneTest/src/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.cpp + + +) + +target_include_directories(${PROJECT_NAME} PUBLIC SceneTest) +target_include_directories(${PROJECT_NAME} PRIVATE ../) + +target_compile_definitions(${PROJECT_NAME} PRIVATE ${dev_definitions}) + +find_package(OpenGL REQUIRED) +find_package(glfw3 REQUIRED) + +find_package(Vulkan REQUIRED) +find_package(VulkanHeaders REQUIRED) + +if(LINUX) +find_package(VulkanLoader REQUIRED) +endif(LINUX) + +# target_include_directories(${PROJECT_NAME} PUBLIC ${ENGINE_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ../) +find_package(glm REQUIRED) +find_package(fmt REQUIRED) +find_package(spdlog REQUIRED) +find_package(yaml-cpp REQUIRED) +find_package(imguidocking REQUIRED) +find_package(box2d REQUIRED) +find_package(joltphysics REQUIRED) +find_package(EnTT REQUIRED) + + +target_link_libraries( + ${PROJECT_NAME} + PRIVATE + glfw + ${OPENGL_LIBRARIES} + Vulkan::Vulkan + vulkan-headers::vulkan-headers + glm::glm + fmt::fmt + spdlog::spdlog + yaml-cpp::yaml-cpp + imguidocking::imguidocking + box2d::box2d + Jolt::Jolt + EnTT::EnTT + engine3d +) \ No newline at end of file diff --git a/TestApp/SceneTest/Scenes/Assets/Components/Bodies/BodyContainer.hpp b/TestApp/SceneTest/Scenes/Assets/Components/Bodies/BodyContainer.hpp new file mode 100644 index 0000000..2fcd601 --- /dev/null +++ b/TestApp/SceneTest/Scenes/Assets/Components/Bodies/BodyContainer.hpp @@ -0,0 +1,11 @@ +#include +// Jolt Includes +class BodyContainer +{ + public: + BodyContainer(); + + operator JPH::BodyID() { return m_BodyID; } + JPH::BodyCreationSettings m_BodySettings; + JPH::BodyID m_BodyID; +}; \ No newline at end of file diff --git a/TestApp/SceneTest/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.hpp b/TestApp/SceneTest/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.hpp new file mode 100644 index 0000000..5ec67a1 --- /dev/null +++ b/TestApp/SceneTest/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.hpp @@ -0,0 +1,6 @@ +#include +class BoxShaper : public BodyContainer +{ + public: + BoxShaper(); +}; \ No newline at end of file diff --git a/TestApp/SceneTest/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.hpp b/TestApp/SceneTest/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.hpp new file mode 100644 index 0000000..472f82d --- /dev/null +++ b/TestApp/SceneTest/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.hpp @@ -0,0 +1,6 @@ +#include +class SphereShaper : public BodyContainer +{ + public: + SphereShaper(); +}; \ No newline at end of file diff --git a/TestApp/SceneTest/Scenes/Assets/Components/Physics/PhysicsBody3D.hpp b/TestApp/SceneTest/Scenes/Assets/Components/Physics/PhysicsBody3D.hpp new file mode 100644 index 0000000..4b4fc6c --- /dev/null +++ b/TestApp/SceneTest/Scenes/Assets/Components/Physics/PhysicsBody3D.hpp @@ -0,0 +1,34 @@ + +#pragma once + +#include "Core/SceneManagment/Components/GameComponent.hpp" +#include +#include +#include +#include + +#include +// This is a test version of this class as there is to much +class PhysicsBody3D: public engine3d::GameComponent +{ + public: + PhysicsBody3D(BodyContainer * p_bodyCon); + ~PhysicsBody3D(); + void OnIntegrate(); + void Update(); + void LateUpdate(); + void PhysicsUpdate(); + void Begin(); + BodyContainer* GetBody(); + + void SetScale(float x, float y, float z); + void SetPosition(float x, float y, float z); + void SetRotation(Quat quaternion); + + private: + engine3d::Transform* m_Transform; + PhysicsBody3D() = default; + BodyContainer * bodyType; + JPH::BodyInterface* m_interface; + bool once = false; +}; diff --git a/TestApp/SceneTest/Scenes/Assets/Components/testComp.hpp b/TestApp/SceneTest/Scenes/Assets/Components/testComp.hpp new file mode 100644 index 0000000..f0cf5d5 --- /dev/null +++ b/TestApp/SceneTest/Scenes/Assets/Components/testComp.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "Scenes/Assets/Components/Physics/PhysicsBody3D.hpp" +#include + + class testComp : public engine3d::GameComponent + { + public: + void OnIntegrate(); + void Update(); + void LateUpdate(); + void PhysicsUpdate(); + private: + bool t_Secret = false; + BodyContainer * m_rb; + }; \ No newline at end of file diff --git a/TestApp/SceneTest/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.hpp b/TestApp/SceneTest/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.hpp new file mode 100644 index 0000000..2195ca0 --- /dev/null +++ b/TestApp/SceneTest/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.hpp @@ -0,0 +1,14 @@ +#include "Core/ApplicationManager/Scene.hpp" +#include "Core/SceneManagment/SceneObjects/SceneObject.hpp" +class ShowCaseSceneInstance +{ + public: + ShowCaseSceneInstance(); + ~ShowCaseSceneInstance(); + engine3d::Scene* m_Scene; + std::vector m_SceneObjects; + engine3d::Scene* GetScene(); + + private: + void CreateObjects(); +}; \ No newline at end of file diff --git a/TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/BodyContainer.cpp b/TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/BodyContainer.cpp new file mode 100644 index 0000000..a4284db --- /dev/null +++ b/TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/BodyContainer.cpp @@ -0,0 +1,6 @@ +#include + +BodyContainer::BodyContainer() +{ + // will add more settings and configurations later +} diff --git a/TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.cpp b/TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.cpp new file mode 100644 index 0000000..566bb88 --- /dev/null +++ b/TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/BoxShaper.cpp @@ -0,0 +1,19 @@ +#include +using namespace JPH; +using namespace JPH::literals; +using namespace engine3d; +BoxShaper::BoxShaper() +{ + JoltHandler * temp = engine3d::JoltHandler::GetInstance(); + m_BodySettings = BodyCreationSettings( + temp->m_BoxShapeScaled, + RVec3(0.0_r, -1.0_r, 0.0_r), + Quat::sIdentity(), + EMotionType::Static, + Engine3DLayers::Static + ); + + m_BodyID = temp->getInterface()->CreateAndAddBody( + m_BodySettings, + EActivation::DontActivate); +} \ No newline at end of file diff --git a/TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.cpp b/TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.cpp new file mode 100644 index 0000000..eec65a1 --- /dev/null +++ b/TestApp/SceneTest/src/Scenes/Assets/Components/Bodies/Shapes/SphereShaper.cpp @@ -0,0 +1,21 @@ +#include +using namespace JPH; +using namespace JPH::literals; +using namespace engine3d; +SphereShaper::SphereShaper() +{ + JoltHandler * temp = engine3d::JoltHandler::GetInstance(); + + + m_BodySettings = BodyCreationSettings( + temp->m_SphereShapeScaled, + RVec3(0.0_r, 4.0_r, 0.0_r), + Quat::sIdentity(), + EMotionType::Dynamic, + Engine3DLayers::Dynamic + ); + + m_BodyID = temp->getInterface()->CreateAndAddBody( + m_BodySettings, + EActivation::Activate); +} \ No newline at end of file diff --git a/TestApp/SceneTest/src/Scenes/Assets/Components/Physics/PhysicsBody3D.cpp b/TestApp/SceneTest/src/Scenes/Assets/Components/Physics/PhysicsBody3D.cpp new file mode 100644 index 0000000..3701bd8 --- /dev/null +++ b/TestApp/SceneTest/src/Scenes/Assets/Components/Physics/PhysicsBody3D.cpp @@ -0,0 +1,111 @@ +#include + +#include +#include +#include +#include +#include +#include +using namespace engine3d; +PhysicsBody3D::PhysicsBody3D(BodyContainer * p_bodyCon) +{ + bodyType = p_bodyCon; +} + +void PhysicsBody3D::OnIntegrate() +{ + SyncUpdateManager::GetInstance()->Subscribe + (this, &PhysicsBody3D::Update); + SyncUpdateManager::GetInstance()->Subscribe + (this, &PhysicsBody3D::LateUpdate); + SyncUpdateManager::GetInstance()->Subscribe + (this, &PhysicsBody3D::PhysicsUpdate); + + // Probably should be an event or called when activated + //! @note For now just calling Begin on integrate + + Begin(); +} + +void PhysicsBody3D::Begin() +{ + m_interface = engine3d::JoltHandler::GetInstance()->getInterface(); + m_Transform = &m_GameObjectRef->SceneGetComponent(); +} + +void PhysicsBody3D::Update() +{ + + //Convert Posiitons + m_Transform->m_Position.x = m_interface-> + GetCenterOfMassPosition(bodyType->m_BodyID).GetX(); + m_Transform->m_Position.y = m_interface-> + GetCenterOfMassPosition(bodyType->m_BodyID).GetY(); + m_Transform->m_Position.z = m_interface-> + GetCenterOfMassPosition(bodyType->m_BodyID).GetZ(); + + //Convert Rotations + m_Transform->m_QuaterionRot.x = m_interface-> + GetRotation(bodyType->m_BodyID).GetX(); + m_Transform->m_QuaterionRot.y = m_interface-> + GetRotation(bodyType->m_BodyID).GetY(); + m_Transform->m_QuaterionRot.z = m_interface-> + GetRotation(bodyType->m_BodyID).GetZ(); + m_Transform->m_QuaterionRot.w = m_interface-> + GetRotation(bodyType->m_BodyID).GetW(); + + //Convert Rotations + m_Transform->m_AxisRotation.x = m_interface-> + GetRotation(bodyType->m_BodyID).GetEulerAngles().GetX(); + m_Transform->m_AxisRotation.y = m_interface-> + GetRotation(bodyType->m_BodyID).GetEulerAngles().GetY(); + m_Transform->m_AxisRotation.z = m_interface-> + GetRotation(bodyType->m_BodyID).GetEulerAngles().GetZ(); + + // std::print("Rotation: (X: {0}, Y: {1}, Z: {2})\n", + // m_Transform->m_AxisRotation.x, + // m_Transform->m_AxisRotation.y, + // m_Transform->m_AxisRotation.z); + +} + +void PhysicsBody3D::SetScale(float x, float y, float z) +{ + m_interface->GetShape(bodyType->m_BodyID)->ScaleShape(RVec3(x,y,z)); +} + +void PhysicsBody3D::SetPosition(float x, float y, float z) +{ + m_interface->SetPosition( + bodyType->m_BodyID, + RVec3(x,y,z), + JPH::EActivation::Activate); +} + +void PhysicsBody3D::SetRotation(Quat quaternion) +{ + m_interface->SetRotation( + bodyType->m_BodyID, + quaternion, + JPH::EActivation::Activate); +} + +void PhysicsBody3D::LateUpdate() +{ + +} + +void PhysicsBody3D::PhysicsUpdate() +{ + +} + +BodyContainer* PhysicsBody3D::GetBody() +{ + return bodyType; +} + +PhysicsBody3D::~PhysicsBody3D() +{ + delete bodyType; +} \ No newline at end of file diff --git a/TestApp/SceneTest/src/Scenes/Assets/Components/testComp.cpp b/TestApp/SceneTest/src/Scenes/Assets/Components/testComp.cpp new file mode 100644 index 0000000..91a6bc4 --- /dev/null +++ b/TestApp/SceneTest/src/Scenes/Assets/Components/testComp.cpp @@ -0,0 +1,49 @@ +// #include +#include "Core/SceneManagment/Components/GameComponent.hpp" +#include "Physics/JoltHandler.hpp" +#include "Scenes/Assets/Components/Physics/PhysicsBody3D.hpp" +#include +#include +#include +#include +#include +#include +// #include "Scene" + +using namespace engine3d; + void testComp::OnIntegrate() + {; + SyncUpdateManager::GetInstance()->Subscribe + (this, &testComp::Update); + SyncUpdateManager::GetInstance()->Subscribe + (this, &testComp::LateUpdate); + SyncUpdateManager::GetInstance()->Subscribe + (this, &testComp::PhysicsUpdate); + + // Need an activation and start funciton + m_rb = m_GameObjectRef->SceneGetComponent().GetBody(); + + } + + void testComp::Update() + { + if(InputPoll::IsKeyPressed(KeyCode::F5)) + { + JoltHandler::GetInstance()-> + getInterface()->AddForce( + m_rb->m_BodyID, + RVec3(0.0f,100000.0f,0.0f), + EActivation::Activate + ); + } + } + + void testComp::LateUpdate() + { + + } + + void testComp::PhysicsUpdate() + { + + } \ No newline at end of file diff --git a/TestApp/SceneTest/src/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.cpp b/TestApp/SceneTest/src/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.cpp new file mode 100644 index 0000000..1e2706e --- /dev/null +++ b/TestApp/SceneTest/src/Scenes/Assets/SceneInstances/ShowCaseSceneInstance.cpp @@ -0,0 +1,41 @@ +#include "Core/ApplicationManager/Scene.hpp" +#include "Core/SceneManagment/SceneObjects/SceneObject.hpp" +#include "Scenes/Assets/Components/Physics/PhysicsBody3D.hpp" +#include "Scenes/Assets/Components/testComp.hpp" +#include +#include +#include + +ShowCaseSceneInstance::ShowCaseSceneInstance() +{ + m_Scene = new engine3d::Scene(); + printf("getting here\n"); + CreateObjects(); + +} + +void ShowCaseSceneInstance::CreateObjects() +{ + //Platform + m_SceneObjects.push_back(new engine3d::SceneObject(m_Scene)); + BodyContainer * l_Body = new BoxShaper(); + m_SceneObjects[0]->AddComponent(l_Body); + m_SceneObjects[0]->name = "Platform1"; + + //Sphere + m_SceneObjects.push_back(new engine3d::SceneObject(m_Scene)); + l_Body = new SphereShaper(); + m_SceneObjects[1]->AddComponent(l_Body); + m_SceneObjects[1]->AddComponent(); + m_SceneObjects[1]->name = "Ball"; + +} + +ShowCaseSceneInstance::~ShowCaseSceneInstance() +{ + delete m_Scene; + for(auto obj : m_SceneObjects) + { + delete obj; + } +} \ No newline at end of file diff --git a/colorful_triangle/compile_shaders.sh b/colorful_triangle/compile_shaders.sh new file mode 100644 index 0000000..5aa7404 --- /dev/null +++ b/colorful_triangle/compile_shaders.sh @@ -0,0 +1,2 @@ +glslc.exe simple_shader.vert -o simple_shader.vert.spv +glslc.exe simple_shader.frag -o simple_shader.frag.spv diff --git a/colorful_triangle/simple_shader.frag b/colorful_triangle/simple_shader.frag new file mode 100644 index 0000000..b981055 --- /dev/null +++ b/colorful_triangle/simple_shader.frag @@ -0,0 +1,10 @@ +#version 450 + + +layout(location = 0) in vec3 fragColor; + +layout(location = 0) out vec4 outColor; + +void main(){ + outColor = vec4(fragColor, 0.0); +} \ No newline at end of file diff --git a/colorful_triangle/simple_shader.frag.spv b/colorful_triangle/simple_shader.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..43d2f81d8ad249bad7466d20509050a625450689 GIT binary patch literal 572 zcmYk2%}T>i5QWF4X=`i$Ea*-uE`{PkMG)PHWD}_31B8-93BB;HfdaBA1S;}jh8Ls ze3#S-z8G~~-+ZUN+7%D0e6^9B5Z`%u-7MZJFwhhpPar7h@muv1ImPR#b8YT?q;pHy zRCz2uZ=y$ks&7Y?zXE<+_Go~?@2bM5hu>4xuW&egdOU!gtA{&K64!bIe$XP=@h!wx xy%WmrzLNQ8q0A0TOywUNl^7ZoZ(L&Rf0BFrA1axL&pkfwrOJD_`;p5VFFODL literal 0 HcmV?d00001 diff --git a/colorful_triangle/simple_shader.vert b/colorful_triangle/simple_shader.vert new file mode 100644 index 0000000..07daf1a --- /dev/null +++ b/colorful_triangle/simple_shader.vert @@ -0,0 +1,17 @@ +#version 450 + +// vec2 positions[3] = vec2[]( +// vec2(0.0, -0.5), +// vec2(0.5, 0.5), +// vec2(-0.5, 0.5) +// ); + +layout(location = 0) in vec2 Position; +layout(location = 1) in vec3 Color; + +layout(location = 0) out vec3 fragColor; + +void main(){ + gl_Position = vec4(Position, 0.0, 1.0); + fragColor = Color; +} \ No newline at end of file diff --git a/colorful_triangle/simple_shader.vert.spv b/colorful_triangle/simple_shader.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..75fe19c4a1749812a3aef036e98214f0c3e8cc43 GIT binary patch literal 1080 zcmYk4-Afxm6vf9RYhpA>V~kqsN5sd1^r4nQX+>1F4*@NLuS-Z)8CW-AvzE3`{%!tM zeJS+(W_LnHu6NG4UuW*7S~;m3vtrgw%N(2HbWKH!5x44mIJ_I4&hyFX$FmP)v`y6| zlG8D3?q1XXr;$woE!n2*Kz1an>aQaIs)Cwnns69}H#gz%IvUSr(LDd1#8G0?IGWfj z9_RLFOkQIt&!*$#d9s`kC}VkMAg$|~@t8!nadsbPdHhRIY{7FUHl5qtPE)aUm(Lp< zZ`1tF{?TM=iWr&|yG-ot%FgpqI*u1HHbCq-Nfxm{@8s>AK!5CDF|g#=$wM}JyqqS} z%yBihBagqUj(2dp_gwK!_*%wz4vplY$8+4_*iWbkck)6pXgZW}!01`Vd@nFFda9!C zSUu>;eOtFx`GIUl_4@HR%&fj}Lw+FRye~1o5c=&4H|42^JJbzrz6UXEpu7!v|Bf#u zX18$6X}i3lFLS^h83$c&L=hVN|o!Mxm|2uhV z;E3;+cX;}P*{zTJo%%SKT{HiazBxMCA%~j3VgmWEV$s}_q4$Sa=5Cjq+=AOFIeOko qDOz`B #include #include -#include "internal/API.hpp" +#include #include namespace engine3d{ @@ -13,6 +14,7 @@ namespace engine3d{ */ // class Window; class ApplicationInstance{ + // friend class GlobalUpdateManager; public: ApplicationInstance(const std::string&); void ExecuteApplicationMainloop(); @@ -31,9 +33,9 @@ namespace engine3d{ static API CurrentAPI(); private: //! @note - void UpdateCurrentApplicationInstance(); + // void UpdateCurrentApplicationInstance(); private: - virtual void UpdateThisApplicationInstance() = 0; + // virtual void UpdateThisApplicationInstance() = 0; private: Window* m_Window; diff --git a/engine3d/Core/ApplicationManager/GameObjManager/UUID.hpp b/engine3d/Core/ApplicationManager/GameObjManager/UUID.hpp new file mode 100644 index 0000000..d5fc466 --- /dev/null +++ b/engine3d/Core/ApplicationManager/GameObjManager/UUID.hpp @@ -0,0 +1,35 @@ +#pragma once +#include +#include +#include + +namespace engine3d{ + /** + * @name UUID + * @note Traditionally a 128-bit value, as it is normally defined + * @note Few options for generating these values + * + * @note Generate UUID by construction + */ + class UUID{ + public: + UUID(); + UUID(uint64_t newID); + UUID(const UUID& id) : uuid(id.uuid) {} + + //! @note Treat our UUID's as a uint64_t (at least returning our actual uuid) + operator uint64_t() const { return uuid; } + + private: + uint64_t uuid; + }; +}; + +namespace std{ + template<> + struct hash{ + std::size_t operator()(const engine3d::UUID& uuid) const { + return hash()((uint64_t)uuid); + } + }; +}; \ No newline at end of file diff --git a/engine3d/Core/ApplicationManager/Scene.hpp b/engine3d/Core/ApplicationManager/Scene.hpp new file mode 100644 index 0000000..5515d32 --- /dev/null +++ b/engine3d/Core/ApplicationManager/Scene.hpp @@ -0,0 +1,14 @@ +#pragma once +#include + +namespace engine3d { + class Scene { + public: + entt::registry m_SceneRegistry; + ~Scene(); + + private: + // Add more later + + }; +}; diff --git a/engine3d/Core/ApplicationManager/ThreadMngr.hpp b/engine3d/Core/ApplicationManager/ThreadMngr.hpp new file mode 100644 index 0000000..3d721e8 --- /dev/null +++ b/engine3d/Core/ApplicationManager/ThreadMngr.hpp @@ -0,0 +1,29 @@ +#pragma once +#include +#include +// #include +#include + + +namespace engine3d +{ + class ThreadMngr + { + public: + ThreadMngr(); + ~ ThreadMngr(); + void ThreadHandler(); + void OnRun(float p_DeltaTime); + SyncUpdateManager * getSyncManager(); + bool m_ThreadStop = false; + private: + std::jthread syncUpdateThread; + void UpdateSyncFunction(); + SyncUpdateManager * m_SyncManager = NULL; + float m_DeltaTime = 0.0f; + + //test stuff + Scene *t_NewScene = NULL; + + }; +}; diff --git a/engine3d/Core/Core.hpp b/engine3d/Core/Core.hpp index 6902e93..364b182 100644 --- a/engine3d/Core/Core.hpp +++ b/engine3d/Core/Core.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -26,6 +27,13 @@ namespace engine3d{ assert(x); } + constexpr void engine_assert(bool p_Exp, const std::string& p_DebugMsg){ + if(!p_Exp){ + printf("%s", p_DebugMsg.c_str()); + assert(false); + } + } + template struct member_bound_function_check { static_assert( diff --git a/engine3d/Core/Event/InputPoll.hpp b/engine3d/Core/Event/InputPoll.hpp index 750adc4..7122171 100644 --- a/engine3d/Core/Event/InputPoll.hpp +++ b/engine3d/Core/Event/InputPoll.hpp @@ -12,6 +12,9 @@ namespace engine3d{ */ class InputPoll{ public: + InputPoll() = delete; + InputPoll(const InputPoll&) = delete; + void operator=(const InputPoll&) = delete; //! @note Key/Mouse event pressed! static bool IsKeyPressed(KeyCode keycode); diff --git a/engine3d/Core/GraphicDrivers/GraphicContextDriver.hpp b/engine3d/Core/GraphicDrivers/GraphicContextDriver.hpp new file mode 100644 index 0000000..50da313 --- /dev/null +++ b/engine3d/Core/GraphicDrivers/GraphicContextDriver.hpp @@ -0,0 +1,52 @@ +#pragma once +#include +#include + +namespace engine3d{ + /** + * @name GraphicSwapchain + * @note Defines what our swapchain is going to be. + * @note Reason for this is because swapchain's API can vary if using vulkan's swapchain or DirectX3D 11/12 + */ + // class GraphicSwapchain; + class graphic_swapchain; + + /** + * @name GraphicPhysicalDeviceDriver + * @note Defines the physical GPU hardware. + * @note Fetches the GPU information. + * @note Notifies our GraphicDriver what GPU's drivers are available from the vendors. + * @note Enable selection of GPU's to submit data to. + * @note Probably use some set or map to check if specific device extensions are available on these GPU's + * @note The actual interaction to how the literal physical GPU is going to deal with our data at the last stage. + */ + // class GraphicPhysicalDriver; + class graphic_physical_driver; + + /** + * @name GraphicDriver + * @note Defines at the software level how data may the GPU use. + * @note Also defines what driver we want to submit our data to. + * @note In the moments that there may be multiple graphic_driver, we may utilize this or multiple instances of this. + */ + // class GraphicDriver; + class graphic_driver; + + /** + * @name Graphic Context Driver + * @note This defines our abstraction of other backend. + * @note Backend refers to our graphics API. Such as Vulkan, Metal, or DirectX11/12 + */ + // class GraphicContextDriver; + class graphic_context_driver{ + public: + //! @note Used to pass our instance + static VkInstance& GetInstance(); + + //! @note Passing pointers to our device/swapchain + static graphic_driver* CurrentDevice(); + static graphic_swapchain* CurrentSwapchain(); + + + }; +}; \ No newline at end of file diff --git a/engine3d/Core/GraphicDrivers/GraphicPhysicalDriver.hpp b/engine3d/Core/GraphicDrivers/GraphicPhysicalDriver.hpp new file mode 100644 index 0000000..a72aac1 --- /dev/null +++ b/engine3d/Core/GraphicDrivers/GraphicPhysicalDriver.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace engine3d{ + class GraphicPhysicalDriver{ + public: + + }; +}; \ No newline at end of file diff --git a/engine3d/Core/GraphicDrivers/GraphicSwapchain.hpp b/engine3d/Core/GraphicDrivers/GraphicSwapchain.hpp new file mode 100644 index 0000000..97e98c2 --- /dev/null +++ b/engine3d/Core/GraphicDrivers/GraphicSwapchain.hpp @@ -0,0 +1,48 @@ +#pragma once +#include +#include + +namespace engine3d{ + class GraphicSwapchain{ + public: + //! @note Initialize our swapchain + static Ref InitializeSwapchain(VkSurfaceKHR p_Surface); + + //! @note Public API's + + uint32_t GetImagesSize() const; + + VkFramebuffer GetFramebuffer(uint32_t index); + + VkImageView GetImageView(uint32_t index); + + VkSwapchainKHR GetVkSwapchainHandler(); + + VkExtent2D GetSwapchainExtent(); + + void SubmitCommandBuffer(VkCommandBuffer* p_CommandBuffers); + + //! @note Proceeds to getting next frame. + uint32_t AcquireNextImage(); + + //! @note m_CurrentFrameIdx + uint32_t GetCurrentFramePerTick(); + + VkFormat GetSwapchainFormat(); + + VkRenderPass GetRenderPass(); + + private: + virtual VkSwapchainKHR VkSwapchainHandler() = 0; + virtual VkRenderPass ReadSwapchainRenderPass() = 0; + virtual VkFormat ReadSwapchainFormat() = 0; + virtual uint32_t ImagesSize() const = 0; + virtual VkFramebuffer ReadFramebuffer(uint32_t idx) = 0; + virtual VkImageView ReadImageView(uint32_t index) = 0; + virtual VkExtent2D ReadSwapchainExtent() = 0; + virtual void SubmitAndWriteCommandBuffer(VkCommandBuffer* p_CommandBuffers) = 0; + virtual uint32_t ReadAcquiredNextFrame() = 0; + virtual uint32_t CurrentFramePerTick() = 0; + + }; +}; \ No newline at end of file diff --git a/engine3d/Core/GraphicDrivers/Shader.hpp b/engine3d/Core/GraphicDrivers/Shader.hpp new file mode 100644 index 0000000..7972ea6 --- /dev/null +++ b/engine3d/Core/GraphicDrivers/Shader.hpp @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include + +namespace engine3d{ + class Shader{ + public: + static Ref Create(const std::string p_VertShader, const std::string& p_FragShader, const vk::ShaderPipelineConfig& p_Config); + + VkPipeline GetGraphicsPipeline(); + + private: + virtual VkPipeline GraphicsPipeline() = 0; + + }; +}; \ No newline at end of file diff --git a/engine3d/Core/Renderer/Renderer.hpp b/engine3d/Core/Renderer/Renderer.hpp index 035a32e..c557768 100644 --- a/engine3d/Core/Renderer/Renderer.hpp +++ b/engine3d/Core/Renderer/Renderer.hpp @@ -1,9 +1,22 @@ #pragma once #include +#include namespace engine3d{ class Renderer{ public: + + static void BeginFrame(); + static void EndFrame(); + + template + static void Submit(const UFunction& p_Commands){ + + } + + + static void SetBackgroundColor(const std::array& rgba); + static RendererSettings& GetSettings(); }; }; \ No newline at end of file diff --git a/engine3d/Core/Scene/SceneObject.hpp b/engine3d/Core/Scene/SceneObject.hpp new file mode 100644 index 0000000..858bf05 --- /dev/null +++ b/engine3d/Core/Scene/SceneObject.hpp @@ -0,0 +1,68 @@ +#pragma once +#include +#include + +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#include +#include + +namespace engine3d{ + //! @note Creating a transform component for our scene object + struct Transform2DComponent{ + glm::vec2 Translation{}; + glm::vec2 scale = {1.f, 1.f}; + float rotation; + + glm::mat2 mat2() { + const float s = glm::sin(rotation); + const float c = glm::cos(rotation); + glm::mat2 rotation_mat = {{c, s}, {-s, c}}; + + glm::mat2 scale_mat{{scale.x, .0f}, {.0f, scale.y}}; + // return glm::mat2{1.f}; + // return scale_mat; + return rotation_mat * scale_mat; + } + }; + + //! @note Defines what our scene objects'll be. + class SceneObject{ + using id_t = unsigned int; + public: + static SceneObject Create(); + + id_t GetID() const { return m_Id; } + + void SetModel(Ref& p_Model){ + m_Model = p_Model; + } + + void SetRotation(float& p_Rotation){ + m_Transform2D.rotation = p_Rotation; + } + + void SetColor(glm::vec3 p_Color){ + m_Color = p_Color; + } + + void SetTranslation(Transform2DComponent p_Transformation){ + m_Transform2D = p_Transformation; + } + + Ref& GetModel() { return m_Model; } + glm::vec3 GetColor() { return m_Color; } + Transform2DComponent& GetTransform() { return m_Transform2D; } + + Transform2DComponent m_Transform2D; + + private: + SceneObject(id_t p_Id); + + private: + Ref m_Model; + glm::vec3 m_Color; + + id_t m_Id; + }; +}; \ No newline at end of file diff --git a/engine3d/Core/SceneManagment/Components/GameComponent.hpp b/engine3d/Core/SceneManagment/Components/GameComponent.hpp new file mode 100644 index 0000000..f846f05 --- /dev/null +++ b/engine3d/Core/SceneManagment/Components/GameComponent.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace engine3d +{ + class GameComponent + { + public: + GameComponent() = default; + ~GameComponent() = default; + + void SetSceneObjectRef(SceneObject &p_Object); + void SetComponentID(uint64_t p_CompID); + + protected: + SceneObject *m_GameObjectRef; + uint64_t m_ComponentID; + }; +}; // namespace Engine3D diff --git a/engine3d/Core/SceneManagment/Components/SPComps/Transform.hpp b/engine3d/Core/SceneManagment/Components/SPComps/Transform.hpp new file mode 100644 index 0000000..f1a187b --- /dev/null +++ b/engine3d/Core/SceneManagment/Components/SPComps/Transform.hpp @@ -0,0 +1,25 @@ +#include +#include +#include + +namespace engine3d +{ + class Transform : public GameComponent + { + public: + Transform(); + glm::vec3 m_Position; + glm::vec4 m_QuaterionRot; + glm::vec3 m_AxisRotation; + glm::vec3 m_Scale; + + + glm::lowp_vec3 GetLPPos(); + glm::lowp_vec4 GetLPQuat(); + glm::lowp_vec3 GetLPAxisRot(); + glm::lowp_vec3 GetLPSclae(); + + void OnIntegrate(); + + }; +}; \ No newline at end of file diff --git a/engine3d/Core/SceneManagment/SceneObjects/SceneObject.hpp b/engine3d/Core/SceneManagment/SceneObjects/SceneObject.hpp new file mode 100644 index 0000000..9a179c8 --- /dev/null +++ b/engine3d/Core/SceneManagment/SceneObjects/SceneObject.hpp @@ -0,0 +1,85 @@ +#pragma once + +/* + * SceneObject + * @param id - the ID of the SceneObject itself + * @note actual wrapper for SceneObject for ECS + * */ +#include +#include +#include +#include + +namespace engine3d +{ + class SceneObject + { + public: + SceneObject() = default; + SceneObject(entt::entity handle, Scene *scene); + SceneObject(const SceneObject &) = default; + SceneObject(Scene* scene); + std::string name; + + template void AddComponent(Args &&...args) + { + //! @note when adding component + T &component = m_ParentScene->m_SceneRegistry.emplace( + SceneObjectHandler, std::forward(args)...); + + // Adding refrence to component + component.SetSceneObjectRef(*(this)); + //! @note Call to component to do specific action when integrating with + //! gameObject + component.OnIntegrate(); + } + + template T &SceneGetComponent() + { + // Checking if SceneObject contains this component. + if (!this->HasComponent()) + { + throw std::exception("Found no component! Cannot add!\n"); + } + + return m_ParentScene->m_SceneRegistry.get(SceneObjectHandler); + } + + // Checking if SceneObject has a component + template bool HasComponent() + { + // has has been renamed to all_of + return m_ParentScene->m_SceneRegistry.all_of(SceneObjectHandler); + } + + template void RemoveComponent() + { + if (!this->HasComponent()) + { + throw std::exception("Found no component! Cannot delete!\n"); + } + m_ParentScene->m_SceneRegistry.remove(SceneObjectHandler); + } + + operator bool() const { return SceneObjectHandler != entt::null; } + + operator entt::entity() const { return SceneObjectHandler; } + + operator uint32_t() const { return (uint32_t)SceneObjectHandler; } + + bool operator==(const SceneObject &other) const + { + return SceneObjectHandler == other.SceneObjectHandler and + m_ParentScene == other.m_ParentScene; + } + + bool operator!=(const SceneObject &other) const { return !(*this == other); } + + UUID GetUUID() { return objectID; } + + private: + entt::entity SceneObjectHandler{entt::null}; + UUID objectID; + Scene *m_ParentScene = nullptr; // 12 bytes + }; +}; // namespace Engine3D diff --git a/engine3d/Core/TimeManagement/GlobalUpdateManager.hpp b/engine3d/Core/TimeManagement/GlobalUpdateManager.hpp new file mode 100644 index 0000000..cd5a704 --- /dev/null +++ b/engine3d/Core/TimeManagement/GlobalUpdateManager.hpp @@ -0,0 +1,89 @@ +#pragma once +// #include +#include +#include +#include +#include + +namespace engine3d +{ + /** + * @name GlobalUpdateManager + * @note Used to keep track of updates and frame data. + * @note Handles the other updateManagers. + */ + + class GlobalUpdateManager + { + private: + //! @note represents the deltaTime for all applications + float m_GlobalDeltaTime; + std::chrono::time_point m_UpdateTime; + Timer* m_GlobalTimer; + Timer* m_FPSMaintain; + + float m_MaxFPS; + int m_FPSCounter; + + public: + /* + * NEEDS FIX: Should not create raw pointers in constructors + * and deleting them in destructor. Unsafe! + */ + //! @note update specialization + template> + struct m_HasUpdate : std::false_type{}; + + template + struct m_HasUpdate().OnApplicationUpdate())>> : std::true_type {}; + + template + void SubscribeApplicationUpdate(UComponent* p_Instance, const UFunction&& p_Update) + { + ConsoleLogError("When do you get called!!!"); + ConsoleLogError("m_HasUpdate = {}", m_HasUpdate::value); + if constexpr (m_HasUpdate::value){ + ConsoleLogError("When are you getting called (2)!!"); + if(&UComponent::OnApplicationUpdate == p_Update) + { + m_ApplicationUpdateSubscribers.push_back([p_Instance, p_Update]() + { + (p_Instance->*p_Update)(); + }); + return; + } + } + throw std::runtime_error + ("Faulty subscribed function!\n \tUse update, lateUpdate, onTickUpdate!"); + } + + static GlobalUpdateManager* GetInstance() + { + static GlobalUpdateManager instance; + return &instance; + } + + /* + * NEEDS FIX: Change to a more secure way to always have one + * GlobalUpdateManager per application instance + */ + GlobalUpdateManager(); + ~GlobalUpdateManager(); + + // Manages the sync of each updateManager if required + void GlobalOnTickUpdate(); + + void OnSetUp(); + + // Maintains a const fps if possible + void WaitForNextFrame(); + + ThreadMngr * m_threadManager = NULL; + + std::vector> m_ApplicationUpdateSubscribers; + + GlobalUpdateManager(const GlobalUpdateManager&) = delete; + GlobalUpdateManager& operator=(const GlobalUpdateManager&) = delete; + }; +}; diff --git a/engine3d/Core/TimeManagement/Timer.hpp b/engine3d/Core/TimeManagement/Timer.hpp new file mode 100644 index 0000000..ec6ac89 --- /dev/null +++ b/engine3d/Core/TimeManagement/Timer.hpp @@ -0,0 +1,21 @@ +#pragma once +#include +namespace engine3d{ + class Timer{ + + public: + Timer(); + + void Reset(); + + float Elapsed(); + + float ElapsedSec(); + + std::chrono::time_point GetCurrentTime(); + + private: + std::chrono::time_point m_StopWatch; + + }; +}; \ No newline at end of file diff --git a/engine3d/Core/TimeManagement/UpdateManagers/ParallelFrameUpdateManager.hpp b/engine3d/Core/TimeManagement/UpdateManagers/ParallelFrameUpdateManager.hpp new file mode 100644 index 0000000..e9c482a --- /dev/null +++ b/engine3d/Core/TimeManagement/UpdateManagers/ParallelFrameUpdateManager.hpp @@ -0,0 +1,4 @@ +class ParallelFrameUpdateManager +{ + //Implement much later +}; \ No newline at end of file diff --git a/engine3d/Core/TimeManagement/UpdateManagers/SyncUpdateManager.hpp b/engine3d/Core/TimeManagement/UpdateManagers/SyncUpdateManager.hpp new file mode 100644 index 0000000..14905c0 --- /dev/null +++ b/engine3d/Core/TimeManagement/UpdateManagers/SyncUpdateManager.hpp @@ -0,0 +1,119 @@ +#pragma once +#include +// #include +#include +#include +#include +namespace engine3d +{ + + class SyncUpdateManager + { + private: + std::chrono::time_point m_LocalUpdateTime; + + int m_MaxVariance; + int m_MinFrames; + + Timer* m_LocalTimer; + // InputPoll* m_KeyEvent; + int m_LocalUpdateCounter; + int m_RandomFrame; + + //! @note inaccurate fps because it relies on window to call. + //! @note Jframe may solve issue but yet to be tested. + int m_LocalFPS; + + // Called EveryFrame + void OnPhysicsUpdate(); + + // Varied by random frames + void OnUpdate(); + void OnLateUpdate(); + + //! @note update specialization + template> + struct m_HasUpdate : std::false_type{}; + + template + struct m_HasUpdate().Update())>> : std::true_type {}; + + //! @note lateUpdate specialization + template> + struct m_HasLateUpdate : std::false_type{}; + + template + struct m_HasLateUpdate().LateUpdate())>> : std::true_type {}; + + //! @note onTickUpdate specialization + template> + struct m_HasPhysicsUpdate : std::false_type{}; + + template + struct m_HasPhysicsUpdate().PhysicsUpdate())>> : std::true_type {}; + + public: + std::vector> m_SyncLateUpdateSubscribers; + std::vector> m_SyncUpdateSubscribers; + std::vector> m_SyncOnTickUpdateSubscribers; + + SyncUpdateManager(); + ~SyncUpdateManager(); + float m_SyncLocalDeltaTime; + //Called by threadManager + void RunUpdate(float deltaTime); + + //Component Subscription + template + void Subscribe(UComponent* p_Instance, const UFunction&& p_Update) + { + + if constexpr (m_HasUpdate::value) + { + if(&UComponent::Update == p_Update) + { + m_SyncUpdateSubscribers.push_back([p_Instance, p_Update]() + { + (p_Instance->*p_Update)(); + }); + return; + } + } + if constexpr (m_HasLateUpdate::value) + { + if(&UComponent::LateUpdate == p_Update) + { + m_SyncLateUpdateSubscribers.push_back([p_Instance, p_Update]() + { + (p_Instance->*p_Update)(); + }); + return; + } + } + if constexpr (m_HasPhysicsUpdate::value) + { + if(&UComponent::PhysicsUpdate == p_Update) + { + m_SyncOnTickUpdateSubscribers.push_back([p_Instance, p_Update]() + { + (p_Instance->*p_Update)(); + }); + return; + } + } + throw std::runtime_error + ("Faulty subscribed function!\n \tUse update, lateUpdate, onTickUpdate!"); + } + + static SyncUpdateManager* GetInstance() + { + static SyncUpdateManager instance; + return &instance; + } + SyncUpdateManager(const SyncUpdateManager&) = delete; + SyncUpdateManager& operator=(const SyncUpdateManager&) = delete; + }; +}; diff --git a/engine3d/Core/Window.hpp b/engine3d/Core/Window.hpp index 76daaab..b445030 100644 --- a/engine3d/Core/Window.hpp +++ b/engine3d/Core/Window.hpp @@ -1,10 +1,13 @@ #pragma once -#include +#include #include #include class GLFWwindow; namespace engine3d{ + // namespace vk{ + // class VulkanSwapchain; + // }; /** * @name * @note Window-agnostic implementation @@ -13,7 +16,8 @@ namespace engine3d{ * @param GetNativeWindow returns a pointer to the actual glfw window * @param IsActive returns a boolean that is used for checking our window is active before use. * @param OnUpdateAllFrames is used for displaying in the last stages of the swapchain of images ready for to be on the actual screen. - */ + */ + class Window{ public: static Window* Create(uint32_t p_Width=900, uint32_t p_Height=600, const std::string& p_Title="Engine3D"); @@ -24,16 +28,26 @@ namespace engine3d{ * @param IWidnowSpecified is what the user defines as their window. * @note TODO --- Probably would have this be in helper_functions.h as this is an exposed to the API that uses may used to get the right API. */ + // template + // static T As(){ + // return static_cast(GetNativeWindow()); + // } bool IsActive() const; + //! @note TODO --- Replace VkSurface with something like DisplaySurface or something with this naming. + //! @note Reason is because we may have one window, but multiple surfaces that may be rendered to. VkSurfaceKHR& GetVkSurface(); + + //! @TODO: Modify vk::VulkanSwapchain into RenderSwapchain or to return an interface. + // Like this: graphic_swapchain& GetCurrentSwapchain(); + Ref GetCurrentSwapchain(); + GLFWwindow* GetNativeWindow(); uint32_t GetWidth() const; uint32_t GetHeight() const; std::string GetTitle() const; - void OnUpdateAllFrames(); protected: @@ -42,15 +56,19 @@ namespace engine3d{ virtual uint32_t Width() const = 0; virtual uint32_t Height() const = 0; virtual std::string Title() const = 0; + // virtual uint32_t SwapchainImagesSize() const = 0; virtual bool CurrentWindowActive() const = 0; + virtual VkSurfaceKHR& VkSurface() = 0; + virtual Ref Swapchain() = 0; + //! @note Returns our current set native window API. virtual GLFWwindow* NativeWindow() = 0; //! @note Update surface rendering every frame. virtual void Presentation() = 0; }; -}; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/Shaders/ShaderPipelineConfig.hpp b/engine3d/Core/internal/Vulkan2Showcase/Shaders/ShaderPipelineConfig.hpp new file mode 100644 index 0000000..1e0bb19 --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/Shaders/ShaderPipelineConfig.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace engine3d::vk{ + //! @note Used for specifying how the shader pipeline configuration may look like. + //! @note Used by VUlkanShader + struct ShaderPipelineConfig{ + VkViewport Viewport; + VkRect2D Scissor; + // VkPipelineViewportStateCreateInfo PipelineViewportCreateInfo; + VkPipelineInputAssemblyStateCreateInfo PipelineInputAsmInfo; + VkPipelineRasterizationStateCreateInfo PipelineRasterizationCreateInfo; + VkPipelineMultisampleStateCreateInfo PipelineMultisampleCreateInfo; + VkPipelineColorBlendAttachmentState PipelineColorBlendAttachments; + VkPipelineColorBlendStateCreateInfo PipelineColorBlendCreateInfo; + VkPipelineDepthStencilStateCreateInfo PipelineDepthStencilCreateInfo; + VkPipelineLayout PipelineLayout; + VkRenderPass PipelineRenderPass; + uint32_t SubpassCount; + }; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/Shaders/ShaderSpirvBins.hpp b/engine3d/Core/internal/Vulkan2Showcase/Shaders/ShaderSpirvBins.hpp new file mode 100644 index 0000000..f5fe971 --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/Shaders/ShaderSpirvBins.hpp @@ -0,0 +1,450 @@ +#pragma once +#include + +namespace engine3d::vk{ + static uint32_t spv_VertShader_bin[] = { + 0x7230203, + 0x010000, + 0x080006, + 0x000023, + 00000000, + 0x020011, + 0x000001, + 0x06000b, + 0x000001, + 0x4c534c47, + 0x6474732e, + 0x3035342e, + 00000000, + 0x03000e, + 00000000, + 0x000001, + 0x09000f, + 00000000, + 0x000004, + 0x6e69616d, + 00000000, + 0x00000d, + 0x000018, + 0x00001f, + 0x000021, + 0x030003, + 0x000002, + 0x0001c2, + 0x040005, + 0x000004, + 0x6e69616d, + 00000000, + 0x060005, + 0x00000b, + 0x505f6c67, + 0x65567265, + 0x78657472, + 00000000, + 0x060006, + 0x00000b, + 00000000, + 0x505f6c67, + 0x7469736f, + 0x6e6f69, + 0x070006, + 0x00000b, + 0x000001, + 0x505f6c67, + 0x746e696f, + 0x657a6953, + 00000000, + 0x070006, + 0x00000b, + 0x000002, + 0x435f6c67, + 0x4470696c, + 0x61747369, + 0x65636e, + 0x070006, + 0x00000b, + 0x000003, + 0x435f6c67, + 0x446c6c75, + 0x61747369, + 0x65636e, + 0x030005, + 0x00000d, + 00000000, + 0x090005, + 0x000011, + 0x65646f6d, + 0x6569566c, + 0x6f725077, + 0x7463656a, + 0x426e6f69, + 0x65666675, + 0x000072, + 0x0a0006, + 0x000011, + 00000000, + 0x65646f6d, + 0x6569566c, + 0x6f725077, + 0x7463656a, + 0x4d6e6f69, + 0x69727461, + 0x000078, + 0x030005, + 0x000013, + 00000000, + 0x040005, + 0x000018, + 0x74726576, + 0x007865, + 0x040005, + 0x00001f, + 0x4f5f5655, + 0x005455, + 0x030005, + 0x000021, + 0x007675, + 0x050048, + 0x00000b, + 00000000, + 0x00000b, + 00000000, + 0x050048, + 0x00000b, + 0x000001, + 0x00000b, + 0x000001, + 0x050048, + 0x00000b, + 0x000002, + 0x00000b, + 0x000003, + 0x050048, + 0x00000b, + 0x000003, + 0x00000b, + 0x000004, + 0x030047, + 0x00000b, + 0x000002, + 0x040048, + 0x000011, + 00000000, + 0x000005, + 0x050048, + 0x000011, + 00000000, + 0x000023, + 00000000, + 0x050048, + 0x000011, + 00000000, + 0x000007, + 0x000010, + 0x030047, + 0x000011, + 0x000002, + 0x040047, + 0x000013, + 0x000022, + 0x000001, + 0x040047, + 0x000013, + 0x000021, + 00000000, + 0x040047, + 0x000018, + 0x00001e, + 00000000, + 0x040047, + 0x00001f, + 0x00001e, + 00000000, + 0x040047, + 0x000021, + 0x00001e, + 0x000001, + 0x020013, + 0x000002, + 0x030021, + 0x000003, + 0x000002, + 0x030016, + 0x000006, + 0x000020, + 0x040017, + 0x000007, + 0x000006, + 0x000004, + 0x040015, + 0x000008, + 0x000020, + 00000000, + 0x04002b, + 0x000008, + 0x000009, + 0x000001, + 0x04001c, + 0x00000a, + 0x000006, + 0x000009, + 0x06001e, + 0x00000b, + 0x000007, + 0x000006, + 0x00000a, + 0x00000a, + 0x040020, + 0x00000c, + 0x000003, + 0x00000b, + 0x04003b, + 0x00000c, + 0x00000d, + 0x000003, + 0x040015, + 0x00000e, + 0x000020, + 0x000001, + 0x04002b, + 0x00000e, + 0x00000f, + 00000000, + 0x040018, + 0x000010, + 0x000007, + 0x000004, + 0x03001e, + 0x000011, + 0x000010, + 0x040020, + 0x000012, + 0x000002, + 0x000011, + 0x04003b, + 0x000012, + 0x000013, + 0x000002, + 0x040020, + 0x000014, + 0x000002, + 0x000010, + 0x040020, + 0x000017, + 0x000001, + 0x000007, + 0x04003b, + 0x000017, + 0x000018, + 0x000001, + 0x040020, + 0x00001b, + 0x000003, + 0x000007, + 0x040017, + 0x00001d, + 0x000006, + 0x000002, + 0x040020, + 0x00001e, + 0x000003, + 0x00001d, + 0x04003b, + 0x00001e, + 0x00001f, + 0x000003, + 0x040020, + 0x000020, + 0x000001, + 0x00001d, + 0x04003b, + 0x000020, + 0x000021, + 0x000001, + 0x050036, + 0x000002, + 0x000004, + 00000000, + 0x000003, + 0x0200f8, + 0x000005, + 0x050041, + 0x000014, + 0x000015, + 0x000013, + 0x00000f, + 0x04003d, + 0x000010, + 0x000016, + 0x000015, + 0x04003d, + 0x000007, + 0x000019, + 0x000018, + 0x050091, + 0x000007, + 0x00001a, + 0x000016, + 0x000019, + 0x050041, + 0x00001b, + 0x00001c, + 0x00000d, + 0x00000f, + 0x03003e, + 0x00001c, + 0x00001a, + 0x04003d, + 0x00001d, + 0x000022, + 0x000021, + 0x03003e, + 0x00001f, + 0x000022, + 0x0100fd, + 0x010038, + }; + + static uint32_t spv_FragShader_bin[] = { + 0x7230203, + 0x010000, + 0x080006, + 0x000014, + 00000000, + 0x020011, + 0x000001, + 0x06000b, + 0x000001, + 0x4c534c47, + 0x6474732e, + 0x3035342e, + 00000000, + 0x03000e, + 00000000, + 0x000001, + 0x07000f, + 0x000004, + 0x000004, + 0x6e69616d, + 00000000, + 0x000009, + 0x000011, + 0x030010, + 0x000004, + 0x000007, + 0x030003, + 0x000002, + 0x0001c2, + 0x040005, + 0x000004, + 0x6e69616d, + 00000000, + 0x050005, + 0x000009, + 0x67617266, + 0x6f6c6f43, + 0x000072, + 0x060005, + 0x00000d, + 0x61697274, + 0x656c676e, + 0x74786554, + 0x657275, + 0x030005, + 0x000011, + 0x005655, + 0x040047, + 0x000009, + 0x00001e, + 00000000, + 0x040047, + 0x00000d, + 0x000022, + 00000000, + 0x040047, + 0x00000d, + 0x000021, + 00000000, + 0x040047, + 0x000011, + 0x00001e, + 00000000, + 0x020013, + 0x000002, + 0x030021, + 0x000003, + 0x000002, + 0x030016, + 0x000006, + 0x000020, + 0x040017, + 0x000007, + 0x000006, + 0x000004, + 0x040020, + 0x000008, + 0x000003, + 0x000007, + 0x04003b, + 0x000008, + 0x000009, + 0x000003, + 0x090019, + 0x00000a, + 0x000006, + 0x000001, + 00000000, + 00000000, + 00000000, + 0x000001, + 00000000, + 0x03001b, + 0x00000b, + 0x00000a, + 0x040020, + 0x00000c, + 00000000, + 0x00000b, + 0x04003b, + 0x00000c, + 0x00000d, + 00000000, + 0x040017, + 0x00000f, + 0x000006, + 0x000002, + 0x040020, + 0x000010, + 0x000001, + 0x00000f, + 0x04003b, + 0x000010, + 0x000011, + 0x000001, + 0x050036, + 0x000002, + 0x000004, + 00000000, + 0x000003, + 0x0200f8, + 0x000005, + 0x04003d, + 0x00000b, + 0x00000e, + 0x00000d, + 0x04003d, + 0x00000f, + 0x000012, + 0x000011, + 0x050057, + 0x000007, + 0x000013, + 0x00000e, + 0x000012, + 0x03003e, + 0x000009, + 0x000013, + 0x0100fd, + 0x010038, + }; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/Shaders/VulkanShader.hpp b/engine3d/Core/internal/Vulkan2Showcase/Shaders/VulkanShader.hpp new file mode 100644 index 0000000..4dbde26 --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/Shaders/VulkanShader.hpp @@ -0,0 +1,38 @@ +#pragma once +#include +#include +#include +#include +// #include + +namespace engine3d::vk{ + /** + * @name Vulkan Shader + * @note Loads in the two shader modules (vertex and fragment shaders) + */ + class VulkanShader : public Shader{ + public: + VulkanShader() = default; + VulkanShader(const std::string& p_VertShader, const std::string& p_FragShader, const ShaderPipelineConfig& p_Config = {}); + ~VulkanShader(){} + + static ShaderPipelineConfig shader_configuration(uint32_t p_Width, uint32_t p_Height); + + VkPipeline GetGraphicsPipeline() { return m_GraphicsPipeline; } + + + private: + VkPipeline GraphicsPipeline() override { return m_GraphicsPipeline; } + private: + + std::vector read_file(const std::string& p_Filepath); + + void initialize_graphics_pipeline(const std::string& p_VertShader, const std::string& p_FragShader, const ShaderPipelineConfig& p_Config); + void initialize_shader_module(const std::vector& p_Bin, VkShaderModule& p_ShaderMod); + + private: + VkPipeline m_GraphicsPipeline; + VkShaderModule m_VertexShaderModule; + VkShaderModule m_FragmentShaderModule; + }; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/Vulkan.hpp b/engine3d/Core/internal/Vulkan2Showcase/Vulkan.hpp new file mode 100644 index 0000000..211ea42 --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/Vulkan.hpp @@ -0,0 +1,13 @@ +#pragma once + +#if _WIN32 +#define VK_USE_PLATFORM_WIN32_KHR +#define GLFW_INCLUDE_VULKAN +#include +#define GLFW_EXPOSE_NATIVE_WIN32 +#include +#include +#else +#include +#include +#endif \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/VulkanContext.hpp b/engine3d/Core/internal/Vulkan2Showcase/VulkanContext.hpp new file mode 100644 index 0000000..dafecdf --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/VulkanContext.hpp @@ -0,0 +1,27 @@ +#pragma once +#include +#include +#include + +namespace engine3d::vk{ + class VulkanContext{ + public: + + static void Initialize(); + static VkInstance GetVkInstance() { return s_Instance; } + + static VulkanPhysicalDriver GetPhysicalDriver() { return s_PhysicalDriver; } + + static VulkanDriver GetDriver() { return s_Driver; } + + private: + static std::vector InitializeValidationLayers(); + + static std::vector InitializeInstanceExtensions(); + + private: + static VkInstance s_Instance; + static VulkanPhysicalDriver s_PhysicalDriver; + static VulkanDriver s_Driver; + }; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/VulkanDriver.hpp b/engine3d/Core/internal/Vulkan2Showcase/VulkanDriver.hpp new file mode 100644 index 0000000..ca71730 --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/VulkanDriver.hpp @@ -0,0 +1,23 @@ +#pragma once +#include + +namespace engine3d::vk{ + class VulkanDriver{ + public: + VulkanDriver() = default; + VulkanDriver(VulkanPhysicalDriver p_PhysicalDevice); + + VkQueue GetGraphicsQueue() { return m_GraphicsQueue; } + + operator VkDevice(){ + return m_CurrentDriver; + } + + //! @note Returns -1 if there are no flags available/compatible/valid + uint32_t SelectMemoryType(uint32_t p_TypeFilter, VkMemoryPropertyFlags p_PropertyFlag); + + private: + VkDevice m_CurrentDriver; + VkQueue m_GraphicsQueue; + }; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/VulkanModel.hpp b/engine3d/Core/internal/Vulkan2Showcase/VulkanModel.hpp new file mode 100644 index 0000000..bf3bb4c --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/VulkanModel.hpp @@ -0,0 +1,42 @@ +#pragma once +#include +#include + +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#include + +namespace engine3d::vk{ + /** + * @name VulkanModel + * @note For now I am going to have each model contain vertices, indices, and so forth. + * @note And may separate the vertex/index/storage buffers as their own thing but for the time being, just gonna have them be under this one class + */ + class VulkanModel{ + public: + //! @note Can be the way we structure what data types is accepted in our shader. + struct Vertex{ + glm::vec2 Position; + glm::vec3 Color; + + static std::vector GetVertexInputBindDescription(); + static std::vector GetVertexAttributeDescriptions(); + }; + + VulkanModel() = default; + VulkanModel(const std::vector& p_Vertices, const VkBufferUsageFlags& p_UsageFlags, const VkMemoryPropertyFlags& p_PropertyFlags); + + + void Bind(VkCommandBuffer p_Command); + void Draw(VkCommandBuffer p_Command); + + + private: + void initialize_vertex_buffers(const std::vector& p_Vertices); + + private: + VkBuffer m_VertexBuffer; + VkDeviceMemory m_VertexBufferDeviceMemory; + uint32_t m_VerticesCount; + }; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/VulkanPhysicalDriver.hpp b/engine3d/Core/internal/Vulkan2Showcase/VulkanPhysicalDriver.hpp new file mode 100644 index 0000000..1ffbe5c --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/VulkanPhysicalDriver.hpp @@ -0,0 +1,36 @@ +#pragma once +#include +#include + +namespace engine3d::vk{ + class VulkanPhysicalDriver{ + public: + struct PhysicalQueueFamilyIndices{ + uint32_t Graphics = -1; + uint32_t Compute = -1; + uint32_t Transfer = -1; + }; + + VulkanPhysicalDriver() = default; + VulkanPhysicalDriver(VkInstance p_Instance); + + uint32_t GetPresentationIndex(VkSurfaceKHR p_Surface); + + PhysicalQueueFamilyIndices GetQueueIndices() { return m_QueueFamilyIndices; } + + operator VkPhysicalDevice(){ + return m_PhysicalDevice; + } + + private: + PhysicalQueueFamilyIndices SelectQueueFamilyIndices(); + + private: + VkPhysicalDevice m_PhysicalDevice; + // VkPhysicalDeviceMemoryProperties m_DeviceMemoryProperties; + std::vector m_QueueFamilyProperties; + + // checking if queue families have queues and they are graphical, compute (optional atm), transfer(optional atm) + PhysicalQueueFamilyIndices m_QueueFamilyIndices; + }; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/VulkanSwapchain.hpp b/engine3d/Core/internal/Vulkan2Showcase/VulkanSwapchain.hpp new file mode 100644 index 0000000..ed3e6f4 --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/VulkanSwapchain.hpp @@ -0,0 +1,97 @@ +#pragma once +#include +#include +#include + +namespace engine3d::vk{ + /** + * @name Vulkan Swapchain + * @note Defines the vulkan-backend implementation of a swapchain. + */ + class VulkanSwapchain : public GraphicSwapchain{ + public: + //! @note TODO: Change this into RendererConfig + static constexpr uint32_t MaxFramesInFlight = 2; + + VulkanSwapchain() = default; + VulkanSwapchain(VulkanPhysicalDriver p_PhysicalDriver, VulkanDriver p_Driver, VkSurfaceKHR p_Surface); + + private: + //! @note Graphic Swapchain virtual implementation functions + VkSwapchainKHR VkSwapchainHandler() override; + VkRenderPass ReadSwapchainRenderPass() override; + VkFormat ReadSwapchainFormat() override; + + uint32_t ImagesSize() const override; + VkFramebuffer ReadFramebuffer(uint32_t idx) override; + VkImageView ReadImageView(uint32_t index) override; + VkExtent2D ReadSwapchainExtent() override; + void SubmitAndWriteCommandBuffer(VkCommandBuffer* p_CommandBuffers) override; + uint32_t ReadAcquiredNextFrame() override; + uint32_t CurrentFramePerTick() override; + + private: + //! @note Helper functions or various operations. + VkPresentModeKHR SelectCompatiblePresentMode(const VkPresentModeKHR& p_RequestMode, const std::vector& p_Modes); + VkExtent2D SelectValidExtent(const VkSurfaceCapabilitiesKHR& p_SurfaceCapabilities); + + //! @note Search Memory Type + uint32_t SelectMemoryType(VkPhysicalDeviceMemoryProperties p_MemoryProperties, uint32_t p_TypeFilter, VkMemoryPropertyFlags property_flag); + + /** + * @note Selecting specific type of format. + * @param VkPhysicalDevice is used to extract the depth format and check if it is available on our current GPU. + */ + VkFormat SelectDepthFormat(VkPhysicalDevice p_PhysicalDevice); + + //! @note Helper function to get the format types we need. + VkFormat SelectSupportedFormat(VkPhysicalDevice p_PhysicalDevice, const std::vector& p_Formats, VkImageTiling p_Tiling, VkFormatFeatureFlags p_FeatureFlag); + + private: + VkQueue m_PresentationQueue; + + struct SwapchainImage{ + VkImage Image; + VkImageView ImageView; + }; + + struct SwapchainDepthImage{ + VkImage Image; + VkImageView ImageView; + VkDeviceMemory DeviceMemory; + }; + + //! @note Images that are either in-use for images or depth images. + std::vector m_ImagesForSwapchain; + std::vector m_DepthImagesForSwapchain; + std::vector m_FramebuffersForSwapchain; + + VkSwapchainKHR m_Swapchain; + VkSurfaceFormatKHR m_SurfaceFormat; + VkPresentModeKHR m_PresentMode; + uint32_t m_PresentationIndex; + VkExtent2D m_SwapchainExtent; + + //! @note Setting up Command Buffers + // VkCommandBuffer m_CommandBufferForSwapchain; + std::vector m_SwapchainCommandBuffers; // command buffers per swapchain + VkCommandPool m_CommandPoolForSwapchain; + + VkRenderPass m_RenderpassForSwapchain; + + //! @note Semaphores to signal when frames finished or current frame being rendered has been completed. + std::vector m_SemaphoresForAvailableImages; // semaphores for when images are available + std::vector m_SemaphoresForRenderCompleted; // semaphores when working on the current frame has been completed + + // std::vector m_InFlightFences; // fences for when frames in flight + // std::vector m_ImagesCurrentlyInFlight; // images fences for when we currently have images currently in flight. + std::vector m_ImagesInFlight; + std::vector m_InFlightFences; + VulkanDriver m_Driver; + + //! @note Current frame that we are at in the application from the start of the app. + size_t m_CurrentFrameIndex = 0; + //! @note Acts as our image index. + uint32_t m_CurrentImageIndex = 0; // contains the index of the image we are currently working through + }; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/VulkanWindow.hpp b/engine3d/Core/internal/Vulkan2Showcase/VulkanWindow.hpp new file mode 100644 index 0000000..8ccd16d --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/VulkanWindow.hpp @@ -0,0 +1,44 @@ +#pragma once +#include +#include +#include +// #include +#include +#include + +class GLFWwindow; +namespace engine3d::vk{ + + class VulkanWindow : public Window{ + public: + VulkanWindow(const std::string& p_Tag, uint32_t w, uint32_t h); + private: + uint32_t Width() const override{ return m_Width; } + uint32_t Height() const override{return m_Height; } + std::string Title() const override{return m_Title; } + + bool CurrentWindowActive() const override; + + VkSurfaceKHR& VkSurface() override; + + Ref Swapchain() override { return m_Swapchain; } + + //! @note Returns our current set native window API. + GLFWwindow* NativeWindow() override; + + + //! @note Update surface rendering every frame. + void Presentation() override; + private: + uint32_t m_Width; + uint32_t m_Height; + std::string m_Title; + GLFWwindow* m_Window; + + // VulkanPhysicalDriver m_PhysicalDriver; + // VulkanDriver m_Driver; + // VulkanSwapchain m_Swapchain; + Ref m_Swapchain; + VkSurfaceKHR m_Surface; + }; +}; \ No newline at end of file diff --git a/engine3d/Core/internal/Vulkan2Showcase/helper_functions.hpp b/engine3d/Core/internal/Vulkan2Showcase/helper_functions.hpp new file mode 100644 index 0000000..f0695f6 --- /dev/null +++ b/engine3d/Core/internal/Vulkan2Showcase/helper_functions.hpp @@ -0,0 +1,14 @@ +#pragma once +#include +#include + +namespace engine3d::vk{ + // const char* vk_to_string(VkResult res); + //! @note Terminates if the result was unsuccessful! + //! @note TODO --- We shouldn't std::terminate, look into alternatives. + void vk_check(VkResult p_Result, const char* p_Tag, const char* p_Filename, uint32_t p_LineName, const char* p_FunctionName); + + void vk_check_format(VkFormat p_Format, const char* p_Filename, uint32_t p_LineName, const char* p_FunctionName); + + std::string vk_queue_flags_to_string(VkQueueFlagBits flags); +}; \ No newline at end of file diff --git a/engine3d/Core/internal/VulkanCpp/Vulkan.hpp b/engine3d/Core/internal/VulkanCpp/Vulkan.hpp deleted file mode 100644 index 8e0deac..0000000 --- a/engine3d/Core/internal/VulkanCpp/Vulkan.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -namespace engine3d{ - namespace vk{ - /* - * @name Vulkan - * @note Used to instantiate the vulkan's application information. - * @note Essentially setting Vulkan's global state that contains information about the application - * @note Which includes extensions and validation layers used for debugging information. - * @note VKInstance used to instantiate vulkan and allows the application to pass information about itself. - */ - class Vulkan{ - public: - static void InitializeVulkanCore(); - static void CleanupVulkanCore(); - - static VkInstance& GetVkInstance(); - }; - }; -}; diff --git a/engine3d/Core/internal/VulkanCpp/VulkanDevice.hpp b/engine3d/Core/internal/VulkanCpp/VulkanDevice.hpp deleted file mode 100644 index baef831..0000000 --- a/engine3d/Core/internal/VulkanCpp/VulkanDevice.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include "internal/VulkanCpp/VulkanLogicalDevice.hpp" - -namespace engine3d::vk{ - class VulkanDevice{ - public: - static void InitializeVulkanDevice(); - static void CleanupVulkanDevices(); - - - static VulkanPhysicalDevice& GetPhysicalDevice(); - static VulkanLogicalDevice& GetLogicalDevice(); - }; -}; \ No newline at end of file diff --git a/engine3d/Core/internal/VulkanCpp/VulkanLogicalDevice.hpp b/engine3d/Core/internal/VulkanCpp/VulkanLogicalDevice.hpp deleted file mode 100644 index 642f717..0000000 --- a/engine3d/Core/internal/VulkanCpp/VulkanLogicalDevice.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include -#include -#include - -namespace engine3d{ - namespace vk{ - /* - * @name VulkanLogicalDevice - * @note Represent our vulkan interface to the physical device. - * @note Using this logical device allows for multiple application accessing the physical devices on our machine. - * @note Utilizing our selected physical device (VulkanPhysicalDevice), using this logical device to specify features/extensions with our selected physical device. - */ - class VulkanLogicalDevice{ - public: - VulkanLogicalDevice() {} - VulkanLogicalDevice(VulkanPhysicalDevice& p_PhysicalDevice); - - VkDevice GetVkDeviceInstance(); - VulkanPhysicalDevice& GetPhysicalDevice(); - VkPhysicalDeviceFeatures GetVkPhysicalDeviceFeatures(); - - VkQueue GetVkGraphicsQueue(); - VkQueue GetVkComputeQueue(); - - private: - VkDevice m_LogicalDevice = nullptr; - VulkanPhysicalDevice m_PhysicalDevice; - VkPhysicalDeviceFeatures m_EnabledPhysicalFeatures; - - //! @note Allocator stuff. - - VkQueue m_GraphicsQueue; - VkQueue m_ComputeQueue; - }; - }; -}; diff --git a/engine3d/Core/internal/VulkanCpp/VulkanPhysicalDevice.hpp b/engine3d/Core/internal/VulkanCpp/VulkanPhysicalDevice.hpp deleted file mode 100644 index 9b84000..0000000 --- a/engine3d/Core/internal/VulkanCpp/VulkanPhysicalDevice.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once -#include -#include -#include -#include - -namespace engine3d{ - namespace vk{ - /* - * @name VulkanPhysicalDevice - * @note Abstracted physical device layer for validating compatbility with our current platform's GPU. - * @note In other words represent actual physical GPU that is available on our current machine. - * @note Allows with workloads from vulkan logical devices and exposing to various queue families the GPU supports. - */ - class VulkanPhysicalDevice{ - struct QueueFamilyIndices{ - int Graphics = -1; - int Compute = -1; - int Transfer = -1; - }; - public: - VulkanPhysicalDevice(); - - VkPhysicalDevice& GetVkPhysicalDevice(); - - /* - * @name GetDepthFormat() - * @note Returns the depth format we need for image depth usage. - * @note By returning the depth format we also describe how our memory is laid out. - */ - VkFormat GetDepthFormat(); - - //! @note Returns boolean if we pass a valid extension name. - bool IsExtensionSupported(const std::string& ext_name); - private: - //! @note Returns the queue family indices to which queue family indices are supported and valid. - VulkanPhysicalDevice::QueueFamilyIndices GetQueueFamilyIndices(int flag); - - //! @note Used for validating if depth format is available or valid on our current machine. - VkFormat SearchAvailableDepthFormat(); - - //! @note print debugging information of our physical device properties. - void print_physical_device_property(VkPhysicalDeviceProperties properties); - - //! @note Fetching our devices that are compatible to use. - std::vector get_available_devices(); - - - private: - VkPhysicalDevice m_PhysicalDeviceHandler = nullptr; // actual physical device handler - VkPhysicalDevice m_SelectedPhysicalDevice = nullptr; - VkPhysicalDeviceProperties m_PhysicalDeviceProperties; // provides specications about our physical device. - VkPhysicalDeviceFeatures m_PhysicalDeviceFeatures; // enabling fine-grained features for buffer-level access - VkPhysicalDeviceMemoryProperties m_PhysicalMemoryProperties; // enable to check memory heaps that are accessible - QueueFamilyIndices m_QueueIndices; // Indices that can be request by logical devices that vary from graphics, compute, and transfer. - VkFormat m_DepthFormat = VK_FORMAT_UNDEFINED; // To validate whether depth format is supported or available from our physical devices. - - // queue family properties - std::vector m_QueueFamilyProperties; - std::vector m_DeviceQueueCreateInfos; - - std::unordered_set m_SupportedExtensions; - }; - }; -}; diff --git a/engine3d/Core/internal/VulkanCpp/VulkanRenderer.hpp b/engine3d/Core/internal/VulkanCpp/VulkanRenderer.hpp deleted file mode 100644 index da0609b..0000000 --- a/engine3d/Core/internal/VulkanCpp/VulkanRenderer.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -namespace engine3d::vk{ - class VulkanRenderer{ - public: - - }; -}; \ No newline at end of file diff --git a/engine3d/Core/internal/VulkanCpp/VulkanSwapchain.hpp b/engine3d/Core/internal/VulkanCpp/VulkanSwapchain.hpp deleted file mode 100644 index 9358d9f..0000000 --- a/engine3d/Core/internal/VulkanCpp/VulkanSwapchain.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once -#include -#include -#include -#include - -class GLFWwindow; -namespace engine3d::vk{ - - /** - * @name VulkanSwapchain - * @note Implementation of a vulkan swapchain represents our frames get rendered. - * @param p_WindowHandler is defined as our current window's swapchain. - */ - class VulkanSwapchain{ - public: - VulkanSwapchain() = default; - VulkanSwapchain(GLFWwindow* p_WindowHandler, bool p_VSync); - - uint32_t GetWidth(); - uint32_t GetHeight(); - - void Presentation(); - - private: - void SearchImageFormatAndColorspace(); - - uint32_t AcquireNextImage(); - - private: - //! @note Per-swapchain has their own respective command buffers attached to them. - struct VulkanSwapchainCommandBuffer{ - VkCommandPool CommandBufferPool = nullptr; - VkCommandBuffer CommndBufferData = nullptr; - }; - - struct SwapchainImage{ - VkImage image = nullptr; - VkImageView image_view = nullptr; - }; - - std::vector m_CommandBuffers; - std::vector m_SwapchainImages; - std::vector m_Images; - - //! @note Semaphores to indicate when the images are available for rendering - std::vector m_ImageAvailableSemaphores; - - //! @note Semaphores for indicating when images that are rendering has been finished (pairing for each frames-in-flight) - std::vector m_ImagesFinishedRenderingSemaphores; - std::vector m_Framebuffers; - std::vector m_Fences; - - uint32_t m_Width, m_Height; - uint32_t m_queue_node_idx; - - VkRenderPass m_RenderPassSwapchain = nullptr; - VkSurfaceKHR m_Surface = nullptr; - bool m_VSync; - VkFormat m_ColorFormat; - VkColorSpaceKHR m_ColorSpace; - - uint32_t m_CurrentFrameIdx = 0; - - VkSwapchainKHR m_CurrentSwapchain, m_OldSwapchain; - - bool m_DoLockForCompute=false; - std::mutex m_GraphicsMutex, m_ComputeMutex; - }; -}; \ No newline at end of file diff --git a/engine3d/Core/internal/VulkanCpp/VulkanWindow.hpp b/engine3d/Core/internal/VulkanCpp/VulkanWindow.hpp deleted file mode 100644 index 09b3a05..0000000 --- a/engine3d/Core/internal/VulkanCpp/VulkanWindow.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "Window.hpp" -#include -#include -#include - -class GLFWwindow; -namespace engine3d{ - namespace vk{ - class VulkanWindow : public Window{ - public: - VulkanWindow(uint32_t p_Width, uint32_t p_Height, const std::string& p_Title); - - protected: - uint32_t Width() const override; - uint32_t Height() const override; - std::string Title() const override; - - bool CurrentWindowActive() const override; - - VkSurfaceKHR& VkSurface() override; - - //! @note Returns our current set native window API. - GLFWwindow* NativeWindow() override; - - //! @note Update surface rendering every frame. - void Presentation() override; - - private: - GLFWwindow* m_Window; - VkSurfaceKHR m_Surface; - bool m_IsCurrentWindowActive = false; - uint32_t m_Width, m_Height; - std::string m_Title; - }; - }; -}; \ No newline at end of file diff --git a/engine3d/Math/Interpolation.hpp b/engine3d/Math/Interpolation.hpp new file mode 100644 index 0000000..f708019 --- /dev/null +++ b/engine3d/Math/Interpolation.hpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include + +namespace engine3d +{ + + //! @note think about this one for a little A function that takes a function + // for time and interpolates based of that + // template + // concept InterpolateFunction = requires(Func function) + // { + // { f(std::declval()) } -> std::convertible_to; + // }; + + class Interpolation + { + public: + template + static T& LinearInterpolate(T start, T end, Func function, float t) + { + float l_AdjustedTime = 0.0f; + if(function == NULL) + { + l_AdjustedTime = t; + } + else + { + l_AdjustedTime = function(t); + } + + + if(l_AdjustedTime < 0) + { + l_AdjustedTime = 0.0f; + } + if(l_AdjustedTime > 1.0f) + { + l_AdjustedTime = 1.0f; + } + + float timeDif = 1.0f - l_AdjustedTime; + + return start * timeDif + end * l_AdjustedTime; + } + + template + constexpr bool IsMathTypeValid(){ + if constexpr (std::same_as){ + return true; + } + + } + + private: + Interpolation() = default; + }; + + // Add a slerp version of this +}; \ No newline at end of file diff --git a/engine3d/Physics/Interaction/Engine3DActivationListener.hpp b/engine3d/Physics/Interaction/Engine3DActivationListener.hpp new file mode 100644 index 0000000..951576a --- /dev/null +++ b/engine3d/Physics/Interaction/Engine3DActivationListener.hpp @@ -0,0 +1,23 @@ +#include +#include + +#include + +using namespace JPH; + +namespace engine3d +{ + class Engine3DActivationListener : public JPH::BodyActivationListener + { + public: + virtual void OnBodyActivated(const BodyID &inBodyID, uint64 inBodyUserData) override + { + std::print("Body was activated!\n"); + } + + virtual void OnBodyDeactivated(const BodyID &inBodyID, uint64 inBodyUserData) override + { + std::print("Body is asleep...\n"); + } + }; +}; \ No newline at end of file diff --git a/engine3d/Physics/Interaction/Engine3DContactListener.hpp b/engine3d/Physics/Interaction/Engine3DContactListener.hpp new file mode 100644 index 0000000..3a428a6 --- /dev/null +++ b/engine3d/Physics/Interaction/Engine3DContactListener.hpp @@ -0,0 +1,36 @@ +#include +#include + + +#include + +using namespace JPH; + +namespace engine3d +{ + class Engine3DContactlistener : public ContactListener + { + virtual ValidateResult OnContactValidate(const Body &inBody1, const Body &inBody2, RVec3Arg inBaseOffset, const CollideShapeResult &inCollisionResult) override + { + std::print("Validating...\n"); + + // Allows you to ignore a contact before it is created (using layers to not make objects collide is cheaper!) + return ValidateResult::AcceptAllContactsForThisBodyPair; + } + + virtual void OnContactAdded(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings) override + { + std::print("Contact was added!\n"); + } + + virtual void OnContactPersisted(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings) override + { + std::print("Contact was persisted!\n"); + } + + virtual void OnContactRemoved(const SubShapeIDPair &inSubShapePair) override + { + std::print("Contact was removed!\n"); + } + }; +}; \ No newline at end of file diff --git a/engine3d/Physics/Interfaces/BPLayerInterfaceHandler.hpp b/engine3d/Physics/Interfaces/BPLayerInterfaceHandler.hpp new file mode 100644 index 0000000..85a97be --- /dev/null +++ b/engine3d/Physics/Interfaces/BPLayerInterfaceHandler.hpp @@ -0,0 +1,65 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace Engine3DLayers +{ + static constexpr JPH::ObjectLayer Static = 0; + static constexpr JPH::ObjectLayer Kenmatic = 1; + static constexpr JPH::ObjectLayer Dynamic = 2; + static constexpr JPH::ObjectLayer NUM_LAYERS = 3; +}; + +namespace Engine3DBroadPhaseLayers +{ + static constexpr JPH::BroadPhaseLayer Static(0); + static constexpr JPH::BroadPhaseLayer Kenmatic(1); + static constexpr JPH::BroadPhaseLayer Dynamic(2); + static constexpr JPH::uint NUM_LAYERS(3); +}; + +namespace engine3d +{ + class BPLayerInterfaceHandler : public JPH::BroadPhaseLayerInterface + { + public: + BPLayerInterfaceHandler() + { + m_SceneObjToBroadPhase[Engine3DLayers::Static] = Engine3DBroadPhaseLayers::Static; + m_SceneObjToBroadPhase[Engine3DLayers::Kenmatic] = Engine3DBroadPhaseLayers::Kenmatic; + m_SceneObjToBroadPhase[Engine3DLayers::Dynamic] = Engine3DBroadPhaseLayers::Dynamic; + } + + virtual JPH::uint GetNumBroadPhaseLayers() const override + { + return Engine3DBroadPhaseLayers::NUM_LAYERS; + } + + virtual JPH::BroadPhaseLayer GetBroadPhaseLayer(JPH::ObjectLayer inLayer) const override + { + JPH_ASSERT(inLayer < Engine3DLayers::NUM_LAYERS); + return m_SceneObjToBroadPhase[inLayer]; + } + + //Debug stuff for profiling + #if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED) + virtual const char * GetBroadPhaseLayerName(JPH::BroadPhaseLayer inLayer) const override + { + switch ((JPH::BroadPhaseLayer::Type)inLayer) + { + case (JPH::BroadPhaseLayer::Type)Engine3DBroadPhaseLayers::Static: return "Static"; + case (JPH::BroadPhaseLayer::Type)Engine3DBroadPhaseLayers::Kenmatic: return "Kenmatic"; + case (JPH::BroadPhaseLayer::Type)Engine3DBroadPhaseLayers::Dynamic: return "Dynamic"; + default: JPH_ASSERT(false); return "INVALID"; + } + } + #endif + + private: + //Places an object into a substruct known as broadphase + JPH::BroadPhaseLayer m_SceneObjToBroadPhase[Engine3DLayers::NUM_LAYERS]; + }; +}; \ No newline at end of file diff --git a/engine3d/Physics/Interfaces/ObjectLayerPairFilterInterface.hpp b/engine3d/Physics/Interfaces/ObjectLayerPairFilterInterface.hpp new file mode 100644 index 0000000..7b83b1b --- /dev/null +++ b/engine3d/Physics/Interfaces/ObjectLayerPairFilterInterface.hpp @@ -0,0 +1,25 @@ +#include +#include +namespace engine3d +{ +class ObjectLayerPairFilterInterface : public JPH::ObjectLayerPairFilter +{ + public: + virtual bool ShouldCollide(JPH::ObjectLayer inObject1, JPH::ObjectLayer inObject2) const override + { + switch (inObject1) + { + case Engine3DLayers::Static: + return (inObject2 == Engine3DLayers::Dynamic || + inObject2 == Engine3DLayers::Kenmatic); + case Engine3DLayers::Kenmatic: + return true; + case Engine3DLayers::Dynamic: + return true; + default: + JPH_ASSERT(false); + return false; + } + } + }; +}; \ No newline at end of file diff --git a/engine3d/Physics/Interfaces/ObjectVsBPLayerFilterInterface.hpp b/engine3d/Physics/Interfaces/ObjectVsBPLayerFilterInterface.hpp new file mode 100644 index 0000000..9b10d0f --- /dev/null +++ b/engine3d/Physics/Interfaces/ObjectVsBPLayerFilterInterface.hpp @@ -0,0 +1,27 @@ + +#include +#include +#include + +namespace engine3d { + class ObjectVsBPLayerFilterInterface : public JPH::ObjectVsBroadPhaseLayerFilter + { + public: + virtual bool ShouldCollide(JPH::ObjectLayer inLayer1, JPH::BroadPhaseLayer inLayer2) const override + { + switch (inLayer1) + { + case Engine3DLayers::Static: + return (inLayer2 == Engine3DBroadPhaseLayers::Dynamic || + inLayer2 == Engine3DBroadPhaseLayers::Kenmatic); + case Engine3DLayers::Kenmatic: + return true; + case Engine3DLayers::Dynamic: + return true; + default: + JPH_ASSERT(false); + return false; + } + } + }; +}; \ No newline at end of file diff --git a/engine3d/Physics/JoltHandler.hpp b/engine3d/Physics/JoltHandler.hpp new file mode 100644 index 0000000..0d58de9 --- /dev/null +++ b/engine3d/Physics/JoltHandler.hpp @@ -0,0 +1,71 @@ +#pragma once +// Engine3d includes +#include +#include +#include +#include +#include + +// Jolt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace engine3d +{ + class JoltHandler + { + public: + JoltHandler(); + ~JoltHandler(); + + static JoltHandler* GetInstance() + { + static JoltHandler instance; + return &instance; + } + + BodyInterface* getInterface(); + JPH::Shape* m_BoxShape; + JPH::Shape* m_SphereShape; + + JPH::ScaledShape* m_BoxShapeScaled; + JPH::ScaledShape* m_SphereShapeScaled; + + // Actuall physics part + JPH::PhysicsSystem physics_system; + + TempAllocatorImpl* physics_allocator; + + JPH::JobSystemThreadPool* job_system; + + // Substructs for seperating types of bodies interface + BPLayerInterfaceHandler broad_phase_layer_interface; + + // Filter for body types filter using broadphase + ObjectVsBPLayerFilterInterface object_vs_broadphase_layer_filter; + + // Filter for body types using Object Layers + ObjectLayerPairFilterInterface object_vs_object_layer_filter; + + // Setting Contact listener + Engine3DContactlistener contact_listener; + + // Setting Activation listener + Engine3DActivationListener body_activation_listener; + + // interface for the bodies + BodyInterface* body_interface; + }; +}; \ No newline at end of file diff --git a/imgui.ini b/imgui.ini index 9c087bb..a7158e1 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,5 +1,6 @@ [Window][Debug##Default] -Pos=60,20 +ViewportPos=336,342 +ViewportId=0x9F5F46A1 Size=400,400 Collapsed=0 @@ -9,7 +10,7 @@ Size=372,295 Collapsed=0 [Window][Hello, world!] -ViewportPos=875,333 +ViewportPos=1245,114 ViewportId=0xEBE6C6E6 Size=329,305 Collapsed=0 @@ -19,5 +20,16 @@ Pos=60,60 Size=32,35 Collapsed=0 +[Window][Dear ImGui Demo] +Pos=596,32 +Size=550,680 +Collapsed=0 + +[Window][Test] +ViewportPos=540,724 +ViewportId=0x784DD132 +Size=87,54 +Collapsed=0 + [Docking][Data] diff --git a/sim_shader_transforms/simple_shader.frag b/sim_shader_transforms/simple_shader.frag new file mode 100644 index 0000000..e877f26 --- /dev/null +++ b/sim_shader_transforms/simple_shader.frag @@ -0,0 +1,17 @@ +#version 450 + + +// layout(location = 0) in vec3 fragColor; + +layout(location = 0) out vec4 outColor; + +layout(push_constant) uniform Push { + mat2 transform; + vec2 offset; + vec3 color; +} push; + +void main(){ + // outColor = vec4(fragColor, 0.0); + outColor = vec4(push.color, 1.0); +} \ No newline at end of file diff --git a/sim_shader_transforms/simple_shader.frag.spv b/sim_shader_transforms/simple_shader.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..96bd40bcd224ff1cde3b85238beb211147efe8f9 GIT binary patch literal 856 zcmYk3UrPc}5XGnbli44&GOGtMd<>+AiXbW?VtWuW`T$GlN(<_Wy9T}W+4@wy1fAb{ zt-UgL?wmP0XJ*W;w%5#7Y{Rzf$QGw&t3pgzG4)>erQ3;s=HRoOz<* zFbAoVJWr>>r-m|2@L&ZE=gT}b0aUE(&E&ZE=f&2CB=41IXj42C{fOXg{h z^a-}B8-JW`cY*EeT@==mHPj3BiP=+2H(LC2;8!lDe=zuEdHB>lP`n`zMofNFo;>`f zn`6l#hsL%%HR%%#Vs-{rSIlfJ*^2DM#WlUr;QJkUxYQ$$UR`GPd3zyEc+A70k8dID z`c60B?#j@k=CzpA*^_}ki$lGAhsph64TsU!l6T-RG<(__dpnfzJ$&-?cB4+{ncR;i HyOjL`c4j@C literal 0 HcmV?d00001 diff --git a/sim_shader_transforms/simple_shader.vert b/sim_shader_transforms/simple_shader.vert new file mode 100644 index 0000000..c5c6daa --- /dev/null +++ b/sim_shader_transforms/simple_shader.vert @@ -0,0 +1,18 @@ +#version 450 + +layout(location = 0) in vec2 Position; +layout(location = 1) in vec3 Color; + +// layout(location = 0) out vec3 fragColor; + +layout(push_constant) uniform Push { + mat2 transform; + vec2 offset; + vec3 color; +} push; + +void main(){ + // gl_Position = vec4(Position, 0.0, 1.0); + gl_Position = vec4(push.transform * Position + push.offset, 0.0, 1.0); + // fragColor = Color; +} \ No newline at end of file diff --git a/sim_shader_transforms/simple_shader.vert.spv b/sim_shader_transforms/simple_shader.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..96e5da90f7d823df928d3f78c8d1958265dd508e GIT binary patch literal 1412 zcmYk4+iuf95Qeu&la`jYl+puGf=kM=QpE)zBm@W*z_VeMLnz4P92Sq+b$J%0*g z-85?=oDH*F+l%^M4s3?ACb=bfB5CT^kp3<5qFFIvFAC4j!rq4{9*?84`j#e9YO^F7 z+9HW7`z3+5Jjb(HoKA-Ggq9fd^;+t4RW&}RQ9mg@B}J8dl`C|LV-w3uTiHAlx>WP& zzs7A=o!jrK%$;eBo)tSu?fAVdt3ehgvl!D8o22P1*3z8J&7r?7>Heg=z^4yoUl}YsWG>*P$ZV@J`))GF4^D_w#iDb;#i{J+S(fc#OL6uFdht3l>PI#a*yawV1Ud z;ovhTK6$ppf_I=h^ozYCt1TT!cEzVYK67mA%Zm*poFnI7kxjmR`76@!!8)>-+vgyL z1mazlrY7-M&gTt)QDL)#_&25LhdS`_*)N#y@s9K1vuAR_Cr&^2BpmN|YwyQf_zz{%FZ;rO zEKP3ur5-;2AJ_}c#H{=;9Pa%Q!kc=hFTL+dn1{W+7Lz&lB;fe;bz8y=zjOzGUjhf5 zJj`%cLLO%G_X64AKi$0p+1w2zAB8dNp#+@cvHP;Y79@R5%B&A0aEY-Wc0z6T@kqkE QV1_rE5+D9wWq2w12V|3GqW}N^ literal 0 HcmV?d00001 diff --git a/simple_shader/compile_shaders.sh b/simple_shader/compile_shaders.sh new file mode 100644 index 0000000..5aa7404 --- /dev/null +++ b/simple_shader/compile_shaders.sh @@ -0,0 +1,2 @@ +glslc.exe simple_shader.vert -o simple_shader.vert.spv +glslc.exe simple_shader.frag -o simple_shader.frag.spv diff --git a/simple_shader/simple_shader.frag b/simple_shader/simple_shader.frag new file mode 100644 index 0000000..156225c --- /dev/null +++ b/simple_shader/simple_shader.frag @@ -0,0 +1,16 @@ +#version 450 + + +// layout(location = 0) in vec3 fragColor; + +layout(location = 0) out vec4 outColor; + +layout(push_constant) uniform Push { + vec2 offset; + vec3 color; +} push; + +void main(){ + // outColor = vec4(fragColor, 0.0); + outColor = vec4(push.color, 0.0); +} \ No newline at end of file diff --git a/simple_shader/simple_shader.frag.spv b/simple_shader/simple_shader.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..f9f7271b79db2df632b0a5e8c396e185cd9cdc8d GIT binary patch literal 756 zcmYk2T}#4X9K|1BW~TX;sdXcUmw|Lq5kx^mtc!t0A7I3sG+0jD4ElO~s&0bLZ!X&d zXaAk^od4TXDvtMzDVVxxm=m)-9aEHIq*c;rJ1@>8PUe$~%X1t}Q%a3^TJn??!TW2l zqI)L*EU9rSHyzweKathmWtC^94&U z+|2U^OOAX`%UEgOXp=ldVYF5|DP?n@INQW;@QM^TCt56GKl#_##mf@OYl^S3JX@Td zh63j)S7*GHb{cii+JddU>BsI}eTk>(YizZ?{wvZ(!azNED>!?N^sOrL(&#rCXAU&{ zHAVc?h1WCA{ZO3Vc+jcWP$VCndT{nc>xs7%M?yh3%Q$<$$?quQr5^Y6J`y-rdK2bg zb`CRqOR*I1^(FUEpdU4F<)ltmK!28pdc90j*lGPtV~#)HAk*kM(+lxN#{&8Ixo5UJ NO~TCF{b-YG;TOGkHy8i_ literal 0 HcmV?d00001 diff --git a/simple_shader/simple_shader.vert b/simple_shader/simple_shader.vert new file mode 100644 index 0000000..243562c --- /dev/null +++ b/simple_shader/simple_shader.vert @@ -0,0 +1,17 @@ +#version 450 + +layout(location = 0) in vec2 Position; +layout(location = 1) in vec3 Color; + +// layout(location = 0) out vec3 fragColor; + +layout(push_constant) uniform Push { + vec2 offset; + vec3 color; +} push; + +void main(){ + // gl_Position = vec4(Position, 0.0, 1.0); + gl_Position = vec4(Position + push.offset, 0.0, 1.0); + // fragColor = Color; +} \ No newline at end of file diff --git a/simple_shader/simple_shader.vert.spv b/simple_shader/simple_shader.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..5b8a97571b2c3df05c565bc324a4359f94fb047c GIT binary patch literal 1224 zcmYk4T~8B16o!Yk3kU)t@}*c?t5+t(3pFG}jRCS=Gyy~6?S^azon+l@x?3Y$>0k3# zd1K=H% z?TK(U%(C}8`u}$2a)LGKed#l4TfdgE-RXr2&>G2buJoU7{bB}*>sT>W+V`k+}GB-YTWp$OOc9vs%a?>oE;KPfB zut!&lz-I?!P@5S>53qYuYQPIMn3o!GwuFNB#i1|$j=V+Lo^)3|^+EcWdA1evh4rM! zizdD!pLz$1S7bR4)|JQnp$0j$C*EDzu~l`SfCU z;(_dflz!AF<}JY9=q=fUJ4QJ7M@S_5RwzBUr0nxSD6{NKnU6aOoQDnmOB~KTl5!6G ulQ3rH?ZJ_NJ&_N_EEk%%p1J0dV^4OYcVG6Yl((YyJ55X6lm1nOBk4aKH(fRW literal 0 HcmV?d00001 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 560ce71..186270a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,8 +1,11 @@ set(ENGINE_INCLUDE_NAME ../engine3d) -set(ENGINE_INTERNAL_INCLUDE ${ENGINE_INCLUDE_NAME}/Core/internal) +# set(ENGINE_INTERNAL_INCLUDE ${ENGINE_INCLUDE_NAME}/Core/internal) set(ENGINE_SRC_DIR engine3d) -set(VULKAN_INCLUDE_DIR ${ENGINE_INCLUDE_NAME}/Core/internal/VulkanCpp) -set(VULKAN_SRC_DIR ${ENGINE_SRC_DIR}/Core/internal/VulkanCpp) +set(VULKAN_INCLUDE_DIR ${ENGINE_INCLUDE_NAME}/Core/internal/Vulkan2Showcase) +set(VULKAN_SRC_DIR ${ENGINE_SRC_DIR}/Core/internal/Vulkan2Showcase) + +set(VULKAN_SHADERS_INCLUDE_DIR ${VULKAN_INCLUDE_DIR}/Shaders) +set(VULKAN_SHADERS_SRC_DIR ${VULKAN_SRC_DIR}/Shaders) build_library( SOURCES @@ -11,6 +14,16 @@ build_library( ${ENGINE_INCLUDE_NAME}/Core/EngineLogger.hpp ${ENGINE_INCLUDE_NAME}/Core/Window.hpp + # Update Management includes + ${ENGINE_INCLUDE_NAME}/Core/TimeManagement/GlobalUpdateManager.hpp + ${ENGINE_INCLUDE_NAME}/Core/TimeManagement/Timer.hpp + ${ENGINE_INCLUDE_NAME}/Core/TimeManagement/UpdateManagers/SyncUpdateManager.hpp + ${ENGINE_INCLUDE_NAME}/Core/TimeManagement/UpdateManagers/ParallelFrameUpdateManager.hpp + + # Application Manager + ${ENGINE_INCLUDE_NAME}/Core/ApplicationManager/Scene.hpp + ${ENGINE_INCLUDE_NAME}/Core/ApplicationManager/ThreadMngr.hpp + # Event system includes ${ENGINE_INCLUDE_NAME}/Core/Event/KeyCodes.hpp ${ENGINE_INCLUDE_NAME}/Core/Event/MouseCodes.hpp @@ -19,17 +32,38 @@ build_library( ${ENGINE_INCLUDE_NAME}/Core/Event/KeyEvent.hpp ${ENGINE_INCLUDE_NAME}/Core/Event/MouseEvent.hpp + ${ENGINE_INCLUDE_NAME}/Core/Scene/SceneObject.hpp + + + + ${ENGINE_INCLUDE_NAME}/Core/GraphicDrivers/GraphicSwapchain.hpp + ${ENGINE_INCLUDE_NAME}/Core/GraphicDrivers/Shader.hpp ${VULKAN_INCLUDE_DIR}/Vulkan.hpp + ${VULKAN_INCLUDE_DIR}/helper_functions.hpp + ${VULKAN_INCLUDE_DIR}/VulkanContext.hpp ${VULKAN_INCLUDE_DIR}/VulkanWindow.hpp - ${VULKAN_INCLUDE_DIR}/VulkanDevice.hpp - ${VULKAN_INCLUDE_DIR}/VulkanPhysicalDevice.hpp - ${VULKAN_INCLUDE_DIR}/VulkanLogicalDevice.hpp + ${VULKAN_INCLUDE_DIR}/VulkanPhysicalDriver.hpp + ${VULKAN_INCLUDE_DIR}/VulkanDriver.hpp ${VULKAN_INCLUDE_DIR}/VulkanSwapchain.hpp + ${VULKAN_INCLUDE_DIR}/VulkanModel.hpp + + ${VULKAN_SHADERS_INCLUDE_DIR}/VulkanShader.hpp + + # Scene Managment Includes + ${ENGINE_INCLUDE_NAME}/Core/SceneManagment/Components/GameComponent.hpp + ${ENGINE_INCLUDE_NAME}/Core/SceneManagment/SceneObjects/SceneObject.hpp + ${ENGINE_INCLUDE_NAME}/Core/ApplicationManager/GameObjManager/UUID.hpp + + # Special Component Includes + ${ENGINE_INCLUDE_NAME}/Core/SceneManagment/Components/SPComps/Transform.hpp # Renderer Includes ${ENGINE_INCLUDE_NAME}/Core/Renderer/Renderer.hpp + ############################# + # Source .cpp files below + ############################# ${ENGINE_SRC_DIR}/Core/ApplicationInstance.cpp @@ -39,14 +73,40 @@ build_library( ${ENGINE_SRC_DIR}/Core/Window.cpp ${ENGINE_SRC_DIR}/Core/EngineLogger.cpp + ${ENGINE_SRC_DIR}/Core/TimeManagement/GlobalUpdateManager.cpp + ${ENGINE_SRC_DIR}/Core/TimeManagement/Timer.cpp + ${ENGINE_SRC_DIR}/Core/TimeManagement/UpdateManagers/SyncUpdateManager.cpp + ${ENGINE_SRC_DIR}/Core/TimeManagement/UpdateManagers/ParallelFrameUpdateManager.cpp + + ${ENGINE_SRC_DIR}/Core/ApplicationManager/Scene.cpp + ${ENGINE_SRC_DIR}/Core/ApplicationManager/ThreadMngr.cpp + + ${ENGINE_SRC_DIR}/Core/Scene/SceneObject.cpp + + ${ENGINE_SRC_DIR}/Core/GraphicDrivers/GraphicSwapchain.cpp + ${ENGINE_SRC_DIR}/Core/GraphicDrivers/Shader.cpp + ${ENGINE_SRC_DIR}/Core/Event/InputPoll.cpp - ${VULKAN_SRC_DIR}/Vulkan.cpp + ${VULKAN_SRC_DIR}//helper_functions.cpp ${VULKAN_SRC_DIR}/VulkanWindow.cpp - ${VULKAN_SRC_DIR}/VulkanDevice.cpp - ${VULKAN_SRC_DIR}/VulkanPhysicalDevice.cpp - ${VULKAN_SRC_DIR}/VulkanLogicalDevice.cpp + ${VULKAN_SRC_DIR}/VulkanContext.cpp + ${VULKAN_SRC_DIR}/VulkanPhysicalDriver.cpp + ${VULKAN_SRC_DIR}/VulkanDriver.cpp ${VULKAN_SRC_DIR}/VulkanSwapchain.cpp + ${VULKAN_SHADERS_SRC_DIR}/VulkanShader.cpp + ${VULKAN_SRC_DIR}/VulkanModel.cpp + + ${ENGINE_SRC_DIR}/Core/SceneManagment/SceneObjects/SceneObject.cpp + ${ENGINE_SRC_DIR}/Core/SceneManagment/Components/GameComponent.cpp + ${ENGINE_SRC_DIR}/Core/ApplicationManager/GameObjManager/UUID.cpp + + ${ENGINE_SRC_DIR}/Core/SceneManagment/Components/SPComps/Transform.cpp + ${ENGINE_SRC_DIR}/Core/Renderer/Renderer.cpp + + ${ENGINE_SRC_DIR}/Math/Interpolation.cpp + + ${ENGINE_SRC_DIR}/Physics/JoltHandler.cpp ) diff --git a/src/engine3d/Core/ApplicationInstance.cpp b/src/engine3d/Core/ApplicationInstance.cpp index e92ec24..34d9dc4 100644 --- a/src/engine3d/Core/ApplicationInstance.cpp +++ b/src/engine3d/Core/ApplicationInstance.cpp @@ -1,14 +1,15 @@ -// #include -#include "Event/InputPoll.hpp" +#include "TimeManagement/GlobalUpdateManager.hpp" +#include #include #include -// #include #include +#include namespace engine3d{ static float m_LastFrameTime = 0.0f; static std::string g_DebugName = "Engine3D"; static API g_CurrentAPI = UNSPECIFIED; + ApplicationInstance* ApplicationInstance::g_ThisInstance = nullptr; ApplicationInstance::ApplicationInstance(const std::string& p_DebugName){ @@ -22,14 +23,19 @@ namespace engine3d{ ConsoleLogInfo("EditorApplication::RunApplicationMainloop called!"); while(m_Window->IsActive()){ + InputPoll::UpdateEvents(); // FrameTimer::UpdateFrameTimer(); // give us the frames in flight. // Renderer::Presentation(); + // m_Window->GetCurrentSwapchain()->BeginFrame(); + // Renderer::BeginFrame(); - UpdateCurrentApplicationInstance(); - m_Window->OnUpdateAllFrames(); + // Renderer::SetBackgroundColor({1.0f, 0.0f, 0.0f, 0.0f}); + // UpdateCurrentApplicationInstance(); - InputPoll::UpdateEvents(); + // Renderer::EndFrame(); + + m_Window->OnUpdateAllFrames(); } //! @note Cleaning up imgui @@ -38,9 +44,9 @@ namespace engine3d{ ApplicationInstance& ApplicationInstance::Super(){ return *g_ThisInstance; } - void ApplicationInstance::UpdateCurrentApplicationInstance(){ - UpdateThisApplicationInstance(); - } + // void ApplicationInstance::UpdateCurrentApplicationInstance(){ + // UpdateThisApplicationInstance(); + // } float ApplicationInstance::CurrentFrameTime(){ return m_LastFrameTime; diff --git a/src/engine3d/Core/ApplicationManager/GameObjManager/UUID.cpp b/src/engine3d/Core/ApplicationManager/GameObjManager/UUID.cpp new file mode 100644 index 0000000..1ac4ec3 --- /dev/null +++ b/src/engine3d/Core/ApplicationManager/GameObjManager/UUID.cpp @@ -0,0 +1,14 @@ +#include +#include + +namespace engine3d +{ + static std::random_device randomDevice; + static std::mt19937_64 engine(randomDevice()); + static std::uniform_int_distribution uniformDistribution; + + UUID::UUID() : uuid(uniformDistribution(engine)) { + } + + UUID::UUID(uint64_t newID){} +}; \ No newline at end of file diff --git a/src/engine3d/Core/ApplicationManager/Scene.cpp b/src/engine3d/Core/ApplicationManager/Scene.cpp new file mode 100644 index 0000000..522c78b --- /dev/null +++ b/src/engine3d/Core/ApplicationManager/Scene.cpp @@ -0,0 +1,9 @@ +#include + +namespace engine3d +{ + Scene::~Scene() + { + m_SceneRegistry.clear(); + } +}; diff --git a/src/engine3d/Core/ApplicationManager/ThreadMngr.cpp b/src/engine3d/Core/ApplicationManager/ThreadMngr.cpp new file mode 100644 index 0000000..5ba98dc --- /dev/null +++ b/src/engine3d/Core/ApplicationManager/ThreadMngr.cpp @@ -0,0 +1,67 @@ + +#include "ApplicationManager/Scene.hpp" +#include "SceneManagment/SceneObjects/SceneObject.hpp" +#include +#include +#include +#include +#include + +//Testing variables +std::mutex syncLock; +std::condition_variable frameKey; +bool ready = false; + +namespace engine3d +{ + ThreadMngr::ThreadMngr() + { + m_SyncManager = SyncUpdateManager::GetInstance(); + t_NewScene = new Scene(); + m_ThreadStop = false; + syncUpdateThread = std::jthread(&ThreadMngr::UpdateSyncFunction, this); + + if(syncUpdateThread.joinable()) + printf("Thread manager Running!\n"); + } + void ThreadMngr::ThreadHandler() + { + // this is supposed to serve Scene class a thread + } + + void ThreadMngr::OnRun(float p_DeltaTime) + { + m_DeltaTime = p_DeltaTime; + ready = true; + frameKey.notify_one(); + } + + void ThreadMngr::UpdateSyncFunction() + { + while(!m_ThreadStop) + { + std::unique_lock lock(syncLock); + frameKey.wait(lock, [] {return ready;}); + if(m_ThreadStop) + { + printf("Cleaning Thread!\n"); + break; + } + ready = false; + m_SyncManager->RunUpdate(m_DeltaTime); + } + } + + SyncUpdateManager * ThreadMngr::getSyncManager() + { + return m_SyncManager; + } + + ThreadMngr::~ThreadMngr() + { + delete t_NewScene; + m_ThreadStop = true; + ready = true; + frameKey.notify_all(); + } +}; diff --git a/src/engine3d/Core/internal/CoreInternal.cpp b/src/engine3d/Core/CoreInternal.cpp similarity index 83% rename from src/engine3d/Core/internal/CoreInternal.cpp rename to src/engine3d/Core/CoreInternal.cpp index e7a609d..5482b49 100644 --- a/src/engine3d/Core/internal/CoreInternal.cpp +++ b/src/engine3d/Core/CoreInternal.cpp @@ -1,4 +1,3 @@ -#include #include namespace engine3d{ @@ -6,7 +5,7 @@ namespace engine3d{ //! @note Should only be used to initialize Vulkan's API and it's devices (physical and logical) void InitializeVulkanCore(){ //! @note Initializes core vulkan API - vk::Vulkan::InitializeVulkanCore(); + // vk::Vulkan::InitializeVulkanCore(); // vk::VulkanSwapchain::InitializeSwaphchain(); // UICore::InitializeImgui(); } @@ -19,5 +18,4 @@ namespace engine3d{ void Engine3DInitializeCore(){ printf("Engine3DInitializeCore() Called!\n"); engine3d::ConsoleEngineLogger::InitializeConsoleLogger("engine3d"); - engine3d::InitializeVulkanCore(); } \ No newline at end of file diff --git a/src/engine3d/Core/Event/InputPoll.cpp b/src/engine3d/Core/Event/InputPoll.cpp index 983da22..439011f 100644 --- a/src/engine3d/Core/Event/InputPoll.cpp +++ b/src/engine3d/Core/Event/InputPoll.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/src/engine3d/Core/GraphicDrivers/GraphicSwapchain.cpp b/src/engine3d/Core/GraphicDrivers/GraphicSwapchain.cpp new file mode 100644 index 0000000..ea1e4b6 --- /dev/null +++ b/src/engine3d/Core/GraphicDrivers/GraphicSwapchain.cpp @@ -0,0 +1,59 @@ +#include "ApplicationInstance.hpp" +#include "internal/Vulkan2Showcase/VulkanSwapchain.hpp" +#include "internal/Vulkan2Showcase/VulkanContext.hpp" +#include +#include + +namespace engine3d{ + Ref GraphicSwapchain::InitializeSwapchain(VkSurfaceKHR p_Surface){ + switch (ApplicationInstance::CurrentAPI()){ + case API::VULKAN: return CreateRef(vk::VulkanContext::GetPhysicalDriver(), vk::VulkanContext::GetDriver(), p_Surface); + default: + break; + } + return nullptr; + } + + uint32_t GraphicSwapchain::GetImagesSize() const{ + return ImagesSize(); + } + + VkFormat GraphicSwapchain::GetSwapchainFormat(){ + return ReadSwapchainFormat(); + } + + VkFramebuffer GraphicSwapchain::GetFramebuffer(uint32_t index){ + return ReadFramebuffer(index); + } + + VkRenderPass GraphicSwapchain::GetRenderPass(){ + return ReadSwapchainRenderPass(); + } + + VkImageView GraphicSwapchain::GetImageView(uint32_t index){ + return ReadImageView(index); + } + + VkSwapchainKHR GraphicSwapchain::GetVkSwapchainHandler(){ + return VkSwapchainHandler(); + } + + VkExtent2D GraphicSwapchain::GetSwapchainExtent(){ + return ReadSwapchainExtent(); + } + + void GraphicSwapchain::SubmitCommandBuffer(VkCommandBuffer* p_CommandBuffers){ + return SubmitAndWriteCommandBuffer(p_CommandBuffers); + } + + //! @note Proceeds to getting next frame. + uint32_t GraphicSwapchain::AcquireNextImage(){ + return ReadAcquiredNextFrame(); + } + + + //! @note m_CurrentFrameIdx + uint32_t GraphicSwapchain::GetCurrentFramePerTick(){ + return CurrentFramePerTick(); + } +}; \ No newline at end of file diff --git a/src/engine3d/Core/GraphicDrivers/Shader.cpp b/src/engine3d/Core/GraphicDrivers/Shader.cpp new file mode 100644 index 0000000..fe69d30 --- /dev/null +++ b/src/engine3d/Core/GraphicDrivers/Shader.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + +namespace engine3d{ + Ref Shader::Create(const std::string p_VertShader, const std::string& p_FragShader, const vk::ShaderPipelineConfig& p_Config){ + switch (ApplicationInstance::CurrentAPI()){ + case API::VULKAN: return CreateRef(p_VertShader, p_FragShader, p_Config); + default: + break; + } + + return nullptr; + } + + VkPipeline Shader::GetGraphicsPipeline(){ + return GraphicsPipeline(); + } +}; \ No newline at end of file diff --git a/src/engine3d/Core/Renderer/Renderer.cpp b/src/engine3d/Core/Renderer/Renderer.cpp index ce91d83..e17294d 100644 --- a/src/engine3d/Core/Renderer/Renderer.cpp +++ b/src/engine3d/Core/Renderer/Renderer.cpp @@ -1,4 +1,7 @@ +// #include "internal/VulkanCpp/Vulkan.hpp" +#include #include +#include namespace engine3d{ static RendererSettings g_Settings; @@ -6,4 +9,62 @@ namespace engine3d{ RendererSettings& Renderer::GetSettings(){ return g_Settings; } + + // Ref g_CurrentSwapchain = nullptr; + VkCommandBuffer g_ActiveCommandBuffer = nullptr; + VkRenderPass g_RenderPass; + + void Renderer::BeginFrame(){ + // g_CurrentSwapchain = ApplicationInstance::GetWindow().GetCurrentSwapchain(); + + } + + void Renderer::SetBackgroundColor(const std::array& p_Rgba){ + VkClearValue clearColorValue = {{p_Rgba[0], p_Rgba[1], p_Rgba[2], p_Rgba[3]}}; + } + + + /* + //! @note This gets submitted into our renderer queue. + //! @note Few properties of how submission to the queue will work. + + @note These are the things we (as the renderer) should keep track of + 1.) Queues submission idx to know the queue we are submitting to. + 2.) Specify what queue to allocate to our tasks to. + 3.) Example is at the end of frame we execute all of our queue's + Example + static uint32_t s_SubmissionCommandQueueCount = 2; + //! @note Atomic are just thread-safe counters. Which we will use for reading in queue's that we are submitting into. + static std::atomic s_SubmissionQueueIdx = 0; // thread-safe in reading the data from queue's that will be needed to render + + Renderer::BeginFrame(){ + // Probably would do some initialization + s_CurrentRendererCommandQueue[0] = new RenderCommandQueue(); + s_CurrentRendererCommandQueue[1] = new RenderCommandQueue(); + } + + //! @note In our renderer thread we would utilize this to make sure that in our renderer thread. + //! @note This would be happening in our next frame. (Where we would do something like double-buffering or something like that) + void Renderer::NextSubmittedQueueInThread(){ + s_SubmissionQueueIdx = (s_SubmissionQueueIdx + 1) % s_SubmissionCommandQueueCount; + } + + Renderer::EndFrame(){ + s_CurrentRendererCommandQueue[s_SubmissionQueueIdx]->Execute(); + } + + while(IsActive()){ + Renderer::BeginFrame(); + + Renderer::EndFrame(); + } + + //! @note This is what the API, would look. + Renderer::Submit([](){ + }); + */ + + + void Renderer::EndFrame(){ + } }; \ No newline at end of file diff --git a/src/engine3d/Core/Scene/SceneObject.cpp b/src/engine3d/Core/Scene/SceneObject.cpp new file mode 100644 index 0000000..fcdc738 --- /dev/null +++ b/src/engine3d/Core/Scene/SceneObject.cpp @@ -0,0 +1,10 @@ +#include + +namespace engine3d{ + SceneObject SceneObject::Create(){ + static id_t current_id = 0; + return SceneObject(current_id); + } + + SceneObject::SceneObject(id_t p_Id) : m_Id(p_Id) {} +}; \ No newline at end of file diff --git a/src/engine3d/Core/SceneManagment/Components/GameComponent.cpp b/src/engine3d/Core/SceneManagment/Components/GameComponent.cpp new file mode 100644 index 0000000..de501d3 --- /dev/null +++ b/src/engine3d/Core/SceneManagment/Components/GameComponent.cpp @@ -0,0 +1,9 @@ +#include + +namespace engine3d +{ + void GameComponent::SetSceneObjectRef(SceneObject &p_Object) + { + m_GameObjectRef = &p_Object; + } +}; diff --git a/src/engine3d/Core/SceneManagment/Components/SPComps/Transform.cpp b/src/engine3d/Core/SceneManagment/Components/SPComps/Transform.cpp new file mode 100644 index 0000000..0ef533b --- /dev/null +++ b/src/engine3d/Core/SceneManagment/Components/SPComps/Transform.cpp @@ -0,0 +1,48 @@ +#include + +namespace engine3d { + void Transform::OnIntegrate(){} + + Transform::Transform () : + m_Position(0.0f), + m_QuaterionRot(0.0f), + m_AxisRotation(0.0f), + m_Scale(0.0f){} + + glm::lowp_vec3 Transform::GetLPPos() + { + glm::lowp_vec3 lp_Position; + lp_Position.x = m_Position.x; + lp_Position.y = m_Position.y; + lp_Position.z = m_Position.z; + return lp_Position; + } + + glm::lowp_vec4 Transform::GetLPQuat() + { + glm::lowp_vec4 lp_Quat; + lp_Quat.x = m_QuaterionRot.x; + lp_Quat.y = m_QuaterionRot.y; + lp_Quat.z = m_QuaterionRot.z; + lp_Quat.w = m_QuaterionRot.w; + return lp_Quat; + } + + glm::lowp_vec3 Transform::GetLPAxisRot() + { + glm::lowp_vec3 lp_AxisRot; + lp_AxisRot.x = m_AxisRotation.x; + lp_AxisRot.y = m_AxisRotation.y; + lp_AxisRot.z = m_AxisRotation.z; + return lp_AxisRot; + } + + glm::lowp_vec3 Transform::GetLPSclae() + { + glm::lowp_vec3 lp_Scale; + lp_Scale.x = m_Scale.x; + lp_Scale.y = m_Scale.y; + lp_Scale.z = m_Scale.z; + return lp_Scale; + } +}; \ No newline at end of file diff --git a/src/engine3d/Core/SceneManagment/SceneObjects/SceneObject.cpp b/src/engine3d/Core/SceneManagment/SceneObjects/SceneObject.cpp new file mode 100644 index 0000000..415077a --- /dev/null +++ b/src/engine3d/Core/SceneManagment/SceneObjects/SceneObject.cpp @@ -0,0 +1,19 @@ +#include +#include +#include "EngineLogger.hpp" + +namespace engine3d { + SceneObject::SceneObject(entt::entity handle, Scene *scene) + : SceneObjectHandler(handle), m_ParentScene(scene) + { + AddComponent(); + } + + SceneObject::SceneObject(Scene *scene) + { + m_ParentScene = scene; + SceneObjectHandler = scene->m_SceneRegistry.create(); + ConsoleLogInfo("Entity Registered"); + AddComponent(); + } +}; // namespace Engine3D diff --git a/src/engine3d/Core/TimeManagement/GlobalUpdateManager.cpp b/src/engine3d/Core/TimeManagement/GlobalUpdateManager.cpp new file mode 100644 index 0000000..4ecd224 --- /dev/null +++ b/src/engine3d/Core/TimeManagement/GlobalUpdateManager.cpp @@ -0,0 +1,102 @@ +#include "ApplicationInstance.hpp" +// #include "Physics/JoltHandler.hpp" +#include +#include +#include +#include +#include +#include +#include + +using namespace JPH; +using namespace JPH::literals; + +using namespace std::chrono; + +#define TOSECONDS 1000000 + +using highResClock = high_resolution_clock; +namespace engine3d +{ + // std::vector> GlobalUpdateManager::m_ApplicationUpdateSubscribers; + + GlobalUpdateManager::GlobalUpdateManager() + { + OnSetUp(); + } + + void GlobalUpdateManager::OnSetUp() + { + m_GlobalTimer = new Timer(); + m_FPSMaintain = new Timer(); + m_threadManager = new ThreadMngr(); + + m_GlobalDeltaTime = 0.0; + m_UpdateTime = m_GlobalTimer->GetCurrentTime(); + m_MaxFPS = 90; + m_FPSCounter = 1; + + //! @note syncupdatemanager will not work until the thread manager works. + ConsoleLogInfo("F1 to see Global time and F2 to see Local time!\n"); + + } + + void GlobalUpdateManager::GlobalOnTickUpdate() + { + m_FPSMaintain->Reset(); + for(const auto& appUpdate : m_ApplicationUpdateSubscribers){ + appUpdate(); + } + + if(m_GlobalTimer->ElapsedSec() >= 1) + { + if(InputPoll::IsKeyPressed(KeyCode::F1)) + { + ConsoleLogInfo("FPS: {1} Delta Time: {0}", + m_GlobalDeltaTime, m_FPSCounter); + } + m_GlobalTimer->Reset(); + m_FPSCounter = 1; + } + else + { + m_FPSCounter++; + } + + if(InputPoll::IsKeyPressed(KeyCode::F12)) + { + glfwDestroyWindow(ApplicationInstance::GetWindow().GetNativeWindow()); + } + + m_GlobalDeltaTime = duration_cast( + m_GlobalTimer->GetCurrentTime() - m_UpdateTime).count(); + + m_UpdateTime = m_GlobalTimer->GetCurrentTime(); + + m_threadManager->OnRun(m_GlobalDeltaTime / TOSECONDS); + + WaitForNextFrame(); + } + + void GlobalUpdateManager::WaitForNextFrame() + { + // if(m_FPSMaintain->ElapsedSec() < 1.0/m_MaxFPS){ + // std::this_thread::sleep_until(std::chrono::time_point()); + // } + + //! @note We'll continue this in a bit.... finish later. + //! @note Technically should be notify by Sync update manager. + //! @note Example: SyncUpdateManager::NotifyAll(); + while(m_FPSMaintain->ElapsedSec() < 1.0/m_MaxFPS) + { + continue; + } + } + + GlobalUpdateManager::~GlobalUpdateManager() + { + delete m_GlobalTimer; + delete m_FPSMaintain; + delete m_threadManager; + } +} diff --git a/src/engine3d/Core/TimeManagement/Timer.cpp b/src/engine3d/Core/TimeManagement/Timer.cpp new file mode 100644 index 0000000..d8e544d --- /dev/null +++ b/src/engine3d/Core/TimeManagement/Timer.cpp @@ -0,0 +1,34 @@ +#include +#include + +using namespace std::chrono; +namespace engine3d +{ + + Timer::Timer() + { + Reset(); + } + + // set a start time + void Timer::Reset() + { + m_StopWatch = high_resolution_clock::now(); + } + + // Get current Time + time_point Timer::GetCurrentTime() + { + return high_resolution_clock::now(); + } + + float Timer::Elapsed() + { + return duration_cast(GetCurrentTime()-m_StopWatch).count(); + } + + float Timer::ElapsedSec() + { + return Elapsed()/1000000; + } +} \ No newline at end of file diff --git a/src/engine3d/Core/TimeManagement/UpdateManagers/ParallelFrameUpdateManager.cpp b/src/engine3d/Core/TimeManagement/UpdateManagers/ParallelFrameUpdateManager.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/engine3d/Core/TimeManagement/UpdateManagers/SyncUpdateManager.cpp b/src/engine3d/Core/TimeManagement/UpdateManagers/SyncUpdateManager.cpp new file mode 100644 index 0000000..75c465b --- /dev/null +++ b/src/engine3d/Core/TimeManagement/UpdateManagers/SyncUpdateManager.cpp @@ -0,0 +1,115 @@ +#include "TimeManagement/UpdateManagers/SyncUpdateManager.hpp" +#include "EngineLogger.hpp" +#include "Event/InputPoll.hpp" +#include "Event/KeyCodes.hpp" +#include "Physics/JoltHandler.hpp" +#include +#include +#include + +namespace engine3d +{ + SyncUpdateManager::SyncUpdateManager() + { + + m_LocalTimer = new Timer(); + m_LocalUpdateTime = m_LocalTimer->GetCurrentTime(); + + m_SyncLocalDeltaTime = 0.0; + m_MaxVariance = 2; + m_MinFrames = 0; + m_LocalUpdateCounter = 0; + m_LocalFPS = 0; + srand(std::time(NULL)); + m_RandomFrame = (rand() % m_MaxVariance) + m_MinFrames; + } + + //! @note this does not work per object this might need to change a little. + //! Possibly pass gameObjects with the virtual functions. + //! Possibly seperate active scripts to non active ones in scenes. + void SyncUpdateManager::RunUpdate(float deltaTime) + { + //! @note unsafe!!!! + /** + * @note Render is not quite placed in the right position here + * @param randomFrame Used both to determine update and + * used to allow render to optimise gpu sending if needed + * + * @note I used random in this case becuase it is hard for a + * human to catch wether the render is correct or not. + * Benchmark later. + */ + OnPhysicsUpdate(); + const int collisionSteps = 1 + (60*(deltaTime)); + + JoltHandler* p_joltHandler = JoltHandler::GetInstance(); + //Updating physics system based on jolt physics + p_joltHandler->physics_system.Update( + deltaTime, + collisionSteps, + p_joltHandler->physics_allocator, + p_joltHandler->job_system); + if(m_RandomFrame <= m_LocalUpdateCounter) + { + m_RandomFrame = (rand() % m_MaxVariance) + m_MinFrames; + m_LocalUpdateCounter = 0; + + OnUpdate(); + OnLateUpdate(); + + m_SyncLocalDeltaTime = duration_cast + (m_LocalTimer->GetCurrentTime() - m_LocalUpdateTime).count(); + m_SyncLocalDeltaTime = m_SyncLocalDeltaTime/1000000; + + m_LocalUpdateTime = m_LocalTimer->GetCurrentTime(); + m_LocalFPS++; + } + else + { + m_LocalUpdateCounter++; + } + + if(m_LocalTimer->ElapsedSec() >= 1.0) + { + m_LocalTimer->Reset(); + + //! @note Key event added to allow switch between global and local. + if(InputPoll::IsKeyPressed(KeyCode::F2)) + { + ConsoleLogInfo("Local FPS: {0}, Local Delta Time: {1}", + m_LocalFPS, m_SyncLocalDeltaTime); + } + m_LocalFPS = 0; + } + + } + + void SyncUpdateManager::OnPhysicsUpdate() + { + for(auto& l_Subscriber : m_SyncOnTickUpdateSubscribers) + { + l_Subscriber(); + } + } + + void SyncUpdateManager::OnUpdate() + { + for(auto& l_Subscriber : m_SyncUpdateSubscribers) + { + l_Subscriber(); + } + } + + void SyncUpdateManager::OnLateUpdate() + { + for(auto& l_Subscriber : m_SyncLateUpdateSubscribers) + { + l_Subscriber(); + } + } + + SyncUpdateManager::~SyncUpdateManager() + { + delete m_LocalTimer; + } +} \ No newline at end of file diff --git a/src/engine3d/Core/Window.cpp b/src/engine3d/Core/Window.cpp index c1c2e0f..2ff3d3d 100644 --- a/src/engine3d/Core/Window.cpp +++ b/src/engine3d/Core/Window.cpp @@ -1,21 +1,19 @@ -// #include -#include -#include "ApplicationInstance.hpp" +#include +#include #include #include #include +#include +#include namespace engine3d{ - // Window* Window::Create(uint32_t p_Width, uint32_t p_Height, const std::string& p_Title){ - - // } static Window* g_WindowAPI = nullptr; Window* Window::Create(uint32_t p_Width, uint32_t p_Height, const std::string &p_Title){ switch (ApplicationInstance::CurrentAPI()){ case API::VULKAN: - return new vk::VulkanWindow(p_Width, p_Height, p_Title); + return new vk::VulkanWindow(p_Title, p_Width, p_Height); default: throw std::runtime_error("API was unspecified!"); } @@ -30,6 +28,14 @@ namespace engine3d{ return VkSurface(); } + //! @note Eventually, I'll wanna change the Graphic + // graphic_swapchain& Window::GetCurrentSwapchain(){ + // return CurrentSwapchain(); + // } + Ref Window::GetCurrentSwapchain(){ + return Swapchain(); + } + GLFWwindow* Window::GetNativeWindow(){ return NativeWindow(); } @@ -46,8 +52,8 @@ namespace engine3d{ return Title(); } - void Window::OnUpdateAllFrames(){ - Presentation(); + + GlobalUpdateManager::GetInstance()->GlobalOnTickUpdate(); } }; \ No newline at end of file diff --git a/src/engine3d/Core/internal/Vulkan2Showcase/Shaders/VulkanShader.cpp b/src/engine3d/Core/internal/Vulkan2Showcase/Shaders/VulkanShader.cpp new file mode 100644 index 0000000..dd56e58 --- /dev/null +++ b/src/engine3d/Core/internal/Vulkan2Showcase/Shaders/VulkanShader.cpp @@ -0,0 +1,232 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace engine3d::vk{ + VulkanShader::VulkanShader(const std::string& p_VertShader, const std::string& p_FragShader, const ShaderPipelineConfig& p_Config){ + initialize_graphics_pipeline(p_VertShader, p_FragShader, p_Config); + } + + std::vector VulkanShader::read_file(const std::string& p_Filepath){ + std::ifstream ins(p_Filepath, std::ios::ate | std::ios::binary); + + if(!ins){ + ConsoleLogError("Could not read in file \"{}\"", p_Filepath); + return {}; + } + size_t file_size = static_cast(ins.tellg()); + std::vector buffer(file_size); + + ins.seekg(0); + ins.read(buffer.data(), file_size); + return buffer; + } + + void VulkanShader::initialize_graphics_pipeline(const std::string& p_VertShader, const std::string& p_FragShader, const ShaderPipelineConfig& p_Config){ + auto vert = read_file(p_VertShader); + auto frag = read_file(p_FragShader); + + initialize_shader_module(vert, m_VertexShaderModule); + initialize_shader_module(frag, m_FragmentShaderModule); + + //! @note Setting vertex/fragment shaders stages. + + std::array shader_stages; + + VkPipelineShaderStageCreateInfo vert_shader_stage = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = m_VertexShaderModule, + .pName = "main" + }; + + VkPipelineShaderStageCreateInfo frag_shader_stage = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = m_FragmentShaderModule, + .pName = "main" + }; + + shader_stages[0] = vert_shader_stage; + shader_stages[1] = frag_shader_stage; + + auto binding_description = VulkanModel::Vertex::GetVertexInputBindDescription(); + auto attachment_description = VulkanModel::Vertex::GetVertexAttributeDescriptions(); + + VkPipelineVertexInputStateCreateInfo vert_input_create_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .pNext = nullptr, + .vertexBindingDescriptionCount = static_cast(binding_description.size()), + .pVertexBindingDescriptions = binding_description.data(), + .vertexAttributeDescriptionCount = static_cast(attachment_description.size()), + .pVertexAttributeDescriptions = attachment_description.data(), + }; + + VkPipelineViewportStateCreateInfo PipelineViewportCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .viewportCount = 1, + .pViewports = &p_Config.Viewport, + .scissorCount = 1, + .pScissors = &p_Config.Scissor + }; + + VkGraphicsPipelineCreateInfo graphics_pipeline_create_info = { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .stageCount = 2, + .pStages = shader_stages.data(), + .pVertexInputState = &vert_input_create_info, + .pInputAssemblyState = &p_Config.PipelineInputAsmInfo, + .pViewportState = &PipelineViewportCreateInfo, + .pRasterizationState = &p_Config.PipelineRasterizationCreateInfo, + .pMultisampleState = &p_Config.PipelineMultisampleCreateInfo, + .pDepthStencilState = &p_Config.PipelineDepthStencilCreateInfo, + .pColorBlendState = &p_Config.PipelineColorBlendCreateInfo, + .pDynamicState = nullptr, + .layout = p_Config.PipelineLayout, + .renderPass = p_Config.PipelineRenderPass, + .subpass = p_Config.SubpassCount, + .basePipelineHandle = nullptr, + .basePipelineIndex = -1, + }; + + vk_check(vkCreateGraphicsPipelines(VulkanContext::GetDriver(), nullptr, 1, &graphics_pipeline_create_info, nullptr, &m_GraphicsPipeline), "vkCreateGraphicsPipelines", __FILE__, __LINE__, __FUNCTION__); + + ConsoleLogWarn("Vertex Shader Size == {}", vert.size()); + ConsoleLogWarn("Fragment Shader Size == {}", frag.size()); + } + + void VulkanShader::initialize_shader_module(const std::vector& p_Bin, VkShaderModule& p_ShaderMod){ + VkShaderModuleCreateInfo shader_mod_create_info = { + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .codeSize = p_Bin.size(), + .pCode = reinterpret_cast(p_Bin.data()) + }; + + vk_check(vkCreateShaderModule(VulkanContext::GetDriver(), &shader_mod_create_info, nullptr, &p_ShaderMod), "vkCreateShaderModule", __FILE__, __LINE__, __FUNCTION__); + + } + + ShaderPipelineConfig VulkanShader::shader_configuration(uint32_t p_Width, uint32_t p_Height){ + ShaderPipelineConfig config{}; + + // VkPipelineInputAssemblyStateCreateInfo pipeline_input_asm_create_info = { + config.PipelineInputAsmInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = false + }; + + config.Viewport = { + .x = 0.0f, + .y = 0.0f, + .width = static_cast(p_Width), + .height = static_cast(p_Height), + .minDepth = 0.0f, + .maxDepth = 1.0f + }; + + config.Scissor = { + .offset = {0, 0}, + .extent = {p_Width, p_Height} + }; + + // config.PipelineViewportCreateInfo = { + // VkPipelineViewportStateCreateInfo PipelineViewportCreateInfo = { + // .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + // .pNext = nullptr, + // .flags = 0, + // .viewportCount = 1, + // .pViewports = &config.Viewport, + // .scissorCount = 1, + // .pScissors = &config.Scissor + // }; + + config.PipelineRasterizationCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .depthClampEnable = false, + .rasterizerDiscardEnable = false, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_NONE, + .frontFace = VK_FRONT_FACE_CLOCKWISE, + .depthBiasEnable = false, + .depthBiasConstantFactor = 0.0f, // optional + .depthBiasClamp = 0.0f, // optional + .depthBiasSlopeFactor = 0.0f, // optional + .lineWidth = 1.0f, + }; + + config.PipelineMultisampleCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, + .sampleShadingEnable = false, + .minSampleShading = 1.0f, // optional + .pSampleMask = nullptr, // optional + .alphaToCoverageEnable = false, // optional + .alphaToOneEnable = false // optional + }; + + config.PipelineColorBlendAttachments = { + .blendEnable = false, + .srcColorBlendFactor = VK_BLEND_FACTOR_ONE, // optional + .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO, // optional + .colorBlendOp = VK_BLEND_OP_ADD, // optional + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, // optional + .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, // optional + .alphaBlendOp = VK_BLEND_OP_ADD, // optional + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT + }; + + config.PipelineColorBlendCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .logicOpEnable = false, + .logicOp = VK_LOGIC_OP_COPY, + .attachmentCount = 1, + .pAttachments = &config.PipelineColorBlendAttachments, + .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f} // optional + // .blendConstants = { // this is a float[4] + // {0.0f, 0.0f, 0.0f, 0.0f} // optional + // } + }; + + config.PipelineDepthStencilCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .depthTestEnable = true, + .depthWriteEnable = true, + .depthCompareOp = VK_COMPARE_OP_LESS, + .depthBoundsTestEnable = false, + .stencilTestEnable = false, + .front = {}, + .back = {}, + .minDepthBounds = 0.0f, + .maxDepthBounds = 1.0f, + }; + + + + + return config; + } +}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/Vulkan2Showcase/VulkanContext.cpp b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanContext.cpp new file mode 100644 index 0000000..728d155 --- /dev/null +++ b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanContext.cpp @@ -0,0 +1,123 @@ +#include +#include +#include +#include + +namespace engine3d::vk{ + const std::vector InstanceLayers = { +// #ifdef DEBUG + // Khronos Validation is a layer which encompasses all of the functionality that used to be contained in VK_LAYER_GOOGLE_threading, + // VK_LAYER_LUNARG_parameter_validation, VK_LAYER_LUNARG_object_tracker, VK_LAYER_LUNARG_core_validation, and VK_LAYER_GOOGLE_unique_objects + "VK_LAYER_KHRONOS_validation", + // Standard Validation is a (now deprecated) meta-layer managed by the LunarG Loader. + // Using Standard Validation will cause the loader to load a standard set of validation layers in an optimal order: + // * VK_LAYER_GOOGLE_threading. + // * VK_LAYER_LUNARG_parameter_validation. + // * VK_LAYER_LUNARG_object_tracker. + // * VK_LAYER_LUNARG_core_validation. + // * VK_LAYER_GOOGLE_unique_objects. + "VK_LAYER_LUNARG_standard_validation", + // PerfDoc is a Vulkan layer which attempts to identify API usage that may be discouraged, primarily by validating applications + // against the rules set out in the Mali Application Developer Best Practices document. + "VK_LAYER_ARM_mali_perf_doc" +// #else +// "" +// #endif +}; + VkInstance VulkanContext::s_Instance = VK_NULL_HANDLE; + VulkanPhysicalDriver VulkanContext::s_PhysicalDriver; + VulkanDriver VulkanContext::s_Driver; + + void VulkanContext::Initialize(){ + ConsoleLogInfo("Vulkan2Showcase: Begin VulkanContext::Initialize()!!"); + VkApplicationInfo app_info = { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pNext = nullptr, + .applicationVersion = 1, + .pEngineName = "Engine3D", + .engineVersion = 1, + .apiVersion = VK_API_VERSION_1_0, + }; + + VkInstanceCreateInfo instance_create_info = { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .pApplicationInfo = &app_info + }; + + std::vector validation_layers= InitializeValidationLayers(); + std::vector instance_extensions = InitializeInstanceExtensions(); + + instance_create_info.enabledExtensionCount = static_cast(validation_layers.size()); + instance_create_info.ppEnabledLayerNames = validation_layers.data(); + + //! @note Setting our instance extensions that will get applied to instance-level objects like VkInstance, VkPhysicalDevice, etc. + instance_create_info.enabledExtensionCount = static_cast(instance_extensions.size()); + instance_create_info.ppEnabledExtensionNames = instance_extensions.data(); + + vk_check(vkCreateInstance(&instance_create_info, nullptr, &s_Instance), "vkCreateInstance", __FILE__, __LINE__, __FUNCTION__); + ConsoleLogWarn("Vulkan2Showcase: VkInstance Initialized Completed!!!"); + + s_PhysicalDriver = VulkanPhysicalDriver(s_Instance); + s_Driver = VulkanDriver(s_PhysicalDriver); + } + + //! @note Returns the validation layers that will be utilized by the vulkan instance. + std::vector VulkanContext::InitializeValidationLayers(){ + uint32_t layer_count; + + //! @note Validation layers that will be returned. + std::vector layer_names; + + //! @note Enumerating the layer size + vk_check(vkEnumerateInstanceLayerProperties(&layer_count, nullptr), "vkEnumerateInstanceLayerProperties (1)", __FILE__, __LINE__, __FUNCTION__); + std::vector layer_properties; + layer_properties.resize(layer_count); + + vk_check(vkEnumerateInstanceLayerProperties(&layer_count, layer_properties.data()), "vkEnumerateInstanceLayerProperties (1)", __FILE__, __LINE__, __FUNCTION__); + + for(const auto& layer : layer_properties){ + for(uint32_t j = 0; j < layer_count; j++){ + // if(layer_properties[j].layerName == layer.layerName) + if(strcmp(layer_properties[j].layerName, layer.layerName)){ + layer_names.emplace_back(layer_properties[j].layerName); + } + } + } + return layer_names; + } + + std::vector VulkanContext::InitializeInstanceExtensions(){ + std::vector extensionNames; + + extensionNames.emplace_back(VK_KHR_SURFACE_EXTENSION_NAME); + + // An additional surface extension needs to be loaded. This extension is platform-specific so needs to be selected based on the + // platform the example is going to be deployed to. + // Preprocessor directives are used here to select the correct platform. + #ifdef VK_USE_PLATFORM_WIN32_KHR + extensionNames.emplace_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + #endif + #ifdef VK_USE_PLATFORM_XLIB_KHR + extensionNames.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); + #endif + #ifdef VK_USE_PLATFORM_XCB_KHR + extensionNames.emplace_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); + #endif + #ifdef VK_USE_PLATFORM_ANDROID_KHR + extensionNames.emplace_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); + #endif + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + extensionNames.emplace_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); + #endif + #ifdef VK_USE_PLATFORM_MACOS_MVK + extensionNames.emplace_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); + #endif + #ifdef USE_PLATFORM_NULLWS + extensionNames.emplace_back(VK_KHR_DISPLAY_EXTENSION_NAME); + #endif + + return extensionNames; + } +}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/Vulkan2Showcase/VulkanDriver.cpp b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanDriver.cpp new file mode 100644 index 0000000..16c2cf3 --- /dev/null +++ b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanDriver.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include + +namespace engine3d::vk{ + VulkanDriver::VulkanDriver(VulkanPhysicalDriver p_PhysicalDevice){ + ConsoleLogInfo("Vulkan2Showcase: Begin Vulkan Driver Initialization!"); + + float queue_priority[1] = { 0.0f }; + + std::vector device_extension = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME + }; + + VkDeviceQueueCreateInfo queue_create_info = { + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .queueFamilyIndex = p_PhysicalDevice.GetQueueIndices().Graphics, + .queueCount = 1, + .pQueuePriorities = queue_priority, + }; + + VkDeviceCreateInfo create_info = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .pNext = nullptr, + .queueCreateInfoCount = 1, + .pQueueCreateInfos = &queue_create_info, + .enabledLayerCount = 0, + .ppEnabledLayerNames = nullptr, + .enabledExtensionCount = static_cast(device_extension.size()), + .ppEnabledExtensionNames = device_extension.data(), + }; + + VkPhysicalDeviceFeatures features; + vkGetPhysicalDeviceFeatures(p_PhysicalDevice, &features); + features.robustBufferAccess = false; + create_info.pEnabledFeatures = &features; + + vk_check(vkCreateDevice(p_PhysicalDevice, &create_info, nullptr, &m_CurrentDriver), "vkCreateDevice", __FILE__, __LINE__, __FUNCTION__); + ConsoleLogWarn("Vulkan2Showcase: Vulkan Driver Initialized Complete!!!"); + + //! @note Initializes our queue for graphics (to render basic primitives) + ConsoleLogInfo("Vulkan2Showcase: In Vulkan Driver, Initializes Queue"); + + /* + //! @note TODO: This should be in VulkanSwapchain + if( p_PhysicalDevice.GetQueueIndices().Graphics == m_PresentationIndex){ + m_PresentationIndex = p_PhysicalDevice.GetQueueIndices().Graphics; + } + else{ + vkGetDeviceQueue(m_, 0, CurrentDriver, m_PresentationIndex, &m_PresentationQueue); + } + */ + + vkGetDeviceQueue(m_CurrentDriver, p_PhysicalDevice.GetQueueIndices().Graphics, 0, &m_GraphicsQueue); + } + + uint32_t VulkanDriver::SelectMemoryType(uint32_t p_TypeFilter, VkMemoryPropertyFlags p_PropertyFlag){ + VkPhysicalDeviceMemoryProperties mem_props; + vkGetPhysicalDeviceMemoryProperties(VulkanContext::GetPhysicalDriver(), &mem_props); + + for(uint32_t i = 0; i < mem_props.memoryTypeCount; i++){ + if((p_TypeFilter & (1 << i)) and (mem_props.memoryTypes[i].propertyFlags & p_PropertyFlag) == p_PropertyFlag){ + return i; + } + } + + return -1; + } +}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/Vulkan2Showcase/VulkanModel.cpp b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanModel.cpp new file mode 100644 index 0000000..8524b61 --- /dev/null +++ b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanModel.cpp @@ -0,0 +1,108 @@ +#include "EngineLogger.hpp" +#include +#include +#include +#include + +namespace engine3d::vk{ + VulkanModel::VulkanModel(const std::vector& p_Vertices, const VkBufferUsageFlags& p_UsageFlags, const VkMemoryPropertyFlags& p_PropertyFlags){ + ConsoleLogInfo("Vulkan2Showcase: Begin Vulkan Model Initialization!!"); + m_VerticesCount = static_cast(p_Vertices.size()); + VkDeviceSize buffer_size = sizeof(p_Vertices[0]) * m_VerticesCount; + + //! @note Host = CPU, Device = GPU + /* + + createBuffer( + VkDeviceSize: VCbufferSize, + VkBufferUsageFlags: VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + VkBuffer: vertexBuffer, + VkDeviceMemory: vertexDeviceMemory + ); + + */ + + //! @note Initialize Vertex Buffer + //! @not eDoes initialize_vertex_buffers(vertices) stuff + VkBufferCreateInfo vk_buf_create_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .size = buffer_size, + .usage = p_UsageFlags, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE + }; + + vk_check(vkCreateBuffer(VulkanContext::GetDriver(), &vk_buf_create_info, nullptr, &m_VertexBuffer), "vkCreateBuffer", __FILE__, __LINE__, __FUNCTION__); + + VkMemoryRequirements memory_reqs; + vkGetBufferMemoryRequirements(VulkanContext::GetDriver(), m_VertexBuffer, &memory_reqs); + + VkMemoryAllocateInfo alloc_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = memory_reqs.size, + .memoryTypeIndex = VulkanContext::GetDriver().SelectMemoryType(memory_reqs.memoryTypeBits, p_PropertyFlags) + }; + + vk_check(vkAllocateMemory(VulkanContext::GetDriver(), &alloc_info, nullptr, &m_VertexBufferDeviceMemory), "vkAllocateMemory", __FILE__, __LINE__, __FUNCTION__); + + vkBindBufferMemory(VulkanContext::GetDriver(), m_VertexBuffer, m_VertexBufferDeviceMemory, 0); + + //! @note Mapping memory data. + void* data; + vkMapMemory(VulkanContext::GetDriver(), m_VertexBufferDeviceMemory, 0, buffer_size, 0, &data); + memcpy(data, p_Vertices.data(), static_cast(buffer_size)); + vkUnmapMemory(VulkanContext::GetDriver(), m_VertexBufferDeviceMemory); + + + ConsoleLogWarn("Vulkan2Showcase: Vulkan Model Initialized Completed!!!"); + + // initialize_vertex_buffers(p_Vertices); + + } + + void VulkanModel::initialize_vertex_buffers(const std::vector& p_Vertices){ + + } + + void VulkanModel::Draw(VkCommandBuffer p_Command){ + vkCmdDraw(p_Command, m_VerticesCount, 1, 0, 0); + } + + void VulkanModel::Bind(VkCommandBuffer p_Command){ + VkBuffer buffers[] = { m_VertexBuffer}; + VkDeviceSize offsets[] = {0}; + vkCmdBindVertexBuffers(p_Command, 0, 1, buffers, offsets); + } + + std::vector VulkanModel::Vertex::GetVertexInputBindDescription(){ + std::vector binding_descriptions(1); + binding_descriptions[0] = { + .binding = 0, + .stride = sizeof(Vertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX + }; + + return binding_descriptions; + } + + std::vector VulkanModel::Vertex::GetVertexAttributeDescriptions(){ + std::vector attribute_description(2); + attribute_description[0] = { + .location = 0, // // layout(location = 0) + .binding = 0, + .format = VK_FORMAT_R32G32_SFLOAT, + // .offset = 0 + .offset = offsetof(Vertex, Position) + }; + + attribute_description[1] = { + .location = 1, // layout(location = 1) + .binding = 0, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(Vertex, Color) + }; + + return attribute_description; + } + +}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/Vulkan2Showcase/VulkanPhysicalDriver.cpp b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanPhysicalDriver.cpp new file mode 100644 index 0000000..eb10afe --- /dev/null +++ b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanPhysicalDriver.cpp @@ -0,0 +1,94 @@ +#include "ApplicationInstance.hpp" +#include +#include +#include +#include + +namespace engine3d::vk{ + VulkanPhysicalDriver::VulkanPhysicalDriver(VkInstance p_Instance){ + ConsoleLogInfo("Vulkan2Showcase: Begin VulkanPhysicalDriver Initialization!!"); + uint32_t gpu_count; + std::vector available_gpus; + + //! @note Querying number of available GPU's (Physical Devices) on our machine + vk_check(vkEnumeratePhysicalDevices(p_Instance, &gpu_count, nullptr), "vkEnumeratePhysicalDevices", __FILE__, __LINE__, __FUNCTION__); + + available_gpus.resize(gpu_count); + vk_check(vkEnumeratePhysicalDevices(p_Instance, &gpu_count, available_gpus.data()), "vkEnumeratePhysicalDevices", __FILE__, __LINE__, __FUNCTION__); + + // we populate the compatible device. + //! @note Checking for compatible GPU's on our machine. (Init the physical device structs) + for(const auto& device : available_gpus){ + VkPhysicalDeviceProperties device_properties; + VkPhysicalDeviceFeatures device_features; + vkGetPhysicalDeviceProperties(device, &device_properties); + vkGetPhysicalDeviceFeatures(device, &device_features); + + //! @note VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU checks if our device is an external device. + if(device_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU || device_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU){ + m_PhysicalDevice = device; + break; + } + } + + if(available_gpus.size() == 0){ + m_PhysicalDevice = available_gpus[0]; + } + + if(available_gpus.empty()){ + ConsoleLogError("There was no available compatible GPU's found!"); + m_PhysicalDevice = VK_NULL_HANDLE; + } + + //! @note Initialized and Identifying Queue Families. + uint32_t queue_family_count; + vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDevice, &queue_family_count, nullptr); + m_QueueFamilyProperties.resize(queue_family_count); + + //! @note Loading queue family data from the physical device that we have selected. + vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDevice, &queue_family_count, m_QueueFamilyProperties.data()); + + m_QueueFamilyIndices = SelectQueueFamilyIndices(); + + ConsoleLogWarn("Vulkan2Showcase: VulkanPhysicalDriver Initialized Completed!!!"); + } + + VulkanPhysicalDriver::PhysicalQueueFamilyIndices VulkanPhysicalDriver::SelectQueueFamilyIndices(){ + VulkanPhysicalDriver::PhysicalQueueFamilyIndices indices; + int i = 0; + VkBool32 compatible = VK_FALSE; + + for(const auto& queue_family : m_QueueFamilyProperties){ + if(queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT){ + indices.Graphics = i; + break; + } + i++; + } + + // Graphics if its -1 meaning it could not find any graphics queue available. + // ConsoleLogWarn("Graphics Index === {}", (int)indices.Graphics); + + return indices; + } + + uint32_t VulkanPhysicalDriver::GetPresentationIndex(VkSurfaceKHR p_Surface){ + uint32_t PresentationIndex = -1; + VkBool32 compatible = VK_FALSE; + uint32_t i = 0; + for(const auto& queue_family : m_QueueFamilyProperties){ + if(queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT){ + vk_check(vkGetPhysicalDeviceSurfaceSupportKHR(m_PhysicalDevice, i, p_Surface, &compatible), "vkGetPhysicalDeviceSurfaceSupportKHR", __FILE__, __LINE__, __FUNCTION__); + + if(compatible){ + PresentationIndex = i; + } + } + i++; + } + + ConsoleLogWarn("Presentation Index === {}", PresentationIndex); + return PresentationIndex; + } + +}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/Vulkan2Showcase/VulkanSwapchain.cpp b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanSwapchain.cpp new file mode 100644 index 0000000..a30a6ad --- /dev/null +++ b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanSwapchain.cpp @@ -0,0 +1,629 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace engine3d::vk{ + VulkanSwapchain::VulkanSwapchain(VulkanPhysicalDriver p_PhysicalDriver, VulkanDriver p_Driver, VkSurfaceKHR p_Surface) : m_Driver(p_Driver){ + //! @note This gives us the queue to present/render to display. + + //! @note We extract the current presentation index from our current selected physical index. + m_PresentationIndex = p_PhysicalDriver.GetPresentationIndex(p_Surface); + vkGetDeviceQueue(m_Driver, m_PresentationIndex, 0, &m_PresentationQueue); + + uint32_t format_count; + std::vector formats; + + //! @note Extracting the surface format that is supported on our current GPU (physical device) + vk_check(vkGetPhysicalDeviceSurfaceFormatsKHR(p_PhysicalDriver, p_Surface, &format_count, nullptr), "vkGetPhysicalDeviceSurfaceFormatsKHR", __FILE__, __LINE__, __FUNCTION__); + + formats.resize(format_count); + vk_check(vkGetPhysicalDeviceSurfaceFormatsKHR(p_PhysicalDriver, p_Surface, &format_count, formats.data()), "vkGetPhysicalDeviceSurfaceFormatsKHR", __FILE__, __LINE__, __FUNCTION__); + + if(format_count == 1 and formats[0].format == VK_FORMAT_UNDEFINED){ + m_SurfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM; + } + else{ + m_SurfaceFormat = formats[0]; + } + + //! @note Getting surface capabilities + VkSurfaceCapabilitiesKHR surface_capabilities; + vk_check(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(p_PhysicalDriver, p_Surface, &surface_capabilities), "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", __FILE__, __LINE__, __FUNCTION__); + + //! @note Extracting number of presentation modes. + uint32_t preset_modes_count; + std::vector presentation_modes; + vk_check(vkGetPhysicalDeviceSurfacePresentModesKHR(p_PhysicalDriver, p_Surface, &preset_modes_count, nullptr), "vkGetPhysicalDeviceSurfacePresentModesKHR", __FILE__, __LINE__, __FUNCTION__); + presentation_modes.resize(preset_modes_count); + vk_check(vkGetPhysicalDeviceSurfacePresentModesKHR(p_PhysicalDriver, p_Surface, &preset_modes_count, presentation_modes.data()), "vkGetPhysicalDeviceSurfacePresentModesKHR", __FILE__, __LINE__, __FUNCTION__); + + m_PresentMode = SelectCompatiblePresentMode(VK_PRESENT_MODE_IMMEDIATE_KHR, presentation_modes); + m_SwapchainExtent = SelectValidExtent(surface_capabilities); + + // Extract min num of images supported on our current surface. + uint32_t surface_img_count = std::max(3, surface_capabilities.minImageCount); + + //! @note Populating swapchain creation into info struct + VkSwapchainCreateInfoKHR create_info = { + .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .pNext = nullptr, + .flags = 0, + .surface = p_Surface, + .imageFormat = m_SurfaceFormat.format, + .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, + }; + + if((surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) == 0){ + bool expression = (surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR); + if(!expression){ + ConsoleLogError("Surface does not support VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR transformation"); + assert(false); + } + } + + create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + create_info.presentMode = m_PresentMode; + create_info.minImageCount = surface_img_count; + create_info.oldSwapchain = nullptr; + create_info.clipped = true; + create_info.imageExtent = { + .width = m_SwapchainExtent.width, + .height = m_SwapchainExtent.height + }; + + create_info.imageArrayLayers = 1; + create_info.imageColorSpace = m_SurfaceFormat.colorSpace; + create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + // ConsoleLogError("Just after create_info.imageUsage called!"); + // ConsoleLogError("App Width == {}", ApplicationInstance::GetWindow().GetWidth()); + // ConsoleLogError("App height == {}", ApplicationInstance::GetWindow().GetHeight()); + //! @note Fixing width/height of surface in case they aren't defined. + // if(ApplicationInstance::GetWindow().GetWidth() == 0 || ApplicationInstance::GetWindow().GetHeight() == 0){ + // ConsoleLogError("Application Width/Height === 0"); + // create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + // create_info.queueFamilyIndexCount = 0; + // create_info.pQueueFamilyIndices = nullptr; + // } + // else{ + // ConsoleLogError("Application Width/height not 0!"); + // uint32_t queue_fam_indices[] = {p_PhysicalDriver.GetQueueIndices().Graphics, m_PresentationIndex}; + // create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; + // create_info.queueFamilyIndexCount = 2; + // create_info.pQueueFamilyIndices = queue_fam_indices; + // } + + //! @note Instantiating swapchain + vk_check(vkCreateSwapchainKHR(p_Driver, &create_info, nullptr, &m_Swapchain), "vkCreateSwapchainKHR", __FILE__, __LINE__, __FUNCTION__); + + ConsoleLogWarn("Vulkan2Showcase: Vulkan Swapchain Initialized Complete!!!"); + + ConsoleLogInfo("Vulkan2Showcase: Begin VulkanSwapchain Images Initialization"); + + uint32_t swapchain_images_count; + std::vector images; + + //! @note Getting amount of images for this swapchain. + vk_check(vkGetSwapchainImagesKHR(p_Driver, m_Swapchain, &swapchain_images_count, nullptr), "vkGetSwapchainImagesKHR", __FILE__, __LINE__, __FUNCTION__); + + images.resize(swapchain_images_count); + + //! @note Keep tracking of our actual swapchain images our swapchain will actually utilize. + m_ImagesForSwapchain.resize(swapchain_images_count); + // extracting all of our images + vk_check(vkGetSwapchainImagesKHR(p_Driver, m_Swapchain, &swapchain_images_count, images.data()), "vkGetSwapchainImagesKHR", __FILE__, __LINE__, __FUNCTION__); + + for(uint32_t i = 0; i < swapchain_images_count; i++){ + m_ImagesForSwapchain[i].Image = images[i]; + + VkImageViewCreateInfo image_view_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .image = m_ImagesForSwapchain[i].Image, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = m_SurfaceFormat.format, + .components = { + .r = VK_COMPONENT_SWIZZLE_R, + .g = VK_COMPONENT_SWIZZLE_G, + .b = VK_COMPONENT_SWIZZLE_B + }, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + } + }; + + vk_check(vkCreateImageView(p_Driver, &image_view_create_info, nullptr, &m_ImagesForSwapchain[i].ImageView), "vkCreateImageView", __FILE__, __LINE__, __FUNCTION__); + } + + ConsoleLogWarn("Vulkan2Showcase: Image Initiated Completed!!!"); + + //! @note Setting up Command Buffers. + + ConsoleLogInfo("Vulkan2Showcase: Begin Command Buffers Initiated!!"); + VkCommandPoolCreateInfo cmd_pool_create_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .pNext = nullptr, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = p_PhysicalDriver.GetQueueIndices().Graphics, + }; + + vk_check(vkCreateCommandPool(p_Driver, &cmd_pool_create_info, nullptr, &m_CommandPoolForSwapchain), "vkCreateCommandPool", __FILE__, __LINE__, __FUNCTION__); + + m_SwapchainCommandBuffers.resize(m_ImagesForSwapchain.size()); + + VkCommandBufferAllocateInfo cmd_buffer_alloc_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = nullptr, + .commandPool = m_CommandPoolForSwapchain, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = static_cast(m_SwapchainCommandBuffers.size()), + }; + + vk_check(vkAllocateCommandBuffers(p_Driver, &cmd_buffer_alloc_info, m_SwapchainCommandBuffers.data()), "vkAllocateCommandBuffers", __FILE__, __LINE__, __FUNCTION__); + + ConsoleLogWarn("Vulkan2Showcase: Vulkan Swapchain CommandBuffers Initiated Completed!!"); + + + //! @note Setting up swapchain render pass here. + //! @note This render pass is ONLY specifically for rendering the images and indicating when they are finished. + ConsoleLogInfo("Vulkan2Showcase: Creating VulkanSwapchain RenderPass!"); + VkAttachmentDescription depth_attachments_description = { + .format = SelectDepthFormat(p_PhysicalDriver), + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + }; + + VkAttachmentReference depth_attachment_ref = { + .attachment = 1, + .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + }; + + VkAttachmentDescription color_attachment_description = { + .format = GetSwapchainFormat(), + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR + }; + + VkAttachmentReference color_attachment_ref = { + .attachment = 0, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + }; + + VkSubpassDescription subpass_description = { + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .colorAttachmentCount = 1, + .pColorAttachments = &color_attachment_ref, + .pDepthStencilAttachment = &depth_attachment_ref + }; + + VkSubpassDependency subpass_dependency = { + .srcSubpass = VK_SUBPASS_EXTERNAL, + .dstSubpass = 0, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + .srcAccessMask = 0, + .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT + }; + + std::array attachments = { color_attachment_description, depth_attachments_description }; + + VkRenderPassCreateInfo renderpass_create_info = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = static_cast(attachments.size()), + .pAttachments = attachments.data(), + .subpassCount = 1, + .pSubpasses = &subpass_description, + .dependencyCount = 1, + .pDependencies = &subpass_dependency + }; + + vk_check(vkCreateRenderPass(p_Driver, &renderpass_create_info, nullptr, &m_RenderpassForSwapchain), "vkCreateRenderPass", __FILE__, __LINE__, __FUNCTION__); + + ConsoleLogWarn("Vulkan2Showcase: Vulkan Swapchain Renderpass Initialized Completed!!!"); + + + //! @note Initializing Depth Formats. + ConsoleLogInfo("Vulkan2Showcase: Begin Vulkan Swapchain Depth Images for swapchains Initializing..."); + VkFormat selected_depth_format = SelectDepthFormat(p_PhysicalDriver); + VkExtent2D swapchain_extent = m_SwapchainExtent; + + //! @note Making sure our depth images are the same as our swapchains amount of images this swapchain can accept. + m_DepthImagesForSwapchain.resize(GetImagesSize()); + + // Creating our images for depth view to lay-over + + //! @note We want to set the depth images to this memory property flag. + //! @note To specify memory allocation with this type for most efficient for specifically device accesses. + + VkPhysicalDeviceMemoryProperties memory_properties; + vkGetPhysicalDeviceMemoryProperties(p_PhysicalDriver, &memory_properties); + + VkMemoryPropertyFlags properties_flag = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + for(size_t i = 0; i < m_DepthImagesForSwapchain.size(); i++){ + VkImageCreateInfo image_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .format = selected_depth_format, + .extent = { .width = swapchain_extent.width, .height = swapchain_extent.height, .depth = 1 }, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + vk_check(vkCreateImage(p_Driver, &image_create_info, nullptr, &m_DepthImagesForSwapchain[i].Image), "vkCreateImage", __FILE__, __LINE__, __FUNCTION__); + + VkMemoryRequirements memory_requirements; + vkGetImageMemoryRequirements(p_Driver, m_DepthImagesForSwapchain[i].Image, &memory_requirements); + + VkMemoryAllocateInfo mem_alloc_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = memory_requirements.size, + .memoryTypeIndex = SelectMemoryType(memory_properties, memory_requirements.memoryTypeBits, properties_flag) + }; + + vk_check(vkAllocateMemory(p_Driver, &mem_alloc_info, nullptr, &m_DepthImagesForSwapchain[i].DeviceMemory), "vkAllocateMemory", __FILE__, __LINE__, __FUNCTION__); + + vk_check(vkBindImageMemory(p_Driver, m_DepthImagesForSwapchain[i].Image, m_DepthImagesForSwapchain[i].DeviceMemory, 0), "vkBindImageMemory", __FILE__, __LINE__, __FUNCTION__); + + VkImageViewCreateInfo image_view_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = m_DepthImagesForSwapchain[i].Image, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = selected_depth_format, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 0 + } + }; + + vk_check(vkCreateImageView(p_Driver, &image_view_create_info, nullptr, &m_DepthImagesForSwapchain[i].ImageView), "vkCreateImageView", __FILE__, __LINE__, __FUNCTION__); + } + + ConsoleLogWarn("Vulkan2Showcase: Depth Images Initialized Completed!!"); + + + //! @note Setting up framebuffers for swapchain. + ConsoleLogInfo("Vulkan2Showcase: Begin Framebuffers Initialization!"); + m_FramebuffersForSwapchain.resize(GetImagesSize()); + + for(size_t i = 0; i < GetImagesSize(); i++){ + std::array attachments = { m_ImagesForSwapchain[i].ImageView, m_DepthImagesForSwapchain[i].ImageView}; + + VkExtent2D swapchain_extent = m_SwapchainExtent; + VkFramebufferCreateInfo fb_create_info = { + .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .renderPass = m_RenderpassForSwapchain, + .attachmentCount = static_cast(attachments.size()), + .pAttachments = attachments.data(), + .width = swapchain_extent.width, + .height = swapchain_extent.height, + .layers = 1 + }; + + vk_check(vkCreateFramebuffer(p_Driver, &fb_create_info, nullptr, &m_FramebuffersForSwapchain[i]), "vkCreateFramebuffer", __FILE__, __LINE__, __FUNCTION__); + } + + ConsoleLogWarn("Vulkan2Showcase: Vulkan Framebuffers Initialization Completed!!!!"); + + + //! @note Setting up Syncrhonization Objects for semaphores/fences. + ConsoleLogInfo("Vulkan2Showcase: Begin Vulkan Sync Objects Initialization"); + + //! @note Setting up our arrays + m_SemaphoresForAvailableImages.resize(MaxFramesInFlight); + m_SemaphoresForRenderCompleted.resize(MaxFramesInFlight); + m_InFlightFences.resize(MaxFramesInFlight); + m_ImagesInFlight.resize(GetImagesSize(), VK_NULL_HANDLE); + + VkSemaphoreCreateInfo semaphore_create_info = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO + }; + + VkFenceCreateInfo fence_create_info = { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .flags = VK_FENCE_CREATE_SIGNALED_BIT + }; + + for(size_t i = 0; i < MaxFramesInFlight; i++){ + vk_check(vkCreateSemaphore(p_Driver, &semaphore_create_info, nullptr, &m_SemaphoresForAvailableImages[i]), "vkCreateSemaphore (1)", __FILE__, __LINE__, __FUNCTION__); + + vk_check(vkCreateSemaphore(p_Driver, &semaphore_create_info, nullptr, &m_SemaphoresForRenderCompleted[i]), "vkCreateSemaphore (2)", __FILE__, __LINE__, __FUNCTION__); + + vk_check(vkCreateFence(p_Driver, &fence_create_info, nullptr, &m_InFlightFences[i]), "vkCreateFence", __FILE__, __LINE__, __FUNCTION__); + } + + ConsoleLogWarn("Vulkan2Showcase: Vulkan Swapchain Sync Objects Initialized Completed!!!!"); + + ConsoleLogWarn("Vulkan2Showcase: Vulkan Swapchain Initialized Complete"); + } + + VkSwapchainKHR VulkanSwapchain::VkSwapchainHandler() { + return m_Swapchain; + } + + VkFormat VulkanSwapchain::ReadSwapchainFormat(){ + return m_SurfaceFormat.format; + } + + uint32_t VulkanSwapchain::ImagesSize() const { + return m_ImagesForSwapchain.size(); + } + + VkFramebuffer VulkanSwapchain::ReadFramebuffer(uint32_t index) { + return m_FramebuffersForSwapchain[index]; + } + + VkImageView VulkanSwapchain::ReadImageView(uint32_t index) { + return m_ImagesForSwapchain[index].ImageView; + } + + VkExtent2D VulkanSwapchain::ReadSwapchainExtent() { + return m_SwapchainExtent; + } + + VkRenderPass VulkanSwapchain::ReadSwapchainRenderPass(){ + return m_RenderpassForSwapchain; + } + + void VulkanSwapchain::SubmitAndWriteCommandBuffer(VkCommandBuffer* p_CommandBuffers) { + if(m_ImagesInFlight[m_CurrentImageIndex] != VK_NULL_HANDLE){ + vkWaitForFences(m_Driver, 1, &m_ImagesInFlight[m_CurrentImageIndex], true, std::numeric_limits::max()); + } + + m_ImagesInFlight[m_CurrentImageIndex] = m_InFlightFences[m_CurrentFrameIndex]; + + VkSubmitInfo submit_info = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = nullptr, + }; + + VkSemaphore wait_semaphore[] = {m_SemaphoresForAvailableImages[m_CurrentFrameIndex]}; + + VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + + submit_info.waitSemaphoreCount = 1; + submit_info.pWaitSemaphores = wait_semaphore; + submit_info.pWaitDstStageMask = wait_stages; + + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = p_CommandBuffers; + + VkSemaphore signal_sems[] = { m_SemaphoresForRenderCompleted[m_CurrentFrameIndex]}; + + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = signal_sems; + + vkResetFences(m_Driver, 1, &m_InFlightFences[m_CurrentFrameIndex]); + + vk_check(vkQueueSubmit(m_Driver.GetGraphicsQueue(), 1, &submit_info, m_InFlightFences[m_CurrentFrameIndex]), "vkQueueSubmit", __FILE__, __LINE__, __FUNCTION__); + + //! @note Now we present our data to the display. + VkPresentInfoKHR present_info = { + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .waitSemaphoreCount = 1, + .pWaitSemaphores = signal_sems, + }; + + VkSwapchainKHR swapchains_array[] = { m_Swapchain }; + present_info.swapchainCount = 1; + present_info.pSwapchains = swapchains_array; + + present_info.pImageIndices = &m_CurrentImageIndex; + if(m_PresentationQueue == VK_NULL_HANDLE){ + ConsoleLogError("PresentationQueue is nullptr!!!"); + } + + vk_check(vkQueuePresentKHR(m_PresentationQueue, &present_info), "vkQueuePresentKHR", __FILE__, __LINE__, __FUNCTION__); + + m_CurrentFrameIndex = (m_CurrentFrameIndex + 1) % VulkanSwapchain::MaxFramesInFlight; + } + + uint32_t VulkanSwapchain::ReadAcquiredNextFrame() { + uint32_t image_index; + vk_check(vkWaitForFences(m_Driver, 1, &m_InFlightFences[m_CurrentFrameIndex], true, std::numeric_limits::max()), "vkWaitForFences", __FILE__, __LINE__, __FUNCTION__); + + vk_check(vkAcquireNextImageKHR(m_Driver, m_Swapchain, std::numeric_limits::max(), m_SemaphoresForAvailableImages[m_CurrentFrameIndex], VK_NULL_HANDLE, &image_index), "vkAcquireNextImageKHR", __FILE__, __LINE__, __FUNCTION__); + m_CurrentImageIndex = image_index; + return image_index; + } + + uint32_t VulkanSwapchain::CurrentFramePerTick() { + return m_CurrentFrameIndex; + } + + + + + + + + + + + + //! @note Extracts the next image. + /* + uint32_t VulkanSwapchain::AcquireNextImage(){ + uint32_t image_index; + vk_check(vkWaitForFences(m_Driver, 1, &m_InFlightFences[m_CurrentFrameIndex], true, std::numeric_limits::max()), "vkWaitForFences", __FILE__, __LINE__, __FUNCTION__); + + vk_check(vkAcquireNextImageKHR(m_Driver, m_Swapchain, std::numeric_limits::max(), m_SemaphoresForAvailableImages[m_CurrentFrameIndex], VK_NULL_HANDLE, &image_index), "vkAcquireNextImageKHR", __FILE__, __LINE__, __FUNCTION__); + m_CurrentImageIndex = image_index; + return image_index; + } + */ + + /* + void VulkanSwapchain::SubmitCommandBuffers(VkCommandBuffer* p_CommandBuffers){ + if(m_ImagesInFlight[m_CurrentImageIndex] != VK_NULL_HANDLE){ + vkWaitForFences(m_Driver, 1, &m_ImagesInFlight[m_CurrentImageIndex], true, std::numeric_limits::max()); + } + + m_ImagesInFlight[m_CurrentImageIndex] = m_InFlightFences[m_CurrentFrameIndex]; + + VkSubmitInfo submit_info = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = nullptr, + }; + + VkSemaphore wait_semaphore[] = {m_SemaphoresForAvailableImages[m_CurrentFrameIndex]}; + + VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + + submit_info.waitSemaphoreCount = 1; + submit_info.pWaitSemaphores = wait_semaphore; + submit_info.pWaitDstStageMask = wait_stages; + + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = p_CommandBuffers; + + VkSemaphore signal_sems[] = { m_SemaphoresForRenderCompleted[m_CurrentFrameIndex]}; + + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = signal_sems; + + vkResetFences(m_Driver, 1, &m_InFlightFences[m_CurrentFrameIndex]); + + vk_check(vkQueueSubmit(m_Driver.GetGraphicsQueue(), 1, &submit_info, m_InFlightFences[m_CurrentFrameIndex]), "vkQueueSubmit", __FILE__, __LINE__, __FUNCTION__); + + //! @note Now we present our data to the display. + VkPresentInfoKHR present_info = { + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .waitSemaphoreCount = 1, + .pWaitSemaphores = signal_sems, + }; + + VkSwapchainKHR swapchains_array[] = { m_Swapchain }; + present_info.swapchainCount = 1; + present_info.pSwapchains = swapchains_array; + + present_info.pImageIndices = &m_CurrentImageIndex; + if(m_PresentationQueue == VK_NULL_HANDLE){ + ConsoleLogError("PresentationQueue is nullptr!!!"); + } + + vk_check(vkQueuePresentKHR(m_PresentationQueue, &present_info), "vkQueuePresentKHR", __FILE__, __LINE__, __FUNCTION__); + + m_CurrentFrameIndex = (m_CurrentFrameIndex + 1) % VulkanSwapchain::MaxFramesInFlight; + } + */ + + + + + + uint32_t VulkanSwapchain::SelectMemoryType(VkPhysicalDeviceMemoryProperties p_MemoryProperties, uint32_t p_TypeFilter, VkMemoryPropertyFlags property_flag){ + for(uint32_t i = 0; i < p_MemoryProperties.memoryTypeCount; i++){ + if((p_TypeFilter & (1 << i)) && (p_MemoryProperties.memoryTypes[i].propertyFlags & property_flag) == property_flag){ + return i; + } + } + ConsoleLogError("VulkanSwapchain::SelectMemoryType returns zero meaning failed to find suitable memory type"); + return 0; + } + + VkPresentModeKHR VulkanSwapchain::SelectCompatiblePresentMode(const VkPresentModeKHR& p_RequestMode, const std::vector& p_Modes){ + for(const auto& mode : p_Modes){ + if(mode == p_RequestMode){ + return mode; + } + } + return VK_PRESENT_MODE_FIFO_KHR; + } + + VkExtent2D VulkanSwapchain::SelectValidExtent(const VkSurfaceCapabilitiesKHR& p_SurfaceCapabilities){ + //! @note Width/Height of our current swapchain + if(p_SurfaceCapabilities.currentExtent.width == std::numeric_limits::max() || p_SurfaceCapabilities.currentExtent.height == std::numeric_limits::max()){ + //! @note Passing width and height from passed in VkSurface. + m_SwapchainExtent = p_SurfaceCapabilities.currentExtent; + VkExtent2D current_extent = m_SwapchainExtent; + + //! @note Swapchain Extent checking so that width/height are not less than minimum width/height or greater then the max width/height + if(m_SwapchainExtent.width < p_SurfaceCapabilities.minImageExtent.width){ + current_extent.width = p_SurfaceCapabilities.minImageExtent.width; + } + else if(m_SwapchainExtent.width > p_SurfaceCapabilities.maxImageExtent.width){ + current_extent.width = p_SurfaceCapabilities.maxImageExtent.width; + } + + + if(m_SwapchainExtent.height < p_SurfaceCapabilities.minImageExtent.height){ + current_extent.height = p_SurfaceCapabilities.minImageExtent.height; + } + else if(m_SwapchainExtent.height > p_SurfaceCapabilities.maxImageExtent.height){ + current_extent.height = p_SurfaceCapabilities.maxImageExtent.height; + } + + if(current_extent.width == 0 and current_extent.height == 0){ + current_extent.width = ApplicationInstance::GetWindow().GetWidth(); + current_extent.height = ApplicationInstance::GetWindow().GetHeight(); + } + + return current_extent; + } + + if(p_SurfaceCapabilities.currentExtent.width == 0 and p_SurfaceCapabilities.currentExtent.height){ + VkExtent2D current_extent; + current_extent.width = ApplicationInstance::GetWindow().GetWidth(); + current_extent.height = ApplicationInstance::GetWindow().GetHeight(); + } + return p_SurfaceCapabilities.currentExtent; + } + + VkFormat VulkanSwapchain::SelectDepthFormat(VkPhysicalDevice p_PhysicalDevice){ + return SelectSupportedFormat(p_PhysicalDevice, + {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, + VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + + + } + + VkFormat VulkanSwapchain::SelectSupportedFormat(VkPhysicalDevice p_PhysicalDevice, const std::vector& p_Formats, VkImageTiling p_Tiling, VkFormatFeatureFlags p_FeatureFlag){ + VkFormat valid_format = VK_FORMAT_UNDEFINED; + + for(const auto& format : p_Formats){ + VkFormatProperties properties; + vkGetPhysicalDeviceFormatProperties(p_PhysicalDevice, format, &properties); + + if(p_Tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & p_FeatureFlag) == p_FeatureFlag){ + valid_format = format; + } + else if(p_Tiling == VK_IMAGE_TILING_OPTIMAL && (properties.optimalTilingFeatures & p_FeatureFlag) == p_FeatureFlag){ + valid_format = format; + } + } + + vk_check_format(valid_format, __FILE__, __LINE__, __FUNCTION__); + + return valid_format; + } +}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/Vulkan2Showcase/VulkanWindow.cpp b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanWindow.cpp new file mode 100644 index 0000000..0ca4a99 --- /dev/null +++ b/src/engine3d/Core/internal/Vulkan2Showcase/VulkanWindow.cpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include + +namespace engine3d::vk{ + VulkanWindow::VulkanWindow(const std::string& p_Tag, uint32_t w, uint32_t h) : m_Width(w), m_Height(h){ + if(!glfwInit()){ + ConsoleLogError("glfwInit failed!"); + } + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + m_Window = glfwCreateWindow((int)w, (int)h, p_Tag.c_str(), nullptr, nullptr); + + if(!glfwVulkanSupported()){ + ConsoleLogError("GLFW: Vulkan not supported!!!"); + } + + ConsoleLogInfo("Before Vulkan2Showcase Context Initialized!"); + vk::VulkanContext::Initialize(); + vk_check(glfwCreateWindowSurface(vk::VulkanContext::GetVkInstance(),m_Window, nullptr, &m_Surface), "glfwCreateWindowSurface", __FILE__, __LINE__, __FUNCTION__); + ConsoleLogWarn("glfwCreateWindowSurface Initialized!"); + // m_Swapchain = VulkanSwapchain(VulkanContext::GetPhysicalDriver(), VulkanContext::GetDriver(), m_Surface); + m_Swapchain = GraphicSwapchain::InitializeSwapchain(m_Surface); + + ConsoleLogInfo("Vulkan2Showcase VulkanWindow Initialized Complete!!!"); + } + + bool VulkanWindow::CurrentWindowActive() const { return !glfwWindowShouldClose(m_Window); } + + VkSurfaceKHR& VulkanWindow::VkSurface(){ return m_Surface; } + + GLFWwindow* VulkanWindow::NativeWindow(){ return m_Window; } + + void VulkanWindow::Presentation(){ + + } +}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/Vulkan2Showcase/helper_functions.cpp b/src/engine3d/Core/internal/Vulkan2Showcase/helper_functions.cpp new file mode 100644 index 0000000..d499938 --- /dev/null +++ b/src/engine3d/Core/internal/Vulkan2Showcase/helper_functions.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +namespace engine3d::vk{ + void vk_check(VkResult result, const char* p_Tag, const char* p_Filename, uint32_t p_LineName, const char* p_FunctionName){ + if(result != VK_SUCCESS){ + ConsoleLogError("VkResult failed taking in {0} file: {1} --- Line: {2} --- In Function: {3}",p_Tag, p_Filename, p_LineName, p_FunctionName); + ConsoleLogError("VkResult returned: {}", (int)result); + // std::terminate(); + // exit(0); + } + } + + void vk_check_format(VkFormat p_Format, const char* p_Filename, uint32_t p_LineName, const char* p_FunctionName){ + if(p_Format == VK_FORMAT_UNDEFINED){ + ConsoleLogError("VkFormat failed in file: {0} --- Line: {1} --- In Function: {2}", p_Filename, p_LineName, p_FunctionName); + ConsoleLogError("VkFormat was assigned to VK_FORMAT_UNDEFINED"); + } + } + + std::string vk_queue_flags_to_string(VkQueueFlagBits flags){ + switch (flags){ + case VK_QUEUE_GRAPHICS_BIT: return "VK_QUEUE_GRAPHICS_BIT"; + case VK_QUEUE_COMPUTE_BIT: return "VK_QUEUE_COMPUTE_BIT"; + case VK_QUEUE_TRANSFER_BIT: return "VK_QUEUE_TRANSFER_BIT"; + case VK_QUEUE_SPARSE_BINDING_BIT: return "VK_QUEUE_SPARSE_BINDING_BIT"; + case VK_QUEUE_PROTECTED_BIT: return "VK_QUEUE_PROTECTED_BIT"; + case VK_QUEUE_VIDEO_DECODE_BIT_KHR: return "VK_QUEUE_VIDEO_DECODE_BIT_KHR"; + case VK_QUEUE_VIDEO_ENCODE_BIT_KHR: return "VK_QUEUE_VIDEO_ENCODE_BIT_KHR"; + case VK_QUEUE_OPTICAL_FLOW_BIT_NV: return "VK_QUEUE_OPTICAL_FLOW_BIT_NV"; + case VK_QUEUE_FLAG_BITS_MAX_ENUM: return "VK_QUEUE_FLAG_BITS_MAX_ENUM"; + } + + return "VkQueueFlag not Selected"; + } +}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/VulkanCpp/Vulkan.cpp b/src/engine3d/Core/internal/VulkanCpp/Vulkan.cpp deleted file mode 100644 index d8e0989..0000000 --- a/src/engine3d/Core/internal/VulkanCpp/Vulkan.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "EngineLogger.hpp" -#include -#include - -#include -#include -#include -#include - -namespace engine3d::vk{ - //! @note These are different extensions we need to check are available as required for the vulkan API. -#if defined(_WIN32) - static std::vector extensions = { - VK_KHR_SURFACE_EXTENSION_NAME, - VK_EXT_DEBUG_UTILS_EXTENSION_NAME, - "VK_KHR_win32_surface" - }; -#elif defined(__APPLE__) - static std::vector extensions = { - VK_KHR_SURFACE_EXTENSION_NAME, - VK_EXT_DEBUG_UTILS_EXTENSION_NAME, - "VK_KHR_surface", - "VK_EXT_metal_surface", - - VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, - VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, - }; -#elif defined(__linux__) - static std::vector extensions = { - VK_KHR_SURFACE_EXTENSION_NAME, - VK_EXT_DEBUG_UTILS_EXTENSION_NAME, - "VK_KHR_xcb_surface", - }; -#else // this is if we aren't on Win32, Mac, or even linux for some odd reason. -#endif - - static std::vector validationLayers = { - "VK_LAYER_KHRONOS_validation", - /* "VK_LAYER_LUNARG_api_dump", */ - /* "VK_LAYER_KHRONOS_profiles", */ - /* "VK_LAYER_KHRONOS_synchronization2", */ - /* "VK_LAYER_KHRONOS_shader_object", */ - }; - - static VkInstance g_Instance; - - void Vulkan::InitializeVulkanCore(){ - //! @note to initialize vulkan we need to first specify our application properties. - //! @note Initialize vulkan's instance information for instantiation. - VkApplicationInfo appInfo = { - .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .pApplicationName = "Engine3D", - .pEngineName = "Engine3D", - .engineVersion = VK_MAKE_API_VERSION(1, 1, 0, 0), - .apiVersion = VK_API_VERSION_1_0 - }; - - VkInstanceCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .pApplicationInfo = &appInfo, - .enabledLayerCount = static_cast(validationLayers.size()), - .ppEnabledLayerNames = validationLayers.data(), - .enabledExtensionCount = static_cast(extensions.size()), - .ppEnabledExtensionNames = extensions.data() - }; - -#if defined(__APPLE__) - //! @note enabling this flags allow vulkan non-conformant vulkan implementation to be built on top of another non-vulkan graphics API sucha as Metal, DX12, and etc. - createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; -#endif - - VkResult res = vkCreateInstance(&createInfo, nullptr, &g_Instance); - if(res != VK_SUCCESS){ - throw std::runtime_error("vkCreateInstance errored message ===> "); - } - - if(g_Instance == VK_NULL_HANDLE){ - throw std::runtime_error("Vulkan VkInstance::g_Instance === nullptr"); - } - - //! @note Setting the debug callback - } - - void Vulkan::CleanupVulkanCore(){ - } - - VkInstance& Vulkan::GetVkInstance(){ - return g_Instance; - } - -}; diff --git a/src/engine3d/Core/internal/VulkanCpp/VulkanDevice.cpp b/src/engine3d/Core/internal/VulkanCpp/VulkanDevice.cpp deleted file mode 100644 index 9cdb811..0000000 --- a/src/engine3d/Core/internal/VulkanCpp/VulkanDevice.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include - -namespace engine3d::vk{ - /** - * @note Having a static pointer to the actual data of the logical device. - * @note Reasons for this: Is because if we dont then the compiler treats this as as a copyable object that wont get instantiated. - * @note To see the error, make g_LogicalDeviceInstance a non-pointer to receive the error. - */ - static VulkanLogicalDevice* g_LogicalDeviceInstance; - - void VulkanDevice::InitializeVulkanDevice(){ - VulkanPhysicalDevice physicalDevice = vk::VulkanPhysicalDevice(); - vk::VulkanLogicalDevice logical = vk::VulkanLogicalDevice(physicalDevice); - g_LogicalDeviceInstance = &logical; - } - - void VulkanDevice::CleanupVulkanDevices(){ - delete g_LogicalDeviceInstance; - } - - VulkanPhysicalDevice& VulkanDevice::GetPhysicalDevice() { - return g_LogicalDeviceInstance->GetPhysicalDevice(); - } - - VulkanLogicalDevice& VulkanDevice::GetLogicalDevice(){ - return *g_LogicalDeviceInstance; - } - - // RendererPipeline* Create(){ - // switch (CurrentAPI()){ - // case API::VULKAN: - // return new VulkanRenderer(); - // case API::DIRECTX12: - // return new Dx12Renderer(); - // default: return nullptr; - // } - - // return nullptr; - // } - -}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/VulkanCpp/VulkanLogicalDevice.cpp b/src/engine3d/Core/internal/VulkanCpp/VulkanLogicalDevice.cpp deleted file mode 100644 index 7feaa24..0000000 --- a/src/engine3d/Core/internal/VulkanCpp/VulkanLogicalDevice.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include - -namespace engine3d::vk{ - VulkanLogicalDevice::VulkanLogicalDevice(VulkanPhysicalDevice& p_PhysicalDevice){ - VkPhysicalDeviceFeatures vulkanEnabledFeatures = { - .independentBlend = true, // specifies when VkPipelineColorAttachmentState settings are controlled independently per attachment - .fillModeNonSolid = true, // specifies whether point and wireframe fill modes are supported. If feature are not enabled, VK_POLYGON_MODE_POINT and VK_POLYGON_MODE_LINE will not be used. - .wideLines = true, // specifies whether lines with width other than 1.0 are supported. Feature if not enabled, lineWidth member of VkPipelineRasterizationStateCreateInfo will default to 1.0 value - .samplerAnisotropy = true, // specifies whether anisotropic filtering is supported. If feature isn't enabled, the "anisotropyEnable" member of "VKSamplerCreateInfo" structure must be VK_FALSE - .pipelineStatisticsQuery = true, // specifies whether the pipeline statistics queries are supported. If not enabled, query type "VK_QUERY_TYPE_PIPELINE_STATISTICS" cannot be created. - .shaderStorageImageReadWithoutFormat = true,// specifies whether storage images and storage texel buffers require a format qualifier to be specified when reading. Applies only to formats listed in "storage without format" list. - }; - - m_PhysicalDevice = p_PhysicalDevice; - - m_EnabledPhysicalFeatures = vulkanEnabledFeatures; - - } - - VkDevice VulkanLogicalDevice::GetVkDeviceInstance(){ - return m_LogicalDevice; - } - - VulkanPhysicalDevice& VulkanLogicalDevice::GetPhysicalDevice(){ - return m_PhysicalDevice; - } - - VkPhysicalDeviceFeatures VulkanLogicalDevice::GetVkPhysicalDeviceFeatures(){ - return m_EnabledPhysicalFeatures; - } - - VkQueue VulkanLogicalDevice::GetVkGraphicsQueue(){ - return m_GraphicsQueue; - } - - VkQueue VulkanLogicalDevice::GetVkComputeQueue(){ - return m_ComputeQueue; - } -}; \ No newline at end of file diff --git a/src/engine3d/Core/internal/VulkanCpp/VulkanPhysicalDevice.cpp b/src/engine3d/Core/internal/VulkanCpp/VulkanPhysicalDevice.cpp deleted file mode 100644 index 278aa62..0000000 --- a/src/engine3d/Core/internal/VulkanCpp/VulkanPhysicalDevice.cpp +++ /dev/null @@ -1,246 +0,0 @@ -#include "EngineLogger.hpp" -#include -#include -#include -#include - -#if _WIN32 -#define VK_USE_PLATFORM_WIN32_KHR -#define GLFW_INCLUDE_VULKAN -#include -#define GLFW_EXPOSE_NATIVE_WIN32 -#include -#include -#include -#else -#include -#include -#endif - -namespace engine3d::vk{ - - VulkanPhysicalDevice::VulkanPhysicalDevice(){ - auto& instance = Vulkan::GetVkInstance(); - std::vector devices = get_available_devices(); - - // printf("available devices size() = %zu\n", devices.size()); - uint32_t gpu_count = devices.size(); - - //! @note Validating our physical device is a discrete GPU. - //! @note Using our discrete GPU that has been found on our machine. - //! @note vkGetPhysicalDeviceProperties is how we get information about our physical device. - for(VkPhysicalDevice device : devices){ - vkGetPhysicalDeviceProperties(device, &m_PhysicalDeviceProperties); - - if(m_PhysicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU){ - m_SelectedPhysicalDevice = device; - break; - } - } - - if(!m_SelectedPhysicalDevice){ - m_SelectedPhysicalDevice = devices.back(); - } - - m_PhysicalDeviceHandler = m_SelectedPhysicalDevice; - - vkGetPhysicalDeviceFeatures(m_PhysicalDeviceHandler, &m_PhysicalDeviceFeatures); - vkGetPhysicalDeviceMemoryProperties(m_PhysicalDeviceHandler, &m_PhysicalMemoryProperties); - - //! @note This is how we know what queue families are available to us by checking through our physical devices. - uint32_t queue_family_count = 0; - vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDeviceHandler, &queue_family_count, nullptr); - /* printf("queue_family_count === %i\n", queue_family_count); */ - // assert(queue_family_count > 0); - if(queue_family_count <= 0) throw std::runtime_error("queue_family_count === 0"); - - m_QueueFamilyProperties.resize(queue_family_count); - vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalDeviceHandler, &queue_family_count, m_QueueFamilyProperties.data()); // reads in the queue family properties from our physical devices - - //! @note Validating our extensions and getting the extensinos that we support. - uint32_t extension_count = 0; - vkEnumerateDeviceExtensionProperties(m_PhysicalDeviceHandler, nullptr, &extension_count, nullptr); // just used to read how many extensions are available. - - if(extension_count > 0){ - std::vector extensions(extension_count); - if(vkEnumerateDeviceExtensionProperties(m_PhysicalDeviceHandler, nullptr, &extension_count, &extensions.front()) == VK_SUCCESS){ - // ConsoleLogInfo("Selected physical device {0} extensions", extensions.size()); - - for(const auto& ext : extensions){ - m_SupportedExtensions.emplace(ext.extensionName); - // ConsoleLogInfo("{0}", ext.extensionName); - } - } - } - - /** - * @name Queue Families - * @note The desired queues needed to be requested from logical device creation - * @note Because there are differing queues family configurations of Vulkan implementation this can be tricky, especially if Engine3D's applicatio - * can request different queue types. - * @note Getting queue family indices for the requested family types. - * @note indices may also overlap depending on the implementation. - */ - static const float defauly_queue_priority = 0.0f; - int requested_queue_t = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT; - m_QueueIndices = GetQueueFamilyIndices(requested_queue_t); - - // VK_QUEUE_GRAPHICS_BIT - //! @note Checking queue family for graphics operations. ( Such as vkCmdDraw*(...) ) - if(requested_queue_t & VK_QUEUE_GRAPHICS_BIT){ - VkDeviceQueueCreateInfo createInfo{ - .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueFamilyIndex = (uint32_t)m_QueueIndices.Graphics, - .queueCount = 1, - .pQueuePriorities = &defauly_queue_priority, - }; - m_DeviceQueueCreateInfos.push_back(createInfo); - } - - // VK_QUEUE_COMPUTE_BIT - //! @note Specifies queues in this queue family support compute operations. - if(requested_queue_t & VK_QUEUE_COMPUTE_BIT){ - if (m_QueueIndices.Compute != m_QueueIndices.Graphics){ - // If compute family index differs, we need an additional queue create info for the compute queue - VkDeviceQueueCreateInfo createInfo{ - .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueFamilyIndex = (uint32_t)m_QueueIndices.Compute, - .queueCount = 1, - .pQueuePriorities = &defauly_queue_priority - }; - m_DeviceQueueCreateInfos.push_back(createInfo); - } - } - - // VK_QUEUE_TRANSFER_BIT - //! @note specifies queues in this family only has support for transfer operations. - if(requested_queue_t & VK_QUEUE_TRANSFER_BIT){ - if((m_QueueIndices.Transfer != m_QueueIndices.Graphics) && (m_QueueIndices.Transfer != m_QueueIndices.Compute)){ - // If compute family index differs, we need an additional queue create info for the compute queue - VkDeviceQueueCreateInfo createInfo{ - .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, - .queueFamilyIndex = (uint32_t)m_QueueIndices.Transfer, - .queueCount = 1, - .pQueuePriorities = &defauly_queue_priority - }; - m_DeviceQueueCreateInfos.push_back(createInfo); - } - } - } - - VulkanPhysicalDevice::QueueFamilyIndices VulkanPhysicalDevice::GetQueueFamilyIndices(int flag){ - QueueFamilyIndices indices; - - /** - * @note Dedicated for computing queues-only. - * @note Searching for a queue family at specific indices that support computing and not graphics. - */ - if(flag & VK_QUEUE_COMPUTE_BIT){ - for(uint32_t i = 0; i < m_QueueFamilyProperties.size(); i++){ - auto& queue_family_properties = m_QueueFamilyProperties[i]; - if((queue_family_properties.queueFlags & VK_QUEUE_COMPUTE_BIT) and ((queue_family_properties.queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)){ - indices.Compute = i; - break; - } - } - } - - /** - * @note Searching for dedicated queues for transfer-specifically. - * @note Attempting searching for queue family index that supports transfering but no graphics/compute. - */ - if(flag & VK_QUEUE_TRANSFER_BIT){ - for(uint32_t i = 0; i < m_QueueFamilyProperties.size(); i++){ - auto& queue_family_properties = m_QueueFamilyProperties[i]; - if((queue_family_properties.queueFlags & VK_QUEUE_TRANSFER_BIT) and ((queue_family_properties.queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)){ - indices.Transfer = i; - break; - } - } - } - - /** - * @note For any other queue types or if no separate compute queue is present, return irst one to support the requested flags instead. - */ - if(flag & VK_QUEUE_GRAPHICS_BIT){ - for(uint32_t i = 0; i < m_QueueFamilyProperties.size(); i++){ - if((flag & VK_QUEUE_TRANSFER_BIT) and indices.Transfer == -1){ - if(m_QueueFamilyProperties[i].queueFlags & VK_QUEUE_TRANSFER_BIT) - indices.Transfer = i; - } - - if((flag & VK_QUEUE_COMPUTE_BIT) and indices.Compute == -1){ - if(m_QueueFamilyProperties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) - indices.Compute = i; - } - - if(flag & VK_QUEUE_GRAPHICS_BIT){ - if(m_QueueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) - indices.Graphics = i; - } - } - } - - return indices; - } - - VkFormat VulkanPhysicalDevice::SearchAvailableDepthFormat(){ - // Since all depth formats may be optional, we need to find a suitable depth format to use - // Start with the highest precision packed format - std::vector depthFormats = { - VK_FORMAT_D32_SFLOAT_S8_UINT, - VK_FORMAT_D32_SFLOAT, - VK_FORMAT_D24_UNORM_S8_UINT, - VK_FORMAT_D16_UNORM_S8_UINT, - VK_FORMAT_D16_UNORM - }; - - // TODO: Move to VulkanPhysicalDevice - for (auto& format : depthFormats) - { - VkFormatProperties formatProps; - vkGetPhysicalDeviceFormatProperties(m_PhysicalDeviceHandler, format, &formatProps); - // Format must support depth stencil attachment for optimal tiling - if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) - return format; - } - - return VK_FORMAT_UNDEFINED; - } - - bool VulkanPhysicalDevice::IsExtensionSupported(const std::string& ext_name){ - return m_SupportedExtensions.find(ext_name) != m_SupportedExtensions.end(); - } - - std::vector VulkanPhysicalDevice::get_available_devices(){ - uint32_t gpu_devices_count = 0; - printf("Before enumerating physical devices\n"); - if(Vulkan::GetVkInstance() == VK_NULL_HANDLE){ - printf("GetVkInstance() == nullptr!\n"); - } - VkResult res = vkEnumeratePhysicalDevices(Vulkan::GetVkInstance(), &gpu_devices_count, nullptr); - // printf("gpu_devices_count (afterwards) === %i\n", gpu_devices_count); - // static_assert(gpu_devices_count > 0); - if(res != VK_SUCCESS){ - printf("get_available_devices error number ===>>> %i\n", res); - } - std::vector devices(gpu_devices_count); - // printf("vector size (afterwards) === %zu\n", devices.size()); - res = vkEnumeratePhysicalDevices(Vulkan::GetVkInstance(), &gpu_devices_count, devices.data()); - return devices; - } - - void VulkanPhysicalDevice::print_physical_device_property(VkPhysicalDeviceProperties properties){ - printf("==================================================\n"); - std::stringstream ss; - ss << "Device ID: " << properties.deviceID << '\n'; - ss << "Device Name: " << properties.deviceName << '\n'; - ss << "Driver Version: " << properties.driverVersion << '\n'; - ss << "API Version: " << properties.apiVersion << '\n'; - } - - - VkPhysicalDevice& VulkanPhysicalDevice::GetVkPhysicalDevice(){ return m_PhysicalDeviceHandler; } - - VkFormat VulkanPhysicalDevice::GetDepthFormat(){ return SearchAvailableDepthFormat(); } -}; diff --git a/src/engine3d/Core/internal/VulkanCpp/VulkanSwapchain.cpp b/src/engine3d/Core/internal/VulkanCpp/VulkanSwapchain.cpp deleted file mode 100644 index 562207e..0000000 --- a/src/engine3d/Core/internal/VulkanCpp/VulkanSwapchain.cpp +++ /dev/null @@ -1,462 +0,0 @@ -#include "EngineLogger.hpp" -#include "Renderer/Renderer.hpp" -#include "internal/VulkanCpp/Vulkan.hpp" -#include "internal/VulkanCpp/VulkanDevice.hpp" -#include - -#include - - -#if _WIN32 -#define VK_USE_PLATFORM_WIN32_KHR -#define GLFW_INCLUDE_VULKAN -#include -#define GLFW_EXPOSE_NATIVE_WIN32 -#include -#include -#include -#define NOMINMAX -#include -#else -#include -#include -#endif - -#include - -static PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR; -static PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR; - - -namespace engine3d::vk{ - VulkanSwapchain::VulkanSwapchain(GLFWwindow* p_WindowHandler, bool p_VSync){ - ConsoleLogInfo("Initializing VulkanSwapchain!!!!"); - m_VSync = p_VSync; - - glfwCreateWindowSurface(Vulkan::GetVkInstance(), p_WindowHandler, nullptr, &m_Surface); - - auto& physical_device = VulkanDevice::GetPhysicalDevice().GetVkPhysicalDevice(); - if(physical_device == VK_NULL_HANDLE){ - /* printf("physical_device === nullptr~\n"); */ - ConsoleLogWarn("physical_device === VK_NULL_HANDLE\n"); - } - - uint32_t queue_count = 0; - vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_count, nullptr); - /* printf("queue_count = %i\n", queue_count); */ - - // assert(queue_count >= 1); - // if(queue_count >= 1){ - // ConsoleLogWarn("Queue Count >= 1"); - // } - - // ConsoleLogError("queue_count = {0}", queue_count); - // std::vector queue_properties(queue_count); - // vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_count, queue_properties.data()); - - //! @note Using our physical device to check what presentation mode is available on our current platform. - // std::vector presentation_supported(queue_count); - // for(uint32_t i = 0; i < queue_count; i++){ - // vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, m_Surface, &presentation_supported[i]); - // } - - // // uint32_t graphics_queue_node_idx = std::numeric_limits::max(); - // uint32_t graphics_queue_node_idx = UINT32_MAX; - // uint32_t presentation_queue_node_idx = UINT32_MAX; - - // //! @note We fetch the index of our queue type. - // for(uint32_t i = 0; i < queue_count; i++){ - // if((queue_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)){ - // if(graphics_queue_node_idx == UINT32_MAX){ - // graphics_queue_node_idx = i; - // } - - // if(presentation_supported[i]){ - // graphics_queue_node_idx = i; - // presentation_queue_node_idx = i; - // break; - // } - // } - // } - - // if(presentation_queue_node_idx == UINT32_MAX){ - // for(uint32_t i = 0; i < queue_count; i++){ - // if(presentation_supported[i]){ - // presentation_queue_node_idx = i; - // break; - // } - // } - // } - - // if(graphics_queue_node_idx == UINT32_MAX){ - // ConsoleLogError("graphics_queue_node_idx == UINT32_MAX"); - // } - - // if(presentation_queue_node_idx == UINT32_MAX){ - // ConsoleLogError("presentation_queue_node_idx == UINT32_MAX"); - // } - - // m_queue_node_idx = graphics_queue_node_idx; - - // SearchImageFormatAndColorspace(); - - // //! @note Initiating Swapchain - // auto device = VulkanDevice::GetLogicalDevice().GetVkDeviceInstance(); - // // auto physical_device = VulkanDevice::GetPhysicalDevice().GetVkPhysicalDevice(); - - // //! @note Extracting presentation modes available. - // uint32_t presentation_mode_count; - // vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, m_Surface, &presentation_mode_count, NULL); - // std::vector presentModes(presentation_mode_count); - // vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, m_Surface, &presentation_mode_count, presentModes.data()); - - // VkSurfaceCapabilitiesKHR surface_capabilities; - // vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, m_Surface, &surface_capabilities); - - // VkExtent2D swapchain_extent = {}; - - // if(surface_capabilities.currentExtent.width == (uint32_t)-1){ - // // If the surface capabilities are -1 or not set we set them. - // int width, height; - // glfwGetWindowSize(p_WindowHandler, &width, &height); - // swapchain_extent.width = width; - // swapchain_extent.height = height; - // } - // else{ - // swapchain_extent = surface_capabilities.currentExtent; - // m_Width = surface_capabilities.currentExtent.width; - // m_Height = surface_capabilities.currentExtent.height; - // } - - // if(m_Width == 0 || m_Height == 0){ - // return; - // } - - // VkPresentModeKHR swapchain_present_mode = VK_PRESENT_MODE_FIFO_KHR; - - // // If v-sync is not requested, try to find a mailbox mode - // // It's the lowest latency non-tearing present mode available - // if(!m_VSync){ - // for (size_t i = 0; i < presentation_mode_count; i++){ - // if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR){ - // swapchain_present_mode = VK_PRESENT_MODE_MAILBOX_KHR; - // break; - // } - // if ((swapchain_present_mode != VK_PRESENT_MODE_MAILBOX_KHR) && (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)){ - // swapchain_present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; - // } - // } - // } - - - // //! @note Determining number of images. - // uint32_t desired_number_of_images = surface_capabilities.minImageCount + 1; - - // if((surface_capabilities.maxImageCount > 0) and (desired_number_of_images > surface_capabilities.maxImageCount)){ - // desired_number_of_images = surface_capabilities.maxImageCount; - // } - - // // Searching transformation of our surface. - // VkSurfaceTransformFlagBitsKHR pres_transform; - // if(surface_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR){ - // // We prefer a non-rotated transform - // pres_transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - // } - // else{ - // pres_transform = surface_capabilities.currentTransform; - // } - - // // Find a supported composite alpha format (not all devices support alpha opaque) - // VkCompositeAlphaFlagBitsKHR composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - // // Simply select the first composite alpha format available - // std::vector compositeAlphaFlags = { - // VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - // VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR, - // VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, - // VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR, - // }; - // for (auto& compositeAlphaFlag : compositeAlphaFlags) { - // if (surface_capabilities.supportedCompositeAlpha & compositeAlphaFlag) { - // composite_alpha = compositeAlphaFlag; - // break; - // }; - // } - - // VkSwapchainCreateInfoKHR createInfo = { - // .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, - // .pNext = nullptr, - // .surface = m_Surface, - // .minImageCount = desired_number_of_images, - // .imageFormat = m_ColorFormat, - // .imageColorSpace = m_ColorSpace, - // .imageExtent = {swapchain_extent.width, swapchain_extent.height}, - // .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - // .preTransform = (VkSurfaceTransformFlagBitsKHR)pres_transform, - // .imageArrayLayers = 1, - // .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, - // .queueFamilyIndexCount = 0, - // .pQueueFamilyIndices = nullptr, - // .presentMode = swapchain_present_mode, - // .oldSwapchain = m_OldSwapchain, - // .clipped = true, - // .compositeAlpha = composite_alpha - // }; - - // vkCreateSwapchainKHR(device, &createInfo, nullptr, &m_CurrentSwapchain); - - // if(m_OldSwapchain){ - // vkDestroySwapchainKHR(device, m_OldSwapchain, nullptr); - // } - - - - // //! @note Determining images. - // uint32_t images_size = 0; - // for(auto& image : m_SwapchainImages){ - // vkDestroyImageView(device, image.image_view, nullptr); - // } - // m_Images.clear(); - - // vkGetSwapchainImagesKHR(device, m_CurrentSwapchain, &images_size, nullptr); - // m_Images.resize(images_size); - // m_Images.resize(images_size); - // vkGetSwapchainImagesKHR(device, m_CurrentSwapchain, &images_size, m_Images.data()); - - // for(uint32_t i = 0; i < m_Images.size(); i++){ - // VkImageViewCreateInfo imageViewCreateInfo = { - // .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - // .pNext = nullptr, - // .format = m_ColorFormat, - // .image = m_Images[i], - // .components = { - // VK_COMPONENT_SWIZZLE_G, - // VK_COMPONENT_SWIZZLE_B, - // VK_COMPONENT_SWIZZLE_A - // }, - // .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - // .subresourceRange.baseMipLevel = 0, - // .subresourceRange.levelCount = 1, - // .subresourceRange.baseArrayLayer = 0, - // .subresourceRange.layerCount = 1, - // .viewType = VK_IMAGE_VIEW_TYPE_2D, - // .flags = 0 - // }; - - // m_SwapchainImages[i].image = m_Images[i]; - - // vkCreateImageView(device, &imageViewCreateInfo, nullptr, &m_SwapchainImages[i].image_view); - // } - - // //! @note Swapchain Creating its own sets of command buffers - // for(auto& command : m_CommandBuffers){ - // vkDestroyCommandPool(device, command.CommandBufferPool, nullptr); - // } - - // VkCommandPoolCreateInfo command_pool_create_info = { - // .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - // .queueFamilyIndex = m_queue_node_idx, - // .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, - // }; - - // VkCommandBufferAllocateInfo allocateInfo = { - // .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - // .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - // .commandBufferCount = 1 - // }; - - // m_CommandBuffers.resize(images_size); - // for(auto& command_buffer : m_CommandBuffers){ - // vkCreateCommandPool(device, &command_pool_create_info, nullptr, &command_buffer.CommandBufferPool); - // vkAllocateCommandBuffers(device, &allocateInfo, &command_buffer.CommndBufferData); - // } - - // auto frames_in_flight = Renderer::GetSettings().FramesInFlight; - // if(m_ImageAvailableSemaphores.size() != frames_in_flight){ - // m_ImageAvailableSemaphores.resize(frames_in_flight); - // // m_RenderFinishedSemaphores.resize(frames_in_flight); - // m_ImagesFinishedRenderingSemaphores.resize(frames_in_flight); - // VkSemaphoreCreateInfo semaphoreCreateInfo{}; - // semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - // for (size_t i = 0; i < frames_in_flight; i++){ - // vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &m_ImageAvailableSemaphores[i]); - // // VKUtils::SetDebugUtilsObjectName(device, VK_OBJECT_TYPE_SEMAPHORE, std::format("Swapchain Semaphore ImageAvailable {0}", i), m_ImageAvailableSemaphores[i]); - // vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &m_ImagesFinishedRenderingSemaphores[i]); - // // VKUtils::SetDebugUtilsObjectName(device, VK_OBJECT_TYPE_SEMAPHORE, std::format("Swapchain Semaphore RenderFinished {0}", i), m_RenderFinishedSemaphores[i]); - // } - // } - - // if(m_Fences.size() != frames_in_flight){ - // VkFenceCreateInfo fenceCreateInfo{}; - // fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - // fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - - // m_Fences.resize(frames_in_flight); - // for (auto& fence : m_Fences){ - // vkCreateFence(device, &fenceCreateInfo, nullptr, &fence); - // // VKUtils::SetDebugUtilsObjectName(device, VK_OBJECT_TYPE_FENCE, "Swapchain Fence", fence); - // } - // } - - // VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - - // VkFormat depthFormat = VulkanDevice::GetPhysicalDevice().GetDepthFormat(); - - // // Render Pass - // VkAttachmentDescription colorAttachmentDesc = {}; - // // Color attachment - // colorAttachmentDesc.format = m_ColorFormat; - // colorAttachmentDesc.samples = VK_SAMPLE_COUNT_1_BIT; - // colorAttachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - // colorAttachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - // colorAttachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - // colorAttachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - // colorAttachmentDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - // colorAttachmentDesc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - // VkAttachmentReference colorReference = {}; - // colorReference.attachment = 0; - // colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - // VkAttachmentReference depthReference = {}; - // depthReference.attachment = 1; - // depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - // VkSubpassDescription subpassDescription = {}; - // subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - // subpassDescription.colorAttachmentCount = 1; - // subpassDescription.pColorAttachments = &colorReference; - // subpassDescription.inputAttachmentCount = 0; - // subpassDescription.pInputAttachments = nullptr; - // subpassDescription.preserveAttachmentCount = 0; - // subpassDescription.pPreserveAttachments = nullptr; - // subpassDescription.pResolveAttachments = nullptr; - - // VkSubpassDependency dependency = {}; - // dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - // dependency.dstSubpass = 0; - // dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - // dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - // dependency.srcAccessMask = 0; - // dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - // VkRenderPassCreateInfo renderPassInfo = {}; - // renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - // renderPassInfo.attachmentCount = 1; - // renderPassInfo.pAttachments = &colorAttachmentDesc; - // renderPassInfo.subpassCount = 1; - // renderPassInfo.pSubpasses = &subpassDescription; - // renderPassInfo.dependencyCount = 1; - // renderPassInfo.pDependencies = &dependency; - - // vkCreateRenderPass(device, &renderPassInfo, nullptr, &m_RenderPassSwapchain); - - // //! @note Creating framebuffers - // for (auto& framebuffer : m_Framebuffers) - // vkDestroyFramebuffer(device, framebuffer, nullptr); - - // VkFramebufferCreateInfo frameBufferCreateInfo = {}; - // frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - // frameBufferCreateInfo.renderPass = m_RenderPassSwapchain; - // frameBufferCreateInfo.attachmentCount = 1; - // frameBufferCreateInfo.width = m_Width; - // frameBufferCreateInfo.height = m_Height; - // frameBufferCreateInfo.layers = 1; - - // m_Framebuffers.resize(images_size); - // for (uint32_t i = 0; i < m_Framebuffers.size(); i++){ - // frameBufferCreateInfo.pAttachments = &m_SwapchainImages[i].image_view; - // vkCreateFramebuffer(device, &frameBufferCreateInfo, nullptr, &m_Framebuffers[i]); - // // VKUtils::SetDebugUtilsObjectName(m_Device->GetVulkanDevice(), VK_OBJECT_TYPE_FRAMEBUFFER, std::format("Swapchain framebuffer (Frame in flight: {})", i), m_Framebuffers[i]); - // } - } - - void VulkanSwapchain::SearchImageFormatAndColorspace(){ - auto physical_device = VulkanDevice::GetPhysicalDevice().GetVkPhysicalDevice(); - - // Get list of supported surface formats - uint32_t formatCount; - vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, m_Surface, &formatCount, NULL); - // HZ_CORE_ASSERT(formatCount > 0); - - std::vector surfaceFormats(formatCount); - vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, m_Surface, &formatCount, surfaceFormats.data()); - - // If the surface format list only includes one entry with VK_FORMAT_UNDEFINED, - // there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM - if ((formatCount == 1) && (surfaceFormats[0].format == VK_FORMAT_UNDEFINED)){ - m_ColorFormat = VK_FORMAT_B8G8R8A8_UNORM; - m_ColorSpace = surfaceFormats[0].colorSpace; - } - else{ - // iterate over the list of available surface format and - // check for the presence of VK_FORMAT_B8G8R8A8_UNORM - bool found_B8G8R8A8_UNORM = false; - for (auto&& surfaceFormat : surfaceFormats){ - if (surfaceFormat.format == VK_FORMAT_B8G8R8A8_UNORM){ - m_ColorFormat = surfaceFormat.format; - m_ColorSpace = surfaceFormat.colorSpace; - found_B8G8R8A8_UNORM = true; - break; - } - } - - // in case VK_FORMAT_B8G8R8A8_UNORM is not available - // select the first available color format - if (!found_B8G8R8A8_UNORM){ - m_ColorFormat = surfaceFormats[0].format; - m_ColorSpace = surfaceFormats[0].colorSpace; - } - } - } - - uint32_t VulkanSwapchain::AcquireNextImage(){ - //! @note We iterate per-frame while modulizing with the amount of frames per-flight - m_CurrentFrameIdx = (m_CurrentFrameIdx++) % Renderer::GetSettings().FramesInFlight; - auto device = VulkanDevice::GetLogicalDevice().GetVkDeviceInstance(); - uint32_t image_idx; - auto res = vkAcquireNextImageKHR(device, m_CurrentSwapchain, UINT32_MAX, m_ImageAvailableSemaphores[m_CurrentFrameIdx], (VkFence)nullptr, &image_idx); - - if (res != VK_SUCCESS){ - if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR){ - // OnResize(m_Width, m_Height); - vkAcquireNextImageKHR(device, m_CurrentSwapchain, UINT64_MAX, m_ImageAvailableSemaphores[m_CurrentFrameIdx], (VkFence)nullptr, &image_idx); - } - } - return image_idx; - } - - void VulkanSwapchain::Presentation(){ - auto device =VulkanDevice::GetLogicalDevice().GetVkDeviceInstance(); - - const uint64_t default_fence_timeout = 100000000000; - VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - - VkSubmitInfo submitInfo = {}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.pWaitDstStageMask = &waitStageMask; - submitInfo.pWaitSemaphores = &m_ImageAvailableSemaphores[m_CurrentFrameIdx]; - submitInfo.waitSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &m_ImagesFinishedRenderingSemaphores[m_CurrentFrameIdx]; - submitInfo.signalSemaphoreCount = 1; - submitInfo.pCommandBuffers = &m_CommandBuffers[m_CurrentFrameIdx].CommndBufferData; - submitInfo.commandBufferCount = 1; - - vkResetFences(device, 1, &m_Fences[m_CurrentFrameIdx]); - - // m_Device->LockQueue(); - - if(m_DoLockForCompute){ - m_ComputeMutex.lock(); - } - else{ - m_GraphicsMutex.lock(); - } - vkQueueSubmit(VulkanDevice::GetLogicalDevice().GetVkGraphicsQueue(), 1, &submitInfo, m_Fences[m_CurrentFrameIdx]); - // if(m_DoLockForCompute){ - // m_ComputeMutex.unlock(); - // } - // else{ - // m_GraphicsMutex.unlock(); - // } - } -}; diff --git a/src/engine3d/Core/internal/VulkanCpp/VulkanWindow.cpp b/src/engine3d/Core/internal/VulkanCpp/VulkanWindow.cpp deleted file mode 100644 index 572646d..0000000 --- a/src/engine3d/Core/internal/VulkanCpp/VulkanWindow.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include -#include - -#if _WIN32 -#define VK_USE_PLATFORM_WIN32_KHR -#define GLFW_INCLUDE_VULKAN -#include -#define GLFW_EXPOSE_NATIVE_WIN32 -#include -#include -#else -#include -#include -#endif - -namespace engine3d::vk{ - VulkanWindow::VulkanWindow(uint32_t p_Width, uint32_t p_Height, const std::string& p_Title) : m_Width(p_Width), m_Height(p_Height), m_Title(p_Title) { - if(!glfwInit()){ - throw std::runtime_error("glfwInit() failed to initialize!"); - } - - if(!glfwVulkanSupported()){ - throw std::runtime_error("glfwVulkanSupported() failed because vulkan might not be supported"); - } - - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - - m_Window = glfwCreateWindow(p_Width, p_Height, p_Title.c_str(), nullptr, nullptr); - glfwMakeContextCurrent(m_Window); - - VkResult res = glfwCreateWindowSurface(Vulkan::GetVkInstance(), m_Window, nullptr, &m_Surface); - if(res != VK_SUCCESS){ - throw std::runtime_error("glfwCreateWindowSurface() failed error number: =====> " + std::to_string(res)); - } - m_IsCurrentWindowActive = true; - } - - void VulkanWindow::Presentation(){ - // m_CurrentWindowSwapchain->Presentation(); - } - - bool VulkanWindow::CurrentWindowActive() const { return !glfwWindowShouldClose(m_Window); } - - VkSurfaceKHR& VulkanWindow::VkSurface() { return m_Surface; } - GLFWwindow* VulkanWindow::NativeWindow() { return m_Window; } - - uint32_t VulkanWindow::Width() const{ return m_Width; } - - uint32_t VulkanWindow::Height() const{ return m_Height; } - - std::string VulkanWindow::Title() const{ return m_Title; } -}; diff --git a/src/engine3d/Core/platforms/win32.cpp b/src/engine3d/Core/platforms/win32.cpp index 5cbef26..914edf5 100644 --- a/src/engine3d/Core/platforms/win32.cpp +++ b/src/engine3d/Core/platforms/win32.cpp @@ -1,6 +1,7 @@ +#include "TimeManagement/GlobalUpdateManager.hpp" #include -#include -#include +// #include +// #include #include @@ -8,8 +9,17 @@ extern engine3d::ApplicationInstance* engine3d::InitializeApplication(); int Main(int argc, char** argv){ engine3d::ConsoleEngineLogger::InitializeConsoleLogger("engine3d"); - engine3d::vk::Vulkan::InitializeVulkanCore(); - engine3d::vk::VulkanDevice::InitializeVulkanDevice(); + //! @note DONT FORGET, GlobalUpdateManager should not be instantiated here. + //! @note By doing this it would be reliant when windows initialized/ + //! @note WILL BE MOVED TO InitializeCore()!!!! + // engine3d::GlobalUpdateManager* s_GlobalUpdateManager = engine3d::GlobalUpdateManager::GetInstance(); + + // engine3d::vk::Vulkan::InitializeVulkanCore(); + // engine3d::vk::VulkanDevice::InitializeVulkanDevice(); + + //! @note For now, GlobalUpdateManager will be initialized in InitializeApplication. + //! @note In the future we add GlobalUpdateManager into InitializeCore() so that + //! @note its initializations not bound to if we were to have multiple applications engine3d::InitializeCore(); engine3d::ApplicationInstance* app = engine3d::InitializeApplication(); app->ExecuteApplicationMainloop(); diff --git a/src/engine3d/Math/Interpolation.cpp b/src/engine3d/Math/Interpolation.cpp new file mode 100644 index 0000000..f0b193c --- /dev/null +++ b/src/engine3d/Math/Interpolation.cpp @@ -0,0 +1,2 @@ +#include + diff --git a/src/engine3d/Physics/JoltHandler.cpp b/src/engine3d/Physics/JoltHandler.cpp new file mode 100644 index 0000000..70c82ae --- /dev/null +++ b/src/engine3d/Physics/JoltHandler.cpp @@ -0,0 +1,129 @@ +#include +// Other includes + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +//! @note All includes under here except JoltHandler + + +using namespace engine3d; +using namespace JPH::literals; +using namespace JPH; + +namespace engine3d +{ + + static void TraceImpl(const char *inFMT, ...) + { + // Format the message + va_list list; + va_start(list, inFMT); + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), inFMT, list); + va_end(list); + + // Print to the TTY + std::print("{0}\n",buffer); + } + + JoltHandler::JoltHandler() + { + // Set up the allocator + JPH::RegisterDefaultAllocator(); + std::print("Wokring1\n"); + //Trace and assert callbacks + JPH::Trace = TraceImpl; + JPH_IF_ENABLE_ASSERTS(AssertFailed = AssertFailedImpl;) + std::print("Wokring2\n"); + // Create the factory + JPH::Factory::sInstance = new JPH::Factory(); + std::print("Wokring2.5\n"); + + assert(JPH::Factory::sInstance != nullptr && "Factory instance must be initialized"); + // Set up all types and shapes + //! @note If we want to create our own shapes + //! @note we have to register to collision dispatch first + JPH::RegisterTypes(); + std::print("Wokring3\n"); + + // Example threadpool, branches will take care of this later. + job_system = new JPH::JobSystemThreadPool( + JPH::cMaxPhysicsJobs, + JPH::cMaxPhysicsBarriers, + std::thread::hardware_concurrency() - 1); + + // Single malloc allocation + physics_allocator = new TempAllocatorImpl(100*1024*1024); + + // Max RB to exsist at once + const uint32_t cMaxBodies = 60000; + + // Mutexes per body (default 0?) + const uint32_t cNumBodyMutexes = 0; + + // Size of queue of pair checking + const uint32_t cMaxBodyPairs = 60000; + + // Max number of touches per object + const uint32_t cMaxContactConstraints = 16000; + + std::print("Wokring4\n"); + // Actual physics system + physics_system.Init( + cMaxBodies, + cNumBodyMutexes, + cMaxBodyPairs, + cMaxContactConstraints, + broad_phase_layer_interface, + object_vs_broadphase_layer_filter, + object_vs_object_layer_filter); + + physics_system.SetContactListener(&contact_listener); + + physics_system.SetBodyActivationListener(&body_activation_listener); + + body_interface = &(physics_system.GetBodyInterface()); + + m_BoxShape = new BoxShape(Vec3(1.0f, 1.0f, 1.0f)); + m_SphereShape = new SphereShape(1.0f); + + m_BoxShapeScaled = new ScaledShape(m_BoxShape, RVec3(1,1,1)); + m_SphereShapeScaled = new ScaledShape(m_SphereShape,RVec3(1,1,1)); + + } + + BodyInterface* JoltHandler::getInterface() + { + return body_interface; + } + + JoltHandler::~JoltHandler() + { + JPH::UnregisterTypes(); + std::print("Deleting Physics Factory...\n"); + delete m_SphereShapeScaled; + delete m_BoxShapeScaled; + delete m_BoxShape; + delete m_SphereShape; + delete JPH::Factory::sInstance; + JPH::Factory::sInstance = nullptr; + } + + +}; \ No newline at end of file