diff --git a/aurora/CMakeLists.txt b/aurora/CMakeLists.txt index 4f0c99b72..51bc733bd 100644 --- a/aurora/CMakeLists.txt +++ b/aurora/CMakeLists.txt @@ -14,7 +14,10 @@ add_library(aurora STATIC lib/imgui.cpp lib/dawn/BackendBinding.cpp lib/gfx/common.cpp + ../extern/imgui/backends/imgui_impl_sdl.cpp + ../extern/imgui/backends/imgui_impl_wgpu.cpp ) +target_compile_definitions(aurora PRIVATE IMGUI_USER_CONFIG="imconfig_user.h") # IMGUI_USE_WCHAR32 target_include_directories(aurora PUBLIC include ../Runtime) target_include_directories(aurora PRIVATE ../imgui ../extern/imgui) target_link_libraries(aurora PRIVATE dawn_native dawncpp webgpu_dawn zeus logvisor SDL2-static) diff --git a/aurora/lib/aurora.cpp b/aurora/lib/aurora.cpp index 345c04cf5..8217c90c7 100644 --- a/aurora/lib/aurora.cpp +++ b/aurora/lib/aurora.cpp @@ -21,6 +21,10 @@ #include "dawn/BackendBinding.hpp" +// imgui +#include +#include + namespace aurora { // TODO: Move global state to a class/struct? static logvisor::Module Log("aurora"); @@ -42,8 +46,8 @@ static wgpu::BackendType preferredBackendType = wgpu::BackendType::OpenGL; static std::unique_ptr g_Instance; static dawn::native::Adapter g_Adapter; static wgpu::AdapterProperties g_AdapterProperties; -static wgpu::Device g_Device; -static wgpu::Queue g_Queue; +wgpu::Device g_Device; +wgpu::Queue g_Queue; static wgpu::SwapChain g_SwapChain; static std::unique_ptr g_BackendBinding; @@ -65,6 +69,8 @@ static void set_window_icon(Icon icon) noexcept { static bool poll_events() noexcept { SDL_Event event; while (SDL_PollEvent(&event) != 0) { + ImGui_ImplSDL2_ProcessEvent(&event); + switch (event.type) { case SDL_WINDOWEVENT: { switch (event.window.event) { @@ -75,14 +81,6 @@ static bool poll_events() noexcept { break; } case SDL_WINDOWEVENT_EXPOSED: { - /* TODO: ImGui code? */ - /* TODO: Frame Time */ - // g_AppDelegate->onAppIdle(1/60.f); - /* TODO: Render Texture */ - // g_AppDelegate->onAppDraw(); - /* TODO: ImGui present code? */ - /* TODO: Present */ - // g_AppDelegate->onAppPostDraw(); break; } case SDL_WINDOWEVENT_MOVED: { @@ -90,6 +88,8 @@ static bool poll_events() noexcept { break; } case SDL_WINDOWEVENT_RESIZED: { + auto format = static_cast(g_BackendBinding->GetPreferredSwapChainTextureFormat()); + g_SwapChain.Configure(format, wgpu::TextureUsage::RenderAttachment, event.window.data1, event.window.data2); g_AppDelegate->onAppWindowResized( {static_cast(event.window.data1), static_cast(event.window.data2)}); break; @@ -162,12 +162,21 @@ static bool poll_events() noexcept { break; } case SDL_KEYDOWN: { + if (!ImGui::GetIO().WantCaptureKeyboard) { + // TODO + } break; } case SDL_KEYUP: { + if (!ImGui::GetIO().WantCaptureKeyboard) { + // TODO + } break; } case SDL_TEXTINPUT: { + if (!ImGui::GetIO().WantCaptureKeyboard) { + // TODO + } break; } case SDL_QUIT: @@ -176,12 +185,12 @@ static bool poll_events() noexcept { return false; } // TODO why doesn't this work? - const auto typedEvent = magic_enum::enum_cast(event.type); - if (typedEvent) { - Log.report(logvisor::Info, FMT_STRING("Received SDL event: {}"), magic_enum::enum_name(typedEvent.value())); - } else { - Log.report(logvisor::Info, FMT_STRING("Received SDL event: {}"), event.type); - } +// const auto typedEvent = magic_enum::enum_cast(event.type); +// if (typedEvent) { +// Log.report(logvisor::Info, FMT_STRING("Received SDL event: {}"), magic_enum::enum_name(typedEvent.value())); +// } else { +// Log.report(logvisor::Info, FMT_STRING("Received SDL event: {}"), event.type); +// } } return true; } @@ -262,16 +271,40 @@ void app_run(std::unique_ptr app, Icon icon, int argc, char** argv) g_SwapChain.Configure(format, wgpu::TextureUsage::RenderAttachment, size.width, size.height); } + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.IniFilename = nullptr; + g_AppDelegate->onImGuiInit(1.f); // TODO scale + ImGui_ImplSDL2_InitForMetal(g_Window); + ImGui_ImplWGPU_Init(g_Device.Get(), 1, g_BackendBinding->GetPreferredSwapChainTextureFormat()); + g_AppDelegate->onImGuiAddTextures(); + g_AppDelegate->onAppLaunched(); g_AppDelegate->onAppWindowResized(get_window_size()); + + bool showDemo = true; while (poll_events()) { + ImGui_ImplWGPU_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + g_AppDelegate->onAppIdle(ImGui::GetIO().DeltaTime); + + const wgpu::TextureView view = g_SwapChain.GetCurrentTextureView(); + g_AppDelegate->onAppDraw(); + if (showDemo) { + ImGui::ShowDemoWindow(&showDemo); + } + ImGui::Render(); + auto encoder = g_Device.CreateCommandEncoder(); { std::array attachments{wgpu::RenderPassColorAttachment{ - .view = g_SwapChain.GetCurrentTextureView(), + .view = view, .loadOp = wgpu::LoadOp::Clear, .storeOp = wgpu::StoreOp::Store, - .clearColor = {0.5f, 0.5f, 0.5f, 1.f}, + .clearColor = {0.f, 0.f, 0.f, 0.f}, }}; auto renderPassDescriptor = wgpu::RenderPassDescriptor{ .label = "Render Pass", @@ -279,13 +312,18 @@ void app_run(std::unique_ptr app, Icon icon, int argc, char** argv) .colorAttachments = attachments.data(), }; auto pass = encoder.BeginRenderPass(&renderPassDescriptor); + ImGui_ImplWGPU_RenderDrawData(ImGui::GetDrawData(), pass.Get()); pass.End(); } const auto buffer = encoder.Finish(); g_Queue.Submit(1, &buffer); g_SwapChain.Present(); + + g_AppDelegate->onAppPostDraw(); } + g_AppDelegate->onAppExiting(); + wgpuSwapChainRelease(g_SwapChain.Release()); wgpuQueueRelease(g_Queue.Release()); g_BackendBinding.reset(); diff --git a/aurora/lib/imgui.cpp b/aurora/lib/imgui.cpp index c9a8a25a4..2d017f6be 100644 --- a/aurora/lib/imgui.cpp +++ b/aurora/lib/imgui.cpp @@ -1,7 +1,44 @@ #include +#include + +namespace aurora { +extern wgpu::Device g_Device; +extern wgpu::Queue g_Queue; +} // namespace aurora + namespace aurora::imgui { ImTextureID add_texture(uint32_t width, uint32_t height, ArrayRef data) noexcept { - return 0; // TODO + const auto size = wgpu::Extent3D{ + .width = width, + .height = height, + }; + const auto textureDescriptor = wgpu::TextureDescriptor{ + .label = "imgui texture", + .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst, + .size = size, + .format = wgpu::TextureFormat::RGBA8Unorm, + }; + const auto textureViewDescriptor = wgpu::TextureViewDescriptor{ + .label = "imgui texture view", + .format = wgpu::TextureFormat::RGBA8Unorm, + .dimension = wgpu::TextureViewDimension::e2D, + .mipLevelCount = 1, + .arrayLayerCount = 1, + }; + auto texture = g_Device.CreateTexture(&textureDescriptor); + auto textureView = texture.CreateView(&textureViewDescriptor); + { + const auto dstView = wgpu::ImageCopyTexture{ + .texture = texture, + }; + const auto dataLayout = wgpu::TextureDataLayout{ + .bytesPerRow = 4 * width, + .rowsPerImage = height, + }; + g_Queue.WriteTexture(&dstView, data.data(), data.size(), &dataLayout, &size); + } + texture.Release(); // leak some memory! + return textureView.Release(); } } // namespace aurora::imgui diff --git a/extern/imgui b/extern/imgui index e3e1fbcf0..5c8f8d031 160000 --- a/extern/imgui +++ b/extern/imgui @@ -1 +1 @@ -Subproject commit e3e1fbcf025cf83413815751f7c33500e1314d57 +Subproject commit 5c8f8d031166765d2f1e2ac2de27df6d3691c05a diff --git a/imgui/CMakeLists.txt b/imgui/CMakeLists.txt index f8e60aeef..68b9ff5ae 100644 --- a/imgui/CMakeLists.txt +++ b/imgui/CMakeLists.txt @@ -5,14 +5,14 @@ add_library(imgui ../extern/imgui/imgui_tables.cpp ../extern/imgui/imgui_widgets.cpp ../extern/imgui/misc/cpp/imgui_stdlib.cpp - ../imgui-sys/third-party/cimgui.cpp +# ../imgui-sys/third-party/cimgui.cpp ImGuiEngine.cpp ImGuiEngine.hpp NotoMono.cpp MetaforceIcon.cpp ) target_include_directories(imgui PUBLIC ${CMAKE_SOURCE_DIR}/extern/imgui ${CMAKE_CURRENT_SOURCE_DIR}) -target_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG="imconfig_user.h" IMGUI_USE_WCHAR32) +target_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG="imconfig_user.h") # IMGUI_USE_WCHAR32 if (CMAKE_COMPILER_IS_GNUCXX) # currently explicitly ignored for clang in imgui code, but not gcc (yet) target_compile_options(imgui PRIVATE -Wno-deprecated-enum-enum-conversion) diff --git a/imgui/ImGuiEngine.cpp b/imgui/ImGuiEngine.cpp index d56cb4e1d..4830aaf97 100644 --- a/imgui/ImGuiEngine.cpp +++ b/imgui/ImGuiEngine.cpp @@ -53,7 +53,61 @@ void ImGuiEngine_Initialize(float scale) { #endif ImGuiEngine::fontLarge = io.Fonts->AddFont(&fontConfig); - ImGui::GetStyle().ScaleAllSizes(scale); + auto& style = ImGui::GetStyle(); + style.FrameRounding = 4.0f; + style.GrabRounding = 4.0f; + + auto colors = style.Colors; + colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); + colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); + colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f); + colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); + colors[ImGuiCol_TabHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f); + colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); + colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); + + style.ScaleAllSizes(scale); } Icon GetIcon() { diff --git a/imgui/imconfig_user.h b/imgui/imconfig_user.h index eec1b4c12..ab17ded4f 100644 --- a/imgui/imconfig_user.h +++ b/imgui/imconfig_user.h @@ -4,9 +4,6 @@ #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS -// To match imgui-sys -#define ImTextureID size_t - #define IM_VEC2_CLASS_EXTRA \ ImVec2(const zeus::CVector2f& v) { \ x = v.x(); \