作为开发者,我们许多人都曾面临为程序引入图形界面的挑战。传统的 GUI 库会增加一定程度的复杂性,如果您正在制作用于各种任务(例如调试)的工具,可能并不希望引入这种复杂性。在这里,我们介绍一个库,它可以让您快速轻松地创建日志记录器性能分析器调试器,甚至整个游戏制作编辑器。这里提供的完整示例可在 Github 上获取。

更新 2023-05-18:更新文章以适应 Conan 2.0

我们已更新此博文中代码和说明,使其与 Conan 2.0 兼容。如果您尚未从 1.X 版本更新,请查看Conan 2.0 文档迁移指南

Dear ImGui?

Dear ImGui 是一个出色的 C++ GUI 库,主要用于游戏开发。该项目是开源软件,根据 MIT 许可证授权。Dear ImGui 侧重于使用所谓的立即模式 GUI 范式来实现简单性和生产力。

立即模式 GUI 与传统的保留模式界面不同,后者是在每一帧创建和绘制小部件,而传统方法则是先创建小部件,然后向其添加回调函数。这种范式的优势之一是您的 UI“更接近”您的数据,并且它允许快速原型设计。

Dear ImGui 主要设计用于开发者在内容创建和调试工具中使用。它在渲染器方面是不可知的,这意味着您必须提供渲染数据的工具,但它非常容易集成到您自己的代码中,因为它有多个绑定可用于不同的窗口和事件处理库(如GLFWSDL2 和 GLUT)以及多个渲染器(如 OpenGL、DirectX 和Vulkan)。

Dear ImGui 带有许多小部件,例如窗口、标签、输入框、进度条、按钮、滑块、树等。您可以在下面的图像中看到一些示例。

Different Dear ImGui widgets

在您的应用程序中集成 Dear ImGui

ImGui 的典型用法是在您已经有 3D 管线启用应用程序(例如内容创建或游戏开发工具)的情况下,希望添加 GUI。让我们看看在我们的应用程序中集成 ImGui 有多容易。我们的示例应用程序使用 OpenGL3 渲染三角形。我们将使用 GLFW 来管理窗口创建和事件处理。由于 ImGui 独立于渲染系统和平台,因此我们必须为我们的渲染系统引入一些绑定。幸运的是,Dear ImGui 的存储库中有很多预制的绑定。由于我们将使用 Dear ImGui v1.89,因此我们需要以下文件:

使此代码正常工作的最小代码位于main.cpp中。首先,您初始化用于渲染的窗口,然后必须初始化 Dear ImGui 上下文以及辅助平台和渲染器绑定。您也可以根据需要更改渲染样式。

// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO &io = ImGui::GetIO();
// Setup Platform/Renderer bindings
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glsl_version);
// Setup Dear ImGui style
ImGui::StyleColorsDark();

然后,您进入主应用程序循环,在这里您可以清楚地看到与经典的保留模式 GUI 的区别。

while (!glfwWindowShouldClose(window))
{
    glfwPollEvents();
    glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
    glClear(GL_COLOR_BUFFER_BIT);

    // feed inputs to dear imgui, start new frame
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    // rendering our geometries
    triangle_shader.use();
    glBindVertexArray(vao);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

    // render your GUI
    ImGui::Begin("Demo window");
    ImGui::Button("Hello!");
    ImGui::End();

    // Render dear imgui into screen
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    int display_w, display_h;
    glfwGetFramebufferSize(window, &display_w, &display_h);
    glViewport(0, 0, display_w, display_h);
    glfwSwapBuffers(window);
}

并且,当循环结束时,我们必须进行一些清理工作。

ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();

所以,这就是我们得到的结果

ImGui Hello World

例如,假设我们想要更改三角形的位置/方向和颜色。这将非常简单,只需调用一些滑块和颜色选择器,并将数据通过着色器 uniform 传递给三角形即可。

// render your GUI
ImGui::Begin("Triangle Position/Color");
static float rotation = 0.0;
ImGui::SliderFloat("rotation", &rotation, 0, 2 * PI);
static float translation[] = {0.0, 0.0};
ImGui::SliderFloat2("position", translation, -1.0, 1.0);
static float color[4] = { 1.0f,1.0f,1.0f,1.0f };
// pass the parameters to the shader
triangle_shader.setUniform("rotation", rotation);
triangle_shader.setUniform("translation", translation[0], translation[1]);
// color picker
ImGui::ColorEdit3("color", color);
// multiply triangle's color with this color
triangle_shader.setUniform("color", color[0], color[1], color[2]);

Change triangle's color

也有一些基本的绘图工具。

Render Conan logo

如果您想探索不同的库小部件和选项,最好的方法是调用ImGui::ShowDemoWindow()并查看不同的示例。

使用 Conan 设置项目

使用 Conan 设置使用 ImGui 的项目只需几分钟。Conan 中已经创建了一个用于 ImGui 的 Conan 包并将其添加到 Conan-Center。此处显示的示例使用的是 Windows 和 Visual Studio 2022,但在 MacOS 或 Linux 上也十分类似。

