【问题标题】:ImGui is not being displayed没有显示 ImGui
【发布时间】:2017-07-21 17:13:09
【问题描述】:

我正在尝试在 Windows 上制作 OpenGL 程序。由于主 exe 文件越来越大,我决定将其拆分为 DLL。这就是我的问题的开始。

对于 ImGui 函数,我创建了一个类。这是我班级的 render() 函数:

cout << "render" << endl;
imgui_newFrame();
{
    ImGui::SetNextWindowSize(ImVec2(30, 30), ImGuiSetCond_FirstUseEver);
    ImGui::Begin("Test", &show_another_window);
    ImGui::Button("Test Window");
    ImGui::End();
}
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
ImGui::Render();

在我的类中调用 render() 函数之前,我在我的类中的另一个函数中启动 ImGui:

if (!imgui_init(glfw_window)) {
    return false;
}

这是我的主要 glfw 循环:

while (!glfwWindowShouldClose(window)) {
    glClear(GL_COLOR_BUFFER_BIT);
    glfwPollEvents();
    MyMyGuiClass.render(); //here i ask my class to render imgui
    glfwSwapBuffers(window);
}

使用此代码,我可以使 ImGui 清除窗口颜色(glClearColor 功能有效,我的控制台打印“渲染”)

但它没有显示任何其他内容。

顺便说一下,这是我运行时完美运行的命令。

while (!glfwWindowShouldClose(window)) {
    glClear(GL_COLOR_BUFFER_BIT);
    glfwPollEvents();
    imgui_newFrame();
    {
        ImGui::SetNextWindowSize(ImVec2(30, 30), ImGuiSetCond_FirstUseEver);
        ImGui::Begin("", &show_another_window);
        ImGui::Button("Test Window");
        ImGui::End();
    }
    glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
    ImGui::Render();
    glfwSwapBuffers(window);
}

我使用的是 VS2017,我的编译器在编译时没有显示任何警告或错误。我也试图让我的班级的功能静态,但我什么也没得到。

这么简单,ImGui 在类内部调用时是否无法呈现?

【问题讨论】:

  • "由于主 exe 文件越来越大,我决定将其拆分为 DLL。"这不是 DLL 应该解决的问题(库重用等)。无论如何都会加载所有内容。
  • 调试和构建一个巨大的 exe 需要时间。这就是我想说的。

标签: c++ opengl glfw


【解决方案1】:

您遇到的问题是 ImGui 维护一个全局状态,并且该状态必须保存在某个地方。 ImGui 将其保存在 module-local 全局符号中。

注意这里的“模块本地”!这意味着每个 DLL(和主 EXE)都有自己的那个状态的副本。因此,在 DLL “A”(或 EXE “1”)中使用 ImGui 执行操作将在其自己的 ImGui 状态实例上运行。

有一个解决方案,就是让令人讨厌的 ImGui 全局状态在 DLL 之间共享。 如何在 DLL 之间共享数据在 MSDN https://msdn.microsoft.com/en-us/library/h90dkhs0(v=vs.90).aspx 中进行了描述 - 至于 ImGui 本身的详细信息。它主要归结为正在使用的 ImGuiContext。目前这是一个模块局部全局变量,但 ImGui 开发人员计划使其显式地在每次调用和最终用户管理。

来自 ImGui 代码的评论:

// Default context storage + current context pointer.  Implicitely used by all
// ImGui functions. Always assumed to be != NULL. Change to a different context
// by calling ImGui::SetCurrentContext() ImGui is currently not thread-safe
// because of this variable. If you want thread-safety to allow N threads to
// access N different contexts, you might work around it by: - Having multiple
// instances of the ImGui code compiled inside different namespace
// (easiest/safest, if you have a finite number of contexts) - or: Changing
// this variable to be TLS. You may #define GImGui in imconfig.h for further
// custom hackery. Future development aim to make this context pointer explicit
// to all calls. Also read https://github.com/ocornut/imgui/issues/586

【讨论】:

  • 好吧,我认为只需通过函数参数传递变量就可以做到这一点,但显然我错了,而且我没有阅读作者的 cmets。谢谢你的麻烦。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-31
  • 2022-07-12
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多