mirror of
https://github.com/ocornut/imgui.git
synced 2025-09-06 19:38:28 +00:00
Backends: Allegro5: added ImGuiBackendFlags_RendererHasTextures support.
This commit is contained in:
@@ -2,7 +2,8 @@
|
|||||||
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
|
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_DestroyFontsTexture().
|
||||||
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||||
// 2025-01-06: Avoid calling al_set_mouse_cursor() repeatedly since it appears to leak on on X11 (#8256).
|
// 2025-01-06: Avoid calling al_set_mouse_cursor() repeatedly since it appears to leak on on X11 (#8256).
|
||||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||||
@@ -137,6 +139,13 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplAllegro5_UpdateTexture(tex);
|
||||||
|
|
||||||
// Backup Allegro state that will be modified
|
// Backup Allegro state that will be modified
|
||||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
|
ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
|
||||||
@@ -232,43 +241,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||||||
|
|
||||||
bool ImGui_ImplAllegro5_CreateDeviceObjects()
|
bool ImGui_ImplAllegro5_CreateDeviceObjects()
|
||||||
{
|
{
|
||||||
// Build texture atlas
|
|
||||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
|
||||||
|
|
||||||
// Create texture
|
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
int flags = al_get_new_bitmap_flags();
|
|
||||||
int fmt = al_get_new_bitmap_format();
|
|
||||||
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
|
||||||
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
|
|
||||||
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
|
|
||||||
al_set_new_bitmap_flags(flags);
|
|
||||||
al_set_new_bitmap_format(fmt);
|
|
||||||
if (!img)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ALLEGRO_LOCKED_REGION* locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
|
|
||||||
if (!locked_img)
|
|
||||||
{
|
|
||||||
al_destroy_bitmap(img);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(locked_img->data, pixels, sizeof(int) * width * height);
|
|
||||||
al_unlock_bitmap(img);
|
|
||||||
|
|
||||||
// Convert software texture to hardware texture.
|
|
||||||
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
|
|
||||||
al_destroy_bitmap(img);
|
|
||||||
if (!cloned_img)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)cloned_img);
|
|
||||||
bd->Texture = cloned_img;
|
|
||||||
|
|
||||||
// Create an invisible mouse cursor
|
// Create an invisible mouse cursor
|
||||||
// Because al_hide_mouse_cursor() seems to mess up with the actual inputs..
|
// Because al_hide_mouse_cursor() seems to mess up with the actual inputs..
|
||||||
@@ -279,16 +252,81 @@ bool ImGui_ImplAllegro5_CreateDeviceObjects()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplAllegro5_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
|
{
|
||||||
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
// Create texture
|
||||||
|
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||||
|
const int new_bitmap_flags = al_get_new_bitmap_flags();
|
||||||
|
int new_bitmap_format = al_get_new_bitmap_format();
|
||||||
|
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
||||||
|
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
|
||||||
|
ALLEGRO_BITMAP* cpu_bitmap = al_create_bitmap(tex->Width, tex->Height);
|
||||||
|
al_set_new_bitmap_flags(new_bitmap_flags);
|
||||||
|
al_set_new_bitmap_format(new_bitmap_format);
|
||||||
|
IM_ASSERT(cpu_bitmap != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
|
// Upload pixels
|
||||||
|
ALLEGRO_LOCKED_REGION* locked_region = al_lock_bitmap(cpu_bitmap, al_get_bitmap_format(cpu_bitmap), ALLEGRO_LOCK_WRITEONLY);
|
||||||
|
IM_ASSERT(locked_region != nullptr && "Backend failed to create texture!");
|
||||||
|
memcpy(locked_region->data, tex->GetPixels(), tex->GetSizeInBytes());
|
||||||
|
al_unlock_bitmap(cpu_bitmap);
|
||||||
|
|
||||||
|
// Convert software texture to hardware texture.
|
||||||
|
ALLEGRO_BITMAP* gpu_bitmap = al_clone_bitmap(cpu_bitmap);
|
||||||
|
al_destroy_bitmap(cpu_bitmap);
|
||||||
|
IM_ASSERT(gpu_bitmap != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)gpu_bitmap);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
|
ImTextureRect r_bb = tex->UpdateRect; // Bounding box encompassing all individual updates
|
||||||
|
ALLEGRO_BITMAP* gpu_bitmap = (ALLEGRO_BITMAP*)(intptr_t)tex->TexID;
|
||||||
|
ALLEGRO_LOCKED_REGION* locked_region = al_lock_bitmap_region(gpu_bitmap, r_bb.x, r_bb.y, r_bb.w, r_bb.h, al_get_bitmap_format(gpu_bitmap), ALLEGRO_LOCK_WRITEONLY);
|
||||||
|
IM_ASSERT(locked_region && "Backend failed to update texture!");
|
||||||
|
for (ImTextureRect& r : tex->Updates)
|
||||||
|
for (int y = 0; y < r.h; y++)
|
||||||
|
memcpy((unsigned char*)locked_region->data + locked_region->pitch * (r.y - r_bb.y + y) + (r.x - r_bb.x) * tex->BytesPerPixel, // dst
|
||||||
|
tex->GetPixelsAt(r.x, r.y + y), r.w * tex->BytesPerPixel); // src, block pitch
|
||||||
|
al_unlock_bitmap(gpu_bitmap);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||||
|
{
|
||||||
|
ALLEGRO_BITMAP* backend_tex = (ALLEGRO_BITMAP*)(intptr_t)tex->TexID;
|
||||||
|
if (backend_tex)
|
||||||
|
al_destroy_bitmap(backend_tex);
|
||||||
|
|
||||||
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui_ImplAllegro5_InvalidateDeviceObjects()
|
void ImGui_ImplAllegro5_InvalidateDeviceObjects()
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
if (bd->Texture)
|
|
||||||
{
|
// Destroy all textures
|
||||||
io.Fonts->SetTexID(0);
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
al_destroy_bitmap(bd->Texture);
|
if (tex->RefCount == 1)
|
||||||
bd->Texture = nullptr;
|
{
|
||||||
}
|
tex->SetStatus(ImTextureStatus_WantDestroy);
|
||||||
|
ImGui_ImplAllegro5_UpdateTexture(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy mouse cursor
|
||||||
if (bd->MouseCursorInvisible)
|
if (bd->MouseCursorInvisible)
|
||||||
{
|
{
|
||||||
al_destroy_mouse_cursor(bd->MouseCursorInvisible);
|
al_destroy_mouse_cursor(bd->MouseCursorInvisible);
|
||||||
@@ -439,6 +477,7 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
|||||||
io.BackendPlatformUserData = (void*)bd;
|
io.BackendPlatformUserData = (void*)bd;
|
||||||
io.BackendPlatformName = io.BackendRendererName = "imgui_impl_allegro5";
|
io.BackendPlatformName = io.BackendRendererName = "imgui_impl_allegro5";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
||||||
|
|
||||||
bd->Display = display;
|
bd->Display = display;
|
||||||
bd->LastCursor = ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE;
|
bd->LastCursor = ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE;
|
||||||
@@ -478,7 +517,7 @@ void ImGui_ImplAllegro5_Shutdown()
|
|||||||
|
|
||||||
io.BackendPlatformName = io.BackendRendererName = nullptr;
|
io.BackendPlatformName = io.BackendRendererName = nullptr;
|
||||||
io.BackendPlatformUserData = nullptr;
|
io.BackendPlatformUserData = nullptr;
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_HasMouseCursors;
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_RendererHasTextures);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,12 +647,8 @@ void ImGui_ImplAllegro5_NewFrame()
|
|||||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplAllegro5_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplAllegro5_Init()?");
|
||||||
|
|
||||||
if (!bd->Texture)
|
|
||||||
ImGui_ImplAllegro5_CreateDeviceObjects();
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
// Setup display size (every frame to accommodate for window resizing)
|
// Setup display size (every frame to accommodate for window resizing)
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
int w, h;
|
int w, h;
|
||||||
w = al_get_display_width(bd->Display);
|
w = al_get_display_width(bd->Display);
|
||||||
h = al_get_display_height(bd->Display);
|
h = al_get_display_height(bd->Display);
|
||||||
|
@@ -2,7 +2,8 @@
|
|||||||
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
|
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
@@ -36,4 +37,7 @@ IMGUI_IMPL_API bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event);
|
|||||||
IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects();
|
||||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAllegro5_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
Reference in New Issue
Block a user