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*系列的类。
原文链接:http://blog.csdn.net/fuyajun01/article/details/9246231/
http://blog.csdn.net/caoshangpa/article/details/51103402
Qt5下OpenGL程序的新写法的更多相关文章
- MAC 下用 Common Lisp 调试 OpenGL 程序
MAC 下用 Common Lisp 调试 OpenGL 程序 环境搭建 运行环境: OSX 10.11.3 EI Capitan Common Lisp: SBCL 使用 SBCL, 首先要安装这几 ...
- 【VS开发】【OpenGL开发】OpenGL---Windows下配置与第一个OpenGL程序
面记录一下Windows下配置OpenGL与我的第一个OpenGL程序. 第一步:选择一个编译环境 现在Windows系统的主流编译环境有Visual Studio,Broland C++ Bu ...
- 第一个openGL程序
一.工具的安装 因为要写C++程序,为了便捷,这里我安装的Visual Studio: 免费使用90天!安装好了之后,我们要为我们的开发安装相应的工具集: 因为我是要在windows上跑的,所以选择如 ...
- 【OpenGL】详解第一个OpenGL程序
写在前面 OpenGL能做的事情太多了!很多程序也看起来很复杂.很多人感觉OpenGL晦涩难懂,原因大多是被OpenGL里面各种语句搞得头大,一会gen一下,一会bind一下,一会又active一下. ...
- MFC下OpenGL入门(可以用)
MFC下OpenGL入门 源文件 1, 建一工程文件,我这里命名为first,现在first工程里面我们没有添加任何东西,所有的东西都是MFC自动帮我们创建的. 2, 添加链接库.这一步很关键.打开菜 ...
- Windows7+VS2012下OpenGL 4的环境配置
系统环境 Windows 7 Ultimate x64,Visual Studio Ultimate 2012 Update 4,和一块支持OpenGL 4.x的显卡. 准备工作 首先用GPU Cap ...
- [BS-02] iOS数组、字典、NSNumber 新写法—— @[]、@{}
IOS数组.字典.NSNumber 新写法—— @[].@{} //标准写法 NSNumber * number = [NSNumber numberWithInt:]; NSArray * ar ...
- 【M32】在未来时态下发展程序
1.在未来时态下发展程序,就是接受“事情总会变化”的事实,并准备应对之策. 2.记住,程序的维护者通常不是最初的开发者,因此,设计和实现的时候,应该考虑别人更好地理解,修改自己的程序. 3.重要的一点 ...
- Linux下C程序的编辑,编译和运行以及调试
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...
随机推荐
- WINDOWS 同步(Interlocked,InterlockedExchangeAdd,Slim读/写锁,WaitForSingleObject,CreateWaitableTimer等等)
NOTE0 在以下两种基本情况下,线程之间需要相互通信: 需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性: 一个线程需要通知其它线程某项任务已经完成 1.原子访问:Interlocked ...
- WPF 针对数据源某个属性进行排序
原文:WPF 针对数据源某个属性进行排序 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/wanlong360599336/article/detai ...
- java中<T> T和T的区别?
如果你希望 getMax 方法的返回值类型为 T,就要这样去定义getMax方法: public T getMax() 如果你希望 getMax 方法返回值的类型由调用者决定,那么就这么去定义 get ...
- Android菜鸟的成长笔记(24)——Android中的振动器
在某些时候,程序需要启动系统振动器,比如手机静音时使用振动提示用户:再比如玩游戏时,当系统碰撞.爆炸时使用振动带给用户更逼真的体验等.总之,振动是除视频.声音之外的另一种"多媒体" ...
- tomcat启动时自动加载一个类 MyServletContextListener
目的: 我们知道在tomcat启动后,需要页面请求进行驱动来执行操作接而响应.我们希望在tomcat启动的时候能够自动运行一个后台线程,以处理我们需要的一些操作.因此需要tomcat启动时就自动加载一 ...
- WPF 获得触摸精度和触摸点
原文:WPF 获得触摸精度和触摸点 本文主要告诉大家如何获得所有的触摸设备的触摸精度和触摸点数. 需要通过反射的方法才可以拿到触摸的精度. 使用 Tablet.TabletDevices 可以获得所有 ...
- 如何使用egit将本地代码提交到托管平台
本文将讲述如何使用eclipse中的egit插件,将代码提交到git托管平台. Eclipse版本:4.7.0 自带egit插件 云端托管平台:华为软件开发云 1.本地git工具安装&环境配置 ...
- WPF 判断调用方法堆栈
原文:WPF 判断调用方法堆栈 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee.io 访问博客 ...
- Qt5.9 官方发布的新版本亮点的确不胜枚举(而且修复2000+ bugs)
作者:Summer Fang链接:https://www.zhihu.com/question/60486611/answer/177584284来源:知乎著作权归作者所有.商业转载请联系作者获得授权 ...
- C#中的SMTP配置Outlook.Com SMTP主机
如果你想以编程方式使用 Outlook.com或Gmail帐户作为 SMTP主机 发送电子邮件,也有为了得到这一切工作的几件事情要注意. 使用基本的System.Net.Mail库, ...