ImGui 예제 분석

헤더 파일 영역

#include <GLFW/glfw3.h>Code language: plaintext (plaintext)

GLFW 창 라이브러리 헤더를 불러옵니다. 창 생성, 마우스/키보드 입력 처리, OpenGL 컨텍스트 관리, 창 메시지 루프를 담당합니다.

GLFW는 창 생성 및 관리 전용 C언어 라이브러리로, ImGui에 종속되지 않은 독립 모듈이지만 ImGui 구동에 필수라서 포함해야 합니다. 지난 강의에서 프로젝트 폴더에 다운로드하고 프로젝트 통합 설정까지 완료했을 겁니다.

#include "imgui.h"Code language: plaintext (plaintext)

ImGui 핵심 헤더 파일로 모든 UI 컨트롤, 컨텍스트, 스타일, 기본 렌더링 API 등이 정의되어 있습니다.

#include "backends/imgui_impl_glfw.h"Code language: plaintext (plaintext)

ImGui와 GLFW를 연결하는 브릿지로, GLFW에서 얻은 창 정보, 마우스, 키보드, 창 크기 데이터를 ImGui로 전달합니다.

#include "backends/imgui_impl_opengl3.h"Code language: plaintext (plaintext)

ImGui OpenGL3 렌더링 백엔드 어댑터 계층. OpenGL 셰이더, 정점 버퍼를 생성하고 ImGui UI 그래픽 데이터를 GPU에 전달해 렌더링합니다.

#include <cstdio>

C++ 표준 C 입출력 라이브러리로 printf로 오류 로그를 출력할 때 사용합니다.


int main()

프로그램 진입점으로 별도 설명은 생략하겠습니다.

GLFW 초기화

    // Initialize GLFW
    if (!glfwInit())
    {
        printf("GLFW initialization failed\n");
        return -1;
    }

glfwInit():그래픽 카드, 창 드라이버, 입력 장치 등 GLFW 전역 리소스를 초기화합니다.

초기화에 실패하면 오류 메시지를 출력하고 -1을 반환해 프로그램을 비정상 종료하며 운영체제가 해당 종료 코드를 감지합니다.

OpenGL 버전 설정

    // OpenGL 3.3
    const char* glsl_version = "#version 330";

GLSL 셰이더 버전 문자열을 선언하며 OpenGL 3.3은 GLSL 330 버전과 호환됩니다.

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);

OpenGL 메이저 버전을 3으로 설정

glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

OpenGL 마이너 버전을 3으로 설정

 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

코어 프로필(Core Profile) 모드 사용

창 생성

    // Create window
    GLFWwindow* window = glfwCreateWindow(1000, 600, "ImGui Minimal Demo (VS2022)", nullptr, nullptr);

창 크기는 가로1000 × 세로600이고 제목은「ImGui Minimal Demo (VS2022)」입니다. 네 번째 인자 nullptr은 기본 창 모드, 다섯 번째는 OpenGL 컨텍스트 공유 대상 창으로 nullptr을 넣으면 공유하지 않습니다.

반환값은 창 핸들 포인터 GLFWwindow* 입니다.

 if (!window)
    {
        glfwTerminate();
        return -1;
    }

위 창 생성에 실패할 경우 window 포인터는 nullptr이 됩니다.

glfwTerminate()는 GLFW가 할당한 모든 리소스를 소멸시킵니다.

그 뒤 -1을 반환해 운영체제에 프로그램 오류 종료를 알립니다.

glfwMakeContextCurrent(window);

현재 창을 OpenGL 렌더링 컨텍스트로 바인딩하며 이후 모든 OpenGL 그리기 명령은 해당 창에 적용됩니다.

glfwSwapInterval(1);

수직 동기화 활성화. 매개변수 1은 화면 주사율에 프레임을 동기화해 화면 찢김 현상을 방지하고, 0은 수직 동기화를 끄고 프레임 제한을 없앱니다.

이 설정은 매우 중요한데 활성화하지 않으면 GLFW 렌더링과 모니터 갱신 타이밍이 어긋나 화면이 깨지는 현상이 발생합니다.

ImGui 전역 초기화

IMGUI_CHECKVERSION(); // 헤더와 백엔드 버전 일치 검사, 버전 불일치 시 단언 오류 발생
ImGui::CreateContext(); // ImGui 전역 컨텍스트 생성, UI 모든 실행 상태 저장
ImGuiIO& io = ImGui::GetIO(); // IO 설정 객체 획득, 입력·폰트·전역 스위치 관리
ImGui::StyleColorsDark(); // 공식 어두운 테마 UI 색상 적용

GLFW+OpenGL 백엔드 연결

ImGui_ImplGlfw_InitForOpenGL(window, true);

두 번째 매개변수를 true로 설정하면 ImGui가 마우스, 키보드 모든 입력 이벤트를 독점 처리하며 입력이 게임 하위 레이어로 통과되지 않게 차단합니다.

 ImGui_ImplOpenGL3_Init(glsl_version);

