1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-11 00:04:24 +00:00

Textures: fixed a building issue when ImTextureID is defined as a struct.

+ Added CI for this case.
This commit is contained in:
ocornut 2025-11-26 14:11:22 +01:00
parent 3a45bae9dc
commit 3fef0d553d
5 changed files with 35 additions and 12 deletions

View file

@ -343,7 +343,7 @@ jobs:
EOF EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp 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: | run: |
cat > example_single_file.cpp <<'EOF' cat > example_single_file.cpp <<'EOF'
@ -356,6 +356,21 @@ jobs:
EOF EOF
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp 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) - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
run: | run: |
cat > example_single_file.cpp <<'EOF' cat > example_single_file.cpp <<'EOF'

View file

@ -48,6 +48,8 @@ Other Changes:
of this flag and wasting memory. of this flag and wasting memory.
Undetected since July 2015 and now spotted by @TellowKrinkle, this is perhaps 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) 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 - Scrollbar: fixed a codepath leading to a divide-by-zero (which would not be
noticeable by user but detected by sanitizers). (#9089) [@judicaelclair] noticeable by user but detected by sanitizers). (#9089) [@judicaelclair]
- Backends: - Backends:

View file

@ -16121,14 +16121,20 @@ void ImGui::UpdateDebugToolFlashStyleColor()
DebugFlashStyleColorStop(); 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) static const char* FormatTextureIDForDebugDisplay(char* buf, int buf_size, ImTextureID tex_id)
{ {
union { void* ptr; int integer; } tex_id_opaque; ImU64 v = ImGui::DebugTextureIDToU64(tex_id);
memcpy(&tex_id_opaque, &tex_id, ImMin(sizeof(void*), sizeof(tex_id)));
if (sizeof(tex_id) >= sizeof(void*)) if (sizeof(tex_id) >= sizeof(void*))
ImFormatString(buf, buf_size, "0x%p", tex_id_opaque.ptr); ImFormatString(buf, buf_size, "0x%p", v);
else else
ImFormatString(buf, buf_size, "0x%04X", tex_id_opaque.integer); ImFormatString(buf, buf_size, "0x%04X", v);
return buf; return buf;
} }
@ -16137,7 +16143,7 @@ static const char* FormatTextureRefForDebugDisplay(char* buf, int buf_size, ImTe
char* buf_end = buf + buf_size; char* buf_end = buf + buf_size;
if (tex_ref._TexData != NULL) if (tex_ref._TexData != NULL)
buf += ImFormatString(buf, buf_end - buf, "#%03d: ", tex_ref._TexData->UniqueID); 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 #ifdef IMGUI_ENABLE_FREETYPE
@ -16323,9 +16329,9 @@ void ImGui::DebugNodeTexture(ImTextureData* tex, int int_id, const ImFontAtlasRe
} }
PopStyleVar(); 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("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(); TreePop();
} }
PopID(); PopID();

View file

@ -4538,16 +4538,16 @@ void ImFontAtlasDebugLogTextureRequests(ImFontAtlas* atlas)
if (tex->Status == ImTextureStatus_WantCreate) if (tex->Status == ImTextureStatus_WantCreate)
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: create %dx%d\n", tex->UniqueID, tex->Width, tex->Height); IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: create %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
else if (tex->Status == ImTextureStatus_WantDestroy) 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) 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) for (const ImTextureRect& r : tex->Updates)
{ {
IM_UNUSED(r); IM_UNUSED(r);
IM_ASSERT(r.x >= 0 && r.y >= 0); 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. 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);
} }
} }
} }

View file

@ -335,7 +335,6 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
#define IM_PRIu64 "llu" #define IM_PRIu64 "llu"
#define IM_PRIX64 "llX" #define IM_PRIX64 "llX"
#endif #endif
#define IM_TEXTUREID_TO_U64(_TEXID) ((ImU64)(intptr_t)(_TEXID))
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Generic helpers // [SECTION] Generic helpers
@ -3697,6 +3696,7 @@ namespace ImGui
IMGUI_API bool DebugBreakButton(const char* label, const char* description_of_location); 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 DebugBreakButtonTooltip(bool keyboard_only, const char* description_of_location);
IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas); 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 DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end);
IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns); IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns);
IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label); IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label);