OpenGL 4.1在Mavericks下是否可用?

22

我刚把我的MacBook Pro升级到Mavericks(MacOS 10.9),包括Xcode。 根据苹果公司的“OpenGL功能表”,此版本支持OpenGL 4.1,但对glGetString(GL_VERSION)的调用返回“1.2”,我的以“#version 330”开头的GLSL 3.30着色器拒绝加载,并说该版本不受支持。

我需要在Mavericks上做些什么才能启用4.1支持吗?


您是否正在请求核心上下文? - genpfault
6
1.2?! 你确定不是指2.1吗? - Andon M. Coleman
当我运行Richard Wright编写的OpenGL SuperBible第五版的示例代码时,遇到了相同的问题。它使用glut来创建上下文,在网上搜索后,人们说glut已经不再活跃开发,这个问题是由GLUT引起的吗? - wenbo qiu
3
有FreeGLUT这个库,它正在维护中...但在OS X上使用它的问题是它要通过X11。在OS X上,X11通过一个兼容的X服务器称为XQuartz提供,你无法使用XQuartz服务器获取3.2+的OpenGL上下文,因为它没有实现必要的GLX扩展来请求核心配置文件。因此,任何在OS X上使用3.2的框架都必须通过本机API,如CGL(全屏和C)或NSOpenGL(全屏/窗口和Objective C)进行操作。 GLFW3和许多其他框架都这样做,而FreeGLUT仍然没有这样做。 - Andon M. Coleman
@AndonM.Coleman:感谢您的回答。 - wenbo qiu
6个回答

23

当您在OS X上使用较低级别的API请求像素格式时,您需要将以下内容添加到属性列表中,以便使用核心配置文件:

CGL:

  kCGLPFAOpenGLProfile,     kCGLOGLPVersion_3_2_Core

NSOpenGL:

  NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core

现在,虽然这个特定的常量被命名为...3_2Core,但它实际上表示请求一个上下文,将所有不推荐使用的功能都删除并支持至少OpenGL 3.2(换句话说是一个核心配置文件)。您可以使用相同的常量获取4.1或3.3上下文;老实说,在常量中包含实际版本号可能是一个糟糕的选择。

如果您在请求像素格式时没有指定此选项,OS X将分别为您提供kCGLOGLPVersion_LegacyNSOpenGLProfileVersionLegacy。这将限制您的功能仅达到OpenGL 2.1。

如果您正在使用更高级的框架,则需要查阅API参考文档。但请注意,在OS X上,您必须拥有核心配置文件才能访问任何新于OpenGL 2.1的功能。


"属性列表"? "核心配置文件"? 这与XCode有关。不幸的是,由于我的应用程序跨平台,我一直避免使用XCode。出于同样的原因,我一直在使用GLUT框架,但我怀疑如果我想使用比OpenGL 2.1更高级的功能,我必须咬紧牙关并深入了解基于MacOS的开发。唉。无论如何,谢谢。 - bobl
6
当我想到Xcode时,我会想到苹果想让你使用的可怕GUI来编写OS X / iOS软件... 这与此毫无关系,CGL和NSOpenGL是OS X中用于创建和管理渲染上下文的两个接口。无论如何,如果您想要使用现代OpenGL并隐藏低级别的OS特定内容,请不要使用GLUT。我建议您使用类似glfw3的东西,您必须拥有一个核心配置文件上下文才能在OS X上使用GL 3.2+,而像GLUT这样的古老框架就不适用了。 - Andon M. Coleman
glGetString(GL_VERSION) 对我来说返回的是 4.1 ATI-1.38.3,但它仍然拒绝编译 #version 130 的着色器。它似乎接受 #version 330 的着色器,尽管我还不知道如何将我的着色器代码更新到 330... 我猜我正在遇到一个完全不同的问题? - Andy
免责声明:我正在使用JOGL,但这是其“glGetString”包装器的输出。 - Andy
OS X 不支持 GLSL 1.30。它们在传统驱动程序中实现了 1.20,而在核心中实现了 3.20。但是你可以在传统驱动程序中获得涉及 1.40 和 1.50 的各种扩展。 - Andon M. Coleman

15

使用OpenGL库GLFW,最新版本为3.0.4,在初始化GLFW之后立即进行初始化。

if (!glfwInit())
{
    printf("glfwInit() fail to initualize. \n");
    glfwTerminate();
    exit(-1);
}

在您初始化glfwInit()之后,请包含以下4行代码。这四行代码将使您能够使用您的操作系统支持的最高版本。在Mac上,它是OpenGL 4.1。

glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);

然后创建您的窗口。

_Window = glfwCreateWindow(width, height, title, 0, 0);

检查以确保它已被创建。

if (!_Window) {
    printf("Display window fail to create. \n");
    glfwTerminate();
    exit(-1);
}

然后使用以下方法将其设置为当前窗口。

glfwMakeContextCurrent(_Window);

当你将它设为当前窗口后,剩下的就是创建你的主循环。

while (!glfwWindowShouldClose(_Window))
{
    ........
    glfwSwapBuffers(_Window);
    glfwPollEvents();
}

确保在循环中包含glfwPollEvents();,这可以使使用关闭按钮退出窗口成为可能。如果您在在Xcode编译库方面遇到问题,请在此处给我发送消息,我会向您发送库的副本。


2

我在这个问题上挣扎了很长时间,最终成功地使用了由显卡支持的任何glsl版本。

有几个关键点:

  1. 使用CORE PROFILE
  2. 将MAJOR.MINOR设置为要使用的GL版本
  3. 如果不是使用的最新GL版本,则必须启用FORWARD COMPATIBILITY。

例如,如@kanthonye所指出的那样,如果您正在使用glfw,并使用gl版本3.2,则需要这些行:

glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);

这对我也起作用,但是只有在我移除glew之后才有效。glew和glfw应该是兼容的,但在OS X上glew只会引起各种问题。OP没有提到glew,但我尝试了两天才弄清楚这个问题。我还必须导入 <OpenGL/OpenGL.h><OpenGL/gl3.h>,然后它就可以工作了。 - Bjorn

1

http://support.apple.com/kb/HT5942

该网站标题为“Mac电脑:OS X Mavericks中的OpenCL和OpenGL支持 - 了解您的计算机在OS X Mavericks中支持的OpenGL和OpenCL版本。”

1
如果您正在使用LWJGL(截至版本2.90),那么在ContextAttribs的javadoc标题中有一个小问题:

......此扩展不支持MacOS X。但是,为了在MacOS X 10.7或更新版本上启用GL 3.2上下文,必须将此类的实例传递给LWJGL。唯一有效的配置是ContextAttribs(3、2、CONTEXT_CORE_PROFILE_BIT_ARB),其他任何内容都将被忽略。


0

如果您正在使用SDL作为高级API,则需要执行一些操作才能获得4.1支持。

首先,请确保您拥有SDL2 2.0.1(或更高版本)。例如,使用brew:

brew update brew upgrade sdl2

其次,您需要明确告诉SDL请求核心配置文件,如下所示

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );

第三,在Mac上请求核心配置文件的一个怪癖实际上需要您请求3.2才能获得4.1(!)。我认为这已经在SDL2存储库中修复,但尚未发布。

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接