我正在使用SDL2进行OS接口,使用GLEW进行OpenGL功能加载。最初我让我的SDL_GL_SetAttribute()调用在窗口创建和上下文创建之间。我注意到我的SDL_GL_SetAttribute()调用影响不大,所以我重新阅读the documentation并指出“在创建OpenGL窗口之前应该设置 ”。如果我尝试这个,我只能设法得到 OpenGL 1.1 上下文(微软发布的那个)。如果我根本不调用SDL_GL_SetAttribute(),我会得到4.4上下文,没有问题。
我注意到的一件奇怪的事情是,在创建上下文后,我对SDL_GL_GetAttribute()的调用似乎返回了不准确的值。如果我不设置我得到的任何属性:
SDL GL Context Major Version: 2
SDL GL Context Minor Version: 1
SDL GL Context Profile: Unknown
SDL GL Accelerated Visuals: True
SDL GL Double Buffering: True
SDL GL Depth Size: 24
----------------------------------------------------------------
Graphics Successfully Initialized
OpenGL Info
Version: 4.4.0
Vendor: NVIDIA Corporation
Renderer: GeForce GT 650M/PCIe/SSE2
Shading: 4.40 NVIDIA via Cg compiler
----------------------------------------------------------------
如果我执行设置我得到的所有属性:
SDL GL Context Major Version: 3
SDL GL Context Minor Version: 1
SDL GL Context Profile: Compatibility
SDL GL Accelerated Visuals: True
SDL GL Double Buffering: True
SDL GL Depth Size: 32
----------------------------------------------------------------
Graphics Successfully Initialized
OpenGL Info
Version: 1.1.0
Vendor: Microsoft Corporation
Renderer: GDI Generic
Shading: (null)
----------------------------------------------------------------
请注意,在第一种情况下,SDL说我有2.1上下文,而实际上我得到4.4。在第二种情况下,它说我有一个3.1上下文(我要求的),当我实际上有一个1.1。
我当前的设置代码(遵循this tutorial中列出的内容)。为简洁起见,省略了错误检查。
SDL_Init(SDL_INIT_VIDEO);
// Request compatibility because GLEW doesn't play well with core contexts.
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
SDL_Window * window = SDL_CreateWindow("Title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
SDL_GLContext context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, context)
// Print what the OS actually gave us for each value we requested.
SDL_GL_GetAttribute(/* ... */);
glewExperimental = GL_TRUE;
GLenum result = glewInit();
if(result != GLEW_OK)
{
// Handle & print error
}
if(GLEW_VERSION_1_1)
{
printf("----------------------------------------------------------------\n");
printf("Graphics Successfully Initialized\n");
printf("OpenGL Info\n");
printf(" Version: %s\n", glGetString(GL_VERSION));
printf(" Vendor: %s\n", glGetString(GL_VENDOR));
printf(" Renderer: %s\n", glGetString(GL_RENDERER));
printf(" Shading: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
printf("----------------------------------------------------------------\n");
}
else
{
printf("Unable to get any OpenGL version from GLEW!");
}
if(!GLEW_VERSION_3_1)
{
// Handle & print error
}
答案 0 :(得分:2)
首先,要完全清楚GL 3.1技术上确实具有兼容性概念,其形式为GL_ARB_compatibility
。如果您的扩展程序字符串中包含该扩展程序,那么GL 3.0规范中标记为 已弃用 的功能将继续可用。如果不存在,则GL 3.0中的 已弃用 实际上在3.1中 已删除 。为此,GL 3.1规范的分叉版本专门处理此扩展。
但是,这与上下文配置文件不同。您无法在3.1中主动请求兼容性,您只能在事后检测到此行为。因此,正如derhass指出的那样,请求3.1"兼容性配置文件" (或任何关于该问题的简介)背景。
更重要的是,Microsoft Windows上的默认帧缓冲区并不广泛支持32位深度缓冲区。有些驱动程序允许您选择具有32位深度缓冲区的像素格式,并且仍然可以获得硬件实现,但通常情况下,您最终会回退到基于Microsoft的基于软件的GDI实现。
这种行为甚至发生在实际支持32位深度缓冲区的GPU上,而接近真正需要32位深度缓冲区的应用程序的最便携方式是使用帧缓冲区对象。