如何使用 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)