C++使用GLEW/GLFW+FreeType动态切换字体时glCreateTextures崩溃求解
问题核心原因
- OpenGL API跨线程非法调用
OpenGL上下文是线程绑定资源,你在启动时执行的glSetup函数及所有GL初始化操作都运行在持有GL上下文的主线程/渲染线程中,但你将initializeFreeType放在了独立的TCP监听线程中调用,该线程没有绑定任何激活的GL上下文,调用glCreateTextures这类GL API属于未定义行为,是直接导致崩溃的核心原因。 - 野指针风险
你在网络线程中定义了栈上数组char c[font.size() + 1],将全局变量FONT指向该栈数组地址,当代码执行出当前if分支作用域后,栈数组会被回收,FONT变成野指针,后续FT_New_Face调用时访问非法地址也可能触发崩溃。 - 资源泄漏隐患
你清空Characters字符映射表时,没有主动释放表中存储的旧纹理ID,会持续占用显存,长期运行会触发显存不足问题。 - 错误处理缺失
FT_Load_Char调用没有做错误判断,若字符加载失败,face->glyph为nullptr,后续访问该指针也会触发崩溃。
修复方案
- 移除网络线程中的
initializeFreeType调用,网络线程仅负责保存字体路径(将FONT改为std::string类型直接存储路径,不需要手动转char数组),新增原子变量或互斥锁保护的SHOULD_RELOAD_FONT标记位,收到字体切换请求后仅更新标记和路径,由持有GL上下文的渲染线程在主循环的合适位置检测标记,执行initializeFreeType操作。 - 清空
Characters前遍历所有元素,调用glDeleteTextures释放每个字符对应的纹理资源,避免显存泄漏。 - 给
FT_Load_Char添加返回值校验,加载失败的字符直接跳过本次循环,不执行后续GL操作。 - 所有GL相关操作必须统一在持有GL上下文的线程中执行,禁止跨线程调用GL API。
内容的提问来源于stack exchange,提问作者benny b
相关产品推荐
相关产品推荐

