【发布时间】:2013-12-17 16:04:30
【问题描述】:
【问题讨论】:
【问题讨论】:
我认为解释这里发生的事情的最佳方式是在大多数平台上(OS X 是规则的例外),它们附带了一个非常原始的 OpenGL 实现(在 Windows 上为 1.1),这是责任用于扩展 OpenGL 的硬件(有时是软件)驱动程序。
因为必须将您的程序显式链接到每个可能的驱动程序组合(并在发布新驱动程序版本时重新编译和链接您的程序)对任何人都没有好处,所以实际发生的情况是:OpenGL 的版本平台附带的运行时具有在运行时从另一个已安装组件(驱动程序)加载扩展函数地址的机制。你不需要知道驱动是谁写的,什么版本,你只需要让平台的OpenGL库与驱动通信,并返回一个库本身没有实现的函数的地址。
通过这种方式,基本库(现在实际上是一个存根,因为大量 OpenGL 1.1 已被弃用)只需编写一次。在运行时之前,您仍然无法确定您的主机将支持什么,因为提供的功能集取决于安装的驱动程序。
我之前提到过 OS X,我会花一些时间来解释它的不同之处。在 OS X 上,该库实际上包含 Apple 在平台上实现的每个扩展的函数(Apple 自己在 OS X 上实现了显示驱动程序)。也就是说,只需链接到适当的框架,您就可以访问每个功能。但是,如果该功能无法在硬件/软件配置上实现,则尝试调用这些功能中的任何一个都会在运行时产生GL_INVALID_OPERATION 错误。
这就是链接时解析和运行时解析之间的区别——在 OS X 上,所有函数都在链接时解析,但这并不意味着它们是可用的。在其他平台上,扩展功能在运行时通过安装的第 3 方驱动程序解析。由于驱动程序由第三方实现比平台开发方更常见,因此第二种情况更为常见。
【讨论】:
KDAB 文章给出了非常详细的解释:
... 自 OpenGL 1.1 以来引入的任何函数的地址都必须在运行时解析
OpenGL 不是一个库,它是一个 API,即提供的一组函数。 API 的某些部分已被定义为始终由操作系统接口 库提供。由于这是固定的,因此可以在链接时解决。
在 Microsoft Windows 中,OpenGL-1.1 的所有功能都是其中的一部分。然而,后来引入 OpenGL 的所有内容,即更新版本的 OpenGL 和 扩展,都没有出现在该接口库中(这在某种程度上是支持的功能集上的最小公分母)。
由于所支持的版本和功能取决于安装的 GPU 和驱动程序,它们会因系统而异,因此必须在运行时动态使用指向所有附加功能的指针。由于加载扩展或新版本功能集没有区别,两者都通过相同的机制发生。
【讨论】:
您应该进一步阅读它。它给出了一个示例,为什么链接器在构建期间无法完成:
... 例如,在 Microsoft Windows 上,自 OpenGL 1.1 以来引入的任何函数的地址都必须在运行时解析。这几乎是现代 OpenGL 应用程序中使用的所有函数! ...
文章还解释了 proc 地址和函数等需要在运行时通过适当的查询和辅助功能来解决。
... 为了帮助解决这个问题,Qt 提供了几个有用的实用程序:QOpenGLContext::getProcAddress() 和 QOpenGLFunctions。 ...
继续阅读这篇文章!
【讨论】: