From ee48fad09d51cbe04696a6ca1b287d347bd6c17b Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 21 Nov 2025 19:47:03 +0100 Subject: [PATCH 1/9] Internals: rename ImStableVector's BLOCK_SIZE to avoid conflict with Linux header defines. (#9088) --- imgui_internal.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index f577c170b..b8d6c469b 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -712,10 +712,10 @@ struct ImSpanAllocator }; // Helper: ImStableVector<> -// Allocating chunks of BLOCK_SIZE items. Objects pointers are never invalidated when growing, only by clear(). +// Allocating chunks of BLOCKSIZE items. Objects pointers are never invalidated when growing, only by clear(). // Important: does not destruct anything! // Implemented only the minimum set of functions we need for it. -template +template struct ImStableVector { int Size = 0; @@ -729,19 +729,19 @@ struct ImStableVector inline void resize(int new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; } inline void reserve(int new_cap) { - new_cap = IM_MEMALIGN(new_cap, BLOCK_SIZE); - int old_count = Capacity / BLOCK_SIZE; - int new_count = new_cap / BLOCK_SIZE; + new_cap = IM_MEMALIGN(new_cap, BLOCKSIZE); + int old_count = Capacity / BLOCKSIZE; + int new_count = new_cap / BLOCKSIZE; if (new_count <= old_count) return; Blocks.resize(new_count); for (int n = old_count; n < new_count; n++) - Blocks[n] = (T*)IM_ALLOC(sizeof(T) * BLOCK_SIZE); + Blocks[n] = (T*)IM_ALLOC(sizeof(T) * BLOCKSIZE); Capacity = new_cap; } - inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCK_SIZE][i % BLOCK_SIZE]; } - inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCK_SIZE][i % BLOCK_SIZE]; } - inline T* push_back(const T& v) { int i = Size; IM_ASSERT(i >= 0); if (Size == Capacity) reserve(Capacity + BLOCK_SIZE); void* ptr = &Blocks[i / BLOCK_SIZE][i % BLOCK_SIZE]; memcpy(ptr, &v, sizeof(v)); Size++; return (T*)ptr; } + inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCKSIZE][i % BLOCKSIZE]; } + inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Blocks[i / BLOCKSIZE][i % BLOCKSIZE]; } + inline T* push_back(const T& v) { int i = Size; IM_ASSERT(i >= 0); if (Size == Capacity) reserve(Capacity + BLOCKSIZE); void* ptr = &Blocks[i / BLOCKSIZE][i % BLOCKSIZE]; memcpy(ptr, &v, sizeof(v)); Size++; return (T*)ptr; } }; // Helper: ImPool<> From 324cea1f41fa6dcdacfa363abfde10d44efaea58 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 24 Nov 2025 13:35:41 +0100 Subject: [PATCH 2/9] Version 1.92.6 WIP --- docs/CHANGELOG.txt | 9 +++++++++ imgui.cpp | 2 +- imgui.h | 6 +++--- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- imgui_widgets.cpp | 2 +- 8 files changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a9c0fea2f..68c4096d0 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -35,6 +35,15 @@ HOW TO UPDATE? and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users. - Please report any issue! +----------------------------------------------------------------------- + VERSION 1.92.6 WIP (In Progress) +----------------------------------------------------------------------- + +Breaking Changes: + +Other Changes: + + ----------------------------------------------------------------------- VERSION 1.92.5 (Released 2025-11-20) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 2bb3ad3d9..5f6e5057e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.5 +// dear imgui, v1.92.6 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index be945c611..fe1385da2 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.5 +// dear imgui, v1.92.6 WIP // (headers) // Help: @@ -29,8 +29,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.92.5" -#define IMGUI_VERSION_NUM 19250 +#define IMGUI_VERSION "1.92.6 WIP" +#define IMGUI_VERSION_NUM 19251 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a3996d961..35451730c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.5 +// dear imgui, v1.92.6 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index de6462295..589de9b91 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.5 +// dear imgui, v1.92.6 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index b8d6c469b..f5a90918f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.5 +// dear imgui, v1.92.6 WIP // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 41fdf6a4c..25d945d2a 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.5 +// dear imgui, v1.92.6 WIP // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index e487b3f96..a4b3e7ed1 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.5 +// dear imgui, v1.92.6 WIP // (widgets code) /* From 136d067eed66204cc50c528812e7ad00104751cb Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 24 Nov 2025 14:27:03 +0100 Subject: [PATCH 3/9] Scrollbar: fixed a codepath leading to a divide-by-zero. (#9089) --- docs/CHANGELOG.txt | 3 +++ imgui_widgets.cpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 68c4096d0..82c81a6ff 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,9 @@ Breaking Changes: Other Changes: +- Scrollbar: fixed a codepath leading to a divide-by-zero (which would not be + noticeable by user but detected by sanitizers). (#9089) [@judicaelclair] + ----------------------------------------------------------------------- VERSION 1.92.5 (Released 2025-11-20) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a4b3e7ed1..9009bbc8c 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1037,6 +1037,8 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6 // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth() : bb.GetHeight(); + if (scrollbar_size_v < 1.0f) + return false; // Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount) // But we maintain a minimum size in pixel to allow for the user to still aim inside. From 5f82275ba1f31e4c8e12c04e699d50f30a4e7a95 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 24 Nov 2025 14:49:16 +0100 Subject: [PATCH 4/9] Docs: updated 1.91.5 logs for missing info that GetKeyIndex() was removed at this date. Amend 6f287dd16 --- docs/CHANGELOG.txt | 1 + imgui.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 82c81a6ff..df9330ea2 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -1386,6 +1386,7 @@ Breaking changes: - Commented out pre-1.87 IO system (equivalent to using IMGUI_DISABLE_OBSOLETE_KEYIO or IMGUI_DISABLE_OBSOLETE_FUNCTIONS before). - io.KeyMap[] and io.KeysDown[] are removed (obsoleted February 2022). Use IsKeyDown() instead. - io.NavInputs[] and ImGuiNavInput are removed (obsoleted July 2022). + - GetKeyIndex() is removed (obsoleted March 2022). The indirection is now unnecessary. - Pre-1.87 backends are not supported: - backends need to call io.AddKeyEvent(), io.AddMouseEvent() instead of writing to io.KeysDown[], io.MouseDown[] fields. - backends need to call io.AddKeyAnalogEvent() for gamepad values instead of writing to io.NavInputs[] fields. diff --git a/imgui.cpp b/imgui.cpp index 5f6e5057e..2cd202386 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -524,6 +524,7 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures: - 2024/11/06 (1.91.5) - commented/obsoleted out pre-1.87 IO system (equivalent to using IMGUI_DISABLE_OBSOLETE_KEYIO or IMGUI_DISABLE_OBSOLETE_FUNCTIONS before) - io.KeyMap[] and io.KeysDown[] are removed (obsoleted February 2022). - io.NavInputs[] and ImGuiNavInput are removed (obsoleted July 2022). + - GetKeyIndex() is removed (obsoleted March 2022). The indirection is now unnecessary. - pre-1.87 backends are not supported: - backends need to call io.AddKeyEvent(), io.AddMouseEvent() instead of writing to io.KeysDown[], io.MouseDown[] fields. - backends need to call io.AddKeyAnalogEvent() for gamepad values instead of writing to io.NavInputs[] fields. From 98636f4a239aed1dfccbc42bd38b76756d7ac0ba Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 24 Nov 2025 15:39:41 +0100 Subject: [PATCH 5/9] Fonts: fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which did erroneously make a copy of the font data. (#9086) Amend 815168c7e + Added explicit casts for intent/clarity when passing to stb_truetype/freetype. --- docs/CHANGELOG.txt | 5 +++++ imgui_draw.cpp | 10 ++-------- misc/freetype/imgui_freetype.cpp | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index df9330ea2..4e1c1c1a7 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,11 @@ Breaking Changes: Other Changes: +- Fonts: fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which + did erroneously make a copy of the font data, essentially defeating the purpose + of this flag and wasting memory. + Undetected since July 2015 and now spotted by @TellowKrinkle, this is perhaps + the oldest bug in Dear ImGui history (albeit for a rarely used feature)! (#9086) - Scrollbar: fixed a codepath leading to a divide-by-zero (which would not be noticeable by user but detected by sanitizers). (#9089) [@judicaelclair] diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 589de9b91..0084dc187 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -3052,12 +3052,6 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in) font->Sources.push_back(font_cfg); ImFontAtlasBuildUpdatePointers(this); // Pointers to Sources are otherwise dangling after we called Sources.push_back(). - if (font_cfg->FontDataOwnedByAtlas == false) - { - font_cfg->FontDataOwnedByAtlas = true; - font_cfg->FontData = ImMemdup(font_cfg->FontData, (size_t)font_cfg->FontDataSize); - } - // Sanity check // We don't round cfg.SizePixels yet as relative size of merged fonts are used afterwards. if (font_cfg->GlyphExcludeRanges != NULL) @@ -4583,14 +4577,14 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig* IM_ASSERT(src->FontLoaderData == NULL); // Initialize helper structure for font loading and verify that the TTF/OTF data is correct - const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)src->FontData, src->FontNo); + const int font_offset = stbtt_GetFontOffsetForIndex((const unsigned char*)src->FontData, src->FontNo); if (font_offset < 0) { IM_DELETE(bd_font_data); IM_ASSERT_USER_ERROR(0, "stbtt_GetFontOffsetForIndex(): FontData is incorrect, or FontNo cannot be found."); return false; } - if (!stbtt_InitFont(&bd_font_data->FontInfo, (unsigned char*)src->FontData, font_offset)) + if (!stbtt_InitFont(&bd_font_data->FontInfo, (const unsigned char*)src->FontData, font_offset)) { IM_DELETE(bd_font_data); IM_ASSERT_USER_ERROR(0, "stbtt_InitFont(): failed to parse FontData. It is correct and complete? Check FontDataSize."); diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index 16bb9817c..26a087017 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -174,7 +174,7 @@ struct ImGui_ImplFreeType_FontSrcBakedData bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_font_loader_flags) { - FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)src->FontData, (FT_Long)src->FontDataSize, (FT_Long)src->FontNo, &FtFace); + FT_Error error = FT_New_Memory_Face(ft_library, (const FT_Byte*)src->FontData, (FT_Long)src->FontDataSize, (FT_Long)src->FontNo, &FtFace); if (error != 0) return false; error = FT_Select_Charmap(FtFace, FT_ENCODING_UNICODE); From 3a45bae9dc6a9006226d58d2fea35c9fa21ad21c Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 24 Nov 2025 18:11:23 +0100 Subject: [PATCH 6/9] Backends: Vulkan: helper for creating a swapchain selects VkSwapchainCreateInfoKHR's compositeAlpha based on cap.supportedCompositeAlpha. (#8784) --- backends/imgui_impl_vulkan.cpp | 8 +++++++- docs/CHANGELOG.txt | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index c62510829..21a7a8580 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -27,6 +27,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2025-11-24: Vulkan: Helper for creating a swap-chain (used by examples and multi-viewports) selects VkSwapchainCreateInfoKHR's compositeAlpha based on cap.supportedCompositeAlpha. (#8784) // 2025-10-15: Vulkan: Added IMGUI_IMPL_VULKAN_VOLK_FILENAME to configure path to volk.h header. (#9008) // 2025-09-26: *BREAKING CHANGE*: moved some fields in ImGui_ImplVulkan_InitInfo: init_info.RenderPass --> init_info.PipelineInfoMain.RenderPass, init_info.Subpass --> init_info.PipelineInfoMain.Subpass, init_info.MSAASamples --> init_info.PipelineInfoMain.MSAASamples, init_info.PipelineRenderingCreateInfo --> init_info.PipelineInfoMain.PipelineRenderingCreateInfo. // 2025-09-26: *BREAKING CHANGE*: renamed ImGui_ImplVulkan_MainPipelineCreateInfo to ImGui_ImplVulkan_PipelineInfo. Introduced very recently so shouldn't affect many users. @@ -1637,7 +1638,12 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | image_usage; info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; // Assume that graphics family == present family info.preTransform = (cap.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : cap.currentTransform; - info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + if (cap.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) + info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + else if (cap.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) + info.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; + else + IM_ASSERT(false && "No supported composite alpha mode found!"); info.presentMode = wd->PresentMode; info.clipped = VK_TRUE; info.oldSwapchain = old_swapchain; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4e1c1c1a7..5a72aade9 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -50,6 +50,10 @@ Other Changes: the oldest bug in Dear ImGui history (albeit for a rarely used feature)! (#9086) - Scrollbar: fixed a codepath leading to a divide-by-zero (which would not be noticeable by user but detected by sanitizers). (#9089) [@judicaelclair] +- Backends: + - Vulkan: helper for creating a swapchain (used by examples and multi-viewports) + selects `VkSwapchainCreateInfoKHR`'s `compositeAlpha` value based on + `cap.supportedCompositeAlpha`. (#8784) [@FelixStach] ----------------------------------------------------------------------- From 3fef0d553df7d32c373fc5d1ab484a0097c44a0b Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Nov 2025 14:11:22 +0100 Subject: [PATCH 7/9] Textures: fixed a building issue when ImTextureID is defined as a struct. + Added CI for this case. --- .github/workflows/build.yml | 17 ++++++++++++++++- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 20 +++++++++++++------- imgui_draw.cpp | 6 +++--- imgui_internal.h | 2 +- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ee729717..482804b47 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -343,7 +343,7 @@ jobs: EOF g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp - - name: Build example_null (with large ImDrawIdx + pointer ImTextureID) + - name: Build example_null (with large ImDrawIdx + custom ImTextureID) run: | cat > example_single_file.cpp <<'EOF' @@ -356,6 +356,21 @@ jobs: EOF g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + cat > example_single_file.cpp <<'EOF' + + // Test build ImTextureID defined as a struct + struct SomeType { int a = 0; int b = 0; }; + #define ImTextureID SomeType + #define ImTextureID_Invalid SomeType() + inline bool operator==(const SomeType& lhs, const SomeType& rhs) { return lhs.a == rhs.a && lhs.b == rhs.b; } + inline bool operator!=(const SomeType& lhs, const SomeType& rhs) { return lhs.a != rhs.a || lhs.b != rhs.b; } + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF + g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp + - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS) run: | cat > example_single_file.cpp <<'EOF' diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 5a72aade9..ed3a65a4a 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -48,6 +48,8 @@ Other Changes: of this flag and wasting memory. Undetected since July 2015 and now spotted by @TellowKrinkle, this is perhaps the oldest bug in Dear ImGui history (albeit for a rarely used feature)! (#9086) +- Textures: + - Fixed a building issue when ImTextureID is defined as a struct. - Scrollbar: fixed a codepath leading to a divide-by-zero (which would not be noticeable by user but detected by sanitizers). (#9089) [@judicaelclair] - Backends: diff --git a/imgui.cpp b/imgui.cpp index 2cd202386..85d2622fd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -16121,14 +16121,20 @@ void ImGui::UpdateDebugToolFlashStyleColor() DebugFlashStyleColorStop(); } +ImU64 ImGui::DebugTextureIDToU64(ImTextureID tex_id) +{ + ImU64 v = 0; + memcpy(&v, &tex_id, ImMin(sizeof(ImU64), sizeof(tex_id))); + return v; +} + static const char* FormatTextureIDForDebugDisplay(char* buf, int buf_size, ImTextureID tex_id) { - union { void* ptr; int integer; } tex_id_opaque; - memcpy(&tex_id_opaque, &tex_id, ImMin(sizeof(void*), sizeof(tex_id))); + ImU64 v = ImGui::DebugTextureIDToU64(tex_id); if (sizeof(tex_id) >= sizeof(void*)) - ImFormatString(buf, buf_size, "0x%p", tex_id_opaque.ptr); + ImFormatString(buf, buf_size, "0x%p", v); else - ImFormatString(buf, buf_size, "0x%04X", tex_id_opaque.integer); + ImFormatString(buf, buf_size, "0x%04X", v); return buf; } @@ -16137,7 +16143,7 @@ static const char* FormatTextureRefForDebugDisplay(char* buf, int buf_size, ImTe char* buf_end = buf + buf_size; if (tex_ref._TexData != NULL) buf += ImFormatString(buf, buf_end - buf, "#%03d: ", tex_ref._TexData->UniqueID); - return FormatTextureIDForDebugDisplay(buf, (int)(buf_end - buf), tex_ref.GetTexID()); // Calling TexRef::GetTexID() to avoid assert of cmd->GetTexID() + return FormatTextureIDForDebugDisplay(buf, (int)(buf_end - buf), tex_ref.GetTexID()); } #ifdef IMGUI_ENABLE_FREETYPE @@ -16323,9 +16329,9 @@ void ImGui::DebugNodeTexture(ImTextureData* tex, int int_id, const ImFontAtlasRe } PopStyleVar(); - char texid_desc[30]; + char texref_desc[30]; Text("Status = %s (%d), Format = %s (%d), UseColors = %d", ImTextureDataGetStatusName(tex->Status), tex->Status, ImTextureDataGetFormatName(tex->Format), tex->Format, tex->UseColors); - Text("TexID = %s, BackendUserData = %p", FormatTextureRefForDebugDisplay(texid_desc, IM_ARRAYSIZE(texid_desc), tex->GetTexRef()), tex->BackendUserData); + Text("TexRef = %s, BackendUserData = %p", FormatTextureRefForDebugDisplay(texref_desc, IM_ARRAYSIZE(texref_desc), tex->GetTexRef()), tex->BackendUserData); TreePop(); } PopID(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 0084dc187..88ad02966 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -4538,16 +4538,16 @@ void ImFontAtlasDebugLogTextureRequests(ImFontAtlas* atlas) if (tex->Status == ImTextureStatus_WantCreate) IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: create %dx%d\n", tex->UniqueID, tex->Width, tex->Height); else if (tex->Status == ImTextureStatus_WantDestroy) - IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: destroy %dx%d, texid=0x%" IM_PRIX64 ", backend_data=%p\n", tex->UniqueID, tex->Width, tex->Height, IM_TEXTUREID_TO_U64(tex->TexID), tex->BackendUserData); + IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: destroy %dx%d, texid=0x%" IM_PRIX64 ", backend_data=%p\n", tex->UniqueID, tex->Width, tex->Height, ImGui::DebugTextureIDToU64(tex->TexID), tex->BackendUserData); else if (tex->Status == ImTextureStatus_WantUpdates) { - IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update %d regions, texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, tex->Updates.Size, IM_TEXTUREID_TO_U64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData); + IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update %d regions, texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, tex->Updates.Size, ImGui::DebugTextureIDToU64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData); for (const ImTextureRect& r : tex->Updates) { IM_UNUSED(r); IM_ASSERT(r.x >= 0 && r.y >= 0); IM_ASSERT(r.x + r.w <= tex->Width && r.y + r.h <= tex->Height); // In theory should subtract PackPadding but it's currently part of atlas and mid-frame change would wreck assert. - //IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update (% 4d..%-4d)->(% 4d..%-4d), texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, r.x, r.y, r.x + r.w, r.y + r.h, IM_TEXTUREID_TO_U64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData); + //IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update (% 4d..%-4d)->(% 4d..%-4d), texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, r.x, r.y, r.x + r.w, r.y + r.h, ImGui::DebugTextureIDToU64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData); } } } diff --git a/imgui_internal.h b/imgui_internal.h index f5a90918f..557a380c7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -335,7 +335,6 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer #define IM_PRIu64 "llu" #define IM_PRIX64 "llX" #endif -#define IM_TEXTUREID_TO_U64(_TEXID) ((ImU64)(intptr_t)(_TEXID)) //----------------------------------------------------------------------------- // [SECTION] Generic helpers @@ -3697,6 +3696,7 @@ namespace ImGui IMGUI_API bool DebugBreakButton(const char* label, const char* description_of_location); IMGUI_API void DebugBreakButtonTooltip(bool keyboard_only, const char* description_of_location); IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas); + IMGUI_API ImU64 DebugTextureIDToU64(ImTextureID tex_id); IMGUI_API void DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end); IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns); IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label); From e768f91dc210149626d0c1b5d4db1bd7d6da28e9 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Nov 2025 14:18:51 +0100 Subject: [PATCH 8/9] Textures: fixed displaying texture # in metrics/debugger. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 18 +++++------------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ed3a65a4a..63ee6c4e0 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -50,6 +50,7 @@ Other Changes: the oldest bug in Dear ImGui history (albeit for a rarely used feature)! (#9086) - Textures: - Fixed a building issue when ImTextureID is defined as a struct. + - Fixed displaying texture # in Metrics/Debugger window. - Scrollbar: fixed a codepath leading to a divide-by-zero (which would not be noticeable by user but detected by sanitizers). (#9089) [@judicaelclair] - Backends: diff --git a/imgui.cpp b/imgui.cpp index 85d2622fd..6cbdcea1e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -16124,26 +16124,18 @@ void ImGui::UpdateDebugToolFlashStyleColor() ImU64 ImGui::DebugTextureIDToU64(ImTextureID tex_id) { ImU64 v = 0; - memcpy(&v, &tex_id, ImMin(sizeof(ImU64), sizeof(tex_id))); + memcpy(&v, &tex_id, ImMin(sizeof(ImU64), sizeof(ImTextureID))); return v; } -static const char* FormatTextureIDForDebugDisplay(char* buf, int buf_size, ImTextureID tex_id) -{ - ImU64 v = ImGui::DebugTextureIDToU64(tex_id); - if (sizeof(tex_id) >= sizeof(void*)) - ImFormatString(buf, buf_size, "0x%p", v); - else - ImFormatString(buf, buf_size, "0x%04X", v); - return buf; -} - static const char* FormatTextureRefForDebugDisplay(char* buf, int buf_size, ImTextureRef tex_ref) { + char* buf_p = buf; char* buf_end = buf + buf_size; if (tex_ref._TexData != NULL) - buf += ImFormatString(buf, buf_end - buf, "#%03d: ", tex_ref._TexData->UniqueID); - return FormatTextureIDForDebugDisplay(buf, (int)(buf_end - buf), tex_ref.GetTexID()); + buf_p += ImFormatString(buf_p, buf_end - buf_p, "#%03d: ", tex_ref._TexData->UniqueID); + buf_p += ImFormatString(buf_p, buf_end - buf_p, "0x%X", ImGui::DebugTextureIDToU64(tex_ref.GetTexID())); + return buf; } #ifdef IMGUI_ENABLE_FREETYPE From d981b33dd0c95bf8ed2f0918fc7425c26f5f1ce4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Nov 2025 14:24:55 +0100 Subject: [PATCH 9/9] Textures: amend to please static analyzer. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 6cbdcea1e..f878a116c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -16134,7 +16134,7 @@ static const char* FormatTextureRefForDebugDisplay(char* buf, int buf_size, ImTe char* buf_end = buf + buf_size; if (tex_ref._TexData != NULL) buf_p += ImFormatString(buf_p, buf_end - buf_p, "#%03d: ", tex_ref._TexData->UniqueID); - buf_p += ImFormatString(buf_p, buf_end - buf_p, "0x%X", ImGui::DebugTextureIDToU64(tex_ref.GetTexID())); + ImFormatString(buf_p, buf_end - buf_p, "0x%X", ImGui::DebugTextureIDToU64(tex_ref.GetTexID())); return buf; }