You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何同时渲染OpenGL三角形与ImGui窗口?

问题:OpenGL三角形与ImGui窗口无法同时渲染

当不在主循环中调用ImguiOnUpdate(width, height)时,窗口可正常显示三角形;但调用该函数后,三角形仅在初始时闪一下,之后只能看到ImGui窗口,无法同时渲染两者。

原代码如下:

#include <iostream>

#include <imgui/imgui.h>
#include <imgui/backends/imgui_impl_glfw.h>
#include <imgui/backends/imgui_impl_opengl3.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>

void ImguiOnUpdate(int width, int height){
    // 1.1 set window size for imgui
    ImGuiIO& io = ImGui::GetIO();
    io.DisplaySize = ImVec2(width, height);

    // 1.2 new frame
    ImGui_ImplOpenGL3_NewFrame();
    ImGui::NewFrame();

    // 1.3 imgui demo window
    static bool show = true;
    ImGui::ShowDemoWindow(&show);

    // 1.4 imgui render
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}

int main() {
    // ===OPENGL===
    int width = 1600;
    int height = 900;
    glfwInit();
    GLFWwindow *window = glfwCreateWindow(width, height, "LearnOpenGL", nullptr, nullptr);
    if (window == nullptr) {
        std::cerr << "failed to create GLFW window\n";
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, [](GLFWwindow *_, int width, int height) {
        glViewport(0, 0, width, height);
    });
    if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
        std::cerr << "failed to initialize GLAD\n";
    }

    uint32_t va_, vb_, ib_;

    glGenVertexArrays(1, &va_);
    glBindVertexArray(va_);

    glGenBuffers(1, &vb_);
    glBindBuffer(GL_ARRAY_BUFFER, vb_);

    float vertices[] = {
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
            0.0f, 0.5f, 0.0f
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);

    glGenBuffers(1, &ib_);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib_);

    int indices[] = {0, 1, 2};
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // ===IMGUI===
    // 1.1 Imgui Context
    ImGui::CreateContext();
    ImGui::StyleColorsDark();

    // 1.2 Imgui flags
    ImGuiIO& io = ImGui::GetIO();
    io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
    io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;

    // 1.3 Imgui init for opengl
    ImGui_ImplOpenGL3_Init("#version 330");

    while(!glfwWindowShouldClose(window)){
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glBindVertexArray(va_);
        glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);

        ImguiOnUpdate(width, height);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}

解决方案

问题核心

  1. 缺少GLFW后端绑定:仅初始化了ImGui的OpenGL3后端,未将其与GLFW窗口关联,导致ImGui无法正确处理窗口输入、尺寸变化,渲染状态出现异常。
  2. 手动设置窗口尺寸干扰逻辑:强制修改io.DisplaySize会覆盖GLFW后端自动获取的窗口数据,导致渲染坐标系错位。
  3. ImGui帧流程不完整:缺少ImGui_ImplGlfw_NewFrame()调用,无法正确启动ImGui的帧循环处理输入事件。

修改步骤

  1. 添加GLFW后端初始化:在OpenGL3后端初始化前,调用ImGui_ImplGlfw_InitForOpenGL绑定GLFW窗口。
  2. 修正ImGui帧流程:移除手动设置io.DisplaySize的代码,添加ImGui_ImplGlfw_NewFrame()以正确处理输入。
  3. 优化主循环调用:ImguiOnUpdate无需传入窗口尺寸,由GLFW后端自动处理。
  4. 添加资源清理:程序退出前清理ImGui后端资源,避免内存泄漏。

修改后的完整代码

#include <iostream>

#include <imgui/imgui.h>
#include <imgui/backends/imgui_impl_glfw.h>
#include <imgui/backends/imgui_impl_opengl3.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>

void ImguiOnUpdate(){
    // 1. 启动ImGui帧循环:先处理GLFW输入事件
    ImGui_ImplGlfw_NewFrame();
    ImGui_ImplOpenGL3_NewFrame();
    ImGui::NewFrame();

    // 2. 绘制ImGui窗口
    static bool show = true;
    ImGui::ShowDemoWindow(&show);

    // 3. 渲染ImGui到屏幕
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}

int main() {
    // ===OPENGL===
    int width = 1600;
    int height = 900;
    glfwInit();
    GLFWwindow *window = glfwCreateWindow(width, height, "LearnOpenGL", nullptr, nullptr);
    if (window == nullptr) {
        std::cerr << "failed to create GLFW window\n";
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, [](GLFWwindow *_, int width, int height) {
        glViewport(0, 0, width, height);
    });
    if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
        std::cerr << "failed to initialize GLAD\n";
        glfwTerminate();
        return -1;
    }

    uint32_t va_, vb_, ib_;

    glGenVertexArrays(1, &va_);
    glBindVertexArray(va_);

    glGenBuffers(1, &vb_);
    glBindBuffer(GL_ARRAY_BUFFER, vb_);

    float vertices[] = {
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
            0.0f, 0.5f, 0.0f
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);

    glGenBuffers(1, &ib_);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib_);

    int indices[] = {0, 1, 2};
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // ===IMGUI===
    ImGui::CreateContext();
    ImGui::StyleColorsDark();

    ImGuiIO& io = ImGui::GetIO();
    io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
    io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;

    // 初始化GLFW后端(绑定当前窗口,第二个参数表示是否让ImGui接管GLFW输入回调)
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    // 初始化OpenGL3后端
    ImGui_ImplOpenGL3_Init("#version 330");

    while(!glfwWindowShouldClose(window)){
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // 渲染OpenGL三角形
        glBindVertexArray(va_);
        glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);

        // 渲染ImGui窗口
        ImguiOnUpdate();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // 清理ImGui资源
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();

    glfwTerminate();
    return 0;
}

效果说明

修改后,主循环先渲染OpenGL三角形,再渲染ImGui窗口,ImGui会自动层叠在3D内容上方,实现两者同时显示。GLFW后端会自动处理窗口尺寸变化和输入事件,无需手动干预窗口尺寸参数。

内容的提问来源于stack exchange,提问作者milanHrabos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 04:07:15