4#include <backends/imgui_impl_sdl3.h>
5#include <backends/imgui_impl_vulkan.h>
13 : m_p_window(window), m_r_context(vulkanContext) {}
18 vkDeviceWaitIdle(m_r_context.device);
20 ImGui_ImplVulkan_Shutdown();
22 if (m_imguiPool != VK_NULL_HANDLE) {
23 vkDestroyDescriptorPool(m_r_context.device, m_imguiPool,
nullptr);
24 m_imguiPool = VK_NULL_HANDLE;
27 ImGui_ImplSDL3_Shutdown();
28 ImGui::DestroyContext();
35 return ImGui_ImplVulkan_AddTexture(sampler, imageView, layout);
37 return VK_NULL_HANDLE;
43 if (descriptorSet != VK_NULL_HANDLE) {
44 ImGui_ImplVulkan_RemoveTexture(descriptorSet);
53 log(
"Initialization of DearImGUI");
55 volatile auto forceLink = ImGuizmo::BeginFrame;
59 ImGui::CreateContext();
60 }
catch (
const std::exception& e) {
61 log(LogLevel::ERROR,
"ImGUI Init Failed");
64 ImGuiIO& io = ImGui::GetIO();
66 io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
67 io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
68 io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
70 if(std::filesystem::exists(
"../Assets/Sono-SemiBold.ttf")){
71 ImFont* myFont = io.Fonts->AddFontFromFileTTF(
"../Assets/Sono-SemiBold.ttf", 14.0f);
73 if (myFont ==
nullptr) {
74 log(LogLevel::WARNING,
"Failed to load editor font!");
75 io.Fonts->AddFontDefault();
78 log(LogLevel::WARNING,
"Failed to load editor font!");
79 io.Fonts->AddFontDefault();
82 if (!vkCreateSampler || !vkCreateDescriptorPool) {
83 throw_error(
"Critical Vulkan function pointers are null!");
86 ImGui_ImplSDL3_InitForVulkan(m_p_window);
88 createDescriptorPool();
90 ImGui_ImplVulkan_InitInfo initInfo = {};
91 initInfo.Instance = m_r_context.instance;
92 initInfo.PhysicalDevice = m_r_context.physicalDevice;
93 initInfo.Device = m_r_context.device;
94 initInfo.QueueFamily = m_r_context.graphicsQueueFamily;
95 initInfo.Queue = m_r_context.graphicsQueue;
96 initInfo.PipelineCache = VK_NULL_HANDLE;
97 initInfo.MinImageCount = m_r_context.swapchainImages.size();
98 initInfo.ImageCount = m_r_context.swapchainImages.size();
99 initInfo.CheckVkResultFn = [](VkResult err) {
100 if (err != VK_SUCCESS) {
101 SDL_LogError(SDL_LOG_CATEGORY_ERROR,
"ImGui Vulkan error: %d", err);
104 initInfo.Allocator =
nullptr;
105 initInfo.DescriptorPool = m_imguiPool;
106 initInfo.UseDynamicRendering =
true;
109 VkPipelineRenderingCreateInfoKHR pipelineRenderingCreateInfo = {};
110 pipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
111 pipelineRenderingCreateInfo.colorAttachmentCount = 1;
112 pipelineRenderingCreateInfo.pColorAttachmentFormats = &m_r_context.swapchainImageFormat;
113 pipelineRenderingCreateInfo.depthAttachmentFormat = m_r_context.depthFormat;
115 ImGui_ImplVulkan_PipelineInfo pipelineInfoMain = {};
116 pipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
117 pipelineInfoMain.PipelineRenderingCreateInfo = pipelineRenderingCreateInfo;
119 initInfo.PipelineInfoMain = pipelineInfoMain;
121 log(
"Initing ImGui Vulkan backend");
122 if (!ImGui_ImplVulkan_Init(&initInfo)) {
123 throw_error(
"Failed to initialize ImGui Vulkan backend");
128 m_initialized =
true;
129 }
catch (
const std::exception& e) {
130 log(LogLevel::ERROR,
"ImGUI Init Failed");
136 ImGui_ImplVulkan_NewFrame();
137 ImGui_ImplSDL3_NewFrame();
140 ImGuiIO& io = ImGui::GetIO();
141 io.DisplaySize = ImVec2(
142 (
float)m_r_context.currentRenderResolution.x,
143 (
float)m_r_context.currentRenderResolution.y
145 io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
151 ImGuiIO& io = ImGui::GetIO();
152 if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
153 ImGui::UpdatePlatformWindows();
154 ImGui::RenderPlatformWindowsDefault();
158 void VulkanImGUIWrapper::draw(VkCommandBuffer commandBuffer) {
159 ImDrawData* drawData = ImGui::GetDrawData();
161 ImGui_ImplVulkan_RenderDrawData(drawData, commandBuffer);
166 ImGuiIO& io = ImGui::GetIO();
169 float scaleX = (float)m_r_context.swapchainExtent.width /
170 (
float)m_r_context.currentRenderResolution.x;
171 float scaleY = (float)m_r_context.swapchainExtent.height /
172 (
float)m_r_context.currentRenderResolution.y;
174 switch (event->type) {
175 case SDL_EVENT_MOUSE_MOTION: {
176 io.MousePos = ImVec2(
177 event->motion.x / scaleX,
178 event->motion.y / scaleY
182 case SDL_EVENT_MOUSE_BUTTON_DOWN:
183 case SDL_EVENT_MOUSE_BUTTON_UP: {
184 io.MousePos = ImVec2(
185 event->button.x / scaleX,
186 event->button.y / scaleY
188 ImGui_ImplSDL3_ProcessEvent(event);
192 ImGui_ImplSDL3_ProcessEvent(event);
198 ImGuiIO& VulkanImGUIWrapper::getIO() {
199 return ImGui::GetIO();
202 void VulkanImGUIWrapper::createDescriptorPool() {
203 log(
"Creating ImGUI DescriptorPools");
205 VkDescriptorPoolSize poolSizes[] = {
206 { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
207 { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
208 { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
209 { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
210 { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
211 { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
212 { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
213 { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
214 { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
215 { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
216 { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
219 VkDescriptorPoolCreateInfo poolInfo = {};
220 poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
221 poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
222 poolInfo.maxSets = 1000 * IM_ARRAYSIZE(poolSizes);
223 poolInfo.poolSizeCount = (uint32_t)IM_ARRAYSIZE(poolSizes);
224 poolInfo.pPoolSizes = poolSizes;
226 if (vkCreateDescriptorPool(m_r_context.device, &poolInfo,
nullptr, &m_imguiPool) != VK_SUCCESS) {
227 throw_error(
"Failed to create descriptor pool for ImGui");
231 void VulkanImGUIWrapper::setupStyle() {
232 ImGui::StyleColorsDark();
234 ImGuiStyle& style = ImGui::GetStyle();
236 style.WindowPadding = ImVec2(10, 10);
237 style.FramePadding = ImVec2(5, 5);
238 style.ItemSpacing = ImVec2(6, 6);
239 style.ItemInnerSpacing = ImVec2(4, 4);
240 style.IndentSpacing = 4.0f;
241 style.ScrollbarSize = 12.0f;
242 style.GrabMinSize = 4.0f;
244 style.WindowRounding = 6.0f;
245 style.ChildRounding = 6.0f;
246 style.FrameRounding = 4.0f;
247 style.PopupRounding = 6.0f;
248 style.ScrollbarRounding = 9.0f;
249 style.GrabRounding = 4.0f;
250 style.TabRounding = 6.0f;
252 ImVec4* colors = style.Colors;
255 const ImVec4 colTextWhite = ImVec4(0.94f, 0.85f, 0.85f, 1.00f);
256 const ImVec4 colOrangeBase = ImVec4(1.00f, 0.23f, 0.01f, 1.00f);
257 const ImVec4 colRedBase = ImVec4(0.47f, 0.05f, 0.05f, 1.00f);
258 const ImVec4 colBgBase = ImVec4(0.015f, 0.015f, 0.019f, 1.00f);
259 const ImVec4 colBgDark = ImVec4(0.012f, 0.012f, 0.014f, 1.00f);
260 const ImVec4 colBgLight = ImVec4(0.02f, 0.02f, 0.024f, 1.00f);
263 colors[ImGuiCol_Text] = colTextWhite;
264 colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
267 colors[ImGuiCol_WindowBg] = colBgBase;
268 colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
269 colors[ImGuiCol_PopupBg] = colBgLight;
270 colors[ImGuiCol_MenuBarBg] = colBgDark;
273 colors[ImGuiCol_Border] = ImVec4(0.47f, 0.05f, 0.05f, 0.40f);
274 colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
277 colors[ImGuiCol_FrameBg] = colBgDark;
278 colors[ImGuiCol_FrameBgHovered] = colBgBase;
279 colors[ImGuiCol_FrameBgActive] = ImVec4(0.47f, 0.05f, 0.05f, 0.50f);
282 colors[ImGuiCol_TitleBg] = colBgDark;
283 colors[ImGuiCol_TitleBgActive] = colBgBase;
284 colors[ImGuiCol_TitleBgCollapsed] = colBgDark;
287 colors[ImGuiCol_ScrollbarBg] = colBgDark;
288 colors[ImGuiCol_ScrollbarGrab] = ImVec4(1.00f, 0.23f, 0.01f, 0.40f);
289 colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(1.00f, 0.23f, 0.01f, 0.70f);
290 colors[ImGuiCol_ScrollbarGrabActive] = colOrangeBase;
293 colors[ImGuiCol_CheckMark] = colOrangeBase;
294 colors[ImGuiCol_SliderGrab] = colOrangeBase;
295 colors[ImGuiCol_SliderGrabActive] = colOrangeBase;
298 colors[ImGuiCol_Button] = colBgLight;
299 colors[ImGuiCol_ButtonHovered] = ImVec4(1.00f, 0.23f, 0.01f, 0.20f);
300 colors[ImGuiCol_ButtonActive] = ImVec4(1.00f, 0.23f, 0.01f, 0.40f);
303 colors[ImGuiCol_Header] = colBgLight;
304 colors[ImGuiCol_HeaderHovered] = ImVec4(1.00f, 0.23f, 0.01f, 0.30f);
305 colors[ImGuiCol_HeaderActive] = ImVec4(1.00f, 0.23f, 0.01f, 0.50f);
308 colors[ImGuiCol_Separator] = ImVec4(0.47f, 0.05f, 0.05f, 0.40f);
309 colors[ImGuiCol_SeparatorHovered] = ImVec4(0.47f, 0.05f, 0.05f, 0.70f);
310 colors[ImGuiCol_SeparatorActive] = colRedBase;
313 colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 0.23f, 0.01f, 0.25f);
314 colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 0.23f, 0.01f, 0.67f);
315 colors[ImGuiCol_ResizeGripActive] = colOrangeBase;
318 colors[ImGuiCol_Tab] = colBgDark;
319 colors[ImGuiCol_TabHovered] = ImVec4(1.00f, 0.23f, 0.01f, 0.40f);
320 colors[ImGuiCol_TabActive] = colBgBase;
321 colors[ImGuiCol_TabUnfocused] = colBgDark;
322 colors[ImGuiCol_TabUnfocusedActive] = colBgBase;
325 colors[ImGuiCol_DockingPreview] = ImVec4(1.00f, 0.23f, 0.01f, 0.30f);
326 colors[ImGuiCol_DockingEmptyBg] = colBgBase;
329 colors[ImGuiCol_PlotLines] = colTextWhite;
330 colors[ImGuiCol_PlotLinesHovered] = colOrangeBase;
331 colors[ImGuiCol_PlotHistogram] = colOrangeBase;
332 colors[ImGuiCol_PlotHistogramHovered] = colOrangeBase;
333 colors[ImGuiCol_TextSelectedBg] = ImVec4(1.00f, 0.23f, 0.01f, 0.35f);
334 colors[ImGuiCol_DragDropTarget] = colOrangeBase;
335 colors[ImGuiCol_NavHighlight] = colOrangeBase;
337 colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.5f);
This file defines class with Imgui for vulkan backend definition.
virtual ~VulkanImGUIWrapper()
Destructor for VulkanImGUIWrapper.
void init() override
Initialization called inside Engine class.
VulkanImGUIWrapper(SDL_Window *window, VulkanContext &vulkanContext)
Constructor for VulkanImGUIWrapper.
void processEvent(const SDL_Event *event) override
Its used to process input needed by interaction with ImGui.
void beginFrame() override
Begining of UI rendering called in vex::Renderer::renderFrame.
void removeTexture(VkDescriptorSet descriptorSet)
Removes a texture from the ImGUI wrapper.
void endFrame() override
Ends UI rendering for frame.
VkDescriptorSet addTexture(VkSampler sampler, VkImageView imageView, VkImageLayout layout)
Adds a texture to the ImGUI wrapper.
void VEX_EXPORT throw_error(const std::string &msg)
Throws an error or terminates the application.
void VEX_EXPORT log(const char *fmt,...)
Logs a formatted message.
void VEX_EXPORT handle_critical_exception(const std::exception &e)
Handles a critical exception, forcing termination.
Struct holding all vulkan data, like device, surface, swapchain, images, views, and more.