Skip to content

Commit abd2394

Browse files
mctb32TheMostDiligent
authored andcommitted
Update ImGui renderer
1 parent 6b8fd03 commit abd2394

File tree

6 files changed

+95
-52
lines changed

6 files changed

+95
-52
lines changed

Imgui/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ if(PLATFORM_UNIVERSAL_WINDOWS)
124124
target_compile_definitions(Diligent-Imgui PRIVATE IMGUI_DISABLE_WIN32_FUNCTIONS)
125125
endif()
126126

127+
target_compile_definitions(Diligent-Imgui PUBLIC IMGUI_DEFINE_MATH_OPERATORS)
128+
127129
if(PLATFORM_WIN32 AND MINGW_BUILD)
128130
# Link with dwmapi.lib as imgui_impl_win32.cpp skips
129131
# '#pragma comment(lib, "dwmapi")'

Imgui/interface/ImGuiDiligentRenderer.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,18 @@ class ImGuiDiligentRenderer
6464
void RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDrawData);
6565
void InvalidateDeviceObjects();
6666
void CreateDeviceObjects();
67-
void CreateFontsTexture();
6867

6968
private:
7069
inline float4 TransformClipRect(const ImVec2& DisplaySize, const float4& rect) const;
70+
void UpdateTexture(IDeviceContext* pCtx, ImTextureData* tex);
71+
void DestroyTexture(ImTextureData* tex);
7172

7273
private:
7374
RefCntAutoPtr<IRenderDevice> m_pDevice;
7475
RefCntAutoPtr<IBuffer> m_pVB;
7576
RefCntAutoPtr<IBuffer> m_pIB;
7677
RefCntAutoPtr<IBuffer> m_pVertexConstantBuffer;
7778
RefCntAutoPtr<IPipelineState> m_pPSO;
78-
RefCntAutoPtr<ITextureView> m_pFontSRV;
7979
RefCntAutoPtr<IShaderResourceBinding> m_pSRB;
8080
IShaderResourceVariable* m_pTextureVar = nullptr;
8181

Imgui/interface/ImGuiImplDiligent.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,6 @@ class ImGuiImplDiligent
120120
void InvalidateDeviceObjects();
121121
void CreateDeviceObjects();
122122

123-
void UpdateFontsTexture();
124-
125123
protected:
126124
std::unique_ptr<ImGuiDiligentRenderer> m_pRenderer;
127125
};

Imgui/src/ImGuiDiligentRenderer.cpp

Lines changed: 90 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ ImGuiDiligentRenderer::ImGuiDiligentRenderer(const ImGuiDiligentCreateInfo& CI)
508508
IO.BackendRendererName = "ImGuiDiligentRenderer";
509509
if (m_BaseVertexSupported)
510510
IO.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
511+
IO.BackendFlags |= ImGuiBackendFlags_RendererHasTextures;
511512

512513
CreateDeviceObjects();
513514
}
@@ -533,11 +534,17 @@ void ImGuiDiligentRenderer::EndFrame()
533534

534535
void ImGuiDiligentRenderer::InvalidateDeviceObjects()
535536
{
537+
// Destroy ImGui textures that may still exist
538+
ImGuiPlatformIO& io = ImGui::GetPlatformIO();
539+
for (int n = 0; n < io.Textures.Size; ++n)
540+
{
541+
DestroyTexture(io.Textures[n]);
542+
}
543+
536544
m_pVB.Release();
537545
m_pIB.Release();
538546
m_pVertexConstantBuffer.Release();
539547
m_pPSO.Release();
540-
m_pFontSRV.Release();
541548
m_pSRB.Release();
542549
}
543550

@@ -718,42 +725,10 @@ void ImGuiDiligentRenderer::CreateDeviceObjects()
718725
}
719726
m_pPSO->GetStaticVariableByName(SHADER_TYPE_VERTEX, "Constants")->Set(m_pVertexConstantBuffer);
720727

721-
CreateFontsTexture();
722-
}
723-
724-
void ImGuiDiligentRenderer::CreateFontsTexture()
725-
{
726-
// Build texture atlas
727-
ImGuiIO& IO = ImGui::GetIO();
728-
729-
unsigned char* pData = nullptr;
730-
int Width = 0;
731-
int Weight = 0;
732-
IO.Fonts->GetTexDataAsRGBA32(&pData, &Width, &Weight);
733-
734-
TextureDesc FontTexDesc;
735-
FontTexDesc.Name = "Imgui font texture";
736-
FontTexDesc.Type = RESOURCE_DIM_TEX_2D;
737-
FontTexDesc.Width = static_cast<Uint32>(Width);
738-
FontTexDesc.Height = static_cast<Uint32>(Weight);
739-
FontTexDesc.Format = TEX_FORMAT_RGBA8_UNORM;
740-
FontTexDesc.BindFlags = BIND_SHADER_RESOURCE;
741-
FontTexDesc.Usage = USAGE_IMMUTABLE;
742-
743-
TextureSubResData Mip0Data[] = {{pData, 4 * Uint64{FontTexDesc.Width}}};
744-
TextureData InitData(Mip0Data, _countof(Mip0Data));
745-
746-
RefCntAutoPtr<ITexture> pFontTex;
747-
m_pDevice->CreateTexture(FontTexDesc, &InitData, &pFontTex);
748-
m_pFontSRV = pFontTex->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
749-
750728
m_pSRB.Release();
751729
m_pPSO->CreateShaderResourceBinding(&m_pSRB, true);
752730
m_pTextureVar = m_pSRB->GetVariableByName(SHADER_TYPE_PIXEL, "Texture");
753731
VERIFY_EXPR(m_pTextureVar != nullptr);
754-
755-
// Store our identifier
756-
IO.Fonts->TexID = reinterpret_cast<ImTextureID>(m_pFontSRV.RawPtr());
757732
}
758733

759734
float4 ImGuiDiligentRenderer::TransformClipRect(const ImVec2& DisplaySize, const float4& rect) const
@@ -869,12 +844,87 @@ float4 ImGuiDiligentRenderer::TransformClipRect(const ImVec2& DisplaySize, const
869844
}
870845
}
871846

