LearnGL – 09 – Include IMGUI – Dear ImGui – 添加Dashboard、Debugging Panel

文章目录

  • Dashboard - 仪表板
    • Code
    • ContextMenu - 上下文菜单/右键菜单
  • Debugging Panel - 调试面板
    • Shortcuts - 快捷键
    • Informations - 其他信息
  • Time - 时间相关的
  • Draw State - 绘制状态
  • Camera - 相机
    • Reset - 重置
    • Enabled Camera Control - 启用相机控制
    • Transform - 变换
    • Code
  • References

LearnGL - 学习笔记目录

本人才疏学浅,如有什么错误,望不吝指出。

上些篇:

  • LearnGL - 08.1 - Camera - GLM 版,了解OpenGL 的一些几何变换,其中包含了摄像机的封装。

这一篇:将引入开源库 Dear ImGui,来方便后续的调试工作。


在学习 OpenGL 过程,免不了需要有一些 GUI 来方便数据调试。

我之前取搜索过,发现 Dear ImGui 在制作 2D GUI 非常的适合,库小,功能强大,GUI 还很舒服,因为基本都是纯色。

如果你想了解 Dear ImGui,可以查看我之前的一篇:IMGUI 系统 - Dear ImGUI,这里不回去写 ImGui 的教程,因为内容说多不多,说少也不少(因为如果要写好一些通俗易通的教程,最好的还是录制视频,但我又不想录制视频)。

Dashboard - 仪表板

我们的 Dashboard 主要是用于显示:

  • 这次的主题是什么
  • 窗口大小是多少
  • 还有 fps,等信息的显示就好了

目前就这些内容,后续按需添加其他功能就可以了

长下面图片的样式
在这里插入图片描述

Code

代码比较简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void showDashboardWin(bool* p_open) {
    const float DISTANCE = 10.0f;
    static int corner = 0;
    ImGuiIO& io = ImGui::GetIO();
    if (corner != -1) {
        // 0 : top-left
        // 1 : top-right
        // 2 : bottom-left
        // 3 : bottom-right
        // corner & 1 ==> (top-left || bottom-right)
        // corner & 2 ==> (bottom-left || bottom-right)
        ImVec2 window_pos = ImVec2((corner & 1) ? io.DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? io.DisplaySize.y - DISTANCE : DISTANCE);
        ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
        ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
    }
    ImGui::SetNextWindowBgAlpha(0.35f);                 // 背景透明 35% 的alpha值
    ImGuiWindowFlags window_flags =
        ImGuiWindowFlags_NoDecoration |                 // 不需要标题、不需要调整大小、不需要滚动条、不需要折叠
        ImGuiWindowFlags_AlwaysAutoResize |             // 自动调整大小
        ImGuiWindowFlags_NoSavedSettings |              // 不需要保存会加载布局信息
        ImGuiWindowFlags_NoFocusOnAppearing |           // 显示时不需要获取交点
        ImGuiWindowFlags_NoNav;                         // 不需要 navigation 的操作交互
    if (corner != -1) {
        window_flags |= ImGuiWindowFlags_NoMove;        // 如果不是 -1 则不能移动
    }
    if (ImGui::Begin("jave's Dashboard", p_open, window_flags)) {
        ImGui::Text(" --- Dashboard --- ");
        ImGui::Separator();
        ImGui::Text(
            "Demo : 09_Add_GUI_System_Dear_ImGui\n"
            "Window Size : %d x %d\n"
            "(right-click to change position)",
            win_width, win_height);
        ImGui::Separator();
        ImGui::Text("FPS : %.1f (ds : %.3f ms/frame)", 1.0f / Timer::inst()->deltaTime, Timer::inst()->deltaTime * 1000);
        if (ImGui::BeginPopupContextWindow()) {
            if (ImGui::MenuItem("Custom", NULL, corner == -1)) corner = -1;
            if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0;
            if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1;
            if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2;
            if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3;
            if (p_open && ImGui::MenuItem("Close")) *p_open = false;
            ImGui::EndPopup();
        }
    }
    ImGui::End();
}

ContextMenu - 上下文菜单/右键菜单

从 Dashboard 中的 right-click to change position 文字提示,可以知道,鼠标右键可以调整位置

从代码中可以看到我们吃根据一个 corner 来判断处理的

弄个 GIF 看看:
在这里插入图片描述


Debugging Panel - 调试面板

目前长这个样子
在这里插入图片描述

Shortcuts - 快捷键

提示一些快捷键信息

  • Exiting Application(Shift+F4) ,退出程序
  • Enabled Cursor(H),是否启用鼠标/光标
    在这里插入图片描述

