目录
1.简介

Dear ImGui(简称 ImGui)是一套C++ 即时模式 GUI(Immediate Mode GUI,IMGUI) 开源库,作者 Omar Cornut,主打游戏、渲染引擎、仿真工具、调试面板开发。
- 无强依赖,仅标准 C++;
- 不自带窗口 / 图形 API,通过后端对接 OpenGL/DX11/Vulkan/GLFW/SDL;
- 定位:编辑器、调试面板、工具 UI,不适合商业桌面客户端(Qt/MFC 场景)。
即时模式 vs 传统保留模式 GUI
保留模式(Qt、Win32、UE 原生 UI)
提前创建控件对象、长期保存在内存,通过事件回调响应交互,控件有独立生命周期。 缺点:代码割裂、大量回调、工具类界面开发繁琐。
即时模式(ImGui 核心设计)
每一帧完整重绘全部 UI,不长期存储控件对象,UI 逻辑和业务逻辑写在同一段代码里。 单帧标准流程:
ImGui::NewFrame()开启新帧,重置布局与输入状态- 顺序执行所有 UI 代码(按钮、输入框、窗口)
- 交互同步修改你自己定义的变量(无回调)
ImGui::Render()生成绘制命令数据- 图形后端渲染顶点到屏幕
状态(勾选框、输入文字、滑动条数值)全部由外部变量保存,ImGui 仅临时缓存布局、绘制数据,帧结束全部丢弃。
优势:开发速度极快、逻辑直观,调试工具首选;
短板:超大数量控件(上万)性能弱于保留式 GUI。
2.安装与集成
1.获取 ImGui 源码
git clone https://github.com/ocornut/imgui.git
cd imgui
# 稳定版本,不要直接拉master
git checkout docking
下载压缩包:
官网 releases:https://github.com/ocornut/imgui/releases
解压后得到 imgui 文件夹。
2.提取项目必需文件(只复制这些,精简体积)
核心内核(必须)
imgui/
├─ imgui.h
├─ imgui.cpp
├─ imgui_draw.cpp
├─ imgui_widgets.cpp
└─ imgui_tables.cpp
后端绑定(二选一组合)
后端分为「平台输入后端」+「图形渲染后端」,成对使用:
A.跨平台 GLFW + OpenGL3(最通用)
backends/imgui_impl_glfw.h/cpp
backends/imgui_impl_opengl3.h/cpp
B.Windows 原生 Win32 + DirectX11
backends/imgui_impl_win32.h/cpp
backends/imgui_impl_dx11.h/cpp
扩展(可选,图表 ImPlot), 单独克隆 ImPlot 放到同级目录:
git clone https://github.com/epezent/implot.git
需要文件:implot.h / implot.cpp / implot_items.cpp
3.vcpkg安装
安装 vcpkg 后执行安装命令
# 基础imgui+glfw+opengl后端
vcpkg install imgui[glfw-binding,opengl3-binding]
# 带ImPlot图表
vcpkg install imgui[glfw-binding,opengl3-binding,implot]
VS 直接集成,无需配置头文件 / 源码,直接 #include <imgui.h>
4.CMake 项目集成配置(跨平台 Linux/Windows/Mac)
基础 CMakeLists.txt(GLFW+OpenGL)
cmake_minimum_required(VERSION 3.16)
project(ImGuiProject)
set(CMAKE_CXX_STANDARD 17)
# 1. 依赖 GLFW + OpenGL
find_package(glfw3 REQUIRED)
find_package(OpenGL REQUIRED)
# 2. ImGui 文件集合
set(IMGUI_ROOT ${CMAKE_SOURCE_DIR}/thirdparty/imgui)
set(IMGUI_SRC
${IMGUI_ROOT}/imgui.cpp
${IMGUI_ROOT}/imgui_draw.cpp
${IMGUI_ROOT}/imgui_widgets.cpp
${IMGUI_ROOT}/imgui_tables.cpp
# GLFW + OpenGL后端
${IMGUI_ROOT}/backends/imgui_impl_glfw.cpp
${IMGUI_ROOT}/backends/imgui_impl_opengl3.cpp
)
# 3. 可选 ImPlot
set(IMPLOT_ROOT ${CMAKE_SOURCE_DIR}/thirdparty/implot)
set(IMPLOT_SRC
${IMPLOT_ROOT}/implot.cpp
${IMPLOT_ROOT}/implot_items.cpp
)
# 编译目标
add_executable(App main.cpp ${IMGUI_SRC} ${IMPLOT_SRC})
# 头文件搜索路径
target_include_directories(App PRIVATE
${IMGUI_ROOT}
${IMGUI_ROOT}/backends
${IMPLOT_ROOT}
${OPENGL_INCLUDE_DIR}
)
# 链接系统库
target_link_libraries(App PRIVATE glfw OpenGL::GL)
3.源码文件架构
核心内核文件
| 文件 | 作用 |
|---|---|
| imgui.h / imgui.cpp | 全局上下文、IO、窗口管理、主逻辑 |
| imgui_widgets.cpp | 所有内置控件(按钮、输入框、表格)实现 |
| imgui_draw.cpp | 顶点生成、线条、文字、图片渲染逻辑 |
| imgui_tables.cpp | 新版表格布局系统(替代旧 Columns) |
后端绑定目录 backends/
分为两类后端,必须成对搭配使用:
- 平台后端:处理窗口、鼠标键盘输入、剪贴板(
glfw,sdl2,win32) - 渲染后端:对接图形 API,绘制顶点缓冲(
opengl3,dx11,dx12,vulkan)
扩展目录 misc/
字体加载、图标集成、修复补丁、文件对话框辅助工具。
关键顶层数据结构
- ImGuiContext 全局 UI 上下文,存储所有窗口、布局、临时状态;支持多实例多隔离 UI 环境,单上下文只能单线程渲染。
- ImGuiIO 输入与全局配置总入口:窗口分辨率、鼠标 / 键盘数据、按键映射、全局开关 Flag、剪贴板、字体。
- ImGuiStyle UI 样式:圆角、间距、内边距、全套颜色配置。
- ImDrawData / ImDrawList 渲染输出核心:每帧
Render()生成ImDrawData,包含多个绘制列表;列表存储顶点、索引、绘制指令(矩形、文字、贴图),后端遍历绘制。
4.标准集成流程
1.初始化阶段
// 1. 创建UI上下文
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
// 2. 全局开关配置(停靠、多视口等)
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // 窗口停靠
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // 独立系统窗口
// 3. 加载字体(中文、图标)
io.Fonts->AddFontFromFileTTF("msyh.ttc", 16, nullptr, io.Fonts->GetGlyphRangesChineseFull());
// 4. 初始化平台+渲染后端(例:GLFW+OpenGL3)
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");
// 5. 修改默认样式
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
style.WindowRounding = 6.0f;
2.主渲染循环(每帧固定顺序)
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
// 1. 后端同步输入给ImGuiIO(鼠标、键盘、窗口尺寸)
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame(); // 开启新帧
// ========== 你的所有UI绘制代码写在这里 ==========
ImGui::ShowDemoWindow(); // 官方Demo,查看全部控件用法
bool open = true;
if (ImGui::Begin("调试面板", &open))
{
static float value = 0.0f;
ImGui::DragFloat("参数", &value, 0.1f, 0, 100);
if (ImGui::Button("执行"))
{
// 按钮点击逻辑直接写在这里,无需回调
}
}
ImGui::End();
// ===============================================
// 2. 生成绘制数据
ImGui::Render();
// 3. 清空屏幕,后端渲染UI
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// 多视口支持(窗口拖出主窗口)
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
GLFWwindow* backup_current_context = glfwGetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwMakeContextCurrent(backup_current_context);
}
glfwSwapBuffers(window);
}
3.程序退出销毁
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
5.核心常用控件与布局 API
1.窗口容器
// 基础窗口,&open 控制右上角关闭叉号
ImGui::Begin("窗口名称", &bool_open);
ImGui::End();
// 内嵌滚动子窗口
ImGui::BeginChild("子面板", ImVec2(300, 200));
ImGui::EndChild();
// 模态弹窗(阻塞交互)
if (ImGui::BeginPopupModal("提示框"))
{
ImGui::Text("弹窗内容");
if (ImGui::Button("关闭")) ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
2.交互控件
// 按钮
if (ImGui::Button("按钮")) {}
ImGui::SmallButton("小按钮");
// 勾选框
static bool enable = false;
ImGui::Checkbox("启用", &enable);
// 单选框
static int sel = 0;
ImGui::RadioButton("选项A", &sel, 0);
ImGui::RadioButton("选项B", &sel, 1);
// 数值输入/拖拽/滑动条
static float f = 1.0f;
ImGui::DragFloat("数值", &f, 0.01f, 0, 10);
ImGui::SliderFloat("滑块", &f, 0, 10);
// 文本输入
char buf[128] = "测试";
ImGui::InputText("单行输入", buf, IM_ARRAYSIZE(buf));
ImGui::InputTextMultiline("多行", buf, ImVec2(200, 80));
// 折叠分组
if (ImGui::CollapsingHeader("折叠分组"))
{
ImGui::Text("内部内容");
}
3.布局控制(高频必备)
ImGui::SameLine(20); // 下一个控件和上一行同行,偏移20像素
ImGui::NewLine(); // 强制换行
ImGui::Spacing(); // 空一行间距
ImGui::Separator(); // 水平分割线
ImGui::Indent(); // 缩进
ImGui::Unindent(); // 取消缩进
// 预先设置下一个窗口位置/大小
ImGui::SetNextWindowPos(ImVec2(10,10));
ImGui::SetNextWindowSize(ImVec2(400,300));
4.表格布局(新版标准,替代 Columns)
// 创建3列表格,自适应宽度
if (ImGui::BeginTable("table", 3, ImGuiTableFlags_Borders))
{
ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::Text("姓名");
ImGui::TableNextColumn(); ImGui::Text("年龄");
ImGui::TableNextColumn(); ImGui::Text("操作");
ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::Text("张三");
ImGui::TableNextColumn(); ImGui::Text("24");
ImGui::TableNextColumn(); ImGui::Button("编辑");
ImGui::EndTable();
}
5.底层绘图原语(自定义绘制)
ImDrawList* draw = ImGui::GetWindowDrawList();
ImVec2 pMin = ImGui::GetCursorScreenPos();
ImVec2 pMax = ImVec2(pMin.x + 100, pMin.y + 60);
draw->AddRectFilled(pMin, pMax, IM_COL32(50,50,180,255)); // 填充矩形
draw->AddLine(pMin, pMax, IM_COL32_WHITE); // 直线
draw->AddText(pMin, IM_COL32_WHITE, "自定义绘制");
6.右键菜单
// 右键点击控件弹出菜单
if (ImGui::BeginPopupContextItem("右键菜单"))
{
if (ImGui::MenuItem("复制")) {}
if (ImGui::MenuItem("删除")) {}
ImGui::EndPopup();
}
6.渲染底层原理
- NewFrame 阶段 读取鼠标、键盘、窗口尺寸输入;重置布局计算器,计算所有窗口 Hover、焦点、滚动状态。
- UI 构建阶段 执行你写的所有控件代码,实时计算每个控件宽高、屏幕坐标,直接写入顶点缓存;同步检测点击、拖拽、输入,修改外部变量。
- Render 阶段 裁剪窗口、合并绘制指令,打包成
ImDrawData;所有文字转为字体图集 UV 坐标,生成三角形顶点。 - 后端绘制阶段 遍历绘制列表,绑定顶点缓冲、字体纹理,批量提交绘制,尽可能减少渲染批次(DrawCall)。
字体渲染机制
ImGui 使用单张图集纹理存储全部字符,支持:
- 加载 TTF 自定义字体;
- 追加中文字符范围;
- 合并图标字体(FontAwesome)实现按钮图标;
- 全局切换字体大小。
7.完整示例
功能:中文支持、窗口停靠、基础控件、表格、自定义绘图、右键菜单、弹窗
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include <cstdio>
#include <vector>
// 全局UI数据
static float g_float_val = 50.0f;
static bool g_check_enable = false;
static int g_radio_sel = 0;
static char g_input_buf[256] = "测试中文输入";
static bool show_demo_window = true;
static bool show_custom_window = true;
int main()
{
// 1. GLFW 窗口初始化
glfwInit();
const char* glsl_version = "#version 330";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui 完整Demo", nullptr, nullptr);
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // 开启垂直同步
// 2. ImGui 上下文创建
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.IniFilename = "ui_layout.ini"; // 自动保存窗口布局
// 开启停靠、多视口
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
// 加载中文字体(fonts/msyh.ttc)
ImFontConfig font_cfg;
font_cfg.GlyphMinAdvanceX = 14.0f;
static const ImWchar chinese_ranges[] = {
0x4E00, 0x9FFF, // 中文汉字区间
0
};
io.Fonts->AddFontFromFileTTF("./fonts/msyh.ttc", 16.0f, &font_cfg, chinese_ranges);
io.Fonts->Build();
// 样式设置
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
style.WindowRounding = 0.0f;
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
}
style.WindowRounding = 6.0f;
style.ItemSpacing = ImVec2(8, 6);
// 3. 绑定GLFW+OpenGL后端
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glsl_version);
// 主渲染循环
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
// ImGui帧启动
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// ========== UI绘制区域 ==========
// 1. 官方示例窗口(查看全部控件用法)
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// 2. 全局停靠空间
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
// 3. 自定义窗口
if (show_custom_window)
{
ImGui::Begin("自定义调试面板", &show_custom_window, ImGuiWindowFlags_MenuBar);
// 菜单栏
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("菜单"))
{
if (ImGui::MenuItem("弹出弹窗"))
ImGui::OpenPopup("提示弹窗");
ImGui::MenuItem("关闭窗口", nullptr, &show_custom_window);
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
// 基础交互控件
ImGui::Text("基础交互控件");
ImGui::DragFloat("浮点参数", &g_float_val, 0.5f, 0.0f, 100.0f);
ImGui::SliderFloat("滑动条", &g_float_val, 0, 100);
ImGui::Checkbox("启用功能", &g_check_enable);
ImGui::Text("单选选择");
ImGui::RadioButton("选项一", &g_radio_sel, 0); ImGui::SameLine();
ImGui::RadioButton("选项二", &g_radio_sel, 1); ImGui::SameLine();
ImGui::RadioButton("选项三", &g_radio_sel, 2);
ImGui::InputText("单行输入框", g_input_buf, IM_ARRAYSIZE(g_input_buf));
if (ImGui::Button("点击按钮"))
{
printf("按钮被点击,当前数值:%.2f\n", g_float_val);
}
ImGui::SameLine();
ImGui::SmallButton("小按钮");
ImGui::Separator();
ImGui::Text("表格布局示例");
// 3列表格
if (ImGui::BeginTable("table_demo", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
{
ImGui::TableSetupColumn("姓名");
ImGui::TableSetupColumn("数值");
ImGui::TableSetupColumn("操作");
ImGui::TableHeadersRow();
ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::Text("测试用户");
ImGui::TableNextColumn(); ImGui::Text("%.2f", g_float_val);
ImGui::TableNextColumn(); if (ImGui::Button("重置")) g_float_val = 0;
ImGui::EndTable();
}
ImGui::Separator();
ImGui::Text("自定义绘制图形");
ImDrawList* draw = ImGui::GetWindowDrawList();
ImVec2 cursor = ImGui::GetCursorScreenPos();
ImVec2 rect_max = ImVec2(cursor.x + 120, cursor.y + 60);
draw->AddRectFilled(cursor, rect_max, IM_COL32(40, 120, 220, 180));
draw->AddRect(cursor, rect_max, IM_COL32_WHITE, 4.0f);
draw->AddText(ImVec2(cursor.x + 10, cursor.y + 20), IM_COL32_WHITE, "自定义矩形");
ImGui::SetCursorScreenPos(ImVec2(rect_max.x + 10, cursor.y));
// 右键菜单
if (ImGui::BeginPopupContextItem("右键菜单"))
{
ImGui::MenuItem("复制");
ImGui::MenuItem("粘贴");
ImGui::MenuItem("清空");
ImGui::EndPopup();
}
ImGui::End();
}
// 模态弹窗
if (ImGui::BeginPopupModal("提示弹窗", nullptr, ImVec2(300, 150)))
{
ImGui::Text("这是模态弹窗,阻塞其他交互");
ImGui::Spacing();
if (ImGui::Button("关闭", ImVec2(100, 30)))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
// =====================================
// 渲染提交
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.12f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 绘制UI
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
// 多视口支持
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
GLFWwindow* backup = glfwGetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwMakeContextCurrent(backup);
}
glfwSwapBuffers(window);
}
// 释放资源
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
8.生态扩展库
- ImPlot:实时曲线图、直方图、性能监控图表,调试性能首选;
- ImNodes:节点编辑器(材质蓝图、流程编辑器);
- ImGuiColorTextEdit:带语法高亮代码编辑器;
- ImFileDialog:跨平台文件打开 / 保存对话框;
- FontAwesome:图标字体,给按钮添加图标;
- ImSpinner:加载动画、进度控件。
9.优缺点
优势:
- 集成简单,无复杂依赖,嵌入自制引擎、模拟器零成本;
- 即时模式开发效率极高,UI 与业务代码合一,无回调;
- 完整内置编辑器功能:停靠、表格、弹窗、拖拽;
- 跨全平台:Windows/Linux/macOS/ 安卓 /iOS;
- 自带完整 Demo,一键查看所有控件用法;
- 底层绘图接口开放,可任意自定义控件。
劣势:
- 每帧重建 UI,上万控件场景性能远弱于 Qt;
- 无原生系统控件,无障碍、系统主题支持差,不适合商业桌面软件;
- 中文需手动加载字体,默认不支持中文;
- 同一 UI 上下文只能单线程渲染,多线程易崩溃;
- 无组件生命周期,复杂界面需要手动封装复用。
10.常见使用场景
- 游戏引擎调试面板、内置编辑器;
- 图形渲染工具、离线仿真、军事仿真控制面板;
- 性能监控工具(帧率、内存、渲染管线参数调节);
- 建模、材质、动画小型工具软件;
- 模拟器、工控调试程序
转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/haokan123456789/article/details/162349773