如果您想尝试一下,可以从 Conan 示例存储库下载所有文件。

git clone https://github.com/conan-io/examples2.git
cd examples2/examples/libraries/imgui/introduction/

首先,让我们检查 CMake 项目。它包含 GLFW 和 OpenGL3 的绑定,以及两个用于处理 OpenGL 着色器和文件读取的文件。它还将在每次应用程序重新编译时将渲染三角形的着色器复制到工作目录。

cmake_minimum_required(VERSION 3.15)
project(dear-imgui-conan CXX)

find_package(imgui REQUIRED)
find_package(glfw3 REQUIRED)
find_package(glew REQUIRED)

add_executable( dear-imgui-conan
                main.cpp
                opengl_shader.cpp
                file_manager.cpp
                opengl_shader.h
                file_manager.h
                bindings/imgui_impl_glfw.cpp
                bindings/imgui_impl_glfw.h
                bindings/imgui_impl_opengl3.cpp
                bindings/imgui_impl_opengl3.h
                bindings/imgui_impl_opengl3_loader.h
                assets/simple-shader.vs
                assets/simple-shader.fs )

add_custom_command(TARGET dear-imgui-conan
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/assets/simple-shader.vs ${PROJECT_BINARY_DIR}
    COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/assets/simple-shader.fs ${PROJECT_BINARY_DIR}
)

target_compile_definitions(dear-imgui-conan PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLEW)
target_link_libraries(dear-imgui-conan imgui::imgui GLEW::GLEW glfw)

为了使 Conan 安装库并生成构建项目所需的文件,我们创建了一个conanfile.py,其中声明了项目的依赖项。除了我们之前讨论过的 GLFW 库之外,我们还需要 GLEW 库来处理 OpenGL 函数加载。我们将使用CMakeDeps生成 CMake 的配置文件,并使用CMakeToolchain生成构建系统所需的所有信息。我们还在generate()方法中复制了 GLFW 和 OpenGL3 的必要绑定。此外,请注意,我们声明了项目的layout()cmake_layout,因为我们正在使用 CMake 进行构建。您可以查看 Conan 文档的使用包教程部分以了解更多信息。

import os

from conan import ConanFile
from conan.tools.cmake import cmake_layout
from conan.tools.files import copy


class ImGuiExample(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    generators = "CMakeDeps", "CMakeToolchain"

    def requirements(self):
        self.requires("imgui/1.89.4")
        self.requires("glfw/3.3.8")
        self.requires("glew/2.2.0")

    def generate(self):
        copy(self, "*glfw*", os.path.join(self.dependencies["imgui"].package_folder,
            "res", "bindings"), os.path.join(self.source_folder, "bindings"))
        copy(self, "*opengl3*", os.path.join(self.dependencies["imgui"].package_folder,
            "res", "bindings"), os.path.join(self.source_folder, "bindings"))

    def layout(self):
        cmake_layout(self)

现在我们可以使用 Conan 来安装库。它不仅会安装imguiglfwglew,还会安装所有必要的传递依赖项。Conan 从默认的ConanCenter远程存储库(开源 Conan 包的官方存储库)获取这些包。如果您的配置没有可用的二进制文件,则也可以从源代码构建。

conan install . --build=missing

使用conan install命令,我们将在本地安装所有必要的包,并生成构建应用程序所需的文件。请注意,我们使用了--build=missing参数,以防远程存储库中没有某些二进制文件。此外,如果您正在运行 Linux,并且系统上缺少某些必要的系统库,则可能需要将-c tools.system.package_manager:mode=install-c tools.system.package_manager:sudo=True参数添加到命令行中(文档参考)。

现在让我们构建项目并运行应用程序。如果您安装了 CMake>=3.23,则可以使用 CMake 预设。

# Linux, macOS
cmake --preset conan-release
cmake --build --preset conan-release
cd build/Release
./dear-imgui-conan 

# Windows
cmake --preset conan-default
cmake --build --preset conan-release
cd build\Release
.\dear-imgui-conan.exe 

否则,您可以为 CMake 添加必要的参数。

# Linux, macOS
cmake . -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=build/Release/generators/conan_toolchain.cmake -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release
cmake --build .
./dear-imgui-conan

# Windows. Assuming Visual Studio 17 2022 
# is your VS version and that it matches 
# your default profile
cmake . -G "Visual Studio 17 2022"
-DCMAKE_TOOLCHAIN_FILE=./build/generators/conan_toolchain.cmake
-DCMAKE_POLICY_DEFAULT_CMP0091=NEW
cmake --build . --config Release
.\dear-imgui-conan.exe

结论

Dear ImGui 是一个功能强大的库,它具有易于使用的 API,可以几乎无缝地集成到启用了 3D 管线的应用程序中。它包含各种小部件,可以成为制作调试软件(例如性能分析器、日志记录器或任何类型的对象编辑器)的强大工具。此外,诸如停靠多个视口等额外功能正在项目的停靠分支中积极开发。该分支的包也已在 ConanCenter 中提供

所以,还在等什么?深入了解,尝试使用 Dear ImGui,看看它如何与您自己的代码结合使用!