QOpenGLWindow 、QOpenGLWidget 和 QPainter混合渲染方法初探
来源:互联网 发布:淘宝卖家开通花呗设置 编辑:程序博客网 时间:2024/04/29 21:16
该方法不存在普遍性。别按照此方法了
我用的是OpenGL 3.3 ,Qt 5.4.0
先说QWindow 和 QPainter 结合,这个Qt有现成的例子。就是 那个openglWindow那个例子。
这个基本直接照搬代码:
.h
#include <QSurfaceFormat>#include <QOpenGLContext>#include <QOpenGLShaderProgram>#include <QTimer>class OpenGLWindow : public QWindow,protected QOpenGLFunctions_3_3_Core{ Q_OBJECTpublic: OpenGLWindow(QWindow *parent = 0); ~OpenGLWindow(); virtual void render(); virtual void initialize();public slots: void renderLater(); void renderNow();protected: bool event(QEvent *event) Q_DECL_OVERRIDE; void exposeEvent(QExposeEvent *event) Q_DECL_OVERRIDE;private: bool m_update_pending; bool m_animating; QOpenGLContext *m_context; QOpenGLPaintDevice *m_device; QOpenGLBuffer * vbo; QOpenGLVertexArrayObject * vao; QOpenGLShaderProgram *m_program; QTimer * timer; float frame;};#endif // OPENGLWINDOW_H
.cpp
#include "openglwindow.h"#include <QCoreApplication>#include <QMatrix4x4>static const char *vertexShaderSource = "#version 330 core \n" "in vec4 posAttr;\n" "uniform mat4 matrix;\n" "void main() {\n" " gl_Position = matrix * posAttr;\n" "}\n";static const char *fragmentShaderSource = "#version 330 core \n" "out vec4 col;\n" "void main() {\n" " col = vec4(1.0f,0.0f,0.0f,1.0f);\n" "}\n";OpenGLWindow::OpenGLWindow(QWindow *parent) : QWindow(parent), m_update_pending(false) , m_context(0) , m_device(0){ setSurfaceType(QWindow::OpenGLSurface); QSurfaceFormat format; format.setDepthBufferSize(24); //format.setVersion(3,3); format.setProfile(QSurfaceFormat::CoreProfile); setFormat(format); timer = new QTimer; connect(timer,SIGNAL(timeout()),this,SLOT(renderNow())); timer->start(50); frame =0 ;// m_context = new QOpenGLContext;// m_context->setFormat(format);// m_context->create();}OpenGLWindow::~OpenGLWindow(){}void OpenGLWindow::initialize(){ m_program = new QOpenGLShaderProgram(this); m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource); m_program->link();}void OpenGLWindow::render(){ m_program->bind(); QMatrix4x4 matrix; matrix.perspective(60.0f, float(width())/float(height()), 0.1f, 100.0f); matrix.rotate(frame, 0, 1, 0); GLfloat vertices[] = { 0.0f, 0.707f,-1.0f,1.0f, -0.5f, -0.5f,-1.0f,1.0f, 0.5f, -0.5f,-1.0f,1.0f }; glClearColor(0.5f,0.5f,0.5f,1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); QOpenGLVertexArrayObject vao; vao.create(); vao.bind(); QOpenGLBuffer vertex; vertex.create(); vertex.bind(); vertex .setUsagePattern(QOpenGLBuffer::StaticDraw); vertex.allocate(vertices,sizeof(vertices)); m_program->enableAttributeArray(0); m_program->setAttributeBuffer(0,GL_FLOAT,0,4,0); m_program->setUniformValue("matrix",matrix); glDrawArrays(GL_TRIANGLES, 0, 3); frame++;}void OpenGLWindow::renderLater(){ if (!m_update_pending) { m_update_pending = true; QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); }}bool OpenGLWindow::event(QEvent *event){ switch (event->type()) { case QEvent::UpdateRequest: m_update_pending = false; renderNow(); return true; default: return QWindow::event(event); }}void OpenGLWindow::exposeEvent(QExposeEvent *event){ Q_UNUSED(event); if (isExposed()) renderNow();}void OpenGLWindow::renderNow(){ if (!isExposed()) return; bool needsInitialize = false; if (!m_context) { m_context = new QOpenGLContext(this); m_context->setFormat(requestedFormat()); m_context->create(); needsInitialize = true; } m_context->makeCurrent(this); if (needsInitialize) { initializeOpenGLFunctions(); initialize(); } if (!m_device) m_device = new QOpenGLPaintDevice; m_device->setSize(size()); QPainter painter(m_device); painter.beginNativePainting(); render(); painter.endNativePainting(); QPen pen; pen.setColor(Qt::green); painter.setPen(pen); painter.setFont(QFont("微软雅黑")); painter.drawText(20,50,"frame:"+QString::number(frame)); painter.drawEllipse(100,100,50,80); painter.end(); m_context->swapBuffers(this); QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));}
2 QOpenGLWidget 和 QOpenGLWindow
这个我原来按照一篇博客 叫“
Qt Weekly #20: Completing the offering: QOpenGLWindow and QRasterWindow
”结果总是不成功,多方发帖询问未果。
后来自己研究了下,基本实现了混合渲染,但是有个缺点就是只能在OpenGL上面绘制图形。具体做法:
那个Qt博客中说,只要在虚函数paintGL()中写上QPainter,然后就可以混合渲染了,但是我按照他的做法没有成功过。我的做法是不再重写 paintGL(),而是重写paintEvent()。
原来的paintEvent()是会自动调用paintGL()的,重写以后的paintEvent如下代码:
void Render::paintEvent(QPaintEvent *e){ makeCurrent(); paintGL(); QPainter pter(this); QImage pic; pic.load("../Select/timg.jpg"); pter.setPen(Qt::blue); pter.drawText(20,50,"This is a Text!"); pter.drawEllipse(80,100,40,50); pter.drawImage(200,40,pic); pter.end(); update();}
paintGL()中还是OpenGL代码。
其次还要注意的时,在类中构造函数中要设置好 format,我试着加入format的版本信息
format.setVersion(3,3);
format.setProfile(QSurfaceFormat::CoreProfile);
但是这样会导致QPainter不起作用。我是在main函数中设置的全局format。
QOpenGLWindow 和 QOpenGLWidget 实现是一样的,就是继承的时候换一下就可以。具体代码在下面的连接可以下载。
我只是初步探索一下,肯定很多不足的地方,如果有更好的方法,记得分享呀。
QOpenGLWindow QPainter混合代码
0 0
- QOpenGLWindow 、QOpenGLWidget 和 QPainter混合渲染方法初探
- QOpenGLWidget + QPainter混合编程
- QOPenGLWidget与QPainter混合编程--绘制文本
- 在Qt5.4中如何实现QOpenGLWidget和QPainter混合编程
- QOpenGLWidget绘制2D的方法
- 实现Qt和OpenGL混合渲染
- 模仿QtOpenGL例子VowelCube时遇到的三维和Qt绘图引擎QPainter混合问题
- 初探java和matlab混合编程
- qt中ogre与QPainter混合
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- 3D地形多层纹理混合加阴影渲染方法
- ComposeShader混合渲染
- HDOJ 4931 Happy Three Friends
- 记录一些自己在linux下常用的软件
- UE 常用功能笔记
- Eclipse+hibernate+mysql错误:Reading schema error解决
- 缓存策略优化
- QOpenGLWindow 、QOpenGLWidget 和 QPainter混合渲染方法初探
- NYOJ349 Sorting It All Out(拓扑排序)
- UnicodeEncodeError: 'latin-1' codec can't encode characters in position 4-5: ordinal not in range(25
- 1B. Spreadsheets(字符串+数学)
- 对第四维,时间的感知
- [python]Python操作MySQL
- 使用ContentProvider读取短信,备份短信
- ACM第K大数——双二分
- Dos中的地址重定位