opengl - 如何测试 OpenGL 应用程序是否适用于某些特定的 OpenGL 版本?
问题描述
最近我意识到我的应用程序正在使用仅在 OpenGL 4.5 - glCreateTextures上可用的 OpenGL 调用,而我意识到这一点只是因为我试图在仅支持 OpenGL 4.1 的 MacOS 计算机上运行该应用程序并且它在那里崩溃了。
应用程序请求 OpenGL 4.0 核心配置文件、3.2 核心配置文件和 3.2 前向兼容核心配置文件(按此顺序),但尽管获得了 4.0 配置文件,但调用glCreateTextures
成功且没有任何警告。
我希望我的应用程序可以在任何支持 3.2 的设备上运行,但我无法定期访问实际上不支持 4.5 的硬件。在 API 和着色器使用中可能存在其他类似的问题,这些问题会阻止与较低 OpenGL 版本的兼容性,我想了解它们。
如何测试我的应用程序以确保它可以与某些特定版本的 OpenGL(3.2、4.0)一起工作,而无需在支持较新版本的硬件上实际运行它?
在我的情况下,应用程序在 JVM 上运行(用 Scala 或 Java 编写)并使用 LWJGL + GLFW 绑定,但即使知道如何对本机 C/C++ 应用程序执行此操作也会有所帮助,如果有办法,应该是可能的将其转换为 JVM 世界。
解决方案
这是 OpenGL 的一个普遍问题,加载核心函数和同名扩展函数之间没有区别。
在 的情况下glCreateTextures
,这个 OpenGL 函数既来自ARB_direct_state_access
扩展,也来自具有相同名称的 OpenGL 4.5(该函数成为核心)。
在 LWJGL 的具体上下文中实际发生的是,它将在运行时检查上下文是否支持 OpenGL 4.5(自 OpenGL 3.0 以来有一个明确的函数允许检查 OpenGL 上下文是否支持特定的核心版本)。当您请求核心配置文件(例如 3.3 核心)时,LWJGL 会发现此检查返回false 。
但是,LWJGL也会检查每个广告的 OpenGL 扩展是否存在,并从这些扩展中加载所有公开函数的函数指针。在您的情况下,当您请求例如 3.3 核心上下文,但您的驱动程序仍然暴露ARB_direct_state_access
(这非常好)时,LWJGL将加载函数指针glCreateTextures
就好了。并且由于在通过核心 GL 类或通过扩展类调用 LWJGL 中路由 GL 函数调用没有区别(毕竟它仍然是相同的底层 GL 函数),因此调用将成功。
现在为了解决这个问题,有一个 GitHub 问题允许 LWJGL 客户端排除某些扩展被加载:https ://github.com/LWJGL/lwjgl3/issues/683
一旦这在 LWJGL 3 版本中登陆,当您还排除扩展时,在您请求的 GL 核心版本中不是核心的功能将不可见/不可用。
另一种至少降低使用来自高于应用程序所针对的 GL 版本的 GL 函数的风险的方法是,简单地不使用高于应用程序所针对的 GL 版本的org.lwjgl.opengl.GLxyC
类中的任何方法。x.y
所以实际上,当你说:
最近我意识到我的应用程序正在使用仅在 OpenGL 4.5 - glCreateTextures 上可用的 OpenGL 调用,而我意识到这一点只是因为我试图在仅支持 OpenGL 4.1 的 MacOS 计算机上运行该应用程序并且它在那里崩溃了。
那么有人可以争辩说这是在你身上。因为这意味着您故意使用 GL45 类中的 OpenGL 函数,所以您希望以 OpenGL 4.5 为目标。
推荐阅读
- sql-server - 将不同的列值转换为 varchar 值
- dafny - 自然数的基本运算 (+/*) 并证明它们的交换性和结合性 - Dafny
- css - 为什么我的 scss 样式不适用于三元表达式
- reactjs - 在 Monorepo 项目中创建 React App 作为示例
- python - 已分配类的变量是否应该是小写?
- nearprotocol - 获取 storaged u64 的默认值
- c++ - 如何从屏幕坐标中获取世界空间坐标
- c# - 在 .NET 4.5 应用程序中启用 TLS1.2
- html - 怎么只有 1 个 div 不会与 flexbox 中的其他 div 一起收缩?
- asp.net - oracle.dataaccess.dll 与 oracle.manageddataaccess.dll 有什么区别以及托管 dll 相对于数据访问 dll 的优势是什么