@@ -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
534535void 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
759734float4 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+
872910void 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 {
0 commit comments