Browse Source

Backends: SDL_GPU: Added multi-viewport support. Amends + update example. (#8573, #8163, #7998, #7988)

ocornut 3 months ago
parent
commit
87f12e56fe
3 changed files with 30 additions and 13 deletions
  1. 12 13
      backends/imgui_impl_sdlgpu3.cpp
  2. 1 0
      docs/CHANGELOG.txt
  3. 17 0
      examples/example_sdl3_sdlgpu3/main.cpp

+ 12 - 13
backends/imgui_impl_sdlgpu3.cpp

@@ -22,6 +22,7 @@
 //   Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
 //   Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
 
 
 // CHANGELOG
 // CHANGELOG
+//  2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
 //  2025-03-30: Made ImGui_ImplSDLGPU3_PrepareDrawData() reuse GPU Transfer Buffers which were unusually slow to recreate every frame. Much faster now.
 //  2025-03-30: Made ImGui_ImplSDLGPU3_PrepareDrawData() reuse GPU Transfer Buffers which were unusually slow to recreate every frame. Much faster now.
 //  2025-03-21: Fixed typo in function name Imgui_ImplSDLGPU3_PrepareDrawData() -> ImGui_ImplSDLGPU3_PrepareDrawData().
 //  2025-03-21: Fixed typo in function name Imgui_ImplSDLGPU3_PrepareDrawData() -> ImGui_ImplSDLGPU3_PrepareDrawData().
 //  2025-01-16: Renamed ImGui_ImplSDLGPU3_InitInfo::GpuDevice to Device.
 //  2025-01-16: Renamed ImGui_ImplSDLGPU3_InitInfo::GpuDevice to Device.
@@ -581,8 +582,7 @@ bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
     io.BackendRendererUserData = (void*)bd;
     io.BackendRendererUserData = (void*)bd;
     io.BackendRendererName = "imgui_impl_sdlgpu3";
     io.BackendRendererName = "imgui_impl_sdlgpu3";
     io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;  // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
     io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;  // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
-    io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports;
-
+    io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports;  // We can create multi-viewports on the Renderer side (optional)
 
 
     IM_ASSERT(info->Device != nullptr);
     IM_ASSERT(info->Device != nullptr);
     IM_ASSERT(info->ColorTargetFormat != SDL_GPU_TEXTUREFORMAT_INVALID);
     IM_ASSERT(info->ColorTargetFormat != SDL_GPU_TEXTUREFORMAT_INVALID);
@@ -590,13 +590,11 @@ bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
     bd->InitInfo = *info;
     bd->InitInfo = *info;
 
 
     ImGui_ImplSDLGPU3_CreateDeviceObjects();
     ImGui_ImplSDLGPU3_CreateDeviceObjects();
-
     ImGui_ImplSDLGPU3_InitMultiViewportSupport();
     ImGui_ImplSDLGPU3_InitMultiViewportSupport();
 
 
     return true;
     return true;
 }
 }
 
 
