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

This commit is contained in:
ocornut
2025-04-17 15:39:28 +02:00
parent baffc4e8b8
commit 87f12e56fe
3 changed files with 30 additions and 13 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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);
} }