Skip to content

Commit

Permalink
Atlas: Added font texture updating support for backends.
Browse files Browse the repository at this point in the history
  • Loading branch information
thedmd committed Jan 26, 2021
1 parent 4f776f5 commit 131fd5f
Show file tree
Hide file tree
Showing 14 changed files with 646 additions and 305 deletions.
23 changes: 22 additions & 1 deletion backends/imgui_impl_allegro5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2021-01-26: Renderer: Add support for ImGuiBackendFlags_RendererHasTexReload.
// 2020-08-10: Inputs: Fixed horizontal mouse wheel direction.
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
Expand Down Expand Up @@ -171,13 +172,14 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
al_use_projection_transform(&last_projection_transform);
}

bool ImGui_ImplAllegro5_CreateDeviceObjects()
static bool ImGui_ImplAllegro5_UpdateFontsTexture()
{
// Build texture atlas
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
io.Fonts->MarkClean();

// Create texture
int flags = al_get_new_bitmap_flags();
Expand Down Expand Up @@ -205,10 +207,25 @@ bool ImGui_ImplAllegro5_CreateDeviceObjects()
if (!cloned_img)
return false;

if (g_Texture)
{
al_destroy_bitmap(g_Texture);
ImGui::GetIO().Fonts->TexID = NULL;
g_Texture = NULL;
}

// Store our identifier
io.Fonts->TexID = (void*)cloned_img;
g_Texture = cloned_img;

return true;
}

bool ImGui_ImplAllegro5_CreateDeviceObjects()
{
if (!ImGui_ImplAllegro5_UpdateFontsTexture())
return false;

// Create an invisible mouse cursor
// Because al_hide_mouse_cursor() seems to mess up with the actual inputs..
ALLEGRO_BITMAP* mouse_cursor = al_create_bitmap(8, 8);
Expand Down Expand Up @@ -255,6 +272,7 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
// Setup backend capabilities flags
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_RendererHasTexReload; // We can update font atlas textures (optional)
io.BackendPlatformName = io.BackendRendererName = "imgui_impl_allegro5";

// Create custom vertex declaration.
Expand Down Expand Up @@ -405,6 +423,9 @@ void ImGui_ImplAllegro5_NewFrame()

ImGuiIO& io = ImGui::GetIO();

if (io.Fonts->IsDirty())
ImGui_ImplAllegro5_UpdateFontsTexture();

// Setup display size (every frame to accommodate for window resizing)
int w, h;
w = al_get_display_width(g_Display);
Expand Down
105 changes: 72 additions & 33 deletions backends/imgui_impl_dx10.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2020-04-24: DirectX10: Add support for ImGuiBackendFlags_RendererHasTexReload.
// 2019-07-21: DirectX10: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData().
// 2019-05-29: DirectX10: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX10: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
Expand Down Expand Up @@ -45,8 +46,11 @@ static ID3D10VertexShader* g_pVertexShader = NULL;
static ID3D10InputLayout* g_pInputLayout = NULL;
static ID3D10Buffer* g_pVertexConstantBuffer = NULL;
static ID3D10PixelShader* g_pPixelShader = NULL;
static ID3D10Texture2D* g_pFontTexture = NULL;
static ID3D10SamplerState* g_pFontSampler = NULL;
static ID3D10ShaderResourceView*g_pFontTextureView = NULL;
static int g_FontTextureWidth = 0;
static int g_FontTextureHeight = 0;
static ID3D10RasterizerState* g_pRasterizerState = NULL;
static ID3D10BlendState* g_pBlendState = NULL;
static ID3D10DepthStencilState* g_pDepthStencilState = NULL;
Expand Down Expand Up @@ -264,50 +268,78 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
}

static void ImGui_ImplDX10_CreateFontsTexture()
static void ImGui_ImplDX10_UpdateFontsTexture()
{
// Build texture atlas
ImGuiIO& io = ImGui::GetIO();

// Build texture atlas
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
io.Fonts->MarkClean();

// Upload texture to graphics system
if ((!g_pFontTextureView) || (g_FontTextureWidth != width) || (g_FontTextureHeight != height))
{
D3D10_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;

ID3D10Texture2D* pTexture = NULL;
D3D10_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels;
subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);

// Create texture view
D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
ZeroMemory(&srv_desc, sizeof(srv_desc));
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MipLevels = desc.MipLevels;
srv_desc.Texture2D.MostDetailedMip = 0;
g_pd3dDevice->CreateShaderResourceView(pTexture, &srv_desc, &g_pFontTextureView);
pTexture->Release();
// Either we have no texture or the size has changed, so (re-)create the texture

// Release old texture
if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (g_pFontTexture) { g_pFontTexture->Release(); g_pFontTexture = NULL; }

// Create new texture
{
D3D10_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;

D3D10_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels;
subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &g_pFontTexture);

// Create texture view
D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
ZeroMemory(&srv_desc, sizeof(srv_desc));
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MipLevels = desc.MipLevels;
srv_desc.Texture2D.MostDetailedMip = 0;
g_pd3dDevice->CreateShaderResourceView(g_pFontTexture, &srv_desc, &g_pFontTextureView);
}

// Store size
g_FontTextureWidth = width;
g_FontTextureHeight = height;
}
else
{
// Upload new atlas data

D3D10_BOX box;
box.left = 0;
box.right = width;
box.top = 0;
box.bottom = height;
box.front = 0;
box.back = 1;

g_pd3dDevice->UpdateSubresource(g_pFontTexture, 0, &box, pixels, g_FontTextureWidth * 4, 0);
}

// Store our identifier
io.Fonts->TexID = (ImTextureID)g_pFontTextureView;

// Create texture sampler
// Create texture sampler if required
if (!g_pFontSampler)
{
D3D10_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
Expand Down Expand Up @@ -471,7 +503,7 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
}

ImGui_ImplDX10_CreateFontsTexture();
ImGui_ImplDX10_UpdateFontsTexture();

return true;
}
Expand All @@ -483,6 +515,7 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()

if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; }
if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (g_pFontTexture) { g_pFontTexture->Release(); g_pFontTexture = NULL; }
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }

Expand All @@ -501,6 +534,7 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_dx10";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
io.BackendFlags |= ImGuiBackendFlags_RendererHasTexReload; // We support font atlas texture reloading (IsDirty() check in ImGui_ImplDX10_NewFrame)

// Get factory from device
IDXGIDevice* pDXGIDevice = NULL;
Expand Down Expand Up @@ -530,6 +564,11 @@ void ImGui_ImplDX10_Shutdown()

void ImGui_ImplDX10_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();

if (!g_pFontSampler)
ImGui_ImplDX10_CreateDeviceObjects();

if (io.Fonts->IsDirty())
ImGui_ImplDX10_UpdateFontsTexture();
}
Loading

0 comments on commit 131fd5f

Please sign in to comment.