C++ 界面开发只有 Qt 一条路?大错特错!今天带你复盘游戏界与工业级工具链的"幕后霸主"------Dear ImGui。无需复杂的信号槽,没有臃肿的依赖,解压即用。本文将从"立即模式"底层原理出发,带你手把手从零搭建、极速入门,解锁 C++ 界面开发的新世界!

在 C++ 研发圈子里,一提到图形用户界面(GUI)开发,绝大多数人的第一反应就是 Qt。
Qt 固然功能强大、生态完善,但它的"重"也是出了名的,复杂的 MOC(元对象编译器)机制、让人头秃的信号与槽同步,以及难以剥离的动态链接库。特别是对于游戏开发、工业自动化控制、实时数据可视化等追求绝对性能、需要快速构建内部Debug工具的场景,Qt 往往显得有些大材小用。
那么,有没有一种界面库,既能做到轻量到只有几个源文件 ,又能做到渲染速度快到飞起,还能让程序员在几分钟内写出功能完备的交互面板?
答案就是今天的主角、在 GitHub 上狂揽 73,000+ Star 的神级开源项目:Dear ImGui。
从 Epic 的虚幻引擎工具链,到各大顶尖 AAA 游戏工作室的内部编辑器,甚至连各种高精度的 AI 推理可视化工具中,你都能看到那个标志性的、半透明的灰色控制面板。
今天,我们就来彻底揭开 Dear ImGui 的神秘面纱,从安装、到入门,带你一口气通关!
先看一下基于 imgui 制作的有意思的项目吧:

极简安装
Dear ImGui 的代码设计可以说是 C++ 界的一股清流。它没有任何第三方硬依赖,不绑定任何特定的图形 API(如 OpenGL, DirectX, Vulkan, Metal)。
它的核心库其实就是几个源文件:
imgui.cpp/imgui.h(核心逻辑)imgui_demo.cpp(官方庞大的示例代码库)imgui_draw.cpp(顶点数据构建与渲染指令生成)imgui_widgets.cpp(按钮、滑块、输入框等核心组件)imgui_tables.cpp(高强度表格系统)
-
直接拷贝:把上述源文件直接下载并拖进你的 C++ 工程目录中。
-
选择后端(Backend) :因为 ImGui 本身只负责计算"要在哪里画什么",真正的渲染需要交给窗口系统和显卡。官方贴心地在
backends/目录下提供了几乎所有主流组合的适配器:- 窗口控制:GLFW, SDL2, Win32, Android
- 图形渲染:OpenGL3, DirectX11/12, Vulkan, Metal
如果你使用的是常用的 GLFW + OpenGL3 组合,只需要把 imgui_impl_glfw.cpp 和 imgui_impl_opengl3.cpp 一并加入编译即可。用 CMake 引入也仅仅只需要几行代码,爽快度拉满!
快速入门
编辑 CMake 引入 imgui 库
txt
cmake_minimum_required(VERSION 3.16)
project(my_server)
find_package(OpenGL REQUIRED)
find_package(Threads REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GLFW3 REQUIRED glfw3)
include(FetchContent)
FetchContent_Declare(imgui GIT_REPOSITORY https://github.com/ocornut/imgui.git GIT_TAG v1.92.8)
FetchContent_MakeAvailable(imgui)
add_executable(my_server
src/main.cpp
${imgui_SOURCE_DIR}/imgui.cpp
${imgui_SOURCE_DIR}/imgui_draw.cpp
${imgui_SOURCE_DIR}/imgui_tables.cpp
${imgui_SOURCE_DIR}/imgui_widgets.cpp
${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp
${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
)
target_include_directories(my_server PRIVATE ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/backends ${GLFW3_INCLUDE_DIRS})
target_link_libraries(my_server PRIVATE ${GLFW3_LIBRARIES} OpenGL::GL Threads::Threads ${CMAKE_DL_LIBS})
target_link_directories(my_server PRIVATE ${GLFW3_LIBRARY_DIRS})
让我们直接来看一段最纯正的 Dear ImGui 代码。假设你已经初始化好了 GLFW 和 OpenGL 环境,你只需要写下这样直观的代码:
C++
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include <GLFW/glfw3.h>
#include <cstdio>
int main() {
// 初始化 GLFW
if (!glfwInit()) {
fprintf(stderr, "GLFW 初始化失败!\n");
return -1;
}
// 创建窗口
GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui 演示程序", nullptr, nullptr);
if (!window) {
fprintf(stderr, "窗口创建失败!\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // 开启 vsync
// 初始化 ImGui
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
// 加载中文字体(TTC 需指定 face 索引,SC=简体中文位于索引 3)
ImFontConfig fontCfg;
fontCfg.FontNo = 3; // NotoSansCJK SC face
io.Fonts->AddFontFromFileTTF(
"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
18.0f, &fontCfg, io.Fonts->GetGlyphRangesChineseFull());
// 绑定 GLFW + OpenGL3 后端
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 130");
// 业务状态变量
float speed = 1.0f;
int click_count = 0;
// 主循环
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
// 开启 ImGui 新帧
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// UI 逻辑
{
ImGui::Begin("控制中心");
ImGui::Text("欢迎来到 Dear ImGui 的世界!");
ImGui::SliderFloat("运行速度", &speed, 0.0f, 10.0f);
if (ImGui::Button("点击加计数")) {
click_count++;
}
ImGui::Text("你一共点击了: %d 次", click_count);
ImGui::Text("当前帧率: %.1f FPS", io.Framerate);
ImGui::End();
}
// 渲染
ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
}
// 清理
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

注意到没有?传统的界面开发需要写一个"OnButtonClick"的响应函数,再通过长长的路径去访问文本控件修改其内容。
而在 Dear ImGui 中:
C++
if (ImGui::Button("点击加计数")) { click_count++; }
这一句话同时完成了:绘制按钮 、检测鼠标点击事件 、返回布尔值 三个操作。如果用户点击了,就立刻执行大括号内的业务代码。数据更新后,下一帧的 ImGui::Text 就会自动刷出最新值。没有中间商赚差价,逻辑丝滑无比!
结语
抛弃繁琐,回归逻辑本身。 Dear ImGui 让我们将绝大部分精力集中在"核心数据处理"上,而不是在界面的排版和回调中痛苦挣扎。
如果你手头正有一个 C++ 项目需要一套高性能、好用且极速完成的开发工具面板,别再犹豫了,快去 GitHub 体验一下 Dear ImGui 带来的极致开发快感吧!