【发布时间】:2012-10-28 03:32:23
【问题描述】:
我正在使用 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 上下文。
【问题讨论】:
-
不确定它是否会有所帮助,但这个问题指出必须在调用 SDL_Init 之前设置上下文版本:stackoverflow.com/questions/8110053/…
-
沃恩,真的吗?这很奇怪,SDL 文档暗示它必须在调用 SDL Init 之后和创建上下文之前进行设置。此外,如果我将代码更改为从 4.2 开始,它就可以正常工作。可能应该提到...
-
您尝试过@VaughnCato 提供的建议吗?您是否检查过来自
SDL_GL_SetAttribute的返回值,文档建议它们应该为 0 表示成功。代码在哪里崩溃?调试器告诉你什么? -
@X-Istence 是的,我试过了。它没有解决它。我还测试了 SDL_GL_SetAttribute 的返回值。它成功了。它只是试图创建失败的上下文。