imgui

wingstone

2022/06/21

阅读量

目录

记录关于imgui的设计思想总结,关于imgui更全面的介绍,imgui的wiki囊括了非常全面的文档介绍,可以进一步学习;

what is imgui

imgui的定义从wiki上来看,还未完全定形,甚至有很多因名字而被人误解的点,这里列举一些imgui所真正关心的要点:

个人认为:最小化application持有与ui system相关的数据,意味着application不需要持有来自ui system的组件,从而使得application所持有的数据减少; 最小化ui system持有与application相关的数据,意味着ui system的显示不需要存储application data的拷贝,只持有与ui system显示状态相关的数据;

与imgui所对应的为rmgui(retained-mode UI),rmgui的特点为:

difference between imgui and rmgui

关于imgui与rmgui的区别,可以查看Immediate Mode Graphical User InterfacesImmediate Mode Graphical User Interface (IMGUI)

这里贴出里面rmgui与imgui的代码样例:

 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
// rmgui
WidgetSet* ws;
const unsigned int ID_BUTTON = 1;
const unsigned int ID_SLIDER = 2;
float my_float = 0.5f;

void init()
{
    ws = new WidgetSet();
    ws->add(create_button(ID_BUTTON, "Click me", ...));
    ws->add(create_slider_float(ID_SLIDER, "Slide me", 0.f, 1.f, ...));
    ws->set_float_value(ID_SLIDER, my_float);
    ws->set_callback(&callback_ws);
}
void callback_ws(int widget_id)
{
    switch(widget_id)
    {
        case ID_BUTTON: do_action(); break;
        case ID_SLIDER: my_float = ws->get_float_value(ID_SLIDER);
        break;
    }
}
void main()
{
    init();
    while(running)
        ws->draw();
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// imgui
void draw_gui(struct GUIState_t* state, float* my_float)
{
    if (do_button(state, "Click me", ))
    do_action();
    do_slider_float(state, "Slide me", my_float, 0.f, 1.f, );
}
void main()
{
    GUIState_t* state;
    float my_float = 0.5f;
    while(running)
    {
        update(state, ...);
        draw_gui(state, &my_float);
    }
}

能明显感受到两者使用上的区别,rmgui本身控制ui的交互逻辑,用户需要在初始化时设置必要的信息以及交互触发的函数,因此rmgui持有大量的数据;

而对于imgui,由用户来直接控制ui的交互逻辑,使用上更符合人的直觉,且由用户来持有必要的数据,不必由ui来持有,从而避免不必要的数据同步;另外imgui本身没有组件化的概念,因此用户不需要持有相应组件;

从文章的实现来看,imgui的实现非常轻量且简单,使得用户不会有太重的包袱;

imgui真的就完美无缺,rmgui真的就一无是处么?在文章Why I think Immediate Mode GUI is way to go for GameDev toolsWhy Qt and not IMGUI,有人从使用及应用层面上给出了更好了的理解,总结来说有以下几点:

个人认为:除了imgui所带来的性能问题,其他的各种支持、特性、工具的问题并不是imgui模式本身所带来的的,而是实际上的imgui库开发者应该解决的问题;

construct imgui library

在文章Immediate Mode Graphical User InterfacesIMGUI中有详细的思路来构建imgui库;想要开发自己的imgui的库可以进行参考;

当然,更全面的办法是直接阅读现有imgui库的源码,比如Dear ImGui以及Nuklear;

实际上,这两种库提供的都是更为基础的ui功能,这也是前面所提的imgui功能不强大原因;因此在实际需求中,需要在imgui上来构建更加强大的功能;文章One Draw Call UI记录了如何在imgui上层使用rmgui来实现docking system;