
Could ImGUI Be the Future of GUIs? - tokyodude
https://games.greggman.com/game/imgui-future/
======
overgard
Really probably not. I love them and they're very handy in certain situations
(debugging tools, quick UIs) but once you need a lot of customization they
become extremely cumbersome. Also really kind of makes it impossible for
designers or less technical people to do anything. Also, while I think
separating view logic is slightly overrated, it is useful, and it's very hard
to do that with IMGUI. Also it doesn't thread well. Also... Look there's like
a million downsides.

Also saying there's no memory allocation is really misleading. There's PLENTY
of memory allocation, per frame, you're just not explicitly doing it yourself.
It's actually much worse than an RMGUI in this regard, because at least with
an RMGUI you get the allocations over with once. With an IMGUI you're
allocating things all the time. They're probably much smaller allocations, but
lots of small allocations does not make for good performance.

One final note, the Unity 3D example always gets used. If you've ever written
a plugin for unity or a custom editor, you're very familiar with the fact that
it's editor gui system is extremely limiting and kind of sucks. I mean, it's
an example, but once you're past the basics it's kind of a bad example.

~~~
josephg
On the allocation point, the efficient way to handle this is to use a per-
frame memory pool. Because nothing in the IMGUI can persist between frames,
you can allocate a single arena of memory for any UI elements that need to
store bounding boxes or callbacks or whatever. Each frame just reset your
next_ptr to the start of the arena. Technically you are allocating memory, but
in practice your allocations are free.

~~~
geezerjay
Adding a separate complex ad hoc memory allocation scheme is not what I would
call free. Granted, computationally-wise it may be relatively cheap but it
does add multiple forms of complexity to a problem that doesn't exist in
rmguis.

~~~
loup-vaillant
Arenas are the simplest allocation scheme ever.

    
    
      // Start of frame
      void *arena    = malloc(LOTS_OF_MEMORY);
      void *next_ptr = arena;
    
      // Allocate something
      object   = *next_ptr;               // return that value
      next_ptr = object_size + alignment; // crash if out of memory
     
      // End of frame
      free(arena);
    

By the way, such "separate complex ad hoc" memory allocation schemes are the
reason why manual memory management is faster than garbage collection. If you
did everything with malloc(), it would be slower (unless the GC language
allocates much more than C, which they often do).

~~~
Keyframe
No need to malloc each frame. Malloc at startup and memset each frame (don't
even need to do that, tbh).

~~~
maccard
Nope, just set the pointer back to where it started from. You do need to be
super careful doing this though, as anything that relies on RAII (in c++ land)
will be busted. You could manually call the destructor on the object in that
case, but kind of defeats the purpose of the "no allocation" goals

~~~
geezerjay
C++ includes it's "placement new" feature specifically to cater to the memory
pool needs. There's no allocation, and only constructor and destructor calls.

------
yonilevy
FWIW, Unity are moving away from ImGUI (to a classic retained mode UI system)
[https://blogs.unity3d.com/2019/04/23/whats-new-with-
uielemen...](https://blogs.unity3d.com/2019/04/23/whats-new-with-uielements-
in-2019-1/)

