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

Multiple Contexts #1

Closed
mchristianl opened this issue Mar 31, 2019 · 5 comments
Closed

Multiple Contexts #1

mchristianl opened this issue Mar 31, 2019 · 5 comments

Comments

@mchristianl
Copy link

mchristianl commented Mar 31, 2019

Hello, I have just recently read about this Wrapper. Thank you for porting!

For a multi-window setup I found that SetCurrentContext is exported, but additionally I had to manually save and restore all global variables g_* from CImGui.OpenGLBackend and CImGui.GLFWBackend

per-window setup

  if isa(state.lastImGuiPlot,Base.RefValue)
    saveImGuiState(state.lastImGuiPlot[])
    state.lastImGuiPlot = Ptr{PlotState}(C_NULL)
  end
  CImGui.OpenGLBackend.__init__()
  CImGui.GLFWBackend.__init__()
  p.imguictx = CImGui.CreateContext()
  CImGui.SetCurrentContext(p.imguictx)
  CImGui.StyleColorsDark()
  ImGui_ImplGlfw_InitForOpenGL(p.window, false)
  ImGui_ImplOpenGL3_Init(glversion)
  saveImGuiState(p)

rendering:

    CImGui.SetCurrentContext(p.imguictx)
    restoreImGuiState(p)
    ImGui_ImplOpenGL3_NewFrame()
    ImGui_ImplGlfw_NewFrame()
    CImGui.NewFrame()
    ...

with something like this

function saveImGuiState(p :: PlotState)
  p.imgui_opengl_state.g_AttribLocationColor     = CImGui.OpenGLBackend.g_AttribLocationColor
  p.imgui_opengl_state.g_AttribLocationTex       = CImGui.OpenGLBackend.g_AttribLocationTex
  p.imgui_opengl_state.g_FontTexture             = CImGui.OpenGLBackend.g_FontTexture
  p.imgui_opengl_state.g_ImageTexture            = CImGui.OpenGLBackend.g_ImageTexture
  p.imgui_opengl_state.g_VertHandle              = CImGui.OpenGLBackend.g_VertHandle
  p.imgui_opengl_state.g_AttribLocationPosition  = CImGui.OpenGLBackend.g_AttribLocationPosition
  p.imgui_opengl_state.g_AttribLocationUV        = CImGui.OpenGLBackend.g_AttribLocationUV
  p.imgui_opengl_state.g_FragHandle              = CImGui.OpenGLBackend.g_FragHandle
  p.imgui_opengl_state.g_ShaderHandle            = CImGui.OpenGLBackend.g_ShaderHandle
  p.imgui_opengl_state.g_AttribLocationProjMtx   = CImGui.OpenGLBackend.g_AttribLocationProjMtx
  p.imgui_opengl_state.g_ElementsHandle          = CImGui.OpenGLBackend.g_ElementsHandle
  p.imgui_opengl_state.g_GlslVersion             = CImGui.OpenGLBackend.g_GlslVersion
  p.imgui_opengl_state.g_VboHandle               = CImGui.OpenGLBackend.g_VboHandle

  p.imgui_glfw_state.g_ClientApi                 = CImGui.GLFWBackend.g_ClientApi
  p.imgui_glfw_state.g_ImplGlfw_SetClipboardText = CImGui.GLFWBackend.g_ImplGlfw_SetClipboardText
  p.imgui_glfw_state.g_MouseJustPressed          = CImGui.GLFWBackend.g_MouseJustPressed
  p.imgui_glfw_state.g_Window                    = CImGui.GLFWBackend.g_Window
  p.imgui_glfw_state.g_ImplGlfw_GetClipboardText = CImGui.GLFWBackend.g_ImplGlfw_GetClipboardText
  p.imgui_glfw_state.g_MouseCursors              = CImGui.GLFWBackend.g_MouseCursors
  p.imgui_glfw_state.g_Time                      = CImGui.GLFWBackend.g_Time
end

function restoreImGuiState(p :: PlotState)
  if isa(state.lastImGuiPlot,Base.RefValue)
    saveImGuiState(state.lastImGuiPlot[])
  end
  state.lastImGuiPlot = Ref(p)
  CImGui.OpenGLBackend.Set_g_AttribLocationColor(    p.imgui_opengl_state.g_AttribLocationColor)
  CImGui.OpenGLBackend.Set_g_AttribLocationTex(      p.imgui_opengl_state.g_AttribLocationTex)
  CImGui.OpenGLBackend.Set_g_FontTexture(            p.imgui_opengl_state.g_FontTexture)
  CImGui.OpenGLBackend.Set_g_ImageTexture(           p.imgui_opengl_state.g_ImageTexture)
  CImGui.OpenGLBackend.Set_g_VertHandle(             p.imgui_opengl_state.g_VertHandle)
  CImGui.OpenGLBackend.Set_g_AttribLocationPosition( p.imgui_opengl_state.g_AttribLocationPosition)
  CImGui.OpenGLBackend.Set_g_AttribLocationUV(       p.imgui_opengl_state.g_AttribLocationUV)
  CImGui.OpenGLBackend.Set_g_FragHandle(             p.imgui_opengl_state.g_FragHandle)
  CImGui.OpenGLBackend.Set_g_ShaderHandle(           p.imgui_opengl_state.g_ShaderHandle)
  CImGui.OpenGLBackend.Set_g_AttribLocationProjMtx(  p.imgui_opengl_state.g_AttribLocationProjMtx)
  CImGui.OpenGLBackend.Set_g_ElementsHandle(         p.imgui_opengl_state.g_ElementsHandle)
  CImGui.OpenGLBackend.Set_g_GlslVersion(            p.imgui_opengl_state.g_GlslVersion)
  CImGui.OpenGLBackend.Set_g_VboHandle(              p.imgui_opengl_state.g_VboHandle)

  CImGui.GLFWBackend.Set_g_ClientApi(                 p.imgui_glfw_state.g_ClientApi)
  CImGui.GLFWBackend.Set_g_ImplGlfw_SetClipboardText( p.imgui_glfw_state.g_ImplGlfw_SetClipboardText)
  CImGui.GLFWBackend.Set_g_MouseJustPressed(          p.imgui_glfw_state.g_MouseJustPressed)
  CImGui.GLFWBackend.Set_g_Window(                    p.imgui_glfw_state.g_Window)
  CImGui.GLFWBackend.Set_g_ImplGlfw_GetClipboardText( p.imgui_glfw_state.g_ImplGlfw_GetClipboardText)
  CImGui.GLFWBackend.Set_g_MouseCursors(              p.imgui_glfw_state.g_MouseCursors)
  CImGui.GLFWBackend.Set_g_Time(                      p.imgui_glfw_state.g_Time)
end

Is there a chance to have these two variable-sets attached to the "current" ImGui context?

regards,
Christian

@Gnimuc
Copy link
Owner

Gnimuc commented Apr 1, 2019

These global GLFW/OpenGL states are holding temporarily only for rendering purpose. They're not ImGui states. Almost all of them are refreshed in every rendering loop when calling:

ImGui_ImplOpenGL3_NewFrame()
ImGui_ImplGlfw_NewFrame()

except g_Window and g_FontTexture. So the hot-fix would be to remove the optimization trick g_FontTexture == 0 used in this line:

g_FontTexture == 0 && ImGui_ImplOpenGL3_CreateDeviceObjects()

and make ImGui_ImplGlfw_NewFrame() aware of current GLFW window context:

function ImGui_ImplGlfw_NewFrame()

function ImGui_ImplGlfw_NewFrame(window)
    global g_Time
    global g_Window = window

then this modified example will work: https://gist.github.com/Gnimuc/b9308bb8ed0a81b4fe1e76d706837f3d

@mchristianl
Copy link
Author

Thank you for the example!

except g_Window and g_FontTexture

nice.

I am still experiencing some issues with that fix, that seem to be related to the event handling: for example, in your code multicontext.jl I sometimes cannot close window1 and only window2 and sometimes the other way around.

Also it seems that currently there is no possiblity to manage the callbacks manually via

ImGui_ImplGlfw_MouseButtonCallback
ImGui_ImplGlfw_ScrollCallback
ImGui_ImplGlfw_KeyCallback
ImGui_ImplGlfw_KeyCallback

which might be of interest also for single multiple contexts.

regards,

@Gnimuc
Copy link
Owner

Gnimuc commented Apr 1, 2019

That's because the script didn't destory GLFW windows instance in the rendering loop: https://gist.github.com/Gnimuc/b9308bb8ed0a81b4fe1e76d706837f3d#file-multicontext-jl-L118-L123
This can be fixed by something like:

# in rendering loop
GLFW.PollEvents()
if GLFW.WindowShouldClose(window1)
    CImGui.DestroyContext(ctx1)
    GLFW.DestroyWindow(window1)
end

As for the callbacks, I didn't implement that because I thought they were not very useful in that one can always overload these callbacks before GLFW initialization. But this feature is very simple to implement by following:
https://github.com/ocornut/imgui/blob/d9568c717de8ec53445bad00be73133f1a110317/examples/imgui_impl_glfw.cpp#L82-L83

so feel free to submit a PR. Or I'll fix it this weekend.

@mchristianl
Copy link
Author

Indeed, I got it working in the way you proposed; the "issues" were just in my implementation. Could resolve them now

@Gnimuc
Copy link
Owner

Gnimuc commented May 30, 2021

UPDATE:

Now the master branch supports multi-viewport and this multiple contexts support is being removed since it's not recommended to use Dear ImGui in this way. Also, see #52.

JamesWrigley added a commit that referenced this issue Jun 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants