Epic、暴雪都在用的 C++ 界面利器:Dear ImGui 零基础全景指南

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 (高强度表格系统)
  1. 直接拷贝:把上述源文件直接下载并拖进你的 C++ 工程目录中。

  2. 选择后端(Backend) :因为 ImGui 本身只负责计算"要在哪里画什么",真正的渲染需要交给窗口系统和显卡。官方贴心地在 backends/ 目录下提供了几乎所有主流组合的适配器:

    • 窗口控制:GLFW, SDL2, Win32, Android
    • 图形渲染:OpenGL3, DirectX11/12, Vulkan, Metal

如果你使用的是常用的 GLFW + OpenGL3 组合,只需要把 imgui_impl_glfw.cppimgui_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 带来的极致开发快感吧!

相关推荐
pixcarp3 小时前
知识库系统的内容资产闭环怎么设计
服务器·数据库·后端·golang
红尘散仙3 小时前
别再手动录屏了:用 VHS 给终端应用生成会动的文档素材
后端·rust
张忠琳6 小时前
【Go 1.26.4】Golang Select 深度解析
开发语言·后端·golang
IT_陈寒6 小时前
React中useEffect依赖项这个坑我居然踩了三天
前端·人工智能·后端
提笔了无痕7 小时前
如何用Go实现整套RAG流程
开发语言·后端·golang
成都第一深情IZZO7 小时前
事务未提交就发送 MQ,导致消费者读不到订单数据的问题
后端
大橙子打游戏8 小时前
Fable5不能用了,但是依然能让 AI 纯靠截图玩通宝可梦
后端
Jason_chen8 小时前
Linux 3.0 总线机制与故障排查详解
后端
成都第一深情IZZO8 小时前
Spring Boot 动态数据源在事务中切库失效问题排查
后端