QOpenGLFunctions的正确用法

Posted

技术标签:

【中文标题】QOpenGLFunctions的正确用法【英文标题】:Correct usages of QOpenGLFunctions 【发布时间】:2014-06-09 14:47:52 【问题描述】:

我目前正在使用 Qt5 gui 模块来访问 OpenGL 函数。 然后我发现QOpenGLFunctions 很有用,因为:

它封装了 OpenGL for Desktop 和 OpenGL ES,确保我以“可移植”的方式使用 OpenGL API。 我不必担心包含 OpenGL 标头,Qt 为我完成。

但我对使用它的正确方法有疑问。 以下几行仅列出了我所知道的使用此类的三种方式。 我的问题是:有没有使用QOpenGLFunctions 的好方法?

继承自QOpenGLFunctions

Qt 官方文档说'从QOpenGLFunctions 继承你的类并像以前一样使用 glXXXX 类。但我不喜欢这种方式:

如果我的类之前希望从其他类继承,我必须进行多重继承。我不是那种东西。即使这样的情况无论如何都是安全的,这也是美学...... 每个 glXXXX 包装类都是非常量的。我会强制所有使用 OpenGL 的方法都是非常量的。这没有多大意义。是的,OpenGLFunctions 类在我做glClear(...) 时可以合法地是非常量,但为什么我的方法DrawableShape::render(...) 会是?

关于继承QOpenGLFunctions。它的构造函数可以接受一个参数:当前的 OpenGL 上下文。这个参数对我来说似乎很重要,但是没有 Qt 文档调用这个构造函数。相反,他们让编译器选择无参数构造函数。

拥有QOpenGLFunctions 成员

另一种想法应该是让QOpenGLFunctions 的实例作为任何调用glXXXXX 函数的类的成员,或者至少是对一个实例的引用,并从该实例调用每个OpenGL 函数。

QOpenGLFunctions 作为参数传递

对于每个使用 OpenGL 的函数,调用者发送QOpenGLFunctions。这样:

void renderRectangle(QOpenGLFunctions& opengl) const;

但是我怎么能确定 this 函数需要它而 this 一个不需要呢?我的意思是源代码到时候会变得更大,我担心看到接收这个参数的类的每个方法都有风险......

【问题讨论】:

最近有几个类似的问题。我会留给其他人来决定这是否足够接近以至于可以复制。但是在任何情况下,以前的答案都应该有帮助。问题一:***.com/questions/23796775/…。问题二:***.com/questions/23841355/…. 实际上,是的,我看到了这两个问题。但即使这两个答案都很有价值,我也不能说他们对“有没有好的做法?”提供了一个很好的答案,他们只回答“我们可以这样做吗?”问题:) 关于在 QOpenGLFunction 构造函数中包含上下文。这在某些平台(Windows/WGL)和其他平台(Linux/GLX)上很重要。这一切都与函数指针在每个特定平台上的加载方式有关。在 Windows 上,两个上下文可能属于完全不同的 GL 实现,因此如果您使用多个上下文,则应始终确保函数指针与某个上下文相关。 GLX 是不同的,事实上你可以在 GLX 中加载函数指针,甚至不需要上下文——它们在调用时不会做任何事情,直到你有一个。 很高兴知道,谢谢! 【参考方案1】:

遵循其他面向对象包装库的相同原则,您可能会考虑对第三个选项进行一些小改动。

定义一个代表你当前的 opengl 上下文的类,它也扩展了 QOpenGLFunctions

class GL : public QOpenGLFunctions

  QGLContext& context;

  GL(QGLContext& c) : glContext(c) ... 

;

渲染线程将初始化一个提供当前上下文的 GL 实例,并将其传递给所有需要执行 opengl 操作的渲染实例。通过这种方式,您还可以确保在初始化和使用 opengl 结构和缓冲区时不会混合多个上下文。

class Visualizer

 void glInit(GL& gl) ...  

 void glPaintOpaque(GL& gl) ...  

 void glPaintTranslucent(GL& gl) ...  

;

【讨论】:

是的,这是个好主意。实际上 glXXX 函数并没有全部包含在 QOpenGLFunctions 中,这迫使我同时使用 gl.doSomething()glDoSomethingElse() 但这并不是一个真正的问题。感谢您的回答。

以上是关于QOpenGLFunctions的正确用法的主要内容,如果未能解决你的问题,请参考以下文章

QOpenGLFunctions的相关的使用

QOpenGLFunctions 缺少重要的 OpenGL 函数

QOpenGLFunctions的使用

QOpenGLFunctions 和 PySide2

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

带有 QT 错误的 OpenGL:断言:“QOpenGLFunctions::isInitialized(d_ptr)”。无法创建 OpenGL 上下文