-
 void ImGui_ImplSDLGPU3_Shutdown()
 void ImGui_ImplSDLGPU3_Shutdown()
 {
 {
     ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
     ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
@@ -604,7 +602,6 @@ void ImGui_ImplSDLGPU3_Shutdown()
     ImGuiIO& io = ImGui::GetIO();
     ImGuiIO& io = ImGui::GetIO();
 
 
     ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport();
     ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport();
-    
     ImGui_ImplSDLGPU3_DestroyDeviceObjects();
     ImGui_ImplSDLGPU3_DestroyDeviceObjects();
     io.BackendRendererName = nullptr;
     io.BackendRendererName = nullptr;
     io.BackendRendererUserData = nullptr;
     io.BackendRendererUserData = nullptr;
@@ -627,7 +624,8 @@ void ImGui_ImplSDLGPU3_NewFrame()
 // If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
 // If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
 //--------------------------------------------------------------------------------------------------------
 //--------------------------------------------------------------------------------------------------------
 
 
-static void ImGui_ImplSDLGPU3_CreateWindow(ImGuiViewport* viewport) {
+static void ImGui_ImplSDLGPU3_CreateWindow(ImGuiViewport* viewport)
+{
     ImGui_ImplSDLGPU3_Data* data = ImGui_ImplSDLGPU3_GetBackendData();
     ImGui_ImplSDLGPU3_Data* data = ImGui_ImplSDLGPU3_GetBackendData();
     SDL_Window* window = SDL_GetWindowFromID((SDL_WindowID)(intptr_t)viewport->PlatformHandle);
     SDL_Window* window = SDL_GetWindowFromID((SDL_WindowID)(intptr_t)viewport->PlatformHandle);
     SDL_ClaimWindowForGPUDevice(data->InitInfo.Device, window);
     SDL_ClaimWindowForGPUDevice(data->InitInfo.Device, window);
@@ -648,8 +646,7 @@ static void ImGui_ImplSDLGPU3_RenderWindow(ImGuiViewport* viewport, void*)
 
 
     if (swapchain_texture != nullptr)
     if (swapchain_texture != nullptr)
     {
     {
-        ImGui_ImplSDLGPU3_PrepareDrawData(draw_data, command_buffer);
-
+        ImGui_ImplSDLGPU3_PrepareDrawData(draw_data, command_buffer); // FIXME-OPT: Not optimal, may this be done earlier?
         SDL_GPUColorTargetInfo target_info = {};
         SDL_GPUColorTargetInfo target_info = {};
         target_info.texture = swapchain_texture;
         target_info.texture = swapchain_texture;
         target_info.clear_color = SDL_FColor{ 0.0f,0.0f,0.0f,1.0f };
         target_info.clear_color = SDL_FColor{ 0.0f,0.0f,0.0f,1.0f };
@@ -659,25 +656,26 @@ static void ImGui_ImplSDLGPU3_RenderWindow(ImGuiViewport* viewport, void*)
         target_info.layer_or_depth_plane = 0;
         target_info.layer_or_depth_plane = 0;
         target_info.cycle = false;
         target_info.cycle = false;
         SDL_GPURenderPass* render_pass = SDL_BeginGPURenderPass(command_buffer, &target_info, 1, nullptr);
         SDL_GPURenderPass* render_pass = SDL_BeginGPURenderPass(command_buffer, &target_info, 1, nullptr);
-
         ImGui_ImplSDLGPU3_RenderDrawData(draw_data, command_buffer, render_pass);
         ImGui_ImplSDLGPU3_RenderDrawData(draw_data, command_buffer, render_pass);
-
         SDL_EndGPURenderPass(render_pass);
         SDL_EndGPURenderPass(render_pass);
     }
     }
 
 
     SDL_SubmitGPUCommandBuffer(command_buffer);
     SDL_SubmitGPUCommandBuffer(command_buffer);
 }
 }
 
 
-static void ImGui_ImplSDLGPU3_DestroyWindow(ImGuiViewport* viewport) {
+static void ImGui_ImplSDLGPU3_DestroyWindow(ImGuiViewport* viewport)
+{
     ImGui_ImplSDLGPU3_Data* data = ImGui_ImplSDLGPU3_GetBackendData();
     ImGui_ImplSDLGPU3_Data* data = ImGui_ImplSDLGPU3_GetBackendData();
-    if (viewport->RendererUserData) {
+    if (viewport->RendererUserData)
+    {
         SDL_Window* window = SDL_GetWindowFromID((SDL_WindowID)(intptr_t)viewport->PlatformHandle);
         SDL_Window* window = SDL_GetWindowFromID((SDL_WindowID)(intptr_t)viewport->PlatformHandle);
         SDL_ReleaseWindowFromGPUDevice(data->InitInfo.Device, window);
         SDL_ReleaseWindowFromGPUDevice(data->InitInfo.Device, window);
     }
     }
     viewport->RendererUserData = nullptr;
     viewport->RendererUserData = nullptr;
 }
 }
 
 
-static void ImGui_ImplSDLGPU3_InitMultiViewportSupport() {
+static void ImGui_ImplSDLGPU3_InitMultiViewportSupport()
+{
     ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
     ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
     platform_io.Renderer_RenderWindow = ImGui_ImplSDLGPU3_RenderWindow;
     platform_io.Renderer_RenderWindow = ImGui_ImplSDLGPU3_RenderWindow;
     platform_io.Renderer_CreateWindow = ImGui_ImplSDLGPU3_CreateWindow;
     platform_io.Renderer_CreateWindow = ImGui_ImplSDLGPU3_CreateWindow;
@@ -689,5 +687,6 @@ static void ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport()
     ImGui::DestroyPlatformWindows();
     ImGui::DestroyPlatformWindows();
 }
 }
 
 
+//-----------------------------------------------------------------------------
 
 
 #endif // #ifndef IMGUI_DISABLE
 #endif // #ifndef IMGUI_DISABLE

+ 1 - 0
docs/CHANGELOG.txt

@@ -113,6 +113,7 @@ Docking+Viewports Branch:
   Because we allowed the Win32 window to close early, Windows destroyed
   Because we allowed the Win32 window to close early, Windows destroyed
   it and our imgui window became not visible even though user code was
   it and our imgui window became not visible even though user code was
   still submitting it.
   still submitting it.
+- Backends: SDLGPU3 for SDL3: added multi-viewport support. (#8573) [@Lekoopapaul]
 - Backends: SDL2, SDL3: revert updating monitors and work areas info every
 - Backends: SDL2, SDL3: revert updating monitors and work areas info every
   frame. Only do it on Windows to detect task-bar resize until we get an
   frame. Only do it on Windows to detect task-bar resize until we get an
   adequate event for it. (#8415, #8558)
   adequate event for it. (#8415, #8558)

+ 17 - 0
examples/example_sdl3_sdlgpu3/main.cpp

@@ -63,11 +63,21 @@ int main(int, char**)
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
     io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
     io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls
     io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls
+    io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;         // Enable Docking
+    io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;       // Enable Multi-Viewport / Platform Windows
 
 
     // Setup Dear ImGui style
     // Setup Dear ImGui style
     ImGui::StyleColorsDark();
     ImGui::StyleColorsDark();
     //ImGui::StyleColorsLight();
     //ImGui::StyleColorsLight();
 
 
+    // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
+    ImGuiStyle& style = ImGui::GetStyle();
+    if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+    {
+        style.WindowRounding = 0.0f;
+        style.Colors[ImGuiCol_WindowBg].w = 1.0f;
+    }
+
     // Setup Platform/Renderer backends
     // Setup Platform/Renderer backends
     ImGui_ImplSDL3_InitForSDLGPU(window);
     ImGui_ImplSDL3_InitForSDLGPU(window);
     ImGui_ImplSDLGPU3_InitInfo init_info = {};
     ImGui_ImplSDLGPU3_InitInfo init_info = {};
@@ -198,6 +208,13 @@ int main(int, char**)
             SDL_EndGPURenderPass(render_pass);
             SDL_EndGPURenderPass(render_pass);
         }
         }
 
 
+        // Update and Render additional Platform Windows
+        if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+        {
+            ImGui::UpdatePlatformWindows();
+            ImGui::RenderPlatformWindowsDefault();
+        }
+
         // Submit the command buffer
         // Submit the command buffer
         SDL_SubmitGPUCommandBuffer(command_buffer);
         SDL_SubmitGPUCommandBuffer(command_buffer);
     }
     }