Textures: ImTextureData::Create() sets status. RegisterUserTexture() increases RefCount. Added comments about ImTextureData::GetTexRef(). (#8789)

This commit is contained in:
ocornut
2025-07-11 16:49:28 +02:00
parent 0e6e876f23
commit a0d3e405a3
5 changed files with 14 additions and 7 deletions
+2
View File
@@ -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`. - 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. - 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. - 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. - 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`. - 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; }` - 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; }`
+4 -1
View File
@@ -8732,16 +8732,19 @@ ImFont* ImGui::GetDefaultFont()
return g.IO.FontDefault ? g.IO.FontDefault : atlas->Fonts[0]; return g.IO.FontDefault ? g.IO.FontDefault : atlas->Fonts[0];
} }
// EXPERIMENTAL: DO NOT USE YET.
void ImGui::RegisterUserTexture(ImTextureData* tex) void ImGui::RegisterUserTexture(ImTextureData* tex)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(tex->RefCount > 0); tex->RefCount++;
g.UserTextures.push_back(tex); g.UserTextures.push_back(tex);
} }
void ImGui::UnregisterUserTexture(ImTextureData* tex) void ImGui::UnregisterUserTexture(ImTextureData* tex)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(tex->RefCount > 0);
tex->RefCount--;
g.UserTextures.find_erase(tex); g.UserTextures.find_erase(tex);
} }
+5 -4
View File
@@ -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. // 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 // - 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. // 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 create a ImTextureRef from a ImTextureData you can use ImTextureData::GetTexRef().
// to be useful to the end-user, and it would be erroneously called by many legacy code. // 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. // - 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. // - 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; } // 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 struct ImTextureData
{ {
//------------------------------------------ core / backend --------------------------------------- //------------------------------------------ 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! 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. 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. 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. bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame.
// Functions // Functions
ImTextureData() { memset(this, 0, sizeof(*this)); TexID = ImTextureID_Invalid; } ImTextureData() { memset(this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; }
~ImTextureData() { DestroyPixels(); } ~ImTextureData() { DestroyPixels(); }
IMGUI_API void Create(ImTextureFormat format, int w, int h); IMGUI_API void Create(ImTextureFormat format, int w, int h);
IMGUI_API void DestroyPixels(); IMGUI_API void DestroyPixels();
+2 -1
View File
@@ -2457,8 +2457,10 @@ const char* ImTextureDataGetFormatName(ImTextureFormat format)
void ImTextureData::Create(ImTextureFormat format, int w, int h) void ImTextureData::Create(ImTextureFormat format, int w, int h)
{ {
IM_ASSERT(Status == ImTextureStatus_Destroyed);
DestroyPixels(); DestroyPixels();
Format = format; Format = format;
Status = ImTextureStatus_WantCreate;
Width = w; Width = w;
Height = h; Height = h;
BytesPerPixel = ImTextureDataGetFormatBytesPerPixel(format); BytesPerPixel = ImTextureDataGetFormatBytesPerPixel(format);
@@ -3971,7 +3973,6 @@ ImTextureData* ImFontAtlasTextureAdd(ImFontAtlas* atlas, int w, int h)
} }
new_tex->Create(atlas->TexDesiredFormat, w, h); new_tex->Create(atlas->TexDesiredFormat, w, h);
new_tex->Status = ImTextureStatus_WantCreate;
atlas->TexIsBuilt = false; atlas->TexIsBuilt = false;
ImFontAtlasBuildSetTexture(atlas, new_tex); ImFontAtlasBuildSetTexture(atlas, new_tex);
+1 -1
View File
@@ -3124,7 +3124,7 @@ namespace ImGui
IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags); IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags);
// Fonts, drawing // 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 UnregisterUserTexture(ImTextureData* tex);
IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas); IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas);
IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas); IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas);