-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
RFC: Proposal for a BeginRender / EndRender "widget" for custom, backend based rendering #4139
Comments
I don't think your idea is feasible. |
I'm not sure I fully understand your proposal, but it appears to be part of what would constitute a game/graphics engine and is out of the scope of dear imgui. dear imgui doesn't aim to replace features that would be present in the host engine. "draw to texture" is such a very large and open ended topic (merely having to consider texture storage memory and texture formats gets us into a very deep pit that's largely out of our scope). However, as part of #3761 and other changes, it is possible that we may end exposing a concept of textures managed and delete by the backend (primarily for the purpose of managing dynamic font atlas and multiple in-flight font atlas). Those may be end up having other convenient uses tangential to your. |
This was one of my questions in another query yesterday (which I was sleeping on before posting). What would be ideal is the ability to enter a function and set an "instant_render" flag, from which point any imgui outputs were rendered, buffered and swapped as they were called while leaving the remainder of the frame intact. Looking at the library code it might be feasible to either create an ImGui::Render() alternative which only rendered the last call, or a function which then took the imgui call as a passthrough, and triggered the buffering and swap functions but as I only found imgui 2 days ago and I seem to had to write a lot of basic code to get it to do simple tasks (probably because I don't understand it's full scope yet) I haven't got under the hood sufficiently to be sure. My Issue/Question: I want to be able display progress of a process within a window without constantly returning to the main render loop, and ideally without multithreading my application. So my question is how best to do that. I've identified how to (rather badly) re-render a frame from within a function (with my minimal code below). But I wonder if its possible to copy the frame information and use it as the beginning of the next frame and just append new information to it. Presumably I could also restrict the bufferswap to only repaint the parts I needed, but I'm not sure how to identify what has been invalidated by imgui. Incidentally, @ocornut Thank you for your responses to my other post. My apologies - I was trying NOT to hog you attention by putting all the questions in one place. Standalone, minimal, complete and verifiable example: (see #2261)
|
I feel like your question is off topic to what's being discussed in this thread. To quickly answer your question though: If you want your UI to be interactive while intensive compute is happening at the same time, your program is inherently no longer linear. You should be marshaling the information you want to present in the UI from your background compute thread to the UI thread. (Also not sure why you describe this as "a pain", that doesn't strike me as painful at all, especially if it's just a progress bar.) I don't think the solution you're proposing is nearly as simple as you think it would be and has a bunch of problems you aren't considering. (Especially around input.) Dear ImGui ties a lot of internal things to the concept of a specific frame and is inherently single-threaded. If you really think this is something you need, you should open another thread and justify why marshaling data between threads is painful in your situation. |
Thanks for your response, and apologies yet again, I thought the redraw aspect was relevant.
|
The currently recommended methods to embed direct rendering into ImGui windows is to either
Each methods has some drawbacks with regard to "ease of use". Among the things that make ImGui so outstanding is, the ease with which UI elements are created: Just call the widget function, passing a pointer to the variable and you're done.
Unfortunately when it comes to adding things rendered directly with the backend, there's some substancial overhead involved. In case of using ann offscreen texture, that texture, together with a framebuffer configuration must be created and managed; in case of UIs created in-situ based on program state this adds the dificulty of texture (and framebuffer) lifetime management, since actually drawing those elements is deferred until
ImGui::Render
. In effect one ends up lobbing around some extra state, usually in some global variable.The use of the callback mechanism sidesteps the proxy object creation, but its usage ties it to internals of ImGui thereby creating additional work in case of internal API changes.
I'm proposing the introduction of a
BeginRender
/EndRender
widget, that offers an abstraction for the canonical draw-to-texture-and-AddImage method, including proxy object lifetime management (delete proxy objects created in a previos frame, if they're not touched between implementationnew frame
andImGui::Render
(or simply if they're not touched between two subsequent calls ofImGui::Render
).Before I actually go ahead implementing such a feature I'd like to inquiry comments and hints for this. My current thinking is to have a pair of functions
with
ImRenderCtx
being a backend dependent type. The semantics would be, that for stateful APIs, like OpenGL "everything" has been set up to match the destination image (viewport, framebuffer object, etc.) and drawing may commence right away (i.e. in the case of OpenGL-2 or a compatibility profile glBegin/glEnd might be done right away). For buffer based APIs (i.e. Vulkan) that context would offer appropriately prepared render pass, synchronization and means to store pipeline and command buffers for eventual cleanup).Usage then would follow the usual steps of
if( Begin ){ ... End; }
And thoughts on that?
The text was updated successfully, but these errors were encountered: