Added Draft on starting a vulkan ImGui context
parent
3c24fcb799
commit
e137cee46d
143
Integrating-with-Vulkan.md
Normal file
143
Integrating-with-Vulkan.md
Normal file
@ -0,0 +1,143 @@
|
||||
# Introduction
|
||||
|
||||
Vulkan is a modern low level graphics api. With vulkan there are changes that is different from OpenGL and DirectX.
|
||||
|
||||
This wiki page is inspired by the article from (François Guthmann)[https://frguthmann.github.io/posts/vulkan_imgui/]
|
||||
|
||||
This is no way a Vulkan tutorial. To get an idea of the Vulkan API please follow the (vulkan-tutorial)[https://vulkan-tutorial.com/]
|
||||
|
||||
Note: I am using Vulkan-HPP headers, but you can certainly use the vulkan.h headers.
|
||||
|
||||
# Implementation
|
||||
|
||||
## ImGui Header Files
|
||||
|
||||
* `imconfig.h`
|
||||
* `imgui.h`
|
||||
* `imgui_internal.h`
|
||||
* `imstb_rectpack.h`
|
||||
* `imstb_textedit.h`
|
||||
* `imstb_truetype.h`
|
||||
|
||||
## ImGui Source Files
|
||||
|
||||
The ImGUI source files you're going to need is.
|
||||
|
||||
* `imgui.cpp`
|
||||
* `imgui_demo.cpp` (optional)
|
||||
* `imgui_draw.cpp`
|
||||
* `imgui_tables.cpp`
|
||||
* `imgui_widgets.cpp`
|
||||
|
||||
## Vulkan Components that is needed for ImGui
|
||||
- `VkInstance`
|
||||
- `VkPhysicalDevice`
|
||||
- `VkDevice`
|
||||
- `VkQueueFamily`
|
||||
- `VkQueue`
|
||||
- `VkDescriptorPool`
|
||||
- `VkCommandPool`
|
||||
- `VkCommandBuffer`
|
||||
- `VkRenderPass`
|
||||
- `VkFramebuffer`
|
||||
|
||||
## Initialize
|
||||
|
||||
First we need to initialize Vulkan. You should already have done so if you're following the (vulkan-tutorial)[https://vulkan-tutorial.com/]. After getting Vulkan running, we can start an ImGui context. It's recommended to create a seperate `VkDescriptorPool`, `VkRenderPass`, `VkCommandBuffer`, and `VkFramebuffer`.
|
||||
|
||||
```c++
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
ImGui_Impl{platform}_InitForVulkan(window, true);
|
||||
```
|
||||
|
||||
After starting an ImGui context, we give ImGui some of the application Vulkan bindings through an `ImGui_ImplVulkan_InitInfo` struct. We then call `ImGui_ImplVulkan_Init()` passing in a pointer to the `ImGui_ImplVulkan_InitInfo` and a `VkRenderPass`. This will initalize Vulkan for ImGui.
|
||||
|
||||
We then upload font textures to the GPU.
|
||||
|
||||
```c++
|
||||
// Allocate a command buffer
|
||||
|
||||
// Record our command buffer
|
||||
cb.begin({vk::CommandBufferUsageFlagBits::eOneTimeSubmit});
|
||||
ImGui_ImplVulkan_CreateFontsTexture(cb);
|
||||
cb.end();
|
||||
|
||||
// Submit to the GPU
|
||||
vk::SubmitInfo si;
|
||||
si.commandBufferCount = cb.size();
|
||||
si.pCommandBuffers = cb.data();
|
||||
vk::Result res = device->getGraphicsQueue().submit(1, &si, {});
|
||||
device->getGraphicsQueue().waitIdle(); // Wait for cb is complete
|
||||
```
|
||||
|
||||
### Begin Frame
|
||||
We need to call the following every frame.
|
||||
|
||||
```c++
|
||||
ImGui_ImplVulkan_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
```
|
||||
|
||||
### Ending Frame
|
||||
When we end the frame, we want to build the model so we can render this to the screen.
|
||||
```c++
|
||||
ImGuiIO& io = ::ImGui::GetIO();
|
||||
ImGui::Render();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable){
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
```
|
||||
|
||||
### Render
|
||||
Once we have the model we can finally submit the draw call.
|
||||
```c++
|
||||
vk::ClearValue clearValue;
|
||||
clearValue.color = vk::ClearColorValue(std::array<float, 4>({0.0f, 0.0f, 0.0f, 1.0f}));
|
||||
cb.begin({vk::CommandBufferUsageFlags()});
|
||||
cb.beginRenderPass({
|
||||
imguiRenderPass,
|
||||
imguiFramebuffers[swapchainCurrentImage],
|
||||
{{0,0}, swapchainExtent},
|
||||
1, &clearValue
|
||||
}, vk::SubpassContents::eInline);
|
||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cb);
|
||||
cb.endRenderPass();
|
||||
cb.end();
|
||||
|
||||
vk::SubmitInfo si;
|
||||
si.commandBufferCount = 1;
|
||||
si.pCommandBuffers = &cb;
|
||||
graphicsQueue->submit(si);
|
||||
```
|
||||
|
||||
### Resize
|
||||
|
||||
When the window viewport resizes, we must create a new `VkFramebuffer` and `VkRenderPass`
|
||||
|
||||
### Clean up
|
||||
|
||||
At the end of the application life-cycle, we must destroy our ImGui context.
|
||||
|
||||
* `ImGui_ImplVulkan_Shutdown()`
|
||||
* `ImGui_ImplGlfw_Shutdown()`
|
||||
* `ImGui::DestroyContext()`
|
||||
|
||||
## Using the API
|
||||
In our application life cycle we should have
|
||||
```c++
|
||||
while(true){
|
||||
updateWindow();
|
||||
|
||||
rendererBeginFrame(); // Acquire images
|
||||
imguiBeginFrame();
|
||||
ImGui::ShowDemoWindow(); // Issue ImGui commands
|
||||
imguiEndFrame();
|
||||
|
||||
imguiRender(); // Submit Command buffers to screen
|
||||
|
||||
rendererPresent(); // Present to the screen
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue
Block a user