-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SDL renderer: How to display the same texture with different scale modes? #7616
Comments
Here is the background of this issue: I wanted to display a zoom window in nearest scale mode for a texture shown in linear mode. The problem was worked around by making a new texture with different scale mode, but I think the solution is wasteful. |
Hello, This is analoguous to this example here changing the sampler for DX11 rendering: |
I've tried this: void ImDrawCallback_ImplSDLRenderer_SetScaleModeNearest(const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
SDL_Texture* texture = (SDL_Texture*)cmd->UserCallbackData;
SDL_SetTextureScaleMode(texture, SDL_ScaleModeNearest);
}
void ImDrawCallback_ImplSDLRenderer_SetScaleModeLinear(const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
SDL_Texture* texture = (SDL_Texture*)cmd->UserCallbackData;
SDL_SetTextureScaleMode(texture, SDL_ScaleModeLinear);
} ImGui::Image((ImTextureID)(intptr_t)my_texture, ImVec2((float)my_image_width * 4, (float)my_image_height * 4));
ImGui::GetWindowDrawList()->AddCallback(ImDrawCallback_ImplSDLRenderer_SetScaleModeNearest, (void*)my_texture);
ImGui::Image((ImTextureID)(intptr_t)my_texture, ImVec2((float)my_image_width * 4, (float)my_image_height * 4));
ImGui::GetWindowDrawList()->AddCallback(ImDrawCallback_ImplSDLRenderer_SetScaleModeLinear, (void*)my_texture); But unfortunately SDL Renderer doesn't seem to allow that changes to happen: because all rendering is done at once and the texture scale mode at the time of calling This didn't work either, which is more puzzling: void ImDrawCallback_ImplSDLRenderer_SetScaleModeNearest(const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
ImGui_ImplSDLRenderer2_RenderState* render_state = (ImGui_ImplSDLRenderer2_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
SDL_RenderFlush(render_state->Renderer);
SDL_Texture* texture = (SDL_Texture*)cmd->UserCallbackData;
SDL_SetTextureScaleMode(texture, SDL_ScaleModeNearest);
}
void ImDrawCallback_ImplSDLRenderer_SetScaleModeLinear(const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
ImGui_ImplSDLRenderer2_RenderState* render_state = (ImGui_ImplSDLRenderer2_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
SDL_RenderFlush(render_state->Renderer);
SDL_Texture* texture = (SDL_Texture*)cmd->UserCallbackData;
SDL_SetTextureScaleMode(texture, SDL_ScaleModeLinear);
} I would expect this to work (even if it's perhaps not efficient). |
Out of curiosity I tried with SDL3 and it worked (but that's with the void ImDrawCallback_ImplSDLRenderer3_SetScaleModeNearest(const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
ImGui_ImplSDLRenderer3_RenderState* render_state = (ImGui_ImplSDLRenderer3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
SDL_FlushRenderer(render_state->Renderer);
SDL_Texture* texture = (SDL_Texture*)cmd->UserCallbackData;
SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST);
}
void ImDrawCallback_ImplSDLRenderer3_SetScaleModeLinear(const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
ImGui_ImplSDLRenderer3_RenderState* render_state = (ImGui_ImplSDLRenderer3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
SDL_FlushRenderer(render_state->Renderer);
SDL_Texture* texture = (SDL_Texture*)cmd->UserCallbackData;
SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_LINEAR);
} I don't think SDL_Renderer is designed for that, but you could ask the team if they would like texture state to be latched during draw calls, it may be a possible improvement for SDL3. |
I am going to have to close this as answered, unfortunately this is not supported by SDL, but feel free to ask on SDL3 repo if they want to make the change to make it work without flushing. I suspect SDL3 will nowadays focus their effort on SDL_GPU rather than SDL_Renderer, but if SDL_Renderer ends up using SDL_GPU then maybe this improvement will come automatically. It's been interesting for me to dig because this topic aligns with recent work I've been doing toward making it easier to change backend render state. We might eventually settle on a mechanism with officially supported callbacks to do exactly what you are trying to do, since it's been a quite common request. |
FYI, I just did that with 98d52b7 |
Version/Branch of Dear ImGui:
Version 1.90.6
Back-ends:
imgui_impl_sdl2.cpp + imgui_impl_sdlrenderer2.cpp
Compiler, OS:
Windows 10 + MSVC 2022
Full config/build information:
No response
Details:
I want to display the same texture in different scale modes. The screenshot shows the effect of
test_fn
below. Can I achieve the same effect without creating multiple textures?Screenshots/Video:
Minimal, Complete and Verifiable Example code:
The text was updated successfully, but these errors were encountered: