Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fitting ImGui into independent update/render rates #1052

Open
MrSapps opened this issue Mar 2, 2017 · 11 comments
Open

Fitting ImGui into independent update/render rates #1052

MrSapps opened this issue Mar 2, 2017 · 11 comments

Comments

@MrSapps
Copy link

MrSapps commented Mar 2, 2017

A lot of engines work in a way where update is called at a fixed rate, and then render also happens at an independent (usually as fast as possible) rate.

How does ImGui fit in to this sort of usage pattern? Right now it appears ImGui calls should be in render, but then a change in frame rate would also change the logic update rate which seem wrong?

@ratchetfreak
Copy link

you can draw imgui multiple times in a row (with the same visuals) without doing the newframe render cycle by using the GetDrawData method.

That lets you keep the imgui calls inside the update call.

@MrSapps
Copy link
Author

MrSapps commented Mar 3, 2017

so

update -> ImGui calls/logic
render -> other stuff that isn't ImGui?

@ratchetfreak
Copy link

You setup imgui without a io.RenderDrawListsFn function.

update does the ImGui::NewFrame(); ... ImGui::Render();

render does drawImgui(ImGui::GetDrawData());

@MrSapps
Copy link
Author

MrSapps commented Jun 4, 2017

With this method I assume its not possible to use ImGui calls within Render anymore? I.e they must all live within the update cycle?

@ocornut
Copy link
Owner

ocornut commented Jun 4, 2017

You can't call any ImGui widget functions after calling ImGui::Render() before the next ImGui::NewFrame().
Usually ImGui::Render() would be called at the very end of your own rendering, so you can use imgui widgets within the rendering of your game/engine.

@MrSapps
Copy link
Author

MrSapps commented Jun 4, 2017

The problem I have is that I only wanted to do the "logic" parts in Update, which means putting ImGui::* calls in there. However there was one case where I wanted to also have calls within my Render which doesn't work when used this way. Which makes sense because there can be unbalanced amounts of Update/Render calls.

@ocornut
Copy link
Owner

ocornut commented Jun 4, 2017

Perhaps using two separate imgui context would allow for this.

@tim-rex
Copy link
Contributor

tim-rex commented Oct 20, 2019

Perhaps using two separate imgui context would allow for this.

I think this is where I'm at right now.
I have update/render operations decoupled into separate threads. All ImGui handling currently occurs on the render thread.

A side effect of this is that ImGui will start to miss input events whenever the rendering performance drops off (since input is processed asynchronously, this is effectively a race condition on GetIO having visibility of the input state).

Using two separate ImGui contexts seems interesting, but the render context would still be subject to missed IO events in such cases.

One way forward would be to implement a buffered interface to GetIO (and if I want to avoid synchronising between those threads, I'll need a buffer for each thread). I'm not sure I want to go down that path..

Maybe I'm thinking about this the wrong way?

@ocornut
Copy link
Owner

ocornut commented Oct 20, 2019 via email

@tim-rex
Copy link
Contributor

tim-rex commented Oct 21, 2019

That looks pretty interesting! Nice. I'll have a play around.

@ocornut ocornut changed the title Fitting ImGui into an update -> render cycle Fitting ImGui into independent update/render rates May 25, 2023
@ocornut
Copy link
Owner

ocornut commented May 25, 2023

This has been a surprisingly frequent question over the years and I have renamed and better labelled this issue accordingly.

Using two separate ImGui contexts seems interesting, but the render context would still be subject to missed IO events in such cases.

This wouldn't apply as they would each have their own set of IO.
Even thought we did formalize the input queue since this was posted, it shouldn't apply directly to this issue.

The TL;DR; is that you would need two independent context, and right now you would likely want to have some sort of global switch between Update and Render domains. Maybe use a different color styles for title-bar to make it evident which is which.

Aside from making context pointer explicit (#5856) I believe there's one big room for improvement:

Instead of requiring app to fully toggle between two contexts, we could make it easier to composite two contexts (or a small number of contexts).

  • By facilitating rendering both overlayed into each others (this is probably trivial already).
  • By facilitating pipping inputs from engine/backend into one or the other depending on mouse position.
  • Perhaps by providing ways for e.g. drag and drop to work across contexts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants