记录关于imgui的设计思想总结,关于imgui更全面的介绍,imgui的wiki囊括了非常全面的文档介绍,可以进一步学习;
what is imgui
imgui的定义从wiki上来看,还未完全定形,甚至有很多因名字而被人误解的点,这里列举一些imgui所真正关心的要点:
- imgui所关心的是api接口,即在application与ui system之间的接口;
- imgui试图最小化application,其持有与ui system相关的数据;
- imgui试图最小化ui system,其持有与application相关的数据;
- imgui不关心实现,在ui system中如何实现皆可;
个人认为:最小化application持有与ui system相关的数据,意味着application不需要持有来自ui system的组件,从而使得application所持有的数据减少; 最小化ui system持有与application相关的数据,意味着ui system的显示不需要存储application data的拷贝,只持有与ui system显示状态相关的数据;
与imgui所对应的为rmgui(retained-mode UI),rmgui的特点为:
- rmgui经常需要让应用程序持有来自ui system的组件;
- rmgui经常需要同步机制,因为ui system持有大量application数据;
difference between imgui and rmgui
关于imgui与rmgui的区别,可以查看Immediate Mode Graphical User Interfaces与Immediate Mode Graphical User Interface (IMGUI);
这里贴出里面rmgui与imgui的代码样例:
|
|
|
|
能明显感受到两者使用上的区别,rmgui本身控制ui的交互逻辑,用户需要在初始化时设置必要的信息以及交互触发的函数,因此rmgui持有大量的数据;
而对于imgui,由用户来直接控制ui的交互逻辑,使用上更符合人的直觉,且由用户来持有必要的数据,不必由ui来持有,从而避免不必要的数据同步;另外imgui本身没有组件化的概念,因此用户不需要持有相应组件;
从文章的实现来看,imgui的实现非常轻量且简单,使得用户不会有太重的包袱;
imgui真的就完美无缺,rmgui真的就一无是处么?在文章Why I think Immediate Mode GUI is way to go for GameDev tools与Why Qt and not IMGUI,有人从使用及应用层面上给出了更好了的理解,总结来说有以下几点:
- imgui非常适合编写自定义控件,这些是用户将经常使用的控件,也是大型框架都会提供的基本控件;
- imgui不需要特定领域的框架知识,它使每个程序员都能有效地创建编辑器和工具来支持他们的引擎功能;
- imgui非常简单,可以被不同团队调整修改接管;
- imgui缺乏更为完善的工具链,以及更为强大但非常通用的功能(如undo/redo,copy/paste,filtering/sorting等等);
- imgui需要重新绘制整个屏幕,在非游戏领域并不是特别友好;
- imgui并没有国际化支持,在做国际化应用时有大量问题;
个人认为:除了imgui所带来的性能问题,其他的各种支持、特性、工具的问题并不是imgui模式本身所带来的的,而是实际上的imgui库开发者应该解决的问题;
construct imgui library
在文章Immediate Mode Graphical User Interfaces与IMGUI中有详细的思路来构建imgui库;想要开发自己的imgui的库可以进行参考;
当然,更全面的办法是直接阅读现有imgui库的源码,比如Dear ImGui以及Nuklear;
实际上,这两种库提供的都是更为基础的ui功能,这也是前面所提的imgui功能不强大原因;因此在实际需求中,需要在imgui上来构建更加强大的功能;文章One Draw Call UI记录了如何在imgui上层使用rmgui来实现docking system;