imgui vk dirty

This commit is contained in:
Ilya Shurupov 2024-11-26 15:32:43 +03:00
parent dc88120f58
commit 94f5cf88d2
6 changed files with 269 additions and 1 deletions

View file

@ -7,4 +7,5 @@ add_subdirectory(extern/Modules)
add_subdirectory(extern/Utils)
add_subdirectory(src/VulkanGraphics)
add_subdirectory(src/DebugGUI)
add_subdirectory(src/App)

View file

@ -0,0 +1,26 @@
cmake_minimum_required(VERSION 3.30)
project(IMGUI)
set(IMDIR ../../extern/imgui/)
add_library(IMGUI
${IMDIR}imgui.cpp
${IMDIR}imgui_demo.cpp
${IMDIR}imgui_tables.cpp
${IMDIR}imgui_widgets.cpp
${IMDIR}imgui_draw.cpp
${IMDIR}backends/imgui_impl_vulkan.cpp
${IMDIR}backends/imgui_impl_glfw.cpp
)
target_include_directories(IMGUI PUBLIC ../../extern/imgui/)
project(DebugGUI)
file(GLOB SOURCES "./private/*.cpp")
add_library(${PROJECT_NAME} ${SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC public)
target_link_libraries(${PROJECT_NAME} PUBLIC VulkanGraphics IMGUI)
add_executable(${PROJECT_NAME}Example exapmle/main.cpp)
target_link_libraries(${PROJECT_NAME}Example PRIVATE ${PROJECT_NAME})

View file

@ -0,0 +1,86 @@
#include "DebugGUI.hpp"
VkRenderPass createRenderPass(VkDevice device, VkFormat format, VkImageLayout finalImageLayout) {
VkRenderPass renderPass = VK_NULL_HANDLE;
VkAttachmentDescription colorAttachment{
.format = format,
.samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.finalLayout = finalImageLayout,
};
VkAttachmentReference colorAttachmentReference{
.attachment = 0,
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
VkSubpassDescription subpassDescription{
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.colorAttachmentCount = 1,
.pColorAttachments = &colorAttachmentReference,
};
VkSubpassDependency dependency{
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
};
VkRenderPassCreateInfo renderPassCreateInfo{
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.attachmentCount = 1,
.pAttachments = &colorAttachment,
.subpassCount = 1,
.pSubpasses = &subpassDescription,
.dependencyCount = 1,
.pDependencies = &dependency
};
vkCreateRenderPass(device, &renderPassCreateInfo, nullptr, &renderPass);
return renderPass;
}
int main() {
VulkanWindow app;
ImGuiVk imgui;
auto renderInfo = app.getRenderInfo();
VkRenderPass renderPass = createRenderPass(renderInfo.device, renderInfo.format, renderInfo.finalImageLayout);
app.setRenderPass(renderPass);
imgui.create(&app);
imgui.setRenderPass(renderPass);
while (!glfwWindowShouldClose(app.getWindow())) {
app.pollEvents();
auto drawData = app.startDrawFrame();
imgui.beginFrame();
ImGuiVk::demo();
imgui.endFrame();
imgui.cmdRender(drawData.commandBuffer, drawData.frameBuffer, drawData.extent2D);
// renderer.fillRenderCommands(drawData.commandBuffer, drawData.frameBuffer, drawData.extent2D);
// renderer.updateUniformBuffer({drawData.extent2D.width, drawData.extent2D.height});
app.endDrawFrame(drawData);
}
app.waitDevice();
vkDestroyRenderPass(app.getDevice(), renderPass, nullptr);
imgui.destroy(app.getDevice());
}

View file

@ -0,0 +1,123 @@
#include "DebugGUI.hpp"
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_vulkan.h"
/*
get render pass from renderer
create frame buffer
*/
void ImGuiVk::create(VulkanWindow* vkWindow) {
mVkWindow = vkWindow;
}
void ImGuiVk::setRenderPass(VkRenderPass renderPass) {
mRenderPass = renderPass;
mContext = ImGui::CreateContext();
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForVulkan(mVkWindow->getWindow(), true);
VkDescriptorPoolSize poolSize{
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
};
VkDescriptorPoolCreateInfo createInfo{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
.maxSets = 1,
.poolSizeCount = 1,
.pPoolSizes = &poolSize,
};
if (vkCreateDescriptorPool(mVkWindow->mDevice, &createInfo, nullptr, &mDescriptorPool) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor pool");
}
ImGui_ImplVulkan_InitInfo init_info = {
.Instance = mVkWindow->mInstance,
.PhysicalDevice = mVkWindow->mPhysicalDevice,
.Device = mVkWindow->mDevice,
.QueueFamily = (uint32_t) mVkWindow->mGraphicsQueueFamilyIndex,
.Queue = mVkWindow->mGraphicsQueue,
.DescriptorPool = mDescriptorPool,
.RenderPass = mRenderPass,
.MinImageCount = 2,
.ImageCount = 2,
.MSAASamples = VK_SAMPLE_COUNT_1_BIT,
};
ImGui_ImplVulkan_Init(&init_info);
}
void ImGuiVk::beginFrame() {
ImGui::SetCurrentContext(mContext);
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}
void ImGuiVk::endFrame() {
ImGui::SetCurrentContext(mContext);
ImGui::Render();
mDrawData = ImGui::GetDrawData();
}
void ImGuiVk::demo() {
ImGui::ShowDemoWindow(nullptr);
}
void ImGuiVk::destroy(VkDevice device) {
ImGui::SetCurrentContext(mContext);
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
vkDestroyDescriptorPool(device, mDescriptorPool, nullptr);
}
ImGuiVk::~ImGuiVk() {
ImGui::SetCurrentContext(mContext);
ImGui::DestroyContext();
}
void ImGuiVk::cmdRender(VkCommandBuffer commandBuffer, VkFramebuffer framebuffer, VkExtent2D extend) {
VkCommandBufferBeginInfo commandBufferBeginInfo{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
};
if (vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo) != VK_SUCCESS) {
throw std::runtime_error("failed to begin command buffer =");
}
VkClearValue clearColor{.color = {.float32 = {0.f, 0.f, 0.f, 1.f}}};
VkRenderPassBeginInfo renderPassBeginInfo{
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = mRenderPass,
.framebuffer = framebuffer,
.renderArea = {
.offset = {0, 0},
.extent = extend,
},
.clearValueCount = 1,
.pClearValues = &clearColor,
};
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
// Record dear imgui primitives into command buffer
ImGui_ImplVulkan_RenderDrawData(mDrawData, commandBuffer);
vkCmdEndRenderPass(commandBuffer);
if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) {
throw std::runtime_error("failed to end command buffer");
}
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "VulkanWindow.hpp"
#include "imgui.h"
class ImGuiVk {
public:
ImGuiVk() = default;
void create(VulkanWindow* vkWindow);
void setRenderPass(VkRenderPass renderPass);
void beginFrame();
void endFrame();
static void demo();
void destroy(VkDevice device);
~ImGuiVk();
void cmdRender(VkCommandBuffer commandBuffer, VkFramebuffer framebuffer, VkExtent2D extend);
private:
ImGuiContext* mContext = nullptr;
VulkanWindow* mVkWindow = nullptr;
ImDrawData* mDrawData = nullptr;
VkRenderPass mRenderPass = VK_NULL_HANDLE;
VkDescriptorPool mDescriptorPool = VK_NULL_HANDLE;
};

View file

@ -58,7 +58,7 @@ private:
void destroyCommandPool();
private:
public:
GLFWwindow *mWindow = nullptr;
bool mWindowSizeDirtyFlag = true;