How do renderers create textures
When talking about the UImGui::Texture class, renderers
must create their own classes that derive from the
UImGui::GenericTexture abstract class.
However, GenericTexture and GenericRenderer
do not depend on each other. This produces following side effects:
- Custom renderers can decide whether to implement a texture backend(some applications might prefer their own custom abstractions)
- Custom renderers based on OpenGL, Vulkan and/or WebGPU can decide to reuse the existing texture creation workflows
- Custom renderers can easily mix and match texture and renderer backends
This is why in the RendererData struct one can see that
there are 2 members of the RendererType enum. One for the
renderer, and one for the texture backend.
By default the rendererType and the
textureRendererType fields are set to be equal to each
other. In order for your renderer to reuse one of the existing texture
renderer backends use
UImGui::Renderer::data().textureRendererType to set it to
another type before creating your texture.
The GenericTexture class
The UImGui::GenericTexture abstract class looks like
this:
class GenericTexture
{
public:
// Event Safety - Any time
virtual void init(TextureData& dt, String location, bool bFiltered) noexcept = 0;
// Event Safety - Post-begin
virtual uintptr_t get(TextureData& dt) noexcept = 0;
// Event Safety - Post-begin
virtual void load(TextureData& dt, void* data, FVector2 size, uint32_t depth, bool bFreeImageData,
const TFunction<void(void*)>& freeFunc) noexcept = 0;
template<TextureFormat format>
static bool saveToFile(TextureData& dt, const String location, const TextureFormat fmt = format, const uint8_t jpegQuality = 100);
// Cleans up the image data
// Event Safety - All initiated
virtual void clear(TextureData& dt) noexcept = 0;
virtual ~GenericTexture() noexcept = default;
protected:
friend class Texture;
static void beginLoad(TextureData& dt, void** data, FVector2& size) noexcept;
static void endLoad(TextureData& dt, void* data, bool bFreeImageData, const TFunction<void(void*)>& freeFunc) noexcept;
static void defaultInit(TextureData& dt, String location, bool bFiltered) noexcept;
static void defaultClear(TextureData& dt) noexcept;
};If you compare it to the normal UImGui::Texture class,
you'll discover that most of the functions map 1:1, except that most
functions in the GenericTexture class get a
TextureData& as their first argument. This is to ensure
that derivations based on GenericTexture are always
code-only, since the same backend instance is used between all
textures.
The TextureData struct looks like this:
struct TextureData
{
String filename;
FVector2 size;
bool bFiltered;
int channels;
uintptr_t id;
void* data;
// This stores the string location for the internal C storage system
size_t storageIndex;
CustomSaveFunction customSaveFunction;
// Data for each custom texture renderer backend
void* context;
size_t contextSize;
};The context and contextSize members are
used for storing any additional data that the custom texture backend
instance may need.
All other members are part of what all textures store as their data. For more info, refer to the Textures entry.
Examples
Here is a pseudo-example that showcases how custom texture backends are generally implemented:
class PseudoTexture final : public UImGui::GenericTexture
{
public:
virtual void init(UImGui::TextureData& dt, const UImGui::String location, const bool bFiltered) noexcept override
{
defaultInit(dt, location, bFiltered);
}
virtual void load(UImGui::TextureData& dt, void* data, UImGui::FVector2 size, uint32_t depth, bool bFreeImageData,
const TFunction<void(void*)>& freeFunc) noexcept override
{
beginLoad(dt, &data, size);
// Load using your renderer API here
endLoad(dt, data, bFreeImageData, freeFunc);
}
virtual uintptr_t get(UImGui::TextureData& dt) noexcept override
{
return dt.id;
}
virtual void clear(UImGui::TextureData& dt) noexcept override
{
// Clear with your renderer API here
dt.id = 0;
defaultClear(dt);
}
virtual ~TestOpenGLTexture() noexcept override = default;
};To then use the PseudoTexture backend, create an
instance of it and assign its address to the customTexture
field of the InitInfo struct.
More examples can be found in the following documentation entry.
C API
The C API for the GenericTexture class looks like
this:
UImGui_CGenericTexture* UImGui_CGenericTexture_make(
UImGui_CGenericTexture_InitFun init,
UImGui_CGenericTexture_GetFun get,
UImGui_CGenericTexture_LoadFun load,
UImGui_CGenericTexture_Clear clear
);
void UImGui_CGenericTexture_free(UImGui_CGenericTexture* texture);As you can see, the callback functions provided to the
UImGui_CGenericTexture_make() function are equivalent to
the ones in the C++ class.
These function pointer types are implemented like this:
typedef void UImGui_CGenericTexture;
typedef void(*UImGui_CGenericTexture_VoidFun)(UImGui_TextureData*);
typedef void(*UImGui_CGenericTexture_InitFun)(UImGui_TextureData*, UImGui_String, bool);
typedef uintptr_t(*UImGui_CGenericTexture_GetFun)(UImGui_TextureData*);
typedef void(*UImGui_CGenericTexture_LoadFun)(UImGui_TextureData*, void*, UImGui_FVector2, uint32_t, bool);
typedef UImGui_CGenericTexture_VoidFun UImGui_CGenericTexture_Clear;Event safety
All functions in the UImGui::GenericTexture class or C
API are rated with the same event safety as their counterparts in the
UImGui::Texture class.
- Home
- Beginner content
- Install guide
- Creating and using the UI components
- The Instance
- The Init Info struct
- Building better titlebar menus
- Textures
- Logging
- Unicode support
- Additional features
- Client-side bar
- Custom type definitions
- Memory management
- C API development
- Config files and Folders
- Interfaces
- Internal Event safety
- Customising the build system
- Modules system
- Collaborating with others
- Advanced content
- Loading dynamic libraries at runtime
- Understanding the library layout
- Compilation mode modifiers
- Supporting plugins
- Production export and deployment
- OS integration tips
- Targeting WASM
- Using a custom rendering engine:
- Using a custom windowing backend:
- Developer and contributor resources
- Misc