ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [51] - imgui
    Graphics 2021. 8. 28. 23:23

     (ocornut/imgui: Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies (github.com))

     Imgui이라고 하며 GUI[Graphical User Interface]입니다. IM은 Immediate Mode의 약자이며 GUI는 흔히 쓰는 그대로 Graphical User Interface입니다. 대부분 C++로 작성되었으며 Platform independent입니다. 따라서 OpenGL이든 D3D이든 Vulkan이든 적당히 버무려서 사용할 수 있습니다. IMGUI의 Core을 떼어다가 적당히 손을 보면 된다는 뜻입니다. 게다가 이미 만들어져 있는 특정 플랫폼을 위한 Adapter들도 상당히 많이 존재하기 때문에 편리하게 쓸 수 있을 것입니다. 골자는, 그래픽 인터페이스를 직접 구현하는 번거로운 일을 하지 않아도 된다는 뜻입니다. 물론, GUI을 직접 구현하는 것도 도움이 될 것입니다. 하지만 Graphics Pipeline을 이해하는 것과 GUI을 구성하는 것은 대체로 별개의 논의라 생각하기 때문에 IMGUI을 끌어다가 쓰도록 합니다. 그런데 외부 라이브러리를 끌어다 쓰는 게 참 험난합니다.

    figure 0. 많은 파일들을 확인할 수 있습니다
    figure 1a

    많은 것들이 추가되었습니다. 이를 분류해보면 Imgui의 Core에 해당하는 것들과 플랫폼 Specific한 implementation files 로 나눌 수 있습니다. Implementation files은 impl이라는 깃발을 사용했으며 이 파일들이 바로 현재 제가 사용하는 Platform을 위한 Adapter라고 할 수 있습니다. 파일 명을 잘 보면 dx11과 win32이라는 suffix를 볼 수 있습니다. 그런데 이들을 곧장 받아서 Solution에 묶어버린다고 쓸 수 있는 것은 아닙니다. 물론 그럴 수 있는 것들도 존재하지만 약간의 조정을 필수입니다.

    figure 1b-1
    figure 1b-2

    figure 1b-1과 1b-2는 각각 IMGUI에서 제공된 코드와 조정을 가한 코드입니다. 이처럼 미리 짜인 라이브러리를 사용하기 위해서는 자신이 사용하는 환경을 이해하지 않으면 아무것도 할 수가 없습니다. 이런 제반 사항은 Chili Planet을 참조하면 알 수가 있기 때문에 기록할 필요는 없습니다. 그런데 제 경우엔 Chili가 제시한 가이드라인에 따라서 ImGui을 쓸 수가 없었기 때문에 직접 하나하나 Document을 읽으며 구현할 수밖에 없었습니다.

    figure 2a

    찾아보니 가이드 라인이 제시되어 있기는 합니다.  그리고 그렇게 어렵지 않습니다. 구조를 고려했을 때, App class가 초기화 되면서 Window의 Register을 비롯한 초기화 작업들이 실시되기 때문에 App에 ImGui을 관리할 통합된 인스턴스나 핸들이 있으면 좋을 것입니다.

    figure 2b

    이렇게 하나의 Manager을 만들어서 통합된 관리를 수행할 수 있도록 합니다. App class에 이에 대한 Instance을 소환하면 App이 초기화 됨과 동시에 ImGui도 함께 초기화를 시킬 것입니다. ImGui의 초기화에 있어서 가장 먼저 수행되어야 할 것은 무엇인지 ImGui에 관련된 Document을 읽어보도록 합니다. (An introduction to the Dear ImGui library (conan.io))

    figure 2c

    해당 글은 glfw을 기준으로 작성된 것 같지만 상관 없습니다. 필수적인 요소가 Version checking과 ImGui의 Context의 생성이었습니다. 따라서 Figure 2c처럼 ImGui Manager의 인스턴스를 App에 등록함으로써 프로그램이 실행됨과 동시에 ImGui가 Init할 수 있도록 구성합니다. 따라서 해당 절차를 Application init이라고 정리할 수 있습니다. 그런데 ImGui의 공식 문서 중 사용 예제를 살펴보면 ImGuiIO& io = ImGui::GetIO();와 같은 절차가 CreateContext() 이전에 수행이 되고 있습니다. 하지만 제 경우엔 해당 코드를 삽입하면 오류를 일으키기 때문에 빼버렸습니다.

    figure 2c-1

    그래서 왜 오류를 일으키는지 한 번 코드를 뒤져보았습니다.

    figure 2c-2
    figure 2c-3
    figure 2c-4

    이건 사용하기 위해서는 몇 가지 세팅을 거쳐야 합니다. 즉, 이 함수는 호출이 되지 않으면 지정된 기본 값이 사용되지만 코드 상에 호출이 되면 반드시 구성해야 할 것이 있었습니다. 복잡하니까 없애버렸고 기본 값으로도 잘 돌아가긴 합니다.

    figure 2c-5

    이런 구조체로 선언이 되어 있습니다.

    figure 2c-6

    사실 아직 왜 이러는지 알아낸 것은 없습니다. 에러 메시지의 SetCurrentContext()는 parameter로 ImGui의 Context을 요구하는데 이 값은 결코 NULL일 수 없습니다. 만약 NULL이라면 기본적으로 ImGui::CreateContext()가 current context pointer을 자동적으로 설정한다고 합니다. 뭔 문제인지 나중에 알아봅시다. 아무튼 해당 코드는 작성해서는 안됩니다.

    figure 3c

    Init을 끝냈으면 ImGui의 GUI을 사용하기 위한 작업을 해야 합니다. Graphics에 매 Frame을 업데이트 하는 함수에 꽂아주도록 합니다. 이후로는 빛과 몇 가지 그래픽 이론을 정리하고 다시 공부하는 것이 좋을 것 같습니다.

    'Graphics' 카테고리의 다른 글

    [53] - Lighting(Illumination) - 2  (0) 2021.09.15
    [52] - Lighting(Illumination)  (0) 2021.09.13
    [50] - Texture - 2  (0) 2021.08.26
    [49] - Texture - 1  (0) 2021.08.17
    [48] - Rasterization  (0) 2021.08.13
Designed by Tistory.