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.
// 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

View File

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

View File

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