Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

IMGUI is good on many levels, but also has some serious drawbacks. Specifically: latency in figuring out exactly how big a control or layout will be. This also translates into at least 1-frame latency when drawing to a widget based on user input. Imagine a scrubber line on a video timeline or graph, for instance.

Non-immediate mode GUI (retained-mode?) means that you can query a layout for exactly how big it will be before it gets drawn. So, if the user clicks at say (100, 200), I know exactly where to draw something in response to that click on top of my widget, without waiting a frame for the GUI to layout.

Maybe developers who have come up in the web world don't care, but I find reflow issues to be one of the worst features of browser apps. If you're going for a tight native experience, then this is a huge no-no.

The "immediate-mode" GUI idea was something that Casey Muratori, a very influential indie game developer, came up with. Part of his rationale was that it was annoying to store all the state for your widgets in a parallel data structure to the widgets themselves. So why not just draw the widgets, as needed, where you have the local variables and data to draw them?

Various developers and frameworks seem to get smitten with this idea, jump on the bandwagon, and then run into the flaws. For a long time the Unity game engine followed this model. I found the GUI easy to get started with, but ultimately limiting. Unity eventually abandoned this approach.

Really, this is good for developer-quality in-game debugging UI, but it's not a great approach for creating polished end-user UI.

I adopted IMGUI, used it briefly, was impressed by its speed, but ran into massive problems customizing controls to get exactly the right look and feel.

My take -- this is an ideologically-driven kind of neat but ultimately dead end. Use it to quickly get a dev GUI going, but it won't see you through to a polished consumer-ready GUI.



There is no reason an IMGUI cannot efficiently construct a hierarchy in the background and do a fast Flutter-like linear layout pass on it before processing input and rendering it. Then throw this away and do it all over again for the next frame (or the next time input arrives, if not used in a game-like context). I've experimented with this, and speed is no impediment if implemented correctly.

IMGUI is about the immediate mode interface, not about layout/rendering/input handling happening at the same time as view functions are called. And don't do "if (Button()) { ... }", but use lambdas for event handling, so the handlers can be invoked at the proper time when everything is laid out.


I guess? But the neat thing about IMGUI is how easy it is to integrate and get up and running without having to learn much. Like dump this thing into my code in 1-2 hours then get back to what I was really doing. With the accommodations you mention, you lose all of that and still don't end up with something as functional as say Qt.


This is the definite TLDR on how layout/constraints in flutter works - https://flutter.dev/docs/development/ui/layout/constraints


I don’t exactly understand argument about frame rates, I thought these GUIs ran at very high frame rates and 1 frame wouldn’t be perceptible by humans. Is there really a human perceptible significant latency with them?


There are a lot of hidden traps when rendering anything on modern operating systems that add small latencies and those small latencies add up quickly (it was much easier on old 8- and 16-bit computers).

For instance rendering something that "sticks" to the system mouse pointer and doesn't lag a few pixels behind when moving the mouse is surprisingly hard if you're rendering through a 3D API (compared to going through the native window system), at least if you also want to be energy efficient (e.g. not spam 1000 frames per second).

What strikes me as odd is describing the ImGui idea as an "ideology" when it's the most pragmatic way to describe user interfaces in a long time, for me that's the opposite of an ideology.


I think if it as Casey Muratori's "brain fart" that made sense in his context but that other developers have latched on to because of his influence in indie game circles.

I have massive respect for him, and followed everything he did back in the late '90s and early aughts, but he's quite opinionated and has some peculiar code aesthetics / trade-offs.


I first got introduced to the concept by his talk, and this implementation here - http://sol.gfxile.net/imgui/ch01.html (latest archive I could find - https://web.archive.org/web/20200428143845/http://sol.gfxile...)

I've did some translations of the above C/C++ code to lua longtime here (actually luajit, as it requires the FFI) - https://github.com/malkia/ufo/blob/master/samples/SDL/imgui/... (simplest example) through https://github.com/malkia/ufo/blob/master/samples/SDL/imgui/... though my hack for C/C++'s __LINE__ macro was

local function GEN_ID() return CURRENT_LINE() end

e.g. you basically tie the state to the... ahem.. source code line (you need really something unique). Obviously Dear ImGUI has better approaches there (use the widget's contents, like text/label contents, or add your own with ##).


Anectodal etc etc, but when I started using Dear ImGui a few years ago I had no idea about the origins of immediate mode UI, or what "immediate mode UI" even means, and neither had heard of Casey Muratori nor Omar Cornut.

All I saw was a very enjoyable way to create UIs, something I loathed before (like most other programmers I guess). So far I haven't come across another UI toolkit which is as enjoyable to use as Dear ImGui (and that includes a couple of other ImGui libraries), and that's the reason why I stick to it, not because of some sort of cult of personality ;)


    I think if it as Casey Muratori's "brain fart" that made sense in his context [...]
    I have massive respect for him, [...]
Sure doesn't sound like it. You're so dismissive of others' ideas that I don't even feel like you're looking for a constructive discussion.


Not sure why you would conclude that from what I wrote. I see myself as adding historical context + usage experience.

EDIT> I've learned a bunch from this discussion, and I haven't directly refuted much of it, just added commentary.


Dragging around a pointer, or scrubbing a line will be noticeably laggy with > 0 frame delay. It leads to a sluggish feeling that may be okay in the web world, but is kind of against the whole aesthetic of performant native apps. What's strange to me is that Muratori is a huge stickler for performance, like Jon Blow. I can't imagine him being happy with any kind of lag.


Cursors are done with hardware cursor sprites on the video card and so run perfectly at the full frame rate of the monitor. In game cursors will be different.


Let's say you're dragging something at 3 cm/s. Rendered at 30 Hz, a one frame latency translates into 30/30 mm which is 1 mm. A 1mm gap between the cursor and the thing you're dragging is definitely perceptible, and this is for a relatively slow drag. It's at least enough to destroy the illusion that the thing is locked to your cursor.


> Part of his rationale was that it was annoying to store all the state for your widgets in a parallel data structure to the widgets themselves.

That is only a problem if you don't have closures (for callbacks) and dynamic and generic data structures (like json and polymorphic object references, that you can attach to generic widgets without having to subclass them).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: