在使用 QOpenGLFunctions 时将 OpenGL 功能封装在 C++ 对象中

Posted

技术标签:

【中文标题】在使用 QOpenGLFunctions 时将 OpenGL 功能封装在 C++ 对象中【英文标题】:Encapsulating OpenGL functionality in C++ objects while using QOpenGLFunctions 【发布时间】:2014-05-22 02:13:34 【问题描述】:

我决定将 Qt 集成到我的 OpenGL 项目中。到目前为止,我一直使用原始 OpenGL 调用来制作纹理、制作帧缓冲区、绘制东西等。问题是 OpenGL 调用隐藏在诸如纹理对象之类的对象中。例如,您可以在其构造函数中为纹理对象提供一个字符串路径,然后该对象将自动从文件中加载该纹理数据并使用它创建一个 OpenGL 纹理(显然使用 OpenGL 函数来执行此操作)。由于 QOpenGLFunctions 本身就是一个对象,我要么必须限制进行这些调用的位置,要么将对它的引用传递给我的项目中进行 OpenGL 函数调用的每个对象。

这确实是不可取的。无论如何我可以解决这个问题吗?我应该重新考虑我的 OpenGL 对象的设计吗?

【问题讨论】:

【参考方案1】:

您有几个选择。我个人认为将渲染代码本地化在软件的有限部分中通常是可取的。将QOpenGLFunctions 对象显式传递给需要它的类可以让您明确哪些类进行渲染,并对其进行一定程度的控制。除非它在您的特定架构中变得过于繁琐,否则这可能是我的首选。

另一种选择是在单例中保留对QOpenGLFunctions 对象的引用,这样每个需要它的人都可以获取该实例。虽然可以争论使用单例(我真的不想就单例的善恶展开宗教辩论),但这是一个非常实用的解决方案。或者,如果您不关心隐藏您真正在做什么,您可以将引用保存在全局变量中。

据我从 Qt 文档 (http://qt-project.org/doc/qt-5/qopenglfunctions.html) 中得知,创建多个实例也是完全合法的。看起来实例不包含任何状态。因此,您可以在构造任何需要 OpenGL 渲染的对象时创建一个实例,并将其保存在成员变量中。有一个代码片段显示了如何在该文档页面上创建一个新实例:

QOpenGLFunctions glFuncs(QOpenGLContext::currentContext());

您只需要注意实例是在上下文为当前时创建的。

【讨论】:

好的,谢谢。 QOpenGLFunctions 是否需要使用?推荐吗? 我分享将指向函数的指针传递给需要它的类的感觉。但是,只有在您期望支持 openGL 2.X 时才应该调用单例和 glFuncs。如果您有多个上下文并希望支持 openGL 4.X 功能,请致电 QOpenGLContext::versionFunctions<T>()。就我而言,我更喜欢在 init() 函数中将上下文传递给我的类。这给了我更多的信息和灵活性。 使用 QOpenGLFunctions 有两个好处。 1) 类中列出的函数一定会被你当前使用的上下文所支持。其次,您不需要在项目中包含 GL 文件夹或库。只是 Qt。

以上是关于在使用 QOpenGLFunctions 时将 OpenGL 功能封装在 C++ 对象中的主要内容,如果未能解决你的问题,请参考以下文章

QOpenGLFunctions的使用

QOpenGLFunctions类

QOpenGLFunctions的正确用法

QOpenGLFunctions 和 PySide2

Qt QOpenGLFunctions 未在此范围内声明

QOpenGLFunctions 缺少重要的 OpenGL 函数