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