diff --git a/docs/FAQ.md b/docs/FAQ.md index 286127cb9..fb693c7e3 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -438,6 +438,8 @@ struct ImTextureRef - When a texture is created by user code (e.g. custom images), we directly store the low-level `ImTextureID`. - Because of this, when displaying your own texture you are likely to ever only manage ImTextureID values on your side. - When a texture is created by the backend, we store a `ImTextureData*` which becomes an indirection to extract the `ImTextureID` value during rendering, after texture upload has happened. + - To create a `ImTextureRef` from a `ImTextureData*` you can use `ImTextureData::GetTexRef()`. + We intentionally do not provide an `ImTextureRef` constructor for this: we don't expect this to be frequently useful to the end-user, and it would be erroneously called by many legacy code. - There is no constructor to create a `ImTextureRef` from a `ImTextureData*` as we don't expect this to be useful to the end-user, and it would be erroneously called by many legacy code. - If you want to bind the current atlas when using custom rectangles, you can use `io.Fonts->TexRef`. - Binding generators for languages such as C (which don't have constructors), should provide a helper, e.g. `inline ImTextureRef ImTextureRefFromID(ImTextureID tex_id) { ImTextureRef tex_ref = { ._TexData = NULL, .TexID = tex_id }; return tex_ref; }` diff --git a/imgui.cpp b/imgui.cpp index 0ba16fb31..31a95716b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8732,16 +8732,19 @@ ImFont* ImGui::GetDefaultFont() return g.IO.FontDefault ? g.IO.FontDefault : atlas->Fonts[0]; } +// EXPERIMENTAL: DO NOT USE YET. void ImGui::RegisterUserTexture(ImTextureData* tex) { ImGuiContext& g = *GImGui; - IM_ASSERT(tex->RefCount > 0); + tex->RefCount++; g.UserTextures.push_back(tex); } void ImGui::UnregisterUserTexture(ImTextureData* tex) { ImGuiContext& g = *GImGui; + IM_ASSERT(tex->RefCount > 0); + tex->RefCount--; g.UserTextures.find_erase(tex); } diff --git a/imgui.h b/imgui.h index cef7d7b87..ee4e976ae 100644 --- a/imgui.h +++ b/imgui.h @@ -345,8 +345,9 @@ typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or // Because of this, when displaying your own texture you are likely to ever only manage ImTextureID values on your side. // - When a texture is created by the backend, we stores a ImTextureData* which becomes an indirection // to extract the ImTextureID value during rendering, after texture upload has happened. -// - There is no constructor to create a ImTextureID from a ImTextureData* as we don't expect this -// to be useful to the end-user, and it would be erroneously called by many legacy code. +// - To create a ImTextureRef from a ImTextureData you can use ImTextureData::GetTexRef(). +// We intentionally do not provide an ImTextureRef constructor for this: we don't expect this +// to be frequently useful to the end-user, and it would be erroneously called by many legacy code. // - If you want to bind the current atlas when using custom rectangle, you can use io.Fonts->TexRef. // - Binding generators for languages such as C (which don't have constructors), should provide a helper, e.g. // inline ImTextureRef ImTextureRefFromID(ImTextureID tex_id) { ImTextureRef tex_ref = { ._TexData = NULL, .TexID = tex_id }; return tex_ref; } @@ -3425,7 +3426,7 @@ struct ImTextureRect struct ImTextureData { //------------------------------------------ core / backend --------------------------------------- - int UniqueID; // w - // Sequential index to facilitate identifying a texture when debugging/printing. Unique per atlas. + int UniqueID; // w - // [DEBUG] Sequential index to facilitate identifying a texture when debugging/printing. Unique per atlas. ImTextureStatus Status; // rw rw // ImTextureStatus_OK/_WantCreate/_WantUpdates/_WantDestroy. Always use SetStatus() to modify! void* BackendUserData; // - rw // Convenience storage for backend. Some backends may have enough with TexID. ImTextureID TexID; // r w // Backend-specific texture identifier. Always use SetTexID() to modify! The identifier will stored in ImDrawCmd::GetTexID() and passed to backend's RenderDrawData function. @@ -3443,7 +3444,7 @@ struct ImTextureData bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame. // Functions - ImTextureData() { memset(this, 0, sizeof(*this)); TexID = ImTextureID_Invalid; } + ImTextureData() { memset(this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; } ~ImTextureData() { DestroyPixels(); } IMGUI_API void Create(ImTextureFormat format, int w, int h); IMGUI_API void DestroyPixels(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 93fa8c344..d12b8b55d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2457,8 +2457,10 @@ const char* ImTextureDataGetFormatName(ImTextureFormat format) void ImTextureData::Create(ImTextureFormat format, int w, int h) { + IM_ASSERT(Status == ImTextureStatus_Destroyed); DestroyPixels(); Format = format; + Status = ImTextureStatus_WantCreate; Width = w; Height = h; BytesPerPixel = ImTextureDataGetFormatBytesPerPixel(format); @@ -3971,7 +3973,6 @@ ImTextureData* ImFontAtlasTextureAdd(ImFontAtlas* atlas, int w, int h) } new_tex->Create(atlas->TexDesiredFormat, w, h); - new_tex->Status = ImTextureStatus_WantCreate; atlas->TexIsBuilt = false; ImFontAtlasBuildSetTexture(atlas, new_tex); diff --git a/imgui_internal.h b/imgui_internal.h index bf744d4b1..f5f324c6e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3124,7 +3124,7 @@ namespace ImGui IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags); // Fonts, drawing - IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture + IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture. EXPERIMENTAL: DO NOT USE YET. IMGUI_API void UnregisterUserTexture(ImTextureData* tex); IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas); IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas);