top | item 24986908

Dear ImGui – Bloat-free graphical user interface library for C++

284 points| dragonsh | 5 years ago |github.com | reply

180 comments

order
[+] exDM69|5 years ago|reply
As much as I like Dear ImGui, the immediate mode paradigm doesn't work everywhere. The problem of "page tearing" (not to be confused with vsync) means you either need to render frames continuously, or at least 2 frames for every time you get input or need to implement some kind of "retained mode state tracking" on top of Imgui. It's good for games, but for applications where you're not rendering new frames constantly, the paradigm doesn't seem a very good fit.

I wish there was a retained mode GUI library that would be as easy to integrate in your game and graphics apps as ImGui (or nuklear) is.

On my spare time, I've been working on a retained mode GUI layout and rendering framework (not a complete GUI toolkit) that uses a DOM-like tree, CSS style flexbox layouts and produces a vertex buffer for rendering like ImGui does.

Unfortunately life gets in the way, and all I have to show for my project is a small prototype in C and another one in Rust (can't decide which I like more) that draws some text and rectangles with a fancy layout. Code is not public at the moment but I'm willing to share it with anyone (on GitHub) who responds with a thoughtful comment or a good question.

I have been following Raph Levien's fantastic work on Druid and Rust GUIs which has been very inspirational, this video in particular [0].

Where Raph is focused on native GUI rendering and high fidelity text output, I've only focused on rendering in a GPU application using shaders and only very basic text layout with simple kerning (like Dear ImGui).

As Raph points out in his later talks on the topic, layout and rendering are only half of the GUI puzzle. The other half is maintaining the state of the application, usually through some kind of widget tree.

Leave a comment if you're interested, I'd be happy to chat even though it doesn't seem like my projects are going anywhere anytime soon.

[0] https://www.youtube.com/watch?v=4YTfxresvS8 Data Oriented GUI in Rust by Raph Levien

[+] raphlinus|5 years ago|reply
Thanks for the kind words. My thinking has evolved since that video; my blog at https://raphlinus.github.io/ is a good place to check.

As flohofwoe suggests in a sibling, combining an imgui-like API with an actual retained widget tree would be something of the best of both worlds. That is indeed pretty close to what the Crochet prototype does. We're not trying to exactly match the imgui but it's pretty close. In particular, getting actions back from widgets (like button presses) is the return value from calling the widget-creating function. That's a notable difference from, say, Jetpack Compose, which is fairly imgui-like on widget creation but pretty much uses callbacks for those actions. Crochet does solve the page tearing problem (though the current implementation is hacky, don't look too closely under the hood).

Another note - the Dear ImGui implementation has become a lot more sophisticated over the years, and is no longer a simplistic implementation of the immediate mode GUI concept. It has unique id's for widgets, its text processing has become better, etc.

[+] flohofwoe|5 years ago|reply
Wouldn't it be possible to separate the public API from the internal implementation so much that the library appears "immediate mode" on the outside, but is completely "retained mode" on the inside? With a persistent widget tree which is only manipulated by diffing it against the current frame's UI description provided by the user code?

The important feature of immediate mode UIs is that there's only one sequential piece of code for UI creation, updating and input handling. All I'm saying as the framework user is basically "this is what I want the UI to look like in the current frame".

E.g. if the UI that's described in the current frame by user code is completely identical to the last frame's UI, exactly "nothing" would happen, the internal widget tree wouldn't change, and nothing would be rendered.

[+] milansuk|5 years ago|reply
Hi, I'm making SkyAlt[0]. It's IDE and language for building applications. Probably I did something right in the beginning, because It doesn't have problems with "page tearing", but it's true that It does "state tracking" in the background.

Feel free to check my blog and send me an email if you are interested. I have work in progress version for Windows and Linux, but no documentation yet. It will be released(free and open-source) by end of this year.

[0] https://skyalt.com/

[+] userbinator|5 years ago|reply
It's good for games, but for applications where you're not rendering new frames constantly, the paradigm doesn't seem a very good fit.

It's also very inefficient to continuously redraw, which is not a concern for games, but not in general.

