diff --git a/.gitmodules b/.gitmodules index 9c48563..f0ab977 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,9 +16,6 @@ [submodule "external/stb"] path = external/stb url = https://github.com/nothings/stb.git -[submodule "external/predef"] - path = external/predef - url = https://github.com/boostorg/predef.git [submodule "external/entt"] path = external/entt url = https://github.com/skypjack/entt.git @@ -28,3 +25,6 @@ [submodule "external/sentry-native"] path = external/sentry-native url = https://github.com/getsentry/sentry-native.git +[submodule "external/magic-enum"] + path = external/magic-enum + url = https://github.com/Neargye/magic_enum.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 24ae5bd..376416f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,45 @@ set(CMAKE_CXX_STANDARD 17) option(TEMPEH_ENABLE_TEST "Test" OFF) add_subdirectory("external") + +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +# https://github.com/izenecloud/cmake/blob/master/SetCompilerWarningAll.cmake +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # Use the highest warning level for Visual Studio. + set(CMAKE_CXX_WARNING_LEVEL 4) + if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + else(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + endif(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") + # Disable C++ exceptions. + string(REGEX REPLACE "/EH[a-z]+" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") + # Disable RTTI. + string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-") +else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # Use -Wall for clang and gcc. + if(NOT CMAKE_CXX_FLAGS MATCHES "-Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + endif(NOT CMAKE_CXX_FLAGS MATCHES "-Wall") + # Use -Wextra for clang and gcc. + if(NOT CMAKE_CXX_FLAGS MATCHES "-Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra") + endif(NOT CMAKE_CXX_FLAGS MATCHES "-Wextra") + # Use -Werror for clang and gcc. + if(NOT CMAKE_CXX_FLAGS MATCHES "-Werror") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + endif(NOT CMAKE_CXX_FLAGS MATCHES "-Werror") + # Disable C++ exceptions. + string(REGEX REPLACE "-fexceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") + # Disable RTTI. + string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") +endif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + add_subdirectory("engine") add_subdirectory("editor") add_subdirectory("test") diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 551d8e7..0d9cd1b 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -1,52 +1,44 @@ set(TEMPEH_ENGINE_EDITOR_HEADERS - "src/window/window.hpp" - "src/core/application.hpp" "src/renderer/render_context.hpp" - - "src/event/event.hpp" + "src/renderer/gui.hpp" "src/renderer/gui_imgui_renderer.hpp" "src/renderer/gui_renderer.hpp" "src/renderer/editor_camera.hpp" - "src/window/keycode_glfw.hpp" "src/renderer/gui_imgui_renderer.cpp") set(TEMPEH_ENGINE_EDITOR_SOURCES - "${CMAKE_SOURCE_DIR}/external/imgui/backends/imgui_impl_wgpu.cpp" - "${CMAKE_SOURCE_DIR}/external/imgui/backends/imgui_impl_glfw.cpp" - "src/main.cpp" - "${CMAKE_SOURCE_DIR}/external/imgui/backends/imgui_impl_wgpu.cpp" - "${CMAKE_SOURCE_DIR}/external/imgui/backends/imgui_impl_glfw.cpp" "src/core/application.cpp" "src/renderer/render_context.cpp" - "src/window/window_glfw.cpp" - "src/window/input_manager.cpp" - "${CMAKE_SOURCE_DIR}/external/imgui/backends/imgui_impl_wgpu.cpp" "${CMAKE_SOURCE_DIR}/external/imgui/backends/imgui_impl_glfw.cpp") add_executable("tempeh_engine_editor" ${TEMPEH_ENGINE_EDITOR_SOURCES} - ${TEMPEH_ENGINE_EDITOR_HEADERS}) + ${TEMPEH_ENGINE_EDITOR_HEADERS} + "src/gui/panel.hpp" + "src/gui/panels/scene_panel.hpp" + "src/gui/panels/scene_panel.cpp" + "src/gui/window_menubar_panel.cpp" + "src/gui/window_menubar_panel.hpp") target_compile_definitions("tempeh_engine_editor" PUBLIC SENTRY_DSN="https://8e07fe63b9c94200a0926d0d28b54ad2@o1113293.ingest.sentry.io/6143604") target_include_directories("tempeh_engine_editor" #PUBLIC "../common" - PUBLIC "${CMAKE_SOURCE_DIR}/external/dawn/src/utils" + PUBLIC "${CMAKE_SOURCE_DIR}/external/dawn/src" PUBLIC "$ENV{MONO_INCLUDE_DIR}" PUBLIC ${TEMPEH_COMMON_INCLUDE}) target_link_libraries("tempeh_engine_editor" # Private, because anyone ain't gonna touch the editor PRIVATE "glfw" - PRIVATE "boost_predef" PRIVATE "tempeh_common" PRIVATE "tempeh_core" PRIVATE "tempeh_log" diff --git a/editor/src/core/application.cpp b/editor/src/core/application.cpp index 34b0120..fb3a051 100644 --- a/editor/src/core/application.cpp +++ b/editor/src/core/application.cpp @@ -3,13 +3,13 @@ #include //#include #include -#include "../window/window_glfw.hpp" +#include namespace TempehEditor::Core { - - Application::Application(): - input_manager(std::make_shared()), - window(std::make_shared(input_manager)), + + Application::Application() : + input_manager(std::make_shared()), + window(std::make_shared(input_manager)), render_context(std::make_shared(window)) { //sentry_options_t* options = sentry_options_new(); @@ -27,8 +27,10 @@ namespace TempehEditor::Core { { while (!window->is_need_to_close()) { + input_manager->clear(); window->process_input(*input_manager); - render_context->frame_start(window); + + render_context->frame_start(window, *input_manager); render_context->render(); } return APPLICATION_RETURN_SUCCESS; diff --git a/editor/src/core/application.hpp b/editor/src/core/application.hpp index 327e523..ce896cd 100644 --- a/editor/src/core/application.hpp +++ b/editor/src/core/application.hpp @@ -4,7 +4,8 @@ #define APPLICATION_RETURN_SUCCESS 0 #include -#include "../window/window.hpp" +#include +#include #include "../renderer/render_context.hpp" #include "../renderer/gui.hpp" @@ -14,8 +15,8 @@ namespace TempehEditor::Core class Application { private: - std::shared_ptr input_manager; - std::shared_ptr window; + std::shared_ptr input_manager; + std::shared_ptr window; std::shared_ptr render_context; std::shared_ptr gui; diff --git a/editor/src/event/event.hpp b/editor/src/event/event.hpp deleted file mode 100644 index 250544c..0000000 --- a/editor/src/event/event.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef _TEMPEH_EDITOR_EVENT_INPUT_MANAGER_HPP -#define _TEMPEH_EDITOR_EVENT_INPUT_MANAGER_HPP - -#include -#include - -namespace Tempeh::Event -{ - - class Event - { - private: - public: - virtual const char* get_type(); - - enum class Type : u8 - { - None = 0, - KeyPress, KeyRelease, - MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseScrolled, - WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved, - }; - - enum class Category : u8 - { - None = 0, - Keyboard = bit(1), - Mouse = bit(2), - MouseButton = bit(3), - Window = bit(4), - }; - }; - -#define TEMPEH_EVENT_CLASS_TYPE(type) static Event::Type get_type() const { return Event::type } - - class MouseButton : public Event - { - private: - - public: - MouseButton() {} - }; - - class MouseMoved : public Event - { - private: - Tempeh::Math::vec2 mouse_delta; - public: - MouseMoved() {} - - TEMPEH_EVENT_CLASS_TYPE(MouseMoved) - }; - - class Dispatcher - { - private: - Event& event; - public: - Dispatcher(Event& event) : event(event) {} - }; - -} - -#endif diff --git a/editor/src/gui/panel.hpp b/editor/src/gui/panel.hpp new file mode 100644 index 0000000..c00d733 --- /dev/null +++ b/editor/src/gui/panel.hpp @@ -0,0 +1,12 @@ +#ifndef _TEMPEH_EDITOR_GUI_PANEL_HPP +#define _TEMPEH_EDITOR_GUI_PANEL_HPP + +#include + +INTERFACE class Panel +{ +public: + virtual void draw() = 0; +}; + +#endif diff --git a/editor/src/gui/panels/scene_panel.cpp b/editor/src/gui/panels/scene_panel.cpp new file mode 100644 index 0000000..4597611 --- /dev/null +++ b/editor/src/gui/panels/scene_panel.cpp @@ -0,0 +1,24 @@ +#include "../panel.hpp" + +#include + +#include "scene_panel.hpp" + +namespace TempehEditor::GUI::Panels +{ + + void ScenePanel::draw() + { + ImGui::Begin("#Scene Panel"); + //ImVec2 pos = ImGui::GetCursorScreenPos(); + //ImGui::GetWindowDrawList()->AddImage( + // (void*)window.getRenderTexture(), + // ImVec2(ImGui::GetCursorScreenPos()), + // ImVec2(ImGui::GetCursorScreenPos().x + window.getWidth() / 2, + // ImGui::GetCursorScreenPos().y + window.getHeight() / 2), + // ImVec2(0, 1), + // ImVec2(1, 0)); + ImGui::End(); + } + +} diff --git a/editor/src/gui/panels/scene_panel.hpp b/editor/src/gui/panels/scene_panel.hpp new file mode 100644 index 0000000..1aeaa2c --- /dev/null +++ b/editor/src/gui/panels/scene_panel.hpp @@ -0,0 +1,19 @@ +#ifndef _TEMPEH_EDITOR_GUI_PANELS_SCENE_HPP +#define _TEMPEH_EDITOR_GUI_PANELS_SCENE_HPP + +#include "../panel.hpp" + +#include + +namespace TempehEditor::GUI::Panels +{ + + class ScenePanel : public Panel + { + private: + void draw() override; + }; + +} + +#endif diff --git a/editor/src/gui/window_menubar_panel.cpp b/editor/src/gui/window_menubar_panel.cpp new file mode 100644 index 0000000..010410a --- /dev/null +++ b/editor/src/gui/window_menubar_panel.cpp @@ -0,0 +1,37 @@ +#include "panel.hpp" +#include "window_menubar_panel.hpp" + +#include + +namespace TempehEditor::GUI::Panels +{ + + void WindowMenubarPanel::draw() + { + if (ImGui::BeginMainMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + if (ImGui::MenuItem("Close", "Blabla")) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Edit")) + { + if (ImGui::MenuItem("Blabla", "Blabla")) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("View")) + { + if (ImGui::MenuItem("Blabla", "Blabla")) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Help")) + { + if (ImGui::MenuItem("Blabla", "Blabla")) {} + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } + } + +} diff --git a/editor/src/gui/window_menubar_panel.hpp b/editor/src/gui/window_menubar_panel.hpp new file mode 100644 index 0000000..1e6e843 --- /dev/null +++ b/editor/src/gui/window_menubar_panel.hpp @@ -0,0 +1,19 @@ +#ifndef _TEMPEH_EDITOR_GUI_PANELS_SCENE_HPP +#define _TEMPEH_EDITOR_GUI_PANELS_SCENE_HPP + +#include "panel.hpp" + +#include + +namespace TempehEditor::GUI::Panels +{ + + class WindowMenubarPanel : public Panel + { + public: + void draw() override; + }; + +} + +#endif diff --git a/editor/src/renderer/gui_imgui_renderer.cpp b/editor/src/renderer/gui_imgui_renderer.cpp index d9f2329..bc342cb 100644 --- a/editor/src/renderer/gui_imgui_renderer.cpp +++ b/editor/src/renderer/gui_imgui_renderer.cpp @@ -7,22 +7,35 @@ #include #include "render_context.hpp" +#include +#include "../gui/window_menubar_panel.hpp" +#include namespace TempehEditor::Renderer::GUI { - GUIImGuiRenderer::GUIImGuiRenderer(std::shared_ptr window, TempehEditor::Renderer::RenderContext* render_context) : + GUIImGuiRenderer::GUIImGuiRenderer(std::shared_ptr window, TempehEditor::Renderer::RenderContext* render_context) : render_context(render_context) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); - io = ImGui::GetIO(); (void)io; + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; io.IniFilename = nullptr; - ImGui::StyleColorsClassic(); + + ImGui::StyleColorsLight(); + + ImGuiStyle& style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } switch (window->get_window_type()) { - case TempehEditor::Window::WindowType::GLFW: + case Tempeh::Window::WindowType::GLFW: ImGui_ImplGlfw_InitForOther(static_cast(window->get_raw_handle()), true); break; default: @@ -34,32 +47,34 @@ namespace TempehEditor::Renderer::GUI ImGui_ImplWGPU_Init(device.Get(), 3, WGPUTextureFormat_BGRA8Unorm); } - void GUIImGuiRenderer::frame_start(std::shared_ptr window) + void GUIImGuiRenderer::frame_start(std::shared_ptr window, Tempeh::Event::InputManager& input_manager) { - int wa, ha; - glfwGetFramebufferSize(static_cast(window->get_raw_handle()), &wa, &ha); - if (wa != w || ha != h) - { - h = ha; - w = wa; - ImGui_ImplWGPU_InvalidateDeviceObjects(); - render_context->get_swap_chain().Configure(wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::RenderAttachment, (u32)w, (u32)h); - ImGui_ImplWGPU_CreateDeviceObjects(); - LOG_INFO("size change"); - } - // TODO ImGui_ImplWGPU_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - ImGui::ShowDemoWindow(&a); + auto dock_space_id = ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); + + // https://github.com/ocornut/imgui/issues/2999 + + static TempehEditor::GUI::Panels::WindowMenubarPanel window_menubar_panel; + window_menubar_panel.draw(); + + ImGui::ShowDemoWindow(); + + ImGui::Begin("Left"); + ImGui::Text("Hello, left!"); + ImGui::End(); + + ImGui::Begin("Down"); + ImGui::Text("Hello, down!"); + ImGui::End(); } void GUIImGuiRenderer::render() { ImGui::Render(); - // TODO change color auto& device = render_context->get_device(); @@ -67,31 +82,35 @@ namespace TempehEditor::Renderer::GUI command_encoder_descriptor.nextInChain = nullptr; command_encoder_descriptor.label = "ImGui command encoder descriptor"; const auto command_encoder = device.CreateCommandEncoder(&command_encoder_descriptor); - - wgpu::RenderPassColorAttachment render_pass_color_attachment; - render_pass_color_attachment.view = render_context->get_swap_chain().GetCurrentTextureView(); - render_pass_color_attachment.resolveTarget = nullptr; - render_pass_color_attachment.loadOp = wgpu::LoadOp::Clear; - render_pass_color_attachment.storeOp = wgpu::StoreOp::Store; { - render_pass_color_attachment.clearColor.r = 1.0f; - render_pass_color_attachment.clearColor.g = 0.0f; - render_pass_color_attachment.clearColor.b = 0.0f; - render_pass_color_attachment.clearColor.a = 1.0f; + wgpu::RenderPassColorAttachment render_pass_color_attachment; + render_pass_color_attachment.view = render_context->get_swap_chain().GetCurrentTextureView(); + render_pass_color_attachment.resolveTarget = nullptr; + render_pass_color_attachment.loadOp = wgpu::LoadOp::Clear; + render_pass_color_attachment.storeOp = wgpu::StoreOp::Store; + { + render_pass_color_attachment.clearColor.r = 0.82f; + render_pass_color_attachment.clearColor.g = 0.82f; + render_pass_color_attachment.clearColor.b = 0.82f; + render_pass_color_attachment.clearColor.a = 1.0f; + } + + //wgpu::RenderPassDescriptor render_pass_descriptor; + //render_pass_descriptor.nextInChain = nullptr; + //render_pass_descriptor.label = "ImGui render pass descriptor"; + //render_pass_descriptor.colorAttachmentCount = 1; + //render_pass_descriptor.colorAttachments = &render_pass_color_attachment; + //render_pass_descriptor.depthStencilAttachment = nullptr; + //render_pass_descriptor.occlusionQuerySet = wgpu::QuerySet{}; + + utils::ComboRenderPassDescriptor render_pass_descriptor({ render_context->get_swap_chain().GetCurrentTextureView() }); + render_pass_descriptor.cColorAttachments[0] = render_pass_color_attachment; + + auto render_pass = command_encoder.BeginRenderPass(&render_pass_descriptor); + ImGui_ImplWGPU_RenderDrawData(ImGui::GetDrawData(), render_pass.Get()); + render_pass.EndPass(); } - wgpu::RenderPassDescriptor render_pass_descriptor; - render_pass_descriptor.nextInChain = nullptr; - render_pass_descriptor.label = "ImGui render pass descriptor"; - render_pass_descriptor.colorAttachmentCount = 1; - render_pass_descriptor.colorAttachments = &render_pass_color_attachment; - render_pass_descriptor.depthStencilAttachment = nullptr; - render_pass_descriptor.occlusionQuerySet = wgpu::QuerySet{}; - - auto render_pass = command_encoder.BeginRenderPass(&render_pass_descriptor); - ImGui_ImplWGPU_RenderDrawData(ImGui::GetDrawData(), render_pass.Get()); - render_pass.EndPass(); - wgpu::CommandBufferDescriptor command_buffer_descriptor; command_buffer_descriptor.nextInChain = nullptr; command_buffer_descriptor.label = "ImGui command buffer descriptor"; @@ -100,9 +119,14 @@ namespace TempehEditor::Renderer::GUI const auto queue = device.GetQueue(); queue.Submit(1, &commands); + { + GLFWwindow* backup_current_context = glfwGetCurrentContext(); + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + glfwMakeContextCurrent(backup_current_context); + } + render_context->get_swap_chain().Present(); } - - } \ No newline at end of file diff --git a/editor/src/renderer/gui_imgui_renderer.hpp b/editor/src/renderer/gui_imgui_renderer.hpp index 33060f9..8aa8dba 100644 --- a/editor/src/renderer/gui_imgui_renderer.hpp +++ b/editor/src/renderer/gui_imgui_renderer.hpp @@ -8,7 +8,7 @@ #include #include "gui.hpp" -#include "../window/window.hpp" +#include #include "gui_renderer.hpp" namespace TempehEditor::Renderer @@ -22,17 +22,15 @@ namespace TempehEditor::Renderer::GUI class GUIImGuiRenderer : public GUIRenderer { private: - ImGuiIO io; // TODO // Probably not a good practice, lets revisit this later bool a = true; - i32 w, h; std::shared_ptr render_context; public: - GUIImGuiRenderer(std::shared_ptr window, TempehEditor::Renderer::RenderContext* render_context); - - void frame_start(std::shared_ptr window); + GUIImGuiRenderer(std::shared_ptr window, TempehEditor::Renderer::RenderContext* render_context); + void frame_start(std::shared_ptr window, Tempeh::Event::InputManager& input_manager); + void resize_swapchain(); void render() override; }; diff --git a/editor/src/renderer/render_context.cpp b/editor/src/renderer/render_context.cpp index 700da50..b178c7e 100644 --- a/editor/src/renderer/render_context.cpp +++ b/editor/src/renderer/render_context.cpp @@ -4,12 +4,12 @@ #include #include #include -#include -#include +#include +#include //#include -#if defined(WIN32) +#if defined(TEMPEH_OS_WINDOWS) # define GLFW_EXPOSE_NATIVE_WIN32 -#elif defined(BOOST_OS_LINUX) +#elif defined(TEMPEH_OS_LINUX) # define GLFW_EXPOSE_NATIVE_X11 #else # error @@ -20,10 +20,12 @@ namespace TempehEditor::Renderer { - RenderContext::RenderContext(std::shared_ptr window) + RenderContext::RenderContext(std::shared_ptr window) { wgpu::BackendType backend = wgpu::BackendType::Vulkan; + + // TODO should be moved before window creation! if (backend == wgpu::BackendType::OpenGL || backend == wgpu::BackendType::OpenGLES) { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); @@ -134,10 +136,11 @@ namespace TempehEditor::Renderer error_type = "Unreachable"; } LOG_ERROR("wgpu Error [{}]: {}", error_type, message); + assert(false); }; device.SetUncapturedErrorCallback(uncaptured_error_callback, nullptr); - // auto binding = utils::CreateBinding(backend, static_cast(window->get_raw_handle()), device.Get()); + auto binding = utils::CreateBinding(backend, static_cast(window->get_raw_handle()), device.Get()); int w, h; glfwGetFramebufferSize(static_cast(window->get_raw_handle()), &w, &h); @@ -149,31 +152,54 @@ namespace TempehEditor::Renderer swap_chain_descriptor.width = (u32)w; swap_chain_descriptor.height = (u32)h; swap_chain_descriptor.presentMode = wgpu::PresentMode::Mailbox; - //.implementation = binding.GetSwapChainImplementation() - // .implementation = binding->GetSwapChainImplementation(),; + swap_chain_descriptor.implementation = binding->GetSwapChainImplementation(); ImGui_ImplWGPU_InvalidateDeviceObjects(); - main_swap_chain = device.CreateSwapChain(main_surface, &swap_chain_descriptor); + main_swap_chain = device.CreateSwapChain(nullptr, &swap_chain_descriptor); ImGui_ImplWGPU_CreateDeviceObjects(); + auto window_size = window->get_window_size(); + resize(window_size); + gui_renderer = std::make_shared(window, this); } std::unique_ptr RenderContext::get_surface_descriptor(GLFWwindow* window) const { -#if BOOST_OS_WINDOWS +#if defined(TEMPEH_OS_WINDOWS) std::unique_ptr desc = std::make_unique(); desc->hwnd = glfwGetWin32Window(window); desc->hinstance = GetModuleHandle(nullptr); return desc; -#elif BOOST_OS_LINUX +#elif defined(TEMPEH_OS_LINUX) std::unique_ptr desc = std::make_unique(); desc->display = glfwGetX11Display(); desc->window = glfwGetX11Window(window); return desc; +#else +# error #endif } + void RenderContext::resize(const Tempeh::Window::WindowSize& window_size) + { + this->window_size = window_size; + main_swap_chain.Configure(wgpu::TextureFormat::BGRA8Unorm, wgpu::TextureUsage::RenderAttachment, window_size.width, window_size.height); + } + void RenderContext::frame_start(std::shared_ptr window, + Tempeh::Event::InputManager& input_manager) + { + Tempeh::Event::Dispatcher dispatcher; + dispatcher.dispatch([&](const Tempeh::Event::Event& event) + { + Tempeh::Window::WindowSize new_window_size; + new_window_size.width = event.inner.window_resize.new_size.x; + new_window_size.height = event.inner.window_resize.new_size.y; + this->resize(new_window_size); + }); + input_manager.dispatch(dispatcher); + gui_renderer->frame_start(window, input_manager); } +} diff --git a/editor/src/renderer/render_context.hpp b/editor/src/renderer/render_context.hpp index c05cad5..4b1585c 100644 --- a/editor/src/renderer/render_context.hpp +++ b/editor/src/renderer/render_context.hpp @@ -4,19 +4,13 @@ #include #include #include -#include +#include #include "gui_imgui_renderer.hpp" namespace TempehEditor::Renderer { - struct WindowSize - { - u32 width; - u32 height; - }; - class RenderContext { private: @@ -27,18 +21,18 @@ namespace TempehEditor::Renderer wgpu::Surface main_surface; wgpu::SwapChain main_swap_chain; - WindowSize window_size; - + Tempeh::Window::WindowSize window_size; + std::shared_ptr gui_renderer; public: - explicit RenderContext(std::shared_ptr window); + explicit RenderContext(std::shared_ptr window); std::unique_ptr get_surface_descriptor(GLFWwindow* window) const; [[nodiscard]] const wgpu::Device& get_device() const { return device; } [[nodiscard]] const wgpu::SwapChain& get_swap_chain() const { return main_swap_chain; } //[[nodiscard]] const wgpu::Surface& get_main_surface() const { return surface; } - void resize(const WindowSize& window_size) { this->window_size = window_size; } - void frame_start(std::shared_ptr window) { gui_renderer->frame_start(window); } - void render() { gui_renderer->render(); } + void resize(const Tempeh::Window::WindowSize& window_size); + void frame_start(std::shared_ptr window, Tempeh::Event::InputManager& input_manager); + void render() const { gui_renderer->render(); } }; } diff --git a/editor/src/window/input_manager.cpp b/editor/src/window/input_manager.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/editor/src/window/input_manager.hpp b/editor/src/window/input_manager.hpp deleted file mode 100644 index df427a5..0000000 --- a/editor/src/window/input_manager.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _TEMPEH_EDITOR_WINDOW_INPUT_MANAGER_HPP -#define _TEMPEH_EDITOR_WINDOW_INPUT_MANAGER_HPP - -namespace TempehEditor::Window -{ - - class InputManager - { - - }; - -} - -#endif diff --git a/editor/src/window/window.hpp b/editor/src/window/window.hpp deleted file mode 100644 index 353e6e1..0000000 --- a/editor/src/window/window.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _TEMPEH_EDITOR_WINDOW_WINDOW -#define _TEMPEH_EDITOR_WINDOW_WINDOW - -#include - -#include "input_manager.hpp" - -namespace TempehEditor::Window { - - enum class WindowType: u8 - { - None, - GLFW - }; - - class Window - { - public: - virtual WindowType get_window_type() = 0; - virtual void set_title(const char* str) = 0; - virtual void* get_raw_handle() = 0; - virtual void process_input(InputManager& input_manager) = 0; - virtual bool is_need_to_close() = 0; - }; - -} - -#endif // _TEMPEH_EDITOR_WINDOW_WINDOW diff --git a/editor/src/window/window_glfw.cpp b/editor/src/window/window_glfw.cpp deleted file mode 100644 index 6ca46b8..0000000 --- a/editor/src/window/window_glfw.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include -#include - -#include "window_glfw.hpp" -#include "input_manager.hpp" - -namespace TempehEditor::Window { - - WindowGLFW::WindowGLFW(std::shared_ptr input_manager): - shared_state{std::move(input_manager)} - { - if (!glfwInit()) - throw std::runtime_error("Failed to initialize GLFW"); - - window = glfwCreateWindow(640, 480, "Dawn window", nullptr, nullptr); - if (!window) - throw std::runtime_error("Error window creation"); - - glfwSetErrorCallback([](int error, const char* description) - { - LOG_ERROR("GLFW error [{}]: {}", error, description); - }); - - glfwSetWindowUserPointer(window, static_cast(&shared_state)); - - //glfwSetWindowSizeCallback(window, [](GLFWwindow* window, i32 width, i32 height) - // { - // WindowGLFWSharedState& shared_state = *static_cast(glfwGetWindowUserPointer(window)); - // shared_state.input_manager. - // }); - } - - WindowGLFW::~WindowGLFW() - { - glfwDestroyWindow(window); - glfwTerminate(); - } - - void WindowGLFW::process_input(InputManager& input_manager) - { - glfwPollEvents(); - } - - -} diff --git a/engine/common/CMakeLists.txt b/engine/common/CMakeLists.txt index b0089f0..1b9e0d4 100644 --- a/engine/common/CMakeLists.txt +++ b/engine/common/CMakeLists.txt @@ -1,5 +1,8 @@ add_library(tempeh_common INTERFACE) target_include_directories( tempeh_common - INTERFACE - $) + INTERFACE $) +target_link_libraries( + tempeh_common + INTERFACE "magic_enum" +) diff --git a/engine/common/include/tempeh/common/os.hpp b/engine/common/include/tempeh/common/os.hpp new file mode 100644 index 0000000..e68563c --- /dev/null +++ b/engine/common/include/tempeh/common/os.hpp @@ -0,0 +1,29 @@ +#ifndef _TEMPEH_COMMON_OS_HPP +#define _TEMPEH_COMMON_OS_HPP + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +# define TEMPEH_OS_WINDOWS +#elif __APPLE__ +# include +# if TARGET_IPHONE_SIMULATOR +# error "Unimplemented" +# elif TARGET_OS_MACCATALYST +# error "Unimplemented" +# elif TARGET_OS_IPHONE +# error "Unimplemented" +# elif TARGET_OS_MAC +# error "Unimplemented" +# else +# error "Unknown Apple platform" +# endif +#elif __linux__ +# define TEMPEH_OS_LINUX +#elif __unix__ +# error "Unimplemented" +#elif defined(_POSIX_VERSION) +# error "Unimplemented" +#else +# error "Unknown compiler" +#endif + +#endif diff --git a/engine/common/sbstd.hpp b/engine/common/include/tempeh/common/sbstd.hpp similarity index 100% rename from engine/common/sbstd.hpp rename to engine/common/include/tempeh/common/sbstd.hpp diff --git a/engine/common/include/tempeh/common/typedefs.hpp b/engine/common/include/tempeh/common/typedefs.hpp index a50e915..ff7e633 100644 --- a/engine/common/include/tempeh/common/typedefs.hpp +++ b/engine/common/include/tempeh/common/typedefs.hpp @@ -1,3 +1,6 @@ +#ifndef _TEMPEH_COMMON_TYPEDEFS +#define _TEMPEH_COMMON_TYPEDEFS + #include using u8 = uint8_t; @@ -12,3 +15,5 @@ using f32 = float; using f64 = double; #define INTERFACE + +#endif diff --git a/engine/common/include/tempeh/common/util.hpp b/engine/common/include/tempeh/common/util.hpp index cbccf3c..299b53f 100644 --- a/engine/common/include/tempeh/common/util.hpp +++ b/engine/common/include/tempeh/common/util.hpp @@ -1,6 +1,8 @@ #ifndef _TEMPEH_UTIL_HPP #define _TEMPEH_UTIL_HPP +#include + template static inline constexpr T bit(T n) { diff --git a/engine/core/CMakeLists.txt b/engine/core/CMakeLists.txt index 0f3e6ef..d3538fc 100644 --- a/engine/core/CMakeLists.txt +++ b/engine/core/CMakeLists.txt @@ -7,8 +7,13 @@ if(NOT(DEFINED ENV{MONO_INCLUDE_DIR})) endif() add_library("tempeh_core" STATIC - "include/tempeh/scripting/mono.hpp" "src/scripting/mono.cpp" + "src/renderer/orthogonal_camera.cpp" + "src/renderer/perspective_camera.cpp" + "src/event/input_manager.cpp" + "src/window/window_glfw.cpp" + + "include/tempeh/scripting/mono.hpp" "include/tempeh/renderer/camera.hpp" "include/tempeh/renderer/backend/framebuffer.hpp" "include/tempeh/renderer/backend/texture.hpp" @@ -21,20 +26,20 @@ add_library("tempeh_core" STATIC "include/tempeh/application.hpp" "include/tempeh/renderer/orthogonal_camera.hpp" "include/tempeh/renderer/perspective_camera.hpp" - "src/renderer/orthogonal_camera.cpp" - "src/renderer/perspective_camera.cpp") + "include/tempeh/window/key_code_glfw.hpp") target_include_directories("tempeh_core" PUBLIC $ PUBLIC "$ENV{MONO_INCLUDE_DIR}" PUBLIC "${CMAKE_SOURCE_DIR}/external/glad/include" PUBLIC "${CMAKE_SOURCE_DIR}/engine/core/include" - PUBLIC "${CMAKE_SOURCE_DIR}/engine/common" PUBLIC "${Vulkan_INCLUDE_DIRS}" ) target_link_libraries("tempeh_core" PUBLIC "${Vulkan_LIBRARIES}" + PUBLIC "tempeh_common" PUBLIC "tempeh_math" + PUBLIC "tempeh_log" PUBLIC "glfw" ) diff --git a/engine/core/include/tempeh/event/dispatcher.hpp b/engine/core/include/tempeh/event/dispatcher.hpp new file mode 100644 index 0000000..3a6cf5b --- /dev/null +++ b/engine/core/include/tempeh/event/dispatcher.hpp @@ -0,0 +1,36 @@ +#ifndef _TEMPEH_EVENT_DISPATCHER_HPP +#define _TEMPEH_EVENT_DISPATCHER_HPP + +#include +#include +#include + +#include + +namespace Tempeh::Event +{ + + class Dispatcher + { + public: + using DispatchCallback = std::function; + using DispatchCallbacksWithType = std::vector>; + + template + void dispatch(DispatchCallback f) + { + m_dispatch_callbacks.push_back(std::make_pair(T, f)); + } + + const DispatchCallbacksWithType& get_dispatch_callbacks() + { + return m_dispatch_callbacks; + } + + private: + DispatchCallbacksWithType m_dispatch_callbacks; + }; + +} + +#endif diff --git a/engine/core/include/tempeh/event/event.hpp b/engine/core/include/tempeh/event/event.hpp new file mode 100644 index 0000000..cb72d5c --- /dev/null +++ b/engine/core/include/tempeh/event/event.hpp @@ -0,0 +1,91 @@ +#ifndef _TEMPEH_EVENT_EVENT_HPP +#define _TEMPEH_EVENT_EVENT_HPP + +#include +#include +#include +#include + +namespace Tempeh::Event +{ + enum class Type : u8 + { + None = 0, + + KeyboardButtonAct, + + MouseButtonAct, + MouseMove, + MouseScroll, + + WindowClose, + WindowResize, + WindowFocus, + WindowLostFocus, + WindowMoved, + }; + + // Should we use this? + //enum class Category : u8 + //{ + // None = 0, + // Keyboard = bit(1), + // Mouse = bit(2), + // MouseButton = bit(3), + // Window = bit(4), + //}; + + enum class KeyState : u8 + { + Pressed = 0, + Released = bit(1), + }; + + struct WindowClose {}; + struct WindowLostFocus {}; + struct WindowFocus {}; + struct WindowResize + { + Tempeh::Math::uvec2 new_size; + }; + struct MouseMove + { + Tempeh::Math::vec2 movement; + }; + struct MouseScroll + { + Tempeh::Math::vec2 delta; + }; + struct MouseButtonAct + { + MouseKeyCode key_code; + KeyState state; + }; + struct KeyboardButtonAct + { + KeyboardKeyCode key_code; + KeyState state; + }; + + struct Event + { + union TypeInner + { + WindowClose window_close; + WindowResize window_resize; + WindowLostFocus window_lost_focus; + WindowFocus window_focus; + KeyboardButtonAct keyboard_button_act; + MouseMove mouse_move; + MouseScroll mouse_scroll; + MouseButtonAct mouse_button_act; + }; + TypeInner inner; + Type type = Type::None; + // TODO category? + }; + + +} + +#endif diff --git a/engine/core/include/tempeh/event/input_manager.hpp b/engine/core/include/tempeh/event/input_manager.hpp new file mode 100644 index 0000000..4b031f8 --- /dev/null +++ b/engine/core/include/tempeh/event/input_manager.hpp @@ -0,0 +1,60 @@ +#ifndef _TEMPEH_EVENT_INPUT_MANAGER_HPP +#define _TEMPEH_EVENT_INPUT_MANAGER_HPP + +#include +#include +#include +#include + +#include +#include + +namespace Tempeh::Event +{ + + struct MouseButton + { + bool left = false; + bool middle = false; + bool right = false; + }; + + struct MouseState + { + MouseButton button; + Tempeh::Math::vec2 pos = Tempeh::Math::vec2(0.0f); + Tempeh::Math::vec2 delta_pos = Tempeh::Math::vec2(0.0f); + Tempeh::Math::vec2 scroll_offset = Tempeh::Math::vec2(0.0f); + }; + + class InputManager + { + private: + MouseState m_mouse_state; + std::unordered_set m_pressed_keyboard_key; + + std::vector m_events; + public: + // Record + void process_keyboard_button(KeyboardKeyCode key_code, KeyState key_state); + void process_mouse_button(MouseKeyCode key_code, KeyState key_state); + void process_event(Event& event); + + // Traditional + [[nodiscard]] bool is_key_pressed(KeyboardKeyCode key) const + { + return m_pressed_keyboard_key.find(key) != m_pressed_keyboard_key.end(); + }; + [[nodiscard]] const MouseState& get_mouse_state() const { return m_mouse_state; } + + // Event + void dispatch(Dispatcher& dispatcher) const; + + // INTERNAL USE ONLY + MouseState& get_mouse_state_mut() { return m_mouse_state; } + void clear(); + }; + +} + +#endif diff --git a/editor/src/window/keycode_glfw.hpp b/engine/core/include/tempeh/event/key_code.hpp similarity index 88% rename from editor/src/window/keycode_glfw.hpp rename to engine/core/include/tempeh/event/key_code.hpp index a2d5f50..58a9c0b 100644 --- a/editor/src/window/keycode_glfw.hpp +++ b/engine/core/include/tempeh/event/key_code.hpp @@ -1,9 +1,23 @@ -namespace Tempeh::Window +#ifndef _TEMPEH_EVENT_KEY_CODE_HPP +#define _TEMPEH_EVENT_KEY_CODE_HPP + +namespace Tempeh::Event { - enum class GLFWKeyCode + enum MouseKeyCode : u8 + { + Left = 0, + Right, + Middle, + Other1, + Other2, + Other3, + Other4, + Other6 + }; + + enum class KeyboardKeyCode : u16 { - // From glfw3.h Space = 32, Apostrophe = 39, /* ' */ Comma = 44, /* , */ @@ -137,3 +151,6 @@ namespace Tempeh::Window }; } + + +#endif diff --git a/engine/core/include/tempeh/window/key_code_glfw.hpp b/engine/core/include/tempeh/window/key_code_glfw.hpp new file mode 100644 index 0000000..329362f --- /dev/null +++ b/engine/core/include/tempeh/window/key_code_glfw.hpp @@ -0,0 +1,162 @@ +#ifndef _TEMPEH_WINDOW_KEYCODE_GLFW_HPP +#define _TEMPEH_WINDOW_KEYCODE_GLFW_HPP + +#include +#include + +namespace Tempeh::Window +{ + + enum class GLFWKeyCode : i32 + { + // From glfw3.h + Space = 32, + Apostrophe = 39, /* ' */ + Comma = 44, /* , */ + Minus = 45, /* - */ + Period = 46, /* . */ + Slash = 47, /* / */ + + D0 = 48, /* 0 */ + D1 = 49, /* 1 */ + D2 = 50, /* 2 */ + D3 = 51, /* 3 */ + D4 = 52, /* 4 */ + D5 = 53, /* 5 */ + D6 = 54, /* 6 */ + D7 = 55, /* 7 */ + D8 = 56, /* 8 */ + D9 = 57, /* 9 */ + + Semicolon = 59, /* ; */ + Equal = 61, /* = */ + + A = 65, + B = 66, + C = 67, + D = 68, + E = 69, + F = 70, + G = 71, + H = 72, + I = 73, + J = 74, + K = 75, + L = 76, + M = 77, + N = 78, + O = 79, + P = 80, + Q = 81, + R = 82, + S = 83, + T = 84, + U = 85, + V = 86, + W = 87, + X = 88, + Y = 89, + Z = 90, + + LeftBracket = 91, /* [ */ + Backslash = 92, /* \ */ + RightBracket = 93, /* ] */ + GraveAccent = 96, /* ` */ + + World1 = 161, /* non-US #1 */ + World2 = 162, /* non-US #2 */ + + /* Function keys */ + Escape = 256, + Enter = 257, + Tab = 258, + Backspace = 259, + Insert = 260, + Delete = 261, + Right = 262, + Left = 263, + Down = 264, + Up = 265, + PageUp = 266, + PageDown = 267, + Home = 268, + End = 269, + CapsLock = 280, + ScrollLock = 281, + NumLock = 282, + PrintScreen = 283, + Pause = 284, + F1 = 290, + F2 = 291, + F3 = 292, + F4 = 293, + F5 = 294, + F6 = 295, + F7 = 296, + F8 = 297, + F9 = 298, + F10 = 299, + F11 = 300, + F12 = 301, + F13 = 302, + F14 = 303, + F15 = 304, + F16 = 305, + F17 = 306, + F18 = 307, + F19 = 308, + F20 = 309, + F21 = 310, + F22 = 311, + F23 = 312, + F24 = 313, + F25 = 314, + + /* Keypad */ + KP0 = 320, + KP1 = 321, + KP2 = 322, + KP3 = 323, + KP4 = 324, + KP5 = 325, + KP6 = 326, + KP7 = 327, + KP8 = 328, + KP9 = 329, + KPDecimal = 330, + KPDivide = 331, + KPMultiply = 332, + KPSubtract = 333, + KPAdd = 334, + KPEnter = 335, + KPEqual = 336, + + LeftShift = 340, + LeftControl = 341, + LeftAlt = 342, + LeftSuper = 343, + RightShift = 344, + RightControl = 345, + RightAlt = 346, + RightSuper = 347, + Menu = 348 + }; + + Event::KeyboardKeyCode keyboard_key_code_from_glfw_key_code(int key) + { + return static_cast(key); + } + + Event::KeyState key_state_from_glfw_action(int action) + { + return static_cast(action); + } + + Event::MouseKeyCode mouse_key_code_from_glfw_key_code(int key) + { + return static_cast(key); + } + +} + +#endif diff --git a/engine/core/include/tempeh/window/window.hpp b/engine/core/include/tempeh/window/window.hpp new file mode 100644 index 0000000..05f0693 --- /dev/null +++ b/engine/core/include/tempeh/window/window.hpp @@ -0,0 +1,34 @@ +#ifndef _TEMPEH_EDITOR_WINDOW_WINDOW_HPP +#define _TEMPEH_EDITOR_WINDOW_WINDOW_HPP + +#include +#include + +namespace Tempeh::Window { + + enum class WindowType : u8 + { + None, + GLFW + }; + + struct WindowSize + { + u32 width; + u32 height; + }; + + class Window + { + public: + virtual WindowType get_window_type() = 0; + virtual void set_title(const char* str) = 0; + virtual void* get_raw_handle() = 0; + virtual void process_input(Event::InputManager& input_manager) = 0; + virtual bool is_need_to_close() = 0; + virtual WindowSize get_window_size() = 0; + }; + +} + +#endif diff --git a/editor/src/window/window_glfw.hpp b/engine/core/include/tempeh/window/window_glfw.hpp similarity index 55% rename from editor/src/window/window_glfw.hpp rename to engine/core/include/tempeh/window/window_glfw.hpp index 5b8a51b..eba3221 100644 --- a/editor/src/window/window_glfw.hpp +++ b/engine/core/include/tempeh/window/window_glfw.hpp @@ -4,15 +4,15 @@ #include #include -#include "window.hpp" -#include "input_manager.hpp" +#include +#include -namespace TempehEditor::Window +namespace Tempeh::Window { struct WindowGLFWSharedState { - std::shared_ptr input_manager; + std::shared_ptr input_manager; }; class WindowGLFW : public Window @@ -21,14 +21,23 @@ namespace TempehEditor::Window GLFWwindow* window; WindowGLFWSharedState shared_state; public: - WindowGLFW(std::shared_ptr input_manager); + WindowGLFW(std::shared_ptr input_manager); ~WindowGLFW(); void set_title(const char* str) override { glfwSetWindowTitle(window, str); } void* get_raw_handle() override { return static_cast(window); } - void process_input(InputManager& input_manager) override; + void process_input(Event::InputManager& input_manager) override; WindowType get_window_type() override { return WindowType::GLFW; } bool is_need_to_close() override { return glfwWindowShouldClose(window); } + WindowSize get_window_size() override { + int width; + int height; + glfwGetWindowSize(window, &width, &height); + WindowSize window_size; + window_size.width = width; + window_size.height = height; + return window_size; + } }; } #endif // _TEMPEH_EDITOR_WINDOW_WINDOWGLFW_HPP \ No newline at end of file diff --git a/engine/core/src/event/input_manager.cpp b/engine/core/src/event/input_manager.cpp new file mode 100644 index 0000000..701bf6e --- /dev/null +++ b/engine/core/src/event/input_manager.cpp @@ -0,0 +1,72 @@ +#include +#include +#include + +namespace Tempeh::Event +{ + void InputManager::clear() + { + m_events.clear(); + m_mouse_state = {}; + } + + void InputManager::process_event(Event& event) + { + if (event.type != Type::MouseMove) LOG_INFO("{}", magic_enum::enum_name(event.type)); + m_events.push_back(event); + } + + void InputManager::process_keyboard_button(KeyboardKeyCode key_code, KeyState key_state) + { + LOG_INFO("Keyboard - Key {}({}) {}", magic_enum::enum_name(key_code), key_code, key_state == KeyState::Pressed ? "Pressed" : "Released"); + if (key_state == KeyState::Pressed) + { + + m_pressed_keyboard_key.insert(key_code); + } + else + { + m_pressed_keyboard_key.erase(key_code); + } + } + + void InputManager::process_mouse_button(MouseKeyCode key_code, KeyState key_state) + { + LOG_INFO("Mouse - Key {}({}) {}", magic_enum::enum_name(key_code), key_code, key_state == KeyState::Pressed ? "Pressed" : "Released"); + switch (key_code) + { + case Left: + m_mouse_state.button.left = true; + break; + case Middle: + m_mouse_state.button.middle = true; + break; + case Right: + m_mouse_state.button.right = true; + break; + default: + // TODO other mouse button + assert(false); + break; + } + } + + void InputManager::dispatch(Dispatcher& dispatcher) const + { + auto& dispatch_callbacks = dispatcher.get_dispatch_callbacks(); + for (auto& event : m_events) + { + for (auto& dispatch_callback : dispatch_callbacks) + { + if (dispatch_callback.first == event.type) + { + dispatch_callback.second(event); + // TODO + } + } + } + + } + + +} \ No newline at end of file diff --git a/engine/core/src/window/window_glfw.cpp b/engine/core/src/window/window_glfw.cpp new file mode 100644 index 0000000..616f7dc --- /dev/null +++ b/engine/core/src/window/window_glfw.cpp @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace Tempeh::Window { + + WindowGLFW::WindowGLFW(std::shared_ptr input_manager) : + shared_state{ std::move(input_manager) } + { + if (!glfwInit()) assert(false && "Failed to initialize GLFW"); + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_MAXIMIZED, GL_TRUE); + + window = glfwCreateWindow(640, 480, "Dawn window", nullptr, nullptr); + if (!window) assert(false && "Error window creation"); + + glfwSetErrorCallback([](int error, const char* description) + { + LOG_ERROR("GLFW error [{}]: {}", error, description); + assert(false); + }); + + glfwSetWindowUserPointer(window, static_cast(&shared_state)); + + glfwSetWindowSizeCallback(window, [](GLFWwindow* window, i32 width, i32 height) + { + Event::Event event; + event.type = Event::Type::WindowResize; + event.inner.window_resize.new_size = Tempeh::Math::uvec2( + static_cast(width), + static_cast(height) + ); + + const WindowGLFWSharedState& shared_state = *static_cast(glfwGetWindowUserPointer(window)); + shared_state.input_manager->process_event(event); + }); + glfwSetKeyCallback(window, [](GLFWwindow* window, i32 key, i32 scancode, i32 action, i32 mods) + { + const Event::KeyboardKeyCode key_code = keyboard_key_code_from_glfw_key_code(key); + const Event::KeyState key_state = key_state_from_glfw_action(action); + + Event::Event event; + event.type = Event::Type::KeyboardButtonAct; + event.inner.keyboard_button_act.state = key_state; + event.inner.keyboard_button_act.key_code = key_code; + + const WindowGLFWSharedState& shared_state = *static_cast(glfwGetWindowUserPointer(window)); + shared_state.input_manager->process_event(event); + shared_state.input_manager->process_keyboard_button(key_code, key_state); + }); + glfwSetMouseButtonCallback(window, [](GLFWwindow* window, i32 button, i32 action, i32 mods) + { + const Event::MouseKeyCode button_key_code = mouse_key_code_from_glfw_key_code(button); + const Event::KeyState key_state = key_state_from_glfw_action(action); + + Event::Event event; + event.type = Event::Type::KeyboardButtonAct; + event.inner.mouse_button_act.state = key_state; + event.inner.mouse_button_act.key_code = button_key_code; + + const WindowGLFWSharedState& shared_state = *static_cast(glfwGetWindowUserPointer(window)); + shared_state.input_manager->process_event(event); + shared_state.input_manager->process_mouse_button(button_key_code, key_state); + }); + glfwSetCursorPosCallback(window, [](GLFWwindow* window, f64 x, f64 y) + { + Event::Event event; + event.type = Event::Type::MouseMove; + event.inner.mouse_move.movement = Tempeh::Math::vec2(static_cast(x), static_cast(y)); + + const WindowGLFWSharedState& shared_state = *static_cast(glfwGetWindowUserPointer(window)); + shared_state.input_manager->process_event(event); + shared_state.input_manager->get_mouse_state_mut().pos = event.inner.mouse_move.movement; + }); + glfwSetScrollCallback(window, [](GLFWwindow* window, f64 x_offset, f64 y_offset) + { + Event::Event event; + event.type = Event::Type::MouseMove; + event.inner.mouse_scroll.delta = Tempeh::Math::vec2(static_cast(x_offset), static_cast(y_offset)); + + const WindowGLFWSharedState& shared_state = *static_cast(glfwGetWindowUserPointer(window)); + shared_state.input_manager->process_event(event); + shared_state.input_manager->get_mouse_state_mut().scroll_offset = event.inner.mouse_scroll.delta; + }); + glfwSetWindowFocusCallback(window, [](GLFWwindow* window, i32 focus) + { + Event::Event event; + event.type = (focus == GLFW_TRUE) ? Event::Type::WindowFocus : Event::Type::WindowLostFocus; + + const WindowGLFWSharedState& shared_state = *static_cast(glfwGetWindowUserPointer(window)); + shared_state.input_manager->process_event(event); + }); + glfwSetWindowCloseCallback(window, [](GLFWwindow* window) + { + Event::Event event; + event.type = Event::Type::WindowClose; + + const WindowGLFWSharedState& shared_state = *static_cast(glfwGetWindowUserPointer(window)); + shared_state.input_manager->process_event(event); + }); + } + + WindowGLFW::~WindowGLFW() + { + glfwDestroyWindow(window); + glfwTerminate(); + } + + void WindowGLFW::process_input(Event::InputManager& input_manager) + { + glfwPollEvents(); + } + + +} diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 3b60da6..d73eea2 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -9,13 +9,14 @@ set(BUILD_EXAMPLE OFF) set(DAWN_BUILD_EXAMPLES OFF) set(DAWN_ENABLE_D3D12 OFF) # Not stable yet! +#set(DAWN_ENABLE_VULKAN OFF) add_subdirectory("dawn") add_subdirectory("sentry-native") add_subdirectory("spdlog") add_subdirectory("entt") +add_subdirectory("magic-enum") add_subdirectory("glm") -add_subdirectory("predef") add_library("imgui" STATIC "imgui/imgui.cpp" diff --git a/external/dawn b/external/dawn index facbc82..1365885 160000 --- a/external/dawn +++ b/external/dawn @@ -1 +1 @@ -Subproject commit facbc82d6cffa924995dfe04bbd944858db4e75f +Subproject commit 1365885386a70456f61bfd20381a590e0bd35391 diff --git a/external/imgui b/external/imgui index e8172fd..27004ac 160000 --- a/external/imgui +++ b/external/imgui @@ -1 +1 @@ -Subproject commit e8172fdfbc003ba28b93905db980f384092faf86 +Subproject commit 27004aca705e33e8a88f368372628c28f1ee4cd1 diff --git a/external/magic-enum b/external/magic-enum new file mode 160000 index 0000000..3d1f6a5 --- /dev/null +++ b/external/magic-enum @@ -0,0 +1 @@ +Subproject commit 3d1f6a5a2a3fbcba077e00ad0ccc2dd9fefc2ca7 diff --git a/external/predef b/external/predef deleted file mode 160000 index 8e62bd0..0000000 --- a/external/predef +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8e62bd04dd313170f16c26dd08740e42042059a8 diff --git a/platform/android/app/src/main/cpp/external/dawn b/platform/android/app/src/main/cpp/external/dawn index facbc82..1365885 160000 --- a/platform/android/app/src/main/cpp/external/dawn +++ b/platform/android/app/src/main/cpp/external/dawn @@ -1 +1 @@ -Subproject commit facbc82d6cffa924995dfe04bbd944858db4e75f +Subproject commit 1365885386a70456f61bfd20381a590e0bd35391