前往
大廳
主題

Vulkan Docking Imgui

%%鼠 拒收病婿 | 2024-12-21 19:04:53 | 巴幣 1346 | 人氣 98

Imgui


ImGui(Immediate Mode GUI)是一個用於構建圖形用戶界面的開源庫。它由Omar Cornut開發,並且在遊戲開發和工具開發中廣泛使用。ImGui的設計理念是即時模式(Immediate Mode),這意味著每次渲染循環都會重新構建整個UI,而不是保留UI的狀態。

Github
兩者安裝步驟相同,但Docking提供視窗合併/分離功能


Vulkan啟動Imgui

#include "./core/DisplayWindow.hpp"
#include "./core/CoreInstance.hpp"
#include "./core/SwapChain.hpp"
#include "./core/GraphicsPipeline.hpp"
#include "render/Renderer.hpp"
#include "imgui.h"
#include "imgui_impl_vulkan.h"
#include "imgui_impl_glfw.h"
int main() {
    ltn::DisplayWindow main_window{};
    ltn::CoreInstance coreInstance{ *main_window.get_window() };
    std::unique_ptr<ltn::SwapChain> swapchain = std::make_unique<ltn::SwapChain>(coreInstance,main_window.SCR_WIDTH , main_window.SCR_HEIGHT);
    std::unique_ptr<ltn::GraphicsPipeline> pipeline = std::make_unique<ltn::GraphicsPipeline>( coreInstance , *swapchain );
    std::unique_ptr<ltn::Renderer>forward_renderer_pass = std::make_unique<ltn::Renderer>( coreInstance , *swapchain );

    pipeline->create_pipleine(
        forward_renderer_pass->get_renderPass(),
        nullptr
        //gameobject.get_all_descriptorLayouts()
    );

    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls
    ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;
    ImGui::StyleColorsLight();
        

    //1: create descriptor pool for IMGUI
    // the size of the pool is very oversize, but it's copied from imgui demo itself.
    VkDescriptorPoolSize pool_sizes[] =
    {
        { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
        { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
        { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
        { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
        { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
        { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
        { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
        { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
        { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
        { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
        { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
    };
    VkDescriptorPoolCreateInfo pool_info = {};
    pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
    pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
    pool_info.maxSets = 1000;
    pool_info.poolSizeCount = std::size(pool_sizes);
    pool_info.pPoolSizes = pool_sizes;

    VkDescriptorPool imguiPool;
    vkCreateDescriptorPool(coreInstance.get_device(), &pool_info, nullptr, &imguiPool);


    // Initialize ImGui for GLFW and Vulkan
    ImGui_ImplGlfw_InitForVulkan(main_window.get_window(), true);
    ImGui_ImplVulkan_InitInfo init_info = {};
    init_info.Instance = coreInstance.get_instance();
    init_info.PhysicalDevice = coreInstance.get_physical_device();
    init_info.Device = coreInstance.get_device();
    init_info.QueueFamily = coreInstance.get_queuefailmy_indexs()->graphic_queuefamily_index.value();
    init_info.Queue = coreInstance.graphic_queue();
    init_info.PipelineCache = nullptr;
    init_info.DescriptorPool = imguiPool;
    init_info.RenderPass = forward_renderer_pass->get_renderPass();
    init_info.Subpass = 0;
    init_info.MinImageCount = swapchain->MAX_FRAMES_IN_FLIGHT;
    init_info.ImageCount = swapchain->MAX_FRAMES_IN_FLIGHT;;
    init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
    init_info.Allocator = nullptr;
    init_info.CheckVkResultFn = nullptr;
    ImGui_ImplVulkan_Init(&init_info);

    while (main_window.is_window_alive())
    {
        glfwPollEvents();
        // Start the ImGui frame
        ImGui_ImplVulkan_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();
        ImGui::Begin("Hello, world!");
        ImGui::Text("hi");
        ImGui::End();
        ImGui::Begin("Hello2");
        ImGui::Text("hi2");
        ImGui::End();
        //ImGui::ShowDemoWindow();
        
        // Detect resize :
        if (main_window.frameBufferedResized) {
            main_window.frameBufferedResized = false;
            vkDeviceWaitIdle(coreInstance.get_device());
            swapchain->cleanup();
            forward_renderer_pass->cleanup();
            
            swapchain = std::make_unique<ltn::SwapChain>(coreInstance, main_window.SCR_WIDTH, main_window.SCR_HEIGHT);
            forward_renderer_pass = std::make_unique<ltn::Renderer>(coreInstance, *swapchain);
            pipeline = std::make_unique<ltn::GraphicsPipeline>(coreInstance, *swapchain);
            pipeline->create_pipleine(
                forward_renderer_pass->get_renderPass(),
                nullptr
                //gameobject.get_all_descriptorLayouts()
            );
        }

        forward_renderer_pass->reset_renderpass();
        forward_renderer_pass->begin_commandBuffer();

        //===========================
        //Draw commands
        //===========================
        ImGui::Render();
        ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), forward_renderer_pass->get_current_cmdbuffer());


        vkCmdBindPipeline(
            forward_renderer_pass->get_current_cmdbuffer(),
            VK_PIPELINE_BIND_POINT_GRAPHICS,
            pipeline->get_pipeline());

        vkCmdDraw(forward_renderer_pass->get_current_cmdbuffer(), 3, 1, 0, 0);
        //------------------------------

        forward_renderer_pass->end_render();
        forward_renderer_pass->draw_frame();
    }

    vkDeviceWaitIdle(coreInstance.get_device());
    //
    swapchain->cleanup();
    forward_renderer_pass->cleanup();

    ImGui_ImplVulkan_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
}

有趣的點是,由於我先畫Imgui才畫三角形,所以會看到UI疊在下的畫面。






送禮物贊助創作者 !
0
留言

創作回應

樂小呈
原來 Immediate 是每次都重劃的意思🤔
2024-12-21 21:13:16
%%鼠 拒收病婿
度的度度
2024-12-21 22:49:10

相關創作

更多創作