现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

Qt5下OpenGL程序的新写法

2015-07-26 06:42 工业·编程 ⁄ 共 5345字 ⁄ 字号 暂无评论

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

作者:fuyajun01

给我留言

留言无头像?