Qt5下OpenGL程序的新写法

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

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

第一种写法:

[cpp] view plain copy
 
  1. #ifndef TRIANGLEWINDOW_H  
  2. #define TRIANGLEWINDOW_H  
  3.   
  4. #include <QWindow>  
  5. #include <QOpenGLFunctions>  
  6.   
  7. class QPainter;  
  8. class QOpenGLContext;  
  9. class QOpenGLPaintDevice;  
  10.   
  11. class TriangleWindow : public QWindow, protected QOpenGLFunctions  
  12. {  
  13.     Q_OBJECT  
  14. public:  
  15.     explicit TriangleWindow(QWindow *parent = 0);  
  16.     ~TriangleWindow();  
  17.       
  18.     virtual void render(QPainter *);  
  19.     virtual void render();  
  20.     virtual void initialize();  
  21.       
  22. public slots:  
  23.     void renderNow();  
  24.   
  25. protected:  
  26.     void exposeEvent(QExposeEvent *);  
  27.     void resizeEvent(QResizeEvent *);  
  28.   
  29. private:  
  30.     bool m_update_pending;  
  31.   
  32.     QOpenGLContext *m_context;  
  33.     QOpenGLPaintDevice *m_device;  
  34.       
  35. };  
  36.   
  37. #endif // TRIANGLEWINDOW_H  

实现代码如下:

[cpp] view plain copy
 
  1. #include "trianglewindow.h"  
  2.   
  3. #include <QCoreApplication>  
  4. #include <QPainter>  
  5. #include <QOpenGLContext>  
  6. #include <QOpenGLPaintDevice>  
  7.   
  8. TriangleWindow::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.   
  17. TriangleWindow::~TriangleWindow()  
  18. {  
  19.     delete m_device;  
  20. }  
  21.   
  22. void TriangleWindow::render(QPainter *painter)  
  23. {  
  24.     Q_UNUSED(painter);  
  25. }  
  26.   
  27. void 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.   
  40. void TriangleWindow::initialize()  
  41. {  
  42.     glClearColor(1, 0, 0, 1);  
  43. }  
  44.   
  45. void 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.   
  74. void TriangleWindow::exposeEvent(QExposeEvent *event)  
  75. {  
  76.     Q_UNUSED(event);  
  77.   
  78.     if (isExposed())  
  79.         renderNow();  
  80. }  
  81.   
  82. void TriangleWindow::resizeEvent(QResizeEvent *event)  
  83. {  
  84.     Q_UNUSED(event);  
  85.   
  86.     if (isExposed())  
  87.         renderNow();  
  88. }  

main方法:

[cpp] view plain copy
 
  1. #include "trianglewindow.h"  
  2.   
  3. #include <QGuiApplication>  
  4.   
  5. int 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. }  

另一种写法:

[cpp] view plain copy
 
  1. #ifndef TRIANGLEWINDOW_H  
  2. #define TRIANGLEWINDOW_H  
  3.   
  4. #include <QWindow>  
  5.   
  6. class QOpenGLContext;  
  7.   
  8. class Renderer : public QObject  
  9. {  
  10.     Q_OBJECT  
  11. public:  
  12.     explicit Renderer(const QSurfaceFormat &format, Renderer *share = 0, QScreen *screen = 0);  
  13.     QSurfaceFormat format() const { return m_format; }  
  14.   
  15. public slots:  
  16.     void render(QSurface *surface, const QColor &color, const QSize &viewSize);  
  17.   
  18. private:  
  19.     void initialize();  
  20.   
  21.     bool m_initialized;  
  22.     QSurfaceFormat m_format;  
  23.     QOpenGLContext *m_context;  
  24. };  
  25.   
  26. class TriangleWindow : public QWindow  
  27. {  
  28.     Q_OBJECT  
  29. public:  
  30.     explicit TriangleWindow(const QSharedPointer<Renderer> &renderer);  
  31.       
  32. signals:  
  33.     void needRender(QSurface *surface, const QColor &color, const QSize &viewSize);  
  34.   
  35. private slots:  
  36.     void render();  
  37.   
  38. protected:  
  39.     void exposeEvent(QExposeEvent *);  
  40.   
  41. private:  
  42.     const QSharedPointer<Renderer> m_renderer;  
  43. };  
  44.   
  45. #endif // TRIANGLEWINDOW_H  

实现文件:

[cpp] view plain copy
 
  1. #include "trianglewindow.h"  
  2.   
  3. #include <QOpenGLContext>  
  4.   
  5. Renderer::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.   
  18. TriangleWindow::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.   
  35. void TriangleWindow::exposeEvent(QExposeEvent *)  
  36. {  
  37.     render();  
  38. }  
  39.   
  40. void TriangleWindow::render()  
  41. {  
  42.     if (isExposed())  
  43.         emit needRender(this, QColor(255, 0, 0), size());  
  44. }  
  45.   
  46. void 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.   
  65. void Renderer::initialize()  
  66. {  
  67.     glClearColor(0.1f, 0.1f, 0.2f, 1.0f);  
  68. }  

main方法:

[cpp] view plain copy
 
  1. #include "trianglewindow.h"  
  2.   
  3. #include <QGuiApplication>  
  4.   
  5. int 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下OpenGL程序的新写法

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

原文链接:http://blog.csdn.net/fuyajun01/article/details/9246231/

http://blog.csdn.net/caoshangpa/article/details/51103402