Browse Source

Examples: DX12: Empty skeleton toward implementing the multi-viewport api for DirectX12. (WIP/test API) (#1542, #301)

omar 7 years ago
parent
commit
baef79415b
2 changed files with 149 additions and 2 deletions
  1. 6 1
      examples/directx12_example/main.cpp
  2. 143 1
      examples/imgui_impl_dx12.cpp

+ 6 - 1
examples/directx12_example/main.cpp

@@ -93,7 +93,7 @@ void ResizeSwapChain(HWND hWnd, int width, int height)
     sd.Width = width;
     sd.Height = height;
 
-    IDXGIFactory4* dxgiFactory = nullptr;
+    IDXGIFactory4* dxgiFactory = NULL;
     g_pSwapChain->GetParent(IID_PPV_ARGS(&dxgiFactory));
 
     g_pSwapChain->Release();
@@ -289,7 +289,9 @@ int main(int, char**)
     // Setup ImGui binding
     ImGui::CreateContext();
     ImGuiIO& io = ImGui::GetIO(); (void)io;
+    io.ConfigFlags |= ImGuiConfigFlags_MultiViewports;
     //io.NavFlags |= ImGuiNavFlags_EnableKeyboard;  // Enable Keyboard Controls
+
     ImGui_ImplWin32_Init(hwnd);
     ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT, DXGI_FORMAT_R8G8B8A8_UNORM,
                         g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart());
@@ -399,6 +401,9 @@ int main(int, char**)
 
         g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);
 
+        ImGui::UpdatePlatformWindows();
+        ImGui::RenderPlatformWindows();
+
         g_pSwapChain->Present(1, 0); // Present with vsync
         //g_pSwapChain->Present(0, 0); // Present without vsync
 

+ 143 - 1
examples/imgui_impl_dx12.cpp

@@ -18,6 +18,7 @@
 
 // DirectX
 #include <d3d12.h>
+#include <dxgi1_4.h>
 #include <d3dcompiler.h>
 
 // DirectX data
@@ -48,6 +49,10 @@ struct VERTEX_CONSTANT_BUFFER
     float        mvp[4][4];
 };
 
+// Forward Declarations
+static void ImGui_ImplDX12_InitPlatformInterface();
+static void ImGui_ImplDX12_ShutdownPlatformInterface();
+
 // Render function
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
 void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data)
@@ -587,7 +592,7 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
     g_RTVFormat = rtv_format;
     g_hFontSrvCpuDescHandle = font_srv_cpu_desc_handle;
     g_hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
-    g_pFrameResources = new FrameResources [num_frames_in_flight];
+    g_pFrameResources = new FrameResources[num_frames_in_flight];
     g_numFramesInFlight = num_frames_in_flight;
     g_frameIndex = UINT_MAX;
 
@@ -599,11 +604,16 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
         g_pFrameResources[i].IndexBufferSize = 10000;
     }
 
+    ImGuiIO& io = ImGui::GetIO();
+    if (io.ConfigFlags & ImGuiConfigFlags_MultiViewports)
+        ImGui_ImplDX12_InitPlatformInterface();
+
     return true;
 }
 
 void ImGui_ImplDX12_Shutdown()
 {
+    ImGui_ImplDX12_ShutdownPlatformInterface();
     ImGui_ImplDX12_InvalidateDeviceObjects();
     delete[] g_pFrameResources;
     g_pd3dDevice = NULL;
@@ -622,3 +632,135 @@ void ImGui_ImplDX12_NewFrame(ID3D12GraphicsCommandList* command_list)
 
     g_pd3dCommandList = command_list;
 }
