GLFW类多窗口异常:关闭首个窗口致程序退出求助
OpenGL多窗口支持问题:关闭首个窗口导致程序退出的修复方案
问题根源
- 无效指针访问:销毁窗口后未清空
m_window_handle,后续循环中继续调用ShouldClose()、onUpdate()会访问已释放的内存,触发崩溃。 - GLAD重复初始化:每个窗口创建时都调用
gladLoadGL,GLAD只需初始化一次,重复操作无意义且可能引发异常。 - Init方法返回值缺失:原
Init方法在GLFW初始化成功后未返回true,会导致主函数中无法进入窗口创建逻辑(隐藏bug)。 - 缺少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
相关产品推荐
相关产品推荐

