当前位置: 首页 > article >正文

【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(glfwGIT_REPOSITORY https://github.com/glfw/glfwGIT_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(imguiGIT_REPOSITORY https://github.com/ocornut/imguiGIT_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);// 初始化 ImGuiIMGUI_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的强大功能。祝你学习愉快!

相关文章:

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

如果你是GUI开发的新手&#xff0c;或想试试轻量级、易集成的GUI库&#xff0c;ImGui&#xff08;即时模式图形用户界面&#xff09;是个不错的选择。它以简洁的API、跨平台的兼容性和卓越的性能&#xff0c;受到许多开发者的喜爱。无论是为C项目添加调试界面&#xff0c;还是构…...

5G学习笔记之BWP

我们只会经历一种人生&#xff0c;我们选择的人生。 参考&#xff1a;《5G NR标准》、《5G无线系统指南:如微见著&#xff0c;赋能数字化时代》 目录 1. 概述2. BWP频域位置3. 初始与专用BWP4. 默认BWP5. 切换BWP 1. 概述 在LTE的设计中&#xff0c;默认所有终端均能处理最大2…...

1. 搭建前端+后端开发框架

1. 说明 本篇博客主要介绍网页开发中&#xff0c;搭建前端和后端开发框架的具体步骤&#xff0c;框架中所使用的技术栈如下&#xff1a; 前端&#xff1a;VUE Javascript 后端&#xff1a;Python Flask Mysql 其中MySQL主要用来存储需要的数据&#xff0c;在本文中搭建基本…...

深入浅出:插入排序算法完全解析

1. 什么是插入排序&#xff1f; 插入排序&#xff08;Insertion Sort&#xff09;是一种简单的排序算法&#xff0c;其基本思想与我们整理扑克牌的方式非常相似。我们将扑克牌从第二张开始依次与前面已排序的牌进行比较&#xff0c;将其插入到合适的位置&#xff0c;直到所有牌…...

(十一)基于vue3+mapbox-GL实现模拟高德实时导航轨迹播放

要在 Vue 3 项目中结合 Mapbox GL 实现类似高德地图的实时导航轨迹功能,您可以按照以下步骤进行: 安装依赖: 首先,安装 mapbox-gl 和 @turf/turf 这两个必要的库: npm install mapbox-gl @turf/turf引入 Mapbox GL: 在组件中引入 mapbox-gl 并初始化地图实例: <templ…...

DeepSeek到TinyLSTM的知识蒸馏

一、架构设计与适配 模型结构对比&#xff1a; DeepSeek&#xff08;教师模型&#xff09;&#xff1a;基于Transformer&#xff0c;多头自注意力机制&#xff0c;层数≥12&#xff0c;隐藏层维度≥768TinyLSTM&#xff08;学生模型&#xff09;&#xff1a;单层双向LSTM&#…...

【Transformer模型学习】第三篇:位置编码

文章目录 0. 前言1. 为什么需要位置编码&#xff1f;2. 如何进行位置编码&#xff1f;3. 正弦和余弦位置编码4. 举个例子4.1 参数设置4.2 计算分母项4.3 计算位置编码4.4 位置编码矩阵 5. 相对位置信息6. 改进的位置编码方式——RoPE6.1 RoPE的核心思想6.2 RoPE的优势 7. 总结 …...

微信小程序自定义导航栏实现指南

文章目录 微信小程序自定义导航栏实现指南一、自定义导航栏的需求分析二、代码实现1. WXML 结构2. WXSS 样式样式解析:3. JavaScript 逻辑三、完整代码示例四、注意事项与优化建议五、总结微信小程序自定义导航栏实现指南 在微信小程序开发中,默认的导航栏样式可能无法满足所…...

(十 六)趣学设计模式 之 责任链模式!

目录 一、 啥是责任链模式&#xff1f;二、 为什么要用责任链模式&#xff1f;三、 责任链模式的实现方式四、 责任链模式的优缺点五、 责任链模式的应用场景六、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&#xff0c;…...

20250225-代码笔记03-class CVRPModel AND other class

文章目录 前言一、class CVRPModel(nn.Module):__init__(self, **model_params)函数功能函数代码 二、class CVRPModel(nn.Module):pre_forward(self, reset_state)函数功能函数代码 三、class CVRPModel(nn.Module):forward(self, state)函数功能函数代码 四、def _get_encodi…...

面试常问的压力测试问题

性能测试作为软件开发中的关键环节&#xff0c;确保系统在高负载下仍能高效运行。压力测试作为性能测试的重要类型&#xff0c;旨在通过施加超出正常负载的压力&#xff0c;观察系统在极端条件下的表现。面试中&#xff0c;相关问题常被问及&#xff0c;包括定义、重要性、与负…...

Python——365天学习规划

文章目录 1. 第一阶段&#xff1a;Python基础&#xff08;Day 1-60&#xff09; 1.1 Week 1-2&#xff1a;基础语法 1.1.1 Day 1-3&#xff1a;变量、数据类型、运算符、输入输出 1.1.2 Day 4-7&#xff1a;条件语句&#xff08;if-elif-else&#xff09; 1.1.3 Day 8-14&…...

河南理工XCPC萌新选拔赛

A 树之荣荣 青梅熙熙 树之荣荣 青梅熙熙 这个题是一个经典的博弈问题。我们可以考虑一种情况&#xff0c;就是你每一次都会取一个。那么最后一个你肯定不能取。所以我们可以考虑减去一个后的值。判断它的和是奇数还是偶数即可。 int n; cin >> n;int s 0;for (int i 1;…...

设计模式|策略模式 Strategy Pattern 详解

目录 一、策略模式概述二、策略模式的实现2.1 策略接口2.2 具体策略类2.3 上下文类2.4 客户端代码2.5 UML类图2.6 UML时序图 三、优缺点3.1 ✅优点3.2 ❌ 缺点 四、最佳实践场景4.1 适合场景描述4.2 具体场景 五、扩展5.1 继承复用机制和复合策略5.2 对象管理&#xff1a;优化策…...

Wireshark 插件开发实战指南

Wireshark 插件开发实战指南 环境搭建流程图 #mermaid-svg-XpNibno7BIyfzNn5 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XpNibno7BIyfzNn5 .error-icon{fill:#552222;}#mermaid-svg-XpNibno7BIyfzNn5 .error-t…...

使用Java构建高效的Web服务架构

使用Java构建高效的Web服务架构 随着互联网技术的飞速发展&#xff0c;Web服务在现代应用中扮演着至关重要的角色。尤其是在企业级应用中&#xff0c;如何构建一个高效、可扩展且易维护的Web服务架构&#xff0c;成为了开发者和架构师面临的一项重要挑战。Java作为一种成熟、稳…...

《Python实战进阶》No 10:基于Flask案例的Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻击

第10集&#xff1a;Web 安全性&#xff1a;防止 SQL 注入、XSS 和 CSRF 攻击 在现代 Web 开发中&#xff0c;安全性是至关重要的。无论是用户数据的保护&#xff0c;还是系统稳定性的维护&#xff0c;开发者都需要对常见的 Web 安全威胁有深刻的理解&#xff0c;并采取有效的防…...

蓝桥备赛(六)- C/C++输入输出

一、OJ题目输入情况汇总 OJ&#xff08;online judge&#xff09; 接下来会有例题 &#xff0c; 根据一下题目 &#xff0c; 对这些情况进行分析 1.1 单组测试用例 单在 --> 程序运行一次 &#xff0c; 就处理一组 练习一&#xff1a;计算 (ab)/c 的值 B2009 计算 (ab)/c …...

企微审批中MySQL字段TEXT类型被截断的排查与修复实践

在MySQL中&#xff0c;TEXT类型字段常用于存储较大的文本数据&#xff0c;但在一些应用场景中&#xff0c;当文本内容较大时&#xff0c;TEXT类型字段可能无法满足需求&#xff0c;导致数据截断或插入失败。为了避免这种问题&#xff0c;了解不同文本类型&#xff08;如TEXT、M…...

[ISP] AE 自动曝光

相机通过不同曝光参数&#xff08;档位快门时间 x 感光度 x 光圈大小&#xff09;控制进光量来完成恰当的曝光。 自动曝光流程大概分为三部分&#xff1a; 1. 测光&#xff1a;点测光、中心测光、全局测光等&#xff1b;通过调整曝光档位使sensor曝光在合理的阈值内&#xff0…...

小程序画带圆角的圆形进度条

老的API <canvas id"{{canvasId}}" canvas-id"{{canvasId}}" style"opacity: 0;" class"canvas"/> startDraw() {const { canvasId } this.dataconst query this.createSelectorQuery()query.select(#${canvasId}).bounding…...

16. LangChain实战项目2——易速鲜花内部问答系统

需求简介 易束鲜花企业内部知识库如下&#xff1a; 本实战项目设计一个内部问答系统&#xff0c;基于这些内部知识&#xff0c;回答内部员工的提问。 在前面课程的基础上&#xff0c;需要安装的依赖包如下&#xff1a; pip install docx2txt pip install qdrant-client pip i…...

代码的解读——自用

代码来自&#xff1a;https://github.com/ChuHan89/WSSS-Tissue?tabreadme-ov-file 借助了一些人工智能 run_pipeline.sh 功能总结 该脚本用于执行一个 弱监督语义分割&#xff08;WSSS&#xff09; 的完整流程&#xff0c;包含三个阶段&#xff1a; Stage1&#xff1a;训…...

蓝桥杯试题:DFS回溯

一、题目要求 输入一个数组n&#xff0c;输出1到n的全排列 二、代码展示 import java.util.*;public class ikun {static List<List<Integer>> list new ArrayList<>();public static void main(String[] args) { Scanner sc new Scanner(System.in);…...

FPGA开发,使用Deepseek V3还是R1(8):FPGA的全流程(简略版)

以下都是Deepseek生成的答案 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;1&#xff09;&#xff1a;应用场景 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;2&#xff09;&#xff1a;V3和R1的区别 FPGA开发&#xff0c;使用Deepseek V3还是R1&#x…...

一个py文件搞定mysql查询+Json转换+表数据提取+根据数据条件生成excel文件+打包运行一条龙

import os import argparse import pymssql import json import pandas as pd from datetime import datetime from pandas.io.formats.excel import ExcelFormatter import openpyxl# 投注类型映射字典 BET_MAPPING {1: WIN, 2: PLA, 3: QIN, 4: QPL,5: DBL, 6: TCE, 7: QTT,…...

微服务学习(1):RabbitMQ的安装与简单应用

目录 RabbitMQ是什么 为什么要使用RabbitMQ RabbitMQ的安装 RabbitMQ架构及其对应概念 队列的主要作用 交换机的主要作用 RabbitMQ的应用 通过控制面板操作&#xff08;实现收发消息&#xff09; RabbitMQ是什么 RabbitMQ是一个开源的消息队列软件&#xff08;消息代理…...

【RAG】Embeding 和 Rerank学习笔记

Q: 现在主流Embeding模型架构 在RAG&#xff08;Retrieval-Augmented Generation&#xff09;系统中&#xff0c;嵌入模型&#xff08;Embedding Model&#xff09; 是检索阶段的核心组件&#xff0c;负责将查询&#xff08;Query&#xff09;和文档&#xff08;Document&#…...

【Delphi】如何解决使用webView2时主界面置顶,而导致网页选择文件对话框被覆盖问题

一、问题描述&#xff1a; 在Delphi 中使用WebView2控件&#xff0c;如果预先把主界面置顶&#xff08;Self.FormStyle : fsStayOnTop;&#xff09;&#xff0c;此时&#xff0c;如果在Web页面中有使用&#xff08;<input type"file" id"fileInput" acc…...

【量化金融自学笔记】--开篇.基本术语及学习路径建议

在当今这个信息爆炸的时代&#xff0c;金融领域正经历着一场前所未有的变革。传统的金融分析方法逐渐被更加科学、精准的量化技术所取代。量化金融&#xff0c;这个曾经高不可攀的领域&#xff0c;如今正逐渐走进大众的视野。它将数学、统计学、计算机科学与金融学深度融合&…...