QPainter如何使用OpenGL 3.3格式? [英] How to use QPainter with OpenGL 3.3 format?

查看:277
本文介绍了QPainter如何使用OpenGL 3.3格式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use QPainter in my QOpenGLWidget. But it only works with 3.0 OpenGL version. What is the problem?

这是我的代码.

#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);"一切都会正常.但是我的着色器无法启动.

If i'll comment "format.setVersion(3,3);" everything will work fine. But my shaders won't start up.

和QOpenGLWidget子类

And QOpenGLWidget subclass

#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());
}

推荐答案

我只是遇到了同样的问题.基本上,QPainter旨在与OpenGL ES 2.0一起使用. 3.3核心桌面OpenGL配置文件与ES 2.0不兼容.如果您使用3.3核心OpenGL配置文件,则无法将其与QPainter一起使用(至少在OS X上不是如此).

I just had the same problem. Basically, QPainter is designed to work with OpenGL ES 2.0. The 3.3 Core desktop OpenGL profile is not compatible with ES 2.0. If you use the 3.3 core OpenGL profile then you cannot use QPainter with it (at least not on OS X).

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

The issue is however apparently being worked on (https://codereview.qt-project.org/#/c/166202/). So perhaps next release this will be possible.

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

Currently, the way to get around this is to use QPainter to draw to a QImage and then draw that image as a texture in OGL.

这是我刚刚提出的概念证明. 在生产代码中不要这样做.为四元设置着色器+ VAO(已附加VBO).然后使用带有适当转换的glDrawArrays将纹理显示在屏幕上.

Here is a proof of concept I just put together. In production code don't do this. Setup a shader + VAO (with VBO attached) for a quad. Then use glDrawArrays with an appropriate transform to put the texture on screen.

    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);

这篇关于QPainter如何使用OpenGL 3.3格式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