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

GLFW类多窗口异常:关闭首个窗口致程序退出求助

OpenGL多窗口支持问题:关闭首个窗口导致程序退出的修复方案

问题根源

  1. 无效指针访问:销毁窗口后未清空m_window_handle,后续循环中继续调用ShouldClose()、onUpdate()会访问已释放的内存,触发崩溃。
  2. GLAD重复初始化:每个窗口创建时都调用gladLoadGL,GLAD只需初始化一次,重复操作无意义且可能引发异常。
  3. Init方法返回值缺失:原Init方法在GLFW初始化成功后未返回true,会导致主函数中无法进入窗口创建逻辑(隐藏bug)。
  4. 缺少GLFW终止操作:程序结束时未调用glfwTerminate(),不符合GLFW资源管理规范。

修复方案

1. 给Window类添加存活状态标记

在WindowManager.hpp的Window类私有成员中添加:

private:
    bool m_isAlive = true;

同时在public部分添加状态查询方法:

public:
    bool IsAlive() { return m_isAlive; }

2. 修正Destroy方法,避免重复销毁并清空指针

修改WindowManager.cpp中的Destroy方法:

void Window::Destroy()
{
    if (m_isAlive && m_window_handle)
    {
        glfwDestroyWindow(m_window_handle);
        m_window_handle = nullptr;
        m_isAlive = false;
    }
}

3. 调整ShouldClose和onUpdate方法,先检查窗口有效性

bool Window::ShouldClose()
{
    return !m_isAlive || (m_window_handle && glfwWindowShouldClose(m_window_handle));
}

void Window::onUpdate()
{
    if (m_isAlive && m_window_handle)
    {
        Update();
    }
}

4. 仅初始化一次GLAD

修改CreateWindow方法,用静态变量控制GLAD只初始化一次:

bool Window::CreateWindow()
{
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    m_window_handle = glfwCreateWindow(m_windowWidth, m_windowHeight, m_windowTitle, NULL, NULL);

    if (!m_window_handle)
    {
        std::cout << "SoulByteEngine :: CORE :: WindowManagerModule :: ERROR :: COULD'T CREATE WINDOW" << std::endl;
        return false;
    }

    glfwMakeContextCurrent(this->m_window_handle);

    static bool gladInitialized = false;
    if (!gladInitialized)
    {
        if (!gladLoadGL(glfwGetProcAddress))
        {
            std::cout << "SoulByteEngine :: CORE :: WINDOW_MANAGER :: ERROR :: CRITICAL :: WINDOW HAS BEEN CREATED, BUT GLAD COULD NOT BE INITIALIZED! " << std::endl;
            return false;
        }
        gladInitialized = true;
    }

    return true;
}

5. 修复Init方法的返回值

bool Window::Init()
{
    if (!glfwInit())
    {
        std::cout << "SoulByteEngine :: CORE :: WINDOW_MANAGER :: ERROR :: CRITICAL :: GLFW CANNOT BE INITIALIZED! " << std::endl;
        return false;
    }
    return true; // 新增返回值
}

6. 优化主循环,确保窗口销毁后不再执行无效操作

修改Application.cpp的main函数:

#include <WindowManager/WindowManager.hpp>

int main()
{
    if (SoulByteEngineCore::WindowManager::Window::Init())
    {
        SoulByteEngineCore::WindowManager::Window first_window(DEFAULT_WIDTH, DEFAULT_HEIGHT, "First SoulByteEngine Window");
        SoulByteEngineCore::WindowManager::Window second_window(DEFAULT_WIDTH, DEFAULT_HEIGHT, "Second SoulByteEngine Window");

        while (!first_window.ShouldClose() || !second_window.ShouldClose())
        {
            // 处理第一个窗口
            if (!first_window.ShouldClose())
            {
                first_window.onUpdate();
            }
            else if (first_window.IsAlive())
            {
                first_window.Destroy();
            }

            // 处理第二个窗口
            if (!second_window.ShouldClose())
            {
                second_window.onUpdate();
            }
            else if (second_window.IsAlive())
            {
                second_window.Destroy();
            }
        }

        glfwTerminate();
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:24:56