You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Version/Branch of Dear ImGui:
Version: v1.84
Branch:
Back-end/Renderer/Compiler/OS
Back-ends: imgui_impl_sdl.cpp + imgui_impl_vulkan.cpp
Compiler: Visual Studio 2015
Operating System: Windows 10
Introduction of the glitch:
a. When I change groups[0].resolutionScale which is for ImGui Windows Text, then there's A LOT of glitch on ImGui Windows Text.
b. When I change groups[1].resolutionScale which is for the default font of my engine's gui, then there's A LITTLE chance that a glitch happens on ImGui Windows Text.
c. Conclusion: I believe that the Font Atlas Texture UVs of ImGui Windows Text changes very frequently for (a.), and the Font Atlas Texture UVs changes with smaller chance for (b.), check How to update only all UV(s) of texts in all drawlist(s) after fonts change? #4637 to get the idea that a Texture UV is always Square, (x, y) between ([0,1], [0,1])
Edit: How the animation looks like after I solved the problem?
How I solved it? Always update Font Atlas with its Texture UVs before starting the Dear ImGui frame. But that logic idea never gets into my head if I don't analyze or if I don't work hard.
Go to the very bottom of the thread for more details.
But it's a luck that I found the problem, it's about philosophy because if you work hard then you will get reward with lucks like magic, and I believe in that.
My Issue/Question:
My engine has separated FontAtlas Texture and ImGui windows have separated FontAtlas Texture which is explained in the C++ code at bottom (paragraphs 2. and 3.). fontGroups[0] is for ImGui windows text, and when I change the font size of fontGroups[1] which is for my engine gui then there is a risk that the ImGui windows texts show glitch just like in the .jpg image below and in the animations. The reason I use many fontGroups is there can be many groups using the same font with same size, so they are all share the same ImFont's Texture.
The question is: "How to fix that glitch in the animation?".
There's a glitch in the ImGui window texts when resizing fonts.
The reason I can build things so fast is I have high experience in my own sources, but when I don't have experience in other sources then I'm stuck. For example, I'm a beginner in Vulkan which is the hardest backend, and I have no idea how to fix the glitch by analyzing 'imgui_impl_vulkan.cpp', because Vulkan is too difficult, I'm only a beginner on it.
1. How I use the function buildFontAtlasIfNeeded_ImGui in my engine
class AppBase : public AppBase_Internal
{
public:
AppBase() : AppBase_Internal(this) {}
virtual void imGuiDebug() {}
virtual void prepareGui(Window *window) {}
virtual void destroyGui() {}
void buildFontAtlasIfNeeded() {
_engine->updateFontGroupsIfNeeded(); // <-- This is the FontGroups I'm talking about in the screenshot.
}
virtual void beforeFrameRender() {}
int main(const char *title, const ivec2 &windowSize, const char *projectName);
};
class App : public AppBase
{
...
void beforeFrameRender() // <-- This is called every frame
{
_engine->getDefaultFontGroup()->setScale(_debug_resolutionScale);
buildFontAtlasIfNeeded();
}
}
2. Old code. Upload Fonts code referenced from "examples/example_sdl_vulkan/main.cpp > in function main" in official ImGui v1.84
void my_engine::AppBase_Internal::buildFontAtlasIfNeeded_ImGui(ImGui_ImplVulkanH_Window* wd)
{
if (_engine->_isFontAtlasBuilt_ImGui) {
return;
}
_engine->_isFontAtlasBuilt_ImGui = true;
VkResult err;
// [Originated from "example_sdl_vulkan > main.cpp" in official ImGui v1.84]
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Read 'docs/FONTS.md' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
//io.Fonts->AddFontDefault();
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != NULL);
// Upload Fonts
{
// Use any command queue
VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool;
VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer;
err = vkResetCommandPool(g_Device, command_pool, 0);
check_vk_result(err);
VkCommandBufferBeginInfo begin_info = {};
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
err = vkBeginCommandBuffer(command_buffer, &begin_info);
check_vk_result(err);
ImGui_ImplVulkan_CreateFontsTexture(command_buffer);
VkSubmitInfo end_info = {};
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
end_info.commandBufferCount = 1;
end_info.pCommandBuffers = &command_buffer;
err = vkEndCommandBuffer(command_buffer);
check_vk_result(err);
err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE);
check_vk_result(err);
err = vkDeviceWaitIdle(g_Device);
check_vk_result(err);
ImGui_ImplVulkan_DestroyFontUploadObjects();
}
}
3. I modified the function ImGui_ImplVulkan_CreateFontsTexture for multiple FontAtlas Texture updates reason
bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
{
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
size_t upload_size = width * height * 4 * sizeof(char);
VkResult err;
//_/--------------------------------------------------\_
// EDIT: The reason is for multiple updates of FontAtlas Texture by calling this function multiple
// times and to avoid memory leak.
if (bd->FontImage) {
vkDestroyImage(v->Device, bd->FontImage, v->Allocator);
bd->FontImage = nullptr;
}
if (bd->FontMemory) {
vkFreeMemory(v->Device, bd->FontMemory, v->Allocator);
bd->FontMemory = nullptr;
}
if (bd->FontView) {
vkDestroyImageView(v->Device, bd->FontView, v->Allocator);
bd->FontView = nullptr;
}
// \--------------------------------------------------/
// Create the Image:
{ ... }
// Create the Image View:
{ ... }
// Update the Descriptor Set:
{ ... }
// Create the Upload Buffer:
{ ... }
// Upload to Buffer:
{ ... }
// Copy to Image:
{ ... }
// Store our identifier
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontImage);
return true;
}
4. Advanced reading just to explain how I update FontAtlas in my engine
void my_engine::Engine::FontGroup::setScale(float scale)
{
int old_isize = _iSizePixels;
_iSizePixels = int(scale * _engine->_iDefaultFontSize);
assert(_iSizePixels >= 1);
if (old_isize != _iSizePixels) {
_engine->_areFontGroupsUpdated = false;
}
}
void my_engine::Engine::updateFontGroupsIfNeeded()
{
if (_areFontGroupsUpdated) {
return;
}
_areFontGroupsUpdated = true;
clearFonts();
for (auto it : _fontGroups) {
switch (it->getType()) {
case FontGroupType_Default: it->_font = loadFont("arial", it->_iSizePixels); break;
case FontGroupType_Script: it->_font = loadFont("consola", it->_iSizePixels); break;
default: assert(0);
}
}
buildFontAtlas(); // Not just skipped if there is no change in the FontAtlas because clearFonts forces to rebuild the FontAtlas, but don't worry, the update function is rarely performed.
}
Version/Branch of Dear ImGui:
Version: v1.84
Branch:
Back-end/Renderer/Compiler/OS
Back-ends: imgui_impl_sdl.cpp + imgui_impl_vulkan.cpp
Compiler: Visual Studio 2015
Operating System: Windows 10
Introduction of the glitch:
Edit: How the animation looks like after I solved the problem?
But it's a luck that I found the problem, it's about philosophy because if you work hard then you will get reward with lucks like magic, and I believe in that.
My Issue/Question:


My engine has separated FontAtlas Texture and ImGui windows have separated FontAtlas Texture which is explained in the C++ code at bottom (paragraphs 2. and 3.). fontGroups[0] is for ImGui windows text, and when I change the font size of fontGroups[1] which is for my engine gui then there is a risk that the ImGui windows texts show glitch just like in the .jpg image below and in the animations. The reason I use many fontGroups is there can be many groups using the same font with same size, so they are all share the same ImFont's Texture.
The question is: "How to fix that glitch in the animation?".
There's a glitch in the ImGui window texts when resizing fonts.
The reason I can build things so fast is I have high experience in my own sources, but when I don't have experience in other sources then I'm stuck. For example, I'm a beginner in Vulkan which is the hardest backend, and I have no idea how to fix the glitch by analyzing 'imgui_impl_vulkan.cpp', because Vulkan is too difficult, I'm only a beginner on it.
1. How I use the function buildFontAtlasIfNeeded_ImGui in my engine
2. Old code. Upload Fonts code referenced from "examples/example_sdl_vulkan/main.cpp > in function main" in official ImGui v1.84
3. I modified the function ImGui_ImplVulkan_CreateFontsTexture for multiple FontAtlas Texture updates reason
4. Advanced reading just to explain how I update FontAtlas in my engine