From adfe3d79de72c9f2104d0b1858f053cb2d74a791 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 15 Feb 2021 12:17:20 +0100 Subject: [PATCH] Draft --- About-the-IMGUI-paradigm.md | 76 +++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 About-the-IMGUI-paradigm.md diff --git a/About-the-IMGUI-paradigm.md b/About-the-IMGUI-paradigm.md new file mode 100644 index 0000000..8a8b4db --- /dev/null +++ b/About-the-IMGUI-paradigm.md @@ -0,0 +1,76 @@ +### Why + +**This is an attempt at explaining what the IMGUI paradigm stands for, and what it could be**. + +Proponent of the IMGUI paradigm have noticed it was that over and over widely misunderstood. +As of Feb 2021, even the [IMGUI Wikipedia page](https://en.wikipedia.org/wiki/Immediate_mode_GUI) is completely off the mark. There are reasons for that: +- the acronym may be misleading in the first place? +- people didn't do a good job enough explaining or documentation what IMGUI means? +- they are different interpretation of what IMGUI means? +- many popular IMGUI implementation have made similar design choices, making it more confusing what is actually the soul and backbone of the IMGUI paradigm vs a set of implementation choices. +- the naming and success of "Dear ImGui" blurred the line a little bit further (should have used another name). + +### History + +The acronym IMGUI was coined by Casey Muratori in this video in 2005: +
https://www.youtube.com/watch?v=Z1qyvQsjK5Y (see also [blog](https://caseymuratori.com/blog_0001)) +
_"I’ve also seen lots of people getting into arguments about immediate-mode vs. retained-mode GUI APIs. I think this has something to do with how simple the IMGUI concept is, as it leads people to think they understand it, and then they proceed to get into heated arguments as if they actually know what they’re talking about. I rarely see this problem when I’m talking about anything even mildly complicated, like quaternions."_ +
It has been privately researched before and after. + +### Do we need a definition? + +Nowadays I am starting to believe that the term has caused more harm than benefit, +because it suggests there are two camps "IMGUI" vs "RMGUI". +The reality is there is a continuum of possibilities over multiple orthogonal axises. + +The term effectively has dumbed down the discourse. The fact that we are even trying to put an official definition to a label is dumbing down the discourse and hindering people's imagination about the many possible areas of researches to be done in UI. + +_"I kind of wish there was more radical experimentation in this space"_ [tweet](https://twitter.com/pervognsen/status/1361241939593416705) + +### Half of a definition + +@ocornut's attempt for a definition (WIP, 2021) + +- IMGUI refers to the **interface** between the app/programmer and the UI library. +- The interface tries to minimize the app/programmer having to retain data from the UI library. +- The interface tries to minimize the UI library having to retain data from the app/programmer. + +This is in comparison with typical RMGUI which: +- Often have the app/programmer to retain lots of artifacts from the UI library (references/objects) +- Often have the UI library retain app/programmer data in widgets, requiring synchronization mechanism. + +What it doesn't stands for: + +- IMGUI does not means that stuff are drawn immediately. +- IMGUI does not means that the library doesn't retain data. +- IMGUI does not means it needs a continuous loop nor need to refresh continuously. +- IMGUI does not means it needs to refresh all-or-nothing. +- IMGUI does not means state are polled. +- IMGUI does not means the UI doesn't look "native". +- IMGUI does not means it needs a GPU to render. +- IMGUI does not means limited layout feature. +- IMGUI does not means single pass flow. + +TODO: Each of those points could be explained with a paragraph. We could also describe how common UI libraries (of all types) stand on a given axis. + +### Vurtun's writeup + +[@vurtun](https://github.com/vurtun) said very eloquently around April 2019: + +_"I usually don't like to write about immediate mode UI since there are a lot of preconceived notions about them. Addressing all of them is hard since often that is required since they all are thrown at once. For example a single implementation of a concept does not define a concept (dear imgui is a immediate mode UI not all imgui are like dear imgui)._ + +_Everything that can be done with "retained" gui can by definition be done by an immdiate mode gui (I hate this whole divide at this point). Then we have state. For some reason like andrew already said I often see confusion that immediate mode means stateless. Immediate mode has nothing to do with how or if state is stored. Immediate mode in guis doesn't remove having two data representation. One on the calling side and one in the library. Even dear imgui and nuklear both have internal state they keep track of. Rather at its core immediate mode is about how this state is updated. In classical gui the state of the application was synchronized to the gui state by modification. On the other hand immediate mode is closer to functional programming. Instead of mutating state, all previous state is immutable and new state can only be generated by taking the previous state and appling new changes. Both in dear imgui and nuklear there is very little previous state and most is build up every "frame"._ + +_Next up handling widget events (press,clicked,...). Immediate mode has nothing to do with events vs polling for input changes. The famously convenient if (button(...)). You can even have retained libraries that use polling instead of events._ + +_Then we have "immediate mode bundles layouting, input and rendering". Once again only dear imgui and nuklear do this. At this point all my imguis have multiple passes. For example if I cache state for layouting I have (layout, input, render). Any change in the input or render pass will will jump back to layouting. If I don't cache state for layouting I still have two passes (input, render) to prevent glitches. To make sure that performance is not a problem I make sure that only those elements that are actually visible are updated, which is important for datastructures (list, trees). Invisible widgets are not only not rendered but also not layouted or have input handling. In a current implementation they are not even iterated over._ + +_Another argument I've read is that immediate mode cannot be used with OOP. While I try to stay away from that term since at this point it has taken so many meaning that it is basically worthless, what I hear it in context of is having composability for widgets. Once again just because dear imgui and nuklear don't have does not mean it has to be or even should be that way. For example the imgui we have at work supports composibility and just like retain mode UIs you can put any widget inside any other. Want a slider inside a tab you can just compose them (not that it makes sense in this case)._ + +_Getting to game vs. tool ui. Disclaimer: I spend most of my time on tool ui however I played around with game ui or rather the concept behind it in my immediate/retain mode hybrid (https://gist.github.com/vurtun/c5b0374c27d2f5e9905bfbe7431d9dc0)._ + +_Personally for me tool and game ui are two completley different use cases. Interestingly at work we actually have a single immediate mode core that is used for both game as well as tool ui and it still works. However our advantage is that our UI designer can code. Immediate mode biggest advantage is that state mutation is extremely simple and easy. However in games all UI (including stuff like animations) outside datastructures likes list are know at compile time or loading time. So most advantages of immediate mode doesn't hold up (outside mentioned datastructures). Interestingly for datastructes you can even have an immediate mode API inside a retained state UI. So having the best of both worlds by having a hybrid._ + +_Finally state handling. For games this is easier since most state is known beforehand and can be reserved/preallocated. For tool ui it is a bit more complicated. First of it is possible to have state per widget. That is what we currently do at keen core. The state itself is lifetime tracked and freed if not used anymore. However what is actually possible as well is having a concept of an window/view and managing state outside the library. By that I mean a tabbed window with content. Like for example a log view or scene view storing all needed state for the UI and the actually data needed (log entries for the log view). Instead of trying to do state handling on the widget level it makes a lot more sense to have state management inside the view itself, since unlike the actually widgets the view itself has an easy to track lifetime. Just to clarify the view in the library API would just an handle while the actual view implementation would store the state._ + +_A lot in ui depends on the problem on hand so I feel there is no silver bullet. But what is actually great about UI is that it is possible to write a version fitting the problem. I hope if anything is taken from this rant is that "imgui" currently entangles a lot of concepts that however don't define it. So everytime it does not work out immediate mode as a grand concept itself is tossed aside instead of reevaluating the parts that did not work out."_