From 4b8c842615dd4708a62b55de7b5abcd1b4a0e984 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Fri, 9 Sep 2022 21:46:30 +0800 Subject: [PATCH] [WIP] SHADE ImGui Vulkan Backend --- SHADE_Engine/SHADE_Engine.vcxproj | 2 + SHADE_Engine/SHADE_Engine.vcxproj.filters | 2 + .../Editor/Backend/SHImGuiVulkanBackend.cpp | 613 ++++++++++++++++++ .../src/Editor/Backend/SHImGuiVulkanBackend.h | 62 ++ SHADE_Engine/src/Editor/SHEditor.cpp | 22 +- 5 files changed, 693 insertions(+), 8 deletions(-) create mode 100644 SHADE_Engine/src/Editor/Backend/SHImGuiVulkanBackend.cpp create mode 100644 SHADE_Engine/src/Editor/Backend/SHImGuiVulkanBackend.h diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj index 3d673b09..cd596fc6 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj +++ b/SHADE_Engine/SHADE_Engine.vcxproj @@ -102,6 +102,7 @@ + @@ -188,6 +189,7 @@ + diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters index e26cacc4..d890c070 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj.filters +++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters @@ -361,6 +361,7 @@ Tools + @@ -541,5 +542,6 @@ Tools + \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/Backend/SHImGuiVulkanBackend.cpp b/SHADE_Engine/src/Editor/Backend/SHImGuiVulkanBackend.cpp new file mode 100644 index 00000000..63fd39b8 --- /dev/null +++ b/SHADE_Engine/src/Editor/Backend/SHImGuiVulkanBackend.cpp @@ -0,0 +1,613 @@ + +#include +#include + +#include + +#include "SHImGuiVulkanBackend.h" + +#include + + +#include "Tools/SHLogger.h" +namespace SHADE +{ +#define GETINSTANCE \ + ImGuiIO& io = ImGui::GetIO(); \ + SHBreachInstance& instance = *reinterpret_cast(io.UserData); + + /* + #==============================================================# + || Embedded Shaders || + #==============================================================# + */ + // glsl_shader.vert, compiled with: + // # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert + /* + #version 450 core + layout(location = 0) in vec2 aPos; + layout(location = 1) in vec2 aUV; + layout(location = 2) in vec4 aColor; + layout(push_constant) uniform uPushConstant { vec2 uScale; vec2 uTranslate; } pc; + + out gl_PerVertex { vec4 gl_Position; }; + layout(location = 0) out struct { vec4 Color; vec2 UV; } Out; + + void main() + { + Out.Color = aColor; + Out.UV = aUV; + gl_Position = vec4(aPos * pc.uScale + pc.uTranslate, 0, 1); + } + */ + static uint32_t __glsl_shader_vert_spv[] = + { + 0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000a000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000b,0x0000000f,0x00000015, + 0x0000001b,0x0000001c,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x00000009,0x00000000,0x00050006,0x00000009,0x00000000,0x6f6c6f43, + 0x00000072,0x00040006,0x00000009,0x00000001,0x00005655,0x00030005,0x0000000b,0x0074754f, + 0x00040005,0x0000000f,0x6c6f4361,0x0000726f,0x00030005,0x00000015,0x00565561,0x00060005, + 0x00000019,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000019,0x00000000, + 0x505f6c67,0x7469736f,0x006e6f69,0x00030005,0x0000001b,0x00000000,0x00040005,0x0000001c, + 0x736f5061,0x00000000,0x00060005,0x0000001e,0x73755075,0x6e6f4368,0x6e617473,0x00000074, + 0x00050006,0x0000001e,0x00000000,0x61635375,0x0000656c,0x00060006,0x0000001e,0x00000001, + 0x61725475,0x616c736e,0x00006574,0x00030005,0x00000020,0x00006370,0x00040047,0x0000000b, + 0x0000001e,0x00000000,0x00040047,0x0000000f,0x0000001e,0x00000002,0x00040047,0x00000015, + 0x0000001e,0x00000001,0x00050048,0x00000019,0x00000000,0x0000000b,0x00000000,0x00030047, + 0x00000019,0x00000002,0x00040047,0x0000001c,0x0000001e,0x00000000,0x00050048,0x0000001e, + 0x00000000,0x00000023,0x00000000,0x00050048,0x0000001e,0x00000001,0x00000023,0x00000008, + 0x00030047,0x0000001e,0x00000002,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040017, + 0x00000008,0x00000006,0x00000002,0x0004001e,0x00000009,0x00000007,0x00000008,0x00040020, + 0x0000000a,0x00000003,0x00000009,0x0004003b,0x0000000a,0x0000000b,0x00000003,0x00040015, + 0x0000000c,0x00000020,0x00000001,0x0004002b,0x0000000c,0x0000000d,0x00000000,0x00040020, + 0x0000000e,0x00000001,0x00000007,0x0004003b,0x0000000e,0x0000000f,0x00000001,0x00040020, + 0x00000011,0x00000003,0x00000007,0x0004002b,0x0000000c,0x00000013,0x00000001,0x00040020, + 0x00000014,0x00000001,0x00000008,0x0004003b,0x00000014,0x00000015,0x00000001,0x00040020, + 0x00000017,0x00000003,0x00000008,0x0003001e,0x00000019,0x00000007,0x00040020,0x0000001a, + 0x00000003,0x00000019,0x0004003b,0x0000001a,0x0000001b,0x00000003,0x0004003b,0x00000014, + 0x0000001c,0x00000001,0x0004001e,0x0000001e,0x00000008,0x00000008,0x00040020,0x0000001f, + 0x00000009,0x0000001e,0x0004003b,0x0000001f,0x00000020,0x00000009,0x00040020,0x00000021, + 0x00000009,0x00000008,0x0004002b,0x00000006,0x00000028,0x00000000,0x0004002b,0x00000006, + 0x00000029,0x3f800000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x00000007,0x00000010,0x0000000f,0x00050041,0x00000011,0x00000012, + 0x0000000b,0x0000000d,0x0003003e,0x00000012,0x00000010,0x0004003d,0x00000008,0x00000016, + 0x00000015,0x00050041,0x00000017,0x00000018,0x0000000b,0x00000013,0x0003003e,0x00000018, + 0x00000016,0x0004003d,0x00000008,0x0000001d,0x0000001c,0x00050041,0x00000021,0x00000022, + 0x00000020,0x0000000d,0x0004003d,0x00000008,0x00000023,0x00000022,0x00050085,0x00000008, + 0x00000024,0x0000001d,0x00000023,0x00050041,0x00000021,0x00000025,0x00000020,0x00000013, + 0x0004003d,0x00000008,0x00000026,0x00000025,0x00050081,0x00000008,0x00000027,0x00000024, + 0x00000026,0x00050051,0x00000006,0x0000002a,0x00000027,0x00000000,0x00050051,0x00000006, + 0x0000002b,0x00000027,0x00000001,0x00070050,0x00000007,0x0000002c,0x0000002a,0x0000002b, + 0x00000028,0x00000029,0x00050041,0x00000011,0x0000002d,0x0000001b,0x0000000d,0x0003003e, + 0x0000002d,0x0000002c,0x000100fd,0x00010038 + }; + + // glsl_shader.frag, compiled with: + // # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag + /* + #version 450 core + layout(location = 0) out vec4 fColor; + layout(set=0, binding=0) uniform sampler2D sTexture; + layout(location = 0) in struct { vec4 Color; vec2 UV; } In; + void main() + { + fColor = In.Color * texture(sTexture, In.UV.st); + } + */ + static uint32_t __glsl_shader_frag_spv[] = + { + 0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000d,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00040005,0x00000009,0x6c6f4366,0x0000726f,0x00030005,0x0000000b,0x00000000, + 0x00050006,0x0000000b,0x00000000,0x6f6c6f43,0x00000072,0x00040006,0x0000000b,0x00000001, + 0x00005655,0x00030005,0x0000000d,0x00006e49,0x00050005,0x00000016,0x78655473,0x65727574, + 0x00000000,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,0x0000000d,0x0000001e, + 0x00000000,0x00040047,0x00000016,0x00000022,0x00000000,0x00040047,0x00000016,0x00000021, + 0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006, + 0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,0x00000003, + 0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,0x0000000a,0x00000006, + 0x00000002,0x0004001e,0x0000000b,0x00000007,0x0000000a,0x00040020,0x0000000c,0x00000001, + 0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000001,0x00040015,0x0000000e,0x00000020, + 0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000000,0x00040020,0x00000010,0x00000001, + 0x00000007,0x00090019,0x00000013,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x0003001b,0x00000014,0x00000013,0x00040020,0x00000015,0x00000000, + 0x00000014,0x0004003b,0x00000015,0x00000016,0x00000000,0x0004002b,0x0000000e,0x00000018, + 0x00000001,0x00040020,0x00000019,0x00000001,0x0000000a,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,0x00000010,0x00000011,0x0000000d, + 0x0000000f,0x0004003d,0x00000007,0x00000012,0x00000011,0x0004003d,0x00000014,0x00000017, + 0x00000016,0x00050041,0x00000019,0x0000001a,0x0000000d,0x00000018,0x0004003d,0x0000000a, + 0x0000001b,0x0000001a,0x00050057,0x00000007,0x0000001c,0x00000017,0x0000001b,0x00050085, + 0x00000007,0x0000001d,0x00000012,0x0000001c,0x0003003e,0x00000009,0x0000001d,0x000100fd, + 0x00010038 + }; + + /* + #==============================================================# + || ImGui Push Constants || + #==============================================================# + */ + struct ImGui_Push_Constants + { + std::array scale; + std::array translate; + }; + + void SHImGuiVulkanBackend::CreateInstance(Handle const& logicalDevice) noexcept + { + if (ImGui::GetCurrentContext() == nullptr) + { + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + } + else { SHLOG_WARNING("ImGui context already exists") }; + + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + //io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) + //io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) + io.BackendRendererName = "SHImGuiVulkanBackend"; + + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGuiPlatformIO& platformIO = ImGui::GetPlatformIO(); + platformIO.Renderer_CreateWindow = CreateChildWindow; + platformIO.Renderer_DestroyWindow = DestroyChildWindow; + platformIO.Renderer_SetWindowSize = SetChildWindowSize; + platformIO.Renderer_RenderWindow = RenderChildWindow; + platformIO.Renderer_SwapBuffers = ChildSwapBuffers; + + platformIO.Platform_CreateWindow = CreateChildWindow; + platformIO.Platform_DestroyWindow = DestroyChildWindow; + platformIO.Platform_ShowWindow = [](ImGuiViewport* pViewport) {}; + platformIO.Platform_SetWindowPos = SetChildWindowPos; + platformIO.Platform_GetWindowPos = GetChildWindowPos; + platformIO.Platform_SetWindowSize = SetChildWindowSize; + platformIO.Platform_GetWindowSize = GetChildWindowSize; + //platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus; + //platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus; + //platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized; + platformIO.Platform_SetWindowTitle = [](ImGuiViewport* pViewport, const char*) {}; + platformIO.Platform_RenderWindow = RenderChildWindow; + platformIO.Platform_SwapBuffers = ChildSwapBuffers; + + platformIO.Monitors.resize(0); + ImGuiPlatformMonitor monitor; + monitor.MainPos = monitor.WorkPos = {}; + monitor.MainSize = monitor.WorkSize = {}; + platformIO.Monitors.push_back(monitor); + }//if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + + //associate io keymap with engine input keymap + + //Initialize instance + auto instance = std::make_unique(); + instance->InitializePipeline(io); + instance->lastFrameTime = std::chrono::high_resolution_clock::now(); + io.UserData = instance.release(); + + ImGuiViewport* viewport = ImGui::GetMainViewport(); + viewport->RendererUserData = io.UserData; + viewport->PlatformHandle = io.UserData; + } + + void SHImGuiVulkanBackend::Render(void) noexcept + { + ImGui::Render(); + ImDrawData* drawData = ImGui::GetDrawData(); + //TODO: instance draw data + } + + void SHImGuiVulkanBackend::CreateChildWindow(ImGuiViewport* viewport) noexcept + { + GETINSTANCE + + auto& info = *new SHImGuiWindow{ instance.device }; + viewport->RendererUserData = &info; + } + + void SHImGuiVulkanBackend::DestroyChildWindow(ImGuiViewport* viewport) noexcept + { + GETINSTANCE + + auto info = reinterpret_cast(viewport->RendererUserData); + delete info; + viewport->RendererUserData = nullptr; + } + + ImVec2 SHImGuiVulkanBackend::GetChildWindowSize(ImGuiViewport* viewport) noexcept + { + auto info = reinterpret_cast(viewport->RendererUserData); + return{}; + } + + void SHImGuiVulkanBackend::SetChildWindowSize(ImGuiViewport* viewport, ImVec2 size) noexcept + { + + } + + ImVec2 SHImGuiVulkanBackend::GetChildWindowPos(ImGuiViewport* viewport) noexcept + { + } + + void SHImGuiVulkanBackend::SetChildWindowPos(ImGuiViewport* viewport, ImVec2 size) noexcept + { + } + + void SHImGuiVulkanBackend::RenderChildWindow(ImGuiViewport* viewport, void*) noexcept + { + } + + void SHImGuiVulkanBackend::ChildSwapBuffers(ImGuiViewport* viewport, void*) noexcept + { + } + + + void SHImGuiVulkanBackend::SHImGuiWindow::InitializeBuffers(void) noexcept + { + for (auto& primBuffer : primitiveBuffers) + { + primBuffer.vertexBuffer = logicalDeviceHdl->CreateBuffer(sizeof(ImDrawVert) * 3000, + nullptr, + sizeof(ImDrawVert) * 3000, + vk::BufferUsageFlagBits::eVertexBuffer, + VMA_MEMORY_USAGE_AUTO, + VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); // alloc flags + + primBuffer.indicesBuffer = logicalDeviceHdl->CreateBuffer(sizeof(ImDrawIdx) * 3000, + nullptr, + sizeof(ImDrawIdx) * 3000, + vk::BufferUsageFlagBits::eIndexBuffer, + VMA_MEMORY_USAGE_AUTO, + VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); // alloc flags + + } + } + + + + void SHImGuiVulkanBackend::SHBreachInstance::CreateFontsTexture(Handle image, ImGuiIO& io) noexcept + { + // Build texture atlas + unsigned char* pixels; + int width, height; + + // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. + // If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + + + // Create the texture in xgpu + { + std::array Mip{ height * width * sizeof(std::uint32_t) }; + xgpu::texture::setup Setup; + + Setup.m_Height = height; + Setup.m_Width = width; + Setup.m_MipChain = Mip; + Setup.m_Data = { reinterpret_cast(pixels), Mip[0].m_Size }; + + if (auto Err = m_Device.Create(Texture, Setup); Err) + return Err; + } + + // We could put here the texture id if we wanted + io.Fonts->TexID = nullptr; + + return nullptr; + + } +} +#include +#include + +#include + +#include "SHImGuiVulkanBackend.h" + +#include + + +#include "Tools/SHLogger.h" +namespace SHADE +{ +#define GETINSTANCE \ + ImGuiIO& io = ImGui::GetIO(); \ + SHBreachInstance& instance = *reinterpret_cast(io.UserData); + + /* + #==============================================================# + || Embedded Shaders || + #==============================================================# + */ + // glsl_shader.vert, compiled with: + // # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert + /* + #version 450 core + layout(location = 0) in vec2 aPos; + layout(location = 1) in vec2 aUV; + layout(location = 2) in vec4 aColor; + layout(push_constant) uniform uPushConstant { vec2 uScale; vec2 uTranslate; } pc; + + out gl_PerVertex { vec4 gl_Position; }; + layout(location = 0) out struct { vec4 Color; vec2 UV; } Out; + + void main() + { + Out.Color = aColor; + Out.UV = aUV; + gl_Position = vec4(aPos * pc.uScale + pc.uTranslate, 0, 1); + } + */ + static uint32_t __glsl_shader_vert_spv[] = + { + 0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000a000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000b,0x0000000f,0x00000015, + 0x0000001b,0x0000001c,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x00000009,0x00000000,0x00050006,0x00000009,0x00000000,0x6f6c6f43, + 0x00000072,0x00040006,0x00000009,0x00000001,0x00005655,0x00030005,0x0000000b,0x0074754f, + 0x00040005,0x0000000f,0x6c6f4361,0x0000726f,0x00030005,0x00000015,0x00565561,0x00060005, + 0x00000019,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000019,0x00000000, + 0x505f6c67,0x7469736f,0x006e6f69,0x00030005,0x0000001b,0x00000000,0x00040005,0x0000001c, + 0x736f5061,0x00000000,0x00060005,0x0000001e,0x73755075,0x6e6f4368,0x6e617473,0x00000074, + 0x00050006,0x0000001e,0x00000000,0x61635375,0x0000656c,0x00060006,0x0000001e,0x00000001, + 0x61725475,0x616c736e,0x00006574,0x00030005,0x00000020,0x00006370,0x00040047,0x0000000b, + 0x0000001e,0x00000000,0x00040047,0x0000000f,0x0000001e,0x00000002,0x00040047,0x00000015, + 0x0000001e,0x00000001,0x00050048,0x00000019,0x00000000,0x0000000b,0x00000000,0x00030047, + 0x00000019,0x00000002,0x00040047,0x0000001c,0x0000001e,0x00000000,0x00050048,0x0000001e, + 0x00000000,0x00000023,0x00000000,0x00050048,0x0000001e,0x00000001,0x00000023,0x00000008, + 0x00030047,0x0000001e,0x00000002,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040017, + 0x00000008,0x00000006,0x00000002,0x0004001e,0x00000009,0x00000007,0x00000008,0x00040020, + 0x0000000a,0x00000003,0x00000009,0x0004003b,0x0000000a,0x0000000b,0x00000003,0x00040015, + 0x0000000c,0x00000020,0x00000001,0x0004002b,0x0000000c,0x0000000d,0x00000000,0x00040020, + 0x0000000e,0x00000001,0x00000007,0x0004003b,0x0000000e,0x0000000f,0x00000001,0x00040020, + 0x00000011,0x00000003,0x00000007,0x0004002b,0x0000000c,0x00000013,0x00000001,0x00040020, + 0x00000014,0x00000001,0x00000008,0x0004003b,0x00000014,0x00000015,0x00000001,0x00040020, + 0x00000017,0x00000003,0x00000008,0x0003001e,0x00000019,0x00000007,0x00040020,0x0000001a, + 0x00000003,0x00000019,0x0004003b,0x0000001a,0x0000001b,0x00000003,0x0004003b,0x00000014, + 0x0000001c,0x00000001,0x0004001e,0x0000001e,0x00000008,0x00000008,0x00040020,0x0000001f, + 0x00000009,0x0000001e,0x0004003b,0x0000001f,0x00000020,0x00000009,0x00040020,0x00000021, + 0x00000009,0x00000008,0x0004002b,0x00000006,0x00000028,0x00000000,0x0004002b,0x00000006, + 0x00000029,0x3f800000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x00000007,0x00000010,0x0000000f,0x00050041,0x00000011,0x00000012, + 0x0000000b,0x0000000d,0x0003003e,0x00000012,0x00000010,0x0004003d,0x00000008,0x00000016, + 0x00000015,0x00050041,0x00000017,0x00000018,0x0000000b,0x00000013,0x0003003e,0x00000018, + 0x00000016,0x0004003d,0x00000008,0x0000001d,0x0000001c,0x00050041,0x00000021,0x00000022, + 0x00000020,0x0000000d,0x0004003d,0x00000008,0x00000023,0x00000022,0x00050085,0x00000008, + 0x00000024,0x0000001d,0x00000023,0x00050041,0x00000021,0x00000025,0x00000020,0x00000013, + 0x0004003d,0x00000008,0x00000026,0x00000025,0x00050081,0x00000008,0x00000027,0x00000024, + 0x00000026,0x00050051,0x00000006,0x0000002a,0x00000027,0x00000000,0x00050051,0x00000006, + 0x0000002b,0x00000027,0x00000001,0x00070050,0x00000007,0x0000002c,0x0000002a,0x0000002b, + 0x00000028,0x00000029,0x00050041,0x00000011,0x0000002d,0x0000001b,0x0000000d,0x0003003e, + 0x0000002d,0x0000002c,0x000100fd,0x00010038 + }; + + // glsl_shader.frag, compiled with: + // # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag + /* + #version 450 core + layout(location = 0) out vec4 fColor; + layout(set=0, binding=0) uniform sampler2D sTexture; + layout(location = 0) in struct { vec4 Color; vec2 UV; } In; + void main() + { + fColor = In.Color * texture(sTexture, In.UV.st); + } + */ + static uint32_t __glsl_shader_frag_spv[] = + { + 0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000d,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00040005,0x00000009,0x6c6f4366,0x0000726f,0x00030005,0x0000000b,0x00000000, + 0x00050006,0x0000000b,0x00000000,0x6f6c6f43,0x00000072,0x00040006,0x0000000b,0x00000001, + 0x00005655,0x00030005,0x0000000d,0x00006e49,0x00050005,0x00000016,0x78655473,0x65727574, + 0x00000000,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,0x0000000d,0x0000001e, + 0x00000000,0x00040047,0x00000016,0x00000022,0x00000000,0x00040047,0x00000016,0x00000021, + 0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006, + 0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,0x00000003, + 0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,0x0000000a,0x00000006, + 0x00000002,0x0004001e,0x0000000b,0x00000007,0x0000000a,0x00040020,0x0000000c,0x00000001, + 0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000001,0x00040015,0x0000000e,0x00000020, + 0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000000,0x00040020,0x00000010,0x00000001, + 0x00000007,0x00090019,0x00000013,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x0003001b,0x00000014,0x00000013,0x00040020,0x00000015,0x00000000, + 0x00000014,0x0004003b,0x00000015,0x00000016,0x00000000,0x0004002b,0x0000000e,0x00000018, + 0x00000001,0x00040020,0x00000019,0x00000001,0x0000000a,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,0x00000010,0x00000011,0x0000000d, + 0x0000000f,0x0004003d,0x00000007,0x00000012,0x00000011,0x0004003d,0x00000014,0x00000017, + 0x00000016,0x00050041,0x00000019,0x0000001a,0x0000000d,0x00000018,0x0004003d,0x0000000a, + 0x0000001b,0x0000001a,0x00050057,0x00000007,0x0000001c,0x00000017,0x0000001b,0x00050085, + 0x00000007,0x0000001d,0x00000012,0x0000001c,0x0003003e,0x00000009,0x0000001d,0x000100fd, + 0x00010038 + }; + + /* + #==============================================================# + || ImGui Push Constants || + #==============================================================# + */ + struct ImGui_Push_Constants + { + std::array scale; + std::array translate; + }; + + void SHImGuiVulkanBackend::CreateInstance(Handle const& logicalDevice) noexcept + { + if (ImGui::GetCurrentContext() == nullptr) + { + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + } + else { SHLOG_WARNING("ImGui context already exists") }; + + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + //io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) + //io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional) + io.BackendRendererName = "SHImGuiVulkanBackend"; + + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGuiPlatformIO& platformIO = ImGui::GetPlatformIO(); + platformIO.Renderer_CreateWindow = CreateChildWindow; + platformIO.Renderer_DestroyWindow = DestroyChildWindow; + platformIO.Renderer_SetWindowSize = SetChildWindowSize; + platformIO.Renderer_RenderWindow = RenderChildWindow; + platformIO.Renderer_SwapBuffers = ChildSwapBuffers; + + platformIO.Platform_CreateWindow = CreateChildWindow; + platformIO.Platform_DestroyWindow = DestroyChildWindow; + platformIO.Platform_ShowWindow = [](ImGuiViewport* pViewport) {}; + platformIO.Platform_SetWindowPos = SetChildWindowPos; + platformIO.Platform_GetWindowPos = GetChildWindowPos; + platformIO.Platform_SetWindowSize = SetChildWindowSize; + platformIO.Platform_GetWindowSize = GetChildWindowSize; + //platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus; + //platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus; + //platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized; + platformIO.Platform_SetWindowTitle = [](ImGuiViewport* pViewport, const char*) {}; + platformIO.Platform_RenderWindow = RenderChildWindow; + platformIO.Platform_SwapBuffers = ChildSwapBuffers; + + platformIO.Monitors.resize(0); + ImGuiPlatformMonitor monitor; + monitor.MainPos = monitor.WorkPos = {}; + monitor.MainSize = monitor.WorkSize = {}; + platformIO.Monitors.push_back(monitor); + }//if(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + + //associate io keymap with engine input keymap + + //Initialize instance + auto instance = std::make_unique(); + instance->InitializePipeline(io); + instance->lastFrameTime = std::chrono::high_resolution_clock::now(); + io.UserData = instance.release(); + + ImGuiViewport* viewport = ImGui::GetMainViewport(); + viewport->RendererUserData = io.UserData; + viewport->PlatformHandle = io.UserData; + } + + void SHImGuiVulkanBackend::Render(void) noexcept + { + ImGui::Render(); + ImDrawData* drawData = ImGui::GetDrawData(); + //TODO: instance draw data + } + + void SHImGuiVulkanBackend::CreateChildWindow(ImGuiViewport* viewport) noexcept + { + GETINSTANCE + + auto& info = *new SHImGuiWindow{ instance.device }; + viewport->RendererUserData = &info; + } + + void SHImGuiVulkanBackend::DestroyChildWindow(ImGuiViewport* viewport) noexcept + { + GETINSTANCE + + auto info = reinterpret_cast(viewport->RendererUserData); + delete info; + viewport->RendererUserData = nullptr; + } + + ImVec2 SHImGuiVulkanBackend::GetChildWindowSize(ImGuiViewport* viewport) noexcept + { + auto info = reinterpret_cast(viewport->RendererUserData); + return{}; + } + + void SHImGuiVulkanBackend::SetChildWindowSize(ImGuiViewport* viewport, ImVec2 size) noexcept + { + + } + + ImVec2 SHImGuiVulkanBackend::GetChildWindowPos(ImGuiViewport* viewport) noexcept + { + } + + void SHImGuiVulkanBackend::SetChildWindowPos(ImGuiViewport* viewport, ImVec2 size) noexcept + { + } + + void SHImGuiVulkanBackend::RenderChildWindow(ImGuiViewport* viewport, void*) noexcept + { + } + + void SHImGuiVulkanBackend::ChildSwapBuffers(ImGuiViewport* viewport, void*) noexcept + { + } + + + void SHImGuiVulkanBackend::SHImGuiWindow::InitializeBuffers(void) noexcept + { + for (auto& primBuffer : primitiveBuffers) + { + primBuffer.vertexBuffer = logicalDeviceHdl->CreateBuffer(sizeof(ImDrawVert) * 3000, + nullptr, + sizeof(ImDrawVert) * 3000, + vk::BufferUsageFlagBits::eVertexBuffer, + VMA_MEMORY_USAGE_AUTO, + VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); // alloc flags + + primBuffer.indicesBuffer = logicalDeviceHdl->CreateBuffer(sizeof(ImDrawIdx) * 3000, + nullptr, + sizeof(ImDrawIdx) * 3000, + vk::BufferUsageFlagBits::eIndexBuffer, + VMA_MEMORY_USAGE_AUTO, + VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT); // alloc flags + + } + } + + void SHImGuiVulkanBackend::SHBreachInstance::CreateFontsTexture(Handle image, ImGuiIO& io) noexcept + { + // Build texture atlas + unsigned char* pixels; + int width, height; + + // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. + // If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + + + // Create the texture in xgpu + { + std::array Mip{ height * width * sizeof(std::uint32_t) }; + xgpu::texture::setup Setup; + + Setup.m_Height = height; + Setup.m_Width = width; + Setup.m_MipChain = Mip; + Setup.m_Data = { reinterpret_cast(pixels), Mip[0].m_Size }; + + if (auto Err = m_Device.Create(Texture, Setup); Err) + return Err; + } + + // We could put here the texture id if we wanted + io.Fonts->TexID = nullptr; + + return nullptr; + + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/Backend/SHImGuiVulkanBackend.h b/SHADE_Engine/src/Editor/Backend/SHImGuiVulkanBackend.h new file mode 100644 index 00000000..df513df7 --- /dev/null +++ b/SHADE_Engine/src/Editor/Backend/SHImGuiVulkanBackend.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/Images/SHVkImage.h" +#include +#include +#include +#include "Graphics/Swapchain/SHVkSwapchain.h" +#include +#include "Graphics/Debugging/SHVulkanDebugUtil.h" + +namespace SHADE +{ + class SHImGuiVulkanBackend + { + struct SHImGuiWindow + { + struct Buffers + { + Handle vertexBuffer; + Handle indicesBuffer; + + }; + + Handle device; + std::array primitiveBuffers; + + public: + void InitializeBuffers(void) noexcept; + + }; + + struct SHBreachInstance : public SHImGuiWindow + { + Handle pipeline; + std::chrono::time_point lastFrameTime; + public: + void CreateFontsTexture (Handle image, ImGuiIO& io) noexcept; + void InitializePipeline(ImGuiIO& io) noexcept; + }; + public: + static void CreateInstance(Handle const& logicalDevice) noexcept; + static void Render(void) noexcept; + + + static void EnableDocking(void) noexcept; + + //Platform specific functions + static void CreateChildWindow(ImGuiViewport* viewport) noexcept; + static void DestroyChildWindow(ImGuiViewport* viewport) noexcept; + static ImVec2 GetChildWindowSize(ImGuiViewport* viewport) noexcept; + static void SetChildWindowSize(ImGuiViewport* viewport, ImVec2 size) noexcept; + static ImVec2 GetChildWindowPos(ImGuiViewport* viewport) noexcept; + static void SetChildWindowPos(ImGuiViewport* viewport, ImVec2 size) noexcept; + static void RenderChildWindow(ImGuiViewport* viewport, void*) noexcept; + static void ChildSwapBuffers(ImGuiViewport* viewport, void*) noexcept; + + private: + + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index b3bac9d1..ab3a220a 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -3,8 +3,8 @@ #include "SHEditorBackend.h" #include -#include +#include #include #include #include @@ -13,6 +13,8 @@ #include "Tools/SHLogger.h" +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + namespace SHADE { Handle SHEditor::cmdPool; @@ -23,14 +25,15 @@ namespace SHADE IMGUI_CHECKVERSION(); ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + SetupWin32Backend(hwnd); SetupVulkanBackend(); - //ImGuiIO& io = ImGui::GetIO(); - - //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - //io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; - //io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; } @@ -44,7 +47,7 @@ namespace SHADE NewFrame(); //Add all windows to draw list, Perform necessary updates - ImGui::ShowDemoWindow(); + //ImGui::ShowDemoWindow(); ImGui::Render(); } @@ -59,6 +62,7 @@ namespace SHADE ImGui::UpdatePlatformWindows(); ImGui::RenderPlatformWindowsDefault(); } + } void SHEditor::Exit() @@ -83,6 +87,7 @@ namespace SHADE initInfo.Allocator = nullptr; initInfo.PipelineCache = nullptr; initInfo.Subpass = 0; + initInfo.CheckVkResultFn = [](VkResult err) { if (err == VK_SUCCESS) @@ -105,8 +110,8 @@ namespace SHADE void SHEditor::NewFrame() { - ImGui_ImplWin32_NewFrame(); ImGui_ImplVulkan_NewFrame(); + ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); } @@ -118,4 +123,5 @@ namespace SHADE void SHEditor::ShutdownWin32Backend() { } + }