This is in opposition from retained-mode, where things are re-rendered only when necessary, like in Win32/Cocoa or the HTML DOM. With those, you need to keep an object in memory.
The nature of the job is what allows for very simple procedure calls that looks almost declarative. Here's an example (it's Unity3D btw):
GUI.Label (new Rect (25, 25, 100, 30), "Label");
if (GUI.Button (new Rect (25, 25, 100, 30), "Button")) {
// This code is executed when the Button is clicked
}That makes no sense though because while you still need to re-render each frame, you do not necessarily have to waste rendering time on GUI each frame when GUIs are mostly static, why not just render the interface to a framebuffer and then simply draw that when composing a frame and only re-draw the framebuffer when the GUI changed/played an animation frame?
In games ImGUI is usually used for debugging purposes and I don't think in that usage you have many frames where nothing would change (e.g. if you are looking at scene-graph nodes their properties will probably constantly change due to things like idle animations, camera movements, scripting, ...)
https://www.glfw.org/docs/latest/group__window.html#ga554e37...
Perhaps in low-power situations it's a different story, though.
Some games did that in the past, and some might still do it!
But keep in mind that today the performance gains are so negligible when compared to the rest of the things you have to render on a single frame that the added complexity and the amount of things that could go wrong (glitches) are normally not worth it.
Also, copying that temporary framebuffer to the screen on each frame is not free and involves copying between two memory locations, whereas procedurally drawing things only involves CPU (or GPU) + the main framebuffer, which is super fast in comparison.
Also, battery life/power usage is an important factor that can push you away from focusing only on consistency.
I’ve seen 8 fps marquees that looked smooth as silk the frame rate SD was so low. It’s amazing what the brain and eye tracking will do to make things look right.
Updating every frame also solves the issue of the GUI updates not being synchronized with screen refreshes (v-sync). You could do something like use event driven programming to draw the GUI to a buffer off screen, and layer that on top of the main render. But that's probably about as intensive as drawing the UI, and more memory intensive.
This isn't quite correct, at least for the library internals. Dear ImGui does persist UI state between frames, the "immediate mode" term only describes how the API looks like to the user, not how the library behind the API is implemented. The user code doesn't need to keep "widget handles" around, and there is no "event handler code" that is called asynchronously. From the user's point of view, control flow is entirely sequential, the UI is described and input events are processed in the same linear control flow context. But this is just what the library user sees, what happens under the hood is very different (e.g. the internal UI state is not rebuilt every frame from scratch, instead the API calls cause changes to the internal UI representation, those API calls just happen to also contain all the information needed to create the required internal UI state if it doesn't exist yet).
There's also nothing preventing the library from only redrawing what has changed, it just turned out that redrawing everything is usually so fast that only drawing what has changed would just add complexity to the implementation for very little gain (even complex ImGui UIs are usually a few dozen drawcalls at most and don't take up any significant chunk of the per-frame budget).
This description may be simplified and in details also slightly incorrect, but it's important to point out that "immediate mode" only applies to the API, not to the implementation, because this argument is often brought up by critics (who often don't quite understand what the "immediate" in "immediate mode UIs" is actually about) as a reason why immediate mode UIs can never be as efficient as traditional "retained mode" UIs (in reality they usually are more efficient than traditional UIs, and situations where traditional UIs are ahead can be optimized in immediate mode UIs just as well).
There's actually a lot more in common between React and ImGUI than you might think, in terms of "state reconciliation". The difference is that React is diffing to apply itself to a retained model, while ImGUI retains the state behind your back.
All state you need to keep track of is purely the input state: e.g. whether a button is pressed, keys are pressed, etc. And very importantly, you also need to store the edges of the input signal. That is, you need to store whether left mouse has changed from not pressed to pressed this frame, and whether it has changed from pressed to not pressed.
Then, the Button(...) call computes the hitbox of the button, checks whether the left mouse button has changed from 'not pressed' to 'pressed' this frame, and if yes, whether the mouse coordinates are inside the hitbox. If yes, it returns True, else it returns False.
No widget state needs to be kept.
If you think this is obscure, try implementing a slider widget any other way. You need a way to keep track of which slider you were dragging, even when the mouse cursor leaves to another.
The only thing I need to make explicit is that you store the mouse coordinates of each event type with that event, for later retrieval. E.g. `events['mouse_down_edge']` stores a tuple `(frame_nr, coords)`.
Then you know that we are dragging this slider if the mouse is held down, and its initial down edge in the signal was generated while hovering over this slider.
---
For what it's worth, I know that (some parts of) dear ImGUI are not implemented in the above way, and instead do keep track of some widget state with labels and unique ids. People however heavily overestimate to what extent this is necessary.
Other immediate mode UIs may decide to delegate this "state housekeeping" to the user (that's how rxi's microui works), but IMHO this isn't quite as convenient for the library user, it keeps the library implementation very simple though.
This is correct. Windows (which includes things like popups and dialogs) have "state behind your back", but widgets generally don't - at least I've never seen it in the code. 99 % of the examples given by other commenters are not handled by hidden widget state, but by g.activeID. As someone pointed out, changing IDs in the middle of an interaction is problematic for that reason (not because imgui fails to find the widget in its hidden tree of widgets, which doesn't exist).
The basic approach certainly existed far earlier, though. Early "graphical" command line applications, for example, most likely all took an immediate mode approach. It's just that no one thought it was worth making the distinction until after living through the hell that is retained mode GUI programming.
In a way, React (along with other vdom-based GUI frameworks) is another rediscovery of immediate mode GUI techniques, but with more of a functional (reactive) programming influence.
"A common misunderstanding is to mistake immediate mode gui for immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes as the gui functions are called. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely."
This is cool, I had that misunderstanding myself (immediate mode vs immediate rendering)
From the linked readme: “DearPyGui provides a wrapping of DearImGui that provides a hybrid of a traditional retained mode GUI and Dear ImGui's immediate mode paradigm.”