Qt OpenGL(二十)——Qt OpenGL 核心模式版本
一、写在前面
在之前的OpenGL教程(1~19)中,采用的方式都是固定渲染管线,也就是OpenGL3.2版本之前的写法,但是OpenGL从3.2版本开始,就鼓励使用核心模式进行开发了,其目的就是为了提高效率,增加编程的灵活性。
从本篇开始,我把核心模式方法的写法分享给大家,主要还是借助以Qt开发。
二、Qt推荐的例程
打开Qt Creator,在Example界面可以搜索到OpenGL相关的例程。
打开Qt creator,可以看到我的Qt版本5.8.0, MinGW的。
搜索OpenGL
如上所示,我们可以看到其中给到的几个例子。
编译运行OpenGL Window Example,可以看到效果:
三、源码
源码部分,主要包含openglwindow.h和openglwindow.cpp文件
#include <QtGui/QWindow>
#include <QtGui/QOpenGLFunctions>QT_BEGIN_NAMESPACE
class QPainter;
class QOpenGLContext;
class QOpenGLPaintDevice;
QT_END_NAMESPACE//! [1]
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{Q_OBJECT
public:explicit OpenGLWindow(QWindow *parent = 0);~OpenGLWindow();virtual void render(QPainter *painter);virtual void render();virtual void initialize();void setAnimating(bool animating);public slots:void renderLater();void renderNow();protected:bool event(QEvent *event) override;void exposeEvent(QExposeEvent *event) override;private:bool m_animating;QOpenGLContext *m_context;QOpenGLPaintDevice *m_device;
};
//! [1]
openglwindow.cpp文件内容:
#include "openglwindow.h"#include <QtCore/QCoreApplication>#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLPaintDevice>
#include <QtGui/QPainter>//! [1]
OpenGLWindow::OpenGLWindow(QWindow *parent): QWindow(parent), m_animating(false), m_context(0), m_device(0)
{setSurfaceType(QWindow::OpenGLSurface);
}
//! [1]OpenGLWindow::~OpenGLWindow()
{delete m_device;
}
//! [2]
void OpenGLWindow::render(QPainter *painter)
{Q_UNUSED(painter);
}void OpenGLWindow::initialize()
{
}void OpenGLWindow::render()
{if (!m_device)m_device = new QOpenGLPaintDevice;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);m_device->setSize(size());QPainter painter(m_device);render(&painter);
}
//! [2]//! [3]
void OpenGLWindow::renderLater()
{requestUpdate();
}bool OpenGLWindow::event(QEvent *event)
{switch (event->type()) {case QEvent::UpdateRequest:renderNow();return true;default:return QWindow::event(event);}
}void OpenGLWindow::exposeEvent(QExposeEvent *event)
{Q_UNUSED(event);if (isExposed())renderNow();
}
//! [3]//! [4]
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();}render();m_context->swapBuffers(this);if (m_animating)renderLater();
}
//! [4]//! [5]
void OpenGLWindow::setAnimating(bool animating)
{m_animating = animating;if (animating)renderLater();
}
//! [5]
四、核心模式
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
通过上面的代码我们可以看到,这个类继承的父类,其中有:QOpenGLFunctions。
这个类Qt封装了对应的OpenGL的核心模式的函数,版本化的函数包装器针对给定的 OpenGL 版本和配置文件,比如 QOpenGLFunctions_3_2_Core。
QOpenGLFunctions_X_X_Core提供OpenGL X.X版本核心模式的所有功能,是对OpenGL函数的封装。
其中的initializeOpenGLFunctions用于初始化OpenGL函数,将Qt里的函数指针指向显卡的函数,之后调用的OpenGL函数才是可用的。
五、QWindow和QOpenGLWidget
Qt这个例子中,窗口类继承了QWindow,在日常的实际项目中,我们使用更多的是继承QOpenGLWidget类。
QWindow类是Qt5.0之后引入的,QWindow的重绘与QWidget重绘有点不一样,QWindow的没有提供PaintEvent相关的函数。得实现event虚函数,才能实现重绘。
QOpenGLWidget 提供了显示集成到 Qt 应用程序中的 OpenGL 图形的功能。它使用起来非常简单:自定义类继承它并像其他 QWidget 子类一样使用,还可以选择使用 QPainter 和标准 OpenGL 渲染命令。
QOpenGLWidget类提供了三个便捷的虚函数,可以重载,用来重新实现典型的OpenGL任务:
1)paintGL () :渲染OpenGL窗口,当窗口widget需要更新时调用;
2)resize () :设置OpenGL视口、投影等,当widget调整大小(或首次显示)时调用;
3)initializeGL () : 设置OpenGL资源和状态,最先调用且调用一次。
和之前的文章中继承自QGLWidget一样,这三个函数功能也一样。
上一篇:OpenGL(十九)——Qt OpenGL波动纹理(旗子的飘动效果)
下一篇:
本文原创作者:冯一川(ifeng12358@163.com),未经作者授权同意,请勿转载。