I've been integrating this great little library into my engine and noticed that the render functions in the example code doesn't save render and texture state which did cause issues with my engine.
Here is what I did to solve this. At the start of the RenderDrawList function, I save both program and texture state:
static void ImGui_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
if (cmd_lists_count == 0)
return;
//
// save current program/texture state
GLint nLastProgram = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &nLastProgram);
GLint nLastTexture = 0;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &nLastTexture);
and then at the end before leaving, I restore it:
// Restore modified state
glBindVertexArray(0);
glUseProgram(nLastProgram);
glDisable(GL_SCISSOR_TEST);
glBindTexture(GL_TEXTURE_2D, nLastTexture);
Hope this helps someone! Might be worth adding to the examples?
i think in the bundled examples this code has no benefit besides being noise. of course integrating it in an engine >may< make this necessary but that depends totally on the usage scenario and should not be part of those examples in my opinion
Well in my case, rather than re-write the render function, I just kept it as is. Seemed like the simpler solution and so I just wanted to save someone else a few hours of figuring out why things were randomly crashing after ImGui::Render was called! :)
why rewrite your render function ? you can simply wrap the ImGui::Render inside the two blocks you posted here?!
Right that's what I'm saying. No one should re-write anything.
Most people who get this library will grab the render function in the examples that best suits their needs and keep going. So I went with the GL 3 demo and just modified the ImGui_ImplGlfwGL3_RenderDrawLists function and in doing so, ran into this small issue with state preservation hence why I posted what I did. :)
If you do this, you need save and restore all render states.
You are correct and ideally we should save/restore all render states, which appears to be a bit of a faff with modern GL. I don't even know how to do it for some of the state modified. I suppose it wouldn't hurt saving/restoring those two.
Out of curiosity why didn't you use the simpler fixed-pipeline GL codebase? That works as well.
I suppose I could have but to stay consistent with my current engine's code base, I went with the GL3 example. :)
is it allowed to even call the legacy immediate mode API from a >=3 ogl context ?
Yes of course. Lots of code depends on it and it's quite widely supported (even if it's probably annoying for the drivers maintainers..). OpenGL being such a mess it is quite helpful sometimes.
I'll close this. I realize we're not saving everything. If someone wants to come up with a patch that saves everything I might consider it but I guess it'll be too bulky.
Those two states (shader and textures) are the most likely to break people software who use the GL3 example code in a way that's confusing for a short while. So fixing them is good. The other states we changes consists in disabling depth testing, disabling culling, enabling blending, enabling scissoring, the effect of those leak if any, should be easiest to assess.
Interesting! This is what I have been struggling recently :)
Thanks for sharing!
@richardlalancetteyoui Could you clarify the issue you were having? Because this thread is very old and AFAIK we have added code to save and restore much more OpenGL state in imgui_impl_opengl.cpp in the past few years.
I believe our engine is breaking IMGUI.
I can render IMGUI in GLFW3 on its own window, but as soon as I combine it with our SDK, our engine renders, but IMGUI is gone.
I doubt it has anything to do with IMGUI, probably something in our SDK.
Works if I have 2 windows/contexts:

Won't work if I combine them into one window/context.

Ideally if you could narrow it down to which GL state is getting in the way we should patch imgui_impl_opengl3 to explicitely reset/set/restore it.
Yup, I guess, that's my next step. Using https://github.com/ocornut/imgui/tree/master/examples/example_glfw_opengl2
ATM.
Thats likely the first source of your problem, you shouldn鈥檛 use the _opengl2 code with modern opengl, it鈥檚 written all over this back-end.
Ah! opengl3 it is then! Thank you!
Looks like I'm stuck with OPENGL2 for now. Until the SDK group upgrades to 3.
I'll fix the render states and hopefully post a PR soon.
Thank you!
For future references, this is what I ended up doing to get our engine to cooperate well with IMGUI using opengl2:
SetupIMGUI(pUswishWindow);
// Push IMGUI states for reuse
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
glPushAttrib(GL_ALL_ATTRIB_BITS);
while (Running)
{
glfwPollEvents();
glfwMakeContextCurrent(pUswishWindow);
glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
RenderUswish(pUswishWindow);
glUseProgram((GLuint) last_program);
// Restore states again before rendering IMGUI
glPopAttrib();
glPopClientAttrib();
RenderIMGUI(pUswishWindow);
// Push clean states again before rendering uswish
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
glPushAttrib(GL_ALL_ATTRIB_BITS);
pApp->Swap();
}
Most helpful comment
Well in my case, rather than re-write the render function, I just kept it as is. Seemed like the simpler solution and so I just wanted to save someone else a few hours of figuring out why things were randomly crashing after ImGui::Render was called! :)