Skip to content

Commit a14f89d

Browse files
committed
use im GUI docking for dx11
whoops... missed this part...
1 parent 8801620 commit a14f89d

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed

DX12P/Renderer/DX11H.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ const std::string fNameEnd = "BMP";
2828
//using namespace Gdiplus;
2929
//#pragma comment (lib,"Gdiplus.lib")
3030

31+
//TODO: use unordered map
32+
3133
using namespace Microsoft::WRL;
3234

3335

DX12P/imGUI/imgui_impl_dx11.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
// Implemented features:
55
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
6+
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
67
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
78

89
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
@@ -12,6 +13,7 @@
1213

1314
// CHANGELOG
1415
// (minor and older changes stripped away, please see git history for details)
16+
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
1517
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
1618
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
1719
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
@@ -75,6 +77,10 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
7577
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
7678
}
7779

80+
// Forward Declarations
81+
static void ImGui_ImplDX11_InitPlatformInterface();
82+
static void ImGui_ImplDX11_ShutdownPlatformInterface();
83+
7884
// Functions
7985
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
8086
{
@@ -547,6 +553,7 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
547553
io.BackendRendererUserData = (void*)bd;
548554
io.BackendRendererName = "imgui_impl_dx11";
549555
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
556+
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
550557

551558
// Get factory from device
552559
IDXGIDevice* pDXGIDevice = NULL;
@@ -566,6 +573,9 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
566573
bd->pd3dDevice->AddRef();
567574
bd->pd3dDeviceContext->AddRef();
568575

576+
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
577+
ImGui_ImplDX11_InitPlatformInterface();
578+
569579
return true;
570580
}
571581

@@ -575,6 +585,7 @@ void ImGui_ImplDX11_Shutdown()
575585
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
576586
ImGuiIO& io = ImGui::GetIO();
577587

588+
ImGui_ImplDX11_ShutdownPlatformInterface();
578589
ImGui_ImplDX11_InvalidateDeviceObjects();
579590
if (bd->pFactory) { bd->pFactory->Release(); }
580591
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
@@ -592,3 +603,126 @@ void ImGui_ImplDX11_NewFrame()
592603
if (!bd->pFontSampler)
593604
ImGui_ImplDX11_CreateDeviceObjects();
594605
}
606+
607+
//--------------------------------------------------------------------------------------------------------
608+
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
609+
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
610+
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
611+
//--------------------------------------------------------------------------------------------------------
612+
613+
// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
614+
struct ImGui_ImplDX11_ViewportData
615+
{
616+
IDXGISwapChain* SwapChain;
617+
ID3D11RenderTargetView* RTView;
618+
619+
ImGui_ImplDX11_ViewportData() { SwapChain = NULL; RTView = NULL; }
620+
~ImGui_ImplDX11_ViewportData() { IM_ASSERT(SwapChain == NULL && RTView == NULL); }
621+
};
622+
623+
static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport)
624+
{
625+
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
626+
ImGui_ImplDX11_ViewportData* vd = IM_NEW(ImGui_ImplDX11_ViewportData)();
627+
viewport->RendererUserData = vd;
628+
629+
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
630+
// Some backend will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND.
631+
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
632+
IM_ASSERT(hwnd != 0);
633+
634+
// Create swap chain
635+
DXGI_SWAP_CHAIN_DESC sd;
636+
ZeroMemory(&sd, sizeof(sd));
637+
sd.BufferDesc.Width = (UINT)viewport->Size.x;
638+
sd.BufferDesc.Height = (UINT)viewport->Size.y;
639+
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
640+
sd.SampleDesc.Count = 1;
641+
sd.SampleDesc.Quality = 0;
642+
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
643+
sd.BufferCount = 1;
644+
sd.OutputWindow = hwnd;
645+
sd.Windowed = TRUE;
646+
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
647+
sd.Flags = 0;
648+
649+
IM_ASSERT(vd->SwapChain == NULL && vd->RTView == NULL);
650+
bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
651+
652+
// Create the render target
653+
if (vd->SwapChain)
654+
{
655+
ID3D11Texture2D* pBackBuffer;
656+
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
657+
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView);
658+
pBackBuffer->Release();
659+
}
660+
}
661+
662+
static void ImGui_ImplDX11_DestroyWindow(ImGuiViewport* viewport)
663+
{
664+
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
665+
if (ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData)
666+
{
667+
if (vd->SwapChain)
668+
vd->SwapChain->Release();
669+
vd->SwapChain = NULL;
670+
if (vd->RTView)
671+
vd->RTView->Release();
672+
vd->RTView = NULL;
673+
IM_DELETE(vd);
674+
}
675+
viewport->RendererUserData = NULL;
676+
}
677+
678+
static void ImGui_ImplDX11_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
679+
{
680+
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
681+
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
682+
if (vd->RTView)
683+
{
684+
vd->RTView->Release();
685+
vd->RTView = NULL;
686+
}
687+
if (vd->SwapChain)
688+
{
689+
ID3D11Texture2D* pBackBuffer = NULL;
690+
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
691+
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
692+
if (pBackBuffer == NULL) { fprintf(stderr, "ImGui_ImplDX11_SetWindowSize() failed creating buffers.\n"); return; }
693+
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView);
694+
pBackBuffer->Release();
695+
}
696+
}
697+
698+
static void ImGui_ImplDX11_RenderWindow(ImGuiViewport* viewport, void*)
699+
{
700+
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
701+
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
702+
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
703+
bd->pd3dDeviceContext->OMSetRenderTargets(1, &vd->RTView, NULL);
704+
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
705+
bd->pd3dDeviceContext->ClearRenderTargetView(vd->RTView, (float*)&clear_color);
706+
ImGui_ImplDX11_RenderDrawData(viewport->DrawData);
707+
}
708+
709+
static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
710+
{
711+
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
712+
vd->SwapChain->Present(0, 0); // Present without vsync
713+
}
714+
715+
static void ImGui_ImplDX11_InitPlatformInterface()
716+
{
717+
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
718+
platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow;
719+
platform_io.Renderer_DestroyWindow = ImGui_ImplDX11_DestroyWindow;
720+
platform_io.Renderer_SetWindowSize = ImGui_ImplDX11_SetWindowSize;
721+
platform_io.Renderer_RenderWindow = ImGui_ImplDX11_RenderWindow;
722+
platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers;
723+
}
724+
725+
static void ImGui_ImplDX11_ShutdownPlatformInterface()
726+
{
727+
ImGui::DestroyPlatformWindows();
728+
}

DX12P/imGUI/imgui_impl_dx11.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
// Implemented features:
55
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
6+
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
67
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
78

89
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.

0 commit comments

Comments
 (0)