如何使用 OpenGL 3.3 格式的 QPainter?

Posted

技术标签:

【中文标题】如何使用 OpenGL 3.3 格式的 QPainter?【英文标题】:How to use QPainter with OpenGL 3.3 format? 【发布时间】:2016-11-30 13:46:00 【问题描述】:

我正在尝试在我的 QOpenGLWidget 中使用 QPainter。但它仅适用于 3.0 OpenGL 版本。有什么问题?

这是我的代码。

#include <QApplication>
#include <QMainWindow>
#include "window.h"

int main(int argc, char *argv[])

  QApplication app(argc, argv);

  QSurfaceFormat format;

  format.setRenderableType(QSurfaceFormat::OpenGL);
  format.setProfile(QSurfaceFormat::CoreProfile);
  format.setVersion(3,3);

  // Set widget up
   Window *widget = new Window;
   widget->setFormat(format);

  // Set the window up
  QMainWindow window;
  window.setCentralWidget(widget);
  window.resize(QSize(800, 600));
  window.show();

  return app.exec();

如果我要评论“format.setVersion(3,3);”一切都会好起来的。但我的着色器无法启动。

和QOpenGLWidget子类

#ifndef WINDOW_H
#define WINDOW_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions>

class QOpenGLShaderProgram;

class Window : public QOpenGLWidget,
               protected QOpenGLFunctions

  Q_OBJECT

// OpenGL Events
public:

  void initializeGL();
  void resizeGL(int width, int height);
  void paintGL();

;

#endif // WINDOW_H

最简单的例子。

#include "window.h"
#include <QDebug>
#include <QString>
#include <QOpenGLShaderProgram>
#include "vertex.h"
#include <QPainter>


void Window::initializeGL()


void Window::resizeGL(int width, int height)


void Window::paintGL()

      QPainter p(this);
      p.setPen(Qt::red);
      p.drawLine(rect().topLeft(), rect().bottomRight());

【问题讨论】:

您有哪些硬件和驱动程序?他们支持 OpenGL 3.3 吗? 【参考方案1】:

我也遇到了同样的问题。基本上,QPainter 旨在与 OpenGL ES 2.0 一起使用。 3.3 Core 桌面 OpenGL 配置文件与 ES 2.0 不兼容。如果您使用 3.3 核心 OpenGL 配置文件,那么您不能将 QPainter 与它一起使用(至少不能在 OS X 上)。

然而,这个问题显然正在解决中 (https://codereview.qt-project.org/#/c/166202/)。所以也许下一个版本这将是可能的。

目前,解决此问题的方法是使用 QPainter 绘制到 QImage,然后将该图像绘制为 OGL 中的纹理。

这是我刚刚汇总的概念证明。 在生产代码中不要这样做。为四边形设置着色器 + VAO(附加 VBO)。然后使用带有适当变换的 glDrawArrays 将纹理放在屏幕上。

    glClearColor(1.f,1.f,1.f,1.f);
    glClear(GL_COLOR_BUFFER_BIT);

    // Use QPainter to draw to a QImage and then display the QImage

    QFont f"Helvetica",18;
    QStaticText txtmsg;
    txt.prepare(,f);
    auto dims = txt.size().toSize();

    QImage buffer(dims,QImage::Format_ARGB32);
    
        QPainter p(&buffer);
        p.fillRect(QRect0,0,dims,QColor::fromRgb(255,255,255));
        p.setPen(QColor::fromRgb(0,0,0));
        p.setFont(f);
        p.drawStaticText(0,0,txt);
    

    // Blit texture to screen
    // If you at all care about performance, don't do this!
    // Create the texture once, store it and draw a quad on screen.
    QOpenGLTexture texture(buffer,QOpenGLTexture::DontGenerateMipMaps);

    GLuint fbo;
    glGenFramebuffers(1,&fbo);
    glBindFramebuffer(GL_READ_FRAMEBUFFER,fbo);

    texture.bind();
    glFramebufferTexture2D(
        GL_READ_FRAMEBUFFER,
        GL_COLOR_ATTACHMENT0,
        GL_TEXTURE_2D,
        texture.textureId(),
        0);

    glBlitFramebuffer(
        0,
        dims.height(),
        dims.width(),
        0,
        width() / 2 - dims.width() / 2,
        height() / 2 - dims.height() / 2,
        width() / 2 + dims.width() / 2,
        height() / 2 + dims.height() / 2,
        GL_COLOR_BUFFER_BIT,
        GL_LINEAR);

    glDeleteFramebuffers(1,&fbo);

【讨论】:

以上是关于如何使用 OpenGL 3.3 格式的 QPainter?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Mac OSX 上将我的 OpenGL 从 2.1 升级到 3.3?

如何在 OS X 上初始化 QOpenGLContext 以使用 OpenGL 3.3 版?

如何使用正交投影在 OpenGL Core 3.3 中绘制一个圆?

如何加快 OpenGL 中纹理的绘制速度? (3.3+/4.1)

打开某个软件时弹出【OpenGl 3.3 is required】,请问大神如何解决?

现代OpenGL 3.3核心黑色纹理