在Qt5中,引入了QOpenGL*系列类,以取代Qt4时代的QGL*系列类。
下面是从Qt5例子中抠出的两种OpenGL程序模板,方便参考。
第一种写法:
1#ifndef TRIANGLEWINDOW_H 2#define TRIANGLEWINDOW_H 3 4#include <QWindow> 5#include <QOpenGLFunctions> 6 7class QPainter; 8class QOpenGLContext; 9class QOpenGLPaintDevice; 10 11class TriangleWindow : public QWindow, protected QOpenGLFunctions 12{ 13 Q_OBJECT 14public: 15 explicit TriangleWindow(QWindow *parent = 0); 16 ~TriangleWindow(); 17 18 virtual void render(QPainter *); 19 virtual void render(); 20 virtual void initialize(); 21 22public slots: 23 void renderNow(); 24 25protected: 26 void exposeEvent(QExposeEvent *); 27 void resizeEvent(QResizeEvent *); 28 29private: 30 bool m_update_pending; 31 32 QOpenGLContext *m_context; 33 QOpenGLPaintDevice *m_device; 34 35}; 36 37#endif // TRIANGLEWINDOW_H
实现代码如下:
1#include "trianglewindow.h" 2 3#include <QCoreApplication> 4#include <QPainter> 5#include <QOpenGLContext> 6#include <QOpenGLPaintDevice> 7 8TriangleWindow::TriangleWindow(QWindow *parent) : 9 QWindow(parent) 10 , m_update_pending(false) 11 , m_context(0) 12 , m_device(0) 13{ 14 setSurfaceType(QWindow::OpenGLSurface); 15} 16 17TriangleWindow::~TriangleWindow() 18{ 19 delete m_device; 20} 21 22void TriangleWindow::render(QPainter *painter) 23{ 24 Q_UNUSED(painter); 25} 26 27void TriangleWindow::render() 28{ 29 if (!m_device) 30 m_device = new QOpenGLPaintDevice; 31 32 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 33 34 m_device->setSize(size()); 35 36 QPainter painter(m_device); 37 render(&painter); 38} 39 40void TriangleWindow::initialize() 41{ 42 glClearColor(1, 0, 0, 1); 43} 44 45void TriangleWindow::renderNow() 46{ 47 if (!isExposed()) 48 return; 49 50 m_update_pending = false; 51 52 bool needsInitialize = false; 53 54 if (!m_context) { 55 m_context = new QOpenGLContext(this); 56 m_context->setFormat(requestedFormat()); 57 m_context->create(); 58 59 needsInitialize = true; 60 } 61 62 m_context->makeCurrent(this); 63 64 if (needsInitialize) { 65 initializeOpenGLFunctions(); 66 initialize(); 67 } 68 69 render(); 70 71 m_context->swapBuffers(this); 72} 73 74void TriangleWindow::exposeEvent(QExposeEvent *event) 75{ 76 Q_UNUSED(event); 77 78 if (isExposed()) 79 renderNow(); 80} 81 82void TriangleWindow::resizeEvent(QResizeEvent *event) 83{ 84 Q_UNUSED(event); 85 86 if (isExposed()) 87 renderNow(); 88}
main方法:
1#include "trianglewindow.h" 2 3#include <QGuiApplication> 4 5int main(int argc, char **argv) 6{ 7 QGuiApplication app(argc, argv); 8 9 QSurfaceFormat format; 10 format.setSamples(4); 11 12 TriangleWindow window; 13 window.setFormat(format); 14 window.resize(640, 480); 15 window.show(); 16 17 return app.exec(); 18}
另一种写法:
1#ifndef TRIANGLEWINDOW_H 2#define TRIANGLEWINDOW_H 3 4#include <QWindow> 5 6class QOpenGLContext; 7 8class Renderer : public QObject 9{ 10 Q_OBJECT 11public: 12 explicit Renderer(const QSurfaceFormat &format, Renderer *share = 0, QScreen *screen = 0); 13 QSurfaceFormat format() const { return m_format; } 14 15public slots: 16 void render(QSurface *surface, const QColor &color, const QSize &viewSize); 17 18private: 19 void initialize(); 20 21 bool m_initialized; 22 QSurfaceFormat m_format; 23 QOpenGLContext *m_context; 24}; 25 26class TriangleWindow : public QWindow 27{ 28 Q_OBJECT 29public: 30 explicit TriangleWindow(const QSharedPointer<Renderer> &renderer); 31 32signals: 33 void needRender(QSurface *surface, const QColor &color, const QSize &viewSize); 34 35private slots: 36 void render(); 37 38protected: 39 void exposeEvent(QExposeEvent *); 40 41private: 42 const QSharedPointer<Renderer> m_renderer; 43}; 44 45#endif // TRIANGLEWINDOW_H
实现文件:
1#include "trianglewindow.h" 2 3#include <QOpenGLContext> 4 5Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *screen) 6 : m_initialized(false) 7 , m_format(format) 8{ 9 m_context = new QOpenGLContext(this); 10 if (screen) 11 m_context->setScreen(screen); 12 m_context->setFormat(format); 13 if (share) 14 m_context->setShareContext(share->m_context); 15 m_context->create(); 16} 17 18TriangleWindow::TriangleWindow(const QSharedPointer<Renderer> &renderer) 19 : m_renderer(renderer) 20{ 21 setSurfaceType(QWindow::OpenGLSurface); 22 setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); 23 24 setGeometry(QRect(10, 10, 640, 480)); 25 26 setFormat(renderer->format()); 27 28 create(); 29 30 connect(this, SIGNAL(needRender(QSurface *, const QColor &, const QSize &)), 31 renderer.data(), SLOT(render(QSurface *, const QColor &, const QSize &))); 32 33} 34 35void TriangleWindow::exposeEvent(QExposeEvent *) 36{ 37 render(); 38} 39 40void TriangleWindow::render() 41{ 42 if (isExposed()) 43 emit needRender(this, QColor(255, 0, 0), size()); 44} 45 46void Renderer::render(QSurface *surface, const QColor &color, const QSize &viewSize) 47{ 48 if (!m_context->makeCurrent(surface)) 49 return; 50 51 if (!m_initialized) { 52 initialize(); 53 m_initialized = true; 54 } 55 56 glViewport(0, 0, viewSize.width(), viewSize.height()); 57 58 glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); 59 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 60 61 m_context->swapBuffers(surface); 62 63} 64 65void Renderer::initialize() 66{ 67 glClearColor(0.1f, 0.1f, 0.2f, 1.0f); 68}
main方法:
1#include "trianglewindow.h" 2 3#include <QGuiApplication> 4 5int main(int argc, char *argv[]) 6{ 7 QGuiApplication app(argc, argv); 8 9 QSurfaceFormat format; 10 format.setDepthBufferSize(16); 11 format.setSamples(4); 12 13 QSharedPointer<Renderer> renderer(new Renderer(format)); 14 TriangleWindow *window = new TriangleWindow(renderer); 15 window->resize(640, 480); 16 window->setVisible(true); 17 18 return app.exec(); 19}
在Qt5,推荐使用QOpenGL*系列的类。