[+] formerly_proven|5 years ago|reply
> As much as I like Dear ImGui, the immediate mode paradigm doesn't work everywhere. The problem of "page tearing" (not to be confused with vsync) means you either need to render frames continuously, or at least 2 frames for every time you get input or need to implement some kind of "retained mode state tracking" on top of Imgui. It's good for games, but for applications where you're not rendering new frames constantly, the paradigm doesn't seem a very good fit.

Writing a desktop app using ImGui I had the same problems. In many instances it can be resolved by re-ordering operations such that in a frame you first update the state and then render it, but this isn't always possible or easy. For those cases I eventually resorted to having a requestFrame() function (which posts an empty event to the input queue at the end of the frame, causing another frame to be rendered immediately).

[+] boomlinde|5 years ago|reply
> The problem of "page tearing" (not to be confused with vsync) means you either need to render frames continuously, or at least 2 frames for every time you get input or need to implement some kind of "retained mode state tracking" on top of Imgui.

Suppose that the widget functions apply one of two different strategies depending on the call context: 1. Render the widgets and 2. Evaluate the layout and process input accordingly. You invoke the GUI code in the second context on every input, and after that invoke it in the first context only if the calls in the second context potentially resulted in a change. This minimizes re-rendering and eliminates page tearing while allowing you to re-render reactively to events.

You will of course still need some kind of basic state tracking to make the GUI re-render to reflect changes that are not triggered by input.

In general, I agree, though. The right tool for the right job.

[+] tgb|5 years ago|reply
Can you explain what "page tearing" is?
[+] t0astbread|5 years ago|reply
Sorry if this comment sounds a lot like "why don't you just"-ing, I'm just trying to understand what I'm missing and I don't expect to be right.

But is rendering twice really that much of a problem if you only have to do it on a state-changing event (even if that includes things like hover events or live data)? Even games that run with 30-60 FPS aren't really a problem anymore on weak hardware so why would a GUI that updates "once in a blue moon" (relatively speaking) be?

Apart from that, I don't know how Dear ImGui or other immediate mode GUI frameworks do it but if a framework handles page tearing with double rendering it could skip the actual paint (i.e. pixel drawing) in the first render. In case the user wants to avoid some needless work (like rendering labels or graphs that never affect state) in the first render the framework could also pass the calling context (update or paint) to the render function.

[+] FraKtus|5 years ago|reply
Maybe it is still VBL related, in the DX11 sample you will see this when presenting the final frame:

g_pSwapChain->Present(1, 0); // Present with vsync

//g_pSwapChain->Present(0, 0); // Present without vsync

So you can control this by setting the first argument to 1 or 0.

[+] DonHopkins|5 years ago|reply
You can't implement a user interface editor, or user editable interfaces, with immediate mode guis. You can't load and save user interfaces out to resource files, or dynamically generate user interface resources from other programs. You can't iterate quickly on user interface development, because the user interface specification is a program that you have to recompile, not data that you can reload.
[+] roytries|5 years ago|reply
Not sure why this is showing up on HN today. But Dear ImGui is absolutely amazing. And its not just for C++. I use it myself in my C# game engine. (There's a C# port that uses System.Numerics: https://github.com/mellinoe/ImGui.NET) which I've ported to MonoGame https://github.com/roy-t/ImGui.NET)

I've used a lot of different UI frameworks (winforms, WPF, Html/CSS based frameworks, custom game engine frameworks). But for prototyping Dear ImGui and the whole immediate GUI idea is amazing. It even looks quite decent and the new docking support is great :).

[+] ahaferburg|5 years ago|reply
Every couple months I browse the screenshot threads https://github.com/ocornut/imgui/issues/3488

Looking at them makes me really happy for some reason.

[+] malkia|5 years ago|reply
Agreed. These look fantastic, and has been the driving force for folks around here to want to change to that. I just don't know what to expect once we go that route (certainly intrigued, also occurnut is one of the nicest and most responsive people around). We have large 3d level editor, and there has been talks about us trying imgui with it. Slowly moving it out of Qt maybe? There is lot to like now in imgui - especially now that there is proper docking :)
[+] JabavuAdams|5 years ago|reply
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.

[+] robinei|5 years ago|reply
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.

[+] DethNinja|5 years ago|reply
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?
[+] DonHopkins|5 years ago|reply
> 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).