~~~
CreepGin
Also to clarify, UIElements (Unity's new retained mode UI framework) is
available now in 2019.1 for Editor UI. Runtime UI will also be using
UIElements in the future.

------
theclaw
In the context of creating debugging UIs for games and graphics applications,
Dear imGUI is a godsend. Programmers love it because there is literally only
the code to worry about. It's very easy to get it up and running, and all the
code that handles the UI drawing and interaction is in one place so it's easy
to reason about.

It works very well in the context where you already have fast graphics and an
update loop, and you're already expecting to redraw the whole screen every
frame. It does not really suit more complex, text-heavy UIs where you're
rendering thousands of glyphs with proper kerning and ligatures and anti-
aliasing, etc, and want the result of that hard work to be retained in the
framebuffer unless it absolutely needs to change.

~~~
pedrocr
> want the result of that hard work to be retained in the framebuffer unless
> it absolutely needs to change

I think immediate mode GUI libraries can get around this issue by still
caching and reusing between frames. Conrod does this by still having the state
in the background although you are programming to an immediate mode API:

[https://docs.rs/conrod/latest/conrod/guide/chapter_1/index.h...](https://docs.rs/conrod/latest/conrod/guide/chapter_1/index.html#is-
conrod-immediate-or-retained)

~~~
sly010
That's a bit antithetical, given the other side of the debate being Retained
Mode GUIs.

That said it's a good middle ground. Use whatever API you prefer over a well
optimized implementation.

------
mindfulplay
The author does a good job explaining some benefits of an immediate mode
renderer but vastly misses the disadvantages.

The immediate mode renderer is great for toy programs. Similar to how you
could reproduce 'look here is how simple it is to write hello world and
compute the millionth digit of PI' in a new esoteric language...

Occlusion, hit-testing, state changes, scrolling/animations even in the
simplest forms will fall over. Infact, that's why we have every major browser
move their touch and animation systems into a layer based compositor system
(into a separate thread / process).

The author also grossly misses their own example of 'how a spreadsheet with
many rows and columns will update faster using ImgUI' and how Instagram styled
apps will fare better ImgUi.

A retained mode renderer will use virtual scrollers, efficient culling of
nodes for both display and hit-testing (scale to billions of virtual cells)
and more importantly help a team of people coordinate their work and get
things done.

We are no longer in the 90s.

~~~
btown
In fact, with Javascript JIT engines (whose teams deeply understand the use of
libraries like React) relentlessly attacking the overhead of DOM nodes and
their initialization, and with users who actually expect the design
flexibility provided by CSS... a system like React is actually an ideal layer
of abstraction for modern UI implementation on practically any platform.

Sure, if you're on an embedded platform, somewhere a JIT can't run, or if
you're doing something with real-time rendering requirements (and honestly
modern React Suspense should even make that feasible), you may want to use
something lower-level. But most people won't need to do this.

~~~
overgard
The DOM being slow is really more an artifact of browsers/HTML and the history
behind doing document based layout. React is a nice solution to that specific
problem; but this article suggests immediate mode gui's are the future, which,
I don't think that's really the case. And I'm not sure I'd really call React
an IMGUI anyway. It's similar, but it's also pretty different.

------
mooman219
This is really reads like someone trying to sell you something. I've done work
on frameworks for both immediate mode and retained mode GUIs. They both
absolutely allocate memory behind the scene. There absolutely is state being
marshaled around. Caching commonly used state is important. Performance can be
bad and great in both. You're really just subscribing to different sets of
opinions

~~~
TazeTSchnitzel
Any moderately complex “immediate mode” GUI system is going to do something
equivalent to constructing a “retained mode” GUI on the fly I'm guessing.

~~~
tom_
It will. In fact, even a simple one will require this. But it's not much of a
problem - 99% of the time, the UI is the same from one frame to the next, and
it isn't much work to detect this. So even if every change requires a complete
rebuild of everything, it's not much of a problem.

(I've written systems like this for Cocoa and Win32, and it never turned out
to be necessary to do anything other than just regenerate the entire UI any
time anything changed. The update runs at 30Hz or 60Hz, and when anything is
changing, the UI gets regenerated a lot! - but so what? Most of the time, the
UI doesn't get regenerated at all. Then something happens, and the code spends
2 seconds getting absolutely hammered continuously, malloc malloc malloc
malloc malloc, god help us all... and then, once again, nothing. The operator
puts their fingers to one side and stares at the result with their eyes.
Repeat.)

------
seanalltogether
I think the author is over exaggerating the problem of object creation and
destruction in traditional gui frameworks. List/collection views are designed
to reuse objects as you scroll. Secondly I think the author is also
downplaying the fact that retained GUIs can also cache object rendering. Just
as the gpu doesn't have to draw the whole screen when only the cursor is
blinking, it also doesn't have to redraw widgets unless their size changes.

Immediate vs retained is a simple case of budgeting against cpu usage or
memory usage, and it should be considered in that light. (immediate uses more
processing, retained uses more memory)

~~~
charlesetc
Thinking about this decision just as a performance one disregards the fact
that the code is substantially different. It does seems likely that one way is
more intuitive / easier to work with than the other, I wouldn't know which
though.

~~~
gmueckl
It depends on the probkem younare trying to solve with your GUI, I suppose.
Sometimes, it is better to just recreate the whole GUI to adapt to a model
change (e.g. the user moved half of the tree nodes somewhere else), sometimes
it is easier/faster/... to just update the existing GUI (e.g. update the text
of a label inside a complex dialog widget).

------
geekpowa
Retained GUIs vary wildly in implementation.

Many of authors most significant criticisms on retained GUIs are
implementation considerations. GUI frameworks exist that solve his key
criticisms of complexity and are pleasant to work with.

Criticisms that target core architecture of retained GUI I don't consider to
be valuable design goals, at least in settings where I work on GUIs. e.g.
memory usage.

Alot of things are glossed over that remain challenges in both, e.g. layout
management.

HTML is an interesting example. First iteration of HTML was essentially
immediate mode if you think about a single client/server interaction as a GUI
update cycle. Server sends draws to client browser and client browser sends
back to server user selections. There is no retained state on gui side. Now
with programmatic access to DOM, ability to attach events to DOM elements from
client side it is now a retained GUI. Seems to be where things evolve to
naturally.

The GUI framework I use nearly daily is retained and very pleasant to work
with in terms of ease of belting out screens & readability/maintainability of
code. The simplicity comes with compromises though as there are limits on GUI
idioms that can be expressed. Occasionally run into those boundaries and
resulting GUI does look a little plain and unexciting, but for something that
is substantially about data entry its fine.

------
arianvanp
Recently I started playing with [https://github.com/ajnsit/concur-
documentation/blob/master/R...](https://github.com/ajnsit/concur-
documentation/blob/master/README.md) which has been the most refreshing UI
paradigm i've used in a while. and it reminds me a lot of this ImGUI approach,
but behind the scenes it uses coroutines instead.

The idea is that a button is a UI element that _blocks_ until an event is
fired. You can then compose elements in time like:

    
    
        button "hey" >> label "clicked"
    

which is a program that displays a button, you click it, the button goes away
and the text "clicked appears"

Or you can compose programs in space:

    
    
        (button "hey" <> label "not clicked") 
    

this is a program that displays both a button, and a label at the same time.

Now, by combining both space and time, we can create a program that changes
the label when clicking as follows:

    
    
        program = (button "toggle" <> label "off") >> (button "toggle" <> label "on") >> program
    
    

This is an application that toggles a label on and off when you press a
button. (Note that the definition is recursive)

------
RandyRanderson
There's a difference bt poor impl and poor design.

As the author points out, HTML has a poor design (eg. if you want to have a
1000x1000 cell table, you have to have 10^6 actual cells - that's a lot of tds
or whatever to parse).

Modern OO GUI frameworks don't do this - they say something like:

cellRenderer.draw(target, row,col,position,size)

No creation of objects required. Of course since it's so easy to create OO
programs a lot of code isn't great... and then others copy that code and so it
goes.

Seems like we keep re-creating software b/c we haven't taken the time to look
at what exists and only then decide on what to keep and what to change. "This
is too complex - I'll re-write it!". 10 years later: "We added all the
features that the existing software had and now the new one... is just as
slow... but we did sell a lot of conference tickets and books so... totally
worth it."

When I was 20 I also thought I knew better so I get it.

------
babel_
I feel that the future lies in combining retained and immediate interfaces,
preferably with the granularity to allow deeply nested retained interfaces
that are fast for complex ui (or for a realtime system with memory to spare),
whilst still allowing one to go the other direction, such that a simple ui can
be written cleanly and logically for low-memory systems (such as embedded or
boot guis). It would need a very well designed api for this, but I feel the
benefits are worth the effort (and I'll probably look into this next time I
have the freedom to choose ui apis).

A balance may be letting people define it either way, so that manually written
ui still can have auto-layout yet intuitive code (following control flow
primitives), whilst allowing generated retained uis to be manually editable --
perhaps even allowing one to then embed one within the other, a boon for
scripted interfaces that perhaps have people of various levels of experience
producing ui elements, such as a musician with little experience being able to
add a simple visualiser in an immediate manner to a deeply retained daw gui.

Of course, there's a lot here that is implementation, and some criticism
either way can be optimised out. Immediate mode can still cache its rendering,
we've had optimised blitting since the early days, and is only usually a
problem with complex ui. Retained would get fewer cache misses if we weren't
allocating madly across the heap and took a more disciplined approach
allocating to contiguous memory -- which is almost entirely a language/api
problem (in my experience) that can also happen with immediate but we
typically don't see since it's often done in a more procedural style that is
allocating to some pool.

