我什么时候需要使用OpenGL函数加载器?

时间:2015-01-10 07:13:11

标签: opengl opengl-es

关于何时需要使用像GLEW这样的OpenGL函数加载器,我有点困惑。通常,您似乎首先获得一个窗口和有效的OpenGL上下文,然后尝试加载函数。

  • 有时这些函数被称为扩展,有时它们也被称为核心函数。似乎加载并归类为“核心”和“扩展”的是依赖于平台的。除了一些基本集之外还加载了哪些函数?

  • 您是否还需要在OpenGL ES平台上以相同的方式加载函数?快速浏览GLEW,我没有看到对Open GL ES的明确支持。其他GL函数加载器库明确提到了专门针对ES的支持(例如https://github.com/Dav1dde/glad

3 个答案:

答案 0 :(得分:13)

OpenGL函数(核心或扩展)必须在运行时动态加载,只要有问题的函数不是平台原始OpenGL ABI(应用程序二进制接口)的一部分。

  • 对于Windows,ABI涵盖的是OpenGL-1.1
  • 对于Linux,ABI涵盖了OpenGL-1.2(其他* nix没有正式的OpenGL ABI,但它们通常也需要OpenGL-1.2)
  • 对于MacOS X,OpenGL版本可用,ABI由OS版本定义。

这导致以下规则:

  • 在Windows中,除了单个纹理,无阴影,固定功能绘图之外,你几乎需要一个函数加载器。可能会加载更多功能,但这不是给定的。
  • 在Linux中你几乎需要一个函数加载器,除了基本的多纹理,只有基本的texenv模式,无阴影,固定功能绘图;可能会加载更多功能,但这不是给定的。
  • 在MacOS X中,根本不需要需要功能加载器,但您可以使用的OpenGL功能严格取决于操作系统版本,无论您拥有它,还是不需要。

核心OpenGL函数和扩展之间的区别在于,核心函数可以在OpenGL规范中找到,而扩展是除了OpenGL版本提供的功能之外可能会或可能不可用的功能。

扩展和较新版本的核心功能都通过相同的机制加载。

答案 1 :(得分:4)

datenwolf的答案很棒,但我想澄清你在问题的第一个要点中所说的话。

核心和扩展状态不依赖于平台,甚至不相互排斥。

核心意味着在某个版本的OpenGL中引入了某些功能。有核心功能,这些功能在X.Y版本中保证存在,甚至还有核心扩展,它们是与X.Y版本一起引入的扩展。核心扩展仅在不需要特定版本的扩展形式中提供与核心功能相同的功能,类型,枚举等。

Framebuffer Objects在OpenGL 3.0中成为核心,并且比早于OpenGL 3.0的EXT扩展(GL_EXT_framebuffer_object)的限制性略低。但是,没有必要使用OpenGL 3.0实现来访问FBO的核心版本 - OpenGL 2.1实现可能提供核心功能。

GL_ARB_framebuffer_object的扩展规范中,您会找到:

  

<强>问题

     
    

(8)为什么此扩展中的新令牌和入口点没有            “ARB”后缀与其他ARB扩展一样吗?

         
      

已解决:与大多数ARB扩展不同,这是一个严格的子集               功能已在OpenGL 3.0中获得批准。这个扩展               仅存在以支持旧硬件上的功能               无法实现完整的OpenGL 3.0驱动程序。既然没有               ARB扩展和核心之间可能的行为更改               功能,源代码兼容性通过不使用提高               扩展名后缀。

    
  

这是我能记得的第一次提到核心扩展,但它不是最后一次。从那时起,已经创建了许多ARB扩展,从更高版本“backport”(如果你愿意)核心功能。

以下是通过解析gl.xml为另一个核心扩展名收集的一些示例输出:

 >> Command:  void glBufferStorage (GLenum target, GLsizeiptr size, const void *
                                    data, GLbitfield flags)

  * Provided by GL_ARB_buffer_storage (gl|glcore)

  * Core in                   GL_VERSION_4_4    (   gl 4.4)

它是4.4中的核心(保证存在于4.4实现中),但由于提供它的扩展名为glcore,因此 核心 功能可能如果核心扩展可用,则可以在较旧的实现中使用。

如果您感兴趣,我可以找到gl.xml解析此信息的简单软件here

答案 2 :(得分:2)

仅在Windows和Linux上需要功能加载器。这里简要介绍了如何在不同平台上构建各种OpenGL版本。

Windows开发工具仅包含OpenGL 1.1的标头。阴谋理论家可能会声称微软对使用OpenGL很不感兴趣,因为它希望开发人员使用专有API。

对于超过1.1的任何内容,您需要通过调用wglGetProcAddress()动态加载入口点。像GLEW这样的库为更高的OpenGL版本提供头文件,并封装了加载入口点的逻辑。

的Linux

我还没有在Linux上完成OpenGL编程。据我所知,它需要类似于Windows的功能加载。我会按照@ datenwolf的答案详细说明。

Mac OS

Mac OS支持两个主要的OpenGL功能集:

  • 具有传统功能的OpenGL 2.1。包含<OpenGL/gl.h>
  • 即可使用此功能
  • OpenGL 3.x及更高版本,仅限核心配置文件。包含<OpenGL/gl3.h>
  • 使用

在这两种情况下,您都不需要任何动态功能加载。头文件包含可支持的最大版本的所有声明/定义,您链接的框架(使用-framework OpenGL)解析函数名称。

您在构建时可以使用的最大版本由您构建的平台SDK决定。默认情况下,这是与您的构建计算机的操作系统匹配的平台SDK。但您可以使用-isysroot构建选项来更改它。

在运行时,机器必须至少运行与构建时使用的平台SDK相匹配的操作系统,并且您只能使用最高支持GPU版本的功能。您可以概述在哪些硬件上支持的版本:

https://developer.apple.com/opengl/capabilities/ http://support.apple.com/en-us/HT202823

Android,NDK

使用Android上的本机代码,您可以在设置上下文和曲面时选择OpenGL版本。然后,您的代码包含所需的标头(如<GLES2/gl2.h><GLES3/gl3.h>)以及针对匹配库的链接。不需要动态函数加载。

如果目标设备不支持您尝试使用的版本,则上下文创建将失败。您可以在清单中有一个条目,阻止将应用程序安装在不支持所需ES版本的设备上。

Android,Java

这与NDK案件非常相似。在设置期间指定所需版本,例如在创建GLSurfaceView

GLES20类包含ES 2.0的定义。 GLES30派生自GLES20,并添加ES 3.0的其他定义。

的iOS

毫不奇怪,这与Mac OS非常相似。您包含与所需OpenGL ES版本匹配的头文件(例如<OpenGLES/ES3/gl.h>),链接到框架,并且您已完成所有操作。

同样匹配Mac OS,您可以构建的最大版本由您选择的平台SDK版本决定。您要运行的设备必须至少使用与此平台SDK版本匹配的操作系统版本,并支持您正在使用的OpenGL ES版本。

显然,您在Mac上交叉编译应用程序的一个主要区别。 iOS使用具有不同标题和框架的不同平台SDK集,但整个过程与为Mac OS构建的过程非常相似。