OpenGL 实践——在没有核心版本的情况下运行 OpenGL

Posted

技术标签:

【中文标题】OpenGL 实践——在没有核心版本的情况下运行 OpenGL【英文标题】:OpenGL practices - Running OpenGL with no core version 【发布时间】:2014-07-26 22:44:48 【问题描述】:

我不确定这是需要由这里的用户塑造的问题或意见, 但是我们开始了。

问题:即使我想支持最新版本和扩展,我是否应该在 1.1 版兼容性配置文件中运行 openGL?更多信息。

某些功能需要您提供您可能想要支持的 openGL 版本, 如果您想支持 openGL 核心配置文件或 3.0 及更高版本,则最常见的用法。 例子:

SDL:SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR/MINOR_VERSION, major/minor version);

GLX:glXCreateContextAttribsARB, GLX_CONTEXT_MAJOR_VERSION_ARB, GLX_CONTEXT_MINOR_VERSION_ARB

我在 openGL 版本控制和扩展系列方面遇到了一些问题(实际上是一些)。

问题 #1 - 查询 OpenGL 版本: 如果我没记错的话,它从 Mesa3D Mesa 7.11 开始,尝试从中查询 GL_VERSION, 我得到了:

“Mesa 7.11 OpenGL 2.1 配置文件”

知道 glew 以及其他项目解析器,他们只寻找字符串中的第一个点,并将点所在的数字作为字符串返回(您可以选择转换为浮点数)

来自 Glew 1.9.0:Code snippet 上面的例子确实返回了“openGL”版本 7.0,这实际上是 MESA3D 驱动程序版本,这让我认为它不可靠。

问题 #2 - 扩展程序(丢失,好吗?) 使用与以前相同的 MESA3D 驱动程序:7.11,运行 Glewinfo (glew 1.9.0) 给了我以下内容:

GL_ARB_texture_storage: 丢失确定

glTexStorage1D:好的

glTexStorage2D:好的

glTexStorage3D:好的

glTextureStorage1DEXT:好的

glTextureStorage2DEXT:好的

glTextureStorage3DEXT:好的

请注意,尝试从“GL_ARB_texture_storage”API 检索(导入)函数地址会导致失败(NULL 指针)。

我解决上述两个问题的方法是在兼容模式下将 openGL 初始化为 1.1 版,然后通过检查我可能需要的每个 API 系列来暴力破解我的方式, 如果 openGL 作为一组以自己的方式独立但协同工作的 API 工作,我们不应该以代码明智的方式对待它们,而不是假设它们在你有核心版本的情况下存在吗?再次使用 MESA3D 7.11 openGL 2.1,我仍然能够使用 openGL 3.0 函数,例如“glGenerateMipmap”

**我试图避免版本和扩展字符串的方式是:**

1.)以兼容模式初始化openGL 1.1。

2.)通过导入核心函数扫描您可能需要的 API。

3.)如果无法获取核心功能,请尝试通过扩展获取功能(如果存在) (无需与扩展列表“GL_EXTENSIONS”进行字符串比较)

4.)如果您无法获得这些功能,请尝试通过编写自己的功能来模拟它们。

5.)如果上面提到的方法都不起作用,那就放弃吧。

6.)如果上述方法中的任何方法有效,请运行健全性测试并确保函数正常工作,例如:glGetError 和应该工作的调用的断言。

您认为它安全/高效吗?我是否通过调用最小版本并试图强行进入而错过了什么?有什么办法可以改进吗? *旁注 - 我知道 openGL 核心配置文件会删除过时的功能,但如果您的驱动程序支持最新版本,您可以选择不自己使用它们。 我也知道 openGL 可能会尝试模拟当前版本之外的功能, 取决于您的驱动程序,您可能仍然可以将 glGenerateMipmap(openGL 3.0 函数)与 openGL 2.1 一起使用

问题 #3 - 命名约定、Core、ARB 和 glew。** 我还不确定名称约定是如何工作的,例如: 看来您在“GL_ARB_debug_output”中有函数“glDebugMessageCallbackARB” 和 GL 版本 4.3 中的 glDebugMessageCallback,看起来还不错, 但是看看上面第2期的例子,你可能会在“GL_ARB_texture_storage”里面看到函数:glTexStorage1D, No ARB suffix。

我的问题是,根据标题和函数名称,我如何知道 API 是否仍在等待董事会批准,或者它是否已经是核心的一部分。

对不起,文字墙,一些关于主题的输入将不胜感激。

