ImGui从入门到精通

发布时间:2023-05-18

一、ImGui简介

ImGui是一种用于创建用户界面的C++库。它具有极低的性能开销,因此可用于需要GUI的游戏、应用程序和工具。 ImGui库由Ocornut维护,已在GitHub上开源。 ImGui的主要特点:

  1. ImGui非常快速,这使得在实时应用程序中使用它成为了一个很好的选择,比如游戏开发。
  2. 使用ImGui的代码量很小,易于理解,不需要太多的抽象概念。
  3. ImGui与任何可编译的C++框架(比如SDL、OpenGL、DirectX)兼容。

二、ImGui的基本用法

在您的代码中使用ImGui主要包含三个步骤:

  1. 在应用程序初始化时,调用初始化函数ImGui::CreateContext()创建一个上下文。
ImGui::CreateContext();
  1. 在每一帧的开始时,开始绘制ImGui UI:
ImGui::NewFrame();
  1. 使用ImGui函数来创建UI元素,例如Button、ProgressBar或者Slider:
ImGui::Begin("Hello, world!");
ImGui::Text("This is some text.");
ImGui::End();

三、ImGui的基本元素

  1. 窗口(Window) 打开一个基本窗口:
ImGui::Begin("My Window");
ImGui::Text("Hello, I am a window.");
ImGui::End();
  1. 文本(Text)
ImGui::Text("Bold text");
ImGui::TextColored(ImVec4(1,1,0,1), "Important stuff");
ImGui::TextDisabled("Disabled text");
ImGui::TextWrapped("This text will automatically wrap on the edge of the window.");
  1. 按钮(Button)
ImGui::Button("Click me");
if (ImGui::Button("Click me too"))
    do_something();
  1. 输入框(Input)
static char str0[128] = "hello world";
ImGui::InputText("string", str0, IM_ARRAYSIZE(str0));
  1. 滑条条目(Slider)
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);

四、ImGui高级元素

  1. 图表(Chart) ImGui::PlotLines函数用于绘制一系列的数据点到一个图表上,数据点只需要传入一个包含x和y坐标的向量。
static float values[90] = {};
ImGui::PlotLines("Line Graph", values, IM_ARRAYSIZE(values));
  1. 拖拽条(Drag)
ImGui::DragFloat("Draggable Float", &f, 0.005f);
ImGui::DragInt("Draggable Int", &i, 1);
  1. 颜色选择器(ColorPicker)
ImGui::ColorEdit3("My Color", color);
  1. 列表框(ListBox)
static const char* items[] = { "Item 1", "Item 2", "Item 3" };
static int item_current = 0;
ImGui::ListBox("listbox", &item_current, items, IM_ARRAYSIZE(items));

五、ImGui样式

ImGui允许您根据您的喜好来改变UI外观。您可以使用ImGui::GetStyle()访问当前的样式设置。您可以使用ImGui风格和ImGui中的元素进行交互,例如以下样式设置将改变按钮、颜色选择器和输入框的外观:

ImGuiStyle& style = ImGui::GetStyle();
style.Colors[ImGuiCol_Button] = ImVec4(0.40f, 0.20f, 0.05f, 1.00f);
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.50f, 0.30f, 0.05f, 1.00f);
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.60f, 0.35f, 0.05f, 1.00f);
style.Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.20f, 0.05f, 1.00f);
style.Colors[ImGuiCol_Header] = ImVec4(0.40f, 0.20f, 0.05f, 1.00f);
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.50f, 0.30f, 0.05f, 1.00f);
style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.60f, 0.35f, 0.05f, 1.00f);
style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.80f, 0.20f, 0.05f, 1.00f);
style.Colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.50f, 0.30f, 0.05f, 1.00f);

六、完整代码示例

下面的示例代码将演示创建一个简单的ImGui UI:

#include "imgui.h"
#include "imgui_impl_sdl.h"
#include "imgui_impl_opengl3.h"
#define IMGUI_IMPL_OPENGL_LOADER_GLAD
#include <glad/glad.h>
#include <SDL.h>
#include <SDL_opengl.h>
int main()
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_Window *window = SDL_CreateWindow("ImGui SDL+OpenGL3 example",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720,
        SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
    SDL_GLContext gl_context = SDL_GL_CreateContext(window);
    if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
        printf("Failed to initialize OpenGL context\n");
        return -1;
    }
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    ImGui::StyleColorsDark();
    ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
    ImGui_ImplOpenGL3_Init("#version 150");
    bool show_demo_window = true;
    while (!done) {
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            ImGui_ImplSDL2_ProcessEvent(&event);
            if (event.type == SDL_QUIT) {
                done = true;
            }
        }
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplSDL2_NewFrame(window);
        ImGui::NewFrame();
        if (show_demo_window) {
            ImGui::ShowDemoWindow(&show_demo_window);
        }
        ImGui::Render();
        SDL_GL_MakeCurrent(window, gl_context);
        glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
        glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        SDL_GL_SwapWindow(window);
    }
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplSDL2_Shutdown();
    ImGui::DestroyContext();
    SDL_GL_DeleteContext(gl_context);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}