From b5135f270f3d43209a9ff4c0075dc46347be52eb Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 17 Sep 2026 15:25:54 +0200 Subject: [PATCH] Backends: SDLRenderer3: added support for platform_io.DrawCallback_SetSamplerFromTex. (#9378) --- backends/imgui_impl_sdlrenderer3.cpp | 46 ++++++++++++++++++++-------- backends/imgui_impl_sdlrenderer3.h | 2 +- docs/CHANGELOG.txt | 8 +++++ imgui.cpp | 2 +- imgui.h | 1 + 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/backends/imgui_impl_sdlrenderer3.cpp b/backends/imgui_impl_sdlrenderer3.cpp index 4e970f97e..121ce59c8 100644 --- a/backends/imgui_impl_sdlrenderer3.cpp +++ b/backends/imgui_impl_sdlrenderer3.cpp @@ -25,7 +25,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) -// 2026-09-17: Restore modified texture scale modes at the end of RenderDrawData(). Added CurrentScaleMode in ImGui_ImplSDLRenderer3_RenderState (#9543, #9378) +// 2026-09-17: Restore modified texture scale modes at the end of RenderDrawData(). Added DrawCallback_SetSamplerFromTex support. Added CurrentScaleMode in ImGui_ImplSDLRenderer3_RenderState (#9543, #9378) // 2026-07-15: Fixed default sampler state to be linear (broken 2026-04-23). (#9470, #9378) // 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378) // 2026-03-12: Fixed invalid assert in ImGui_ImplSDLRenderer3_UpdateTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295) @@ -122,6 +122,7 @@ static int SDL_RenderGeometryRaw8BitColor(SDL_Renderer* renderer, ImVectorCurrentScaleMode = SDL_SCALEMODE_LINEAR; } static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = SDL_SCALEMODE_NEAREST; } +static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerFromTex(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = SDL_SCALEMODE_INVALID; } // SDL_SCALEMODE_INVALID = use/keep value in texture. // SDLRenderer has various design issues which makes it hard to do it compared to regular graphics API. // - scale/filtering mode is tied to a texture. @@ -129,18 +130,38 @@ static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest(const ImDrawLi static void ImGui_ImplSDLRenderer3_TexScaleModeUpdate(SDL_Renderer* renderer, SDL_Texture* tex, SDL_ScaleMode desired_scale_mode) { ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData(); - SDL_ScaleMode tex_scale_mode = desired_scale_mode; - if (!SDL_GetTextureScaleMode(tex, &tex_scale_mode) || tex_scale_mode == desired_scale_mode) - return; - SDL_FlushRenderer(renderer); - SDL_SetTextureScaleMode(tex, desired_scale_mode); - - // Store backup of old scale mode - for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups) - if (entry.Texture == tex) + if (desired_scale_mode != SDL_SCALEMODE_INVALID) + { + // Enforce a scale mode + SDL_ScaleMode tex_scale_mode = desired_scale_mode; + if (!SDL_GetTextureScaleMode(tex, &tex_scale_mode) || tex_scale_mode == desired_scale_mode) return; - ImGui_ImplSDLRenderer3_TexScaleModeEntry entry = { tex, tex_scale_mode }; - bd->TexScaleModeBackups.push_back(entry); + SDL_FlushRenderer(renderer); + SDL_SetTextureScaleMode(tex, desired_scale_mode); + + // Store backup of old scale mode (FIXME-OPT) + for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups) + if (entry.Texture == tex) + { + if (entry.ScaleModeBackup == SDL_SCALEMODE_INVALID) + entry.ScaleModeBackup = tex_scale_mode; + return; + } + ImGui_ImplSDLRenderer3_TexScaleModeEntry entry = { tex, tex_scale_mode }; + bd->TexScaleModeBackups.push_back(entry); + } + else + { + // Use scale mode that was set in texture by user. If there is an entry, restore it and clear the entry. + for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups) + if (entry.Texture == tex && entry.ScaleModeBackup != SDL_SCALEMODE_INVALID) + { + SDL_FlushRenderer(renderer); + SDL_SetTextureScaleMode(tex, entry.ScaleModeBackup); + entry.ScaleModeBackup = SDL_SCALEMODE_INVALID; + return; + } + } } static void ImGui_ImplSDLRenderer3_TexScaleModeRestoreBackups(SDL_Renderer* renderer) @@ -345,6 +366,7 @@ bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer) platform_io.DrawCallback_ResetRenderState = ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState; platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear; platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest; + platform_io.DrawCallback_SetSamplerFromTex = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerFromTex; bd->Renderer = renderer; diff --git a/backends/imgui_impl_sdlrenderer3.h b/backends/imgui_impl_sdlrenderer3.h index 13efcba27..019def26a 100644 --- a/backends/imgui_impl_sdlrenderer3.h +++ b/backends/imgui_impl_sdlrenderer3.h @@ -49,7 +49,7 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex) struct ImGui_ImplSDLRenderer3_RenderState { SDL_Renderer* Renderer; - SDL_ScaleMode CurrentScaleMode; // Current scale mode during render. + SDL_ScaleMode CurrentScaleMode; // Current scale mode during render. Set to SDL_SCALEMODE_INVALID to use "SetSamplerFromTex" mode. }; static inline ImGui_ImplSDLRenderer3_RenderState* ImGui_ImplSDLRenderer3_GetRenderState() { return (ImGui_ImplSDLRenderer3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; } diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 6ba8bcfdd..4ff37a224 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -100,6 +100,9 @@ Other Changes: - Reworked assert in PushTexture() to allow convenience grace period of using a texture that was queue for destroy during the frame. Make it safe to stick to an existing texture during the frame. (#9528, #8465) + - Added optional `platform_io.DrawCallback_SetSamplerFromTex` standard backend-agnostic + draw callback for requesting to use the sampler associated already associated to a texture. + Currently only supported by the SDLRenderer3 backend. (#9378) - Demo: - Added `Widgets->Mixed Values` section. (#5518, #5677, #6865) - Backends: @@ -108,6 +111,11 @@ Other Changes: going through a SDL_Renderer. (#5592) [@lailoken] - SDLRenderer3: restore any temporarily modified texture scale modes at the of `RenderDrawData()`. (#9378) - SDLRenderer3: expose CurrentScaleMode in ImGui_ImplSDLRenderer3_RenderState. (#9543, #9378) [@Clownacy] + - SDLRenderer3: added support for `platform_io.DrawCallback_SetSamplerFromTex` draw callback to request + using the sampler associated already associated to a texture via `SDL_SetTextureScaleMode()`. (#9378) + It is equivalent to setting `render_state->CurrentScaleMode = SDL_SCALEMODE_INVALID`. + Note: this callback is only supported by selected rendering backends: most other graphics API + don't have the equivalent of `SDL_SetTextureScaleMode()` and the callback won't work with them. - Vulkan: added for support for multiple Vulkan contexts with custom loaders. (#6616) [@lstalmir] - WebGPU: fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport()` when when `FramebufferScale` is >1.0f. (#9515, #8628) [@WayU] diff --git a/imgui.cpp b/imgui.cpp index 90a80a3f8..9e5880ebd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -16111,7 +16111,7 @@ void ImGuiPlatformIO::ClearRendererHandlers() { Renderer_TextureMaxWidth = Renderer_TextureMaxHeight = 0; Renderer_RenderState = NULL; - DrawCallback_ResetRenderState = DrawCallback_SetSamplerLinear = DrawCallback_SetSamplerNearest = NULL; + DrawCallback_ResetRenderState = DrawCallback_SetSamplerLinear = DrawCallback_SetSamplerNearest = DrawCallback_SetSamplerFromTex = NULL; } ImGuiViewport* ImGui::GetMainViewport() diff --git a/imgui.h b/imgui.h index fe4f82d58..53f1e8660 100644 --- a/imgui.h +++ b/imgui.h @@ -4114,6 +4114,7 @@ struct ImGuiPlatformIO ImDrawCallback DrawCallback_ResetRenderState; // Request to reset the graphics/render state. ImDrawCallback DrawCallback_SetSamplerLinear; // Request backend to set texture sampling to Linear. ImDrawCallback DrawCallback_SetSamplerNearest; // Request backend to set texture sampling to Nearest/Point. + ImDrawCallback DrawCallback_SetSamplerFromTex; // Request backend to use sampler associated to texture - only available in some backends: SDLRenderer3. //ImDrawCallback DrawCallback_SetSamplerCustom; // Request backend to set texture sampling using Backend Specific data. //------------------------------------------------------------------