如何将 QPainter 和 OpenGL 与着色器与 Qt5.9 并行使用

Posted

技术标签:

【中文标题】如何将 QPainter 和 OpenGL 与着色器与 Qt5.9 并行使用【英文标题】:How to use QPainter and OpenGL with shaders in parallel with Qt5.9 【发布时间】:2019-04-11 08:46:01 【问题描述】:

我看到很多关于如何在QOpenGLWidget 上并行使用带有着色器和QPainter 的OpenGL 的问题。例如Example 1、Example 2 和Example 3。

我经历了很多问题,当使用 QPainter、原生 OpenGL 代码和着色器时。有时只有 QPainter 的东西被渲染,有时只有存储在 VertexArrayObjects 中的东西被渲染,或者使用“旧方式”设置顶点的东西被渲染,glVertex() 被渲染。

我设法构建了一个非常小的解决方案,它只修改了 QPainter 的用法,以并行使用每 3 种绘图方法。

结果是,您可以在QOpenGLWidgetpaintGL() 管道中的任意位置使用QPainter 和着色器,而无需每次修改OpenGL 状态或使用@987654331 开始和结束nativePainting @。

【问题讨论】:

【参考方案1】:

所以解决方案是创建一个自己的QPainter 类,称为MyPainter,它继承自QPainter

class MyPainter : public QPainter 

public:
    MyPainter(QPaintDevice* device, ShaderProgram* sp);
    bool end();

private:
    ShaderProgram* shaderProgram;
;

在这个类中,你重写QPainterend()-方法并以下列方式实现它:

 MyPainter::MyPainter(QPaintDevice* device, ShaderProgram* sp)
: QPainter(device), shaderProgram(sp) 


bool MyPainter::end() 
    beginNativePainting();
    bool b = shaderProgram->bind();
    return b;

首先你必须再次beginNativePainting(),当QPainter在绘制完之后结束,然后你必须再次绑定你当前的shaderProgram。请注意,ShaderProgram 在此示例中是 QOpenGLShaderProgram 的继承类。 现在在paintGL() 方法的QOpenGLWidget 类中使用MyPainter 而不是QPainter,一切都应该正常工作,您可以随时调用OpenGL 函数和QPainter 方法。 此解决方案已使用 Qt5.9.1、Visual Studio 2015 和 Windows 7 进行了测试。 如果某些东西对您不起作用,也许您可​​以提供一个示例,说明什么不起作用以及如何使用 QPainter 和 OpenGL。我对并行使用 QPainter 和 OpenGL 的“正确”方式非常感兴趣。

【讨论】:

以上是关于如何将 QPainter 和 OpenGL 与着色器与 Qt5.9 并行使用的主要内容,如果未能解决你的问题,请参考以下文章

将 emscripten 与 opengl 着色器一起使用

如何使用 OpenGL 3.3 格式的 QPainter?

OpenGL:如何将多个纹理传递给具有一个变量的着色器?

跨多个着色器的 OpenGL 统一

如何通过实例渲染将每个实例数据(例如定位)传递给 OpenGL 3.2 中的着色器?

用于渲染 2D 文本的 paintGL() 中的着色器和 QPainter 之间的冲突