mirror of
https://github.com/kevinporetti/UnrealImGui.git
synced 2025-01-29 20:40:31 +00:00
Added support for registering in module user textures to them in ImGui:
- Added ImGuiTextureHandle that is implicitly convertible to ImTextureID and can be used directly with ImGui interface. - Added to ImGui Module interface allowing to register, update and release textures or find handles to existing resources. - Refactored Texture Manager and added functions allowing create, update or release resources for user textures. - Loosened resource verification policy in Texture Manager to work smoothly with external requests and to handle gracefully situations when invalid texture id is passed to ImGui. - Introduced ‘error texture’ that is used for invalid resources.
This commit is contained in:
parent
9c181463ce
commit
dd06fcbbdf
@ -3,6 +3,9 @@
|
||||
#include "ImGuiPrivatePCH.h"
|
||||
|
||||
#include "ImGuiModuleManager.h"
|
||||
|
||||
#include "ImGuiTextureHandle.h"
|
||||
#include "TextureManager.h"
|
||||
#include "Utilities/WorldContext.h"
|
||||
#include "Utilities/WorldContextIndex.h"
|
||||
|
||||
@ -113,6 +116,26 @@ void FImGuiModule::RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle)
|
||||
}
|
||||
}
|
||||
|
||||
FImGuiTextureHandle FImGuiModule::FindTextureHandle(const FName& Name)
|
||||
{
|
||||
const TextureIndex Index = ImGuiModuleManager->GetTextureManager().FindTextureIndex(Name);
|
||||
return (Index != INDEX_NONE) ? FImGuiTextureHandle{ Name, ImGuiInterops::ToImTextureID(Index) } : FImGuiTextureHandle{};
|
||||
}
|
||||
|
||||
FImGuiTextureHandle FImGuiModule::RegisterTexture(const FName& Name, class UTexture2D* Texture, bool bMakeUnique)
|
||||
{
|
||||
const TextureIndex Index = ImGuiModuleManager->GetTextureManager().CreateTextureResources(Name, Texture, bMakeUnique);
|
||||
return FImGuiTextureHandle{ Name, ImGuiInterops::ToImTextureID(Index) };
|
||||
}
|
||||
|
||||
void FImGuiModule::ReleaseTexture(const FImGuiTextureHandle& Handle)
|
||||
{
|
||||
if (Handle.IsValid())
|
||||
{
|
||||
ImGuiModuleManager->GetTextureManager().ReleaseTextureResources(ImGuiInterops::ToTextureIndex(Handle.GetTextureId()));
|
||||
}
|
||||
}
|
||||
|
||||
void FImGuiModule::StartupModule()
|
||||
{
|
||||
// Create managers that implements module logic.
|
||||
@ -198,6 +221,17 @@ void FImGuiModule::ToggleShowDemo()
|
||||
SetShowDemo(!IsShowingDemo());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Partial implementations of other classes that needs access to ImGuiModuleManager
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
bool FImGuiTextureHandle::HasValidEntry() const
|
||||
{
|
||||
const TextureIndex Index = ImGuiInterops::ToTextureIndex(TextureId);
|
||||
return Index != INDEX_NONE && ImGuiModuleManager && ImGuiModuleManager->GetTextureManager().GetTextureName(Index) == Name;
|
||||
}
|
||||
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FImGuiModule, ImGui)
|
||||
|
@ -62,6 +62,8 @@ void FImGuiModuleManager::LoadTextures()
|
||||
{
|
||||
bTexturesLoaded = true;
|
||||
|
||||
TextureManager.InitializeErrorTexture(FColor::Magenta);
|
||||
|
||||
// Create an empty texture at index 0. We will use it for ImGui outputs with null texture id.
|
||||
TextureManager.CreatePlainTexture(FName{ "ImGuiModule_Plain" }, 2, 2, FColor::White);
|
||||
|
||||
|
26
Source/ImGui/Private/ImGuiTextureHandle.cpp
Normal file
26
Source/ImGui/Private/ImGuiTextureHandle.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
|
||||
|
||||
#include "ImGuiPrivatePCH.h"
|
||||
|
||||
#include "ImGuiTextureHandle.h"
|
||||
|
||||
#include "ImGuiInteroperability.h"
|
||||
|
||||
|
||||
FImGuiTextureHandle::FImGuiTextureHandle()
|
||||
: FImGuiTextureHandle(NAME_None, ImGuiInterops::ToImTextureID(INDEX_NONE))
|
||||
{
|
||||
}
|
||||
|
||||
FImGuiTextureHandle::FImGuiTextureHandle(const FName& InName, ImTextureID InTextureId)
|
||||
: Name(InName)
|
||||
, TextureId(InTextureId)
|
||||
{
|
||||
const TextureIndex Index = ImGuiInterops::ToTextureIndex(TextureId);
|
||||
checkf((Index == INDEX_NONE) == (Name == NAME_None),
|
||||
TEXT("Mismatch between Name and TextureId parameters, with only one indicating a null handle.")
|
||||
TEXT(" Name = '%s', TextureIndex(TextureId) = %d"), *Name.ToString(), Index);
|
||||
}
|
||||
|
||||
// FImGuiTextureHandle::HasValidEntry() is implemented in ImGuiModule.cpp to get access to FImGuiModuleManager instance
|
||||
// without referencing in this class.
|
@ -7,10 +7,51 @@
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
void FTextureManager::InitializeErrorTexture(const FColor& Color)
|
||||
{
|
||||
CreatePlainTextureInternal(NAME_ErrorTexture, 2, 2, Color);
|
||||
}
|
||||
|
||||
TextureIndex FTextureManager::CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup)
|
||||
{
|
||||
checkf(FindTextureIndex(Name) == INDEX_NONE, TEXT("Trying to create texture using resource name '%s' that is already registered."), *Name.ToString());
|
||||
checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
|
||||
checkf(FindTextureIndex(Name) == INDEX_NONE, TEXT("Trying to create texture using name '%s' that is already registered."), *Name.ToString());
|
||||
|
||||
return CreateTextureInternal(Name, Width, Height, SrcBpp, SrcData, SrcDataCleanup);
|
||||
}
|
||||
|
||||
TextureIndex FTextureManager::CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color)
|
||||
{
|
||||
checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
|
||||
checkf(FindTextureIndex(Name) == INDEX_NONE, TEXT("Trying to create texture using name '%s' that is already registered."), *Name.ToString());
|
||||
|
||||
return CreatePlainTextureInternal(Name, Width, Height, Color);
|
||||
}
|
||||
|
||||
TextureIndex FTextureManager::CreateTextureResources(const FName& Name, UTexture2D* Texture, bool bMakeUnique)
|
||||
{
|
||||
checkf(Name != NAME_None, TEXT("Trying to create texture resources with a name 'NAME_None' is not allowed."));
|
||||
checkf(Texture, TEXT("Null Texture."));
|
||||
|
||||
if (bMakeUnique)
|
||||
{
|
||||
checkf(FindTextureIndex(Name) == INDEX_NONE, TEXT("Trying to create texture resources using name '%s' that is already registered.")
|
||||
TEXT(" Consider using different name or set bMakeUnique parameter to false."), *Name.ToString());
|
||||
}
|
||||
|
||||
// Create an entry for the texture.
|
||||
return AddTextureEntry(Name, Texture, false, true);
|
||||
}
|
||||
|
||||
void FTextureManager::ReleaseTextureResources(TextureIndex Index)
|
||||
{
|
||||
checkf(IsInRange(Index), TEXT("Invalid texture index %d. Texture resources array has %d entries total."), Index, TextureResources.Num());
|
||||
|
||||
TextureResources[Index] = {};
|
||||
}
|
||||
|
||||
TextureIndex FTextureManager::CreateTextureInternal(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup)
|
||||
{
|
||||
// Create a texture.
|
||||
UTexture2D* Texture = UTexture2D::CreateTransient(Width, Height);
|
||||
|
||||
@ -26,11 +67,19 @@ TextureIndex FTextureManager::CreateTexture(const FName& Name, int32 Width, int3
|
||||
};
|
||||
Texture->UpdateTextureRegions(0, 1u, TextureRegion, SrcBpp * Width, SrcBpp, SrcData, DataCleanup);
|
||||
|
||||
// Create a new entry for the texture.
|
||||
return TextureResources.Emplace(Name, Texture);
|
||||
// Create an entry for the texture.
|
||||
if (Name == NAME_ErrorTexture)
|
||||
{
|
||||
ErrorTexture = { Name, Texture, true };
|
||||
return INDEX_ErrorTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AddTextureEntry(Name, Texture, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
TextureIndex FTextureManager::CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color)
|
||||
TextureIndex FTextureManager::CreatePlainTextureInternal(const FName& Name, int32 Width, int32 Height, const FColor& Color)
|
||||
{
|
||||
// Create buffer with raw data.
|
||||
const uint32 ColorPacked = Color.ToPackedARGB();
|
||||
@ -42,15 +91,44 @@ TextureIndex FTextureManager::CreatePlainTexture(const FName& Name, int32 Width,
|
||||
auto SrcDataCleanup = [](uint8* Data) { delete[] Data; };
|
||||
|
||||
// Create new texture from raw data.
|
||||
return CreateTexture(Name, Width, Height, Bpp, SrcData, SrcDataCleanup);
|
||||
return CreateTextureInternal(Name, Width, Height, Bpp, SrcData, SrcDataCleanup);
|
||||
}
|
||||
|
||||
FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* InTexture)
|
||||
: Name{ InName }
|
||||
, Texture{ InTexture }
|
||||
TextureIndex FTextureManager::AddTextureEntry(const FName& Name, UTexture2D* Texture, bool bAddToRoot, bool bUpdate)
|
||||
{
|
||||
// Add texture to root to prevent garbage collection.
|
||||
Texture->AddToRoot();
|
||||
// If we update try to find entry with that name.
|
||||
TextureIndex Index = bUpdate ? FindTextureIndex(Name) : INDEX_NONE;
|
||||
|
||||
// If we didn't find, try to find and entry to reuse.
|
||||
if (Index == INDEX_NONE)
|
||||
{
|
||||
Index = FindTextureIndex(NAME_None);
|
||||
}
|
||||
|
||||
// Either update/reuse entry or add a new one.
|
||||
if (Index != INDEX_NONE)
|
||||
{
|
||||
TextureResources[Index] = { Name, Texture, bAddToRoot };
|
||||
return Index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TextureResources.Emplace(Name, Texture, bAddToRoot);
|
||||
}
|
||||
}
|
||||
|
||||
FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* InTexture, bool bAddToRoot)
|
||||
: Name(InName)
|
||||
{
|
||||
checkf(InTexture, TEXT("Null texture."));
|
||||
|
||||
if (bAddToRoot)
|
||||
{
|
||||
// Get pointer only for textures that we added to root, so we can later release them.
|
||||
Texture = InTexture;
|
||||
// Add texture to the root to prevent garbage collection.
|
||||
InTexture->AddToRoot();
|
||||
}
|
||||
|
||||
// Create brush and resource handle for input texture.
|
||||
Brush.SetResourceObject(InTexture);
|
||||
@ -59,16 +137,50 @@ FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* I
|
||||
|
||||
FTextureManager::FTextureEntry::~FTextureEntry()
|
||||
{
|
||||
// Release brush.
|
||||
if (Brush.HasUObject() && FSlateApplication::IsInitialized())
|
||||
Reset(true);
|
||||
}
|
||||
|
||||
FTextureManager::FTextureEntry& FTextureManager::FTextureEntry::operator=(FTextureEntry&& Other)
|
||||
{
|
||||
// Release old resources if allocated.
|
||||
Reset(true);
|
||||
|
||||
// Move data and ownership to this instance.
|
||||
Name = MoveTemp(Other.Name);
|
||||
Texture = MoveTemp(Other.Texture);
|
||||
Brush = MoveTemp(Other.Brush);
|
||||
ResourceHandle = MoveTemp(Other.ResourceHandle);
|
||||
|
||||
// Reset the other entry (without releasing resources which are already moved to this instance) to remove tracks
|
||||
// of ownership and mark it as empty/reusable.
|
||||
Other.Reset(false);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void FTextureManager::FTextureEntry::Reset(bool bReleaseResources)
|
||||
{
|
||||
if (bReleaseResources)
|
||||
{
|
||||
FSlateApplication::Get().GetRenderer()->ReleaseDynamicResource(Brush);
|
||||
// Release brush.
|
||||
if (Brush.HasUObject() && FSlateApplication::IsInitialized())
|
||||
{
|
||||
FSlateApplication::Get().GetRenderer()->ReleaseDynamicResource(Brush);
|
||||
}
|
||||
|
||||
// Remove texture from root to allow for garbage collection (it might be invalid, if we never set it
|
||||
// or this is an application shutdown).
|
||||
if (Texture.IsValid())
|
||||
{
|
||||
Texture->RemoveFromRoot();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove texture from root to allow for garbage collection (it might be already invalid if this is application
|
||||
// shutdown).
|
||||
if (Texture.IsValid())
|
||||
{
|
||||
Texture->RemoveFromRoot();
|
||||
}
|
||||
// We use empty name to mark unused entries.
|
||||
Name = NAME_None;
|
||||
|
||||
// Clean fields to make sure that we don't reference released or moved resources.
|
||||
Texture.Reset();
|
||||
Brush = FSlateNoResource();
|
||||
ResourceHandle = FSlateResourceHandle();
|
||||
}
|
||||
|
@ -27,6 +27,13 @@ public:
|
||||
FTextureManager(FTextureManager&&) = default;
|
||||
FTextureManager& operator=(FTextureManager&&) = default;
|
||||
|
||||
// Initialize error texture that will be used for rendering textures without registered resources. Can be called
|
||||
// multiple time, if color needs to be changed.
|
||||
// Note: Because of any-time module loading and lazy resources initialization goals we can't simply call it from
|
||||
// constructor.
|
||||
// @param Color - The color of the error texture
|
||||
void InitializeErrorTexture(const FColor& Color);
|
||||
|
||||
// Find texture index by name.
|
||||
// @param Name - The name of a texture to find
|
||||
// @returns The index of a texture with given name or INDEX_NONE if there is no such texture
|
||||
@ -35,20 +42,22 @@ public:
|
||||
return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.Name == Name; });
|
||||
}
|
||||
|
||||
// Get the name of a texture at given index. Throws exception if index is out of range.
|
||||
// Get the name of a texture at given index. Returns NAME_None, if index is out of range.
|
||||
// @param Index - Index of a texture
|
||||
// @returns The name of a texture at given index
|
||||
FORCEINLINE FName GetTextureName(TextureIndex Index) const
|
||||
// @returns The name of a texture at given index or NAME_None if index is out of range.
|
||||
FName GetTextureName(TextureIndex Index) const
|
||||
{
|
||||
return TextureResources[Index].Name;
|
||||
return IsInRange(Index) ? TextureResources[Index].Name : NAME_None;
|
||||
}
|
||||
|
||||
// Get the Slate Resource Handle to a texture at given index. Throws exception if index is out of range.
|
||||
// Get the Slate Resource Handle to a texture at given index. If index is out of range or resources are not valid
|
||||
// it returns a handle to the error texture.
|
||||
// @param Index - Index of a texture
|
||||
// @returns The Slate Resource Handle for a texture at given index
|
||||
FORCEINLINE const FSlateResourceHandle& GetTextureHandle(TextureIndex Index) const
|
||||
// @returns The Slate Resource Handle for a texture at given index or to error texture, if no valid resources were
|
||||
// found at given index
|
||||
const FSlateResourceHandle& GetTextureHandle(TextureIndex Index) const
|
||||
{
|
||||
return TextureResources[Index].ResourceHandle;
|
||||
return IsValidTexture(Index) ? TextureResources[Index].ResourceHandle : ErrorTexture.ResourceHandle;
|
||||
}
|
||||
|
||||
// Create a texture from raw data. Throws exception if there is already a texture with that name.
|
||||
@ -69,27 +78,81 @@ public:
|
||||
// @returns The index of a texture that was created
|
||||
TextureIndex CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color);
|
||||
|
||||
// Create Slate resources to an existing texture, managed externally. As part of an external interface it allows
|
||||
// to loosen resource verification policy. By default (consistently with other create function) it protects from
|
||||
// creating resources with name that is already registered. If bMakeUnique is false, then existing resources are
|
||||
// updated/replaced. Throws exception, if name argument is NAME_None or texture is null.
|
||||
// @param Name - The texture name
|
||||
// @param Texture - The texture
|
||||
// @param bMakeUnique - If true (default) and there is already a texture with given name, then exception is thrown,
|
||||
// otherwise existing resources are updated.
|
||||
// @returns The index to created/updated texture resources
|
||||
TextureIndex CreateTextureResources(const FName& Name, UTexture2D* Texture, bool bMakeUnique = true);
|
||||
|
||||
// Release resources for given texture. Ignores invalid indices.
|
||||
// @param Index - The index of a texture resources
|
||||
void ReleaseTextureResources(TextureIndex Index);
|
||||
|
||||
private:
|
||||
|
||||
// See CreateTexture for general description.
|
||||
// Internal implementations doesn't validate name or resource uniqueness. Instead it uses NAME_ErrorTexture
|
||||
// (aka NAME_None) and INDEX_ErrorTexture (aka INDEX_NONE) to identify ErrorTexture.
|
||||
TextureIndex CreateTextureInternal(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup = [](uint8*) {});
|
||||
|
||||
// See CreatePlainTexture for general description.
|
||||
// Internal implementations doesn't validate name or resource uniqueness. Instead it uses NAME_ErrorTexture
|
||||
// (aka NAME_None) and INDEX_ErrorTexture (aka INDEX_NONE) to identify ErrorTexture.
|
||||
TextureIndex CreatePlainTextureInternal(const FName& Name, int32 Width, int32 Height, const FColor& Color);
|
||||
|
||||
// Add or reuse texture entry.
|
||||
// @param Name - The texture name
|
||||
// @param Texture - The texture
|
||||
// @param bAddToRoot - If true, we should add texture to root to prevent garbage collection (use for own textures)
|
||||
// @returns The index of the entry that we created or reused
|
||||
TextureIndex AddTextureEntry(const FName& Name, UTexture2D* Texture, bool bAddToRoot, bool bUpdate);
|
||||
|
||||
// Check whether index is in range allocated for TextureResources (it doesn't mean that resources are valid).
|
||||
FORCEINLINE bool IsInRange(TextureIndex Index) const
|
||||
{
|
||||
return static_cast<uint32>(Index) < static_cast<uint32>(TextureResources.Num());
|
||||
}
|
||||
|
||||
// Check whether index is in range and whether texture resources are valid (using NAME_None sentinel).
|
||||
FORCEINLINE bool IsValidTexture(TextureIndex Index) const
|
||||
{
|
||||
return IsInRange(Index) && TextureResources[Index].Name != NAME_None;
|
||||
}
|
||||
|
||||
// Entry for texture resources. Only supports explicit construction.
|
||||
struct FTextureEntry
|
||||
{
|
||||
FTextureEntry(const FName& InName, UTexture2D* InTexture);
|
||||
FTextureEntry() = default;
|
||||
FTextureEntry(const FName& InName, UTexture2D* InTexture, bool bAddToRoot);
|
||||
~FTextureEntry();
|
||||
|
||||
// Copying is not supported.
|
||||
FTextureEntry(const FTextureEntry&) = delete;
|
||||
FTextureEntry& operator=(const FTextureEntry&) = delete;
|
||||
|
||||
// We rely on TArray and don't implement custom move semantics.
|
||||
// We rely on TArray and don't implement custom move constructor...
|
||||
FTextureEntry(FTextureEntry&&) = delete;
|
||||
FTextureEntry& operator=(FTextureEntry&&) = delete;
|
||||
// ... but we need move assignment to support reusing entries.
|
||||
FTextureEntry& operator=(FTextureEntry&& Other);
|
||||
|
||||
FName Name = NAME_None;
|
||||
TWeakObjectPtr<UTexture2D> Texture;
|
||||
FSlateBrush Brush;
|
||||
FSlateResourceHandle ResourceHandle;
|
||||
|
||||
private:
|
||||
|
||||
void Reset(bool bReleaseResources);
|
||||
};
|
||||
|
||||
TArray<FTextureEntry> TextureResources;
|
||||
FTextureEntry ErrorTexture;
|
||||
|
||||
static constexpr EName NAME_ErrorTexture = NAME_None;
|
||||
static constexpr TextureIndex INDEX_ErrorTexture = INDEX_NONE;
|
||||
};
|
||||
|
@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ImGuiDelegates.h"
|
||||
#include "ImGuiTextureHandle.h"
|
||||
|
||||
#include <ModuleManager.h>
|
||||
|
||||
@ -69,6 +70,39 @@ public:
|
||||
*/
|
||||
virtual void RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle);
|
||||
|
||||
/**
|
||||
* If it exists, get a handle to the texture with given resource name.
|
||||
*
|
||||
* @param Name - Resource name of a texture to find
|
||||
* @returns Handle to a registered texture or invalid handle if resources could not be found or were not valid
|
||||
*/
|
||||
virtual FImGuiTextureHandle FindTextureHandle(const FName& Name);
|
||||
|
||||
/**
|
||||
* Register texture and create its Slate resources. If texture with that name already exists then it may be updated
|
||||
* or if bMakeUnique is true, exception will be thrown. Throws exception, if name argument is NAME_None or texture
|
||||
* is null.
|
||||
*
|
||||
* Note, that updating texture resources doesn't invalidate already existing handles and returned handle will have
|
||||
* the same value.
|
||||
*
|
||||
* @param Name - Resource name for the texture that needs to be registered or updated
|
||||
* @param Texture - Texture for which we want to create or update Slate resources
|
||||
* @param bMakeUnique - If false then existing resources are updated/overwritten (default). If true, then stricter
|
||||
* policy is applied and if resource with that name exists then exception is thrown.
|
||||
* @returns Handle to the texture resources, which can be used to release allocated resources and as an argument to
|
||||
* relevant ImGui functions
|
||||
*/
|
||||
virtual FImGuiTextureHandle RegisterTexture(const FName& Name, class UTexture2D* Texture, bool bMakeUnique = false);
|
||||
|
||||
/**
|
||||
* Unregister texture and release its Slate resources. If handle is null or not valid, this function fails silently
|
||||
* (for definition of 'valid' look @ FImGuiTextureHandle).
|
||||
*
|
||||
* @returns ImGui Texture Handle to texture that needs to be unregistered
|
||||
*/
|
||||
virtual void ReleaseTexture(const FImGuiTextureHandle& Handle);
|
||||
|
||||
/**
|
||||
* Check whether Input Mode is enabled (tests ImGui.InputEnabled console variable).
|
||||
*
|
||||
|
64
Source/ImGui/Public/ImGuiTextureHandle.h
Normal file
64
Source/ImGui/Public/ImGuiTextureHandle.h
Normal file
@ -0,0 +1,64 @@
|
||||
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <CoreMinimal.h>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
|
||||
/**
|
||||
* Handle to texture resources registered in module instance. Returned after successful texture registration.
|
||||
* Can be implicitly converted to ImTextureID making it possible to use it directly with ImGui interface.
|
||||
* Once texture is not needed handle can be used to release resources.
|
||||
*/
|
||||
class IMGUI_API FImGuiTextureHandle
|
||||
{
|
||||
public:
|
||||
|
||||
/** Creates an empty (null and not valid) texture handle. */
|
||||
FImGuiTextureHandle();
|
||||
|
||||
/**
|
||||
* Checks whether this handle is null. Can be used as a quick test whether it points to any resources but it does
|
||||
* not check whether those resources are valid (see @ IsValid).
|
||||
*
|
||||
* @returns True, if this handle is null (Name is NAME_None and TextureId is invalid) and false otherwise.
|
||||
*/
|
||||
bool IsNull() const { return Name == NAME_None; }
|
||||
|
||||
/**
|
||||
* Checks whether this handle is not null and valid. Valid handle points to valid texture resources.
|
||||
* It is slower but safer test, more useful when there is no guarantee that resources haven't been released.
|
||||
*
|
||||
* @returns True, if this handle is not null and valid, false otherwise.
|
||||
*/
|
||||
bool IsValid() const { return !IsNull() && HasValidEntry(); }
|
||||
|
||||
/** Get the name of the texture resources (NAME_None if handle is null). */
|
||||
const FName& GetName() const { return Name; }
|
||||
|
||||
/** Get the ImGui texture id for this texture (invalid if handle is null). */
|
||||
ImTextureID GetTextureId() const { return TextureId; }
|
||||
|
||||
/** Implicit conversion to ImTextureID. */
|
||||
operator ImTextureID() const { return GetTextureId(); }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Creates a texture handle with known name and texture id.
|
||||
* @param InName - Name of the texture
|
||||
* @param InTextureId - ImGui id of texture
|
||||
*/
|
||||
FImGuiTextureHandle(const FName& InName, ImTextureID InTextureId);
|
||||
|
||||
/** Checks if texture manager has entry that matches this name and texture id index. */
|
||||
bool HasValidEntry() const;
|
||||
|
||||
FName Name;
|
||||
ImTextureID TextureId;
|
||||
|
||||
// Give module class a private access, so it can create valid handles.
|
||||
friend class FImGuiModule;
|
||||
};
|
Loading…
Reference in New Issue
Block a user