Qt OpenGL(二十)——Qt OpenGL 核心模式版本

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),未经作者授权同意,请勿转载。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冯一川

谢谢老板对我的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值