【问题讨论】:

【参考方案1】:

问题:即使我想支持最新版本和扩展,我是否应该在 1.1 版兼容性配置文件中运行 openGL?

首先:没有 1.1 的“兼容性配置文件”。配置文件是在 GL 3.2 中引入的。但另一方面,您的问题的答案显然是。如果你关心便携性,至少。为了声明 OpenGL 一致性,实现必须支持 核心配置文件,而兼容性是可选的。这不是理论上的可能性,而是在现实世界中以这种方式实现的。在 OSX 上,旧版 GL 上下文仅限于 GL 2.1。如果您想要现代 GL3.x/4.x 功能,您必须使用核心配置文件。 Linux 上的 mesa 3D 开源实现也是如此:现代 GL 仅在核心配置文件中受支持。在 Windows 上,通常支持兼容性配置文件,并且专有的 AMD 和 Nvidia linux 驱动程序也支持兼容性配置文件,因此您可以使用“1.1”

问题 #1 - 查询 OpenGL 版本

如果 mesa 曾经将“Mesa 7.11 OpenGL 2.1 Profile”报告为 GL_VERSION,那么它就严重损坏了(不过,我从来没有经历过 mesa 做这样的事情)。 GL 规范要求版本字符串以数字 GL major.minor 版本开头。 Modern GL 还提供了 GL_MAJOR_VERSIONGL_MINOR_VERSION 整数查询,这使得解析该字符串已过时。

问题 #2 - 扩展(丢失,好吗?)

glewinfos 的输出可能令人困惑。但重要的是它为每个扩展写的第一件事。这就是 GL 实现通过扩展字符串实际宣传为支持的扩展的内容。它清楚地写着“MISSING”,因此无论函数指针是否为 NULL,尝试使用该功能都是未定义的行为。

我不知道为什么你有一个 NULL 指针,而 GLEW 没有。实际上,mesa 是一个适用于多种不同驱动器的框架,对所有驱动器都使用相同的前端 libGL.so。因此,这是一个很好的实现示例,其中功能可能存在但不能使用,因为并非所有台面后端驱动程序都支持它。

GLEW 在这方面被破坏了,因为它只使用GL_EXTENSIONS 字符串,这在现代核心 porifle 中不再可用。 glewExperimental hack 完全禁用字符串检查,并尝试使用它获得的指针。这可不是什么好事……

问题 #3 - 命名约定

扩展的原型循环是

供应商特定(NV/AMD/APPLE/INTEL/...) 多供应商 (EXT) ARB 批准 (ARB) 集成到核心中。

但是,这或多或少只是通常的情况。一些扩展直接从 EXT 提升为核心。一些 ARB 扩展在进入核心时会进行大量修改。有时,更高版本的核心功能也会作为扩展引入(尤其是对于较低版本)。

实际上,特定于供应商的扩展和 EXT 扩展都使用函数名和枚举的后缀。仅当 ARB 扩展在该扩展中首次定义时才可能使用它。 GL_ARB_sync 扩展的问题部分对此给出了很好的解释:

13) 为什么入口点/枚举没有附加 ARB? 此功能直接进入 OpenGL 3.2 核心 并且也被定义为旧平台的扩展 同时,所以它不使用 ARB 后缀,像其他 这些新功能直接进入 GL 核心。

我不能 100% 确定 ARB_texture 存储,但我认为它是与 GL 4.2 一起引入的,这是一个核心功能。这些扩展允许实现者支持扩展,即使他们不支持最初引入该功能的 GL 核心版本。

我的问题是,我如何知道 API 是否仍在等待董事会批准,或者它是否已经是核心的一部分,根据标头和函数名称来判断。

我的问题是:你为什么要这样做?那有什么用?一般规则是“如果它没有后缀,则它是 some GL 版本的核心功能。”但是您实际上会如何处理这些信息?

【讨论】:

这非常有用且非常有用,至于“我为什么要真正关心 API 是否拥有后缀”,总是很高兴知道,这有点试图指出不一致。

以上是关于OpenGL 实践——在没有核心版本的情况下运行 OpenGL的主要内容,如果未能解决你的问题,请参考以下文章

核心数据在没有堆栈的情况下工作

在没有打开版本控制的情况下更改了核心数据模型

在不安装的情况下运行 OpenGL?

在没有事务的情况下运行 EF 核心迁移?

在没有 openGL 的情况下使用 Qt

为啥在使用 OpenGL 核心配置文件时会崩溃?