[openGL] imgui

나우히즈·2024년 10월 7일

Graphics

목록 보기
8/17

서론

imgui 를 활용하면 그래픽스 프로그램의 디버깅을 용이하게 할 수 있다. 기존에는 프로그램을 수정해서 재컴파일 후 실행하여 결과를 확인했지만, imgui를 통해 특정 옵션들을 빠르게 변경해보며 그 변화를 확인할 수 있다.

imgui가 어떤 GUI인지 알아보도록 하자.


GUI in openGL

GUI를 구성하는 방법으로는 아래 두 가지 방식이 존재한다.

  1. GUI 프레임워크를 사용하여 GUI 화면을 구성하고 그 중에서 OpenGL surface를 만들어 원하는 장면을 그린다.

  2. OpenGL 화면 내부에 GUI 콤포넌트를 만들고 이벤트를 처리할 수 있는 라이브러리를 사용한다.

아예 GUI프레임워크를 통해 구성하는 방식과, GUI 컴포넌트를 화면 내부에 작성하는 방식. 여기서 imgui의 경우 2번 방식에 해당한다. GUI 컴포넌트를 만들어내고 그 컴포넌트와 입출력 상호작용을 통해 동작하는 원리인데 화면 내부에 존재하는 요소다보니, 매 렌더링 시마다 GUI를 그려내게 된다.

imgui 특징

  • Immediate Mode GUI : 사용자가 매 렌더마다 상태와 이벤트를 직접 갱신.
  • Rendering Backend 분리 : OpenGL 뿐만 아니라 다양한 Graphics API와 함께 사용 가능.
  • Graphics programming에 필요한 GUI component 지원
  • 의존성이 거의 없어서, 빌드가 간단

이러한 특징은 imgui가 다양한 회사로부터 지원받으며 성장할 수 있는 오픈소스가 될 수 있게 하였다.


사용해보기

1. ImGui::CreateContext();

auto imguiContext = ImGui::CreateContext();
  • ImGui의 전역 상태(UI 관련 데이터, 스타일, 폰트, 테마 등)를 저장하는 새로운 컨텍스트를 생성하는 함수. 이 함수는 ImGui가 작동할 수 있는 기본 환경을 설정한다.
  • ImGui Context는 여러 개의 UI 인스턴스를 동시에 사용할 수 있게 해주는 구조. 여러 창이나 장면(Scene) 간의 상태를 독립적으로 관리할 때 유용함.

2. ImGui::SetCurrentContext(imguiContext);

ImGui::SetCurrentContext(imguiContext);
  • 현재 활성화된 ImGui 컨텍스트를 설정하는 함수. CreateContext로 만든 컨텍스트를 SetCurrentContext로 지정해서 ImGui가 이 컨텍스트를 사용.
  • 만약 하나의 애플리케이션에서 여러 개의 ImGui 컨텍스트를 사용하려면, 그때그때 현재 사용할 컨텍스트를 지정해야함.

3. ImGui_ImplGlfw_InitForOpenGL(window, false);

ImGui_ImplGlfw_InitForOpenGL(window, false);
  • GLFWOpenGL을 사용하여 ImGui를 초기화하는 함수. 이 함수는 GLFW 윈도우 시스템과 ImGui 간의 상호작용을 설정.
  • windowGLFW로 생성한 윈도우 객체를 가리킨다. 이를 통해 ImGui가 해당 윈도우의 입력(마우스, 키보드 등)을 처리할 수 있게 한다.
  • 두 번째 인자인 false는 ImGui의 키보드 및 마우스 입력 콜백을 비활성화하겠다는 의미로, GLFW의 콜백을 직접 관리하겠다는 설정. 필요에 따라 true로 설정.
  • GLFW로 윈도우에 대한 세팅을 완료해야 openGL이 윈도우 타깃을 잡을 수 있으므로, GLFW에 대한 초기화를 먼저 진행하도록 한다.

4. ImGui_ImplOpenGL3_Init();

ImGui_ImplOpenGL3_Init();
  • OpenGL 3.x을 사용하는 ImGui 백엔드를 초기화하는 함수. 이 함수는 ImGui가 OpenGL을 통해 UI를 렌더링할 수 있게 해주는 백엔드 설정을 한다. OpenGL의 셰이더, 버텍스 배열 등과 연결되도록 해주는 과정.

5. ImGui_ImplOpenGL3_CreateFontsTexture();

ImGui_ImplOpenGL3_CreateFontsTexture();
  • ImGui에서 사용되는 폰트를 GPU에 업로드하기 위한 과정.
  • 이 함수는 ImGui가 UI에 사용할 폰트를 OpenGL 텍스처로 변환하고, 이를 GPU에 저장한다. 이렇게 하면 UI에 텍스트를 표시할 때 텍스처 기반으로 빠르게 렌더링.
  • 폰트는 화면에 나오는 텍스트를 위한 중요한 자원이기 때문에 이를 텍스처로 관리하여 효율적인 렌더링을 가능하게 한다.

6. ImGui_ImplOpenGL3_CreateDeviceObjects();

ImGui_ImplOpenGL3_CreateDeviceObjects();
  • ImGui를 위한 OpenGL 객체들(예: 셰이더, 버텍스 배열)을 생성하는 함수
  • 이 함수는 ImGui가 OpenGL의 렌더링 파이프라인을 사용하여 UI를 그릴 수 있게 해주는 기초적인 그래픽 자원들을 생성한다. ImGui가 UI를 화면에 표시하기 위해 필요한 OpenGL 자원(버퍼, 셰이더 프로그램 등)을 준비하는 과정.

소멸은 생성의 역순으로 진행해주도록 한다.

ImGui_ImplOpenGL3_DestroyFontsTexture();
ImGui_ImplOpenGL3_DestroyDeviceObjects();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext(imguiContext);

이후 메인루프에서 아래와 같이 렌더링 될 수 있도록 했다.

	while (!glfwWindowShouldClose(window)) {
    glfwPollEvents();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();
 
    context->ProcessInput(window);
    context->Render();
 
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    glfwSwapBuffers(window);
}

매 렌더링 시, openGL의 이미지 렌더링과 함께 GUI의 렌더링도 진행되게 된다.
우선 glfwPollEvents 를 통해 발생한 키보드/마우스의 입출력을 받는다. 그리고 그에 대한 정보를 ImGui_ImplGlfw_NewFrame()를 통해 ImGui에도 기록한다.

새로운 GUI 프레임을 만들고 이미지가 렌더링된 후 ImGui::Render를 통해 렌더링할 값들을 세팅하여 Draw하게 된다.


이 외

다양한 기능에 대해서는 imgui.h를 참고.
별도의 튜토리얼이나 메뉴얼은 없다고 알고 있어서, 헤더파일에 나와있는 코멘트를 보면서 필요한 기능들을 찾아 사용하면 된다.

imgui는 openGL 외에도 다양한 그래픽스 API에 함께 사용할 수 있다. 따라서 한 번 익혀두면 두고두고 잘 쓸 것 같으니 여러가지 장난을 쳐보면서 배워놔야겠다!

0개의 댓글