[+] prvc|5 years ago|reply
>This library is called Dear ImGui. Please refer to it as Dear ImGui (not ImGui, not IMGUI).

>(The library misleadingly started its life in 2014 as "ImGui" due to the fact that I didn't give it a proper name when when I released 1.0, and had no particular expectation that it would take off. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations e.g. Unity uses it own implementation of the IMGUI paradigm. To reduce the ambiguity without affecting existing code bases, I have decided in December 2015 a fully qualified name "Dear ImGui" for this library.

Yes, but why "Dear"? Makes it read in an odd way wrt to idiomatic English.

[+] modeless|5 years ago|reply
One of the most valuable parts of Dear Imgui is the example applications, which are great as a reference and starting point for your own projects. Many different platforms and rendering APIs are covered.

Also be sure to check out the 'docking' branch, which implements docking panels and tearaway windows in the style of Visual Studio. There are many low quality versions of this concept in other GUI libraries but I think Dear Imgui's version is the best I've seen outside of Visual Studio itself.

[+] Torkel|5 years ago|reply
Happy to see ImGui trend here on HN!

It is an amazing tool that is used in a lot of game engines for making internal/dev gui:s. The principle of drawing gui "as you go", interleaved with control flow makes it easier+faster to make gui:s.

In our company's main app we use ImGui (with customizations) for all gui work (from C++ and Rust).

[+] varispeed|5 years ago|reply
This is neat, but the problem I always had in these type of libraries is that they only work enough for the examples to be usable. As soon as I wanted to do something that was not in examples, that would either won't work at all or needed a horrible hack to work. I can't give a real example from the top of my head, but I am thinking like the examples would not show how to do a modal popup window and then you learn when you try to instatiate such window then the other window goes crazy or if you close the modal window everything closes and there would be no way to fix it other than digging into library code. I hope this one is not like that.
[+] MattRix|5 years ago|reply
Dear ImGui is not some half-baked experiment. It's used in tons of real world projects right now. The main way I've seen it used is for developer-facing GUI (debug views, tool/editors, etc)
[+] softawre|5 years ago|reply
Did you read far enough in the readme to see the screenshots of the projects using this already? Those look like very complex UIs, and at least one of them is open source for you to look at.
[+] DonHopkins|5 years ago|reply
I agree. They work fine for simplistic interfaces with a few buttons, but what about more complex widgets, like plain/rich/code text editors, that have a lot of different callbacks and fire many different asynchronous events?

Sure, a button function that returns a boolean can be used as a simple parameter to an if statement, but you would would need a switch statement to test for all the different events that a text editor could send. That's a terrible clumsy API! And where do you store the complex state of the attributed text, or parsed source code in a code editor? Do you just pass the entire string in every frame and re-parse html each time?

Where do you store and how do you access all the hidden state, like keyboard focus, cursor position, editing modes, etc, that object oriented user interfaces simply expose as properties, getters or setters?

And how do you implement an outliner? Do you have to write recursive immediate code that traverses the entire tree every frame? Where do you store the outline opened/closed state, per-item state, and the cursor position?

You can't just store that state in the actual objects you're showing in the outline, because that mixes your user interface layer with your data modeling layer. The cure is worse than the disease. You end up cobbling together your own spaghetti-coded special-purpose object oriented retained mode adaptation layer, just what you were trying to avoid by using immediate mode in the first place.

And how do you implement efficient scrolling lists or tables or spreadsheets containing thousands or even hundreds of thousands of items? Do you have to pass every single item through the API every frame, instead of implementing callbacks to only pass and cache the items that fit on the screen?

And how do you implement graphics editors? Or drag and drop previewing? Or popping up item specific menus and submenus when you right-click on a list or outline item? Or anything more complex than a simple button?

Objects and closures and asynchronous event handlers are the best thing that happened to user interface programming since the pixel. Use them!

[+] hartmel|5 years ago|reply
- the developer is the creator of MEKA, a (1998!) Sega Master System emulator, which had the reputation to be the best during a long time (and still may be, I don't know anymore)

- WonderBoy Dragon's Trap remake and Street Of Rage 4 for PC/consoles, it's him too

I may be wrong, but following the screenshots, the Dragon's Trap development was like : we need tools to write a game ! let's write it ! Wait we need libraries to write tools ! let's write them !

The quality of the game and all the details reflect impressive skills and amount of work.

[+] perfunctory|5 years ago|reply
I like ideas behind immediate mode gui. It's a bit like React.js only without DOM in between. It's not ideal, it has its own issues, but it could develop further into something more robust, I hope.

GUI is hard.

[+] srikz|5 years ago|reply
Dear ImGui is excellent and is very handy to make GUI version of a CLI app especially if we want to interactively set values and see results.

It is fairly low level (deliberately) and that’s great to keep it simple. I wish there is a standalone GUI ‘framework’ which builds on these primitives and leans on standard library to make the experience a bit more nicer when building standalone applications.

I understand this is not the goal of Dear ImGui. I may give it a shot in a few months time if I don’t come across any such project.

[+] andybak|5 years ago|reply
I haven't properly thought this through but is here a sense in which the React "one way data flow" paradigm is a case of rediscovering immediate mode GUIs on the web?
[+] flohofwoe|5 years ago|reply
IMHO there's a lot of overlap between the reactive UI philosophy and the immediate mode UI philosophy. The main difference is IMHO that React is "mainly data" while IMGUI is "mainly code". But code is data and data is code, so... :)
[+] gauchojs|5 years ago|reply
I love it until I have to do modals..
[+] enriquto|5 years ago|reply
Widgets are bloat.

Is there a similar library but without widgets? Something really, really simple. I just want a canvas to draw, and a handler to receive mouse and keyboard events. No windows, no text, just a framebuffer.

Back in the day I was really happy with glut and opengl. You just took the three-line hello world and started drawing stuff without fuss. ImGui seems too unnecessarily complicated for me.

[+] dgr582systems|5 years ago|reply
Dear ImGui is so easy to get working compared to other similar C++ libraries. For small dev teams using C++ that alone makes it super valuable.

I hate losing a day to figure out how to link in some crazy, clashing dependencies. Never had that problem with this library.

[+] FullyFunctional|5 years ago|reply
Over decades, I had developed an almost not-invented-here attitude exact because dependencies are always such a pita (oh Python hell) and drag in a lot of bloat. Rust is the first language I have used where external dependencies (from crates.io) Just Works(TM). However they can still drag in bloat :)
[+] grliga|5 years ago|reply
"Dear ImGui is designed to enable fast iterations and to empower programmers to create content creation tools and visualization / debug tools (as opposed to UI for the average end-user)."
[+] phkahler|5 years ago|reply
>> You will need a backend to integrate Dear ImGui in your app. The backend passes mouse/keyboard/gamepad inputs and variety of settings to Dear ImGui, and is in charge of rendering the resulting vertices

Some people say this thing is platform agnostic, which is sort of true. But in no way does it give you a multiplatform GUI. You must provide this "backend" for every OS you want to run on. If you decide to handle that with QT, GTK, or WX, then what use is this?

[+] tom_|5 years ago|reply
If you are already using qt, gtk or wx, then dear imgui is not really aimed at you. The intended use case is more the situation where you already have what you term the backend, and you want to add a gui to your program.

(There's not much that's platform-specific in dear imgui, so you end up with a GUI that's as multiplatform as your program is.)

[+] kevingadd|5 years ago|reply
Game devs are probably using SDL2 or equivalent, at which point they can just use SDL2's simple cross-platform primitives to get everything they need to use Dear ImGUI.
[+] database_lost|5 years ago|reply
I don't work that much with GUI applications, but Dear ImGui was perfect for a past project and I just wanted to chime in on the positive feedback :) Take care everyone!
[+] aquova|5 years ago|reply
I'm curious on what opinions are on Dear ImGui's bindings in other languages, namely Rust. imgui-rs seems to be one of the only mature-ish GUI libraries, but I found myself struggling with it. The multiple window "debug view" looks great, but for something like an OpenGL window with a simple menu bar, I found it difficult to create. There is also apparently no file picker widget, which I found to be a big downside.
[+] pansa2|5 years ago|reply
Qt seems to be the most popular library for cross-platform GUI apps written in C++. Is Dear ImGui a credible alternative?

How does Dear ImGui compare to Qt?