/**************************************************************************** ** ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include class tst_QOpenGLWidget : public QObject { Q_OBJECT private slots: void create(); void clearAndGrab(); void clearAndResizeAndGrab(); void createNonTopLevel(); void painter(); void reparentToAlreadyCreated(); void reparentToNotYetCreated(); }; void tst_QOpenGLWidget::create() { QScopedPointer w(new QOpenGLWidget); QVERIFY(!w->isValid()); QSignalSpy frameSwappedSpy(w.data(), SIGNAL(frameSwapped())); w->show(); QTest::qWaitForWindowExposed(w.data()); QVERIFY(frameSwappedSpy.count() > 0); QVERIFY(w->isValid()); QVERIFY(w->context()); QVERIFY(w->context()->format() == w->format()); QVERIFY(w->defaultFramebufferObject() != 0); } class ClearWidget : public QOpenGLWidget, protected QOpenGLFunctions { public: ClearWidget(QWidget *parent, int expectedWidth, int expectedHeight) : QOpenGLWidget(parent), m_initCalled(false), m_paintCalled(false), m_resizeCalled(false), m_resizeOk(false), m_w(expectedWidth), m_h(expectedHeight) { } void initializeGL() Q_DECL_OVERRIDE { m_initCalled = true; initializeOpenGLFunctions(); } void paintGL() Q_DECL_OVERRIDE { m_paintCalled = true; glClearColor(1.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); } void resizeGL(int w, int h) Q_DECL_OVERRIDE { m_resizeCalled = true; m_resizeOk = w == m_w && h == m_h; } bool m_initCalled; bool m_paintCalled; bool m_resizeCalled; bool m_resizeOk; int m_w; int m_h; }; void tst_QOpenGLWidget::clearAndGrab() { QScopedPointer w(new ClearWidget(0, 800, 600)); w->resize(800, 600); w->show(); QTest::qWaitForWindowExposed(w.data()); QVERIFY(w->m_initCalled); QVERIFY(w->m_resizeCalled); QVERIFY(w->m_resizeOk); QVERIFY(w->m_paintCalled); QImage image = w->grabFramebuffer(); QVERIFY(!image.isNull()); QCOMPARE(image.width(), w->width()); QCOMPARE(image.height(), w->height()); QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0)); } void tst_QOpenGLWidget::clearAndResizeAndGrab() { QScopedPointer w(new ClearWidget(0, 640, 480)); w->resize(640, 480); w->show(); QTest::qWaitForWindowExposed(w.data()); QImage image = w->grabFramebuffer(); QVERIFY(!image.isNull()); QCOMPARE(image.width(), w->width()); QCOMPARE(image.height(), w->height()); w->resize(800, 600); image = w->grabFramebuffer(); QVERIFY(!image.isNull()); QCOMPARE(image.width(), 800); QCOMPARE(image.height(), 600); QCOMPARE(image.width(), w->width()); QCOMPARE(image.height(), w->height()); QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0)); } void tst_QOpenGLWidget::createNonTopLevel() { QWidget w; ClearWidget *glw = new ClearWidget(&w, 600, 700); QSignalSpy frameSwappedSpy(glw, SIGNAL(frameSwapped())); w.resize(400, 400); w.show(); QTest::qWaitForWindowExposed(&w); QVERIFY(frameSwappedSpy.count() > 0); QVERIFY(glw->m_resizeCalled); glw->m_resizeCalled = false; QVERIFY(!glw->m_resizeOk); glw->resize(600, 700); QVERIFY(glw->m_initCalled); QVERIFY(glw->m_resizeCalled); QVERIFY(glw->m_resizeOk); QVERIFY(glw->m_paintCalled); QImage image = glw->grabFramebuffer(); QVERIFY(!image.isNull()); QCOMPARE(image.width(), glw->width()); QCOMPARE(image.height(), glw->height()); QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0)); glw->doneCurrent(); QVERIFY(!QOpenGLContext::currentContext()); glw->makeCurrent(); QVERIFY(QOpenGLContext::currentContext() == glw->context() && glw->context()); } class PainterWidget : public QOpenGLWidget, protected QOpenGLFunctions { public: PainterWidget(QWidget *parent) : QOpenGLWidget(parent), m_clear(false) { } void initializeGL() Q_DECL_OVERRIDE { initializeOpenGLFunctions(); } void paintGL() Q_DECL_OVERRIDE { QPainter p(this); QCOMPARE(p.device()->width(), width()); QCOMPARE(p.device()->height(), height()); p.fillRect(QRect(QPoint(0, 0), QSize(width(), height())), Qt::blue); if (m_clear) { p.beginNativePainting(); glClearColor(0.0f, 1.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); p.endNativePainting(); } } bool m_clear; }; void tst_QOpenGLWidget::painter() { QWidget w; PainterWidget *glw = new PainterWidget(&w); w.resize(640, 480); glw->resize(320, 200); w.show(); QTest::qWaitForWindowExposed(&w); QImage image = glw->grabFramebuffer(); QCOMPARE(image.width(), glw->width()); QCOMPARE(image.height(), glw->height()); QVERIFY(image.pixel(20, 10) == qRgb(0, 0, 255)); glw->m_clear = true; image = glw->grabFramebuffer(); QVERIFY(image.pixel(20, 10) == qRgb(0, 255, 0)); } void tst_QOpenGLWidget::reparentToAlreadyCreated() { QWidget w1; PainterWidget *glw = new PainterWidget(&w1); w1.resize(640, 480); glw->resize(320, 200); w1.show(); QTest::qWaitForWindowExposed(&w1); QWidget w2; w2.show(); QTest::qWaitForWindowExposed(&w2); glw->setParent(&w2); glw->show(); QImage image = glw->grabFramebuffer(); QCOMPARE(image.width(), 320); QCOMPARE(image.height(), 200); QVERIFY(image.pixel(20, 10) == qRgb(0, 0, 255)); } void tst_QOpenGLWidget::reparentToNotYetCreated() { QWidget w1; PainterWidget *glw = new PainterWidget(&w1); w1.resize(640, 480); glw->resize(320, 200); w1.show(); QTest::qWaitForWindowExposed(&w1); QWidget w2; glw->setParent(&w2); w2.show(); QTest::qWaitForWindowExposed(&w2); QImage image = glw->grabFramebuffer(); QCOMPARE(image.width(), 320); QCOMPARE(image.height(), 200); QVERIFY(image.pixel(20, 10) == qRgb(0, 0, 255)); } QTEST_MAIN(tst_QOpenGLWidget) #include "tst_qopenglwidget.moc"