-
-
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
Changing texture sampler / Passing a bigger ImVec2 to AddImage and Image leads to pixel line #7230
Comments
Looks like texture wrapping combined with bilinear filtering to me. Because of the magnification, the top pixel row filters above the top row texel center and therefore interpolates to the bottom row texels. If you look closely or with other textures, you will see that this happens on all sides, not just the top. It is just more noticeable there because of the image and your background. You could adjust the sampler directly in your backend to use clamping instead of wrapping. Or you could substitute y clamping sampler in a draw list callback. before submitting the image, then restore the default one afterwards. |
As Daniel said. Basically any form of GPU-based textured rendering would give you similar result, and you may need to configure the texture sampler. For some reasons all our backends are setup by default with wrapping samplers. In imgui_impl_dx11.cpp code we use: // Create texture sampler
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
{
D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.MinLOD = 0.f;
desc.MaxLOD = 0.f;
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
} You would need to create your own sampler, using If I have to be honest I am surprised this hasn't been asked before, as it seems like the kind of problem many would encounter, and we could argue that it may be useful if our backends had a system in place to standardize this, the same way we have a pseudo-callback value |
By the way, it this is very a bad idea to use hard-coded constants instead of enum value: ImGui::PushStyleColor(2, ImVec4(1, 1, 1, 1)); Should be ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1, 1, 1, 1)); The library doesn't provide ABI backward/forward compatibility meaning we are technically free to change underlying value of enums/flags, and we occasionally do. |
Yeah, is what I normally do, this time Visual Studio for C just didn't want to auto complete so I took the int value from ImGui.NET and tried it |
Switching to a sampler with Clamp works as expected, thanks |
First:
Secondly:
I have verified that it was possible with the DX11 backend: {
D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.MinLOD = 0.f;
desc.MaxLOD = 0.f;
g_pd3dDevice->CreateSamplerState(&desc, &g_SamplerPoint);
} ImGui::Image((void*)my_texture, ImVec2((float)my_image_width * 4, (float)my_image_height * 4));
auto dx11_set_sampler = [](const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
ImGui_ImplDX11_RenderState* state = (ImGui_ImplDX11_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
ID3D11SamplerState* sampler = cmd->UserCallbackData ? (ID3D11SamplerState*)cmd->UserCallbackData : state->SamplerDefault;
state->DeviceContext->PSSetSamplers(0, 1, &sampler);
};
ImGui::GetWindowDrawList()->AddCallback(dx11_set_sampler, g_SamplerPoint);
ImGui::Image((void*)my_texture, ImVec2((float)my_image_width * 4, (float)my_image_height * 4));
ImGui::GetWindowDrawList()->AddCallback(dx11_set_sampler, NULL);
ImGui::End(); I am not 100% sure it is possible OR particularly convenient with all backends. |
I have added a "Modifying Render State" section in the Texture/Image wiki page: |
Version/Branch of Dear ImGui:
1.90.2 and before
Back-ends:
Win32 DirectX11
Compiler, OS:
MSVC, Windows 10
Full config/build information:
No response
Details:
Was trying around with AddImage in ImGui.NET and noticed that giving the AddImage/Image functions p_max that exceed the image width/height leads to a 1 pixel line being added on top of it.
This doesn't happen with the exact size or smaller size.
So i tried the same in the DirectX11 example provided for C ImGui and it produces the same result.
Looking through the web for DirectX11 issues with this specific problem, i couldn't find anything, so i wondered if this is ImGui doing something wrong
Screenshots/Video:
The result in the ImGui preview window, very noticeable line above it
And here the used texture for this test
Minimal, Complete and Verifiable Example code:
Code from https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples#example-for-directx11-users
The text was updated successfully, but these errors were encountered: