diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index f136689..91f60e2 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -3,43 +3,19 @@ { "name": "Win32", "includePath": [ - "${workspaceFolder}/src/**", - "${workspaceFolder}/src/Engine" + "${workspaceFolder}/src/**" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE" ], + "windowsSdkVersion": "10.0.20348.0", + "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.32.31326/bin/Hostx64/x64/cl.exe", + "cStandard": "c17", + "cppStandard": "c++17", "intelliSenseMode": "windows-msvc-x64", - "configurationProvider": "ms-vscode.cmake-tools", - "cppStandard": "c++20", - "browse": { - "limitSymbolsToIncludedHeaders": true, - "path": [ - "${workspaceFolder}/src/**" - ] - }, - "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe" - }, - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/src/**", - "${workspaceFolder}/external/**" - ], - "defines": [ - "_DEBUG", - "UNICODE", - "_UNICODE" - ], - "configurationProvider": "ms-vscode.cmake-tools", - "cppStandard": "c++20", - "browse": { - "path": [ - "${workspaceFolder}/src/**" - ] - } + "configurationProvider": "ms-vscode.cmake-tools" } ], "version": 4 diff --git a/.vscode/launch.json b/.vscode/launch.json index 7de2dc8..c784074 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,32 +5,7 @@ "version": "0.2.0", "configurations": [ { - "name": "Engine Debug (Linux)", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceRoot}/bin/Debug/Engine", - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceRoot}/bin/Debug", - "console": "integratedTerminal", - "visualizerFile": "${workspaceRoot}/Seele.natvis", - "environment": [], - "externalConsole": false, - "setupCommands": [ - { - "description": "Enable break on all exceptions", - "text": "catch throw", - "ignoreFailures": true - }, - { - "description": "Connect to valgrind", - "text": "${command:valgrind-task-integration.valgrindGdbArg}", - "ignoreFailures": true - } - ] - }, - { - "name": "Editor Debug", + "name": "Editor", "type": "cppvsdbg", "request": "launch", "program": "${workspaceRoot}/bin/Debug/Editor.exe", @@ -49,61 +24,5 @@ "traceResponse": true } }, - { - "name": "Editor Release", - "type": "cppvsdbg", - "request": "launch", - "program": "${workspaceRoot}/bin/Release/Editor.exe", - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceRoot}/bin/Release", - "console": "integratedTerminal", - "environment": [], - "symbolSearchPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.25.28610\\lib\\x64", - "requireExactSource": false, - "visualizerFile": "${workspaceRoot}/Seele.natvis", - "logging": { - "moduleLoad": false, - "exceptions": true, - "trace": true, - "traceResponse": true - } - }, - { - "name": "Test (Linux)", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceRoot}/bin/Debug/Seele_unit_tests", - "args": [], - "stopAtEntry": false, - "console": "integratedTerminal", - "cwd": "${workspaceRoot}/bin/Debug", - "environment": [], - "visualizerFile": "${workspaceRoot}/Seele.natvis", - "setupCommands": [ - { - "description": "Enable break on all exceptions", - "text": "catch throw", - "ignoreFailures": true - }, - { - "description": "Connect to valgrind", - "text": "${command:valgrind-task-integration.valgrindGdbArg}", - "ignoreFailures": true - } - ] - }, - { - "name": "Test", - "type": "cppvsdbg", - "request": "launch", - "program": "${workspaceRoot}/bin/Debug/Seele_unit_tests.exe", - "args": ["--detect_memory_leaks"], - "stopAtEntry": false, - "console": "integratedTerminal", - "cwd": "${workspaceRoot}/bin/Debug", - "visualizerFile": "${workspaceRoot}/Seele.natvis", - "environment": [], - }, ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 044b7e0..3055e5a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -135,5 +135,12 @@ }, "git.ignoreSubmodules": true, "cmake.configureOnOpen": true, - "cmake.parallelJobs": 0 + "cmake.parallelJobs": 0, + "C_Cpp.files.exclude": { + "**/.vs": true, + "**/.vscode": true, + "**/bin": true, + "**/external": true, + "**/res": true, + }, } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 47663a9..c9902a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,7 @@ if(CMAKE_DEBUG_POSTFIX) endif() add_library(Engine STATIC "") + target_compile_definitions(Engine PRIVATE GLFW_WINDOWS) target_include_directories(Engine PRIVATE src/Engine) target_link_libraries(Engine PUBLIC Vulkan::Vulkan) @@ -78,11 +79,17 @@ target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json) target_link_libraries(Engine PUBLIC dp::thread-pool) target_link_libraries(Engine PUBLIC crcpp) target_link_libraries(Engine PUBLIC odeint) +target_link_libraries(Engine PUBLIC zlib) if(UNIX) - target_link_libraries(Engine PUBLIC Threads::Threads) - target_link_libraries(Engine PUBLIC dl) +target_link_libraries(Engine PUBLIC Threads::Threads) +target_link_libraries(Engine PUBLIC dl) endif() +add_executable(Editor "") +target_link_libraries(Editor PRIVATE Engine) +target_include_directories(Editor PRIVATE src/Editor) +target_compile_definitions(Editor PRIVATE EDITOR) + target_precompile_headers(Engine PUBLIC @@ -103,8 +110,7 @@ if(MSVC) set(_CRT_SECURE_NO_WARNINGS) target_compile_options(Engine PUBLIC /Zi /MP14 /W4 /DEBUG "/WX-") target_sources(Engine INTERFACE - $ - $ + $ $ ) install(FILES @@ -125,7 +131,8 @@ add_custom_target(SeeleEngine ALL DEPENDS Editor slang-build) install( - TARGETS + TARGETS + Editor Engine EnTT glfw diff --git a/CMakeSettings.json b/CMakeSettings.json index 78e54b1..72b0bcc 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -1,11 +1,25 @@ { - "configurations": [ - { - "name": "Debug", - "cmakeCommandArgs": "-DUSE_SUPERBUILD=OFF", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "inheritEnvironments": [] - } - ] + "configurations": [ + { + "name": "Debug", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "configurationType": "Debug", + "generator": "Visual Studio 17 2022 Win64", + "intelliSenseMode": "windows-msvc-x64", + "cmakeExecutable": "D:/Programms/CMake/bin/cmake.exe", + "inheritEnvironments": [], + "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=d -DCMAKE_PLATFORM=x64 -DCMAKE_BUILD_TYPE=Debug", + "buildRoot": "bin/Debug" + }, + { + "name": "Release", + "configurationType": "Release", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "generator": "Visual Studio 17 2022 Win64", + "intelliSenseMode": "windows-msvc-x64", + "inheritEnvironments": [] + } + ] } \ No newline at end of file diff --git a/OPTIMIZATIONS.md b/OPTIMIZATIONS.md new file mode 100644 index 0000000..3668c56 --- /dev/null +++ b/OPTIMIZATIONS.md @@ -0,0 +1,52 @@ +# Build Options + +- Compiler optimizations: /O3 +- Link Time Optimization: /LTO +- Fast-Math(dangerous) +- Unity Builds +- Profile Guided optimizations +- Static Linking?? +- LLVM Bolt + +# C++ Options + +## Annotations +constexpr +constinit +consteval(C++23) +const +static global variables/functions + +## Attributes +\[\[noreturn]] => saves calls +\[\[likely]] => reorders branches +\[\[assume(condition)]] => UB if condition is false +__restrict => disallowes aliasing +\[\[gnu::pure]] => pure math functions, not supported in MSVC + +## Avoid copies +using std::optional instead of nullable pointer +use smart pointers +if stealing, use rvalue ref +if need copy, use plain type +if modified, use lvalue ref +if cheap to copy, use plain type +if only reading, use const lvalue ref +if using a range and continous, use std::span +if can be arbitrary range, use std::ranges::*** +if it needs to be a specific container, use the container +otherwise take iterator base +use std::string_view(readonly) +for invocables, try: + - std::invocable<\Args...> auto&& x + - return_t(*x)(Args...) + - std::move_only_function&&<\return_t(Args...)> x + - std::function<\return_t(Args...)> x + +## Avoid allocation +dont allocate in loops +dont catch exceptions by value(use const lvalue ref) +use const lvalue refs also in range for loops, lambda captures and structured bindings +provide rvalue accessors T&& value() &&, C++23 provides this auto&& self + +# Manual Hardware Optimizations diff --git a/external/slang b/external/slang index cedd936..1f4c7ca 160000 --- a/external/slang +++ b/external/slang @@ -1 +1 @@ -Subproject commit cedd93690c63188cf98e452c9d104cf51aad6c4e +Subproject commit 1f4c7cab13341c2e9d48df2b01ed2c048c17c152 diff --git a/res/cmake/main.cpp.in b/res/cmake/main.cpp.in new file mode 100644 index 0000000..f4d6a54 --- /dev/null +++ b/res/cmake/main.cpp.in @@ -0,0 +1,28 @@ +#include "Window/WindowManager.h" +#include "Asset/AssetRegistry.h" + +int main() +{ + PWindowManager windowManager = new WindowManager(); + AssetRegistry::load("registry"); + WindowCreateInfo gameWindowInfo = { + .title = ${GAME_TITLE}, + .width = 1280, + .height = 720, + .bFullscreen = false, + .numSamples = 1, + .pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM, + }; + auto window = windowManager->addWindow(gameWindowInfo); + ViewportCreateInfo gameViewinfo = { + .dimensions = { + .size = { + .x = 1280, + .y = 720, + }, + }, + }; + new GameView(windowManager->getGraphics(), window, gameViewInfo); + window->render(); + return 0; +} \ No newline at end of file diff --git a/res/shaders/Skybox.slang b/res/shaders/Skybox.slang new file mode 100644 index 0000000..bbfe83e --- /dev/null +++ b/res/shaders/Skybox.slang @@ -0,0 +1,52 @@ +import Common; + +struct VertexShaderInput +{ + float3 position; +}; + +struct VertexShaderOutput +{ + float4 clipPos : SV_Position; + float3 texCoords; +}; + +[[vk::push_constant]] +ConstantBuffer transformMatrix; + +[shader("vertex")] +VertexStageOutput vertexMain( + VertexShaderInput input) +{ + VertexStageOutput output; + vec4 worldPos = 512 * vec4(input.position, 1.0f); + clip(dot(worldPos, clipPlane)); + output.clipPos = gViewParams.projectionMatrix * gViewParams.viewMatrix * worldPos; + output.texCoords = position; + return output; +} + +[[vk::push_constant]] +ConstantBuffer fogColor; + +[[vk::push_constant]] +ConstantBuffer blendFactor; + +Texture3D cubeMap; +Texture3D cubeMap2; +SamplerState sampler; + +const float lowerLimit = 0.0; +const float upperLimit = 0.1; + +float4 fragMain( + VertexShaderOutput output) +{ + float4 texture1 = cubeMap.Sample(sampler, output.texCoords); + float4 texture2 = cubeMap2.Sample(sampler, output.texCoords); + float4 finalColor = mix(texture1, texture2, blendFactor); + + float factor = (input.texCoords.y - lowerLimit) / (upperLimit - lowerLimit); + factor = clamp(factor, 0.0, 1.0); + return = mix(vec4(fogColor, 1), finalColor, factor); +} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6c815da..85b3389 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1 +1,2 @@ +add_subdirectory(Editor/) add_subdirectory(Engine/) \ No newline at end of file diff --git a/src/Editor/CMakeLists.txt b/src/Editor/CMakeLists.txt index 19b1540..7f5de55 100644 --- a/src/Editor/CMakeLists.txt +++ b/src/Editor/CMakeLists.txt @@ -1,4 +1,4 @@ -add_subdirectory(System/) +add_subdirectory(Platform/) add_subdirectory(Window/) target_sources(Editor diff --git a/src/Editor/Component/CMakeLists.txt b/src/Editor/Component/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/Editor/Platform/CMakeLists.txt b/src/Editor/Platform/CMakeLists.txt new file mode 100644 index 0000000..196f640 --- /dev/null +++ b/src/Editor/Platform/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(Windows/) \ No newline at end of file diff --git a/src/Editor/Platform/Windows/CMakeLists.txt b/src/Editor/Platform/Windows/CMakeLists.txt new file mode 100644 index 0000000..0698097 --- /dev/null +++ b/src/Editor/Platform/Windows/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(Editor + PRIVATE + GameInterface.h + GameInterface.cpp) \ No newline at end of file diff --git a/src/Editor/Platform/Windows/GameInterface.cpp b/src/Editor/Platform/Windows/GameInterface.cpp new file mode 100644 index 0000000..616b6dd --- /dev/null +++ b/src/Editor/Platform/Windows/GameInterface.cpp @@ -0,0 +1,28 @@ +#include "GameInterface.h" + +using namespace Seele; + +GameInterface::GameInterface(std::string dllPath) + : dllPath(dllPath) +{ + reloadGame(); +} + +GameInterface::~GameInterface() +{ + +} + +Game* GameInterface::reloadGame() +{ + if(lib != NULL) + { + destroyInstance(game); + FreeLibrary(lib); + } + lib = LoadLibraryA(dllPath.c_str()); + createInstance = (decltype(createInstance))GetProcAddress(lib, "createInstance"); + destroyInstance = (decltype(destroyInstance))GetProcAddress(lib, "destroyInstance"); + game = createInstance(); + return game; +} \ No newline at end of file diff --git a/src/Editor/Platform/Windows/GameInterface.h b/src/Editor/Platform/Windows/GameInterface.h new file mode 100644 index 0000000..f817d8b --- /dev/null +++ b/src/Editor/Platform/Windows/GameInterface.h @@ -0,0 +1,20 @@ +#pragma once +#include "Game.h" +#include "Windows.h" + +namespace Seele +{ +class GameInterface +{ +public: + GameInterface(std::string dllPath); + ~GameInterface(); + Game* reloadGame(); +private: + HMODULE lib = NULL; + std::string dllPath; + Game* game; + Game* (*createInstance)() = nullptr; + void (*destroyInstance)(Game*) = nullptr; +}; +} // namespace Seele \ No newline at end of file diff --git a/src/Editor/System/CMakeLists.txt b/src/Editor/System/CMakeLists.txt deleted file mode 100644 index 7e54b38..0000000 --- a/src/Editor/System/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -target_sources(Editor - PRIVATE) \ No newline at end of file diff --git a/src/Editor/Window/CMakeLists.txt b/src/Editor/Window/CMakeLists.txt index 5e99fb0..279cf0e 100644 --- a/src/Editor/Window/CMakeLists.txt +++ b/src/Editor/Window/CMakeLists.txt @@ -1,5 +1,7 @@ target_sources(Editor PRIVATE + GameView.h + GameView.cpp InspectorView.h InspectorView.cpp SceneView.h diff --git a/src/Editor/Window/GameView.cpp b/src/Editor/Window/GameView.cpp new file mode 100644 index 0000000..0ebbf84 --- /dev/null +++ b/src/Editor/Window/GameView.cpp @@ -0,0 +1,146 @@ +#include "GameView.h" +#include "Graphics/Graphics.h" +#include "Window/Window.h" +#include "Component/KeyboardInput.h" +#include "Actor/CameraActor.h" + +using namespace Seele; + +GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo) + : View(graphics, window, createInfo, "Game") + , gameInterface("C:\\Users\\Dynamitos\\TrackClear\\bin\\TrackCleard.dll") + , renderGraph(RenderGraphBuilder::build( + DepthPrepass(graphics), + LightCullingPass(graphics), + BasePass(graphics), +#ifdef EDITOR + DebugPass(graphics), +#endif + SkyboxRenderPass(graphics) + )) +{ + scene = new Scene(graphics); + systemGraph = new SystemGraph(); + gameInterface.reloadGame()->setupScene(scene, systemGraph); + renderGraph.updateViewport(viewport); +} + +GameView::~GameView() +{ + +} + +void GameView::beginUpdate() +{ +} + +void GameView::update() +{ + static auto startTime = std::chrono::high_resolution_clock::now(); + systemGraph->run(threadPool, updateTime); + scene->update(updateTime); + auto endTime = std::chrono::high_resolution_clock::now(); + std::chrono::duration duration = (endTime - startTime); + updateTime = duration.count(); + startTime = endTime; +} + +void GameView::commitUpdate() +{ + depthPrepassData.staticDrawList = scene->getStaticMeshes(); + depthPrepassData.sceneDataBuffer = scene->getSceneDataBuffer(); + lightCullingData.lightEnv = scene->getLightBuffer(); + basePassData.staticDrawList = scene->getStaticMeshes(); + basePassData.sceneDataBuffer = scene->getSceneDataBuffer(); +#ifdef EDITOR + if(showDebug) + { + debugPassData.vertices = Seele::gDebugVertices; + } +#endif + Seele::gDebugVertices.clear(); +} + +void GameView::prepareRender() +{ +#ifdef EDITOR + renderGraph.updatePassData(depthPrepassData, lightCullingData, basePassData, debugPassData, skyboxData); +#else + renderGraph.updatePassData(depthPrepassData, lightCullingData, basePassData, skyboxData); +#endif +} + +void GameView::render() +{ + scene->view([&](Component::Camera& cam) + { + if(cam.mainCamera) + { + renderGraph.render(cam); + } + }); +} + +void GameView::keyCallback(KeyCode code, InputAction action, KeyModifier) +{ + scene->view([=](Component::KeyboardInput& input) + { + //if(code == KeyCode::KEY_R && action == InputAction::PRESS) + //{ + // auto cubeMesh = AssetRegistry::findMesh("cube"); + // PEntity cube2 = new Entity(scene); + // Component::Transform& cube2Transform = cube2->attachComponent(); + // cube2Transform.setPosition(Vector(0, 20, 0)); + // cube2Transform.setRotation(Quaternion(Vector(0.f, 90.f, 90.f))); + // cube2Transform.setScale(Vector(2.f, 2.f, 2.f)); + // cubeMesh->physicsMesh.type = Component::ColliderType::DYNAMIC; + // cube2->attachComponent(cubeMesh->physicsMesh); + // cube2->attachComponent(cubeMesh); + // Component::RigidBody& physics2 = cube2->attachComponent(); + // physics2.linearMomentum = Vector(0, -10, 0); + // physics2.angularMomentum = Vector(0, 0, 0); + //} + // + //if(code == KeyCode::KEY_B && action == InputAction::PRESS) + //{ + // showDebug = !showDebug; + // debugPassData.vertices.clear(); + //} + + input.keys[code] = action != InputAction::RELEASE; + }); +} + +void GameView::mouseMoveCallback(double xPos, double yPos) +{ + scene->view([=](Component::KeyboardInput& input) + { + input.mouseX = static_cast(xPos); + input.mouseY = static_cast(yPos); + }); +} + +void GameView::mouseButtonCallback(MouseButton button, InputAction action, KeyModifier) +{ + scene->view([=](Component::KeyboardInput& input) + { + if (button == MouseButton::MOUSE_BUTTON_1) + { + input.mouse1 = action != InputAction::RELEASE; + } + if (button == MouseButton::MOUSE_BUTTON_2) + { + input.mouse2 = action != InputAction::RELEASE; + } + }); +} + +void GameView::scrollCallback(double, double) +{ + +} + +void GameView::fileCallback(int, const char**) +{ + +} diff --git a/src/Editor/Window/GameView.h b/src/Editor/Window/GameView.h new file mode 100644 index 0000000..4ef6280 --- /dev/null +++ b/src/Editor/Window/GameView.h @@ -0,0 +1,59 @@ +#pragma once +#include "Window/View.h" +#include "Scene/Scene.h" +#include "Graphics/RenderPass/DepthPrepass.h" +#include "Graphics/RenderPass/LightCullingPass.h" +#include "Graphics/RenderPass/BasePass.h" +#include "Graphics/RenderPass/DebugPass.h" +#include "Graphics/RenderPass/SkyboxRenderPass.h" +#include "Platform/Windows/GameInterface.h" // TODO + +namespace Seele +{ +class GameView : public View +{ +public: + GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo); + virtual ~GameView(); + virtual void beginUpdate() override; + virtual void update() override; + virtual void commitUpdate() override; + + virtual void prepareRender() override; + virtual void render() override; +private: + GameInterface gameInterface; + RenderGraph< + DepthPrepass, + LightCullingPass, + BasePass, +#ifdef EDITOR + DebugPass, +#endif + SkyboxRenderPass + > renderGraph; + + DepthPrepassData depthPrepassData; + LightCullingPassData lightCullingData; + BasePassData basePassData; + SkyboxPassData skyboxData; +#ifdef EDITOR + DebugPassData debugPassData; +#endif + + PScene scene; + PSystemGraph systemGraph; + dp::thread_pool<> threadPool; + float updateTime = 0; +#ifdef EDITOR + bool showDebug = true; +#endif + + virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override; + virtual void mouseMoveCallback(double xPos, double yPos) override; + virtual void mouseButtonCallback(Seele::MouseButton button, Seele::InputAction action, Seele::KeyModifier modifier) override; + virtual void scrollCallback(double xOffset, double yOffset) override; + virtual void fileCallback(int count, const char** paths) override; +}; +DEFINE_REF(GameView) +} // namespace Seele diff --git a/src/Editor/Window/SceneView.cpp b/src/Editor/Window/SceneView.cpp index 317d879..ed7c86d 100644 --- a/src/Editor/Window/SceneView.cpp +++ b/src/Editor/Window/SceneView.cpp @@ -22,19 +22,6 @@ SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreat )) , cameraSystem(createInfo.dimensions, Vector(0, 0, 10)) { - AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png"); - AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png"); - AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png"); - AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Hair_Diffuse.png"); - AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Hair_Lightmap.png"); - AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Tex_FaceLightmap.png"); - AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Ayaka.fbx"); - auto meshAsset = AssetRegistry::findMesh("Ayaka"); - for(auto mesh : meshAsset->getMeshes()) - { - PActor actor = new Actor(scene); - actor->attachComponent(mesh->vertexInput, mesh->indexBuffer, mesh->referencedMaterial); - } //AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Ely\\Ely.fbx"); //AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Cube\\cube.obj"); @@ -51,14 +38,12 @@ SceneView::~SceneView() void SceneView::beginUpdate() { - scene->beginUpdate(Gfx::currentFrameDelta); //co_return; } void SceneView::update() { cameraSystem.update(viewportCamera, static_cast(Gfx::currentFrameDelta)); - scene->commitUpdate(); //co_return; } diff --git a/src/Editor/Window/ViewportControl.cpp b/src/Editor/Window/ViewportControl.cpp index 0124544..117e63c 100644 --- a/src/Editor/Window/ViewportControl.cpp +++ b/src/Editor/Window/ViewportControl.cpp @@ -69,7 +69,6 @@ void ViewportControl::update(Component::Camera& camera, float deltaTime) sin(pitch), sin(yaw) * cos(pitch))); camera.viewMatrix = glm::lookAt(position, position + springArm, Vector(0, 1, 0)); - camera.projectionMatrix = glm::perspective(fieldOfView, aspectRatio, 0.1f, 1000.0f); std::cout << yaw << " " << pitch << std::endl; } diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index f9fcfd5..7925848 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -1,15 +1,20 @@ #include "Window/WindowManager.h" #include "Window/SceneView.h" +#include "Window/GameView.h" #include "Window/InspectorView.h" #include "Asset/AssetRegistry.h" +#include "Graphics/Vulkan/VulkanGraphics.h" using namespace Seele; using namespace Seele::Editor; int main() { + Gfx::PGraphics graphics = new Vulkan::Graphics(); + GraphicsInitializer initializer; + graphics->init(initializer); PWindowManager windowManager = new WindowManager(); - AssetRegistry::init("C:\\Users\\Dynamitos\\TestSeeleProject"); + AssetRegistry::init(std::string("C:\\Users\\Dynamitos\\TrackClear"), graphics); WindowCreateInfo mainWindowInfo; mainWindowInfo.title = "SeeleEngine"; mainWindowInfo.width = 1280; @@ -17,24 +22,26 @@ int main() mainWindowInfo.bFullscreen = false; mainWindowInfo.numSamples = 1; mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM; - auto window = windowManager->addWindow(mainWindowInfo); + auto window = windowManager->addWindow(graphics, mainWindowInfo); ViewportCreateInfo sceneViewInfo; sceneViewInfo.dimensions.size.x = 1280; sceneViewInfo.dimensions.size.y = 720; sceneViewInfo.dimensions.offset.x = 0; sceneViewInfo.dimensions.offset.y = 0; - PSceneView sceneView = new SceneView(windowManager->getGraphics(), window, sceneViewInfo); - window->addView(sceneView); + PGameView sceneView = new GameView(graphics, window, sceneViewInfo); ViewportCreateInfo inspectorViewInfo; inspectorViewInfo.dimensions.size.x = 640; inspectorViewInfo.dimensions.size.y = 720; inspectorViewInfo.dimensions.offset.x = 640; inspectorViewInfo.dimensions.offset.y = 0; - PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo); + PInspectorView inspectorView = new InspectorView(graphics, window, inspectorViewInfo); //window->addView(inspectorView); sceneView->setFocused(); window->render(); + //export game + std::string outputPath = "C:\\Users\\Dynamitos\\TrackClearGame"; + return 0; } \ No newline at end of file diff --git a/src/Engine/Asset/Asset.h b/src/Engine/Asset/Asset.h index 413f4ea..d2d967d 100644 --- a/src/Engine/Asset/Asset.h +++ b/src/Engine/Asset/Asset.h @@ -3,6 +3,7 @@ namespace Seele { +DECLARE_NAME_REF(Gfx, Graphics) class Asset { public: @@ -17,8 +18,8 @@ public: Asset(const std::filesystem::path& path); virtual ~Asset(); - virtual void save() = 0; - virtual void load() = 0; + virtual void save(Gfx::PGraphics graphics) = 0; + virtual void load(Gfx::PGraphics graphics) = 0; // returns the name of the file, without extension std::string getFileName() const; diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index 86da3c3..969b48c 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -21,9 +21,9 @@ AssetRegistry::~AssetRegistry() { } -void AssetRegistry::init(const std::string& rootFolder) +void AssetRegistry::init(const std::string& rootFolder, Gfx::PGraphics graphics) { - get().init(rootFolder, WindowManager::getGraphics()); + get().initialize(rootFolder, graphics); } void AssetRegistry::importFile(const std::string &filePath) @@ -133,14 +133,14 @@ AssetRegistry::AssetRegistry() { } -void AssetRegistry::init(const std::filesystem::path &_rootFolder, Gfx::PGraphics graphics) +void AssetRegistry::initialize(const std::filesystem::path &_rootFolder, Gfx::PGraphics _graphics) { - AssetRegistry ® = get(); - reg.rootFolder = _rootFolder; - reg.fontLoader = new FontLoader(graphics); - reg.meshLoader = new MeshLoader(graphics); - reg.textureLoader = new TextureLoader(graphics); - reg.materialLoader = new MaterialLoader(graphics); + this->graphics = _graphics; + this->rootFolder = _rootFolder; + this->fontLoader = new FontLoader(graphics); + this->meshLoader = new MeshLoader(graphics); + this->textureLoader = new TextureLoader(graphics); + this->materialLoader = new MaterialLoader(graphics); } std::string AssetRegistry::getRootFolder() diff --git a/src/Engine/Asset/AssetRegistry.h b/src/Engine/Asset/AssetRegistry.h index 7055a10..e52d756 100644 --- a/src/Engine/Asset/AssetRegistry.h +++ b/src/Engine/Asset/AssetRegistry.h @@ -19,7 +19,7 @@ class AssetRegistry { public: ~AssetRegistry(); - static void init(const std::string& rootFolder); + static void init(const std::string& rootFolder, Gfx::PGraphics graphics); static std::string getRootFolder(); @@ -47,7 +47,7 @@ private: static AssetRegistry& get(); AssetRegistry(); - void init(const std::filesystem::path& rootFolder, Gfx::PGraphics graphics); + void initialize(const std::filesystem::path& rootFolder, Gfx::PGraphics graphics); void importMesh(const std::filesystem::path& filePath, const std::string& importPath); void importTexture(const std::filesystem::path& filePath, const std::string& importPath); @@ -66,6 +66,7 @@ private: std::filesystem::path rootFolder; AssetFolder assetRoot; + Gfx::PGraphics graphics; UPTextureLoader textureLoader; UPFontLoader fontLoader; UPMeshLoader meshLoader; diff --git a/src/Engine/Asset/FontAsset.cpp b/src/Engine/Asset/FontAsset.cpp index a17bdb2..b3fcde0 100644 --- a/src/Engine/Asset/FontAsset.cpp +++ b/src/Engine/Asset/FontAsset.cpp @@ -1,8 +1,5 @@ #include "FontAsset.h" -#include "Graphics/GraphicsResources.h" -#include -#include FT_FREETYPE_H -#include "Window/WindowManager.h" +#include "Graphics/Graphics.h" using namespace Seele; @@ -25,55 +22,12 @@ FontAsset::~FontAsset() } -void FontAsset::save() +void FontAsset::save(Gfx::PGraphics graphics) { assert(false && "Cannot save font files"); } -// in case of the space character there is no bitmap -// so we create a single pixel empty texture -uint8 transparentPixel = 0; -void FontAsset::load() +void FontAsset::load(Gfx::PGraphics graphics) { - FT_Library ft; - FT_Error error = FT_Init_FreeType(&ft); - assert(!error); - FT_Face face; - error = FT_New_Face(ft, getFullPath().c_str(), 0, &face); - assert(!error); - FT_Set_Pixel_Sizes(face, 0, 48); - for(uint32 c = 0; c < 256; ++c) - { - Gfx::PGraphics graphics = WindowManager::getGraphics(); - if(FT_Load_Char(face, c, FT_LOAD_RENDER)) - { - std::cout << "error loading " << (char)c << std::endl; - continue; - } - Glyph& glyph = glyphs[c]; - glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows); - glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top); - glyph.advance = face->glyph->advance.x; - TextureCreateInfo imageData; - imageData.format = Gfx::SE_FORMAT_R8_UINT; - imageData.width = face->glyph->bitmap.width; - imageData.height = face->glyph->bitmap.rows; - imageData.resourceData.data = face->glyph->bitmap.buffer; - imageData.resourceData.size = imageData.width * imageData.height; - if(imageData.width == 0 || imageData.width == 0) - { - glyph.size.x = 1; - glyph.size.y = 1; - glyph.bearing.x = 0; - glyph.bearing.y = 0; - imageData.width = 1; - imageData.height = 1; - imageData.resourceData.size = sizeof(uint8); - imageData.resourceData.data = &transparentPixel; - } - glyph.texture = graphics->createTexture2D(imageData); - } - FT_Done_Face(face); - FT_Done_FreeType(ft); } \ No newline at end of file diff --git a/src/Engine/Asset/FontAsset.h b/src/Engine/Asset/FontAsset.h index 7a50390..5fd351f 100644 --- a/src/Engine/Asset/FontAsset.h +++ b/src/Engine/Asset/FontAsset.h @@ -11,8 +11,8 @@ public: FontAsset(const std::string& directory, const std::string& name); FontAsset(const std::filesystem::path& fullPath); virtual ~FontAsset(); - virtual void save() override; - virtual void load() override; + virtual void save(Gfx::PGraphics graphics) override; + virtual void load(Gfx::PGraphics graphics) override; struct Glyph { @@ -24,6 +24,7 @@ public: const std::map getGlyphData() const { return glyphs; } private: std::map glyphs; + friend class FontLoader; }; DECLARE_REF(FontAsset) } // namespace Seele diff --git a/src/Engine/Asset/FontLoader.cpp b/src/Engine/Asset/FontLoader.cpp index 14cde23..168e8f8 100644 --- a/src/Engine/Asset/FontLoader.cpp +++ b/src/Engine/Asset/FontLoader.cpp @@ -2,6 +2,9 @@ #include "Graphics/Graphics.h" #include "FontAsset.h" #include "AssetRegistry.h" +#include "Graphics/GraphicsResources.h" +#include +#include FT_FREETYPE_H using namespace Seele; @@ -27,7 +30,49 @@ void FontLoader::importAsset(const std::filesystem::path& filePath, const std::s import(filePath, asset); } +// in case of the space character there is no bitmap +// so we create a single pixel empty texture +uint8 transparentPixel = 0; void FontLoader::import(std::filesystem::path path, PFontAsset asset) { - asset->load(); + FT_Library ft; + FT_Error error = FT_Init_FreeType(&ft); + assert(!error); + FT_Face face; + error = FT_New_Face(ft, asset->getFullPath().c_str(), 0, &face); + assert(!error); + FT_Set_Pixel_Sizes(face, 0, 48); + for(uint32 c = 0; c < 256; ++c) + { + if(FT_Load_Char(face, c, FT_LOAD_RENDER)) + { + std::cout << "error loading " << (char)c << std::endl; + continue; + } + FontAsset::Glyph& glyph = asset->glyphs[c]; + glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows); + glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top); + glyph.advance = face->glyph->advance.x; + TextureCreateInfo imageData; + imageData.format = Gfx::SE_FORMAT_R8_UINT; + imageData.width = face->glyph->bitmap.width; + imageData.height = face->glyph->bitmap.rows; + imageData.resourceData.data = face->glyph->bitmap.buffer; + imageData.resourceData.size = imageData.width * imageData.height; + if(imageData.width == 0 || imageData.width == 0) + { + glyph.size.x = 1; + glyph.size.y = 1; + glyph.bearing.x = 0; + glyph.bearing.y = 0; + imageData.width = 1; + imageData.height = 1; + imageData.resourceData.size = sizeof(uint8); + imageData.resourceData.data = &transparentPixel; + } + glyph.texture = graphics->createTexture2D(imageData); + } + FT_Done_Face(face); + FT_Done_FreeType(ft); + asset->setStatus(Asset::Status::Ready); } \ No newline at end of file diff --git a/src/Engine/Asset/MaterialAsset.cpp b/src/Engine/Asset/MaterialAsset.cpp index 59cb3f5..6dce448 100644 --- a/src/Engine/Asset/MaterialAsset.cpp +++ b/src/Engine/Asset/MaterialAsset.cpp @@ -1,5 +1,6 @@ #include "MaterialAsset.h" #include "Material/Material.h" +#include "Graphics/Graphics.h" using namespace Seele; @@ -22,20 +23,12 @@ MaterialAsset::~MaterialAsset() } -void MaterialAsset::save() +void MaterialAsset::save(Gfx::PGraphics graphics) { } -void MaterialAsset::load() +void MaterialAsset::load(Gfx::PGraphics graphics) { } - -void MaterialAsset::beginFrame() -{ -} - -void MaterialAsset::endFrame() -{ -} diff --git a/src/Engine/Asset/MaterialAsset.h b/src/Engine/Asset/MaterialAsset.h index faf6bf0..7a8e6c8 100644 --- a/src/Engine/Asset/MaterialAsset.h +++ b/src/Engine/Asset/MaterialAsset.h @@ -11,10 +11,8 @@ public: MaterialAsset(const std::string &directory, const std::string &name); MaterialAsset(const std::filesystem::path &fullPath); virtual ~MaterialAsset(); - virtual void beginFrame(); - virtual void endFrame(); - virtual void save() override; - virtual void load() override; + virtual void save(Gfx::PGraphics graphics) override; + virtual void load(Gfx::PGraphics graphics) override; PMaterial getMaterial() const { return material; } private: PMaterial material; diff --git a/src/Engine/Asset/MaterialInstanceAsset.cpp b/src/Engine/Asset/MaterialInstanceAsset.cpp index 38682cf..4c0289d 100644 --- a/src/Engine/Asset/MaterialInstanceAsset.cpp +++ b/src/Engine/Asset/MaterialInstanceAsset.cpp @@ -1,6 +1,7 @@ #include "MaterialInstanceAsset.h" #include "Material/MaterialInstance.h" #include "Material/Material.h" +#include "Graphics/Graphics.h" using namespace Seele; @@ -23,10 +24,10 @@ MaterialInstanceAsset::~MaterialInstanceAsset() } -void MaterialInstanceAsset::save() +void MaterialInstanceAsset::save(Gfx::PGraphics graphics) { } -void MaterialInstanceAsset::load() +void MaterialInstanceAsset::load(Gfx::PGraphics graphics) { } diff --git a/src/Engine/Asset/MaterialInstanceAsset.h b/src/Engine/Asset/MaterialInstanceAsset.h index c5f84ed..89d3479 100644 --- a/src/Engine/Asset/MaterialInstanceAsset.h +++ b/src/Engine/Asset/MaterialInstanceAsset.h @@ -11,10 +11,8 @@ public: MaterialInstanceAsset(const std::string &directory, const std::string &name); MaterialInstanceAsset(const std::filesystem::path &fullPath); virtual ~MaterialInstanceAsset(); - virtual void beginFrame(); - virtual void endFrame(); - virtual void save() override; - virtual void load() override; + virtual void save(Gfx::PGraphics graphics) override; + virtual void load(Gfx::PGraphics graphics) override; private: PMaterialInstance material; }; diff --git a/src/Engine/Asset/MaterialLoader.cpp b/src/Engine/Asset/MaterialLoader.cpp index e679a61..057a5c3 100644 --- a/src/Engine/Asset/MaterialLoader.cpp +++ b/src/Engine/Asset/MaterialLoader.cpp @@ -38,7 +38,7 @@ void MaterialLoader::import(std::filesystem::path name, PMaterialAsset asset) json j; stream >> j; std::string materialName = j["name"].get() + "Material"; - Gfx::PDescriptorLayout layout = WindowManager::getGraphics()->createDescriptorLayout(materialName + "Layout"); + Gfx::PDescriptorLayout layout = graphics->createDescriptorLayout(materialName + "Layout"); //Shader file needs to conform to the slang standard, which prohibits _ materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end()); materialName.erase(std::remove(materialName.begin(), materialName.end(), '.'), materialName.end()); @@ -111,7 +111,7 @@ void MaterialLoader::import(std::filesystem::path name, PMaterialAsset asset) { PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter); layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER); - p->data = WindowManager::getGraphics()->createSamplerState({}); + p->data = graphics->createSamplerState({}); parameters.add(p); } else @@ -128,6 +128,7 @@ void MaterialLoader::import(std::filesystem::path name, PMaterialAsset asset) codeStream.close(); layout->create(); asset->material = new Material( + graphics, std::move(parameters), std::move(layout), uniformDataSize, diff --git a/src/Engine/Asset/MeshAsset.cpp b/src/Engine/Asset/MeshAsset.cpp index 9d84973..3eea15b 100644 --- a/src/Engine/Asset/MeshAsset.cpp +++ b/src/Engine/Asset/MeshAsset.cpp @@ -1,4 +1,5 @@ #include "MeshAsset.h" +#include "Graphics/Graphics.h" #include "Graphics/Mesh.h" #include "Graphics/VertexShaderInput.h" #include "Material/MaterialInterface.h" @@ -21,10 +22,10 @@ MeshAsset::~MeshAsset() { } -void MeshAsset::save() +void MeshAsset::save(Gfx::PGraphics graphics) { } -void MeshAsset::load() +void MeshAsset::load(Gfx::PGraphics graphics) { } diff --git a/src/Engine/Asset/MeshAsset.h b/src/Engine/Asset/MeshAsset.h index 5db9431..75b6ef2 100644 --- a/src/Engine/Asset/MeshAsset.h +++ b/src/Engine/Asset/MeshAsset.h @@ -13,8 +13,8 @@ public: MeshAsset(const std::string& directory, const std::string& name); MeshAsset(const std::filesystem::path& fullPath); virtual ~MeshAsset(); - virtual void save() override; - virtual void load() override; + virtual void save(Gfx::PGraphics graphics) override; + virtual void load(Gfx::PGraphics graphics) override; void addMesh(PMesh mesh); const Array getMeshes(); //Workaround while no editor diff --git a/src/Engine/Asset/MeshLoader.cpp b/src/Engine/Asset/MeshLoader.cpp index 0efd4cd..0721657 100644 --- a/src/Engine/Asset/MeshLoader.cpp +++ b/src/Engine/Asset/MeshLoader.cpp @@ -259,7 +259,7 @@ void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path& unsigned char* texData = new unsigned char[tex->mWidth * tex->mHeight * 4]; convertAssimpARGB(texData, tex->pcData, tex->mWidth * tex->mHeight); stbi_write_png(texPngPath.string().c_str(), tex->mWidth, tex->mHeight, 4, tex->pcData, tex->mWidth * 32); - delete texData; + delete[] texData; } std::cout << "Loading model texture " << texPngPath.string() << std::endl; AssetRegistry::importFile(texPngPath.string()); @@ -300,6 +300,5 @@ void MeshLoader::import(std::filesystem::path path, PMeshAsset meshAsset) } meshAsset->physicsMesh = std::move(collider); meshAsset->setStatus(Asset::Status::Ready); - meshAsset->save(); std::cout << "Finished loading " << path << std::endl; } diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index f881da2..82aa582 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -25,13 +25,13 @@ TextureAsset::~TextureAsset() } -void TextureAsset::save() +void TextureAsset::save(Gfx::PGraphics graphics) { //TODO: make this an actual file, not just a png wrapper assert(false && "Editing textures is not yet supported"); } -void TextureAsset::load() +void TextureAsset::load(Gfx::PGraphics graphics) { setStatus(Status::Loading); ktxTexture2* kTexture; @@ -40,19 +40,32 @@ void TextureAsset::load() ktxTexture2_CreateFromNamedFile(getFullPath().c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &kTexture); + TextureCreateInfo createInfo; createInfo.width = kTexture->baseWidth; createInfo.height = kTexture->baseHeight; createInfo.depth = kTexture->baseDepth; createInfo.bArray = kTexture->isArray; - createInfo.arrayLayers = kTexture->numLayers; + createInfo.arrayLayers = kTexture->isArray ? kTexture->numLayers : kTexture->numFaces; createInfo.format = Vulkan::cast((VkFormat)kTexture->vkFormat); createInfo.mipLevels = kTexture->numLevels; createInfo.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT; createInfo.resourceData.data = ktxTexture_GetData(ktxTexture(kTexture)); createInfo.resourceData.size = ktxTexture_GetDataSize(ktxTexture(kTexture)); createInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; - Gfx::PTexture2D tex = WindowManager::getGraphics()->createTexture2D(createInfo); + Gfx::PTexture tex; + if (kTexture->isCubemap) + { + tex = graphics->createTextureCube(createInfo); + } + else if (kTexture->isArray) + { + tex = graphics->createTexture3D(createInfo); + } + else + { + tex = graphics->createTexture2D(createInfo); + } tex->transferOwnership(Gfx::QueueType::GRAPHICS); setTexture(tex); setStatus(Asset::Status::Ready); diff --git a/src/Engine/Asset/TextureAsset.h b/src/Engine/Asset/TextureAsset.h index 6586a55..de526d3 100644 --- a/src/Engine/Asset/TextureAsset.h +++ b/src/Engine/Asset/TextureAsset.h @@ -11,8 +11,8 @@ public: TextureAsset(const std::string& directory, const std::string& name); TextureAsset(const std::filesystem::path& fullPath); virtual ~TextureAsset(); - virtual void save() override; - virtual void load() override; + virtual void save(Gfx::PGraphics graphics) override; + virtual void load(Gfx::PGraphics graphics) override; void setTexture(Gfx::PTexture _texture) { std::scoped_lock lck(lock); diff --git a/src/Engine/Asset/TextureLoader.cpp b/src/Engine/Asset/TextureLoader.cpp index c51f51d..a78d355 100644 --- a/src/Engine/Asset/TextureLoader.cpp +++ b/src/Engine/Asset/TextureLoader.cpp @@ -15,7 +15,7 @@ TextureLoader::TextureLoader(Gfx::PGraphics graphics) : graphics(graphics) { placeholderAsset = new TextureAsset(std::filesystem::absolute("./textures/placeholder.ktx")); - placeholderAsset->load(); + placeholderAsset->load(graphics); AssetRegistry::get().assetRoot.textures[""] = placeholderAsset; } @@ -41,35 +41,80 @@ PTextureAsset TextureLoader::getPlaceholderTexture() void TextureLoader::import(std::filesystem::path path, PTextureAsset textureAsset) { - int x, y, n; - unsigned char* data = stbi_load(path.string().c_str(), &x, &y, &n, 4); + int totalWidth, totalHeight, n; + unsigned char* data = stbi_load(path.string().c_str(), &totalWidth, &totalHeight, &n, 4); ktxTexture2* kTexture; ktxTextureCreateInfo createInfo; - createInfo.vkFormat = VK_FORMAT_R8G8B8A8_SRGB; - createInfo.baseWidth = x; - createInfo.baseHeight = y; - createInfo.baseDepth = 1; - createInfo.numDimensions = 1 + (y > 1); - createInfo.numLevels = 1; - createInfo.numLayers = 1; - createInfo.numFaces = 1; - createInfo.isArray = false; - createInfo.generateMipmaps = true; + if (totalWidth / 4 == totalHeight / 3) + { + uint32 faceWidth = totalWidth / 4; + uint32 faceHeight = totalHeight / 3; + // Cube map + createInfo.vkFormat = VK_FORMAT_R8G8B8A8_SRGB; + createInfo.baseWidth = totalWidth / 4; + createInfo.baseHeight = totalHeight / 3; + createInfo.baseDepth = 1; + createInfo.numFaces = 6; + createInfo.numDimensions = 3; + createInfo.numLevels = 1; + createInfo.numLayers = 1; + createInfo.isArray = false; + createInfo.generateMipmaps = true; - ktxTexture2_Create(&createInfo, - KTX_TEXTURE_CREATE_ALLOC_STORAGE, - &kTexture); + ktxTexture2_Create(&createInfo, + KTX_TEXTURE_CREATE_ALLOC_STORAGE, + &kTexture); - ktxTexture_SetImageFromMemory(ktxTexture(kTexture), - 0, 0, 0, data, x * y * 4 * sizeof(unsigned char)); + auto loadCubeFace = [kTexture, faceWidth, totalWidth, data](int xPos, int yPos, int faceName) + { + std::vector vec(faceWidth * faceWidth * 4); + for (int y = 0; y < faceWidth; ++y) + { + for (int x = 0; x < faceWidth; ++x) + { + int imgX = x + (xPos * faceWidth); + int imgY = y + (yPos * faceWidth); + std::memcpy(&vec[(x + (faceWidth * y)) * 4], &data[(imgX + (totalWidth * imgY)) * 4], 4); + } + } + ktxTexture_SetImageFromMemory(ktxTexture(kTexture), + 0, 0, faceName, vec.data(), vec.size()); + }; + loadCubeFace(1, 0, 0); + loadCubeFace(0, 1, 1); + loadCubeFace(1, 1, 2); + loadCubeFace(2, 1, 3); + loadCubeFace(3, 1, 4); + loadCubeFace(1, 2, 5); + } + else + { + createInfo.vkFormat = VK_FORMAT_R8G8B8A8_SRGB; + createInfo.baseWidth = totalWidth; + createInfo.baseHeight = totalHeight; + createInfo.baseDepth = 1; + createInfo.numDimensions = 1 + (totalHeight > 1); + createInfo.numLevels = 1; + createInfo.numLayers = 1; + createInfo.numFaces = 1; + createInfo.isArray = false; + createInfo.generateMipmaps = true; + + ktxTexture2_Create(&createInfo, + KTX_TEXTURE_CREATE_ALLOC_STORAGE, + &kTexture); + + ktxTexture_SetImageFromMemory(ktxTexture(kTexture), + 0, 0, 0, data, totalWidth * totalHeight * 4 * sizeof(unsigned char)); + } stbi_image_free(data); ktxTexture_WriteToNamedFile(ktxTexture(kTexture), textureAsset->getFullPath().c_str()); ktxTexture_Destroy(ktxTexture(kTexture)); - textureAsset->load(); + textureAsset->load(graphics); textureAsset->setStatus(Asset::Status::Ready); ////co_return; } \ No newline at end of file diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index 2ef6664..c214030 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -1,12 +1,14 @@ target_sources(Engine PRIVATE EngineTypes.h + Game.h MinimalEngine.h MinimalEngine.cpp) target_sources(Engine PUBLIC FILE_SET HEADERS FILES + Game.h EngineTypes.h MinimalEngine.h) diff --git a/src/Engine/Component/CMakeLists.txt b/src/Engine/Component/CMakeLists.txt index b136ac9..1d7b0c2 100644 --- a/src/Engine/Component/CMakeLists.txt +++ b/src/Engine/Component/CMakeLists.txt @@ -4,13 +4,15 @@ target_sources(Engine BoxCollider.h Camera.h Camera.cpp - Component.h Collider.h Collider.cpp + Component.h + KeyboardInput.h MeshCollider.h RigidBody.h ShapeBase.h ShapeBase.cpp + Skybox.h SphereCollider.h StaticMesh.h Transform.h @@ -22,11 +24,13 @@ target_sources(Engine AABB.h BoxCollider.h Camera.h - Component.h Collider.h + Component.h + KeyboardInput.h MeshCollider.h RigidBody.h ShapeBase.h + Skybox.h SphereCollider.h StaticMesh.h Transform.h) \ No newline at end of file diff --git a/src/Engine/Component/Camera.h b/src/Engine/Component/Camera.h index 4401298..1b951e2 100644 --- a/src/Engine/Component/Camera.h +++ b/src/Engine/Component/Camera.h @@ -34,6 +34,7 @@ struct Camera //Transforms relative to actor float yaw; float pitch; + bool mainCamera = true; private: bool bNeedsViewBuild; }; diff --git a/src/Engine/Component/KeyboardInput.h b/src/Engine/Component/KeyboardInput.h new file mode 100644 index 0000000..ef43905 --- /dev/null +++ b/src/Engine/Component/KeyboardInput.h @@ -0,0 +1,17 @@ +#pragma once +#include "Graphics/GraphicsResources.h" + +namespace Seele +{ +namespace Component +{ +struct KeyboardInput +{ + Seele::StaticArray(Seele::KeyCode::KEY_LAST)> keys; + bool mouse1; + bool mouse2; + float mouseX; + float mouseY; +}; +} // namespace Component +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Component/Skybox.h b/src/Engine/Component/Skybox.h new file mode 100644 index 0000000..c3eae5d --- /dev/null +++ b/src/Engine/Component/Skybox.h @@ -0,0 +1,17 @@ +#pragma once +#include "Graphics/GraphicsResources.h" + +namespace Seele +{ +namespace Component +{ +struct Skybox +{ + Gfx::PTextureCube day; + Gfx::PTextureCube night; + Gfx::PSamplerState sampler; + Vector fogColor; + float blendFactor; +}; +} // namespace Component +} // namespace Seele diff --git a/src/Engine/Game.h b/src/Engine/Game.h new file mode 100644 index 0000000..f7e567f --- /dev/null +++ b/src/Engine/Game.h @@ -0,0 +1,14 @@ +#pragma once +#include "Scene/Scene.h" +#include "System/SystemGraph.h" + +namespace Seele +{ +class Game +{ +public: + Game() {} + virtual ~Game() {} + virtual void setupScene(PScene scene, PSystemGraph graph) = 0; +}; +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Graphics.cpp b/src/Engine/Graphics/Graphics.cpp index 9b55e72..15651df 100644 --- a/src/Engine/Graphics/Graphics.cpp +++ b/src/Engine/Graphics/Graphics.cpp @@ -25,4 +25,4 @@ PVertexBuffer Graphics::getNullVertexBuffer() nullVertexBuffer = createVertexBuffer(createInfo); } return nullVertexBuffer; -} \ No newline at end of file +} diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index fd022c3..97b8481 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -37,6 +37,8 @@ public: virtual void executeCommands(const Array& commands) = 0; virtual PTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0; + virtual PTexture3D createTexture3D(const TextureCreateInfo &createInfo) = 0; + virtual PTextureCube createTextureCube(const TextureCreateInfo &createInfo) = 0; virtual PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) = 0; virtual PStructuredBuffer createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) = 0; virtual PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0; diff --git a/src/Engine/Graphics/GraphicsResources.cpp b/src/Engine/Graphics/GraphicsResources.cpp index 7854c6c..e321e02 100644 --- a/src/Engine/Graphics/GraphicsResources.cpp +++ b/src/Engine/Graphics/GraphicsResources.cpp @@ -434,6 +434,24 @@ Texture2D::~Texture2D() { } +Texture3D::Texture3D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) + : Texture(mapping, startQueueType) +{ +} + +Texture3D::~Texture3D() +{ +} + +TextureCube::TextureCube(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) + : Texture(mapping, startQueueType) +{ +} + +TextureCube::~TextureCube() +{ +} + RenderCommand::RenderCommand() { } diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index 6f339fd..b99ed43 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -45,7 +45,7 @@ DEFINE_REF(VertexShader) class ControlShader { public: - ControlShader() {} + ControlShader() : numPatchPoints(0) {} virtual ~ControlShader() {} uint32 getNumPatches() const { return numPatchPoints; } @@ -555,6 +555,7 @@ protected: SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; }; DEFINE_REF(Texture) + class Texture2D : public Texture { public: @@ -577,6 +578,50 @@ protected: }; DEFINE_REF(Texture2D) +class Texture3D : public Texture +{ +public: + Texture3D(QueueFamilyMapping mapping, QueueType startQueueType); + virtual ~Texture3D(); + + virtual SeFormat getFormat() const = 0; + virtual uint32 getSizeX() const = 0; + virtual uint32 getSizeY() const = 0; + virtual uint32 getSizeZ() const = 0; + virtual SeSampleCountFlags getNumSamples() const = 0; + virtual uint32 getMipLevels() const = 0; + virtual void changeLayout(SeImageLayout newLayout) = 0; + virtual class Texture3D* getTexture3D() { return this; } +protected: + //Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; +}; +DEFINE_REF(Texture3D) + +class TextureCube : public Texture +{ +public: + TextureCube(QueueFamilyMapping mapping, QueueType startQueueType); + virtual ~TextureCube(); + + virtual SeFormat getFormat() const = 0; + virtual uint32 getSizeX() const = 0; + virtual uint32 getSizeY() const = 0; + virtual uint32 getSizeZ() const = 0; + virtual SeSampleCountFlags getNumSamples() const = 0; + virtual uint32 getMipLevels() const = 0; + virtual void changeLayout(SeImageLayout newLayout) = 0; + virtual class TextureCube* getTextureCube() { return this; } +protected: + //Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; +}; +DEFINE_REF(TextureCube) + DECLARE_REF(Viewport) class RenderCommand { @@ -684,6 +729,8 @@ public: , stencilLoadOp(stencilLoadOp) , stencilStoreOp(stencilStoreOp) , texture(texture) + , clear() + , componentFlags(0) { } virtual ~RenderTargetAttachment() diff --git a/src/Engine/Graphics/RenderPass/CMakeLists.txt b/src/Engine/Graphics/RenderPass/CMakeLists.txt index 70cea3d..ea4bf3d 100644 --- a/src/Engine/Graphics/RenderPass/CMakeLists.txt +++ b/src/Engine/Graphics/RenderPass/CMakeLists.txt @@ -14,6 +14,8 @@ target_sources(Engine RenderGraphResources.h RenderGraphResources.cpp RenderPass.h + SkyboxRenderPass.h + SkyboxRenderPass.cpp TextPass.h TextPass.cpp UIPass.h @@ -30,5 +32,6 @@ target_sources(Engine RenderGraph.h RenderGraphResources.h RenderPass.h + SkyboxRenderPass.h TextPass.h UIPass.h) \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp new file mode 100644 index 0000000..46dbe37 --- /dev/null +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp @@ -0,0 +1,194 @@ +#include "SkyboxRenderPass.h" +#include "Graphics/Graphics.h" + +using namespace Seele; + +SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics) + : RenderPass(graphics) +{ + Array vertices = { + // Back + Vector(-1, -1, -1), + Vector(1, -1, -1), + Vector(-1, 1, -1), + + Vector(1, -1, -1), + Vector(-1, 1, -1), + Vector(1, 1, -1), + + // Front + Vector(1, -1, 1), + Vector(-1, 1, 1), + Vector(-1, -1, 1), + + Vector(-1, 1, 1), + Vector(1, 1, 1), + Vector(1, -1, 1), + + // Top + Vector(-1, -1, -1), + Vector(1, -1, -1), + Vector(1, -1, 1), + + Vector(1, -1, -1), + Vector(1, -1, 1), + Vector(1, -1, 1), + + // Bottom + Vector(-1, 1, -1), + Vector(-1, 1, 1), + Vector(1, 1, -1), + + Vector(1, 1, -1), + Vector(-1, 1, 1), + Vector(1, 1, 1), + + // Left + Vector(-1, -1, -1), + Vector(-1, -1, 1), + Vector(-1, 1, -1), + + Vector(-1, 1, -1), + Vector(-1, -1, 1), + Vector(-1, 1, 1), + + // Right + Vector(1, -1, 1), + Vector(1, 1, -1), + Vector(1, -1, -1), + + Vector(1, -1, 1), + Vector(1, 1, 1), + Vector(1, 1, -1), + }; + + VertexBufferCreateInfo vertexBufferInfo = { + .resourceData = { + .size = sizeof(Vector) * vertices.size(), + .data = (uint8*)vertices.data(), + }, + .vertexSize = sizeof(Vector), + .numVertices = (uint32)vertices.size(), + }; + cubeBuffer = graphics->createVertexBuffer(vertexBufferInfo); +} +SkyboxRenderPass::~SkyboxRenderPass() +{ + +} + +void SkyboxRenderPass::beginFrame(const Component::Camera& cam) +{ + BulkResourceData uniformUpdate; + + viewParams.viewMatrix = cam.getViewMatrix(); + viewParams.projectionMatrix = viewport->getProjectionMatrix(); + viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 0); + viewParams.screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); + uniformUpdate.size = sizeof(ViewParameter); + uniformUpdate.data = (uint8*)&viewParams; + viewParamsBuffer->updateContents(uniformUpdate); + descriptorLayout->reset(); + descriptorSet = descriptorLayout->allocateDescriptorSet(); + descriptorSet->updateBuffer(0, viewParamsBuffer); + descriptorSet->updateTexture(1, passData.skybox.day); + descriptorSet->updateTexture(2, passData.skybox.night); + descriptorSet->updateSampler(3, passData.skybox.sampler); + descriptorSet->writeChanges(); +} + +void SkyboxRenderPass::render() +{ + graphics->beginRenderPass(renderPass); + Gfx::PRenderCommand renderCommand = graphics->createRenderCommand("SkyboxRender"); + renderCommand->setViewport(viewport); + renderCommand->bindPipeline(pipeline); + renderCommand->bindDescriptor(descriptorSet); + renderCommand->bindVertexBuffer({ VertexInputStream(0, 0, cubeBuffer) }); + renderCommand->pushConstants(pipelineLayout, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, sizeof(Vector), &passData.skybox.fogColor); + renderCommand->pushConstants(pipelineLayout, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, sizeof(Vector), sizeof(float), &passData.skybox.blendFactor); + renderCommand->draw(36, 1, 0, 0); + graphics->executeCommands(Array{ renderCommand }); + graphics->endRenderPass(); +} + +void SkyboxRenderPass::endFrame() +{ + +} + +void SkyboxRenderPass::publishOutputs() +{ + UniformBufferCreateInfo viewCreateInfo = { + .resourceData = BulkResourceData { + .size = sizeof(ViewParameter), + .data = nullptr, + }, + .bDynamic = true + }; + viewParamsBuffer = graphics->createUniformBuffer(viewCreateInfo); + + descriptorLayout = graphics->createDescriptorLayout("SkyboxDescLayout"); + descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + descriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); + descriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); + descriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER); + descriptorLayout->create(); + + pipelineLayout = graphics->createPipelineLayout(); + pipelineLayout->addDescriptorLayout(0, descriptorLayout); + pipelineLayout->addPushConstants(Gfx::SePushConstantRange{ + .stageFlags = Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .offset = 0, + .size = sizeof(Vector), + }); + pipelineLayout->addPushConstants(Gfx::SePushConstantRange{ + .stageFlags = Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .offset = sizeof(Vector), + .size = sizeof(float), + }); + + pipelineLayout->create(); +} + +void SkyboxRenderPass::createRenderPass() +{ + Gfx::PRenderTargetAttachment baseColorAttachment = resources->requestRenderTarget("BASEPASS_COLOR"); + baseColorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; + Gfx::PRenderTargetAttachment depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); + depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; + Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(baseColorAttachment, depthAttachment); + renderPass = graphics->createRenderPass(layout, viewport); + + ShaderCreateInfo createInfo; + createInfo.name = "SkyboxVertex"; + createInfo.mainModule = "Skybox"; + createInfo.entryPoint = "vertexMain"; + createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; + Gfx::PVertexShader vertexShader = graphics->createVertexShader(createInfo); + + createInfo.name = "SkyboxFragment"; + createInfo.entryPoint = "fragmentMain"; + Gfx::PFragmentShader fragmentShader = graphics->createFragmentShader(createInfo); + + Gfx::PVertexDeclaration vertexDecl = graphics->createVertexDeclaration({ + Gfx::VertexElement { + .streamIndex = 0, + .offset = 0, + .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, + .attributeIndex = 0, + .stride = sizeof(Vector), + } + }); + + GraphicsPipelineCreateInfo gfxInfo; + gfxInfo.vertexDeclaration = vertexDecl; + gfxInfo.vertexShader = vertexShader; + gfxInfo.fragmentShader = fragmentShader; + gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL; + gfxInfo.rasterizationState.lineWidth = 5.f; + gfxInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + gfxInfo.pipelineLayout = pipelineLayout; + gfxInfo.renderPass = renderPass; + pipeline = graphics->createGraphicsPipeline(gfxInfo); +} diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h new file mode 100644 index 0000000..f88533d --- /dev/null +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h @@ -0,0 +1,34 @@ +#pragma once +#include "RenderPass.h" +#include "Graphics/GraphicsResources.h" +#include "Component/Skybox.h" + +namespace Seele +{ +DECLARE_REF(CameraActor) +DECLARE_REF(Scene) +DECLARE_REF(Viewport) +struct SkyboxPassData +{ + Component::Skybox skybox; +}; +class SkyboxRenderPass : public RenderPass +{ +public: + SkyboxRenderPass(Gfx::PGraphics graphics); + virtual ~SkyboxRenderPass(); + virtual void beginFrame(const Component::Camera& cam) override; + virtual void render() override; + virtual void endFrame() override; + virtual void publishOutputs() override; + virtual void createRenderPass() override; +private: + Gfx::PVertexBuffer cubeBuffer; + Gfx::PUniformBuffer viewParamsBuffer; + Gfx::PDescriptorLayout descriptorLayout; + Gfx::PDescriptorSet descriptorSet; + Gfx::PPipelineLayout pipelineLayout; + Gfx::PGraphicsPipeline pipeline; +}; +DEFINE_REF(SkyboxRenderPass) +} // namespace Seele diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp index d96eb44..8782e65 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp @@ -116,6 +116,18 @@ Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo) return result; } +Gfx::PTexture3D Graphics::createTexture3D(const TextureCreateInfo &createInfo) +{ + PTexture3D result = new Texture3D(this, createInfo); + return result; +} + +Gfx::PTextureCube Graphics::createTextureCube(const TextureCreateInfo &createInfo) +{ + PTextureCube result = new TextureCube(this, createInfo); + return result; +} + Gfx::PUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData) { PUniformBuffer uniformBuffer = new UniformBuffer(this, bulkData); diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.h b/src/Engine/Graphics/Vulkan/VulkanGraphics.h index 49078b7..f35378a 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.h @@ -45,6 +45,8 @@ public: virtual void executeCommands(const Array& commands) override; virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override; + virtual Gfx::PTexture3D createTexture3D(const TextureCreateInfo &createInfo) override; + virtual Gfx::PTextureCube createTextureCube(const TextureCreateInfo &createInfo) override; virtual Gfx::PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override; virtual Gfx::PStructuredBuffer createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) override; virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override; diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h index 60b63e7..3fec584 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h @@ -268,6 +268,8 @@ private: Gfx::SeImageLayout layout; friend class TextureBase; friend class Texture2D; + friend class Texture3D; + friend class TextureCube; friend class Graphics; }; @@ -336,6 +338,116 @@ protected: }; DEFINE_REF(Texture2D) +class Texture3D : public Gfx::Texture3D, public TextureBase +{ +public: + Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); + virtual ~Texture3D(); + virtual uint32 getSizeX() const override + { + return textureHandle->sizeX; + } + virtual uint32 getSizeY() const override + { + return textureHandle->sizeY; + } + virtual uint32 getSizeZ() const override + { + return textureHandle->sizeZ; + } + virtual Gfx::SeFormat getFormat() const override + { + return textureHandle->format; + } + virtual Gfx::SeSampleCountFlags getNumSamples() const override + { + return textureHandle->getNumSamples(); + } + virtual uint32 getMipLevels() const override + { + return textureHandle->getMipLevels(); + } + virtual void changeLayout(Gfx::SeImageLayout newLayout) override; + virtual void* getNativeHandle() override + { + return textureHandle; + } + inline VkImage getHandle() const + { + return textureHandle->image; + } + inline VkImageView getView() const + { + return textureHandle->defaultView; + } + inline bool isDepthStencil() const + { + return textureHandle->isDepthStencil(); + } +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + +}; +DEFINE_REF(Texture3D) + +class TextureCube : public Gfx::TextureCube, public TextureBase +{ +public: + TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); + virtual ~TextureCube(); + virtual uint32 getSizeX() const override + { + return textureHandle->sizeX; + } + virtual uint32 getSizeY() const override + { + return textureHandle->sizeY; + } + virtual uint32 getSizeZ() const override + { + return textureHandle->sizeZ; + } + virtual Gfx::SeFormat getFormat() const override + { + return textureHandle->format; + } + virtual Gfx::SeSampleCountFlags getNumSamples() const override + { + return textureHandle->getNumSamples(); + } + virtual uint32 getMipLevels() const override + { + return textureHandle->getMipLevels(); + } + virtual void changeLayout(Gfx::SeImageLayout newLayout) override; + virtual void* getNativeHandle() override + { + return textureHandle; + } + inline VkImage getHandle() const + { + return textureHandle->image; + } + inline VkImageView getView() const + { + return textureHandle->defaultView; + } + inline bool isDepthStencil() const + { + return textureHandle->isDepthStencil(); + } +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); + virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); + +}; +DEFINE_REF(TextureCube) + class SamplerState : public Gfx::SamplerState { public: diff --git a/src/Engine/Graphics/Vulkan/VulkanTexture.cpp b/src/Engine/Graphics/Vulkan/VulkanTexture.cpp index d6c2d15..a965b06 100644 --- a/src/Engine/Graphics/Vulkan/VulkanTexture.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanTexture.cpp @@ -305,4 +305,58 @@ void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageF VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) { textureHandle->executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); -} \ No newline at end of file +} + +Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage) + : Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.resourceData.owner) +{ + textureHandle = new TextureHandle(graphics, VK_IMAGE_VIEW_TYPE_3D, + createInfo, currentOwner, existingImage); +} + +Texture3D::~Texture3D() +{ +} + +void Texture3D::changeLayout(Gfx::SeImageLayout newLayout) +{ + textureHandle->changeLayout(newLayout); +} + +void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + textureHandle->executeOwnershipBarrier(newOwner); +} + +void Texture3D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) +{ + textureHandle->executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); +} + +TextureCube::TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage) + : Gfx::TextureCube(graphics->getFamilyMapping(), createInfo.resourceData.owner) +{ + textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE, + createInfo, currentOwner, existingImage); +} + +TextureCube::~TextureCube() +{ +} + +void TextureCube::changeLayout(Gfx::SeImageLayout newLayout) +{ + textureHandle->changeLayout(newLayout); +} + +void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + textureHandle->executeOwnershipBarrier(newOwner); +} + +void TextureCube::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, + VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) +{ + textureHandle->executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); +} diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 43b7ddf..089de6c 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -1,14 +1,16 @@ #include "Material.h" #include "Window/WindowManager.h" #include "MaterialInstance.h" +#include "Graphics/VertexShaderInput.h" +#include "Graphics/Graphics.h" using namespace Seele; Gfx::ShaderMap Material::shaderMap; std::mutex Material::shaderMapLock; -Material::Material(Array parameter, Gfx::PDescriptorLayout layout, uint32 uniformDataSize, uint32 uniformBinding, std::string materialName) - : MaterialInterface(parameter, uniformDataSize, uniformBinding) +Material::Material(Gfx::PGraphics graphics, Array parameter, Gfx::PDescriptorLayout layout, uint32 uniformDataSize, uint32 uniformBinding, std::string materialName) + : MaterialInterface(graphics, parameter, uniformDataSize, uniformBinding) , layout(layout) , materialName(materialName) { @@ -40,7 +42,7 @@ Gfx::PDescriptorSet Material::createDescriptorSet() PMaterialInstance Material::instantiate() { - return new MaterialInstance(this); + return new MaterialInstance(graphics, this); } const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const diff --git a/src/Engine/Material/Material.h b/src/Engine/Material/Material.h index fe53b30..35d9f8e 100644 --- a/src/Engine/Material/Material.h +++ b/src/Engine/Material/Material.h @@ -7,7 +7,7 @@ DECLARE_REF(MaterialInstance) class Material : public MaterialInterface { public: - Material(Array parameter, Gfx::PDescriptorLayout layout, uint32 uniformDataSize, uint32 uniformBinding, std::string materialName); + Material(Gfx::PGraphics graphics, Array parameter, Gfx::PDescriptorLayout layout, uint32 uniformDataSize, uint32 uniformBinding, std::string materialName); virtual ~Material(); virtual Gfx::PDescriptorSet createDescriptorSet(); virtual Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; } diff --git a/src/Engine/Material/MaterialInstance.cpp b/src/Engine/Material/MaterialInstance.cpp index be9c6ca..886f85b 100644 --- a/src/Engine/Material/MaterialInstance.cpp +++ b/src/Engine/Material/MaterialInstance.cpp @@ -4,8 +4,8 @@ using namespace Seele; -MaterialInstance::MaterialInstance(PMaterial baseMaterial) - : MaterialInterface(baseMaterial->parameters, baseMaterial->uniformDataSize, baseMaterial->uniformBinding) +MaterialInstance::MaterialInstance(Gfx::PGraphics graphics, PMaterial baseMaterial) + : MaterialInterface(graphics, baseMaterial->parameters, baseMaterial->uniformDataSize, baseMaterial->uniformBinding) , baseMaterial(baseMaterial) { } diff --git a/src/Engine/Material/MaterialInstance.h b/src/Engine/Material/MaterialInstance.h index 9f42aea..09c5fa0 100644 --- a/src/Engine/Material/MaterialInstance.h +++ b/src/Engine/Material/MaterialInstance.h @@ -7,7 +7,7 @@ DECLARE_REF(Material) class MaterialInstance : public MaterialInterface { public: - MaterialInstance(PMaterial baseMaterial); + MaterialInstance(Gfx::PGraphics graphics, PMaterial baseMaterial); virtual ~MaterialInstance(); virtual Gfx::PDescriptorSet createDescriptorSet(); virtual Gfx::PDescriptorLayout getDescriptorLayout() const; diff --git a/src/Engine/Material/MaterialInterface.cpp b/src/Engine/Material/MaterialInterface.cpp index f83cb11..2ea0371 100644 --- a/src/Engine/Material/MaterialInterface.cpp +++ b/src/Engine/Material/MaterialInterface.cpp @@ -4,8 +4,9 @@ using namespace Seele; -MaterialInterface::MaterialInterface(Array parameter, uint32 uniformDataSize, uint32 uniformBinding) - : parameters(parameter) +MaterialInterface::MaterialInterface(Gfx::PGraphics graphics, Array parameter, uint32 uniformDataSize, uint32 uniformBinding) + : graphics(graphics) + , parameters(parameter) , uniformDataSize(uniformDataSize) , uniformBinding(uniformBinding) { @@ -18,7 +19,7 @@ MaterialInterface::MaterialInterface(Array parameter, uint32 u .data = nullptr, } }; - uniformBuffer = WindowManager::getGraphics()->createUniformBuffer(uniformInitializer); + uniformBuffer = graphics->createUniformBuffer(uniformInitializer); } } diff --git a/src/Engine/Material/MaterialInterface.h b/src/Engine/Material/MaterialInterface.h index b9cee5f..f142d4a 100644 --- a/src/Engine/Material/MaterialInterface.h +++ b/src/Engine/Material/MaterialInterface.h @@ -9,7 +9,7 @@ DECLARE_NAME_REF(Gfx, UniformBuffer) class MaterialInterface { public: - MaterialInterface(Array parameter, uint32 uniformDataSize, uint32 uniformBinding); + MaterialInterface(Gfx::PGraphics graphics, Array parameter, uint32 uniformDataSize, uint32 uniformBinding); virtual ~MaterialInterface(); PShaderParameter getParameter(const std::string& name); virtual Gfx::PDescriptorSet createDescriptorSet() = 0; @@ -20,6 +20,7 @@ public: virtual const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const = 0; virtual Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput) = 0; protected: + Gfx::PGraphics graphics; //For now its simply the collection of parameters, since there is no point for expressions Array parameters; Gfx::PUniformBuffer uniformBuffer; diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h index f714476..e472235 100644 --- a/src/Engine/Scene/Scene.h +++ b/src/Engine/Scene/Scene.h @@ -1,7 +1,7 @@ #pragma once #include #include "MinimalEngine.h" -#include "Graphics/GraphicsResources.h" +#include "Graphics/Graphics.h" #include "Graphics/MeshBatch.h" #include "Physics/PhysicsSystem.h" @@ -63,10 +63,15 @@ public: { return registry.get(entity); } + template + void view(Func func) requires std::is_invocable_v + { + registry.view().each(func); + } Array getStaticMeshes(); LightEnv getLightBuffer() const; Gfx::PStructuredBuffer getSceneDataBuffer() const { return sceneDataBuffer; } - + Gfx::PGraphics getGraphics() const { return graphics; } entt::registry registry; private: struct PrimitiveSceneData diff --git a/src/Engine/System/CMakeLists.txt b/src/Engine/System/CMakeLists.txt index dd8df78..f0880e5 100644 --- a/src/Engine/System/CMakeLists.txt +++ b/src/Engine/System/CMakeLists.txt @@ -1,11 +1,16 @@ target_sources(Engine PRIVATE + ComponentSystem.h Executor.h Executor.cpp - SystemBase.h) + SystemBase.h + SystemGraph.h + SystemGraph.cpp) target_sources(Engine PUBLIC FILE_SET HEADERS FILES + ComponentSystem.h Executor.h - SystemBase.h) \ No newline at end of file + SystemBase.h + SystemGraph.h) \ No newline at end of file diff --git a/src/Engine/System/ComponentSystem.h b/src/Engine/System/ComponentSystem.h new file mode 100644 index 0000000..170b8a1 --- /dev/null +++ b/src/Engine/System/ComponentSystem.h @@ -0,0 +1,57 @@ +#pragma once +#include "SystemBase.h" +#include "Component/Component.h" + +namespace Seele +{ +namespace System +{ +template +class ComponentSystem : public SystemBase +{ +public: + ComponentSystem(PScene scene) : SystemBase(scene) {} + virtual ~ComponentSystem() {} + template + auto getDependencies() + { + return Comp::dependencies; + } + template + Dependencies<> getDependencies() + { + return Dependencies<>(); + } + template + auto mergeDependencies(Dep... deps) + { + return (deps | ...); + } + template + void setupView(Dependencies, dp::thread_pool<>&) + { + registry.view().each([&](Components&... comp, Deps&... deps){ + //pool.enqueue_detach([&](){ + (accessComponent(deps) + ...); + update((comp,...)); + //}); + }); + } + template<> + void setupView(Dependencies<>, dp::thread_pool<>&) + { + registry.view().each([&](Components&... comp){ + //pool.enqueue_detach([&](){ + update(comp...); + //}); + }); + } + virtual void run(dp::thread_pool<>& pool, double delta) override + { + SystemBase::run(pool, delta); + setupView(mergeDependencies((getDependencies(),...)), pool); + } + virtual void update(Components&... components) = 0; +}; +} // namespace System +} // namespace Seele diff --git a/src/Engine/System/SystemBase.h b/src/Engine/System/SystemBase.h index 1321fee..5e59089 100644 --- a/src/Engine/System/SystemBase.h +++ b/src/Engine/System/SystemBase.h @@ -1,63 +1,28 @@ #pragma once -#include #include -#include "Component/Component.h" +#include +#include "Scene/Scene.h" namespace Seele { namespace System { - -template -class SystemBase +class SystemBase { public: - SystemBase(entt::registry& registry) : registry(registry) {} + SystemBase(PScene scene) : registry(scene->registry), scene(scene) {} virtual ~SystemBase() {} - template - auto getDependencies() - { - return Comp::dependencies; - } - template - Dependencies<> getDependencies() - { - return Dependencies<>(); - } - template - auto mergeDependencies(Dep... deps) - { - return (deps | ...); - } - template - void setupView(Dependencies, dp::thread_pool<>&) - { - registry.view().each([&](Components&... comp, Deps&... deps){ - //pool.enqueue_detach([&](){ - (accessComponent(deps) + ...); - update((comp,...)); - //}); - }); - } - template<> - void setupView(Dependencies<>, dp::thread_pool<>&) - { - registry.view().each([&](Components&... comp){ - //pool.enqueue_detach([&](){ - update(comp...); - //}); - }); - } - void run(dp::thread_pool<>& pool, double delta) + virtual void run(dp::thread_pool<>& pool, double delta) { deltaTime = delta; - setupView(mergeDependencies((getDependencies(),...)), pool); + update(); } - virtual void update(Components&... components) = 0; + virtual void update() {} protected: double deltaTime; -private: entt::registry& registry; + PScene scene; }; +DEFINE_REF(SystemBase) } // namespace System -} // namespace Seele +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/System/SystemGraph.cpp b/src/Engine/System/SystemGraph.cpp new file mode 100644 index 0000000..9666eef --- /dev/null +++ b/src/Engine/System/SystemGraph.cpp @@ -0,0 +1,15 @@ +#include "SystemGraph.h" + +using namespace Seele; + +void SystemGraph::addSystem(System::UPSystemBase system) +{ + systems.add(std::move(system)); +} + +void SystemGraph::run(dp::thread_pool<>& threadPool, float deltaTime) +{ + for(auto& system : systems) { + system->run(threadPool, deltaTime); + } +} diff --git a/src/Engine/System/SystemGraph.h b/src/Engine/System/SystemGraph.h new file mode 100644 index 0000000..8b09ed5 --- /dev/null +++ b/src/Engine/System/SystemGraph.h @@ -0,0 +1,16 @@ +#pragma once +#include "Containers/Array.h" +#include "SystemBase.h" + +namespace Seele +{ +class SystemGraph +{ +public: + void addSystem(System::UPSystemBase system); + void run(dp::thread_pool<>& threadPool, float deltaTime); +private: + Array systems; +}; +DEFINE_REF(SystemGraph) +} // namespace Seele; \ No newline at end of file diff --git a/src/Engine/Window/View.cpp b/src/Engine/Window/View.cpp index eea5c6b..8a26b0e 100644 --- a/src/Engine/Window/View.cpp +++ b/src/Engine/Window/View.cpp @@ -10,6 +10,8 @@ View::View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &vi , name(name) { viewport = graphics->createViewport(owner->getGfxHandle(), viewportInfo); + owner->addView(this); + setFocused(); } View::~View() diff --git a/src/Engine/Window/WindowManager.cpp b/src/Engine/Window/WindowManager.cpp index 43871df..d6e08af 100644 --- a/src/Engine/Window/WindowManager.cpp +++ b/src/Engine/Window/WindowManager.cpp @@ -1,22 +1,17 @@ #include "WindowManager.h" -#include "Graphics/Vulkan/VulkanGraphics.h" +#include "Graphics/Graphics.h" using namespace Seele; -Gfx::PGraphics WindowManager::graphics; - WindowManager::WindowManager() { - graphics = new Vulkan::Graphics(); - GraphicsInitializer initializer; - graphics->init(initializer); } WindowManager::~WindowManager() { } -PWindow WindowManager::addWindow(const WindowCreateInfo &createInfo) +PWindow WindowManager::addWindow(Gfx::PGraphics graphics, const WindowCreateInfo &createInfo) { Gfx::PWindow handle = graphics->createWindow(createInfo); PWindow window = new Window(this, handle); diff --git a/src/Engine/Window/WindowManager.h b/src/Engine/Window/WindowManager.h index 0ac3171..b87ae29 100644 --- a/src/Engine/Window/WindowManager.h +++ b/src/Engine/Window/WindowManager.h @@ -1,22 +1,17 @@ #pragma once -#include "Graphics/GraphicsResources.h" -#include "Graphics/Graphics.h" #include "Containers/Array.h" #include "Window.h" namespace Seele { +DECLARE_NAME_REF(Gfx, Graphics) class WindowManager { public: WindowManager(); ~WindowManager(); - PWindow addWindow(const WindowCreateInfo &createInfo); + PWindow addWindow(Gfx::PGraphics graphics, const WindowCreateInfo &createInfo); void notifyWindowClosed(PWindow window); - static Gfx::PGraphics getGraphics() - { - return graphics; - } inline bool isActive() const { return windows.size(); @@ -24,7 +19,6 @@ public: private: Array windows; - static Gfx::PGraphics graphics; }; DEFINE_REF(WindowManager) } // namespace Seele \ No newline at end of file