From daedb66293e03046fec6651d44ec6b0495c24d00 Mon Sep 17 00:00:00 2001 From: Denys Kryvytskyi Date: Mon, 22 Apr 2024 17:54:10 +0300 Subject: [PATCH] Improved and simplified Renderer API, Implemed Render Target logic - Reduced redundant static RenderCommand class - Renderer now isn't static and exist in Application class - All render commands submited directly by Renderer class - Imgui library is being built along with other vendor libs - Rendering is now consists of Three Render passes: 1. Render to multisampled render target (if MSAA is enabled) 2. Render from multisampled to intermidiate 3. Render to framebuffer to draw on screen --- CMakeLists.txt | 8 +- Engine/CMakeLists.txt | 56 ++++---- .../{res => assets}/fonts/Roboto_Medium.ttf | Bin .../{res => assets}/fonts/Roboto_Regular.ttf | Bin Engine/{res => assets}/fonts/arial.ttf | Bin .../{res => assets}/shaders/light_debug.frag | 0 .../{res => assets}/shaders/light_debug.vert | 0 .../{res => assets}/shaders/mesh_phong.frag | 1 - .../{res => assets}/shaders/mesh_phong.vert | 0 Engine/assets/shaders/quad.frag | 13 ++ Engine/assets/shaders/quad.vert | 11 ++ Engine/{res => assets}/shaders/sprite.frag | 0 Engine/{res => assets}/shaders/sprite.vert | 0 Engine/{res => assets}/shaders/text2d.frag | 0 Engine/{res => assets}/shaders/text2d.vert | 0 Engine/src/Core/Application.cpp | 17 +-- Engine/src/Core/Application.h | 4 + Engine/src/Editor/Editor.cpp | 27 ++-- Engine/src/Editor/Editor.h | 5 - Engine/src/Editor/ImGuiOverlay.cpp | 1 - Engine/src/Elven.h | 7 +- Engine/src/Platform/OpenGL/OpenGLBuffer.h | 2 +- Engine/src/Platform/OpenGL/OpenGLContext.h | 2 +- .../Platform/OpenGL/OpenGLRenderTarget.cpp | 83 ++++++++++++ .../src/Platform/OpenGL/OpenGLRenderTarget.h | 33 +++++ .../src/Platform/OpenGL/OpenGLRendererAPI.cpp | 20 ++- .../src/Platform/OpenGL/OpenGLRendererAPI.h | 4 +- Engine/src/Platform/OpenGL/OpenGLShader.h | 2 +- Engine/src/Platform/OpenGL/OpenGLTexture.cpp | 121 ++++++++++++++++++ Engine/src/Platform/OpenGL/OpenGLTexture.h | 29 +++++ .../src/Platform/OpenGL/OpenGLTexture2D.cpp | 77 ----------- Engine/src/Platform/OpenGL/OpenGLTexture2D.h | 26 ---- .../src/Platform/OpenGL/OpenGLVertexArray.cpp | 3 +- .../src/Platform/OpenGL/OpenGLVertexArray.h | 3 +- Engine/src/Platform/Windows/WindowsWindow.cpp | 4 +- Engine/src/Platform/Windows/WindowsWindow.h | 3 +- Engine/src/Renderer/Material.cpp | 8 +- Engine/src/Renderer/Material.h | 6 +- Engine/src/Renderer/Mesh.cpp | 15 ++- Engine/src/Renderer/Mesh.h | 5 +- Engine/src/Renderer/{ => RHI}/Buffer.cpp | 3 +- Engine/src/Renderer/{ => RHI}/Buffer.h | 0 .../Renderer/{ => RHI}/GraphicsContext.cpp | 3 +- .../src/Renderer/{ => RHI}/GraphicsContext.h | 0 Engine/src/Renderer/RHI/RenderTarget.cpp | 33 +++++ Engine/src/Renderer/RHI/RenderTarget.h | 39 ++++++ Engine/src/Renderer/{ => RHI}/RendererAPI.cpp | 2 +- Engine/src/Renderer/{ => RHI}/RendererAPI.h | 5 +- Engine/src/Renderer/{ => RHI}/Shader.cpp | 5 +- Engine/src/Renderer/{ => RHI}/Shader.h | 1 + Engine/src/Renderer/RHI/Texture.h | 47 +++++++ Engine/src/Renderer/{ => RHI}/VertexArray.cpp | 6 +- Engine/src/Renderer/{ => RHI}/VertexArray.h | 4 +- Engine/src/Renderer/RenderCommand.h | 7 +- Engine/src/Renderer/Renderer.cpp | 112 ++++++++++++++-- Engine/src/Renderer/Renderer.h | 58 ++++++--- Engine/src/Renderer/Renderer2D.cpp | 22 ++-- Engine/src/Renderer/Renderer2D.h | 8 +- Engine/src/Renderer/TextRenderer.cpp | 25 ++-- Engine/src/Renderer/TextRenderer.h | 7 +- Engine/src/Renderer/Texture2D.h | 23 ---- Engine/src/Resources/FontManager.cpp | 4 +- Engine/src/Resources/FontManager.h | 4 +- Engine/src/Resources/MeshLibrary.cpp | 2 +- Engine/src/Resources/ModelImporter.cpp | 2 +- Engine/src/Resources/TextureManager.cpp | 28 ++-- Engine/src/Resources/TextureManager.h | 20 ++- Engine/src/Scene/Components/SceneComponents.h | 4 +- Engine/src/Scene/Scene.cpp | 10 +- Engine/src/Scene/Systems/Render2dSystem.cpp | 11 +- Engine/src/Scene/Systems/RenderSystem.cpp | 14 +- Engine/vendor/CMakeLists.txt | 1 + Engine/vendor/imgui/CMakeLists.txt | 4 +- .../vendor/imgui/src/imgui_impl_opengl3.cpp | 2 +- Games/CMakeLists.txt | 2 +- Games/Invaders/CMakeLists.txt | 2 +- Games/Pong/CMakeLists.txt | 2 +- Games/TRON/CMakeLists.txt | 2 +- README.md | 21 +-- Sandbox2D/CMakeLists.txt | 2 +- Sandbox2D/src/SandboxApp.cpp | 2 +- Sandbox3D/CMakeLists.txt | 2 +- Sandbox3D/src/MeshModelSandbox.cpp | 2 +- Sandbox3D/src/PrimitivesSandbox.cpp | 4 +- scripts/configure-vs2019.bat | 5 - scripts/configure-vs2022.bat | 2 +- 86 files changed, 799 insertions(+), 361 deletions(-) rename Engine/{res => assets}/fonts/Roboto_Medium.ttf (100%) rename Engine/{res => assets}/fonts/Roboto_Regular.ttf (100%) rename Engine/{res => assets}/fonts/arial.ttf (100%) rename Engine/{res => assets}/shaders/light_debug.frag (100%) rename Engine/{res => assets}/shaders/light_debug.vert (100%) rename Engine/{res => assets}/shaders/mesh_phong.frag (99%) rename Engine/{res => assets}/shaders/mesh_phong.vert (100%) create mode 100644 Engine/assets/shaders/quad.frag create mode 100644 Engine/assets/shaders/quad.vert rename Engine/{res => assets}/shaders/sprite.frag (100%) rename Engine/{res => assets}/shaders/sprite.vert (100%) rename Engine/{res => assets}/shaders/text2d.frag (100%) rename Engine/{res => assets}/shaders/text2d.vert (100%) create mode 100644 Engine/src/Platform/OpenGL/OpenGLRenderTarget.cpp create mode 100644 Engine/src/Platform/OpenGL/OpenGLRenderTarget.h create mode 100644 Engine/src/Platform/OpenGL/OpenGLTexture.cpp create mode 100644 Engine/src/Platform/OpenGL/OpenGLTexture.h delete mode 100644 Engine/src/Platform/OpenGL/OpenGLTexture2D.cpp delete mode 100644 Engine/src/Platform/OpenGL/OpenGLTexture2D.h rename Engine/src/Renderer/{ => RHI}/Buffer.cpp (98%) rename Engine/src/Renderer/{ => RHI}/Buffer.h (100%) rename Engine/src/Renderer/{ => RHI}/GraphicsContext.cpp (93%) rename Engine/src/Renderer/{ => RHI}/GraphicsContext.h (100%) create mode 100644 Engine/src/Renderer/RHI/RenderTarget.cpp create mode 100644 Engine/src/Renderer/RHI/RenderTarget.h rename Engine/src/Renderer/{ => RHI}/RendererAPI.cpp (93%) rename Engine/src/Renderer/{ => RHI}/RendererAPI.h (87%) rename Engine/src/Renderer/{ => RHI}/Shader.cpp (98%) rename Engine/src/Renderer/{ => RHI}/Shader.h (98%) create mode 100644 Engine/src/Renderer/RHI/Texture.h rename Engine/src/Renderer/{ => RHI}/VertexArray.cpp (87%) rename Engine/src/Renderer/{ => RHI}/VertexArray.h (92%) delete mode 100644 Engine/src/Renderer/Texture2D.h delete mode 100644 scripts/configure-vs2019.bat diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b6dade..3454ca9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ option(BUILD_SANDBOX "build sandbox projects" ON) option(BUILD_GAMES "build games" ON) option(EDITOR_MODE "Enable ImGUI editor overlay" ON) option(PROFILE_MODE "Enable functions profiling" ON) -option(ASSIMP_MODE "Enable 3D module with Assimp support" ON) +option(THREE_D_MODE "Enable 3D module with Assimp support" ON) if(WIN32) add_compile_definitions( @@ -33,8 +33,8 @@ if (PROFILE_MODE) add_compile_definitions(PROFILE_MODE) endif() -if (ASSIMP_MODE) - add_compile_definitions(ASSIMP_MODE) +if (THREE_D_MODE) + add_compile_definitions(THREE_D_MODE) endif() add_subdirectory(Engine) @@ -43,7 +43,7 @@ set(ElvenEngine_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) if (BUILD_SANDBOX) - if (ASSIMP_MODE) + if (THREE_D_MODE) add_subdirectory(Sandbox3D) set(STARTUP_PROJECT_NAME "Sandbox3D") else() diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt index ef35bb9..e596d4e 100644 --- a/Engine/CMakeLists.txt +++ b/Engine/CMakeLists.txt @@ -26,19 +26,19 @@ set(ENGINE_HEADERS "src/Events/TextureEvent.h" "src/Events/PhysicsEvent.h" "src/Events/MeshEvent.h" -"src/Renderer/Buffer.h" -"src/Renderer/GraphicsContext.h" +"src/Renderer/RHI/Buffer.h" +"src/Renderer/RHI/GraphicsContext.h" +"src/Renderer/RHI/RendererAPI.h" +"src/Renderer/RHI/Shader.h" +"src/Renderer/RHI/VertexArray.h" +"src/Renderer/RHI/Texture.h" +"src/Renderer/RHI/RenderTarget.h" "src/Renderer/Camera.h" "src/Renderer/CameraController.h" "src/Renderer/OrthographicCameraController.h" "src/Renderer/EditorCameraController.h" -"src/Renderer/RenderCommand.h" "src/Renderer/Renderer2D.h" "src/Renderer/Renderer.h" -"src/Renderer/RendererAPI.h" -"src/Renderer/Shader.h" -"src/Renderer/VertexArray.h" -"src/Renderer/Texture2D.h" "src/Renderer/TextRenderer.h" "src/Renderer/Material.h" "src/Renderer/Mesh.h" @@ -49,7 +49,8 @@ set(ENGINE_HEADERS "src/Platform/OpenGL/OpenGLRendererAPI.h" "src/Platform/OpenGL/OpenGLShader.h" "src/Platform/OpenGL/OpenGLVertexArray.h" -"src/Platform/OpenGL/OpenGLTexture2D.h" +"src/Platform/OpenGL/OpenGLTexture.h" +"src/Platform/OpenGL/OpenGLRenderTarget.h" "src/Scene/Entity.h" "src/Scene/Component.h" "src/Scene/Behavior.h" @@ -96,18 +97,18 @@ set(ENGINE_SOURCES "src/Core/SettingsConfig.cpp" "src/Core/Profiler.cpp" "src/Events/EventManager.cpp" -"src/Renderer/Buffer.cpp" -"src/Renderer/GraphicsContext.cpp" +"src/Renderer/RHI/Buffer.cpp" +"src/Renderer/RHI/GraphicsContext.cpp" +"src/Renderer/RHI/RendererAPI.cpp" +"src/Renderer/RHI/Shader.cpp" +"src/Renderer/RHI/VertexArray.cpp" +"src/Renderer/RHI/RenderTarget.cpp" "src/Renderer/Camera.cpp" "src/Renderer/CameraController.cpp" "src/Renderer/OrthographicCameraController.cpp" "src/Renderer/EditorCameraController.cpp" -"src/Renderer/RenderCommand.cpp" "src/Renderer/Renderer2D.cpp" "src/Renderer/Renderer.cpp" -"src/Renderer/RendererAPI.cpp" -"src/Renderer/Shader.cpp" -"src/Renderer/VertexArray.cpp" "src/Renderer/TextRenderer.cpp" "src/Renderer/Mesh.cpp" "src/Renderer/Material.cpp" @@ -116,7 +117,8 @@ set(ENGINE_SOURCES "src/Platform/OpenGL/OpenGLRendererAPI.cpp" "src/Platform/OpenGL/OpenGLShader.cpp" "src/Platform/OpenGL/OpenGLVertexArray.cpp" -"src/Platform/OpenGL/OpenGLTexture2D.cpp" +"src/Platform/OpenGL/OpenGLTexture.cpp" +"src/Platform/OpenGL/OpenGLRenderTarget.cpp" "src/Platform/Windows/WindowsInput.cpp" "src/Platform/Windows/WindowsWindow.cpp" "src/Scene/Behavior.cpp" @@ -193,17 +195,6 @@ target_include_directories(${LIBRARY_NAME} PUBLIC ${ENGINE_INCLUDE_DIRS} ) -if (EDITOR_MODE) - add_subdirectory(${VENDOR_PATH}/imgui) - set_target_properties(imgui PROPERTIES FOLDER "Libs") -endif() - -if (EDITOR_MODE) - set(STATIC_THIRD_PARTY_LIBRARIES - imgui - ) -endif() - set(VENDOR_PATH_DEBUG ${PROJECT_SOURCE_DIR}/build_vendor/lib/Debug/) set(VENDOR_PATH_RELEASE ${PROJECT_SOURCE_DIR}/build_vendor/lib/Release/) @@ -214,6 +205,7 @@ find_library(lia_d NAMES lia PATHS ${VENDOR_PATH_DEBUG}) find_library(stb_d NAMES stb PATHS ${VENDOR_PATH_DEBUG}) find_library(freetype_d NAMES freetyped PATHS ${VENDOR_PATH_DEBUG}) find_library(fmt_d NAMES fmtd PATHS ${VENDOR_PATH_DEBUG}) +find_library(imgui_d NAMES imguid PATHS ${VENDOR_PATH_DEBUG}) find_library(assimp_d NAMES assimp-vc143-mtd PATHS ${VENDOR_PATH_DEBUG}) find_library(zlib_d NAMES zlibstaticd PATHS ${VENDOR_PATH_DEBUG}) @@ -224,6 +216,7 @@ find_library(lia NAMES lia PATHS ${VENDOR_PATH_RELEASE}) find_library(stb NAMES stb PATHS ${VENDOR_PATH_RELEASE}) find_library(freetype NAMES freetype PATHS ${VENDOR_PATH_RELEASE}) find_library(fmt NAMES fmt PATHS ${VENDOR_PATH_RELEASE}) +find_library(imgui NAMES imgui PATHS ${VENDOR_PATH_RELEASE}) find_library(irrklang NAMES irrKlang.lib PATHS ${VENDOR_PATH}/irrklang/lib) find_library(assimp NAMES assimp-vc143-mt PATHS ${VENDOR_PATH_RELEASE}) find_library(zlib NAMES zlibstatic PATHS ${VENDOR_PATH_RELEASE}) @@ -239,7 +232,14 @@ debug ${irrklang} optimized ${irrklang} debug ${fmt_d} optimized ${fmt} ) -if (ASSIMP_MODE) +if (EDITOR_MODE) + set(VENDOR + ${VENDOR} + debug ${imgui_d} optimized ${imgui} + ) +endif() + +if (THREE_D_MODE) set(VENDOR ${VENDOR} debug ${assimp_d} optimized ${assimp} @@ -247,7 +247,7 @@ if (ASSIMP_MODE) ) endif() -target_link_libraries(${LIBRARY_NAME} ${STATIC_THIRD_PARTY_LIBRARIES} ${VENDOR}) +target_link_libraries(${LIBRARY_NAME} ${VENDOR}) # pch header file path set(ENGINE_PRECOMPILED_HEADERS diff --git a/Engine/res/fonts/Roboto_Medium.ttf b/Engine/assets/fonts/Roboto_Medium.ttf similarity index 100% rename from Engine/res/fonts/Roboto_Medium.ttf rename to Engine/assets/fonts/Roboto_Medium.ttf diff --git a/Engine/res/fonts/Roboto_Regular.ttf b/Engine/assets/fonts/Roboto_Regular.ttf similarity index 100% rename from Engine/res/fonts/Roboto_Regular.ttf rename to Engine/assets/fonts/Roboto_Regular.ttf diff --git a/Engine/res/fonts/arial.ttf b/Engine/assets/fonts/arial.ttf similarity index 100% rename from Engine/res/fonts/arial.ttf rename to Engine/assets/fonts/arial.ttf diff --git a/Engine/res/shaders/light_debug.frag b/Engine/assets/shaders/light_debug.frag similarity index 100% rename from Engine/res/shaders/light_debug.frag rename to Engine/assets/shaders/light_debug.frag diff --git a/Engine/res/shaders/light_debug.vert b/Engine/assets/shaders/light_debug.vert similarity index 100% rename from Engine/res/shaders/light_debug.vert rename to Engine/assets/shaders/light_debug.vert diff --git a/Engine/res/shaders/mesh_phong.frag b/Engine/assets/shaders/mesh_phong.frag similarity index 99% rename from Engine/res/shaders/mesh_phong.frag rename to Engine/assets/shaders/mesh_phong.frag index 8597a03..fc2b39a 100644 --- a/Engine/res/shaders/mesh_phong.frag +++ b/Engine/assets/shaders/mesh_phong.frag @@ -1,4 +1,3 @@ -// Fragment shader for the mesh #version 450 core struct Material { diff --git a/Engine/res/shaders/mesh_phong.vert b/Engine/assets/shaders/mesh_phong.vert similarity index 100% rename from Engine/res/shaders/mesh_phong.vert rename to Engine/assets/shaders/mesh_phong.vert diff --git a/Engine/assets/shaders/quad.frag b/Engine/assets/shaders/quad.frag new file mode 100644 index 0000000..3a7bc03 --- /dev/null +++ b/Engine/assets/shaders/quad.frag @@ -0,0 +1,13 @@ +#version 450 core + +uniform sampler2D u_screenTexture; + +in vec2 v_uv; + +out vec4 color; + +void main() +{ + vec3 col = texture(u_screenTexture, v_uv).rgb; + color = vec4(col, 1.0); +} \ No newline at end of file diff --git a/Engine/assets/shaders/quad.vert b/Engine/assets/shaders/quad.vert new file mode 100644 index 0000000..079859b --- /dev/null +++ b/Engine/assets/shaders/quad.vert @@ -0,0 +1,11 @@ +#version 450 core +layout (location = 0) in vec2 pos; +layout (location = 1) in vec2 uv; + +out vec2 v_uv; + +void main() +{ + v_uv = uv; + gl_Position = vec4(pos, 0.0, 1.0); +} \ No newline at end of file diff --git a/Engine/res/shaders/sprite.frag b/Engine/assets/shaders/sprite.frag similarity index 100% rename from Engine/res/shaders/sprite.frag rename to Engine/assets/shaders/sprite.frag diff --git a/Engine/res/shaders/sprite.vert b/Engine/assets/shaders/sprite.vert similarity index 100% rename from Engine/res/shaders/sprite.vert rename to Engine/assets/shaders/sprite.vert diff --git a/Engine/res/shaders/text2d.frag b/Engine/assets/shaders/text2d.frag similarity index 100% rename from Engine/res/shaders/text2d.frag rename to Engine/assets/shaders/text2d.frag diff --git a/Engine/res/shaders/text2d.vert b/Engine/assets/shaders/text2d.vert similarity index 100% rename from Engine/res/shaders/text2d.vert rename to Engine/assets/shaders/text2d.vert diff --git a/Engine/src/Core/Application.cpp b/Engine/src/Core/Application.cpp index 85c1d25..b0e912a 100644 --- a/Engine/src/Core/Application.cpp +++ b/Engine/src/Core/Application.cpp @@ -37,17 +37,15 @@ Application::Application() EL_CORE_INFO("Executable path: {0}", fileSystem::GetCurrentPath()); - // Init global engine settings gEngineSettings.LoadSettings(); m_window = Window::Create({ "ElvenEngine", gEngineSettings.windowWidth, gEngineSettings.windowHeight, gEngineSettings.enableFullscreen, gEngineSettings.enableVSync }); - RenderCommand::SetViewport(0, 0, m_window->GetWidth(), m_window->GetHeight()); gTextureManager.Init(); gMeshLibrary.Init(); - Renderer::Init(); - Renderer2D::Init(); - TextRenderer::Init(); + m_renderer.Init(m_window->GetWidth(), m_window->GetHeight()); + Renderer2D::Init(&m_renderer); + TextRenderer::Init(m_renderer); gAudioManager.Init(); gSceneManager.Init(); @@ -93,7 +91,7 @@ Application::~Application() gMeshLibrary.Shutdown(); gSceneManager.Shutdown(); gTextureManager.Shutdown(); - Renderer::Shutdown(); + m_renderer.Shutdown(); Renderer2D::Shutdown(); } @@ -149,11 +147,10 @@ void Application::Run() // ============== Rendering Step ============== { PROFILE_SCOPE("Render in: "); - RenderCommand::SetClearColor(Renderer::GetClearColor()); - RenderCommand::Clear(); - + m_renderer.BeginScene(m_cameraController); gSceneManager.Render(elapsedTime); OnRender(elapsedTime); + m_renderer.EndScene(); } #if EDITOR_MODE @@ -187,7 +184,7 @@ void Application::OnWindowResize(const events::WindowResizeEvent& e) } m_isPaused = false; - Renderer::OnWindowResize(e.width, e.height); + m_renderer.OnWindowResize(e.width, e.height); if (!OrthographicCameraController::IsCustomCameraController()) { auto& cameraComponent = GetScene().GetComponent(m_orthoCameraEntity); diff --git a/Engine/src/Core/Application.h b/Engine/src/Core/Application.h index c067b3a..200330f 100644 --- a/Engine/src/Core/Application.h +++ b/Engine/src/Core/Application.h @@ -4,6 +4,7 @@ #include "Events/ApplicationEvent.h" #include "Events/EventHandler.h" +#include "Renderer/Renderer.h" #include "Scene/Entity.h" #if EDITOR_MODE @@ -40,6 +41,8 @@ class Application { SharedPtr GetCameraController() const { return m_cameraController; } + Renderer& GetRenderer() { return m_renderer; } + protected: virtual void OnCreate() {}; virtual void OnUpdate(float dt) {}; @@ -63,6 +66,7 @@ class Application { bool m_running { false }; SharedPtr m_cameraController { nullptr }; + Renderer m_renderer; private: static Application* s_instance; diff --git a/Engine/src/Editor/Editor.cpp b/Engine/src/Editor/Editor.cpp index fb59b24..ba00bc2 100644 --- a/Engine/src/Editor/Editor.cpp +++ b/Engine/src/Editor/Editor.cpp @@ -5,7 +5,6 @@ #include "Core/Application.h" #include "Core/SettingsConfig.h" #include "Core/Window.h" -#include "Renderer/RenderCommand.h" #include "Renderer/Renderer.h" #include @@ -13,9 +12,6 @@ namespace elv::editor { void Editor::OnInit() { - m_isVSync = Application::Get().GetWindow()->IsVSync(); - m_isFullScreen = Application::Get().GetWindow()->IsFullScreen(); - if (gEngineSettings.enableSceneGraph) { m_sceneHierarchyPanel.OnInit(); } else { @@ -31,28 +27,35 @@ void Editor::OnImGuiRender() ImGui::ShowDemoWindow(&showDemo); } + auto& window = Application::Get().GetWindow(); + auto& renderer = Application::Get().GetRenderer(); + + bool isVSync = window->IsVSync(); + bool isFullScreen = window->IsFullScreen(); + bool isMSAAEnabled = renderer.IsMSAAEnabled(); + // ============ Settings panel ============ ImGui::Begin("Settings"); ImGui::SetWindowSize(ImVec2(300.0f, 200.0f)); - if (ImGui::Checkbox("V-Sync", &m_isVSync)) { - Application::Get().GetWindow()->SetVSync(m_isVSync); + if (ImGui::Checkbox("V-Sync", &isVSync)) { + window->SetVSync(isVSync); } - if (ImGui::Checkbox("Fullsreen mode", &m_isFullScreen)) { - Application::Get().GetWindow()->SetFullScreen(m_isFullScreen); + if (ImGui::Checkbox("Fullsreen mode", &isFullScreen)) { + window->SetFullScreen(isFullScreen); } - if (ImGui::Checkbox("MSAA", &m_isMSAAEnabled)) { - RenderCommand::EnableMSAA(m_isMSAAEnabled); + if (ImGui::Checkbox("MSAA", &isMSAAEnabled)) { + renderer.EnableMSAA(isMSAAEnabled); } ImGui::End(); // ============ Environment ============ ImGui::Begin("Environment"); - auto clearColor = Renderer::GetClearColor(); + auto clearColor = renderer.GetClearColor(); if (DrawRGBAColorControl("Clear color", clearColor)) { - Renderer::SetClearColor(clearColor); + renderer.SetClearColor(clearColor); } ImGui::End(); diff --git a/Engine/src/Editor/Editor.h b/Engine/src/Editor/Editor.h index 3f74d84..312d32c 100644 --- a/Engine/src/Editor/Editor.h +++ b/Engine/src/Editor/Editor.h @@ -14,11 +14,6 @@ class Editor { // panels SceneHierarchyPanel m_sceneHierarchyPanel; ProfileTelemetryPanel m_profileTelemetry; - - // settings - bool m_isVSync { false }; - bool m_isFullScreen { false }; - bool m_isMSAAEnabled { true }; }; } // namespace elv::editor diff --git a/Engine/src/Editor/ImGuiOverlay.cpp b/Engine/src/Editor/ImGuiOverlay.cpp index 0343cc6..f7b9eef 100644 --- a/Engine/src/Editor/ImGuiOverlay.cpp +++ b/Engine/src/Editor/ImGuiOverlay.cpp @@ -9,7 +9,6 @@ #include "Core/Application.h" #include "Core/Window.h" -#include "Renderer/RenderCommand.h" #include "Renderer/Renderer2D.h" namespace elv { diff --git a/Engine/src/Elven.h b/Engine/src/Elven.h index ba41224..4da1a49 100644 --- a/Engine/src/Elven.h +++ b/Engine/src/Elven.h @@ -29,14 +29,13 @@ #include "Renderer/CameraController.h" #include "Renderer/EditorCameraController.h" #include "Renderer/OrthographicCameraController.h" -#include "Renderer/RenderCommand.h" #include "Renderer/Renderer.h" #include "Renderer/Renderer2D.h" -#include "Renderer/Buffer.h" #include "Renderer/Material.h" -#include "Renderer/Shader.h" -#include "Renderer/VertexArray.h" +#include "Renderer/RHI/Buffer.h" +#include "Renderer/RHI/Shader.h" +#include "Renderer/RHI/VertexArray.h" #include "Resources/TextureManager.h" diff --git a/Engine/src/Platform/OpenGL/OpenGLBuffer.h b/Engine/src/Platform/OpenGL/OpenGLBuffer.h index eb9ab9f..0b47c91 100644 --- a/Engine/src/Platform/OpenGL/OpenGLBuffer.h +++ b/Engine/src/Platform/OpenGL/OpenGLBuffer.h @@ -1,6 +1,6 @@ #pragma once -#include "Renderer/Buffer.h" +#include "Renderer/RHI/Buffer.h" namespace elv { diff --git a/Engine/src/Platform/OpenGL/OpenGLContext.h b/Engine/src/Platform/OpenGL/OpenGLContext.h index ba12258..238c6a3 100644 --- a/Engine/src/Platform/OpenGL/OpenGLContext.h +++ b/Engine/src/Platform/OpenGL/OpenGLContext.h @@ -1,6 +1,6 @@ #pragma once -#include "Renderer/GraphicsContext.h" +#include "Renderer/RHI/GraphicsContext.h" struct GLFWwindow; diff --git a/Engine/src/Platform/OpenGL/OpenGLRenderTarget.cpp b/Engine/src/Platform/OpenGL/OpenGLRenderTarget.cpp new file mode 100644 index 0000000..0f81820 --- /dev/null +++ b/Engine/src/Platform/OpenGL/OpenGLRenderTarget.cpp @@ -0,0 +1,83 @@ +#include "OpenGLRenderTarget.h" + +#include "Renderer/RHI/Texture.h" +#include "Resources/TextureManager.h" + +#include + +namespace elv { +OpenGLRenderTarget::~OpenGLRenderTarget() +{ + glDeleteFramebuffers(1, &m_id); +} + +void OpenGLRenderTarget::Init(const std::uint32_t width, const std::uint32_t height, bool isMultisampled) +{ + m_isMultisampled = isMultisampled; + m_size = { width, height }; + + glCreateFramebuffers(1, &m_id); + InitAttachments(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void OpenGLRenderTarget::Bind() const +{ + glBindFramebuffer(GL_FRAMEBUFFER, m_id); +} + +void OpenGLRenderTarget::Unbind() const +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void OpenGLRenderTarget::BindDraw() const +{ + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_id); +} + +void OpenGLRenderTarget::BindRead() const +{ + glBindFramebuffer(GL_READ_FRAMEBUFFER, m_id); +} + +void OpenGLRenderTarget::Resize(const std::uint32_t width, const std::uint32_t height) +{ + m_size = { width, height }; + + Bind(); + InitAttachments(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void OpenGLRenderTarget::Blit(const UniquePtr& src) +{ + src->BindRead(); + BindDraw(); + glBlitFramebuffer(0, 0, m_size.Width, m_size.Height, 0, 0, src->GetSize().Width, src->GetSize().Height, GL_COLOR_BUFFER_BIT, GL_NEAREST); +} + +void OpenGLRenderTarget::InitAttachments() +{ + { + Texture::Info info; + info.Multisampled = m_isMultisampled; + + m_colorTextureAttachment = textures::Load(m_size.Width, m_size.Height, info); + glNamedFramebufferTexture(m_id, GL_COLOR_ATTACHMENT0, m_colorTextureAttachment->GetId(), 0); + } + + { + Texture::Info info; + info.InternalFormat = Texture::InternalFormat::DepthStencil; + info.Multisampled = m_isMultisampled; + + m_depthStencilAttachment = textures::Load(m_size.Width, m_size.Height, info); + glNamedFramebufferTexture(m_id, GL_DEPTH_STENCIL_ATTACHMENT, m_depthStencilAttachment->GetId(), 0); + } + + if (glCheckNamedFramebufferStatus(m_id, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + std::cout << "Framebuffer is not complete!" << std::endl; + } +} +} // namespace elv diff --git a/Engine/src/Platform/OpenGL/OpenGLRenderTarget.h b/Engine/src/Platform/OpenGL/OpenGLRenderTarget.h new file mode 100644 index 0000000..cb046f3 --- /dev/null +++ b/Engine/src/Platform/OpenGL/OpenGLRenderTarget.h @@ -0,0 +1,33 @@ +#pragma once + +#include "Renderer/RHI/RenderTarget.h" + +namespace elv { + +class OpenGLRenderTarget : public RenderTarget { +public: + struct Size { + std::uint32_t Width { 0 }; + std::uint32_t Height { 0 }; + }; + +public: + OpenGLRenderTarget() = default; + ~OpenGLRenderTarget(); + + virtual void Init(const std::uint32_t width, const std::uint32_t height, bool isMultisampled = false) override; + virtual void Bind() const override; + virtual void Unbind() const override; + virtual void BindDraw() const override; + virtual void BindRead() const override; + virtual void Resize(const std::uint32_t width, const std::uint32_t height) override; + virtual void Blit(const UniquePtr& src) override; + +private: + void InitAttachments(); + +private: + std::uint32_t m_id { 0 }; +}; + +} // namespace elv diff --git a/Engine/src/Platform/OpenGL/OpenGLRendererAPI.cpp b/Engine/src/Platform/OpenGL/OpenGLRendererAPI.cpp index fd3fae0..28d52f7 100644 --- a/Engine/src/Platform/OpenGL/OpenGLRendererAPI.cpp +++ b/Engine/src/Platform/OpenGL/OpenGLRendererAPI.cpp @@ -54,12 +54,6 @@ void OpenGLRendererAPI::Init() // blending glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // msaa - glEnable(GL_MULTISAMPLE); - - // faceculling - glEnable(GL_CULL_FACE); } void OpenGLRendererAPI::SetViewport(std::uint32_t x, std::uint32_t y, std::uint32_t width, std::uint32_t height) @@ -76,6 +70,11 @@ void OpenGLRendererAPI::Clear() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } +void OpenGLRendererAPI::ClearColorBit() +{ + glClear(GL_COLOR_BUFFER_BIT); +} + void OpenGLRendererAPI::EnableDepthTesting(bool enabled) { if (enabled) { @@ -95,6 +94,15 @@ void OpenGLRendererAPI::EnableMSAA(bool enabled) } } +void OpenGLRendererAPI::EnableFaceculling(bool enabled) +{ + if (enabled) { + glEnable(GL_CULL_FACE); + } else { + glDisable(GL_CULL_FACE); + } +} + void OpenGLRendererAPI::DisableByteAlignment() { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); diff --git a/Engine/src/Platform/OpenGL/OpenGLRendererAPI.h b/Engine/src/Platform/OpenGL/OpenGLRendererAPI.h index a7f6b7e..e14a597 100644 --- a/Engine/src/Platform/OpenGL/OpenGLRendererAPI.h +++ b/Engine/src/Platform/OpenGL/OpenGLRendererAPI.h @@ -1,6 +1,6 @@ #pragma once -#include "Renderer/RendererAPI.h" +#include "Renderer/RHI/RendererAPI.h" namespace elv { @@ -10,9 +10,11 @@ class OpenGLRendererAPI : public RendererAPI { void SetClearColor(const lia::vec4& color) override; void Clear() override; + void ClearColorBit() override; void EnableDepthTesting(bool enabled) override; void EnableMSAA(bool enabled) override; + void EnableFaceculling(bool enabled) override; void DisableByteAlignment() override; diff --git a/Engine/src/Platform/OpenGL/OpenGLShader.h b/Engine/src/Platform/OpenGL/OpenGLShader.h index 321b3f6..f69308d 100644 --- a/Engine/src/Platform/OpenGL/OpenGLShader.h +++ b/Engine/src/Platform/OpenGL/OpenGLShader.h @@ -1,6 +1,6 @@ #pragma once -#include "Renderer/Shader.h" +#include "Renderer/RHI/Shader.h" namespace elv { diff --git a/Engine/src/Platform/OpenGL/OpenGLTexture.cpp b/Engine/src/Platform/OpenGL/OpenGLTexture.cpp new file mode 100644 index 0000000..c3983d7 --- /dev/null +++ b/Engine/src/Platform/OpenGL/OpenGLTexture.cpp @@ -0,0 +1,121 @@ +#include "OpenGLTexture.h" + +#include + +namespace elv { + +GLenum GetGLWrappingMode(const Texture::WrappingMode wrappingMode) +{ + switch (wrappingMode) { + case Texture::WrappingMode::Repeat: + return GL_REPEAT; + case Texture::WrappingMode::MirroredRepeat: + return GL_MIRRORED_REPEAT; + case Texture::WrappingMode::ClampToBorder: + return GL_CLAMP_TO_BORDER; + } + + return GL_CLAMP_TO_EDGE; +} + +std::pair GetGLDataFormat(const Texture::InternalFormat format) +{ + GLenum internalFormat = GL_RGBA8; + GLenum dataFormat = GL_RGBA; + + switch (format) { + case Texture::InternalFormat::RGB8: + internalFormat = GL_RGB8; + dataFormat = GL_RGB; + break; + case Texture::InternalFormat::R8: + internalFormat = GL_R8; + dataFormat = GL_RED; + break; + case Texture::InternalFormat::DepthStencil: + internalFormat = GL_DEPTH24_STENCIL8; + dataFormat = GL_DEPTH_STENCIL; + break; + } + + return std::make_pair(internalFormat, dataFormat); +} + +OpenGLTexture::OpenGLTexture(std::uint32_t width, std::uint32_t height, std::uint32_t nrChannels /* = 3 */) + : m_width(width) + , m_height(height) +{ + + if (nrChannels == 4) { + m_internalFormat = GL_RGBA8; + m_dataFormat = GL_RGBA; + } else if (nrChannels == 3) { + m_internalFormat = GL_RGB8; + m_dataFormat = GL_RGB; + } else { + m_internalFormat = GL_R8; + m_dataFormat = GL_RED; + } + + glCreateTextures(GL_TEXTURE_2D, 1, &m_id); + glTextureStorage2D(m_id, 1, m_internalFormat, m_width, m_height); + + glTextureParameteri(m_id, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTextureParameteri(m_id, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTextureParameteri(m_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTextureParameteri(m_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} + +OpenGLTexture::OpenGLTexture(std::uint32_t width, std::uint32_t height, const Info& info) +{ + const auto format = GetGLDataFormat(info.InternalFormat); + + if (info.Multisampled) { + glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_id); + glTextureStorage2DMultisample(m_id, 4, format.first, width, height, GL_TRUE); + } else { + glCreateTextures(GL_TEXTURE_2D, 1, &m_id); + glTextureStorage2D(m_id, 1, format.first, width, height); + + const auto mode = GetGLWrappingMode(info.WrapR); + glTextureParameteri(m_id, GL_TEXTURE_WRAP_R, GetGLWrappingMode(info.WrapR)); + glTextureParameteri(m_id, GL_TEXTURE_WRAP_S, GetGLWrappingMode(info.WrapS)); + glTextureParameteri(m_id, GL_TEXTURE_WRAP_T, GetGLWrappingMode(info.WrapT)); + glTextureParameteri(m_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTextureParameteri(m_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } +} + +OpenGLTexture::~OpenGLTexture() +{ + glDeleteTextures(1, &m_id); +} + +void OpenGLTexture::BindToSlot(std::uint32_t slot) +{ + m_slot = slot; + glBindTextureUnit(slot, m_id); +} + +void OpenGLTexture::Unbind() +{ + glBindTextureUnit(m_slot, 0); +} + +void OpenGLTexture::SetData(void* data, bool generateMipmap /* = true */) +{ + if (generateMipmap) { + glGenerateTextureMipmap(m_id); + } + glTextureSubImage2D(m_id, 0, 0, 0, m_width, m_height, m_dataFormat, GL_UNSIGNED_BYTE, data); +} + +void OpenGLTexture::SetWrappingMode(const WrappingMode wrappingMode) +{ + auto mode = GetGLWrappingMode(wrappingMode); + + glTextureParameteri(m_id, GL_TEXTURE_WRAP_S, mode); + glTextureParameteri(m_id, GL_TEXTURE_WRAP_T, mode); +} + +} // namespace elv diff --git a/Engine/src/Platform/OpenGL/OpenGLTexture.h b/Engine/src/Platform/OpenGL/OpenGLTexture.h new file mode 100644 index 0000000..1a21bf4 --- /dev/null +++ b/Engine/src/Platform/OpenGL/OpenGLTexture.h @@ -0,0 +1,29 @@ +#pragma once + +#include "Renderer/RHI/Texture.h" + +namespace elv { + +class OpenGLTexture : public Texture { +public: + OpenGLTexture(std::uint32_t width, std::uint32_t height, std::uint32_t nrChannels = 3); + OpenGLTexture(std::uint32_t width, std::uint32_t height, const Info& info); + ~OpenGLTexture(); + + void BindToSlot(std::uint32_t slot) override; + void Unbind() override; + void SetData(void* data, bool generateMipmap = true) override; + void SetWrappingMode(const WrappingMode wrappingMode) override; + + std::uint32_t GetId() const override { return m_id; } + +private: + uint32_t m_id { 0 }; + uint32_t m_slot { 0 }; + uint32_t m_width { 0 }; + uint32_t m_height { 0 }; + unsigned int m_internalFormat { 0 }; + unsigned int m_dataFormat { 0 }; +}; + +} // namespace elv diff --git a/Engine/src/Platform/OpenGL/OpenGLTexture2D.cpp b/Engine/src/Platform/OpenGL/OpenGLTexture2D.cpp deleted file mode 100644 index ffb278a..0000000 --- a/Engine/src/Platform/OpenGL/OpenGLTexture2D.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "OpenGLTexture2D.h" - -#include - -namespace elv { - -GLenum GetGLWrappingMode(const TextureWrappingMode wrappingMode) -{ - switch (wrappingMode) { - case TextureWrappingMode::Repeat: - return GL_REPEAT; - case TextureWrappingMode::MirroredRepeat: - return GL_MIRRORED_REPEAT; - case TextureWrappingMode::ClampToBorder: - return GL_CLAMP_TO_BORDER; - } - - return GL_CLAMP_TO_EDGE; -} - -OpenGLTexture2D::OpenGLTexture2D(std::uint32_t width, std::uint32_t height, std::uint32_t nrChannels /* = 3 */) - : m_width(width) - , m_height(height) -{ - if (nrChannels == 4) { - m_internalFormat = GL_RGBA8; - m_dataFormat = GL_RGBA; - } else if (nrChannels == 3) { - m_internalFormat = GL_RGB8; - m_dataFormat = GL_RGB; - } else { - m_internalFormat = GL_R8; - m_dataFormat = GL_RED; - } - - glCreateTextures(GL_TEXTURE_2D, 1, &m_id); - glTextureStorage2D(m_id, 1, m_internalFormat, m_width, m_height); - - glTextureParameteri(m_id, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTextureParameteri(m_id, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTextureParameteri(m_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTextureParameteri(m_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -} - -OpenGLTexture2D::~OpenGLTexture2D() -{ - glDeleteTextures(1, &m_id); -} - -void OpenGLTexture2D::BindToUnit(std::uint32_t unit) -{ - m_slot = unit; - glBindTextureUnit(unit, m_id); -} - -void OpenGLTexture2D::Unbind() -{ - glBindTextureUnit(m_slot, 0); -} - -void OpenGLTexture2D::SetData(void* data, bool generateMipmap /* = true */) -{ - if (generateMipmap) { - glGenerateTextureMipmap(m_id); - } - glTextureSubImage2D(m_id, 0, 0, 0, m_width, m_height, m_dataFormat, GL_UNSIGNED_BYTE, data); -} - -void OpenGLTexture2D::SetWrappingMode(const TextureWrappingMode wrappingMode) -{ - auto mode = GetGLWrappingMode(wrappingMode); - - glTextureParameteri(m_id, GL_TEXTURE_WRAP_S, mode); - glTextureParameteri(m_id, GL_TEXTURE_WRAP_T, mode); -} - -} // namespace elv diff --git a/Engine/src/Platform/OpenGL/OpenGLTexture2D.h b/Engine/src/Platform/OpenGL/OpenGLTexture2D.h deleted file mode 100644 index 30a75b3..0000000 --- a/Engine/src/Platform/OpenGL/OpenGLTexture2D.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "Renderer/Texture2D.h" - -namespace elv { - -class OpenGLTexture2D : public Texture2D { -public: - OpenGLTexture2D(std::uint32_t width, std::uint32_t height, std::uint32_t nrChannels = 3); - ~OpenGLTexture2D(); - - void BindToUnit(std::uint32_t unit) override; - void Unbind() override; - void SetData(void* data, bool generateMipmap = true) override; - void SetWrappingMode(const TextureWrappingMode wrappingMode) override; - -private: - uint32_t m_id { 0 }; - uint32_t m_slot { 0 }; - uint32_t m_width { 0 }; - uint32_t m_height { 0 }; - unsigned int m_internalFormat { 0 }; - unsigned int m_dataFormat { 0 }; -}; - -} // namespace elv diff --git a/Engine/src/Platform/OpenGL/OpenGLVertexArray.cpp b/Engine/src/Platform/OpenGL/OpenGLVertexArray.cpp index 9270304..3e3a5e1 100644 --- a/Engine/src/Platform/OpenGL/OpenGLVertexArray.cpp +++ b/Engine/src/Platform/OpenGL/OpenGLVertexArray.cpp @@ -1,5 +1,4 @@ - -#include "Platform/OpenGL/OpenGLVertexArray.h" +#include "OpenGLVertexArray.h" #include diff --git a/Engine/src/Platform/OpenGL/OpenGLVertexArray.h b/Engine/src/Platform/OpenGL/OpenGLVertexArray.h index 869b6f3..196eb41 100644 --- a/Engine/src/Platform/OpenGL/OpenGLVertexArray.h +++ b/Engine/src/Platform/OpenGL/OpenGLVertexArray.h @@ -1,6 +1,7 @@ #pragma once -#include "Renderer/VertexArray.h" +#include "Renderer/RHI/Buffer.h" +#include "Renderer/RHI/VertexArray.h" namespace elv { diff --git a/Engine/src/Platform/Windows/WindowsWindow.cpp b/Engine/src/Platform/Windows/WindowsWindow.cpp index 9517167..a336ab1 100644 --- a/Engine/src/Platform/Windows/WindowsWindow.cpp +++ b/Engine/src/Platform/Windows/WindowsWindow.cpp @@ -2,11 +2,13 @@ #include "Platform/OpenGL/OpenGLContext.h" #include "Events/ApplicationEvent.h" +#include "Events/EventManager.h" #include "Events/KeyEvent.h" #include "Events/MouseEvent.h" #include "Core/SettingsConfig.h" -#include "Events/EventManager.h" + +#include "Renderer/RHI/GraphicsContext.h" #include diff --git a/Engine/src/Platform/Windows/WindowsWindow.h b/Engine/src/Platform/Windows/WindowsWindow.h index cba2bd4..f9b0b0c 100644 --- a/Engine/src/Platform/Windows/WindowsWindow.h +++ b/Engine/src/Platform/Windows/WindowsWindow.h @@ -1,13 +1,14 @@ #pragma once #include "Core/Window.h" -#include "Renderer/GraphicsContext.h" struct GLFWwindow; struct GLFWmonitor; namespace elv { +class GraphicsContext; + class WindowsWindow : public Window { private: struct WindowData { diff --git a/Engine/src/Renderer/Material.cpp b/Engine/src/Renderer/Material.cpp index 1557158..54d375e 100644 --- a/Engine/src/Renderer/Material.cpp +++ b/Engine/src/Renderer/Material.cpp @@ -1,7 +1,7 @@ #include "Material.h" -#include "Shader.h" -#include "Texture2D.h" +#include "RHI/Shader.h" +#include "RHI/Texture.h" #include "Core/StringId.h" #include "Events/EventManager.h" @@ -32,7 +32,7 @@ Material::Material() LoadTexture("", false, m_textures[TextureSlot::Transparency]); } -void Material::SetTexture(const TextureSlot slot, const std::string& name, SharedPtr texture) +void Material::SetTexture(const TextureSlot slot, const std::string& name, SharedPtr texture) { auto& map = m_textures[slot]; map.name = name; @@ -105,7 +105,7 @@ void Material::ApplyMaterial(const SharedPtr& shader) const for (int i = 0; i < TextureSlot::Count; ++i) { const auto& textureMap = m_textures[i]; if (textureMap.texturePtr) { - textureMap.texturePtr->BindToUnit(i); + textureMap.texturePtr->BindToSlot(i); shader->SetInteger(fmt::format("u_Material.{}", kDefaultTextureMapNames[i]), i); } } diff --git a/Engine/src/Renderer/Material.h b/Engine/src/Renderer/Material.h index 6d8b458..4b02bd5 100644 --- a/Engine/src/Renderer/Material.h +++ b/Engine/src/Renderer/Material.h @@ -1,7 +1,7 @@ #pragma once namespace elv { -class Texture2D; +class Texture; class Shader; class Material { @@ -20,7 +20,7 @@ class Material { struct TextureMap { bool needReload { false }; std::string name; - SharedPtr texturePtr { nullptr }; + SharedPtr texturePtr { nullptr }; }; public: @@ -33,7 +33,7 @@ class Material { * @param name Texture name * @param texture already loaded texture pointer */ - void SetTexture(const TextureSlot slot, const std::string& name, SharedPtr texture); + void SetTexture(const TextureSlot slot, const std::string& name, SharedPtr texture); /** * Set texture info to the slot, texture will be loaded on LoadTextures function call diff --git a/Engine/src/Renderer/Mesh.cpp b/Engine/src/Renderer/Mesh.cpp index afb6b20..30cc871 100644 --- a/Engine/src/Renderer/Mesh.cpp +++ b/Engine/src/Renderer/Mesh.cpp @@ -1,9 +1,10 @@ #include "Mesh.h" -#include "RenderCommand.h" -#include "Shader.h" -#include "Texture2D.h" -#include "VertexArray.h" +#include "RHI/Buffer.h" +#include "RHI/Shader.h" +#include "RHI/Texture.h" +#include "RHI/VertexArray.h" +#include "Renderer.h" namespace elv { @@ -57,15 +58,15 @@ void Mesh::LoadTextures(const std::string& dir, const bool async) } } -void Mesh::Draw(const SharedPtr& shader) const +void Mesh::Draw(Renderer* renderer, const SharedPtr& shader) const { m_vao->Bind(); m_material.ApplyMaterial(shader); - RenderCommand::DrawIndexed(m_vao, 0, m_topology); + renderer->Submit(m_vao, 0, m_topology); // draw submeshes for (auto& submesh : m_submeshes) { - submesh.Draw(shader); + submesh.Draw(renderer, shader); } } diff --git a/Engine/src/Renderer/Mesh.h b/Engine/src/Renderer/Mesh.h index a276aaf..54c1a75 100644 --- a/Engine/src/Renderer/Mesh.h +++ b/Engine/src/Renderer/Mesh.h @@ -6,8 +6,9 @@ namespace elv { class Shader; -class Texture2D; +class Texture; class VertexArray; +class Renderer; struct MeshVertex { lia::vec3 Position; @@ -29,7 +30,7 @@ class Mesh { virtual ~Mesh() = default; void SetInfo(const std::vector& vertices, const std::vector& indices, const std::vector& texturesInfo); - void Draw(const SharedPtr& shader) const; + void Draw(Renderer* renderer, const SharedPtr& shader) const; void AddSubmesh(Mesh&& submesh); void SetMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async); diff --git a/Engine/src/Renderer/Buffer.cpp b/Engine/src/Renderer/RHI/Buffer.cpp similarity index 98% rename from Engine/src/Renderer/Buffer.cpp rename to Engine/src/Renderer/RHI/Buffer.cpp index 96909cd..88aef09 100644 --- a/Engine/src/Renderer/Buffer.cpp +++ b/Engine/src/Renderer/RHI/Buffer.cpp @@ -1,4 +1,5 @@ -#include "Renderer/Buffer.h" +#include "Buffer.h" + #include "Renderer/Renderer.h" #include "Platform/OpenGL/OpenGLBuffer.h" diff --git a/Engine/src/Renderer/Buffer.h b/Engine/src/Renderer/RHI/Buffer.h similarity index 100% rename from Engine/src/Renderer/Buffer.h rename to Engine/src/Renderer/RHI/Buffer.h diff --git a/Engine/src/Renderer/GraphicsContext.cpp b/Engine/src/Renderer/RHI/GraphicsContext.cpp similarity index 93% rename from Engine/src/Renderer/GraphicsContext.cpp rename to Engine/src/Renderer/RHI/GraphicsContext.cpp index 0492220..8476f77 100644 --- a/Engine/src/Renderer/GraphicsContext.cpp +++ b/Engine/src/Renderer/RHI/GraphicsContext.cpp @@ -1,4 +1,5 @@ -#include "Renderer/GraphicsContext.h" +#include "GraphicsContext.h" + #include "Renderer/Renderer.h" #include "Platform/OpenGL/OpenGLContext.h" diff --git a/Engine/src/Renderer/GraphicsContext.h b/Engine/src/Renderer/RHI/GraphicsContext.h similarity index 100% rename from Engine/src/Renderer/GraphicsContext.h rename to Engine/src/Renderer/RHI/GraphicsContext.h diff --git a/Engine/src/Renderer/RHI/RenderTarget.cpp b/Engine/src/Renderer/RHI/RenderTarget.cpp new file mode 100644 index 0000000..58246e2 --- /dev/null +++ b/Engine/src/Renderer/RHI/RenderTarget.cpp @@ -0,0 +1,33 @@ +#include "RenderTarget.h" + +#include "Renderer/Renderer.h" +#include "RendererAPI.h" +#include "Texture.h" + +#include "Platform/OpenGL/OpenGLRenderTarget.h" + +namespace elv { + +void RenderTarget::BindColorTexture(const int slot) const +{ + m_colorTextureAttachment->BindToSlot(slot); +} +std::shared_ptr RenderTarget::GetColorTextureAttachment() const +{ + return m_colorTextureAttachment; +} + +UniquePtr RenderTarget::Create() +{ + switch (Renderer::GetAPI()) { + case RendererAPI::API::None: + EL_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); + return nullptr; + case RendererAPI::API::OpenGL: + return MakeUniquePtr(); + } + + EL_CORE_ASSERT(false, "Unknown RendererAPI!"); + return nullptr; +} +} // namespace elv diff --git a/Engine/src/Renderer/RHI/RenderTarget.h b/Engine/src/Renderer/RHI/RenderTarget.h new file mode 100644 index 0000000..c275d11 --- /dev/null +++ b/Engine/src/Renderer/RHI/RenderTarget.h @@ -0,0 +1,39 @@ +#pragma once + +namespace elv { + +class Texture; + +class RenderTarget { +public: + struct Size { + std::uint32_t Width { 0 }; + std::uint32_t Height { 0 }; + }; + +public: + RenderTarget() = default; + virtual ~RenderTarget() = default; + + virtual void Init(const std::uint32_t width, const std::uint32_t height, bool isMultisampled = false) = 0; + virtual void Bind() const = 0; + virtual void Unbind() const = 0; + virtual void BindDraw() const = 0; + virtual void BindRead() const = 0; + virtual void Resize(const std::uint32_t width, const std::uint32_t height) = 0; + virtual void Blit(const UniquePtr& src) = 0; + + void BindColorTexture(const int slot) const; + std::shared_ptr GetColorTextureAttachment() const; + const Size& GetSize() const { return m_size; } + + static UniquePtr Create(); + +protected: + bool m_isMultisampled { false }; + Size m_size; + std::shared_ptr m_colorTextureAttachment { nullptr }; + std::shared_ptr m_depthStencilAttachment { nullptr }; +}; + +} // namespace elv diff --git a/Engine/src/Renderer/RendererAPI.cpp b/Engine/src/Renderer/RHI/RendererAPI.cpp similarity index 93% rename from Engine/src/Renderer/RendererAPI.cpp rename to Engine/src/Renderer/RHI/RendererAPI.cpp index 80d5eab..4af7d9f 100644 --- a/Engine/src/Renderer/RendererAPI.cpp +++ b/Engine/src/Renderer/RHI/RendererAPI.cpp @@ -1,4 +1,4 @@ -#include "Renderer/RendererAPI.h" +#include "RendererAPI.h" #include "Platform/OpenGL/OpenGLRendererAPI.h" diff --git a/Engine/src/Renderer/RendererAPI.h b/Engine/src/Renderer/RHI/RendererAPI.h similarity index 87% rename from Engine/src/Renderer/RendererAPI.h rename to Engine/src/Renderer/RHI/RendererAPI.h index da10312..b697d3d 100644 --- a/Engine/src/Renderer/RendererAPI.h +++ b/Engine/src/Renderer/RHI/RendererAPI.h @@ -1,8 +1,9 @@ #pragma once -#include "RenderTopology.h" #include "VertexArray.h" +#include "Renderer/RenderTopology.h" + namespace elv { class RendererAPI { @@ -19,8 +20,10 @@ class RendererAPI { virtual void SetViewport(std::uint32_t x, std::uint32_t y, std::uint32_t width, std::uint32_t height) = 0; virtual void SetClearColor(const lia::vec4& color) = 0; virtual void Clear() = 0; + virtual void ClearColorBit() = 0; virtual void EnableDepthTesting(bool enabled) = 0; virtual void EnableMSAA(bool enabled) = 0; + virtual void EnableFaceculling(bool enabled) = 0; virtual void DisableByteAlignment() = 0; virtual void DrawIndexed(const SharedPtr& vertexArray, const std::uint32_t indexCount = 0, const RenderTopology topology = RenderTopology::Triangles) = 0; diff --git a/Engine/src/Renderer/Shader.cpp b/Engine/src/Renderer/RHI/Shader.cpp similarity index 98% rename from Engine/src/Renderer/Shader.cpp rename to Engine/src/Renderer/RHI/Shader.cpp index b368458..915ad32 100644 --- a/Engine/src/Renderer/Shader.cpp +++ b/Engine/src/Renderer/RHI/Shader.cpp @@ -1,7 +1,8 @@ -#include "Renderer/Shader.h" -#include "Core/FileSystem.h" +#include "Shader.h" + #include "Renderer/Renderer.h" +#include "Core/FileSystem.h" #include "Platform/OpenGL/OpenGLShader.h" namespace elv { diff --git a/Engine/src/Renderer/Shader.h b/Engine/src/Renderer/RHI/Shader.h similarity index 98% rename from Engine/src/Renderer/Shader.h rename to Engine/src/Renderer/RHI/Shader.h index cf5fc27..efb62aa 100644 --- a/Engine/src/Renderer/Shader.h +++ b/Engine/src/Renderer/RHI/Shader.h @@ -1,4 +1,5 @@ #pragma once +#include namespace elv { diff --git a/Engine/src/Renderer/RHI/Texture.h b/Engine/src/Renderer/RHI/Texture.h new file mode 100644 index 0000000..858e3f9 --- /dev/null +++ b/Engine/src/Renderer/RHI/Texture.h @@ -0,0 +1,47 @@ +#pragma once + +namespace elv { + +class Texture { +public: + enum class WrappingMode { + Repeat, + MirroredRepeat, + ClampToEdge, + ClampToBorder + }; + + enum class InternalFormat { + RGBA8, + RGB8, + R8, + DepthStencil + }; + + enum class DataType { + UnsignedByte, + UnsignedInt32 + }; + + struct Info { + InternalFormat InternalFormat { InternalFormat::RGBA8 }; + DataType DataType { DataType::UnsignedByte }; + WrappingMode WrapS { WrappingMode::ClampToEdge }; + WrappingMode WrapT { WrappingMode::ClampToEdge }; + WrappingMode WrapR { WrappingMode::ClampToEdge }; + + bool Multisampled { false }; + }; + +public: + virtual ~Texture() = default; + + virtual void BindToSlot(std::uint32_t slot) = 0; + virtual void Unbind() = 0; + virtual void SetData(void* data, bool generateMipmap = true) = 0; + virtual void SetWrappingMode(const WrappingMode wrappingMode) = 0; + + virtual std::uint32_t GetId() const = 0; +}; + +} // namespace elv diff --git a/Engine/src/Renderer/VertexArray.cpp b/Engine/src/Renderer/RHI/VertexArray.cpp similarity index 87% rename from Engine/src/Renderer/VertexArray.cpp rename to Engine/src/Renderer/RHI/VertexArray.cpp index 1a74bf9..2d8e9cd 100644 --- a/Engine/src/Renderer/VertexArray.cpp +++ b/Engine/src/Renderer/RHI/VertexArray.cpp @@ -1,5 +1,9 @@ -#include "Renderer/VertexArray.h" +#include "VertexArray.h" + +#include "Buffer.h" + #include "Renderer/Renderer.h" +#include "RendererAPI.h" #include "Platform/OpenGL/OpenGLVertexArray.h" diff --git a/Engine/src/Renderer/VertexArray.h b/Engine/src/Renderer/RHI/VertexArray.h similarity index 92% rename from Engine/src/Renderer/VertexArray.h rename to Engine/src/Renderer/RHI/VertexArray.h index 8151994..e07c418 100644 --- a/Engine/src/Renderer/VertexArray.h +++ b/Engine/src/Renderer/RHI/VertexArray.h @@ -1,8 +1,8 @@ #pragma once -#include "Renderer/Buffer.h" - namespace elv { +class VertexBuffer; +class IndexBuffer; class VertexArray { public: diff --git a/Engine/src/Renderer/RenderCommand.h b/Engine/src/Renderer/RenderCommand.h index 599d15f..78cba39 100644 --- a/Engine/src/Renderer/RenderCommand.h +++ b/Engine/src/Renderer/RenderCommand.h @@ -1,6 +1,6 @@ #pragma once -#include "Renderer/RendererAPI.h" +#include "Renderer/RHI/RendererAPI.h" namespace elv { @@ -30,6 +30,11 @@ class RenderCommand { s_RendererAPI->Clear(); } + static void ClearColorBit() + { + s_RendererAPI->ClearColorBit(); + } + static void EnableDepthTesting(bool enable) { s_RendererAPI->EnableDepthTesting(enable); diff --git a/Engine/src/Renderer/Renderer.cpp b/Engine/src/Renderer/Renderer.cpp index f3d7c03..8c6c582 100644 --- a/Engine/src/Renderer/Renderer.cpp +++ b/Engine/src/Renderer/Renderer.cpp @@ -1,54 +1,138 @@ #include "Renderer/Renderer.h" #include "Mesh.h" +#include "RHI/Buffer.h" + +#include "Resources/TextureManager.h" namespace elv { -UniquePtr Renderer::m_sceneData = MakeUniquePtr(); -lia::vec4 Renderer::m_clearColor { 0.2f, 0.2f, 0.2f, 1.0f }; +Renderer::Renderer() + : m_rendererAPI(RendererAPI::Create()) + , m_renderTargetMultisampled(RenderTarget::Create()) + , m_renderTargetIntermidiate(RenderTarget::Create()) +{ +} -void Renderer::Init() +void Renderer::Init(const uint16_t width, const uint16_t height) { - RenderCommand::Init(); - RenderCommand::EnableDepthTesting(true); + m_rendererAPI->SetViewport(0, 0, width, height); + + m_renderTargetMultisampled->Init(width, height, true); + m_renderTargetIntermidiate->Init(width, height, false); + + m_screenQuadShader = ShaderManager::Load("screen_quad", "quad.vert", "quad.frag"); + m_NDCPlaneVao = VertexArray::Create(); + + float quadData[] = { + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f + }; + SharedPtr vbo = VertexBuffer::Create(&quadData[0], sizeof(quadData)); + vbo->SetLayout({ { BufferAttributeType::Float2 }, // pos + { BufferAttributeType::Float2 } }); // uv + + m_NDCPlaneVao->AddVertexBuffer(vbo); + + std::uint32_t quadIndices[] = { + 0, 1, 2, // first Triangle + 0, 2, 3 // second Triangle + }; + + SharedPtr ebo = IndexBuffer::Create(&quadIndices[0], sizeof(quadIndices)); + m_NDCPlaneVao->SetIndexBuffer(ebo); + + m_rendererAPI->Init(); } void Renderer::Shutdown() { - RenderCommand::Shutdown(); } -void Renderer::BeginScene(Camera& camera) +void Renderer::BeginScene(SharedPtr& cameraController) { - m_sceneData->ViewProjectionMatrix = camera.GetViewProjectionMatrix(); + // 1. Render pass: draw to separate render target + if (m_isMSAAEnabled) { + m_renderTargetMultisampled->Bind(); + } else { + m_renderTargetIntermidiate->Bind(); + } + + m_rendererAPI->EnableDepthTesting(true); + m_rendererAPI->SetClearColor(Renderer::GetClearColor()); + m_rendererAPI->Clear(); + + if (cameraController) { + m_sceneData.ViewProjectionMatrix = cameraController->GetCamera().GetViewProjectionMatrix(); + } } void Renderer::EndScene() { + // 2. Render pass: blit the multisampled to the intermediate render target + if (m_isMSAAEnabled) { + m_renderTargetIntermidiate->Blit(m_renderTargetMultisampled); + } + + // 3. Render pass: draw on screen + m_renderTargetIntermidiate->Unbind(); + + m_rendererAPI->EnableDepthTesting(false); + m_rendererAPI->SetClearColor(Renderer::GetClearColor()); + m_rendererAPI->ClearColorBit(); + + m_screenQuadShader->Bind(); + m_renderTargetIntermidiate->BindColorTexture(0); + m_screenQuadShader->SetInteger("u_screenTexture", 0); + + m_rendererAPI->DrawIndexed(m_NDCPlaneVao); } void Renderer::Submit(const SharedPtr& shader, const SharedPtr& vertexArray, const lia::mat4& modelMatrix) { - shader->SetMatrix4("u_ViewProjection", m_sceneData->ViewProjectionMatrix); + shader->SetMatrix4("u_ViewProjection", m_sceneData.ViewProjectionMatrix); shader->SetMatrix4("u_Model", modelMatrix); - RenderCommand::DrawIndexed(vertexArray); + m_rendererAPI->DrawIndexed(vertexArray); } void Renderer::Submit(const SharedPtr& shader, const SharedPtr& mesh, const lia::mat4& modelMatrix) { if (mesh) { - - shader->SetMatrix4("u_ViewProjection", m_sceneData->ViewProjectionMatrix); + shader->SetMatrix4("u_ViewProjection", m_sceneData.ViewProjectionMatrix); shader->SetMatrix4("u_Model", modelMatrix); - mesh->Draw(shader); + mesh->Draw(this, shader); } else { EL_CORE_ERROR("Failed to render mesh: is empty"); } } +void Renderer::Submit(const SharedPtr& vertexArray, std::uint32_t indexCount, const RenderTopology topology) +{ + m_rendererAPI->DrawIndexed(vertexArray, indexCount); +} + void Renderer::OnWindowResize(std::uint32_t width, std::uint32_t height) { - RenderCommand::SetViewport(0, 0, width, height); + m_renderTargetMultisampled->Resize(width, height); + m_renderTargetIntermidiate->Resize(width, height); + m_rendererAPI->SetViewport(0, 0, width, height); +} +void Renderer::EnableDepthTesting(bool enabled) +{ + m_rendererAPI->EnableDepthTesting(enabled); +} + +void Renderer::EnableMSAA(bool enabled) +{ + m_isMSAAEnabled = enabled; + m_rendererAPI->EnableMSAA(enabled); +} + +void Renderer::DisableByteAlignment() +{ + m_rendererAPI->DisableByteAlignment(); } } // namespace elv diff --git a/Engine/src/Renderer/Renderer.h b/Engine/src/Renderer/Renderer.h index bd868c0..a419250 100644 --- a/Engine/src/Renderer/Renderer.h +++ b/Engine/src/Renderer/Renderer.h @@ -1,38 +1,60 @@ #pragma once -#include "Renderer/Camera.h" -#include "Renderer/RenderCommand.h" -#include "Shader.h" +#include "CameraController.h" +#include "RHI/RenderTarget.h" +#include "RHI/RendererAPI.h" +#include "RHI/Shader.h" namespace elv { class Mesh; +class RenderTarget; +class VertexArray; class Renderer { +private: + struct SceneData { + lia::mat4 ViewProjectionMatrix; + }; + public: - static void Init(); - static void Shutdown(); + Renderer(); - static void BeginScene(Camera& camera); - static void EndScene(); + void Init(const uint16_t width, const uint16_t height); + void Shutdown(); - static void Submit(const SharedPtr& shader, const SharedPtr& vertexArray, const lia::mat4& modelMatrix = lia::mat4(1.0f)); - static void Submit(const SharedPtr& shader, const SharedPtr& mesh, const lia::mat4& modelMatrix = lia::mat4(1.0f)); + void BeginScene(SharedPtr& cameraController); + void Submit(const SharedPtr& shader, const SharedPtr& vertexArray, const lia::mat4& modelMatrix = lia::mat4(1.0f)); + void Submit(const SharedPtr& shader, const SharedPtr& mesh, const lia::mat4& modelMatrix = lia::mat4(1.0f)); + void Submit(const SharedPtr& vertexArray, std::uint32_t indexCount = 0, const RenderTopology topology = RenderTopology::Triangles); + void EndScene(); - static void OnWindowResize(std::uint32_t width, std::uint32_t height); + void OnWindowResize(std::uint32_t width, std::uint32_t height); - static RendererAPI::API GetAPI() { return RendererAPI::GetAPI(); } + void EnableDepthTesting(bool enabled); + void DisableByteAlignment(); - static void SetClearColor(const lia::vec4& color) { m_clearColor = color; } - static const lia::vec4& GetClearColor() { return m_clearColor; } + void SetClearColor(const lia::vec4& color) { m_clearColor = color; } + const lia::vec4& GetClearColor() { return m_clearColor; } + + void EnableMSAA(bool enabled); + bool IsMSAAEnabled() const { return m_isMSAAEnabled; } + + static RendererAPI::API GetAPI() { return RendererAPI::GetAPI(); } private: - struct SceneData { - lia::mat4 ViewProjectionMatrix; - }; + bool m_isMSAAEnabled { true }; + + SceneData m_sceneData; + lia::vec4 m_clearColor { 0.2f, 0.2f, 0.2f, 1.0f }; + + UniquePtr m_rendererAPI { nullptr }; + + UniquePtr m_renderTargetMultisampled { nullptr }; + UniquePtr m_renderTargetIntermidiate { nullptr }; - static UniquePtr m_sceneData; - static lia::vec4 m_clearColor; + SharedPtr m_screenQuadShader { nullptr }; + SharedPtr m_NDCPlaneVao { nullptr }; }; } // namespace elv diff --git a/Engine/src/Renderer/Renderer2D.cpp b/Engine/src/Renderer/Renderer2D.cpp index 657fcd9..09ecabe 100644 --- a/Engine/src/Renderer/Renderer2D.cpp +++ b/Engine/src/Renderer/Renderer2D.cpp @@ -1,8 +1,10 @@ #include "Renderer2D.h" -#include "Renderer/RenderCommand.h" -#include "Renderer/Shader.h" -#include "Renderer/VertexArray.h" +#include "Renderer/RHI/Buffer.h" +#include "Renderer/RHI/Shader.h" +#include "Renderer/RHI/VertexArray.h" +#include "Renderer/Renderer.h" + #include "Resources/TextureManager.h" #include "Core/FileSystem.h" @@ -35,7 +37,7 @@ struct Renderer2DData { QuadVertex* quadVerticesBegin { nullptr }; QuadVertex* quadVerticesCurrent { nullptr }; uint32_t quadIndexCount = 0; - std::array, MAX_TEXTURE_SLOTS> textures; + std::array, MAX_TEXTURE_SLOTS> textures; uint32_t usedTextureSlots = 1; // white texture const lia::vec4 quadPositions[4] = { @@ -53,10 +55,12 @@ struct Renderer2DData { }; Renderer2DData Renderer2D::s_data; +Renderer* Renderer2D::s_rendererPtr = nullptr; Renderer2D::Telemetry Renderer2D::s_telemetry; -void Renderer2D::Init() +void Renderer2D::Init(Renderer* renderer) { + s_rendererPtr = renderer; s_data.quadVAO = VertexArray::Create(); s_data.quadVerticesBegin = new QuadVertex[MAX_QUAD_VERTICES]; @@ -90,7 +94,7 @@ void Renderer2D::Init() s_data.shader = ShaderManager::Load("sprite", "sprite.vert", "sprite.frag"); // Textures - SharedPtr whiteTexture = textures::Get("white"); + SharedPtr whiteTexture = textures::Get("white"); s_data.textures[0] = std::move(whiteTexture); } @@ -121,10 +125,10 @@ void Renderer2D::Flush() s_data.shader->SetMatrix4("u_ViewProjection", s_data.viewProjectionMat); for (std::uint32_t i = 0; i < s_data.usedTextureSlots; ++i) { - s_data.textures[i]->BindToUnit(i); + s_data.textures[i]->BindToSlot(i); } - RenderCommand::DrawIndexed(s_data.quadVAO, s_data.quadIndexCount); + s_rendererPtr->Submit(s_data.quadVAO, s_data.quadIndexCount); s_telemetry.drawCalls++; } @@ -147,7 +151,7 @@ void Renderer2D::DrawQuad(const lia::vec3& pos, const lia::vec3& scale, float ro DrawQuad(pos, scale, rotation, color, 0); } -void Renderer2D::DrawQuad(const SharedPtr& texture, const lia::vec3& pos, const lia::vec3& scale, float rotation, const lia::vec4& color) +void Renderer2D::DrawQuad(const SharedPtr& texture, const lia::vec3& pos, const lia::vec3& scale, float rotation, const lia::vec4& color) { if (s_data.usedTextureSlots >= MAX_TEXTURE_SLOTS) { NextBatch(); diff --git a/Engine/src/Renderer/Renderer2D.h b/Engine/src/Renderer/Renderer2D.h index 9f7283a..70d0b76 100644 --- a/Engine/src/Renderer/Renderer2D.h +++ b/Engine/src/Renderer/Renderer2D.h @@ -4,9 +4,10 @@ namespace elv { +class Renderer; class VertexArray; class Shader; -class Texture2D; +class Texture; struct Renderer2DData; class Renderer2D { @@ -17,7 +18,7 @@ class Renderer2D { }; public: - static void Init(); + static void Init(Renderer* renderer); static void Shutdown(); static void BeginScene(const Camera& camera); @@ -31,7 +32,7 @@ class Renderer2D { * @param angle Rotation angle around Z axis in degrees */ static void DrawQuad(const lia::vec3& pos, const lia::vec3& scale, float rotation, const lia::vec4& color = lia::vec4(1.0f)); - static void DrawQuad(const SharedPtr& texture, const lia::vec3& pos, const lia::vec3& scale, float rotation, const lia::vec4& color = lia::vec4(1.0f)); + static void DrawQuad(const SharedPtr& texture, const lia::vec3& pos, const lia::vec3& scale, float rotation, const lia::vec4& color = lia::vec4(1.0f)); static Telemetry GetTelemetry() { return s_telemetry; } @@ -41,6 +42,7 @@ class Renderer2D { private: static Renderer2DData s_data; + static Renderer* s_rendererPtr; static Telemetry s_telemetry; }; diff --git a/Engine/src/Renderer/TextRenderer.cpp b/Engine/src/Renderer/TextRenderer.cpp index 3ce81e6..ffc0b22 100644 --- a/Engine/src/Renderer/TextRenderer.cpp +++ b/Engine/src/Renderer/TextRenderer.cpp @@ -1,15 +1,16 @@ #include "TextRenderer.h" -#include "RenderCommand.h" -#include "Renderer/Buffer.h" -#include "Renderer/VertexArray.h" -#include "Resources/FontManager.h" -#include "Resources/TextureManager.h" -#include "Shader.h" -#include "Texture2D.h" +#include "RHI/Buffer.h" +#include "RHI/Shader.h" +#include "RHI/Texture.h" +#include "RHI/VertexArray.h" #include "Core/Application.h" #include "Core/Window.h" + +#include "Resources/FontManager.h" +#include "Resources/TextureManager.h" + #include "Scene/Components/SceneComponents.h" #include "Scene/SceneManager.h" @@ -55,7 +56,7 @@ static lia::vec2 FromUiToCameraPos(const lia::vec2& pos, const OrthoCameraBounds cameraBounds.top - ((pos.y - uiRectMin) * cameraRangeY / uiRange) }; } -void TextRenderer::Init() +void TextRenderer::Init(Renderer& renderer) { s_data.shader = ShaderManager::Load("text2d", "text2d.vert", "text2d.frag"); @@ -77,7 +78,7 @@ void TextRenderer::Init() s_data.vao->SetIndexBuffer(ebo); // disable byte-alignment restriction - RenderCommand::DisableByteAlignment(); + renderer.DisableByteAlignment(); } void TextRenderer::PreRender(const Camera& camera) @@ -89,7 +90,7 @@ void TextRenderer::PreRender(const Camera& camera) s_data.pixelToCamera = GetPixelToCameraVec(s_data.cameraBounds); } -void TextRenderer::RenderText(std::string_view text, const std::string& fontName, const lia::vec2& pos, const lia::vec2& scale, lia::vec4 color) +void TextRenderer::RenderText(Renderer& renderer, std::string_view text, const std::string& fontName, const lia::vec2& pos, const lia::vec2& scale, lia::vec4 color) { const auto& glyphs = gFontManager.GetGlyphs(fontName); @@ -138,9 +139,9 @@ void TextRenderer::RenderText(std::string_view text, const std::string& fontName s_data.vbo->SetData(vertices, sizeof(vertices)); - glyph.texture->BindToUnit(0); + glyph.texture->BindToSlot(0); - RenderCommand::DrawIndexed(s_data.vao, quadIndexCount); + renderer.Submit(s_data.vao, quadIndexCount); // now advance cursors for next glyph currentGlyphPosX += s_data.pixelToCamera.x * scale.x * static_cast(glyph.advance >> 6); // bitshift by 6 to get value in pixels (1/64th times 2^6 = 64) diff --git a/Engine/src/Renderer/TextRenderer.h b/Engine/src/Renderer/TextRenderer.h index 2ebf3fb..71bafef 100644 --- a/Engine/src/Renderer/TextRenderer.h +++ b/Engine/src/Renderer/TextRenderer.h @@ -1,12 +1,15 @@ #pragma once #include "Camera.h" +#include "Renderer/Renderer.h" namespace elv { +class Renderer; + class TextRenderer { public: - static void Init(); + static void Init(Renderer& renderer); // Setting up projection matrix for the shader static void PreRender(const Camera& camera); @@ -17,6 +20,6 @@ class TextRenderer { * @param pos Fixed position (RectTransform) on the screen according to camera bounds ([0;0] is a left top position of the screen and [100;100] is the right bottom position) * */ - static void RenderText(std::string_view text, const std::string& fontName, const lia::vec2& pos, const lia::vec2& scale, lia::vec4 color = lia::vec4(1.0f)); + static void RenderText(Renderer& renderer, std::string_view text, const std::string& fontName, const lia::vec2& pos, const lia::vec2& scale, lia::vec4 color = lia::vec4(1.0f)); }; } // namespace elv diff --git a/Engine/src/Renderer/Texture2D.h b/Engine/src/Renderer/Texture2D.h deleted file mode 100644 index 44e69f1..0000000 --- a/Engine/src/Renderer/Texture2D.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -namespace elv { - -enum class TextureWrappingMode { - Repeat, - MirroredRepeat, - ClampToEdge, - ClampToBorder -}; - -class Texture2D { - -public: - virtual ~Texture2D() = default; - - virtual void BindToUnit(std::uint32_t unit) = 0; - virtual void Unbind() = 0; - virtual void SetData(void* data, bool generateMipmap = true) = 0; - virtual void SetWrappingMode(const TextureWrappingMode wrappingMode) = 0; -}; - -} // namespace elv diff --git a/Engine/src/Resources/FontManager.cpp b/Engine/src/Resources/FontManager.cpp index b263687..cd1839d 100644 --- a/Engine/src/Resources/FontManager.cpp +++ b/Engine/src/Resources/FontManager.cpp @@ -48,13 +48,13 @@ void FontManager::Load(const std::string& fontName, const std::string& fontPath) continue; } - SharedPtr texture { nullptr }; + SharedPtr texture { nullptr }; // don't create texture for the Space symbol if (c != 32) { const std::string textureName = fmt::format("{}{}{}", fontName, "text2d_glyph_", c); texture = textures::LoadUnique(textureName, face->glyph->bitmap.width, face->glyph->bitmap.rows, 1); - texture->SetWrappingMode(TextureWrappingMode::ClampToBorder); + texture->SetWrappingMode(Texture::WrappingMode::ClampToBorder); texture->SetData(face->glyph->bitmap.buffer); } diff --git a/Engine/src/Resources/FontManager.h b/Engine/src/Resources/FontManager.h index e847950..49eef54 100644 --- a/Engine/src/Resources/FontManager.h +++ b/Engine/src/Resources/FontManager.h @@ -2,10 +2,10 @@ namespace elv { -class Texture2D; +class Texture; struct Glyph { - SharedPtr texture { nullptr }; + SharedPtr texture { nullptr }; lia::vec2 size; // size of glyph lia::vec2 offset; // offset from baseline to left/top glyph uint32_t advance; // horizontal offset to advance to the next glyph diff --git a/Engine/src/Resources/MeshLibrary.cpp b/Engine/src/Resources/MeshLibrary.cpp index 43b6b65..52a8890 100644 --- a/Engine/src/Resources/MeshLibrary.cpp +++ b/Engine/src/Resources/MeshLibrary.cpp @@ -26,7 +26,7 @@ static void LoadMeshFromFile(std::vector& loadedMeshesInfo, co info.name = meshName; info.root = root; -#ifdef ASSIMP_MODE +#ifdef THREE_D_MODE ImportModel(meshPath, info); #endif diff --git a/Engine/src/Resources/ModelImporter.cpp b/Engine/src/Resources/ModelImporter.cpp index ce57b3b..b5ff877 100644 --- a/Engine/src/Resources/ModelImporter.cpp +++ b/Engine/src/Resources/ModelImporter.cpp @@ -1,6 +1,6 @@ #include "ModelImporter.h" -#if ASSIMP_MODE +#if THREE_D_MODE # include "Core/Profiler.h" diff --git a/Engine/src/Resources/TextureManager.cpp b/Engine/src/Resources/TextureManager.cpp index 9b69553..68de135 100644 --- a/Engine/src/Resources/TextureManager.cpp +++ b/Engine/src/Resources/TextureManager.cpp @@ -3,7 +3,7 @@ #include "Core/StringId.h" #include "Events/EventManager.h" #include "Events/TextureEvent.h" -#include "Platform/OpenGL/OpenGLTexture2D.h" +#include "Platform/OpenGL/OpenGLTexture.h" #include "Renderer/Renderer.h" #include "Core/Profiler.h" @@ -62,7 +62,7 @@ void TextureManager::Load(const std::string& textureName, const std::string& fil EL_CORE_INFO("Texture {0} is already loaded.", textureName); } -SharedPtr TextureManager::Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels, bool addToPool) +SharedPtr TextureManager::Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels, bool save) { // check whether we already loaded this texture auto it = m_textures.find(textureName); @@ -70,8 +70,8 @@ SharedPtr TextureManager::Load(const std::string& textureName, std::u if (it == m_textures.end()) { switch (Renderer::GetAPI()) { case RendererAPI::API::OpenGL: { - SharedPtr texture = MakeSharedPtr(width, height, nrChannels); - if (addToPool) { + SharedPtr texture = MakeSharedPtr(width, height, nrChannels); + if (save) { m_textures.insert({ textureName, texture }); } return texture; @@ -87,13 +87,25 @@ SharedPtr TextureManager::Load(const std::string& textureName, std::u return nullptr; } +SharedPtr TextureManager::Load(const std::uint32_t width, const std::uint32_t height, const Texture::Info& info) +{ + switch (Renderer::GetAPI()) { + case RendererAPI::API::OpenGL: + SharedPtr texture = MakeSharedPtr(width, height, info); + return texture; + } + + EL_CORE_ASSERT(false, "Unknown Renderer API!"); + return nullptr; +} + void TextureManager::Init() { - SharedPtr whiteTexture = Load("white", 1, 1, 3); + SharedPtr whiteTexture = Load("white", 1, 1, 3); unsigned char whiteData[] = { 255, 255, 255 }; // RGB format whiteTexture->SetData(&whiteData, false); - SharedPtr blackTexture = Load("black", 1, 1, 3); + SharedPtr blackTexture = Load("black", 1, 1, 3); unsigned char blackData[] = { 0, 0, 0 }; // RGB format blackTexture->SetData(&blackData, false); } @@ -130,7 +142,7 @@ void TextureManager::Shutdown() m_loadedInfo.clear(); } -SharedPtr TextureManager::Get(std::string_view textureName) +SharedPtr TextureManager::Get(std::string_view textureName) { auto it = m_textures.find(textureName.data()); return it != m_textures.end() ? it->second : nullptr; @@ -151,7 +163,7 @@ void TextureManager::CreateTexture(const LoadedTextureInfo& info) { switch (Renderer::GetAPI()) { case RendererAPI::API::OpenGL: { - SharedPtr texture = MakeSharedPtr(info.width, info.height, info.nrChannels); + SharedPtr texture = MakeSharedPtr(info.width, info.height, info.nrChannels); texture->SetData(info.data); m_textures.insert({ info.textureName, std::move(texture) }); diff --git a/Engine/src/Resources/TextureManager.h b/Engine/src/Resources/TextureManager.h index 63a9a8f..c09f447 100644 --- a/Engine/src/Resources/TextureManager.h +++ b/Engine/src/Resources/TextureManager.h @@ -1,6 +1,6 @@ #pragma once -#include "Renderer/Texture2D.h" +#include "Renderer/RHI/Texture.h" #include #include @@ -26,13 +26,14 @@ class TextureManager { void Load(const std::string& textureName, const std::string& filePath, const bool isAsync); // just create texture for specific texture implementation - SharedPtr Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels, bool AddToPool = true); + SharedPtr Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels, bool save = true); + SharedPtr Load(const std::uint32_t width, const std::uint32_t height, const Texture::Info& info); void Init(); void Update(); void Shutdown(); - SharedPtr Get(std::string_view textureName); + SharedPtr Get(std::string_view textureName); std::vector GetTextureNames() const; @@ -40,7 +41,7 @@ class TextureManager { void CreateTexture(const LoadedTextureInfo& info); private: - std::unordered_map> m_textures; + std::unordered_map> m_textures; std::vector m_loadedInfo; std::set m_textureLoadingInProgress; std::vector> m_futures; @@ -55,17 +56,22 @@ inline void Load(const std::string& textureName, const std::string& filePath, co gTextureManager.Load(textureName, filePath, async); } -inline SharedPtr Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels = 3) +inline SharedPtr Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels = 3) { return gTextureManager.Load(textureName, width, height, nrChannels); } -inline SharedPtr LoadUnique(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels = 3) +inline SharedPtr Load(std::uint32_t width, std::uint32_t height, const Texture::Info& info) +{ + return gTextureManager.Load(width, height, info); +} + +inline SharedPtr LoadUnique(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels = 3) { return gTextureManager.Load(textureName, width, height, nrChannels, false); } -inline SharedPtr Get(std::string_view textureName) +inline SharedPtr Get(std::string_view textureName) { return gTextureManager.Get(textureName); } diff --git a/Engine/src/Scene/Components/SceneComponents.h b/Engine/src/Scene/Components/SceneComponents.h index 75ba7c3..a37fdc0 100644 --- a/Engine/src/Scene/Components/SceneComponents.h +++ b/Engine/src/Scene/Components/SceneComponents.h @@ -18,7 +18,7 @@ struct QuadComponent { void to_json(nlohmann::json& j, const QuadComponent& t); void from_json(const nlohmann::json& j, QuadComponent& t); -class Texture2D; +class Texture; struct SpriteComponent { SpriteComponent() = default; @@ -60,7 +60,7 @@ struct SpriteComponent { public: std::string textureName; std::string texturePath; - SharedPtr texture { nullptr }; + SharedPtr texture { nullptr }; lia::vec4 color { 1.0f }; }; diff --git a/Engine/src/Scene/Scene.cpp b/Engine/src/Scene/Scene.cpp index 62ec91c..2e6476d 100644 --- a/Engine/src/Scene/Scene.cpp +++ b/Engine/src/Scene/Scene.cpp @@ -1,22 +1,18 @@ #include "Scene.h" -#include "Renderer/RenderCommand.h" -#include "Renderer/Renderer2D.h" -#include "Renderer/Texture2D.h" - #include "Core/Profiler.h" +#include "Core/SettingsConfig.h" #include "Components/LightComponent.h" #include "Components/SceneComponents.h" #include "Components/StaticMeshComponent.h" + #include "Systems/BehaviorSystem.h" #include "Systems/LightSystem.h" #include "Systems/Physics2dSystem.h" #include "Systems/Render2dSystem.h" #include "Systems/RenderSystem.h" -#include "Core/SettingsConfig.h" - namespace elv { void Scene::OnInit() { @@ -41,7 +37,7 @@ void Scene::OnInit() // Engine systems register RegisterSystem(); -#if ASSIMP_MODE +#ifdef THREE_D_MODE RegisterSystem(); #endif RegisterSystem(); diff --git a/Engine/src/Scene/Systems/Render2dSystem.cpp b/Engine/src/Scene/Systems/Render2dSystem.cpp index 18f76d5..d55d325 100644 --- a/Engine/src/Scene/Systems/Render2dSystem.cpp +++ b/Engine/src/Scene/Systems/Render2dSystem.cpp @@ -5,7 +5,7 @@ #include "Core/SettingsConfig.h" #include "Events/EventManager.h" #include "Events/TextureEvent.h" -#include "Renderer/RenderCommand.h" +#include "Renderer/Renderer.h" #include "Renderer/Renderer2D.h" #include "Renderer/TextRenderer.h" #include "Resources/FontManager.h" @@ -88,7 +88,9 @@ void Render2dSystem::OnRender(float dt) Renderer2D::EndScene(); // Text - RenderCommand::EnableDepthTesting(false); + auto& renderer = Application::Get().GetRenderer(); + renderer.EnableDepthTesting(false); + TextRenderer::PreRender(camera); auto& textComponents = m_textsPool->GetComponents(); for (uint32_t i = 0; i < textComponents.size(); ++i) { @@ -99,11 +101,10 @@ void Render2dSystem::OnRender(float dt) if (m_pScene->HasComponent(entity)) { auto& rectTransform = m_rectTransformPool->GetComponent(entity); - TextRenderer::RenderText(textComponent.text, textComponent.fontName, rectTransform.pos, rectTransform.scale, textComponent.color); + TextRenderer::RenderText(renderer, textComponent.text, textComponent.fontName, rectTransform.pos, rectTransform.scale, textComponent.color); } } } - - RenderCommand::EnableDepthTesting(true); + renderer.EnableDepthTesting(true); } } // namespace elv diff --git a/Engine/src/Scene/Systems/RenderSystem.cpp b/Engine/src/Scene/Systems/RenderSystem.cpp index 9575156..b2407f9 100644 --- a/Engine/src/Scene/Systems/RenderSystem.cpp +++ b/Engine/src/Scene/Systems/RenderSystem.cpp @@ -4,8 +4,8 @@ #include "Core/Profiler.h" #include "Renderer/CameraController.h" #include "Renderer/Mesh.h" +#include "Renderer/RHI/Shader.h" #include "Renderer/Renderer.h" -#include "Renderer/Shader.h" #include "Resources/MeshLibrary.h" #include "Scene/Components/LightComponent.h" #include "Scene/Components/StaticMeshComponent.h" @@ -22,6 +22,8 @@ void RenderSystem::OnInit() void RenderSystem::OnRender(float dt) { + auto& renderer = Application::Get().GetRenderer(); + auto cameraController = Application::Get().GetCameraController(); if (!cameraController) { EL_CORE_ERROR("Failed to find main camera"); @@ -29,8 +31,6 @@ void RenderSystem::OnRender(float dt) } auto& camera = cameraController->GetCamera(); - Renderer::BeginScene(camera); - m_shader->Bind(); m_shader->SetVector3f("u_ViewPos", camera.GetPosition()); @@ -126,7 +126,7 @@ void RenderSystem::OnRender(float dt) m_shader->SetMatrix4("u_NormalModel", transform.normalMatrix); const auto& meshPtr = meshComponent.GetMeshPtr(); if (meshPtr) { - Renderer::Submit(m_shader, meshPtr, transform.modelMatrix); + renderer.Submit(m_shader, meshPtr, transform.modelMatrix); } } } @@ -154,7 +154,7 @@ void RenderSystem::OnRender(float dt) m_lightShader->SetVector3f("u_Color.ambient", pointLight.ambient); m_lightShader->SetVector3f("u_Color.diffuse", pointLight.diffuse); - Renderer::Submit(m_lightShader, m_debugLightMesh, transform.modelMatrix); + renderer.Submit(m_lightShader, m_debugLightMesh, transform.modelMatrix); } } } @@ -172,12 +172,10 @@ void RenderSystem::OnRender(float dt) m_lightShader->SetVector3f("u_Color.ambient", spotlight.ambient); m_lightShader->SetVector3f("u_Color.diffuse", spotlight.diffuse); - Renderer::Submit(m_lightShader, m_debugLightMesh, transform.modelMatrix); + renderer.Submit(m_lightShader, m_debugLightMesh, transform.modelMatrix); } } } } - - Renderer::EndScene(); } } // namespace elv diff --git a/Engine/vendor/CMakeLists.txt b/Engine/vendor/CMakeLists.txt index a2f679f..9bfb9c5 100644 --- a/Engine/vendor/CMakeLists.txt +++ b/Engine/vendor/CMakeLists.txt @@ -17,6 +17,7 @@ add_subdirectory(spdlog) add_subdirectory(stb) add_subdirectory(freetype) add_subdirectory(fmt) +add_subdirectory(imgui) # reset flag to build assimp dll set(BUILD_SHARED_LIBS ON) add_subdirectory(assimp) \ No newline at end of file diff --git a/Engine/vendor/imgui/CMakeLists.txt b/Engine/vendor/imgui/CMakeLists.txt index 8365914..222b030 100644 --- a/Engine/vendor/imgui/CMakeLists.txt +++ b/Engine/vendor/imgui/CMakeLists.txt @@ -11,8 +11,8 @@ add_library(imgui STATIC ${IMGUI_SOURCES}) set(INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/Engine/vendor/GLFW/include - ${CMAKE_SOURCE_DIR}/Engine/vendor/GLAD/include + ${CMAKE_SOURCE_DIR}/GLFW/include + ${CMAKE_SOURCE_DIR}/GLAD/include ) target_include_directories(imgui PUBLIC ${INCLUDE_DIRS}) \ No newline at end of file diff --git a/Engine/vendor/imgui/src/imgui_impl_opengl3.cpp b/Engine/vendor/imgui/src/imgui_impl_opengl3.cpp index 1d93d97..4104d75 100644 --- a/Engine/vendor/imgui/src/imgui_impl_opengl3.cpp +++ b/Engine/vendor/imgui/src/imgui_impl_opengl3.cpp @@ -607,7 +607,7 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects() "varying vec4 Frag_Color;\n" "void main()\n" "{\n" - " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" + " gl_FragColor = Frag_Color * Texture(Texture, Frag_UV.st);\n" "}\n"; const GLchar* fragment_shader_glsl_130 = "uniform sampler2D Texture;\n" diff --git a/Games/CMakeLists.txt b/Games/CMakeLists.txt index 00581c6..cf53da1 100644 --- a/Games/CMakeLists.txt +++ b/Games/CMakeLists.txt @@ -1,4 +1,4 @@ -if (NOT ASSIMP_MODE) +if (NOT THREE_D_MODE) add_subdirectory(TRON) add_subdirectory(Pong) add_subdirectory(Invaders) diff --git a/Games/Invaders/CMakeLists.txt b/Games/Invaders/CMakeLists.txt index 2ae4eb9..e091df5 100644 --- a/Games/Invaders/CMakeLists.txt +++ b/Games/Invaders/CMakeLists.txt @@ -48,7 +48,7 @@ else() message("This is not supported platform for now!") endif() -set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/res) +set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/assets) add_custom_command(TARGET ${APP_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory diff --git a/Games/Pong/CMakeLists.txt b/Games/Pong/CMakeLists.txt index 6b154c3..e4e17b0 100644 --- a/Games/Pong/CMakeLists.txt +++ b/Games/Pong/CMakeLists.txt @@ -48,7 +48,7 @@ else() message("This is not supported platform for now!") endif() -set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/res) +set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/assets) add_custom_command(TARGET ${APP_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory diff --git a/Games/TRON/CMakeLists.txt b/Games/TRON/CMakeLists.txt index b2daeb6..7e2d401 100644 --- a/Games/TRON/CMakeLists.txt +++ b/Games/TRON/CMakeLists.txt @@ -48,7 +48,7 @@ else() message("This is not supported platform for now!") endif() -set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/res) +set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/assets) add_custom_command(TARGET ${APP_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory diff --git a/README.md b/README.md index baeebb2..1e1cb3b 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,15 @@ Elven Engine is primarily a 2D/3D game engine that is being developed from scrat ## Features + [x] Logging system + [x] Event system (non-blocking event queue-based system, described architecture in the [article](https://denyskryvytskyi.github.io/event-system)) -+ [x] Custom math library ([lia](https://github.com/denyskryvytskyi/lia)) -+ [x] Renderer core (graphics API agnostic) - - [x] Shaders loading - - [x] Async textures loading - - [x] Buffers, Shader, Texture abstractions ++ [x] Custom 3D math library ([lia](https://github.com/denyskryvytskyi/lia)) ++ [x] Renderer Core + - [x] RHI (Render Hardware Interface): Buffers, Shader, Texture, Render Target + - [x] Graphics API agnostic Renderer API + - [x] Modern OpenGL (with Direct State Access) specific Renderer API implementation + - [x] Shader loading + - [x] Async texture loading - [x] Camera (orthographic, perspective) - - [x] DSA OpenGL Renderer implementation - - [x] Fullscreen switch support + - [x] Render Passes based on Render Targets + [ ] 2D Renderer - [x] Quad rendering - [x] Texture rendering @@ -33,8 +34,9 @@ Elven Engine is primarily a 2D/3D game engine that is being developed from scrat - [x] Mesh-Material system (Static mesh support with one material slot per mesh/submesh for now) - [x] Primitives: cube, sphere, plane - [x] Async 3D model loading and async material textures loading + - [x] Render Target + - [x] MSAA (Multisample anti-alising) - [ ] Uniform buffer - - [ ] Framebuffer - [ ] Cubemap - [ ] Shadows + [x] ECS (investigated different techniques and my particular architecture in the [article](https://denyskryvytskyi.github.io/ecs)) @@ -64,6 +66,7 @@ Elven Engine is primarily a 2D/3D game engine that is being developed from scrat - [x] Telemetry: performance panel - [ ] Graphics stats + [x] Just cool stuff + - [x] Fullscreen switch support - [x] Orthographic camera controller (OrthographicCameraController), that can be used if needed - [x] Fly(FPS-like) 3D camera support (CameraController) + [ ] Multithreading support @@ -109,7 +112,7 @@ You can modify configure file to enable/disable the following cmake options: - **BUILD_GAMES** (default ON): Enable Games build - **PROFILE_MODE** (default ON): Enable Profiling (`PROFILE_MODE` preprocessor definition will be added) - **EDITOR_MODE** (default ON): Enable Editor (`EDITOR_MODE` preprocessor definition will be added) -- **ASSIMP_MODE** (default ON): Enable Assimp library for 3D model loading (`ASSIMP_MODE` preprocessor definition will be added). **IMPORTANT**: ON - only Sandbox3D project will be configured, OFF - only Sandbox2D and Games projects will be configured. +- **THREE_D_MODE** (default ON): Enable 3D mode and Assimp library for 3D model loading (`THREE_D_MODE` preprocessor definition will be added). **IMPORTANT**: ON - only Sandbox3D project will be configured, OFF - only Sandbox2D and Games projects will be configured. ## Third-party libraries | Lib | | diff --git a/Sandbox2D/CMakeLists.txt b/Sandbox2D/CMakeLists.txt index fa76ed5..bb1a0a6 100644 --- a/Sandbox2D/CMakeLists.txt +++ b/Sandbox2D/CMakeLists.txt @@ -46,7 +46,7 @@ else() message("This is not supported platform for now!") endif() -set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/res) +set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/assets) add_custom_command(TARGET ${APP_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory diff --git a/Sandbox2D/src/SandboxApp.cpp b/Sandbox2D/src/SandboxApp.cpp index b18fadf..9d55f0d 100644 --- a/Sandbox2D/src/SandboxApp.cpp +++ b/Sandbox2D/src/SandboxApp.cpp @@ -108,7 +108,7 @@ void Sandbox2D::OnTextureLoaded(const elv::events::TextureLoadedEvent& e) elv::Scene& scene = elv::GetScene(); - const elv::SharedPtr texture = elv::textures::Get("wizard_fire"); + const elv::SharedPtr texture = elv::textures::Get("wizard_fire"); for (size_t i = 0; i < 100; ++i) { for (size_t j = 0; j < 100; ++j) { diff --git a/Sandbox3D/CMakeLists.txt b/Sandbox3D/CMakeLists.txt index 003a698..387abbb 100644 --- a/Sandbox3D/CMakeLists.txt +++ b/Sandbox3D/CMakeLists.txt @@ -56,7 +56,7 @@ else() message("This is not supported platform for now!") endif() -set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/res) +set(RES_COMMON_PATH ${PROJECT_SOURCE_DIR}/Engine/assets) add_custom_command(TARGET ${APP_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory diff --git a/Sandbox3D/src/MeshModelSandbox.cpp b/Sandbox3D/src/MeshModelSandbox.cpp index de393d8..cfb5f76 100644 --- a/Sandbox3D/src/MeshModelSandbox.cpp +++ b/Sandbox3D/src/MeshModelSandbox.cpp @@ -153,7 +153,7 @@ void MeshModelSandbox::SetEnvironment(const int envIndex) const auto& env = kEnvironmenMaterials[envIndex]; - elv::Renderer::SetClearColor(env.clearColor); + m_renderer.SetClearColor(env.clearColor); // directional auto& dirLights = scene.GetComponents(); diff --git a/Sandbox3D/src/PrimitivesSandbox.cpp b/Sandbox3D/src/PrimitivesSandbox.cpp index b9a9188..c7d1a5a 100644 --- a/Sandbox3D/src/PrimitivesSandbox.cpp +++ b/Sandbox3D/src/PrimitivesSandbox.cpp @@ -136,6 +136,7 @@ void PrimitivesSandbox::OnImguiRender() ImGui::End(); } +#endif void PrimitivesSandbox::SetEnvironment(const int envIndex) { @@ -143,7 +144,7 @@ void PrimitivesSandbox::SetEnvironment(const int envIndex) const auto& env = kEnvironmenMaterials[envIndex]; - elv::Renderer::SetClearColor(env.clearColor); + m_renderer.SetClearColor(env.clearColor); // directional auto& dirLight = scene.GetComponent(m_dirLightEntity); @@ -166,4 +167,3 @@ void PrimitivesSandbox::SetEnvironment(const int envIndex) pointLight.specular = env.pointLightColors[i]; } } -#endif diff --git a/scripts/configure-vs2019.bat b/scripts/configure-vs2019.bat deleted file mode 100644 index a302195..0000000 --- a/scripts/configure-vs2019.bat +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -pushd %~dp0\..\ -call cmake -B build -G "Visual Studio 16 2019" -A x64 -D ASSIMP_MODE=ON -D BUILD_SANDBOX=ON -D BUILD_GAMES=ON -D EDITOR_MODE=ON -D PROFILE_MODE=ON >> scripts/configure.log -popd -PAUSE \ No newline at end of file diff --git a/scripts/configure-vs2022.bat b/scripts/configure-vs2022.bat index 2323cb1..facd5a1 100644 --- a/scripts/configure-vs2022.bat +++ b/scripts/configure-vs2022.bat @@ -1,5 +1,5 @@ @echo off pushd %~dp0\..\ -call cmake -B build -G "Visual Studio 17 2022" -A x64 -D ASSIMP_MODE=ON -D BUILD_SANDBOX=ON -D BUILD_GAMES=ON -D EDITOR_MODE=ON -D PROFILE_MODE=ON >> scripts/configure.log +call cmake -B build -G "Visual Studio 17 2022" -A x64 -D THREE_D_MODE=ON -D BUILD_SANDBOX=ON -D BUILD_GAMES=ON -D EDITOR_MODE=ON -D PROFILE_MODE=ON >> scripts/configure.log popd PAUSE \ No newline at end of file