Qt5下OpenGL程序的新写法

在Qt5中,引入了QOpenGL*系列类,以取代Qt4时代的QGL*系列类。


下面是从Qt5例子中抠出的两种OpenGL程序模板,方便参考。


第一种写法:

#ifndef TRIANGLEWINDOW_H
#define TRIANGLEWINDOW_H

#include <QWindow>
#include <QOpenGLFunctions>

class QPainter;
class QOpenGLContext;
class QOpenGLPaintDevice;

class TriangleWindow : public QWindow, protected QOpenGLFunctions
{
    Q_OBJECT
public:
    explicit TriangleWindow(QWindow *parent = 0);
    ~TriangleWindow();
    
    virtual void render(QPainter *);
    virtual void render();
    virtual void initialize();
    
public slots:
    void renderNow();

protected:
    void exposeEvent(QExposeEvent *);
    void resizeEvent(QResizeEvent *);

private:
    bool m_update_pending;

    QOpenGLContext *m_context;
    QOpenGLPaintDevice *m_device;
    
};

#endif // TRIANGLEWINDOW_H

实现代码如下:

#include "trianglewindow.h"

#include <QCoreApplication>
#include <QPainter>
#include <QOpenGLContext>
#include <QOpenGLPaintDevice>

TriangleWindow::TriangleWindow(QWindow *parent) :
    QWindow(parent)
  , m_update_pending(false)
  , m_context(0)
  , m_device(0)
{
    setSurfaceType(QWindow::OpenGLSurface);
}

TriangleWindow::~TriangleWindow()
{
    delete m_device;
}

void TriangleWindow::render(QPainter *painter)
{
    Q_UNUSED(painter);
}

void TriangleWindow::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);
}

void TriangleWindow::initialize()
{
    glClearColor(1, 0, 0, 1);
}

void TriangleWindow::renderNow()
{
    if (!isExposed())
        return;

    m_update_pending = false;

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

void TriangleWindow::exposeEvent(QExposeEvent *event)
{
    Q_UNUSED(event);

    if (isExposed())
        renderNow();
}

void TriangleWindow::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);

    if (isExposed())
        renderNow();
}

main方法:

#include "trianglewindow.h"

#include <QGuiApplication>

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);

    QSurfaceFormat format;
    format.setSamples(4);

    TriangleWindow window;
    window.setFormat(format);
    window.resize(640, 480);
    window.show();

    return app.exec();
}

另一种写法:

#ifndef TRIANGLEWINDOW_H
#define TRIANGLEWINDOW_H

#include <QWindow>

class QOpenGLContext;

class Renderer : public QObject
{
    Q_OBJECT
public:
    explicit Renderer(const QSurfaceFormat &format, Renderer *share = 0, QScreen *screen = 0);
    QSurfaceFormat format() const { return m_format; }

public slots:
    void render(QSurface *surface, const QColor &color, const QSize &viewSize);

private:
    void initialize();

    bool m_initialized;
    QSurfaceFormat m_format;
    QOpenGLContext *m_context;
};

class TriangleWindow : public QWindow
{
    Q_OBJECT
public:
    explicit TriangleWindow(const QSharedPointer<Renderer> &renderer);
    
signals:
    void needRender(QSurface *surface, const QColor &color, const QSize &viewSize);

private slots:
    void render();

protected:
    void exposeEvent(QExposeEvent *);

private:
    const QSharedPointer<Renderer> m_renderer;
};

#endif // TRIANGLEWINDOW_H

实现文件:

#include "trianglewindow.h"

#include <QOpenGLContext>

Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *screen)
    : m_initialized(false)
    , m_format(format)
{
    m_context = new QOpenGLContext(this);
    if (screen)
        m_context->setScreen(screen);
    m_context->setFormat(format);
    if (share)
        m_context->setShareContext(share->m_context);
    m_context->create();
}

TriangleWindow::TriangleWindow(const QSharedPointer<Renderer> &renderer)
    : m_renderer(renderer)
{
    setSurfaceType(QWindow::OpenGLSurface);
    setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);

    setGeometry(QRect(10, 10, 640, 480));

    setFormat(renderer->format());

    create();

    connect(this, SIGNAL(needRender(QSurface *, const QColor &, const QSize &)),
            renderer.data(), SLOT(render(QSurface *, const QColor &, const QSize &)));

}

void TriangleWindow::exposeEvent(QExposeEvent *)
{
    render();
}

void TriangleWindow::render()
{
    if (isExposed())
        emit needRender(this, QColor(255, 0, 0), size());
}

void Renderer::render(QSurface *surface, const QColor &color, const QSize &viewSize)
{
    if (!m_context->makeCurrent(surface))
        return;

    if (!m_initialized) {
        initialize();
        m_initialized = true;
    }

    glViewport(0, 0, viewSize.width(), viewSize.height());

    glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    m_context->swapBuffers(surface);

}

void Renderer::initialize()
{
    glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
}

main方法:

#include "trianglewindow.h"

#include <QGuiApplication>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QSurfaceFormat format;
    format.setDepthBufferSize(16);
    format.setSamples(4);

    QSharedPointer<Renderer> renderer(new Renderer(format));
    TriangleWindow *window = new TriangleWindow(renderer);
    window->resize(640, 480);
    window->setVisible(true);

    return app.exec();
}

在Qt5,推荐使用QOpenGL*系列的类。

### QT 支持信息与资源 #### 官方文档和支持渠道 官方提供了详尽的文档来帮助开发者理解和使用 Qt 技术栈。这些资料不仅涵盖了安装指南、教程,还包括详细的 API 参考手册[^1]。 对于多语言支持方面,在使用 Qt Installer Framework 进行应用程序打包时,如果目标语言不在框架预设范围内,则需额外引入对应于该语言版本的 `qtbase_*.qm` 文件到项目资源中,并通过别名机制使其生效。 #### 社区和技术论坛 除了官方文档外,活跃的技术社区也是获取支持的重要途径之一。无论是遇到具体技术难题还是希望交流最佳实践,都可以在 Stack Overflow 或者专门针对 Qt 用户设立的讨论板上找到答案。 #### 开发工具集成 为了简化开发过程并提高效率,Qt 提供了一系列 IDE 插件和其他辅助工具。例如,Visual Studio 和 CLion 的插件能够显著改善编码体验;而 Qt Creator 则是一个专为 C++ 应用程序设计的强大环境,内置了调试器、UI 设计器等多种实用组件。 #### 版本兼容性和特性启用 当涉及到不同版本间的差异时,特别是从旧版迁移到版的过程中,需要注意一些特定配置项的变化。比如,在 qmake 构建系统下,“greaterThan(QT_MAJOR_VERSION,4):QT+=widgets”的写法用于确保仅当主版本号大于 4 时才加载 widgets 模块,这有助于保持向后兼容性的同时利用功能[^2]。 #### OpenGL 渲染能力增强 关于图形渲染性能优化,QOpenGLWidget 类作为 Qt 自带的一个高效解决方案被广泛采用。它允许直接访问底层硬件加速接口如 OpenGL ES,从而实现复杂场景下的流畅交互效果。此部件内部实现了初始化 (`initializeGL`)、绘制(`paintGL`) 等核心方法,并提供了一套完整的着色器编程接口 (QOpenGLShaderProgram),使得自定义视觉特效变得更加容易[^3]。 ```cpp // 示例:创建一个简单的 QOpenGLWidget 子类 class MyGLWidget : public QOpenGLWidget { protected: void initializeGL() override; void paintGL() override; private: QOpenGLShaderProgram *m_program; }; ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值