From c9b7cf85ba8488a3c2cb6af9bc7b9609b032ff12 Mon Sep 17 00:00:00 2001 From: James Johnson Date: Sat, 15 Nov 2025 09:13:20 -0500 Subject: [PATCH 1/2] Split ImGuiImplSDL class into two for the SDL2 and SDL3 backends. --- Imgui/CMakeLists.txt | 6 +- .../{ImGuiImplSDL.hpp => ImGuiImplSDL2.hpp} | 16 ++-- Imgui/interface/ImGuiImplSDL3.hpp | 59 ++++++++++++ .../{ImGuiImplSDL.cpp => ImGuiImplSDL2.cpp} | 24 ++--- Imgui/src/ImGuiImplSDL3.cpp | 95 +++++++++++++++++++ 5 files changed, 178 insertions(+), 22 deletions(-) rename Imgui/interface/{ImGuiImplSDL.hpp => ImGuiImplSDL2.hpp} (81%) create mode 100644 Imgui/interface/ImGuiImplSDL3.hpp rename Imgui/src/{ImGuiImplSDL.cpp => ImGuiImplSDL2.cpp} (79%) create mode 100644 Imgui/src/ImGuiImplSDL3.cpp diff --git a/Imgui/CMakeLists.txt b/Imgui/CMakeLists.txt index 65ac1eb0..e91fa671 100644 --- a/Imgui/CMakeLists.txt +++ b/Imgui/CMakeLists.txt @@ -20,8 +20,10 @@ set(INTERFACE ) if(EXISTS "${DILIGENT_DEAR_IMGUI_PATH}/backends") - list(APPEND SOURCE src/ImGuiImplSDL.cpp) - list(APPEND INTERFACE interface/ImGuiImplSDL.hpp) + list(APPEND SOURCE src/ImGuiImplSDL2.cpp) + list(APPEND SOURCE src/ImGuiImplSDL3.cpp) + list(APPEND INTERFACE interface/ImGuiImplSDL2.hpp) + list(APPEND INTERFACE interface/ImGuiImplSDL3.hpp) if(PLATFORM_WIN32) list(APPEND SOURCE src/ImGuiImplWin32.cpp) list(APPEND INTERFACE interface/ImGuiImplWin32.hpp) diff --git a/Imgui/interface/ImGuiImplSDL.hpp b/Imgui/interface/ImGuiImplSDL2.hpp similarity index 81% rename from Imgui/interface/ImGuiImplSDL.hpp rename to Imgui/interface/ImGuiImplSDL2.hpp index 98743765..0403c8ea 100644 --- a/Imgui/interface/ImGuiImplSDL.hpp +++ b/Imgui/interface/ImGuiImplSDL2.hpp @@ -34,20 +34,20 @@ extern "C" union SDL_Event; namespace Diligent { -class ImGuiImplSDL final : public ImGuiImplDiligent +class ImGuiImplSDL2 final : public ImGuiImplDiligent { public: - static std::unique_ptr + static std::unique_ptr Create(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow); - ImGuiImplSDL(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow); - ~ImGuiImplSDL(); + ImGuiImplSDL2(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow); + ~ImGuiImplSDL2(); // clang-format off - ImGuiImplSDL (const ImGuiImplSDL&) = delete; - ImGuiImplSDL ( ImGuiImplSDL&&) = delete; - ImGuiImplSDL& operator = (const ImGuiImplSDL&) = delete; - ImGuiImplSDL& operator = ( ImGuiImplSDL&&) = delete; + ImGuiImplSDL2 (const ImGuiImplSDL2&) = delete; + ImGuiImplSDL2 ( ImGuiImplSDL2&&) = delete; + ImGuiImplSDL2& operator = (const ImGuiImplSDL2&) = delete; + ImGuiImplSDL2& operator = ( ImGuiImplSDL2&&) = delete; // clang-format on virtual void NewFrame(Uint32 RenderSurfaceWidth, diff --git a/Imgui/interface/ImGuiImplSDL3.hpp b/Imgui/interface/ImGuiImplSDL3.hpp new file mode 100644 index 00000000..a15a9a43 --- /dev/null +++ b/Imgui/interface/ImGuiImplSDL3.hpp @@ -0,0 +1,59 @@ +/* + * Copyright 2025 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include "ImGuiImplDiligent.hpp" + +extern "C" struct SDL_Window; +extern "C" union SDL_Event; + +namespace Diligent +{ +class ImGuiImplSDL3 final : public ImGuiImplDiligent +{ +public: + static std::unique_ptr + Create(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow); + + ImGuiImplSDL3(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow); + ~ImGuiImplSDL3(); + + // clang-format off + ImGuiImplSDL3 (const ImGuiImplSDL3&) = delete; + ImGuiImplSDL3 ( ImGuiImplSDL3&&) = delete; + ImGuiImplSDL3& operator = (const ImGuiImplSDL3&) = delete; + ImGuiImplSDL3& operator = ( ImGuiImplSDL3&&) = delete; + // clang-format on + + virtual void NewFrame(Uint32 RenderSurfaceWidth, + Uint32 RenderSurfaceHeight, + SURFACE_TRANSFORM SurfacePreTransform) override final; + virtual void Render(IDeviceContext* pCtx) override final; + bool HandleSDLEvent(const SDL_Event* ev); +}; +} // namespace Diligent diff --git a/Imgui/src/ImGuiImplSDL.cpp b/Imgui/src/ImGuiImplSDL2.cpp similarity index 79% rename from Imgui/src/ImGuiImplSDL.cpp rename to Imgui/src/ImGuiImplSDL2.cpp index 4c4051ee..6916e06c 100644 --- a/Imgui/src/ImGuiImplSDL.cpp +++ b/Imgui/src/ImGuiImplSDL2.cpp @@ -24,7 +24,7 @@ * of the possibility of such damages. */ -#include "ImGuiImplSDL.hpp" +#include "ImGuiImplSDL2.hpp" #include "Errors.hpp" #include "RenderDevice.h" @@ -33,14 +33,14 @@ namespace Diligent { -std::unique_ptr -ImGuiImplSDL::Create(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow) +std::unique_ptr +ImGuiImplSDL2::Create(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow) { - return std::make_unique(CI, pWindow); + return std::make_unique(CI, pWindow); } -ImGuiImplSDL::ImGuiImplSDL(const ImGuiDiligentCreateInfo& CI, - SDL_Window* pWindow) : +ImGuiImplSDL2::ImGuiImplSDL2(const ImGuiDiligentCreateInfo& CI, + SDL_Window* pWindow) : ImGuiImplDiligent(CI) { switch (CI.pDevice->GetDeviceInfo().Type) @@ -71,23 +71,23 @@ ImGuiImplSDL::ImGuiImplSDL(const ImGuiDiligentCreateInfo& CI, } } -ImGuiImplSDL::~ImGuiImplSDL() { ImGui_ImplSDL2_Shutdown(); } +ImGuiImplSDL2::~ImGuiImplSDL2() { ImGui_ImplSDL2_Shutdown(); } -void ImGuiImplSDL::NewFrame(Uint32 RenderSurfaceWidth, - Uint32 RenderSurfaceHeight, - SURFACE_TRANSFORM SurfacePreTransform) +void ImGuiImplSDL2::NewFrame(Uint32 RenderSurfaceWidth, + Uint32 RenderSurfaceHeight, + SURFACE_TRANSFORM SurfacePreTransform) { ImGui_ImplSDL2_NewFrame(); ImGuiImplDiligent::NewFrame(RenderSurfaceWidth, RenderSurfaceHeight, SurfacePreTransform); } -void ImGuiImplSDL::Render(IDeviceContext* pCtx) +void ImGuiImplSDL2::Render(IDeviceContext* pCtx) { ImGuiImplDiligent::Render(pCtx); } -bool ImGuiImplSDL::HandleSDLEvent(const SDL_Event* ev) +bool ImGuiImplSDL2::HandleSDLEvent(const SDL_Event* ev) { return ImGui_ImplSDL2_ProcessEvent(ev); } diff --git a/Imgui/src/ImGuiImplSDL3.cpp b/Imgui/src/ImGuiImplSDL3.cpp new file mode 100644 index 00000000..e5a57729 --- /dev/null +++ b/Imgui/src/ImGuiImplSDL3.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2025 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "ImGuiImplSDL3.hpp" + +#include "Errors.hpp" +#include "RenderDevice.h" +#include "backends/imgui_impl_sdl3.h" + +namespace Diligent +{ + +std::unique_ptr +ImGuiImplSDL3::Create(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow) +{ + return std::make_unique(CI, pWindow); +} + +ImGuiImplSDL3::ImGuiImplSDL3(const ImGuiDiligentCreateInfo& CI, + SDL_Window* pWindow) : + ImGuiImplDiligent(CI) +{ + switch (CI.pDevice->GetDeviceInfo().Type) + { + case RENDER_DEVICE_TYPE_UNDEFINED: + LOG_ERROR_AND_THROW("Undefined device type"); + break; + case RENDER_DEVICE_TYPE_D3D11: + case RENDER_DEVICE_TYPE_D3D12: + ImGui_ImplSDL3_InitForD3D(pWindow); + break; + case RENDER_DEVICE_TYPE_GL: + case RENDER_DEVICE_TYPE_GLES: + ImGui_ImplSDL3_InitForOpenGL(pWindow, nullptr); + break; + case RENDER_DEVICE_TYPE_VULKAN: + ImGui_ImplSDL3_InitForVulkan(pWindow); + break; + case RENDER_DEVICE_TYPE_METAL: + ImGui_ImplSDL3_InitForMetal(pWindow); + break; + case RENDER_DEVICE_TYPE_WEBGPU: + LOG_ERROR_AND_THROW("WebGPU not supported"); + break; + case RENDER_DEVICE_TYPE_COUNT: + LOG_ERROR_AND_THROW("Unsupported device type"); + break; + } +} + +ImGuiImplSDL3::~ImGuiImplSDL3() { ImGui_ImplSDL3_Shutdown(); } + +void ImGuiImplSDL3::NewFrame(Uint32 RenderSurfaceWidth, + Uint32 RenderSurfaceHeight, + SURFACE_TRANSFORM SurfacePreTransform) +{ + ImGui_ImplSDL3_NewFrame(); + ImGuiImplDiligent::NewFrame(RenderSurfaceWidth, RenderSurfaceHeight, + SurfacePreTransform); +} + +void ImGuiImplSDL3::Render(IDeviceContext* pCtx) +{ + ImGuiImplDiligent::Render(pCtx); +} + +bool ImGuiImplSDL3::HandleSDLEvent(const SDL_Event* ev) +{ + return ImGui_ImplSDL3_ProcessEvent(ev); +} + +} // namespace Diligent From f512671c1e50fe082df98a9ad9b9ab40b7f896b3 Mon Sep 17 00:00:00 2001 From: James Johnson Date: Tue, 18 Nov 2025 19:45:57 -0500 Subject: [PATCH 2/2] Wrap the auxiliary functions for ImGuiImplSDL2 and 3. --- Imgui/interface/ImGuiImplSDL2.hpp | 10 ++++++++++ Imgui/interface/ImGuiImplSDL3.hpp | 8 ++++++++ Imgui/src/ImGuiImplSDL2.cpp | 28 ++++++++++++++++++++++++++++ Imgui/src/ImGuiImplSDL3.cpp | 18 ++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/Imgui/interface/ImGuiImplSDL2.hpp b/Imgui/interface/ImGuiImplSDL2.hpp index 0403c8ea..f4943d6a 100644 --- a/Imgui/interface/ImGuiImplSDL2.hpp +++ b/Imgui/interface/ImGuiImplSDL2.hpp @@ -30,6 +30,7 @@ #include "ImGuiImplDiligent.hpp" extern "C" struct SDL_Window; +extern "C" struct _SDL_GameController; extern "C" union SDL_Event; namespace Diligent @@ -55,5 +56,14 @@ class ImGuiImplSDL2 final : public ImGuiImplDiligent SURFACE_TRANSFORM SurfacePreTransform) override final; virtual void Render(IDeviceContext* pCtx) override final; bool HandleSDLEvent(const SDL_Event* ev); + float GetContentScaleForWindow(SDL_Window* pWindow); + float GetContentScaleForDisplay(int DisplayIndex); + enum GAMEPAD_MODE + { + GAMEPAD_MODE_AUTO_FIRST, + GAMEPAD_MODE_AUTO_ALL, + GAMEPAD_MODE_MANUAL + }; + void SetGamepadMode(GAMEPAD_MODE mode, _SDL_GameController** ppManualGamepadsArray = nullptr, int ManualGamepadsCount = -1); }; } // namespace Diligent diff --git a/Imgui/interface/ImGuiImplSDL3.hpp b/Imgui/interface/ImGuiImplSDL3.hpp index a15a9a43..aa9f2f37 100644 --- a/Imgui/interface/ImGuiImplSDL3.hpp +++ b/Imgui/interface/ImGuiImplSDL3.hpp @@ -30,6 +30,7 @@ #include "ImGuiImplDiligent.hpp" extern "C" struct SDL_Window; +extern "C" struct SDL_Gamepad; extern "C" union SDL_Event; namespace Diligent @@ -55,5 +56,12 @@ class ImGuiImplSDL3 final : public ImGuiImplDiligent SURFACE_TRANSFORM SurfacePreTransform) override final; virtual void Render(IDeviceContext* pCtx) override final; bool HandleSDLEvent(const SDL_Event* ev); + enum GAMEPAD_MODE + { + GAMEPAD_MODE_AUTO_FIRST, + GAMEPAD_MODE_AUTO_ALL, + GAMEPAD_MODE_MANUAL + }; + void SetGamepadMode(GAMEPAD_MODE mode, SDL_Gamepad** ppManualGamepadsArray = nullptr, int ManualGamepadsCount = -1); }; } // namespace Diligent diff --git a/Imgui/src/ImGuiImplSDL2.cpp b/Imgui/src/ImGuiImplSDL2.cpp index 6916e06c..9aa76fc2 100644 --- a/Imgui/src/ImGuiImplSDL2.cpp +++ b/Imgui/src/ImGuiImplSDL2.cpp @@ -92,4 +92,32 @@ bool ImGuiImplSDL2::HandleSDLEvent(const SDL_Event* ev) return ImGui_ImplSDL2_ProcessEvent(ev); } +float ImGuiImplSDL2::GetContentScaleForWindow(SDL_Window* pWindow) +{ + return ImGui_ImplSDL2_GetContentScaleForWindow(pWindow); +} + +float ImGuiImplSDL2::GetContentScaleForDisplay(int DisplayIndex) +{ + return ImGui_ImplSDL2_GetContentScaleForDisplay(DisplayIndex); +} + +void ImGuiImplSDL2::SetGamepadMode(GAMEPAD_MODE GamepadMode, _SDL_GameController** ppManualGamepadsArray, int ManualGamepadsCount) +{ + ImGui_ImplSDL2_GamepadMode imgGamepadMode{}; + switch (GamepadMode) + { + case GAMEPAD_MODE_AUTO_FIRST: + imgGamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst; + break; + case GAMEPAD_MODE_AUTO_ALL: + imgGamepadMode = ImGui_ImplSDL2_GamepadMode_AutoAll; + break; + case GAMEPAD_MODE_MANUAL: + imgGamepadMode = ImGui_ImplSDL2_GamepadMode_Manual; + break; + } + ImGui_ImplSDL2_SetGamepadMode(imgGamepadMode, ppManualGamepadsArray, ManualGamepadsCount); +} + } // namespace Diligent diff --git a/Imgui/src/ImGuiImplSDL3.cpp b/Imgui/src/ImGuiImplSDL3.cpp index e5a57729..ed78a6cd 100644 --- a/Imgui/src/ImGuiImplSDL3.cpp +++ b/Imgui/src/ImGuiImplSDL3.cpp @@ -92,4 +92,22 @@ bool ImGuiImplSDL3::HandleSDLEvent(const SDL_Event* ev) return ImGui_ImplSDL3_ProcessEvent(ev); } +void ImGuiImplSDL3::SetGamepadMode(GAMEPAD_MODE GamepadMode, SDL_Gamepad** ppManualGamepadsArray, int ManualGamepadsCount) +{ + ImGui_ImplSDL3_GamepadMode imgGamepadMode{}; + switch (GamepadMode) + { + case GAMEPAD_MODE_AUTO_FIRST: + imgGamepadMode = ImGui_ImplSDL3_GamepadMode_AutoFirst; + break; + case GAMEPAD_MODE_AUTO_ALL: + imgGamepadMode = ImGui_ImplSDL3_GamepadMode_AutoAll; + break; + case GAMEPAD_MODE_MANUAL: + imgGamepadMode = ImGui_ImplSDL3_GamepadMode_Manual; + break; + } + ImGui_ImplSDL3_SetGamepadMode(imgGamepadMode, ppManualGamepadsArray, ManualGamepadsCount); +} + } // namespace Diligent