SDL2和GLEW,如果使用SDL_GL_SetAttribute(),则无法获得正确的OpenGL版本

时间:2014-03-16 10:09:42

标签: opengl sdl glew sdl-2

我正在使用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

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(/* ... */);

紧接着是GLEW

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
}

1 个答案:

答案 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位深度缓冲区的应用程序的最便携方式是使用帧缓冲区对象。