summaryrefslogtreecommitdiffstats
path: root/tests/auto/render/scene2d
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/render/scene2d')
-rw-r--r--tests/auto/render/scene2d/scene2d.pro12
-rw-r--r--tests/auto/render/scene2d/tst_scene2d.cpp450
2 files changed, 462 insertions, 0 deletions
diff --git a/tests/auto/render/scene2d/scene2d.pro b/tests/auto/render/scene2d/scene2d.pro
new file mode 100644
index 000000000..aacdea3e4
--- /dev/null
+++ b/tests/auto/render/scene2d/scene2d.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_scene2d
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib 3dquickscene2d 3dquickscene2d-private
+
+CONFIG += testcase
+
+SOURCES += tst_scene2d.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/scene2d/tst_scene2d.cpp b/tests/auto/render/scene2d/tst_scene2d.cpp
new file mode 100644
index 000000000..a78ed0ab1
--- /dev/null
+++ b/tests/auto/render/scene2d/tst_scene2d.cpp
@@ -0,0 +1,450 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <Qt3DQuickScene2D/qscene2d.h>
+#include <private/qscene2d_p.h>
+#include <private/scene2d_p.h>
+#include <Qt3DRender/qgeometryrenderer.h>
+#include <Qt3DRender/qbuffer.h>
+#include <private/trianglesvisitor_p.h>
+#include <private/nodemanagers_p.h>
+#include <private/managers_p.h>
+#include <private/geometryrenderer_p.h>
+#include <private/geometryrenderermanager_p.h>
+#include <private/buffermanager_p.h>
+#include <Qt3DRender/qpicktriangleevent.h>
+#include <private/qpickevent_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <qbackendnodetester.h>
+#include "testrenderer.h"
+
+using namespace Qt3DRender::Quick;
+using namespace Qt3DRender::Render;
+using namespace Qt3DRender::Render::Quick;
+
+bool qFuzzyComparePointF(const QPointF& a, const QPointF& b) {
+ return qFuzzyCompare(a.x(), b.x()) && qFuzzyCompare(a.y(), b.y());
+}
+
+class TestWindow : public QQuickWindow
+{
+ Q_OBJECT
+public:
+ TestWindow()
+ : QQuickWindow()
+ {
+
+ }
+
+ bool event(QEvent *e) Q_DECL_OVERRIDE
+ {
+ if (e->type() >= QEvent::MouseButtonPress &&
+ e->type() <= QEvent::MouseMove) {
+ QMouseEvent *me = static_cast<QMouseEvent *>(e);
+ m_eventTypes.push_back(e->type());
+ m_mousePoints.push_back(me->localPos());
+ }
+ return QQuickWindow::event(e);
+ }
+
+ bool verifyEventPos(uint index, QEvent::Type type, const QPointF& pos)
+ {
+ if (index >= unsigned(m_eventTypes.size()) ||
+ m_eventTypes[index] != type ||
+ !qFuzzyComparePointF(pos, m_mousePoints[index]))
+ return false;
+ return true;
+ }
+
+ void clear()
+ {
+ m_eventTypes.clear();
+ m_mousePoints.clear();
+ }
+
+private:
+ QVector<QEvent::Type> m_eventTypes;
+ QVector<QPointF> m_mousePoints;
+};
+
+class tst_Scene2D : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void checkInitialState()
+ {
+ // GIVEN
+ Scene2D backendScene2d;
+
+ // THEN
+ QCOMPARE(backendScene2d.isEnabled(), false);
+ QVERIFY(backendScene2d.peerId().isNull());
+ QCOMPARE(backendScene2d.m_context, nullptr);
+ QCOMPARE(backendScene2d.m_shareContext, nullptr);
+ QCOMPARE(backendScene2d.m_renderThread, nullptr);
+ QCOMPARE(backendScene2d.m_outputId, Qt3DCore::QNodeId());
+ QCOMPARE(backendScene2d.m_initialized, false);
+ QCOMPARE(backendScene2d.m_renderInitialized, false);
+ QCOMPARE(backendScene2d.m_renderPolicy, QScene2D::Continuous);
+ QCOMPARE(backendScene2d.m_mouseEnabled, true);
+ backendScene2d.cleanup();
+ }
+
+ void checkInitializeFromPeer()
+ {
+ // GIVEN
+ Qt3DRender::Quick::QScene2D frontend;
+ TestRenderer renderer;
+
+ {
+ // WHEN
+ QScopedPointer<Scene2D> backendScene2d(new Scene2D());
+ backendScene2d->setRenderer(&renderer);
+ simulateInitialization(&frontend, backendScene2d.data());
+
+ // THEN
+ QCOMPARE(backendScene2d->isEnabled(), true);
+ QCOMPARE(backendScene2d->peerId(), frontend.id());
+ QCOMPARE(backendScene2d->m_outputId, Qt3DCore::QNodeId());
+ QVERIFY(backendScene2d->m_sharedObject.data() != nullptr);
+ QCOMPARE(backendScene2d->m_renderPolicy, QScene2D::Continuous);
+ QCOMPARE(backendScene2d->m_mouseEnabled, true);
+ backendScene2d->cleanup();
+ }
+ {
+ // WHEN
+ QScopedPointer<Scene2D> backendScene2d(new Scene2D());
+ frontend.setEnabled(false);
+ backendScene2d->setRenderer(&renderer);
+ simulateInitialization(&frontend, backendScene2d.data());
+
+ // THEN
+ QCOMPARE(backendScene2d->peerId(), frontend.id());
+ QCOMPARE(backendScene2d->isEnabled(), false);
+ backendScene2d->cleanup();
+ }
+ }
+
+ void checkSceneChangeEvents()
+ {
+ // GIVEN
+ QScopedPointer<Scene2D> backendScene2d(new Scene2D());
+ TestRenderer renderer;
+ QScopedPointer<Qt3DRender::QRenderTargetOutput> output(new Qt3DRender::QRenderTargetOutput());
+ backendScene2d->setRenderer(&renderer);
+
+ {
+ // WHEN
+ const bool newValue = false;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("enabled");
+ change->setValue(newValue);
+ backendScene2d->sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendScene2d->isEnabled(), newValue);
+ }
+ {
+ // WHEN
+ const Qt3DCore::QNodeId newValue = output.data()->id();
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("output");
+ change->setValue(QVariant::fromValue(newValue));
+ backendScene2d->sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendScene2d->m_outputId, newValue);
+ }
+ {
+ // WHEN
+ const QScene2D::RenderPolicy newValue = QScene2D::SingleShot;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("renderPolicy");
+ change->setValue(QVariant::fromValue(newValue));
+ backendScene2d->sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendScene2d->m_renderPolicy, newValue);
+ }
+ {
+ // WHEN
+ const bool newValue = false;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("mouseEnabled");
+ change->setValue(newValue);
+ backendScene2d->sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendScene2d->isEnabled(), newValue);
+ }
+
+ backendScene2d->cleanup();
+ }
+
+
+ void testCoordinateCalculation()
+ {
+ // GIVEN
+ QScopedPointer<TestWindow> testWindow(new TestWindow());
+ Scene2DSharedObjectPtr sharedObject(new Scene2DSharedObject(nullptr));
+ QScopedPointer<Scene2D> scene2d(new Scene2D());
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry();
+ Qt3DRender::QGeometryRenderer *geometryRenderer = new Qt3DRender::QGeometryRenderer();
+ Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute();
+ Qt3DRender::QAttribute *texcoordAttribute = new Qt3DRender::QAttribute();
+ Qt3DRender::QBuffer *dataBuffer =new Qt3DRender::QBuffer();
+ QScopedPointer<Qt3DCore::QEntity> entity(new Qt3DCore::QEntity());
+ entity->addComponent(geometryRenderer);
+ TestRenderer renderer;
+ renderer.setNodeManagers(nodeManagers.data());
+ scene2d->setRenderer(&renderer);
+ scene2d->setEnabled(true);
+ sharedObject->m_quickWindow = testWindow.data();
+ scene2d->setSharedObject(sharedObject);
+ testWindow->setGeometry(0,0,1024,1024);
+
+ QByteArray data;
+ data.resize(sizeof(float) * 5 * 6);
+ float *dataPtr = reinterpret_cast<float *>(data.data());
+ int i = 0;
+ dataPtr[i++] = -1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 0;
+ dataPtr[i++] = 0;
+
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 0;
+
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = -1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 1.0f;
+
+ dataPtr[i++] = -1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 0;
+ dataPtr[i++] = 0;
+
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = -1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 1.0f;
+
+ dataPtr[i++] = -1.0f;
+ dataPtr[i++] = -1.0f;
+ dataPtr[i++] = 1.0f;
+ dataPtr[i++] = 0.0f;
+ dataPtr[i++] = 1.0f;
+
+ dataBuffer->setData(data);
+ Buffer *backendBuffer = nodeManagers->bufferManager()->getOrCreateResource(dataBuffer->id());
+ backendBuffer->setRenderer(&renderer);
+ backendBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(dataBuffer, backendBuffer);
+
+ positionAttribute->setBuffer(dataBuffer);
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setCount(6);
+ positionAttribute->setByteStride(sizeof(float) * 5);
+ positionAttribute->setByteOffset(0);
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+ geometry->addAttribute(positionAttribute);
+
+ texcoordAttribute->setBuffer(dataBuffer);
+ texcoordAttribute->setName(Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName());
+ texcoordAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ texcoordAttribute->setVertexSize(2);
+ texcoordAttribute->setCount(6);
+ texcoordAttribute->setByteStride(sizeof(float) * 5);
+ texcoordAttribute->setByteOffset(sizeof(float) * 3);
+ texcoordAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+ geometry->addAttribute(texcoordAttribute);
+
+ geometryRenderer->setGeometry(geometry);
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
+
+ Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(
+ positionAttribute->id());
+ backendAttribute->setRenderer(&renderer);
+ simulateInitialization(positionAttribute, backendAttribute);
+
+ Attribute *backendTexcoordAttribute = nodeManagers->attributeManager()
+ ->getOrCreateResource(texcoordAttribute->id());
+ backendTexcoordAttribute->setRenderer(&renderer);
+ simulateInitialization(texcoordAttribute, backendTexcoordAttribute);
+
+ Geometry *backendGeometry = nodeManagers->geometryManager()
+ ->getOrCreateResource(geometry->id());
+ backendGeometry->setRenderer(&renderer);
+ simulateInitialization(geometry, backendGeometry);
+
+ GeometryRenderer *backendRenderer = nodeManagers->geometryRendererManager()
+ ->getOrCreateResource(geometryRenderer->id());
+ backendRenderer->setRenderer(&renderer);
+ backendRenderer->setManager(nodeManagers->geometryRendererManager());
+ simulateInitialization(geometryRenderer, backendRenderer);
+
+ Entity *backendEntity = nodeManagers->renderNodesManager()->getOrCreateResource(entity->id());
+ backendEntity->setRenderer(&renderer);
+ backendEntity->setNodeManagers(nodeManagers.data());
+ simulateInitialization(entity.data(), backendEntity);
+
+#define PICK_TRIANGLE(tri, v0, v1, v2, uvw) \
+ new Qt3DRender::QPickTriangleEvent(QPointF(), QVector3D(), QVector3D(), 0.0f, \
+ tri, v0, v1, v2, Qt3DRender::QPickEvent::LeftButton, Qt::LeftButton, 0, uvw)
+
+ {
+ // WHEN
+ QVector3D uvw(1.0, 0.0f, 0.0f);
+ Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw));
+ Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
+ scene2d->handlePickEvent(QEvent::MouseButtonPress, ev);
+
+ QCoreApplication::processEvents();
+
+ // THEN
+ QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(0,1024)));
+ testWindow->clear();
+ }
+
+ {
+ // WHEN
+ QVector3D uvw(0.0, 1.0f, 0.0f);
+ Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw));
+ Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
+ scene2d->handlePickEvent(QEvent::MouseButtonPress, ev);
+
+ QCoreApplication::processEvents();
+
+ // THEN
+ QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(1024,1024)));
+ testWindow->clear();
+ }
+
+ {
+ // WHEN
+ QVector3D uvw(0.0, 0.0f, 1.0f);
+ Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw));
+ Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
+ scene2d->handlePickEvent(QEvent::MouseButtonPress, ev);
+
+ QCoreApplication::processEvents();
+
+ // THEN
+ QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(1024,0)));
+ testWindow->clear();
+ }
+
+ {
+ // WHEN
+ QVector3D uvw(1.0, 0.0f, 0.0f);
+ Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw));
+ Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
+ scene2d->handlePickEvent(QEvent::MouseButtonPress, ev);
+
+ QCoreApplication::processEvents();
+
+ // THEN
+ QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(0,1024)));
+ testWindow->clear();
+ }
+
+ {
+ // WHEN
+ QVector3D uvw(0.0, 1.0f, 0.0f);
+ Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw));
+ Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
+ scene2d->handlePickEvent(QEvent::MouseButtonPress, ev);
+
+ QCoreApplication::processEvents();
+
+ // THEN
+ QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(1024,0)));
+ testWindow->clear();
+ }
+
+ {
+ // WHEN
+ QVector3D uvw(0.0, 0.0f, 1.0f);
+ Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw));
+ Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
+ scene2d->handlePickEvent(QEvent::MouseButtonPress, ev);
+
+ QCoreApplication::processEvents();
+
+ // THEN
+ QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(0,0)));
+ testWindow->clear();
+ }
+
+ {
+ // WHEN
+ QVector3D uvw(0.5f, 0.25f, 0.25f);
+ Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw));
+ Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
+ scene2d->handlePickEvent(QEvent::MouseButtonPress, ev);
+
+ QCoreApplication::processEvents();
+
+ // THEN
+ QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(512.0f, 768.0f)));
+ testWindow->clear();
+ }
+
+ {
+ // WHEN
+ QVector3D uvw(0.875f, 0.09375f, 0.03125f);
+ Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw));
+ Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
+ scene2d->handlePickEvent(QEvent::MouseButtonPress, ev);
+
+ QCoreApplication::processEvents();
+
+ // THEN
+ QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(96.0f, 896.0f)));
+ testWindow->clear();
+ }
+ }
+};
+
+QTEST_MAIN(tst_Scene2D)
+
+#include "tst_scene2d.moc"