Informations - 其他信息

目前我是直接放到一些简单的分栏中

后面还可以自己制作一个完全的 Console 或是 Log 面板,方便输出日志记录用。
在这里插入图片描述

Time - 时间相关的

目前就:

  • ScaleTime 当前的时间缩放倍率,后续在调试一些动画效果,比较有用
  • TargetFPS 设置的期望的 FPS 更新频率
    在这里插入图片描述

Draw State - 绘制状态

目前为了代表性的添加 GUI 功能,象征性的只添加一个:Clear Color,就是 glClear 值的 ClearColor 的颜色值

在这里插入图片描述

Camera - 相机

最后是我们的相机

Reset - 重置

重置相机的设置参数,下面就是我们本身的镜头参数,之前拉远一些镜头方便其他 GUI 的效果查看
在这里插入图片描述

Enabled Camera Control - 启用相机控制

开启后(勾上复选框)后,我们就可以用鼠标的左右上下来控制相机的:Yaw、Pitch,也可以用 W, S, A, D 按键来控制相机的左右上下的平移

可以用鼠标来勾选复选框,也可以用快捷键:C,来启用或禁用相机的控制

GIF 效果如下:
在这里插入图片描述

Transform - 变换

  • Pos 相机的位置
  • Fov 全写是:Field Of View 相机的视角(Frustum 的 Top 与 Bottom 的夹角)(单位:角度)
  • Near 近截面
  • Far 远截面
  • Yaw 相机绕Y轴的旋转量
  • Pitch 相机绕X轴的旋转量
    在这里插入图片描述

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void showToolsPanel() {
    ImGui::Begin("Jave's Debugging Panel");
    if (ImGui::CollapsingHeader("Shortcuts")) {
        ImGui::Text("Exiting Application(Shift+F4)");
        ImGui::Text("Enabled Cursor(H) : %s", getEnabledCursor() ? "true" : "false");
    }
    if (ImGui::CollapsingHeader("Informations")) {
        ImGui::Text("IsAnyItemActive : %s", ImGui::IsAnyItemActive() ? "true" : "false");
        ImGui::Checkbox("ShowDashBoard", &show_dashboard);
    }
    if (ImGui::CollapsingHeader("Time")) {
        ImGui::SliderFloat("ScaleTime", &Timer::inst()->scaled, 0, 2);
        ImGui::SliderInt("TargetFPS", &targetFPS, 1, 120);
    }
    if (ImGui::CollapsingHeader("Draw State")) {
        ImGui::ColorEdit4("ClearColor", glm::value_ptr(clearCol));
    }
    if (ImGui::CollapsingHeader("Camera")) {
        if (ImGui::Button("Reset")) {                                   // 恢复相机
            memcpy(cam, backupCam, sizeof(Camera));
            memcpy(camCtrl, backupCamCtrl, sizeof(CameraController));
        }
        ImGui::Checkbox("Enabled Camera Control(C)", &enabledCamCtrl);
        ImGui::Separator();
        ImGui::Text("Transform:");
        ImGui::Separator();
        ImGui::Indent();
        //ImGui::InputFloat3("Pos", glm::value_ptr(cam->mPosition), 1); // 可以用输入条
        //ImGui::SliderFloat3("Pos", glm::value_ptr(cam->mPosition), -100.0f, 100.0f); // 也可以使用滑动条
        ImGui::DragFloat3("Pos", glm::value_ptr(cam->mPosition), 0.01f, -100.0f, 100.0f); // 可以使用拖拽条,这个体验就好,所以使用这个
        ImGui::DragFloat("Fov", &cam->mFov, 0.1f, 1.0f, 60.0f);
        ImGui::DragFloat("Near", &cam->mNear, 0.1f, 0.1f, 1000.0f);
        ImGui::DragFloat("Far", &cam->mFar, 0.1f, 0.1f, 1000.0f);
        ImGui::DragFloat("Yaw", &camCtrl->mYaw, 0.01f);
        ImGui::DragFloat("Pitch", &camCtrl->mPitch, 0.01f);
        camCtrl->updateCameraVectors();
        ImGui::Unindent();
    }
    ImGui::End();

    if (show_dashboard) {
        showDashboardWin(&show_dashboard);
    }
}

OK,就到这里吧,这个 Dear ImGui 还有很多强大的功能,后续需要的时候再使用。

如果你要制作一个 3D Engine,GUI 截面可以考虑使用 Dear ImGui,至于场景的 3D IMGUI,也是可以使用另一些开源库来实现(有现成的,真的太好了)


References

  • IMGUI 系统 - Dear ImGUI