Other api elements, such as handling lists etc aren't really a differentiation
between retained and immediate, those can be made in either.

For me, I often find that the ability to write out prototype ui code in an
immediate style in very quick and satisfying (exactly what I want in
prototyping), however once I start to expand upon a ui, I find it best to over
time refactor towards a retained style, since by then I will typically have
some templates for what ui elements look like, and so I just have to pass a
string and function pointer to fill in the template.

Can't see why we can't have nice things and let both coexist...

------
pedrocr
Conrod is an immediate mode GUI library for rust[1]. I've been using it for an
image processing app[2] and have enjoyed the way the code turns out.
Everything is much more straightforward as you don't have to reason about
callbacks interacting with a loop that's not yours to control and the
performance seems good.

[1]
[https://github.com/pistondevelopers/conrod](https://github.com/pistondevelopers/conrod)

[2] [https://github.com/pedrocr/chimper](https://github.com/pedrocr/chimper)

------
thrax
Immediate mode uis are fine for debug displays or for displaying data that's
changes every single frame, but for anything else, in a shipping product they
are just a waste of resources. The primary wasters are excess memory
allocation, string generation, and the sheer amount of redundant function
calls. Anything you do to address those problems result in converting your ui
to a retained mode UI. For those advocating react like approaches to solving
this.. similar problems are involved. Diffing state is wasting cycles unless
it's done so optimally and carefully that it becomes a technical feat and ends
up being as complex as just doing something retained. Source: game developer
for 25 years on console, desktop, and mobile.

------
seanmcdirmid
Probably not. With technologies like React that make retained-mode UIs look
more like immediate-mode ones, there is less need for full blown immediate-
mode UIs. React achieves the programmability of an immediate-mode UI without
sacrificing the performance of a retained-mode UI (at least, that’s the goal).

------
weinzierl
> A few problems with this GUI style are:

> You have to write lots of code to manage the the creation and destruction of
> GUI objects. [..]

> The creation and destruction problem leads to slow unresponsive UIs [..]

> You have to marshal your data into and out of the widgets. [..]

My biggest pain point with the retained mode GUIs I worked with was none of
the issues mentioned above. It was always the centralized GUI thread and the
consequential synchronization complications. I don't know if this is an
inherent problem of retained mode GUI frameworks and if there are some that
don't force all widgets into a single thread. If not, this alone is a reason
to for me to find immediate mode interesting.

~~~
overgard
Immediate mode, if anything, makes this harder. (You absolutely have to run
the GUI on one thread, for instance). Really though you can get around that on
either of them by spawning a worker thread/coroutine/etc. on button clicks and
so on.

~~~
weinzierl
The real problems start, when the worker thread needs to update the GUI, for
example to advance a progress bar. With the frameworks I know I have to build
a communication channel between the threads and tell the GUI thread to show
and update the progress bar.

My hope was that with an immediate mode framework I could just show a progress
bar on top of the existing GUI right from the worker thread. I don't know
enough about immediate mode to say if this is really possible. It would
simplify a lot of my code though.

------
Klonoar
I recall reading this article in your comments on the last GUI-specific link
posted here... where you just kept disagreeing with comments that took the
time to point out how this stuff is largely off base.

We moved away from WM_PAINT for a reason.

------
amluto
Here’s a downside that wasn’t mentioned:

    
    
        if (ImGUI::Button("Click Me")) {
            IWasClickedSoDoSomething();
        }
    

This forces Button to be stateless, which limits the possible quality of
implementation. If you mouse-down on a button and the button changes before
you mouse-up, it shouldn’t register as a click. Similarly, if you mouse-down
on a button, drag to the button, and mouse-up, it shouldn’t be a click.
Implementing this in a fully immediate-mode GUI with this interface is either
impossible or requires gross hacks.

~~~
bdowling
A naive implementation would have the problem you describe. However, a smarter
library implementation avoids this (e.g., by generating an id for the button,
saving the id on mouse-down, and checking the id on mouse-up). The user of
such a library won't have to worry about it.

~~~
amluto
And how, exactly, is the id created? Some hash of the button’s text and
coordinates?

I would call that a dirty hack, no to mention being implicitly stateful.

~~~
HelloNurse
But a stateful GUI is not a sin: the program as a whole has state, application
code needs to process GUI inputs to update application-level state (e.g.
currently set game options) while tracking mechanical details like whether a
button is "half clicked" is suitable for automation at the GUI library level.

Regarding IDs, they can (and must) be provided by client code, as client code
is responsible for managing widget identity (i.e. whether the button that
might have a mouse up event this frame is "the same" that received a mouse
down event some frames ago). In C or C++, string names could usually be
autogenerated with trivial macros relying on __LINE__ and __FILE__.

------
jbverschoor
Can we please just stop moving around in circles in the tech industry? Nobody
seems to learn anything from past methods, tech and everything.

~~~
analognoise
LOL. My favorite part of it was the last line:

"More research into ImGUI style UIs could lead to huge gains in productivity."

Don't tell this cat that the research on this stuff goes back >40 years and
that the introductory chapter of any book on computer graphics would have
talked about all of this. Not like it would help him - he hasn't read anything
about it, didn't even do a cursory Google search. Sheesh. A low, low bar.

~~~
tom_
Do you have any recommended links?

~~~
analognoise
I do!

One of my favorite is "Don't Fidget with Widgets, Draw!"
([https://www.hpl.hp.com/techreports/Compaq-
DEC/WRL-91-6.pdf](https://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-6.pdf))
It's modern enough to be understandable, and while it's referencing Ezd (a
Scheme drawing system) it greatly influenced Tk (which is still used in all
kinds of heavy-hitting EDA software).

That one's only been around for 28 years though (well, the paper was published
in 1991, so code was before that...) but let's go further:

The drawing system(s) that greatly influenced Ezd came largely from Xerox
PARC, such as ALTO: [https://www.computerhistory.org/atchm/xerox-alto-source-
code...](https://www.computerhistory.org/atchm/xerox-alto-source-code/)

There's code in there for a vector drawing program (in 1980!), as well as
interacting widgets. Let's go back further...

Finally, we have to mention the Mother of All Demos, in 1968:
[https://en.wikipedia.org/wiki/The_Mother_of_All_Demos](https://en.wikipedia.org/wiki/The_Mother_of_All_Demos)

Which if you haven't watched MOAD before, give it a spin. It will still blow
your mind, but the interactive graphical drawing mechanisms will be
recognizable.

Also, this "paint the screen every time" method is how a tremendous number of
people who cut their teeth on DOS did things on the screen. DOS release date:
1981. So you don't have to have been an academic (which I am NOT) to have
tried these techniques while solving practical problems.

As far as books: Computer Graphics Principles and Practice in C (later
editions use C#/C++/etc. - the ideas are the same)

The 1995/96 one talks about retained mode graphics directly. That book has
been standard in "intro computer graphics" courses for as long as it's been
out. So at least 20+ years it's been the "start here" book.

So yea, this stuff has been around for a while...

------
jayd16
IMGUI must sound appealing to people who have never done UI work. Just try to
implement a responsive UI in an IMGUI. Layout code is not fun.

------
laythea
I got fed up of ImGUI when I wanted to route events to my application instead
of the GUI. Its good "out the box" ut when you need to get down and dirty to
customise, it can be awkward.

Nowadays I do a hybrid approach, so I have use NanoGUI and create my own "live
data" "retained mode" controls. Now I have either the best of both worlds or
the worst of both worlds. I think the best:

Pros: \- I don't have to bother with data binding. As the control is passed a
pointer to the actual memory for he value, it can "go get it" when rendering,
rather than my application setting its state. \- I still have classes to
represent elements and state, so its conceptually simple to build controls on
controls. I found this difficult with Imgui.

Cons: \- renders 100% full speed, but I am working on way to speed up and slow
down render loop depending on user activity, so that when sitting idle, the
cpu is not burning.

~~~
ahaferburg
This is the exact issue I'm running into right now with dear ImGui. There is
no event propagation. You can either transfer control over to ImGui, or you
retain control. In Qt it would be possible for the focus widget to not accept
events, so they would bubble up the hierarchy. Considering how the hierarchy
is tied to the callstack, this seems difficult to achieve with an ImGui.

~~~
laythea
NanoGUI + live data custom controls = happy days

------
sago
I have implemented a bunch of UIs for games. Immediate mode sounds good, but
each time the thing that has bit me has been layout.

Sometimes you need to traverse the hierarchy to figure out where things will
be placed. Before traversing it for render. If your hierarchy is implicit in a
call graph, you have to either duplicate your calls, or implement some kind of
backend retained system so you can defer rendering until after layout.

Beyond the absolute simplest of toy UIs, immediate mode doesn't work in my
opinion.

------
golergka
Every time a developer decries some abstractions and tools as unnecessary
complicated and too "enterprise", it probably means he haven't encountered a
problem that this solution was created to address.

As a Unity developer, I love immediate mode GUI for debugging. But I would
never in my right mind attempt to use it for actual in-game GUI. Project I'm
working on right now is not incredibly complicated, it's just a typical mobile
match3 game. But a typical screen here has: (1) background that has to be
scaled over all screen, eveloping it around while keeping aspect ratio, (2)
frame that has to be scaled to screen without keeping aspect ratio, (3) a
"window" background that has to be scaled somewhat to screen (with margin),
being enveloped by it, (4) interactive elements, that have to be scaled down
from the "safe area" (so that there are no button under the iPhone bevel), (5)
match3 game field that has to be scaled according to physical sizes of the
screen, (6) pixel-perfect elements that have to be chosen according to pixel
size of the screen (1x, 2x and 3x options) and scaled appropriately.

So, no, immediate GUI is definitely not the solution here.

------
ahaferburg
From dear ImGui's mission statement:

 _> Designed for developers and content-creators, not the typical end-user!
Some of the weaknesses includes:

> \- Doesn't look fancy, doesn't animate.

> \- Limited layout features, intricate layouts are typically crafted in
> code._

It may not replace retained mode GUI toolkits, but it can certainly make the
life of devs easier. If all you need is to quickly hack together an internal
tool, or some quick debugging interface, keep ImGui in mind.

------
zzo38computer
I have seem other programs doing stuff like that before, and I have also done
some of that in my own programming (although not with this or any other
library). I did not know what it is called, until I read this today. It look
like good to me. Also, you will still need to add some extra variables if you
are doing such thing as tab to focus, I think.

------
4thaccount
Anyone experienced with ImGUI ever use Rebol and Red's DRAW DSL?

I believe Rebol's GUI support is even easier to use than ImGUI, but of course
it can't be embedded and used in the same way as ImGUI either. I wonder if non
Red projects could possibly hook into Red's system once Red/System gets closer
to C level performance?

------
nh2
> ... people scroll almost constantly in which case the ImGUI wins by a
> landslide

I think this is a misrepresentation of how fast scrolling is usually
implemented.

For fast scrolling, you render the page (which is larger than the viewport =
"what fits on the monitor") ONCE onto a GPU texture, and then all scolling
happens on the GPU side (the CPU just tells the GPU the offsets into that
texture).

Immediate mode has to recreate the texture every frame, instead of once for
multiple frames. So "It might use more CPU" is quite certainly true.

~~~
nh2
You can also do some simple math to arrive at a justification:

Assume a 4k x 2k display at 60 FPS.

Compute the throughput needed (Bytes per second) to draw an RGB framebuffer.

That is: 8M pixels x 3 Bytes x 60 fps = 1.44 GB/s

Note how we haven't done any computation yet to decide what the colours should
be, this is just the CPU effort to do IO to tell the GPU about the new colours
to show.

This would incur significant CPU usage, and your device would get hot quickly.
In contrast, if you let the GPU scroll, you have to send two floats (for X and
Y offset) per frame, and the GPU just does a hardware-parallelised lookup.

This is why we have GPUs, and why scrolling immediate-mode would make your
device burning hot while a GPU does the task with minimal energy usage.

~~~
hevi_jos
Following the same logic that you use... have you calculated how much memory
do you need to store the memory of a single treeview, or a single scrolling
document of just several pages?

Two floats? You are using a memory that is a CPU memory, a big chunk of
memory. That does not exist in the GPU. In the GPU the memory is distributed
so it can be used in parallel.

Immediate GUI exist because of GPUs, because with GPUs you can draw frames
fast. If you look at Imgui code it uses GPU drawing for everything. In fact it
uses only two drawing functions copying small rectangles in the screen.

It is drawing a single big chunk of memory what is extremely slow, and you
need to do that before you do offsetting.

And if you work with variable data, like a treeview, you need to allocate for
a finite amount of memory in the GPU buffers.

------
627467
I'm having a hard time to understand what is ImGUI (and what is the opposite
RmGUI)... any could help me with ELI5? It sounds like ImGUI is reactive while
RmGUI is not?

~~~
revvx
Games (normally) re-render the whole scene every frame.

ImGUI exposes that to their API users: you have to re-render and check for
clicks on every frame. The code looks like React, (but not as optimized, it
re-renders every frame!), and normally you have to keep state by yourself.
Code example: [1].

Retained Mode is closer to the DOM, Cocoa or WPF: you create objects and
there's an abstraction between the API and the renderer: they get re-rendered
every frame for you. Componentes normally have events and state by themselves.
Sometimes there's a visual editor too.

The main difference is the API. One is lower level than the other. In
practice, the APIs aren't that different, except when it comes to event
handling.

[1] - [https://docs.unity3d.com/Manual/gui-
Basics.html](https://docs.unity3d.com/Manual/gui-Basics.html)

~~~
floatboth
> Games (normally) re-render the whole scene every frame

They don't re-upload the whole scene to the GPU every frame, they don't
recreate objects all the time. Immediate mode was only used in, like, the GL
1.x times.

~~~
revvx
But I never said they did?

------
dang
Related recent thread:
[https://news.ycombinator.com/item?id=19744513](https://news.ycombinator.com/item?id=19744513)

------
dwrodri
Great find! I haven't done much work GUIs myself, but I would love to read
more about alternative design philosophies in human-centered computing and
their downfalls.

------
cotelletta
React hooks is the closest you'll get in practice, once you factor in async,
layout measurements and other practical things. But useState is pretty much
just imgui with built in getters/setters rather than external state.

------
polytronic
The single most important factor when it comes to UI is text rendering.
Immediate mode UIs are based on text rasterization, ie polygon creation for
each character of the text while retained mode text is usually featuring
texture atlases containing all characters in upper and lower case. This of
course introduces a limitation on the number of fonts available to the
developer, font sizes, etc. My 3D engine is using an immediate mode UI for the
editor and tools while it allows for creation of retained mode UI for in-game
UI components by automatically generating texture atlases for the selected
font types

------
etaioinshrdlu
Didn't Firefox put forward a big plan to basically implement the browser as an
immediate mode UI designed to redraw everything on every frame?

~~~
floatboth
WebRender is not just a "plan" but a real thing (I'm using it right now), and
it's fully retained.

Immediate doesn't mean just redrawing everything on every frame, immediate
means what's described in the article — not keeping state. WR _aggressively_
relies on kept state to optimize rendering of each frame as much as possible.

~~~
etaioinshrdlu
Very interesting, thank you.

------
Vanit
I hadn't heard of ImGUI, but after reading the definition realised that's
exactly how you made custom menus in RM2k/3 :)

------
abledon
Say I want to make a program, X, that draws a 50x50px square over another
program, Y, at (200,100) and only program Y. Do i need a low level stuff for
this, can imGUI be used here? or is it possible with electronjs etc... Also,
would program Y be able to detect, with administrator privileges that another
program was targeting its pixel space and drawing over it?

------
grifball
>programmers find it more performant >plusses speed >minuses uses more CPU
what?

------
qwerty456127
Are any implementations of this approach available for high-level languages?

------
pjmlp
ImGUI is the past of GUIs.

That is how we used to do it on 8 bit and 16 bit platforms, before frameworks
like Turbo Vision, GEM and Workbench came into the scene.

------
rambojazz
Could somebody please ELI5 this? How is this different from traditional UI
approaches and why would I want to use this?

------
dzonga
this feels more like drawing UI's using state charts in terms of
expressiveness.

------
ianrathbone
Isn't the future of GUIs to have no GUI?

------
781
It's important to point out why games use immediate mode GUIs:

1\. The GUI needs to be overlaid on the game image (OpenGL/DirectX). This is
difficult with traditional GUIs like QT.

2\. The GUI needs to be updated in sync with the game, again, it's difficult
to integrate traditional GUIs event loops into the game loop, especially with
stuff like double/triple buffering.

3\. The GUI needs to be as fast as possible, games are severely CPU bound.

A retained mode GUI is typically easier to use, convenience is not why people
use immediate mode GUIs.

It's worth pointing out that the immediate/retained split doesn't apply only
to the GUI - there are retained mode graphical APIs - DirectX used to have
one. They are only used in low-demand games, they sacrifice a lot of speed for
the convenience of using a retained mode.

~~~
invokestatic
I've written real-time game UIs before so I think I have some relevant
experience here.

1\. It is very possible to write a retained-mode GUI in a graphics API like
DirectX or OpenGL. In fact, a retained GUI would typically wipe immediate GUIs
in terms of performance in this context. In immediate mode, the GUI's vertex
buffers need to be completely reconstructed from scratch every single frame,
which is _slow_ , CPU bound, and cannot be (easily) parallelized. It's like
reconstructing the game world every frame -- that would be ludicrous for any
non-trivial game.

2\. I don't think there would be that much of a difference between the two UI
models, since data updates can be dispatched from the event loop. It would be
faster, too, because only UI components that need updating could be redrawn.
This is far faster than updating the entire UI every single frame.

3\. As mentioned earlier, immediate mode GUIs are going to be a lot slower
than retained mode, when implemented properly. Immediate mode GUIs put most of
the work on the CPU instead of offloading most of the work to the GPU like in
the retained model.

I think developers that are using immediate mode GUIs are doing so because of
their ease of use. I think retained mode is typically harder for a game
developer to conceptualize because immediate mode is conceptually similar to a
game loop. Also, I don't know of any free & open source retained mode GUIs for
DirectX and OpenGL and the like.

Also, DirectX at least (and probably OpenGL) encourages a retained-like model
for general rendering. The only way to get decent performance is to re-use
vertex buffers between frames and only update them when something changes.

~~~
tom_
I've written real-time game UIs too. I think you underestimate just how
ludicrously fast CPUs and GPUs are, and overestimate the complexity of your
average GUI. What does your average screen's-worth of GUI consist of, after
all? How many widgets are there? I double dare you to tell me that a modern
computer or games console can't handle 500 widgets per frame. And I now triple
dare you to tell me that your UI designer has put that many damn widgets on
one stupid screen in the first place.

(Every UI I worked on actually did redraw everything every frame anyway. It's
really not a big deal. Your average GPU can draw a monstrous amount of stuff,
something quite ridiculous, and any sensible game UI that's actually usable
will struggle to get anywhere near that limit.)

~~~
invokestatic
I'm sure many games can get away very well with an immediate mode GUI. I think
the question is not _can_ you, but rather _should_ you. My last project used a
custom immediate-mode GUI. At the absolute pinnacle of optimization, it was
pushing 2,000+ FPS on my machine with something like 3-4k vertices, with heavy
texture mapping and anti-aliasing. But the problem was that even with peak
optimization, the CPU was spending 15-20% of its time every frame recreating
the UI's vertex buffer. Now imagine if we had done a retained-mode GUI
instead. That 15-20% overhead would be reduced to near 0% on a typical frame.
For nearly any type of game, that kind of savings is really significant. Think
of how many more vertices your artists can add, or cool gameplay elements you
can add that you didn't have the CPU time available before, and how much
better it will run on lower-end hardware.

Why settle for "good-enough" performance?

~~~
revvx
> The CPU was spending 15-20% of its time every frame recreating the UI's
> vertex buffer.

Not saying it is easy, but it's possible to optimize and cache vertex buffers
by using something similar to React's VDOM.

~~~
smallnamespace
Doesn't your cache just become a limited retained mode with a somewhat hacky,
opaque API?

~~~
DougBTX
Basically yes. If an immediate mode API is much easier to use, and a retained
mode underlying implementation has much better performance, then putting a
React-style VDOM layer in-between could get the best of both worlds, depending
on how well the middle layer is implemented.

------
layoutIfNeeded
So basically go back to WM_PAINT

~~~
pjmlp
Not really, it is a go back to mode 13h.

------
chaboud
No. ImGUI could not be the future of GUIs.

GUIs are multi-process, multi-system, multi-clock, multi-network entities, or
at least they have the potential to be. Immediate Mode GUIs are almost non-
scalable by design.

Imagine a multi-system asynchronous AR collaboration environment. Now imagine
that as an Immediate Mode GUI. If we had enough horsepower to do that, we'd be
doing something far better with it.

