c – 创建OpenGL 4.3上下文崩溃了GLX
我正在使用SDL2和C 11构建一个游戏引擎(就像个人项目一样,为了娱乐和练习),我想做的其中一件事就是尝试让图形驱动程序使用最新支持的OpenGL版本,并根据版本改变引擎的图形部分的呈现方式.这样我可以使用OpenGL的最新功能,它们相关且有用,但也支持旧硬件.我能想到两种方法:
>检测最新支持的OpenGL版本并使用它,但我想不出任何方法可以做到这一点.是的,我试过谷歌. 我使用的方法(#2)在创建4.3上下文后立即失败.我知道我的图形驱动程序现在只支持4.2,但我原以为GLX被设计为抛出一个错误,给出一个NULL上下文,并让你的程序继续运行,但它无法通过上下文的失败创建.我的假设是关于GLX如何表现错误?有没有办法在不创建上下文的情况下检测最新支持的版本? 因为我知道有些人喜欢看到演示错误的完整和最小的来源,这里是: #include <SDL2/SDL.h> #include <SDL2/SDL_opengl.h> int main() { if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) { return -1; } SDL_Window* window = SDL_CreateWindow( "SDL Window",800,600,SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN ); if( window == nullptr ) { return -1; } unsigned int major = 4; unsigned int minor = 3; SDL_GLContext context = nullptr; while( context == nullptr ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION,major ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION,minor ); context = SDL_GL_CreateContext( window ); if( context == nullptr ) { if( minor == 0 && major > 1 ) { --major; minor = 9; } else if( minor > 0 ) { --minor; } else { SDL_DestroyWindow( window ); return -1; } } } SDL_Delay( 5000 ); SDL_GL_DeleteContext( context ); SDL_DestroyWindow( window ); return 0; } 此外,如果我将该代码更改为以4.2上下文而不是4.3开头,则它可以正常工作.所以错误在于专门创建4.3上下文. 解决方法
这可能表明SDL的X11_GL_CreateContext()中存在错误(在网络上它表示SDL2仍然是实验性的).您找到支持的OpenGL版本的策略是有效的,但为了让SDL为您提供前向兼容的上下文,它首先需要创建一个临时上下文,调用glXGetProcAddress()来获取glCreateContextAttribsARB(它不能没有这样做一个活动的OpenGL上下文),然后它尝试初始化您请求的OpenGL版本.现在,如果失败,它将处置临时上下文并返回NULL.
我的猜测是第二次创建临时上下文失败,我建议使用调试信息构建SDL并尝试找出X11_GL_CreateContext()中的确切位置(或者至少插入几个printf). 另一方面,如果将SDL_GL_CONTEXT_MAJOR_VERSION和SDL_GL_CONTEXT_MINOR_VERSION保留为默认值,则已获得最大OpenGL版本.你只是没有得到一个前向兼容的上下文,这意味着它会让一些在未来版本中被认为是“错误”的行为漏掉. 此外,通常,创建具有最大版本的前向兼容上下文并不是一个好主意.例如.在OpenGL 3.2中,前向兼容配置文件强制使用顶点数组对象,这使得不使用VAO的旧代码被破坏.因此,如果为OpenGL 3.1(或任何其他版本)编写的应用程序试图获得最新的向前兼容配置文件,它实际上可能在将来停止工作.这不是一个好主意. 一种选择是决定使用一个向前兼容的配置文件,这通常非常有用,因为它报告有关已弃用功能的错误.如果您真的想要使用更多版本,则需要更多代码路径(=游戏引擎的更多版本).为了检测OpenGL版本,我建议创建一个虚拟SDL窗口,初始化一个简单的OpenGL配置文件,获取版本并关闭所有内容,然后再次初始化,使用您决定的版本.这应该工作. 另一种选择是仅将前向兼容配置文件用于开发,并使用简单的旧配置文件进行分发.它是最兼容的并且涉及的工作量最少(您希望无论如何都要忽略发布版本中的大多数OpenGL错误 – 驱动程序甚至可能会禁用错误报告). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |