diff --git a/imgui.h b/imgui.h index 753fffe92..e51280e44 100644 --- a/imgui.h +++ b/imgui.h @@ -318,6 +318,11 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE typedef ImU64 ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that) #endif +// Define this to another value if you need value of 0 to be valid. +#ifndef ImTextureID_Invalid +#define ImTextureID_Invalid ((ImTextureID)0) +#endif + // ImTextureRef contains: // - a texture/atlas pointer, typically when created by Dear ImGui itself. // - OR a raw ImTextureID value (user/backend identifier), typically when created by user code to load images. @@ -3362,21 +3367,19 @@ struct ImTextureRect // - void* BackendUserData = higher-level opaque storage for backend own book-keeping. Some backends may have enough with TexID and not need both. struct IMGUI_API ImTextureData { - ImTextureStatus Status; // ImTextureStatus_OK/_WantCreate/_WantUpdates/_WantDestroy + ImTextureStatus Status; // ImTextureStatus_OK/_WantCreate/_WantUpdates/_WantDestroy. Always use SetStatus() to modify! ImTextureFormat Format; // ImTextureFormat_RGBA32 (default) or ImTextureFormat_Alpha8 int Width; // Texture width int Height; // Texture height int BytesPerPixel; // 4 or 1 int UniqueID; // Sequential index to facilitate identifying a texture when debugging/printing. Only unique per atlas. unsigned char* Pixels; // Pointer to buffer holding 'Width*Height' pixels and 'Width*Height*BytesPerPixels' bytes. - ImTextureID TexID; // Identifier stored in ImDrawCmd::GetTexID() and passed to backend RenderDrawData loop. + ImTextureID TexID; // Always use SetTexID() to modify! Identifier stored in ImDrawCmd::GetTexID() and passed to backend RenderDrawData loop. void* BackendUserData; // Convenience storage for backend. Some backends may have enough with TexID. ImTextureRect UpdateRect; // Bounding box encompassing all individual updates. ImVector Updates; // Array of individual updates. int UnusedFrames; // In order to facilitate handling Status==WantDestroy in some backend: this is a count successive frames where the texture was not used. Always >0 when Status==WantDestroy. - - // [Internal] - bool UseColors; // [Internal] Tell whether our texture data is known to use colors (rather than just white + alpha). + bool UseColors; // Tell whether our texture data is known to use colors (rather than just white + alpha). bool WantDestroyNextFrame; // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame. // Functions @@ -3390,6 +3393,10 @@ struct IMGUI_API ImTextureData int GetPitch() const { return Width * BytesPerPixel; } ImTextureRef GetTexRef() const { ImTextureRef tex_ref; tex_ref._TexData = (ImTextureData*)(void*)this; tex_ref._TexID = TexID; return tex_ref; } ImTextureID GetTexID() const { return TexID; } + + // Called by Renderer backend + void SetTexID(ImTextureID tex_id) { TexID = tex_id; } // Call after creating or destroying the texture. Never modify TexID directly! + void SetStatus(ImTextureStatus status) { Status = status; } // Call after honoring a request. Never modify Status directly! }; //----------------------------------------------------------------------------- @@ -3689,9 +3696,11 @@ struct ImFont // FIXME-NEWATLAS: Added indirection to avoid patching ImDrawCmd after texture updates. inline ImTextureID ImDrawCmd::GetTexID() const { + // If you are getting this assert: A renderer backend with support for ImGuiBackendFlags_RendererHasTextures (1.92) + // must iterate and handle ImTextureData requests stored in ImDrawData::Textures[]. ImTextureID tex_id = TexRef._TexData ? TexRef._TexData->TexID : TexRef._TexID; if (TexRef._TexData != NULL) - IM_ASSERT(tex_id && "ImDrawCmd is referring to Atlas texture that wasn't uploaded to graphics system."); + IM_ASSERT(tex_id != ImTextureID_Invalid && "ImDrawCmd is referring to ImTextureData that wasn't uploaded to graphics system. Backend must call ImTextureData::SetTexID() after handling ImTextureStatus_WantCreate request!"); return tex_id; } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index a497663b9..1e66a3b9c 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2695,7 +2695,7 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas) if (tex->Status == ImTextureStatus_Destroyed) { - IM_ASSERT(tex->TexID == 0 && tex->BackendUserData == NULL); + IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL); if (tex->WantDestroyNextFrame) remove_from_list = true; // Destroy was scheduled by us else @@ -2715,7 +2715,7 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas) tex->UnusedFrames++; // If a texture has never reached the backend, they don't need to know about it. - if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == 0 && tex->BackendUserData == NULL) + if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL) remove_from_list = true; // Remove @@ -3518,7 +3518,7 @@ ImTextureData* ImFontAtlasBuildAddTexture(ImFontAtlas* atlas, int w, int h) /*if (old_tex != NULL && old_tex->Status == ImTextureStatus_WantCreate) { // Reuse texture not yet used by backend. - IM_ASSERT(old_tex->TexID == 0 && old_tex->BackendUserData == NULL); + IM_ASSERT(old_tex->TexID == ImTextureID_Invalid && old_tex->BackendUserData == NULL); old_tex->DestroyPixels(); old_tex->Updates.clear(); new_tex = old_tex;