OpenGL3 렌더링 백엔드를 초기화하고 GLSL 버전 문자열을 전달해 UI 그리기용 정점/프래그먼트 셰이더 컴파일, GPU 버퍼를 생성합니다.

float slider_value = 0.5f;    // 슬라이더 연동 수치
int click_count = 0;          // 버튼 클릭 횟수 카운터
bool show_full_demo = false;  // ImGui 공식 데모 창 표시 여부 제어 플래그

위 변수들은 각 컨트롤 값을 저장하는 용도로 매 프레임 갱신 시 읽고 수정하며 프레임 간 값이 유지됩니다.

메인 렌더링 루프

프로그램 핵심 로직으로 초당 수십~수백 회 반복 실행됩니다.

while (!glfwWindowShouldClose(window))

오른쪽 상단 X 버튼 클릭, Alt+F4 등 창 종료 신호가 들어오기 전까지 렌더링을 반복합니다.

glfwPollEvents();

마우스 클릭/이동, 키 입력, 창 크기 조절, 종료 등 모든 창 시스템 메시지를 폴링합니다.

 ImGui_ImplOpenGL3_NewFrame();

OpenGL 백엔드 프레임 전처리. 렌더링 리소스를 초기화하고 다음 프레임 버퍼를 준비합니다.

ImGui_ImplGlfw_NewFrame();

GLFW 백엔드 프레임 전처리. 현재 마우스 좌표, 키 상태, 창 크기를 읽어 ImGui IO 입력 데이터에 반영합니다.

ImGui::NewFrame();

새 프레임 UI 레이아웃 계산을 시작하며 모든 ImGui::xxx() 컨트롤 코드 앞에 선언해야 합니다. 내부에서 이전 프레임 그리기 명령을 비우고 현재 프레임 UI 데이터 수집을 준비합니다.

UI 컨트롤 데이터 구축 영역

// Draw custom UI panel
ImGui::Begin("Control Panel");                // 커스텀 제어판 창 활성화
ImGui::Text("Hello ImGui + VS2022");          // 정적 텍스트 출력
ImGui::SliderFloat("Slider Value", &slider_value, 0.f, 1.f); // 부동 소수점 슬라이더, 수치 변수 연동

if (ImGui::Button("Click to Count"))          // 클릭용 버튼 생성, 누를 시 true 반환
    click_count++;                            // 버튼 클릭 시 카운터 증가
ImGui::SameLine();                            // 다음 컨트롤을 같은 줄에 배치
ImGui::Text("Click Count: %d", click_count);  // 버튼 클릭 횟수 표시

ImGui::Checkbox("Show Full ImGui Demo Window", &show_full_demo); // 체크박스로 데모 창 표시 토글
ImGui::End();                                 // 현재 커스텀 창 렌더링 종료

if (show_full_demo)
    ImGui::ShowDemoWindow(&show_full_demo);    // ImGui 공식 전체 데모 창 실행

이 블록은 매 루프마다 UI를 그려주며 버튼 클릭 여부를 감지해 카운트를 늘리고 횟수를 화면에 표시하는 로직입니다.

실제 렌더링 처리 영역

// Render ImGui draw data
ImGui::Render();                                        // 현재 프레임 UI 정점 렌더 데이터 생성
int width, height;
glfwGetFramebufferSize(window, &width, &height);        // 창 실제 렌더링 해상도 획득
glViewport(0, 0, width, height);                       // OpenGL 렌더링 뷰포트를 창 전체로 설정
glClearColor(0.12f, 0.12f, 0.12f, 1.f);                // 창 초기화 배경색을 짙은 회색으로 지정
glClear(GL_COLOR_BUFFER_BIT);                           // 화면 색상 버퍼 초기화
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());// OpenGL로 모든 ImGui 인터페이스 렌더링

glfwSwapBuffers(window);                                // 전/후면 버퍼 교체, 화면에 최신 이미지 출력

종료 후 리소스 정리 영역

아래 코드는 사용자가 프로그램을 종료했을 때 사용한 모든 리소스를 정리하는 로직입니다.

// Cleanup resources
ImGui_ImplOpenGL3_Shutdown();  // OpenGL 렌더링 백엔드 리소스(셰이더, 버퍼 등) 해제
ImGui_ImplGlfw_Shutdown();     // GLFW 창 연동 백엔드 리소스 해제
ImGui::DestroyContext();       // ImGui 전역 컨텍스트 소멸, UI 메모리 반환
glfwDestroyWindow(window);     // GLFW 창 닫기, 창 핸들 제거
glfwTerminate();               // GLFW 라이브러리 완전 언로드, 전역 창/입력 리소스 해제
return 0;                      // 프로그램 정상 종료, 성공 코드 0 반환

리소스 소멸 순서는 초기화 순서와 정반대로 작성해야 메모리 누수, 잔여 리소스 문제를 방지할 수 있습니다.

이상으로 지난 수업 예제 분석을 마치겠습니다. 궁금한 점이 있으면 하단 댓글로 질문해 주세요.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다