Try using imgui in Direct3D12
Writing a Direct3D application requires debug drawing. Debug drawing is, for example, drawing the frame rate and various settings on the screen. It is not used in the final product, so we want to make it so that it can be separated and compiled.
I have tried to incorporate this with the help of this website.
https://zenn.dev/norainu/articles/10856bfe120aa2
Put them together in a separate class so that they can be separated.
class ImGuiUtil {
public:
ImGuiUtil() {
}
virtual ~ImGuiUtil() {
}
// initialization
void Initialize(HWND hWnd, ID3D12Device *pDevice)
{
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
ImGui::StyleColorsLight();
D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
srvHeapDesc.NumDescriptors = 1;
srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
pDevice->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&m_srvHeap));
ImGui_ImplWin32_Init(hWnd);
ImGui_ImplDX12_Init(pDevice, FRAME_BUFFER_COUNT,
DXGI_FORMAT_R8G8B8A8_UNORM, m_srvHeap.Get(),
m_srvHeap->GetCPUDescriptorHandleForHeapStart(),
m_srvHeap->GetGPUDescriptorHandleForHeapStart());
}
// end processing
void Finalize()
{
ImGui_ImplDX12_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
}
// Call at the beginning of the frame
void NewFrame()
{
ImGui_ImplDX12_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
}
// Call at the end of the drawing
void Render(ID3D12GraphicsCommandList *pCommandList)
{
ImGui::Render();
ID3D12DescriptorHeap* descriptorHeaps[] = { m_srvHeap.Get() };
pCommandList->SetDescriptorHeaps(_countof(descriptorHeaps), descriptorHeaps);
ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), pCommandList);
}
private:
ComPtr<ID3D12DescriptorHeap> m_srvHeap;
};
Write a Direct3D12 application (3)
Direct3D12 takes the form of buffering drawing commands in a command list and executing them together.
A simple description of the process to be executed every frame is as follows.
{
// Start of command list
commandAllocator->Reset();
commandList->Reset(commandAllocator.Get(), pipelineState.Get());
// Execute various drawing commands to create a command list
...
// Execute buffered command list
commandList->Close();
ID3D12CommandList* commandLists[] = { commandList.Get() };
commandQueue->ExecuteCommandLists(_countof(commandLists), commandLists);
// View swap chain
swapChain->Present(1, 0);
}
Write a Direct3D12 application (2)
First, before explaining the Direct3D12 program, we will write a program to display only a Window.
Basically, all you have to do is create a Window with CreateWindow and process messages in the main loop.
Incidentally, Window applications are message-driven. For example, operations such as moving, resizing, or closing a Window are stored in a queue in the form of messages.
The program processes the messages in the main loop. Therefore, when there are no messages, the program is in the same state as if it were in Sleep.
This is not suitable for programs such as game programs that process animation and other operations in real time, frame by frame.
Write a Direct3D12 application (1)
First, to build a Direct3D12 app, you need to include the Direct3D12 header files and link the library files.
In the past, you could download something called the DirectX SDK and write the include and link settings in VisualStudio,
Now it seems that the DirectX SDK is gone and is included in the Windows SDK.
So where is the Windows SDK? You can run an app called Visual Studio Installer, select it from the VisualStudio components, and install it.
There are Windows 10 SDK and Windows 11 SDK, multiple versions, and you may not know which one to choose.
If you are just building your own application, you only need to install the latest version. If you are building someone else’s program, it is safer to include the older version.
«
2/2