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/ImGuiImplSDL2.hpp b/Imgui/interface/ImGuiImplSDL2.hpp new file mode 100644 index 00000000..f4943d6a --- /dev/null +++ b/Imgui/interface/ImGuiImplSDL2.hpp @@ -0,0 +1,69 @@ +/* + * 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" struct _SDL_GameController; +extern "C" union SDL_Event; + +namespace Diligent +{ +class ImGuiImplSDL2 final : public ImGuiImplDiligent +{ +public: + static std::unique_ptr + Create(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow); + + ImGuiImplSDL2(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow); + ~ImGuiImplSDL2(); + + // clang-format off + ImGuiImplSDL2 (const ImGuiImplSDL2&) = delete; + ImGuiImplSDL2 ( ImGuiImplSDL2&&) = delete; + ImGuiImplSDL2& operator = (const ImGuiImplSDL2&) = delete; + ImGuiImplSDL2& operator = ( ImGuiImplSDL2&&) = 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); + 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/ImGuiImplSDL.hpp b/Imgui/interface/ImGuiImplSDL3.hpp similarity index 72% rename from Imgui/interface/ImGuiImplSDL.hpp rename to Imgui/interface/ImGuiImplSDL3.hpp index 98743765..aa9f2f37 100644 --- a/Imgui/interface/ImGuiImplSDL.hpp +++ b/Imgui/interface/ImGuiImplSDL3.hpp @@ -30,24 +30,25 @@ #include "ImGuiImplDiligent.hpp" extern "C" struct SDL_Window; +extern "C" struct SDL_Gamepad; extern "C" union SDL_Event; namespace Diligent { -class ImGuiImplSDL final : public ImGuiImplDiligent +class ImGuiImplSDL3 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(); + ImGuiImplSDL3(const ImGuiDiligentCreateInfo& CI, SDL_Window* pWindow); + ~ImGuiImplSDL3(); // clang-format off - ImGuiImplSDL (const ImGuiImplSDL&) = delete; - ImGuiImplSDL ( ImGuiImplSDL&&) = delete; - ImGuiImplSDL& operator = (const ImGuiImplSDL&) = delete; - ImGuiImplSDL& operator = ( ImGuiImplSDL&&) = delete; + ImGuiImplSDL3 (const ImGuiImplSDL3&) = delete; + ImGuiImplSDL3 ( ImGuiImplSDL3&&) = delete; + ImGuiImplSDL3& operator = (const ImGuiImplSDL3&) = delete; + ImGuiImplSDL3& operator = ( ImGuiImplSDL3&&) = delete; // clang-format on virtual void NewFrame(Uint32 RenderSurfaceWidth, @@ -55,5 +56,12 @@ class ImGuiImplSDL 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/ImGuiImplSDL.cpp b/Imgui/src/ImGuiImplSDL2.cpp similarity index 61% rename from Imgui/src/ImGuiImplSDL.cpp rename to Imgui/src/ImGuiImplSDL2.cpp index 4c4051ee..9aa76fc2 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,25 +71,53 @@ 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); } +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 new file mode 100644 index 00000000..ed78a6cd --- /dev/null +++ b/Imgui/src/ImGuiImplSDL3.cpp @@ -0,0 +1,113 @@ +/* + * 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); +} + +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