헤더 파일 영역
#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 반환
리소스 소멸 순서는 초기화 순서와 정반대로 작성해야 메모리 누수, 잔여 리소스 문제를 방지할 수 있습니다.
이상으로 지난 수업 예제 분석을 마치겠습니다. 궁금한 점이 있으면 하단 댓글로 질문해 주세요.
