【C++】ImGui:极简化的立即模式GUI开发

如果你是GUI开发的新手,或想试试轻量级、易集成的GUI库,ImGui(即时模式图形用户界面)是个不错的选择。它以简洁的API、跨平台的兼容性和卓越的性能,受到许多开发者的喜爱。无论是为C++项目添加调试界面,还是构建完整应用,ImGui都能满足你的需求。

本教程将从零开始,帮助你了解ImGui的基本概念,学习如何设置开发环境,理解项目结构,并通过简单的示例项目掌握其使用方法。让我们开始吧!

什么是ImGui

ImGui是一个即时模式GUI库,这意味着它不需要像传统GUI库那样维护复杂的对象层次或事件循环。相反,ImGui允许你在每一帧中直接绘制和更新界面元素,这种方式非常直观,特别适合于游戏开发、工具开发和实时应用。

ImGui的优点:

  • 轻量级:ImGui的代码库非常小,易于集成到现有项目中。
  • 高性能:ImGui的设计使其在渲染大量界面元素时仍能保持流畅。
  • 跨平台:ImGui支持Windows、macOS、Linux等多种操作系统。
  • 易于使用:ImGui的API简单直观,学习曲线平缓。
  • 高度可定制:你可以轻松地调整ImGui的样式和行为,以适应你的项目需求。

环境准备

在开始编写ImGui代码之前,你需要准备好以下开发环境和工具。请确保你已经安装了以下软件:

  • C++编译器:本教程使用MinGW(Minimalist GNU for Windows)作为编译器,但你也可以使用其他支持C++17的编译器,如Visual Studio、Clang等。
  • CMake:CMake是一个跨平台的构建工具,用于生成Makefile或项目文件,版本要求3.20或更高。
  • Git:用于下载ImGui和GLFW的源代码。
  • OpenGL:ImGui使用OpenGL进行渲染,因此你的系统需要支持OpenGL 3.0或更高版本。
  • 文本编辑器或IDE:如Visual Studio Code、CLion、Sublime Text等,用于编写和编辑代码。

提示:本教程不会提供具体安装步骤,请根据你的操作系统和偏好,自行安装和配置上述工具。

项目结构

在开始编写代码之前,了解项目的文件组织方式非常重要。我们的示例项目结构非常简单,所有文件都平铺在项目根目录下:

my_imgui_project/
├── CMakeLists.txt
├── main.cpp
└── Application.hpp
  • CMakeLists.txt:CMake配置文件,负责下载依赖库(如ImGui和GLFW)、配置编译选项和生成可执行文件。
  • main.cpp:主程序文件,包含GLFW和ImGui的初始化、主循环和清理代码。
  • Application.hpp:头文件,定义了ImGui界面的绘制逻辑。

这种平铺结构适合小型项目,易于管理和理解。

CMake配置

CMakeLists.txt是项目的核心配置文件,它告诉CMake如何构建项目。它的主要作用包括:

  • 设置CMake最低版本和项目名称。
  • 指定C++标准(本项目使用C++17)。
  • 配置编译选项(如MinGW的静态链接)。
  • 自动下载和集成GLFW和ImGui库。
  • 生成可执行文件并链接必要的库(如OpenGL)。

具体的CMakeLists.txt内容请参考项目文件,这里我们只关注其作用:它简化了项目的构建过程,让你专注于代码编写。

# 设置最低 CMake 版本要求
cmake_minimum_required(VERSION 3.20)
# 定义项目名称
project(my_imgui_project)

# 设置 C++ 标准并强制要求
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 如果使用 MinGW,启用静态链接
if(MINGW)
    add_link_options(-static -static-libgcc -static-libstdc++)
endif()

# 引入 FetchContent 模块
include(FetchContent)

# 下载并配置 GLFW(静态库)
FetchContent_Declare(
    glfw
    GIT_REPOSITORY https://github.com/glfw/glfw
    GIT_TAG 3.3.8
)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(glfw)

# 下载并配置 ImGui
FetchContent_Declare(
    imgui
    GIT_REPOSITORY https://github.com/ocornut/imgui
    GIT_TAG v1.89.9
)
FetchContent_MakeAvailable(imgui)

# 定义 ImGui 源文件并创建静态库
file(GLOB IMGUI_SOURCES
    "${imgui_SOURCE_DIR}/*.cpp"
    "${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp"
    "${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp"
)
add_library(imgui STATIC ${IMGUI_SOURCES})
target_include_directories(imgui PUBLIC ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/backends)
target_link_libraries(imgui PUBLIC glfw)

# 创建可执行文件,所有源文件平铺在根目录
add_executable(${PROJECT_NAME} WIN32 main.cpp)

# 链接库(Windows 下添加 gdi32 以确保兼容性)
target_link_libraries(${PROJECT_NAME} PRIVATE imgui glfw opengl32 $<$<PLATFORM_ID:Windows>:gdi32>)

代码解析

Application.hpp

Application.hpp是项目的头文件,负责定义ImGui界面的绘制逻辑。它被包含在main.cpp中,并在主循环中调用。