847+
void ImGuiDiligentRenderer::UpdateTexture(IDeviceContext* pCtx, ImTextureData* tex)
848+
{
849+
auto* backend = static_cast<ITexture*>(tex->BackendUserData);
850+
851+
if (tex->Status == ImTextureStatus_WantCreate)
852+
{
853+
IM_ASSERT(backend == nullptr && tex->TexID == ImTextureID_Invalid);
854+
855+
TextureDesc desc;
856+
desc.Name = "ImGuiTexture";
857+
desc.Type = RESOURCE_DIM_TEX_2D;
858+
desc.Width = static_cast<Uint32>(tex->Width);
859+
desc.Height = static_cast<Uint32>(tex->Height);
860+
desc.Format = tex->Format == ImTextureFormat_Alpha8 ? TEX_FORMAT_R8_UNORM : TEX_FORMAT_RGBA8_UNORM;
861+
desc.Usage = USAGE_DEFAULT; // allow future UpdateTexture()
862+
desc.BindFlags = BIND_SHADER_RESOURCE;
863+
864+
TextureSubResData mip0;
865+
mip0.pData = tex->GetPixels();
866+
mip0.Stride = tex->GetPitch();
867+
TextureData init(&mip0, 1);
868+
869+
ITexture* pTexture = nullptr;
870+
m_pDevice->CreateTexture(desc, &init, &pTexture);
871+
ITextureView* ptexView = pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
872+
873+
// store texture view and texture pointers inside imgui and set texture state to ok
874+
tex->SetTexID(reinterpret_cast<ImTextureID>(ptexView));
875+
tex->BackendUserData = reinterpret_cast<void*>(pTexture);
876+
tex->SetStatus(ImTextureStatus_OK);
877+
return;
878+
}
879+
else if (tex->Status == ImTextureStatus_WantUpdates && backend != nullptr)
880+
{
881+
Box dstBox{Uint32(tex->UpdateRect.x), Uint32(tex->UpdateRect.x + tex->UpdateRect.w),
882+
Uint32(tex->UpdateRect.y), Uint32(tex->UpdateRect.y + tex->UpdateRect.h)};
883+
884+
TextureSubResData SubresData;
885+
SubresData.pData = tex->GetPixelsAt(tex->UpdateRect.x, tex->UpdateRect.y);
886+
SubresData.Stride = tex->GetPitch();
887+
888+
pCtx->UpdateTexture(backend, 0, 0, dstBox, SubresData, RESOURCE_STATE_TRANSITION_MODE_VERIFY, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
889+
tex->SetStatus(ImTextureStatus_OK);
890+
return;
891+
}
892+
else if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
893+
{
894+
DestroyTexture(tex);
895+
}
896+
}
897+
898+
void ImGuiDiligentRenderer::DestroyTexture(ImTextureData* tex)
899+
{
900+
if (auto* pTexture = static_cast<ITexture*>(tex->BackendUserData))
901+
{
902+
pTexture->Release();
903+
}
904+
905+
tex->BackendUserData = nullptr;
906+
tex->SetTexID(ImTextureID_Invalid);
907+
tex->SetStatus(ImTextureStatus_Destroyed);
908+
}
909+
872910
void ImGuiDiligentRenderer::RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDrawData)
873911
{
874912
ScopedDebugGroup DebugGroup{pCtx, "ImGui"};
875913

914+
// Handle requested texture creates/updates/destroys -----------------
915+
if (pDrawData->Textures != nullptr)
916+
{
917+
for (ImTextureData* tex : *pDrawData->Textures)
918+
{
919+
if (tex->Status != ImTextureStatus_OK)
920+
{
921+
UpdateTexture(pCtx, tex);
922+
}
923+
}
924+
}
925+
876926
// Avoid rendering when minimized
877-
if (pDrawData->DisplaySize.x <= 0.0f || pDrawData->DisplaySize.y <= 0.0f || pDrawData->CmdListsCount == 0)
927+
if (pDrawData->DisplaySize.x <= 0.0f || pDrawData->DisplaySize.y <= 0.0f || pDrawData->CmdLists.empty())
878928
return;
879929

880930
// Create and grow vertex/index buffers if needed
@@ -916,9 +966,8 @@ void ImGuiDiligentRenderer::RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDr
916966

917967
ImDrawVert* pVtxDst = Vertices;
918968
ImDrawIdx* pIdxDst = Indices;
919-
for (Int32 CmdListID = 0; CmdListID < pDrawData->CmdListsCount; CmdListID++)
969+
for (const ImDrawList* pCmdList : pDrawData->CmdLists)
920970
{
921-
const ImDrawList* pCmdList = pDrawData->CmdLists[CmdListID];
922971
memcpy(pVtxDst, pCmdList->VtxBuffer.Data, pCmdList->VtxBuffer.Size * sizeof(ImDrawVert));
923972
memcpy(pIdxDst, pCmdList->IdxBuffer.Data, pCmdList->IdxBuffer.Size * sizeof(ImDrawIdx));
924973
pVtxDst += pCmdList->VtxBuffer.Size;
@@ -1020,13 +1069,12 @@ void ImGuiDiligentRenderer::RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDr
10201069
Uint32 GlobalVtxOffset = 0;
10211070

10221071
ITextureView* pLastTextureView = nullptr;
1023-
for (Int32 CmdListID = 0; CmdListID < pDrawData->CmdListsCount; CmdListID++)
1072+
for (const ImDrawList* pCmdList : pDrawData->CmdLists)
10241073
{
1025-
const ImDrawList* pCmdList = pDrawData->CmdLists[CmdListID];
1026-
for (Int32 CmdID = 0; CmdID < pCmdList->CmdBuffer.Size; CmdID++)
1074+
for (const ImDrawCmd& Cmd : pCmdList->CmdBuffer)
10271075
{
1028-
const ImDrawCmd* pCmd = &pCmdList->CmdBuffer[CmdID];
1029-
if (pCmd->UserCallback != NULL)
1076+
const ImDrawCmd* pCmd = &Cmd;
1077+
if (pCmd->UserCallback != nullptr)
10301078
{
10311079
// User callback, registered via ImDrawList::AddCallback()
10321080
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
@@ -1067,7 +1115,7 @@ void ImGuiDiligentRenderer::RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDr
10671115
pCtx->SetScissorRects(1, &Scissor, m_RenderSurfaceWidth, m_RenderSurfaceHeight);
10681116

10691117
// Bind texture
1070-
ITextureView* pTextureView = reinterpret_cast<ITextureView*>(pCmd->TextureId);
1118+
ITextureView* pTextureView = reinterpret_cast<ITextureView*>(pCmd->GetTexID());
10711119
VERIFY_EXPR(pTextureView);
10721120
if (pTextureView != pLastTextureView)
10731121
{

Imgui/src/ImGuiImplDiligent.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,4 @@ void ImGuiImplDiligent::CreateDeviceObjects()
9595
m_pRenderer->CreateDeviceObjects();
9696
}
9797

98-
void ImGuiImplDiligent::UpdateFontsTexture()
99-
{
100-
m_pRenderer->CreateFontsTexture();
101-
}
102-
10398
} // namespace Diligent

Imgui/src/ImGuiImplSDL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
#include "Errors.hpp"
3030
#include "RenderDevice.h"
31-
#include "backends/imgui_impl_sdl.h"
31+
#include "backends/imgui_impl_sdl2.h"
3232

3333
namespace Diligent
3434
{

0 commit comments

Comments
 (0)