Parcourir la source

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

ocornut il y a 3 mois
Parent
commit
87f12e56fe
3 fichiers modifiés avec 30 ajouts et 13 suppressions
  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.
 
 // 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-21: Fixed typo in function name Imgui_ImplSDLGPU3_PrepareDrawData() -> ImGui_ImplSDLGPU3_PrepareDrawData().
 //  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.BackendRendererName = "imgui_impl_sdlgpu3";
     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->ColorTargetFormat != SDL_GPU_TEXTUREFORMAT_INVALID);
@@ -590,13 +590,11 @@ bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
     bd->InitInfo = *info;
 
     ImGui_ImplSDLGPU3_CreateDeviceObjects();
-
     ImGui_ImplSDLGPU3_InitMultiViewportSupport();
 
     return true;
 }
 
-
 void ImGui_ImplSDLGPU3_Shutdown()
 {
     ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
@@ -604,7 +602,6 @@ void ImGui_ImplSDLGPU3_Shutdown()
     ImGuiIO& io = ImGui::GetIO();
 
     ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport();
-    
     ImGui_ImplSDLGPU3_DestroyDeviceObjects();
     io.BackendRendererName = 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..
 //--------------------------------------------------------------------------------------------------------
 
-static void ImGui_ImplSDLGPU3_CreateWindow(ImGuiViewport* viewport) {
+static void ImGui_ImplSDLGPU3_CreateWindow(ImGuiViewport* viewport)
+{
     ImGui_ImplSDLGPU3_Data* data = ImGui_ImplSDLGPU3_GetBackendData();
     SDL_Window* window = SDL_GetWindowFromID((SDL_WindowID)(intptr_t)viewport->PlatformHandle);
     SDL_ClaimWindowForGPUDevice(data->InitInfo.Device, window);
@@ -648,8 +646,7 @@ static void ImGui_ImplSDLGPU3_RenderWindow(ImGuiViewport* viewport, void*)
 
     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 = {};
         target_info.texture = swapchain_texture;
         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.cycle = false;
         SDL_GPURenderPass* render_pass = SDL_BeginGPURenderPass(command_buffer, &target_info, 1, nullptr);
-
         ImGui_ImplSDLGPU3_RenderDrawData(draw_data, command_buffer, render_pass);
-
         SDL_EndGPURenderPass(render_pass);
     }
 
     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();
-    if (viewport->RendererUserData) {
+    if (viewport->RendererUserData)
+    {
         SDL_Window* window = SDL_GetWindowFromID((SDL_WindowID)(intptr_t)viewport->PlatformHandle);
         SDL_ReleaseWindowFromGPUDevice(data->InitInfo.Device, window);
     }
     viewport->RendererUserData = nullptr;
 }
 
-static void ImGui_ImplSDLGPU3_InitMultiViewportSupport() {
+static void ImGui_ImplSDLGPU3_InitMultiViewportSupport()
+{
     ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
     platform_io.Renderer_RenderWindow = ImGui_ImplSDLGPU3_RenderWindow;
     platform_io.Renderer_CreateWindow = ImGui_ImplSDLGPU3_CreateWindow;
@@ -689,5 +687,6 @@ static void ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport()
     ImGui::DestroyPlatformWindows();
 }
 
+//-----------------------------------------------------------------------------
 
 #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
   it and our imgui window became not visible even though user code was
   still submitting it.
+- Backends: SDLGPU3 for SDL3: added multi-viewport support. (#8573) [@Lekoopapaul]
 - 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
   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;
     io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard 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
     ImGui::StyleColorsDark();
     //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
     ImGui_ImplSDL3_InitForSDLGPU(window);
     ImGui_ImplSDLGPU3_InitInfo init_info = {};
@@ -198,6 +208,13 @@ int main(int, char**)
             SDL_EndGPURenderPass(render_pass);
         }
 
+        // Update and Render additional Platform Windows
+        if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+        {
+            ImGui::UpdatePlatformWindows();
+            ImGui::RenderPlatformWindowsDefault();
+        }
+
         // Submit the command buffer
         SDL_SubmitGPUCommandBuffer(command_buffer);
     }