Qt5下OpenGL程序的新写法

来源:互联网 发布:弯曲法测杨氏模量数据 编辑:程序博客网 时间:2024/06/04 20:05

在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_OBJECTpublic:    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_OBJECTpublic:    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_OBJECTpublic:    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*系列的类。

原创粉丝点击