[DirectX11] 14. ImGUI 설치하기



Reference


ocornut/imgui: Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies 에서 설치 및 시작 가이드를 볼 수 있다.



설치하기


Pasted image 20250101114318.png


Pasted image 20250101114448.png

압축을 푼 후 루트 경로에 있는 필수 파일들을 내 프로젝트에 복사하여 포함한다.

Pasted image 20250101114539.png

내가 사용할 그래픽스 API에 맞는 Implement 파일들을 추가로 복사하여 포함한다. 멀티플랫폼 환경으로 개발한다면 플랫폼별로 모두 복사하여 #ifdef등으로 분기처리가 필요하다.
다운로드할 원본 폴더는 backends하위에 있다.

Pasted image 20250101114742.png

일단 나는 Dx11, Dx12를 사용하므로 해당 파일들만 포함해주었다.

Pasted image 20250101115020.png

윈도우즈 환경에서 개발하므로 imgui_impl_wind32.h, imgui_impl_win32.cpp파일도 추가 복사 포함해준다.



사용하기



C++
IMGUI_CHECKVERSION();  
  
ImGui::CreateContext();  
  
ImGuiIO& io = ImGui::GetIO();  
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  
  
ImGui::StyleColorsDark();  
  
ImGui_ImplWin32_Init( hWnd );  
ImGui_ImplDX11_Init( GD11.GetDevice(), GD11.GetDeviceContext() );

프로그램 초기화 부분에 추가해주어야 할 코드들이다. ImGUI역시 그래픽스 API를 이용하여 렌더링하므로 그래픽스 API관련 인스턴스들이 초기화 및 생성된 이후에 추가되어야 한다.




ImGUI를 렌더링 하는 코드는 다음과 같다.

C++
ImGui_ImplDX11_NewFrame();  
ImGui_ImplWin32_NewFrame();  
  
ImGui::NewFrame();  

/// 이곳부터 내가 그리고 싶은 GUI들을 구성한다.
{
    ImGui::Button( "Test Button" ); 
}
  
ImGui::Render();  
ImGui_ImplDX11_RenderDrawData( ImGui::GetDrawData() );



윈도우즈 애플리케이션 환경이기 때문에 ImGUI에서도 윈도우 메시지 관련 처리가 필요하다. 따라서 WndProc에서도 추가의 별도 처리가 필요하다.

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

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    /// ...
    if ( ImGui_ImplWin32_WndProcHandler( hWnd, message, wParam, lParam ) )
        return true;
    /// ...
}

ImGui_ImplWin32_WndProcHandler함수로 메시지 처리를 할 수 있도록 해주어야 한다. 이 함수는 cpp에 구현되어 있으므로 extern정의를 해주어야 함수 참조가 정상적으로 가능하다.



활용하기


ImGUI의 렌더링 역시 백 버퍼에 드로우 하는것이므로 ImGui_ImplDX11_RenderDrawData() 함수의 위치에 신경을 써야 한다. 다음 위치를 지켜야 한다.

C++
/// GD11Renderer.ClearRenderTarget()
{
    float color[ 4 ] = { 0.0f, 0.4f, 0.7f, 1.0f };  
    GD11.GetDeviceContext()->ClearRenderTargetView( RenderTargetView->GetObjectPtr(), color );
}

/// ImGUI Code
{
    ImGui_ImplDX11_RenderDrawData( ImGui::GetDrawData() );
}

/// GD11Renderer.Present()
{
    GD11.GetSwapChain()->Present( 0, 0 );
}

백 버퍼 초기화 이후Present 호출 이전에 렌더링 코드가 있어야 한다. 이 함수를 호출하면 구성된 ImGUI 요소들을 백 버퍼에 Write하게 된다. 따라서 인게임 구성 요소간의 순서에도 결과물에 영향을 끼치게 된다.

C++
/// GD11Renderer.Draw()
{
    GD11.GetDeviceContext()->Draw( VertexBuffer.lock()->GetCount(), 0 );
}

ImGui_ImplDX11_RenderDrawData( ImGui::GetDrawData() );

이렇게 인게임 요소 Draw이후에 ImGui_ImplDX11_RenderDrawData를 호출하면 인게임 요소위에 ImGUI가 렌더링되어 인게임 요소가 가려진다.

Pasted image 20250101121556.png

C++
ImGui_ImplDX11_RenderDrawData( ImGui::GetDrawData() );

/// GD11Renderer.Draw()
{
    GD11.GetDeviceContext()->Draw( VertexBuffer.lock()->GetCount(), 0 );
}

반대로 ImGui_ImplDX11_RenderDrawData를 먼저 호출하게 되면 ImGUI구성 요소들이 백 버퍼에 먼저 쓰이게 되므로 인게임 요소가 ImGUI를 가리게 된다.

Pasted image 20250101121733.png


이것을 잘 기억해두면 나중에 인게임 요소와 GUI간의 Rendering Order를 적용할 수 있을 것이다.

yunei0313/CRY at Add-ImGUI에서 코드를 확인할 수 있다.



이전글 : [DirectX11] 13. 라이트( Directional Light ) – Constant Buffer 활용하기.
다음글 : [DirectX11] 15. 카메라( View & Projection ) – Constant Buffer 활용하기 2편.



Leave a Comment