如何在OpenGL 3.3格式中使用QPainter?

时间:2016-11-30 13:46:00

标签: c++ qt opengl

我正在尝试在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());
}

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。基本上,QPainter旨在与OpenGL ES 2.0一起使用。 3.3核心桌面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 txt{msg};
    txt.prepare({},f);
    auto dims = txt.size().toSize();

    QImage buffer(dims,QImage::Format_ARGB32);
    {
        QPainter p(&buffer);
        p.fillRect(QRect{{0,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);