🌲

DirectX12でImGuiを使用する

2023/03/21に公開

はじめに

DirectX12にImGuiを導入する手順を記録しておきます。

環境

VisualStudio 2019 16.11.24
ImGui 1.89.4

ファイルの配置

https://github.com/ocornut/imgui

gitからファイルをClone or ダウンロードして、
・imguiのルートフォルダにある.hと.cppファイル
・imgui\backends以下にあるimgui_impl_dx12/imgui_impl_win32の.hと.cpp
をプロジェクトファイルに配置します。

初期化/更新/終了

https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx12/main.cpp
上記の手順を参考にしてください。
以下補足説明をします。

初期化処理

// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls

// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsLight();

// Setup Platform/Renderer backends
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT,
        DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap,
        g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(),
        g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart());

上記処理を呼び出してください。
ImGui styleはウィンドウのカラースタイルです。お好みで変更してください。
補足説明としてImGui_ImplWin32_Initにはウィンドウハンドルを、ImGui_ImplDX12_Initには下記の引数を与えます。

  • DirectX12デバイスのポインタ
  • フレームバッファの数
  • レンダーターゲットビューのフォーマット
  • シェーダリソースビューのヒープ
  • フォントテクスチャのCPUディスクリプタハンドル
  • フォントテクスチャのGPUディスクリプタハンドル

更新処理

// Start the Dear ImGui frame
ImGui_ImplDX12_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
	
// 任意のImGui関数の呼び出し
// 下記では"Hello, world!"というタイトルのウィンドウを表示する
ImGui::Begin("Hello, world!");
ImGui::End();
	
ImGui::Render();

規定の関数を呼び出し、その間に任意のウィンドウ処理を記述します。
上記の処理だけでは描画はできません。コマンドリストにImGuiの描画命令を加えるため、下記の処理をプロジェクトに応じた適切なタイミングで加えます。

ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), g_pd3dCommandList);

上記までの手順を踏むことでウィンドウの描画はできますが、ウィンドウの拡縮等々ができません。以下のImGui_ImplWin32_WndProcHandler処理をウィンドウプロシージャに追加します。

extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
        return true;
	
	//以下省略
}

終了処理

// Cleanup
ImGui_ImplDX12_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();

特記することはありません。メモリの開放を行います。

描画結果


ImGuiを描画することができました。

Discussion