Backends: SDLRenderer3: added support for platform_io.DrawCallback_SetSamplerFromTex. (#9378)

This commit is contained in:
ocornut 2026-09-17 15:25:54 +02:00
parent 09b7ff9385
commit b5135f270f
5 changed files with 45 additions and 14 deletions

View File

@ -25,7 +25,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (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-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-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) // 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, ImVector<SDL_F
static void ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way. static void ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = SDL_SCALEMODE_LINEAR; } static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = 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_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. // 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. // - 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) static void ImGui_ImplSDLRenderer3_TexScaleModeUpdate(SDL_Renderer* renderer, SDL_Texture* tex, SDL_ScaleMode desired_scale_mode)
{ {
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData(); ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
if (desired_scale_mode != SDL_SCALEMODE_INVALID)
{
// Enforce a scale mode
SDL_ScaleMode tex_scale_mode = desired_scale_mode; SDL_ScaleMode tex_scale_mode = desired_scale_mode;
if (!SDL_GetTextureScaleMode(tex, &tex_scale_mode) || tex_scale_mode == desired_scale_mode) if (!SDL_GetTextureScaleMode(tex, &tex_scale_mode) || tex_scale_mode == desired_scale_mode)
return; return;
SDL_FlushRenderer(renderer); SDL_FlushRenderer(renderer);
SDL_SetTextureScaleMode(tex, desired_scale_mode); SDL_SetTextureScaleMode(tex, desired_scale_mode);
// Store backup of old scale mode // Store backup of old scale mode (FIXME-OPT)
for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups) for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups)
if (entry.Texture == tex) if (entry.Texture == tex)
{
if (entry.ScaleModeBackup == SDL_SCALEMODE_INVALID)
entry.ScaleModeBackup = tex_scale_mode;
return; return;
}
ImGui_ImplSDLRenderer3_TexScaleModeEntry entry = { tex, tex_scale_mode }; ImGui_ImplSDLRenderer3_TexScaleModeEntry entry = { tex, tex_scale_mode };
bd->TexScaleModeBackups.push_back(entry); 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) 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_ResetRenderState = ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState;
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear; platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear;
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest; platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest;
platform_io.DrawCallback_SetSamplerFromTex = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerFromTex;
bd->Renderer = renderer; bd->Renderer = renderer;

View File

@ -49,7 +49,7 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex)
struct ImGui_ImplSDLRenderer3_RenderState struct ImGui_ImplSDLRenderer3_RenderState
{ {
SDL_Renderer* Renderer; 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; } static inline ImGui_ImplSDLRenderer3_RenderState* ImGui_ImplSDLRenderer3_GetRenderState() { return (ImGui_ImplSDLRenderer3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }

View File

@ -100,6 +100,9 @@ Other Changes:
- Reworked assert in PushTexture() to allow convenience grace period of using a - 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 texture that was queue for destroy during the frame. Make it safe to stick to
an existing texture during the frame. (#9528, #8465) 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: - Demo:
- Added `Widgets->Mixed Values` section. (#5518, #5677, #6865) - Added `Widgets->Mixed Values` section. (#5518, #5677, #6865)
- Backends: - Backends:
@ -108,6 +111,11 @@ Other Changes:
going through a SDL_Renderer. (#5592) [@lailoken] going through a SDL_Renderer. (#5592) [@lailoken]
- SDLRenderer3: restore any temporarily modified texture scale modes at the of `RenderDrawData()`. (#9378) - SDLRenderer3: restore any temporarily modified texture scale modes at the of `RenderDrawData()`. (#9378)
- SDLRenderer3: expose CurrentScaleMode in ImGui_ImplSDLRenderer3_RenderState. (#9543, #9378) [@Clownacy] - 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] - Vulkan: added for support for multiple Vulkan contexts with custom loaders. (#6616) [@lstalmir]
- WebGPU: fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport()` - WebGPU: fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport()`
when when `FramebufferScale` is >1.0f. (#9515, #8628) [@WayU] when when `FramebufferScale` is >1.0f. (#9515, #8628) [@WayU]

View File

@ -16111,7 +16111,7 @@ void ImGuiPlatformIO::ClearRendererHandlers()
{ {
Renderer_TextureMaxWidth = Renderer_TextureMaxHeight = 0; Renderer_TextureMaxWidth = Renderer_TextureMaxHeight = 0;
Renderer_RenderState = NULL; Renderer_RenderState = NULL;
DrawCallback_ResetRenderState = DrawCallback_SetSamplerLinear = DrawCallback_SetSamplerNearest = NULL; DrawCallback_ResetRenderState = DrawCallback_SetSamplerLinear = DrawCallback_SetSamplerNearest = DrawCallback_SetSamplerFromTex = NULL;
} }
ImGuiViewport* ImGui::GetMainViewport() ImGuiViewport* ImGui::GetMainViewport()

View File

@ -4114,6 +4114,7 @@ struct ImGuiPlatformIO
ImDrawCallback DrawCallback_ResetRenderState; // Request to reset the graphics/render state. ImDrawCallback DrawCallback_ResetRenderState; // Request to reset the graphics/render state.
ImDrawCallback DrawCallback_SetSamplerLinear; // Request backend to set texture sampling to Linear. 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_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. //ImDrawCallback DrawCallback_SetSamplerCustom; // Request backend to set texture sampling using Backend Specific data.
//------------------------------------------------------------------ //------------------------------------------------------------------