ImGui
카테고리: OpenGL
태그: Graphics
Main Reference
- Learn OpenGL
- Rinthel Kwon - OpenGL Lecture
ImGui
ImGui는 Immediate Mode GUI란 뜻으로 Graphics API를 이용해 GUI 컴포넌트를 그리는 기능을 제공한다. 즉 매 프레임마다 화면 위에 GUI를 렌더링하는 방식이다. 기본적으로 UI이기 때문에 input callback 기능을 제공하고, 특히 graphics programming에 적합한 vector editor, color picker 등의 기능도 제공한다(애초에 graphics작업하려고 만듬). 또 다른 특징으로는 빌드가 간단하며, Rendering Backend를 분리해놨기 때문에 필요한 Graphics API 버전을 사용하면 된다.
- ImGui gitgub에서 코드 zip파일 다운
- 강의는 1.82버전, 최신은 1.9x인데 IO 관련 기능이 많이 바뀌어서 안돌아감..
- 해당 포스팅은 1.82 버전 사용
- 루트 폴더에 imgui 폴더를 생성하고, 필요한 파일들만 복사
- cmake를 이용해 직접 빌드파일 생성
Initialize ImGui
// main.cpp
// glad를 활용한 OpenGL 함수 로딩
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
SPDLOG_ERROR("failed to initialize glad");
glfwTerminate();
return -1;
}
auto glVersion = glGetString(GL_VERSION);
SPDLOG_INFO("OpenGL context version: {}", (const char*)glVersion);
auto imguiContext = ImGui::CreateContext();
ImGui::SetCurrentContext(imguiContext);
ImGui_ImplGlfw_InitForOpenGL(window, false);
ImGui_ImplOpenGL3_Init();
ImGui_ImplOpenGL3_CreateFontsTexture();
ImGui_ImplOpenGL3_CreateDeviceObjects();
// ...
SPDLOG_INFO("Start main loop");
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
context->ProcessInput(window);
context->Render();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
}
context.reset();
ImGui_ImplOpenGL3_DestroyFontsTexture();
ImGui_ImplOpenGL3_DestroyDeviceObjects();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext(imguiContext);
glfwTerminate();
- OpenGL 초기화 후 ImGui 초기화
- main loop에서 ImGui 렌더링 파트 추가 (순서 유의)
- ImGui 프레임 준비
- screen 렌더링
- ImGui 렌더링
- 프로그램 종료 전 리소스 반납
void OnKeyEvent(GLFWwindow* window, int key, int scancode, int action, int mods) {
ImGui_ImplGlfw_KeyCallback(window, key, scancode, action, mods);
// ...
}
void OnMouseButton(GLFWwindow* window, int button, int action, int modifier) {
ImGui_ImplGlfw_MouseButtonCallback(window, button, action, modifier);
// ...
}
- 기존 callback 함수에서 ImGui callback 함수 추가해줘야 input 반응
Example
void Context::Render() {
if (ImGui::Begin("ui window")) {
if (ImGui::ColorEdit4("clear color", glm::value_ptr(m_clearColor))) {
glClearColor(m_clearColor.r, m_clearColor.g, m_clearColor.b, m_clearColor.a);
}
ImGui::Separator();
ImGui::DragFloat3("camera pos", glm::value_ptr(m_cameraPos), 0.01f);
ImGui::DragFloat("camera yaw", &m_cameraYaw, 0.5f);
ImGui::DragFloat("camera pitch", &m_cameraPitch, 0.5f, -89.0f, 89.0f);
ImGui::Separator();
if (ImGui::Button("reset camera")) {
m_cameraYaw = 0.0f;
m_cameraPitch = 0.0f;
m_cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
}
}
ImGui::End();
// ...
}
- Begin() ~ End() 로 UI window 생성
- ImGui 함수 하나가 하나의 UI Component와 대응
- UI가 조작되면(값이 변경되면) true 리턴
댓글 남기기