
Using ImGui with modern C++ and STL for creating game dev tools – Part 2 - eliasdaler
https://eliasdaler.github.io/using-imgui-with-sfml-pt2
======
flohofwoe
Dear Imgui is absolutely awesome, first time in my life where I'm actually
enjoying writing UI code. AFAIK it was an intentional (and IMHO good) design
decision to not tie the API to the C++ std library, this makes imgui more
widely usable, for instance in code bases that also don't use the STL,
exceptions or RTTI (and that's quite common in the game development world), it
also makes it easier to write wrappers for other languages.

Check out what people have been doing with Dear Imgui:

\-
[https://github.com/ocornut/imgui/issues/123](https://github.com/ocornut/imgui/issues/123)

\-
[https://github.com/ocornut/imgui/issues/539](https://github.com/ocornut/imgui/issues/539)

~~~
eliasdaler
Yup, there's no doubt that it's awesome that ImGui doesn't force you to use
some particular library.

But for people already using STL and integrating ImGui with their codebase,
using STL with ImGui may be somewhat difficult and that's why I wrote the
article about things that worked for me. :)

------
Keyframe
For C, there's C wrapper
[https://github.com/Extrawurst/cimgui](https://github.com/Extrawurst/cimgui)
and another library Nuklear
[https://github.com/vurtun/nuklear](https://github.com/vurtun/nuklear) which
is also really nice.

------
CyberDildonics
I'm surprised immediate mode guis have taken such a long time to take hold.
The separation of data and drawing in very elegant after having come from ui
systems where your widgets essentially end up being data structures.

------
golergka
Immediate mode GUI still has a huge drawback - running UI code every frame.
It's not a big deal with simple widgets, but with complicated UI, especially
with some kind of automatic layout involved, it becomes a pain.

In Unity3d game engine in particular, IMGUI was originally used, and it was a
huge performance drain. Now all the "real" UIs have been moved to a new,
object-based system (with a LOT of caching and optimization), but IMGUI is
still used for quick prototyping and debug UIs.

~~~
pcwalton
It all depends on how complex your layout is.

I think the arguments that "well, games redraw the HUD every frame and it's
fine, so why is recreating the UI every frame a problem?" are misunderstanding
the problem. HUDs usually don't have much _layout_ to do: in CSS terms,
everything is absolutely positioned. Designers usually create HUDs visually
using Flash or similar, so the layout ends up being trivial since, in effect,
a human has already manually calculated the positions of every widget. For a
programmatically-created GUI, though, there is actually layout to perform,
usually via a flexbox-like model but sometimes via a constraint solving system
(which makes the time complexity go way up). For this to be efficient you need
a way to cache the results of layout so that you only recompute them from
frame to frame when needed. This caching is precisely what a retained mode UI
_is_.

For those who think that layout is always fast enough to never be a
performance problem, try writing a flexbox UI in your browser, then open the
dev tools, resize the window (which will trigger a full relayout if you don't
have any explicit widths in there) and see how long the layout takes. It often
eats up the time budgets of multiple frames (and this is not just browsers
being slow--the complexity is inherent).

This is not to say IMGUI is bad, mind you! It's a great solution for debug
overlays, which is what it was originally designed for, because of how simple
it is. Just don't overstate its benefits: retained mode UIs exist for a
reason.

~~~
panic
At a clock rate of 2 GHz, at least 64 million cycles will elapse during
multiple frames (> 32 milliseconds) of layout. What makes flexbox layout so
inherently complicated that computing it takes such a huge number of
operations? Maybe we should come up with ways of specifying layout that take
fewer operations to compute.

~~~
eddyb
But how many times can you access the DRAM in that time?

One thing you have to keep in mind is that the more dynamic the scene graph,
and the larger its memory footprint, the more frequent you'll miss the cache
while traversing it.

It's possible to manually write optimized flex-box-like layout code, where the
overall structure, if not exact position, is mostly static.

For example, if you always have one resizable panel to the side of two
viewports, of equal width (as is the case in the editor I use atm), you can
easily do `viewport_width = (total_width - panel_width) / 2` and be done.

Those operations, if done with integers, should be _faster_ than a read from
cache, or if done with floating-point numbers, (much) faster than going to
DRAM in the even of a cache miss.

However, doing all of that by hand would be a pain, and it's hopeless in the
face of user customization. SIMD is another resource that's _completely
unusable_ in the face of truly dynamic data, and a time sink to do manually.

What we're missing is _automation_ of mostly-static UIs, generating
specialized code and optimizing it into computations that run under a
microsecond. For HTML, the hope would be JITs, but highly dynamic DOMs are
still all over the place, so you're not going to have as many gains as a
dedicated UI system, and it wouldn't be free for the user.

~~~
panic
Yes, exactly! It seems like immediate-mode GUIs could actually lay out faster
than retained-mode: you don't have a scene graph, and the layout code is just
normal code that can be optimized by the compiler.

~~~
pcwalton
Layout code is _always_ "normal code that can be optimized by the compiler".
Why wouldn't it be?

I think you're referring to applying optimizations to static UI with constant
data structures, but that can be done with retained mode too, and I doubt it
actually is going to help.

------
hellofunk
How would this UI library work on an iOS OpenGL project? I would expect it to
display fine, but maybe lining up the touches with the buttons could require
some extra thought.

------
aDevilInMe
<StlIsTheWrongName>If writing "modern C++", why do you want to use a really
old library, STL, why not instead use the "Standard Library"?
</StlIsTheWrongName>

~~~
StephanTLavavej
As an STL maintainer, I can say that using "STL" to refer to "the C++ Standard
Library" is a perfectly valid use of metonymy.

~~~
aDevilInMe
Do you not maintain threads, RegEx etc... ? At best STL can be reffered to as
a subset of the Standard Library, which contains the algorithms and containers
framework. I take Stroustrup's word over a maintainer with the intials STL,
who has an interest to keep calling it by this name.

~~~
to3m
No, the STL doesn't exist any more, at least as a going concern. That's why
it's metonymy. It sounds like you're thinking of synecdoche.