+
+// --------------------------------------------------------------------------------------------------------
+// Platform Windows
+// --------------------------------------------------------------------------------------------------------
+
+#include "imgui_internal.h"     // ImGuiViewport
+
+struct ImGuiPlatformDataDx12
+{
+    IDXGISwapChain3*            SwapChain;
+
+    ImGuiPlatformDataDx12() { SwapChain = NULL; }
+    ~ImGuiPlatformDataDx12() { IM_ASSERT(SwapChain == NULL); }
+};
+
+static void ImGui_ImplDX12_CreateViewport(ImGuiViewport* viewport)
+{
+    ImGuiPlatformDataDx12* data = IM_NEW(ImGuiPlatformDataDx12)();
+    viewport->RendererUserData = data;
+    IM_ASSERT(0);
+
+    /*
+    // FIXME-PLATFORM
+    HWND hwnd = (HWND)viewport->PlatformHandle;
+    IM_ASSERT(hwnd != 0);
+
+    // Create swap chain
+    DXGI_SWAP_CHAIN_DESC sd;
+    ZeroMemory(&sd, sizeof(sd));
+    sd.BufferDesc.Width = (UINT)viewport->Size.x;
+    sd.BufferDesc.Height = (UINT)viewport->Size.y;
+    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+    sd.SampleDesc.Count = 1;
+    sd.SampleDesc.Quality = 0;
+    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+    sd.BufferCount = 1;
+    sd.OutputWindow = hwnd;
+    sd.Windowed = TRUE;
+    sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+    sd.Flags = 0;
+
+    IM_ASSERT(data->SwapChain == NULL && data->RTView == NULL);
+    g_pFactory->CreateSwapChain(g_pd3dDevice, &sd, &data->SwapChain);
+
+    // Create the render target
+    if (data->SwapChain)
+    {
+        ID3D11Texture2D* pBackBuffer;
+        data->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
+        g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &data->RTView);
+        pBackBuffer->Release();
+    }
+    */
+}
+
+static void ImGui_ImplDX12_DestroyViewport(ImGuiViewport* viewport)
+{
+    if (ImGuiPlatformDataDx12* data = (ImGuiPlatformDataDx12*)viewport->RendererUserData)
+    {
+        IM_ASSERT(0);
+        /*
+        if (data->SwapChain)
+            data->SwapChain->Release();
+        data->SwapChain = NULL;
+        if (data->RTView)
+            data->RTView->Release();
+        data->RTView = NULL;
+        IM_DELETE(data);
+        */
+    }
+    viewport->RendererUserData = NULL;
+}
+
+static void ImGui_ImplDX12_ResizeViewport(ImGuiViewport* viewport, int w, int h)
+{
+    ImGuiPlatformDataDx12* data = (ImGuiPlatformDataDx12*)viewport->RendererUserData;
+    IM_ASSERT(0);
+    /*
+    if (data->RTView)
+    {
+        data->RTView->Release();
+        data->RTView = NULL;
+    }
+    if (data->SwapChain)
+    {
+        ID3D11Texture2D* pBackBuffer = NULL;
+        data->SwapChain->ResizeBuffers(0, w, h, DXGI_FORMAT_UNKNOWN, 0);
+        data->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
+        g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &data->RTView);
+        pBackBuffer->Release();
+    }
+    */
+}
+
+static void ImGui_ImplDX12_RenderViewport(ImGuiViewport* viewport)
+{
+    ImGuiPlatformDataDx12* data = (ImGuiPlatformDataDx12*)viewport->RendererUserData;
+    IM_ASSERT(0);
+    /*
+    ImVec4 clear_color = ImGui::GetStyle().Colors[ImGuiCol_WindowBg]; // FIXME-PLATFORM
+    clear_color.w = 1.0f;
+    g_pd3dDeviceContext->OMSetRenderTargets(1, &data->RTView, NULL);
+    g_pd3dDeviceContext->ClearRenderTargetView(data->RTView, (float*)&clear_color);
+    */
+    ImGui_ImplDX12_RenderDrawData(&viewport->DrawData);
+}
+
+static void ImGui_ImplDX12_SwapBuffers(ImGuiViewport* viewport)
+{
+    ImGuiPlatformDataDx12* data = (ImGuiPlatformDataDx12*)viewport->RendererUserData;
+    IM_ASSERT(0);
+    /*
+    data->SwapChain->Present(0, 0); // Present without vsync
+    */
+}
+
+void ImGui_ImplDX12_InitPlatformInterface()
+{
+    ImGuiIO& io = ImGui::GetIO();
+    io.RendererInterface.CreateViewport = ImGui_ImplDX12_CreateViewport;
+    io.RendererInterface.DestroyViewport = ImGui_ImplDX12_DestroyViewport;
+    io.RendererInterface.ResizeViewport = ImGui_ImplDX12_ResizeViewport;
+    io.RendererInterface.RenderViewport = ImGui_ImplDX12_RenderViewport;
+    io.RendererInterface.SwapBuffers = ImGui_ImplDX12_SwapBuffers;
+}
+
+void ImGui_ImplDX12_ShutdownPlatformInterface()
+{
+    ImGuiIO& io = ImGui::GetIO();
+    memset(&io.RendererInterface, 0, sizeof(io.RendererInterface));
+}
+