我正在使用 SDL2 和 C++11 构建游戏引擎(只是作为个人项目,为了娱乐和练习),我想做的一件事是尝试让图形驱动程序使用最新的支持版本OpenGL,并根据版本改变引擎的图形部分的渲染方式。这样,我可以在相关且有用的地方使用 OpenGL 的最新功能,同时也支持旧硬件。我能想到的方法有两种:
检测最新支持的 OpenGL 版本并使用它,但我想不出任何方法来做到这一点。是的,我试过谷歌。
使用反复试验,我从最新版本开始(4.3,但我的 GTX 460 仅支持最高 4.2,即使我更新了驱动程序),如果失败(我通过检查 SDL 来检测返回 NULL 上下文),我降低版本号并重试。
我使用的方法(#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", 0, 0, 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 上下文。