#pragma once  

#include <imgui.h>  

namespace app {  
    // Render 函数:负责绘制 ImGui 界面  
    inline void Render() {  
        // 开始一个新的 ImGui 窗口  
        ImGui::Begin("Made By Touken", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove);

        // 获取当前窗口的大小  
        ImVec2 windowSize = ImGui::GetIO().DisplaySize;  

        // 设置窗口的大小和位置  
        ImGui::SetWindowSize(windowSize);  
        ImGui::SetWindowPos(ImVec2(0, 0));  

        // 显示一段简单的文本  
        ImGui::Text("This is a minimal ImGui application.");  

        // 结束当前窗口  
        ImGui::End();  
    }  
}  

代码解析

  • #include <imgui.h>:包含ImGui的头文件,提供ImGui的核心功能。
  • namespace app:使用命名空间封装代码,避免命名冲突。
  • inline void Render():定义一个内联函数,负责绘制界面。
  • ImGui::Begin("Hello, world!"):创建一个标题为"Hello, world!"的窗口。
  • ImGui::Text(...):在窗口中显示文本。
  • ImGui::End():结束窗口的绘制。

这个文件展示了ImGui的核心思想:通过简单的函数调用快速构建界面。

main.cpp

main.cpp是项目的入口文件,负责初始化GLFW和ImGui,运行主循环,并在程序结束时清理资源。

#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <GLFW/glfw3.h>
#include "Application.hpp"

// 主函数,程序入口
int main() {
    // 初始化 GLFW 库
    if (!glfwInit()) {
        return -1; // 初始化失败则退出
    }

    // 创建一个 1280x720 的窗口
    GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui GLFW OpenGL3 Example", nullptr, nullptr);
    if (!window) {
        glfwTerminate(); // 创建失败则清理并退出
        return -1;
    }

    // 将当前窗口的 OpenGL 上下文设置为活动状态
    glfwMakeContextCurrent(window);

    // 初始化 ImGui
    IMGUI_CHECKVERSION(); // 检查 ImGui 版本
    ImGui::CreateContext(); // 创建 ImGui 上下文
    ImGuiIO& io = ImGui::GetIO(); (void)io; // 获取 IO 对象
    ImGui::StyleColorsDark(); // 设置暗色主题
    ImGui_ImplGlfw_InitForOpenGL(window, true); // 初始化 GLFW 后端
    ImGui_ImplOpenGL3_Init("#version 130"); // 初始化 OpenGL3 后端

    // 主循环,直到窗口关闭
    while (!glfwWindowShouldClose(window)) {
        // 处理 GLFW 事件(如键盘、鼠标输入)
        glfwPollEvents();

        // 开始新的一帧
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        // 调用封装的 Render 函数绘制界面
        app::Render();

        // 渲染 ImGui 内容
        ImGui::Render();
        int display_w, display_h;
        glfwGetFramebufferSize(window, &display_w, &display_h); // 获取窗口大小
        glViewport(0, 0, display_w, display_h); // 设置 OpenGL 视口
        glClearColor(0.45f, 0.55f, 0.60f, 1.00f); // 设置背景颜色
        glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); // 渲染 ImGui 数据

        // 交换前后缓冲区,显示渲染结果
        glfwSwapBuffers(window);
    }

    // 清理资源
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

代码解析

  • GLFW初始化
    • glfwInit():初始化GLFW库。
    • glfwCreateWindow():创建1280x720的窗口。
    • glfwMakeContextCurrent():激活窗口的OpenGL上下文。
  • ImGui初始化
    • ImGui::CreateContext():创建ImGui上下文。
    • ImGui::StyleColorsDark():设置暗色主题。
    • ImGui_ImplGlfw_InitForOpenGL()ImGui_ImplOpenGL3_Init():初始化GLFW和OpenGL3后端。
  • 主循环
    • glfwPollEvents():处理用户输入事件。
    • ImGui::NewFrame()等:准备新的一帧。
    • app::Render():绘制ImGui界面。
    • glClear()ImGui_ImplOpenGL3_RenderDrawData():渲染界面到屏幕。
    • glfwSwapBuffers():显示渲染结果。
  • 清理:按顺序关闭ImGui和GLFW,释放资源。

构建和运行

要构建和运行项目,请按照以下步骤操作:

  1. 打开终端,进入项目根目录。

  2. 创建build文件夹并进入:

mkdir build
cd build
  1. 使用CMake生成Makefile:
cmake -G "MinGW Makefiles" ..
  1. 编译项目:
mingw32-make
  1. 运行可执行文件:
./my_imgui_project.exe

成功运行后,你将看到一个简单的ImGui窗口,显示"Hello, world!"和一段文本。

扩展和学习

你已经完成了ImGui的入门!接下来可以尝试:

  • Render()中添加按钮、滑块等控件。
  • 修改ImGui::StyleColorsDark()为其他样式。
  • 响应用户输入,实现交互功能。
  • 查看ImGui官方文档,学习更多高级用法。

通过实践和探索,你将逐渐掌握ImGui的强大功能。祝你学习愉快!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值