Introduction
Immediate Mode GUI (ImGui) is a popular graphical user interface library designed for simplicity and flexibility. Whether you’re building tools, debugging interfaces, or even game UI, ImGui’s focus on immediate rendering makes it highly efficient and intuitive.
In this tutorial, we’ll guide you through:
- Setting up ImGui in your project.
- Creating a basic UI.
- Handling user inputs.
- Customizing styles for a professional look.
Prerequisites
Before diving in, ensure you have the following:
Graphics Backend: ImGui supports various backends like OpenGL, DirectX, and Vulkan. We’ll use OpenGL in this tutorial.
Development Environment: A modern C++ compiler and an IDE (e.g., Visual Studio, CLion, or VS Code).
Step 1: Setting Up ImGui
- Clone the ImGui Repository:
git clone https://github.com/ocornut/imgui.git
cd imgui
Include ImGui in Your Project:
Copy these essential files into your project:
imgui.cpp
imgui.h
imgui_draw.cpp
imgui_widgets.cpp
imgui_tables.cpp
imgui_demo.cpp
(optional, for examples).
Setup a Rendering Backend:
For OpenGL:
Add imgui_impl_opengl3.cpp
and imgui_impl_opengl3.h
.
Link against OpenGL libraries (e.g., -lGL
on Linux).
For DirectX:
Use imgui_impl_dx11.cpp
or your preferred DirectX version.
Integrate into Your Build System: Add the ImGui files to your CMakeLists.txt
or your IDE’s project configuration.
Step 2: Creating a Basic UI
Here’s how to initialize and render a basic ImGui window.
Initialize ImGui:
// Initialize ImGui
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable keyboard navigation
ImGui_ImplOpenGL3_Init("#version 130"); // Initialize OpenGL
Rendering Loop: Inside your rendering loop:
while (!glfwWindowShouldClose(window)) {
// Start ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();
// Create a simple window
ImGui::Begin("Hello, ImGui!");
ImGui::Text("Welcome to ImGui!");
ImGui::Button("Click Me");
ImGui::End();
// Render
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
glfwPollEvents();
}
Cleanup:
ImGui_ImplOpenGL3_Shutdown();
ImGui::DestroyContext();
Step 3: Handling User Inputs
ImGui integrates with your input system, such as GLFW for OpenGL. Ensure the input data flows to ImGui:
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) {
ImGuiIO& io = ImGui::GetIO();
if (action == GLFW_PRESS) io.KeysDown[key] = true;
if (action == GLFW_RELEASE) io.KeysDown[key] = false;
});
Step 4: Customizing Styles
ImGui allows you to change the look and feel of your UI:
ImGuiStyle& style = ImGui::GetStyle();
style.WindowRounding = 5.0f; // Rounded corners
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.2f, 0.2f, 0.2f, 1.0f); // Background color
Experiment with the ImGui::ShowStyleEditor()
to interactively adjust styles.
Step 5: Debugging with ImGui
Enable the demo window to explore features:
ImGui::ShowDemoWindow();
Use this for quick debugging and testing different widgets and layouts.
Best Practices
- Minimize Stateful Logic:
- ImGui excels with immediate rendering; avoid storing unnecessary state.
- Use the Demo Code:
- The included
imgui_demo.cpp
showcases advanced widgets and layouts.
- The included
- Optimize Rendering:
- Batch your draw calls and avoid redundant calls in performance-critical applications.
Complete Code: Basic ImGui Application
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <GLFW/glfw3.h>
#include <iostream>
// Callback for GLFW errors
void glfw_error_callback(int error, const char* description) {
std::cerr << "GLFW Error " << error << ": " << description << std::endl;
}
int main() {
// Set GLFW error callback
glfwSetErrorCallback(glfw_error_callback);
// Initialize GLFW
if (!glfwInit()) {
std::cerr << "Failed to initialize GLFW" << std::endl;
return -1;
}
// Create a GLFW window
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui Example", nullptr, nullptr);
if (!window) {
std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Make OpenGL context current
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable VSync
// Initialize ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable keyboard navigation
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable docking
// Initialize ImGui style
ImGui::StyleColorsDark();
// Initialize ImGui backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");
// Main rendering loop
while (!glfwWindowShouldClose(window)) {
// Poll events
glfwPollEvents();
// Start a new ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// Create a simple ImGui window
ImGui::Begin("Hello, ImGui!");
ImGui::Text("Welcome to ImGui!");
if (ImGui::Button("Click Me")) {
std::cout << "Button clicked!" << std::endl;
}
ImGui::End();
// Rendering
ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// Swap buffers
glfwSwapBuffers(window);
}
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
Steps to Run
- Clone the ImGui Repository:
- Add ImGui Files to Your Project: Copy these files into your project directory:
imgui.h
imgui.cpp
imgui_draw.cpp
imgui_widgets.cpp
imgui_tables.cpp
- Backends:
imgui_impl_glfw.h
and.cpp
imgui_impl_opengl3.h
and.cpp
- Link OpenGL and GLFW:\
- Add OpenGL and GLFW to your build system (e.g.,
-lGL -lglfw
).
- Add OpenGL and GLFW to your build system (e.g.,
- Build and Run:
- If using
g++
:bashCopy code
- If using
g++ main.cpp -o imgui_app -lGL -lglfw -ldl -I<path-to-imgui> -I<path-to-glfw>
./imgui_app
Alternatively, configure your project in an IDE like Visual Studio, CLion, or VS Code.