summaryrefslogtreecommitdiffstats
path: root/tests/auto/render
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/render')
-rw-r--r--tests/auto/render/armature/armature.pro12
-rw-r--r--tests/auto/render/armature/tst_armature.cpp120
-rw-r--r--tests/auto/render/blitframebuffer/blitframebuffer.pro12
-rw-r--r--tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp196
-rw-r--r--tests/auto/render/buffer/tst_buffer.cpp65
-rw-r--r--tests/auto/render/commons/testrenderer.h1
-rw-r--r--tests/auto/render/ddstextures/data/16x16-etc1.pkmbin0 -> 144 bytes
-rw-r--r--tests/auto/render/ddstextures/data/16x16-etc2.pkmbin0 -> 144 bytes
-rw-r--r--tests/auto/render/ddstextures/ddstextures.pro4
-rw-r--r--tests/auto/render/ddstextures/tst_ddstextures.cpp2
-rw-r--r--tests/auto/render/entity/tst_entity.cpp20
-rw-r--r--tests/auto/render/filtercompatibletechniquejob/BLACKLIST7
-rw-r--r--tests/auto/render/geometry/tst_geometry.cpp29
-rw-r--r--tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp88
-rw-r--r--tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp86
-rw-r--r--tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp125
-rw-r--r--tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp125
-rw-r--r--tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp138
-rw-r--r--tests/auto/render/joint/joint.pro13
-rw-r--r--tests/auto/render/joint/tst_joint.cpp242
-rw-r--r--tests/auto/render/layerfiltering/tst_layerfiltering.cpp502
-rw-r--r--tests/auto/render/loadscenejob/tst_loadscenejob.cpp31
-rw-r--r--tests/auto/render/meshfunctors/tst_meshfunctors.cpp32
-rw-r--r--tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp1
-rw-r--r--tests/auto/render/proximityfilter/proximityfilter.pro12
-rw-r--r--tests/auto/render/proximityfilter/tst_proximityfilter.cpp133
-rw-r--r--tests/auto/render/proximityfiltering/proximityfiltering.pro13
-rw-r--r--tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp287
-rw-r--r--tests/auto/render/qattribute/tst_qattribute.cpp6
-rw-r--r--tests/auto/render/qblitframebuffer/qblitframebuffer.pro11
-rw-r--r--tests/auto/render/qblitframebuffer/tst_qblitframebuffer.cpp338
-rw-r--r--tests/auto/render/qbuffer/tst_qbuffer.cpp1
-rw-r--r--tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp16
-rw-r--r--tests/auto/render/qgraphicsapifilter/tst_qgraphicsapifilter.cpp7
-rw-r--r--tests/auto/render/qmesh/tst_qmesh.cpp34
-rw-r--r--tests/auto/render/qproximityfilter/qproximityfilter.pro12
-rw-r--r--tests/auto/render/qproximityfilter/tst_qproximityfilter.cpp270
-rw-r--r--tests/auto/render/qrendercapture/tst_qrendercapture.cpp7
-rw-r--r--tests/auto/render/qrendersettings/tst_qrendersettings.cpp37
-rw-r--r--tests/auto/render/qshaderprogrambuilder/qshaderprogrambuilder.pro12
-rw-r--r--tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp601
-rw-r--r--tests/auto/render/render.pro45
-rw-r--r--tests/auto/render/rendercapture/tst_rendercapture.cpp14
-rw-r--r--tests/auto/render/renderer/renderer.pro9
-rw-r--r--tests/auto/render/renderer/tst_renderer.cpp234
-rw-r--r--tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp350
-rw-r--r--tests/auto/render/sceneloader/tst_sceneloader.cpp4
-rw-r--r--tests/auto/render/segmentvisitor/segmentvisitor.pro12
-rw-r--r--tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp814
-rw-r--r--tests/auto/render/sendrendercapturejob/tst_sendrendercapturejob.cpp6
-rw-r--r--tests/auto/render/shader/shader.pro1
-rw-r--r--tests/auto/render/shader/tst_shader.cpp188
-rw-r--r--tests/auto/render/shaderbuilder/input.json90
-rw-r--r--tests/auto/render/shaderbuilder/lightmodel.es2.inc6
-rw-r--r--tests/auto/render/shaderbuilder/lightmodel.gl3.inc6
-rw-r--r--tests/auto/render/shaderbuilder/output.es236
-rw-r--r--tests/auto/render/shaderbuilder/output.gl337
-rw-r--r--tests/auto/render/shaderbuilder/prototypes.json237
-rw-r--r--tests/auto/render/shaderbuilder/shaderbuilder.pro13
-rw-r--r--tests/auto/render/shaderbuilder/shaderbuilder.qrc10
-rw-r--r--tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp548
-rw-r--r--tests/auto/render/skeleton/skeleton.pro13
-rw-r--r--tests/auto/render/skeleton/tst_skeleton.cpp405
-rw-r--r--tests/auto/render/texture/tst_texture.cpp10
-rw-r--r--tests/auto/render/transform/tst_transform.cpp8
-rw-r--r--tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp50
-rw-r--r--tests/auto/render/uniform/tst_uniform.cpp65
67 files changed, 6586 insertions, 273 deletions
diff --git a/tests/auto/render/armature/armature.pro b/tests/auto/render/armature/armature.pro
new file mode 100644
index 000000000..fc8d69eaa
--- /dev/null
+++ b/tests/auto/render/armature/armature.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_armature
+
+QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_armature.cpp
+
+include(../../core/common/common.pri)
diff --git a/tests/auto/render/armature/tst_armature.cpp b/tests/auto/render/armature/tst_armature.cpp
new file mode 100644
index 000000000..2c481db7a
--- /dev/null
+++ b/tests/auto/render/armature/tst_armature.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** 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 <Qt3DRender/private/armature_p.h>
+#include <Qt3DCore/qarmature.h>
+#include <Qt3DCore/qskeleton.h>
+#include <Qt3DCore/private/qnode_p.h>
+#include <Qt3DCore/private/qscene_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qbackendnode_p.h>
+#include <qbackendnodetester.h>
+#include <testpostmanarbiter.h>
+
+using namespace Qt3DCore;
+using namespace Qt3DRender;
+using namespace Qt3DRender::Render;
+
+class tst_Armature: public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void checkPeerPropertyMirroring()
+ {
+ // GIVEN
+ Armature backendArmature;
+ QArmature armature;
+ auto skeleton = new QSkeleton;
+
+ armature.setSkeleton(skeleton);
+
+ // WHEN
+ simulateInitialization(&armature, &backendArmature);
+
+ // THEN
+ QCOMPARE(backendArmature.peerId(), armature.id());
+ QCOMPARE(backendArmature.isEnabled(), armature.isEnabled());
+ QCOMPARE(backendArmature.skeletonId(), skeleton->id());
+ }
+
+ void checkInitialAndCleanedUpState()
+ {
+ // GIVEN
+ Armature backendArmature;
+
+ // THEN
+ QVERIFY(backendArmature.peerId().isNull());
+ QCOMPARE(backendArmature.isEnabled(), false);
+ QCOMPARE(backendArmature.skeletonId(), Qt3DCore::QNodeId());
+
+ // GIVEN
+ QArmature armature;
+ auto skeleton = new QSkeleton();
+ armature.setSkeleton(skeleton);
+
+ // WHEN
+ simulateInitialization(&armature, &backendArmature);
+ backendArmature.cleanup();
+
+ // THEN
+ QCOMPARE(backendArmature.skeletonId(), Qt3DCore::QNodeId());
+ QCOMPARE(backendArmature.isEnabled(), false);
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Armature backendArmature;
+ Qt3DCore::QPropertyUpdatedChangePtr updateChange;
+
+ // WHEN
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("enabled");
+ updateChange->setValue(true);
+ backendArmature.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendArmature.isEnabled(), true);
+
+ // WHEN
+ auto newSkeleton = new QSkeleton();
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("skeleton");
+ updateChange->setValue(QVariant::fromValue(newSkeleton->id()));
+ backendArmature.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendArmature.skeletonId(), newSkeleton->id());
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_Armature)
+
+#include "tst_armature.moc"
diff --git a/tests/auto/render/blitframebuffer/blitframebuffer.pro b/tests/auto/render/blitframebuffer/blitframebuffer.pro
new file mode 100644
index 000000000..39531ae9a
--- /dev/null
+++ b/tests/auto/render/blitframebuffer/blitframebuffer.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_blitframebuffer
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_blitframebuffer.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp b/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp
new file mode 100644
index 000000000..6c70b0e95
--- /dev/null
+++ b/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** 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 <Qt3DRender/qblitframebuffer.h>
+#include <Qt3DRender/private/qblitframebuffer_p.h>
+#include <Qt3DRender/private/blitframebuffer_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include "qbackendnodetester.h"
+#include "testrenderer.h"
+
+class tst_BlitFramebuffer : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void checkInitialState()
+ {
+ // GIVEN
+ Qt3DRender::Render::BlitFramebuffer backendBlitFramebuffer;
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.nodeType(), Qt3DRender::Render::FrameGraphNode::BlitFramebuffer);
+ QCOMPARE(backendBlitFramebuffer.isEnabled(), false);
+ QVERIFY(backendBlitFramebuffer.peerId().isNull());
+ QVERIFY(backendBlitFramebuffer.sourceRenderTargetId().isNull());
+ QVERIFY(backendBlitFramebuffer.destinationRenderTargetId().isNull());
+ QCOMPARE(backendBlitFramebuffer.sourceRect(), QRect());
+ QCOMPARE(backendBlitFramebuffer.destinationRect(), QRect());
+ QCOMPARE(backendBlitFramebuffer.sourceAttachmentPoint(), Qt3DRender::QRenderTargetOutput::Color0);
+ QCOMPARE(backendBlitFramebuffer.destinationAttachmentPoint(), Qt3DRender::QRenderTargetOutput::Color0);
+ QCOMPARE(backendBlitFramebuffer.interpolationMethod(), Qt3DRender::QBlitFramebuffer::Linear);
+ }
+
+ void checkInitializeFromPeer()
+ {
+ // GIVEN
+ Qt3DRender::QRenderTarget sourceTarget;
+ Qt3DRender::QRenderTarget destinationTarget;
+ Qt3DRender::QBlitFramebuffer blitFramebuffer;
+ blitFramebuffer.setSource(&sourceTarget);
+ blitFramebuffer.setDestination(&destinationTarget);
+ blitFramebuffer.setSourceRect(QRect(0,0,1,1));
+ blitFramebuffer.setDestinationRect(QRect(0,0,1,1));
+ blitFramebuffer.setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1);
+ blitFramebuffer.setDestinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1);
+ blitFramebuffer.setInterpolationMethod(Qt3DRender::QBlitFramebuffer::Nearest);
+
+ {
+ // WHEN
+ Qt3DRender::Render::BlitFramebuffer backendBlitFramebuffer;
+ simulateInitialization(&blitFramebuffer, &backendBlitFramebuffer);
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.isEnabled(), true);
+ QCOMPARE(backendBlitFramebuffer.peerId(), blitFramebuffer.id());
+ QCOMPARE(backendBlitFramebuffer.sourceRenderTargetId(), sourceTarget.id());
+ QCOMPARE(backendBlitFramebuffer.destinationRenderTargetId(), destinationTarget.id());
+ QCOMPARE(backendBlitFramebuffer.sourceRect(), QRect(0,0,1,1));
+ QCOMPARE(backendBlitFramebuffer.destinationRect(), QRect(0,0,1,1));
+ QCOMPARE(backendBlitFramebuffer.sourceAttachmentPoint(), Qt3DRender::QRenderTargetOutput::Color1);
+ QCOMPARE(backendBlitFramebuffer.destinationAttachmentPoint(), Qt3DRender::QRenderTargetOutput::Color1);
+ QCOMPARE(backendBlitFramebuffer.interpolationMethod(), Qt3DRender::QBlitFramebuffer::Nearest);
+ }
+ {
+ // WHEN
+ Qt3DRender::Render::BlitFramebuffer backendBlitFramebuffer;
+ blitFramebuffer.setEnabled(false);
+ simulateInitialization(&blitFramebuffer, &backendBlitFramebuffer);
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.peerId(), blitFramebuffer.id());
+ QCOMPARE(backendBlitFramebuffer.isEnabled(), false);
+ }
+ }
+
+ void checkSceneChangeEvents()
+ {
+ // GIVEN
+ Qt3DRender::Render::BlitFramebuffer backendBlitFramebuffer;
+ TestRenderer renderer;
+ backendBlitFramebuffer.setRenderer(&renderer);
+
+ {
+ // WHEN
+ const bool newValue = false;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("enabled");
+ change->setValue(newValue);
+ backendBlitFramebuffer.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.isEnabled(), newValue);
+ }
+ {
+ // WHEN
+ const Qt3DRender::QRenderTarget sourceRenderTarget;
+ const Qt3DCore::QNodeId newValue = sourceRenderTarget.id();
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("sourceRenderTarget");
+ change->setValue(QVariant::fromValue(newValue));
+ backendBlitFramebuffer.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.sourceRenderTargetId(), newValue);
+ }
+ {
+ // WHEN
+ const Qt3DRender::QRenderTarget destinationRenderTarget;
+ const Qt3DCore::QNodeId newValue = destinationRenderTarget.id();
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("destinationRenderTarget");
+ change->setValue(QVariant::fromValue(newValue));
+ backendBlitFramebuffer.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.destinationRenderTargetId(), newValue);
+ }
+ {
+ // WHEN
+ const auto newValue = QRect(0,0,1,1);
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("sourceRect");
+ change->setValue(QVariant::fromValue(newValue));
+ backendBlitFramebuffer.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.sourceRect(), newValue);
+ }
+ {
+ // WHEN
+ const auto newValue = QRect(0,0,1,1);
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("destinationRect");
+ change->setValue(QVariant::fromValue(newValue));
+ backendBlitFramebuffer.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.destinationRect(), newValue);
+ }
+ {
+ // WHEN
+ const auto newValue = Qt3DRender::QRenderTargetOutput::Color1;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("sourceAttachmentPoint");
+ change->setValue(QVariant::fromValue(newValue));
+ backendBlitFramebuffer.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.sourceAttachmentPoint(), newValue);
+ }
+ {
+ // WHEN
+ const auto newValue = Qt3DRender::QRenderTargetOutput::Color1;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("destinationAttachmentPoint");
+ change->setValue(QVariant::fromValue(newValue));
+ backendBlitFramebuffer.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendBlitFramebuffer.destinationAttachmentPoint(), newValue);
+ }
+ }
+
+};
+
+QTEST_MAIN(tst_BlitFramebuffer)
+
+#include "tst_blitframebuffer.moc"
diff --git a/tests/auto/render/buffer/tst_buffer.cpp b/tests/auto/render/buffer/tst_buffer.cpp
index 6fa7960fe..f9a54c8bf 100644
--- a/tests/auto/render/buffer/tst_buffer.cpp
+++ b/tests/auto/render/buffer/tst_buffer.cpp
@@ -73,18 +73,20 @@ private Q_SLOTS:
Qt3DRender::Render::Buffer renderBuffer;
Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
Qt3DRender::Render::BufferManager bufferManager;
+ TestRenderer renderer;
+
buffer.setUsage(Qt3DRender::QBuffer::DynamicCopy);
buffer.setData(QByteArrayLiteral("Corvette"));
buffer.setDataGenerator(Qt3DRender::QBufferDataGeneratorPtr(new TestFunctor(883)));
// WHEN
+ renderBuffer.setRenderer(&renderer);
renderBuffer.setManager(&bufferManager);
simulateInitialization(&buffer, &renderBuffer);
// THEN
QCOMPARE(renderBuffer.peerId(), buffer.id());
QCOMPARE(renderBuffer.isDirty(), true);
- QCOMPARE(renderBuffer.type(), buffer.type());
QCOMPARE(renderBuffer.usage(), buffer.usage());
QCOMPARE(renderBuffer.data(), buffer.data());
QCOMPARE(renderBuffer.dataGenerator(), buffer.dataGenerator());
@@ -102,7 +104,6 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderBuffer.isDirty(), false);
- QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::VertexBuffer);
QCOMPARE(renderBuffer.usage(), Qt3DRender::QBuffer::StaticDraw);
QVERIFY(renderBuffer.data().isEmpty());
QVERIFY(renderBuffer.peerId().isNull());
@@ -110,7 +111,7 @@ private Q_SLOTS:
QVERIFY(renderBuffer.pendingBufferUpdates().empty());
// GIVEN
- Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
+ Qt3DRender::QBuffer buffer;
buffer.setUsage(Qt3DRender::QBuffer::DynamicCopy);
buffer.setData(QByteArrayLiteral("C7"));
buffer.setDataGenerator(Qt3DRender::QBufferDataGeneratorPtr(new TestFunctor(73)));
@@ -129,7 +130,6 @@ private Q_SLOTS:
renderBuffer.sceneChangeEvent(updateChange);
// THEN
- QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::IndexBuffer);
QCOMPARE(renderBuffer.usage(), Qt3DRender::QBuffer::DynamicCopy);
QCOMPARE(renderBuffer.isDirty(), true);
QCOMPARE(renderBuffer.data(), QByteArrayLiteral("C7"));
@@ -141,7 +141,6 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderBuffer.isDirty(), false);
- QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::VertexBuffer);
QCOMPARE(renderBuffer.usage(), Qt3DRender::QBuffer::StaticDraw);
QVERIFY(renderBuffer.data().isEmpty());
QVERIFY(renderBuffer.dataGenerator().isNull());
@@ -156,27 +155,14 @@ private Q_SLOTS:
renderBuffer.setRenderer(&renderer);
// THEN
- QVERIFY(renderBuffer.type() != Qt3DRender::QBuffer::IndexBuffer);
QVERIFY(renderBuffer.data().isEmpty());
QVERIFY(renderBuffer.usage() != Qt3DRender::QBuffer::DynamicRead);
QVERIFY(!renderBuffer.isDirty());
+ QVERIFY(!(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::BuffersDirty));
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
- updateChange->setValue(static_cast<int>(Qt3DRender::QBuffer::IndexBuffer));
- updateChange->setPropertyName("type");
- renderBuffer.sceneChangeEvent(updateChange);
-
- // THEN
- QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::IndexBuffer);
- QVERIFY(renderer.dirtyBits() != 0);
- QVERIFY(renderBuffer.isDirty());
-
- renderBuffer.unsetDirty();
- QVERIFY(!renderBuffer.isDirty());
-
- // WHEN
- updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(static_cast<int>(Qt3DRender::QBuffer::DynamicRead));
updateChange->setPropertyName("usage");
renderBuffer.sceneChangeEvent(updateChange);
@@ -185,6 +171,9 @@ private Q_SLOTS:
QCOMPARE(renderBuffer.usage(), Qt3DRender::QBuffer::DynamicRead);
QVERIFY(renderBuffer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::BuffersDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderBuffer.unsetDirty();
QVERIFY(!renderBuffer.isDirty());
@@ -201,6 +190,10 @@ private Q_SLOTS:
QCOMPARE(renderBuffer.pendingBufferUpdates().first().offset, -1);
renderBuffer.pendingBufferUpdates().clear();
+
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::BuffersDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderBuffer.unsetDirty();
QVERIFY(!renderBuffer.isDirty());
@@ -215,6 +208,9 @@ private Q_SLOTS:
QCOMPARE(renderBuffer.dataGenerator(), functor);
QVERIFY(renderBuffer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::BuffersDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderBuffer.unsetDirty();
QVERIFY(!renderBuffer.isDirty());
@@ -228,6 +224,9 @@ private Q_SLOTS:
QCOMPARE(renderBuffer.isSyncData(), true);
QVERIFY(!renderBuffer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::BuffersDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
// WHEN
TestArbiter arbiter;
Qt3DCore::QBackendNodePrivate::get(&renderBuffer)->setArbiter(&arbiter);
@@ -258,6 +257,9 @@ private Q_SLOTS:
QCOMPARE(renderBuffer.pendingBufferUpdates().first().offset, 2);
QVERIFY(renderBuffer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::BuffersDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderBuffer.unsetDirty();
QVERIFY(!renderBuffer.isDirty());
}
@@ -268,8 +270,10 @@ private Q_SLOTS:
Qt3DRender::Render::Buffer renderBuffer;
Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
Qt3DRender::Render::BufferManager bufferManager;
+ TestRenderer renderer;
// WHEN
+ renderBuffer.setRenderer(&renderer);
renderBuffer.setManager(&bufferManager);
simulateInitialization(&buffer, &renderBuffer);
@@ -285,6 +289,27 @@ private Q_SLOTS:
QVERIFY(buffers.first() == renderBuffer.peerId());
QVERIFY(bufferManager.takeBuffersToRelease().empty());
}
+
+ void checkSetRendererDirtyOnInitialization()
+ {
+ // GIVEN
+ Qt3DRender::Render::Buffer renderBuffer;
+ Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer);
+ Qt3DRender::Render::BufferManager bufferManager;
+ TestRenderer renderer;
+
+ renderBuffer.setRenderer(&renderer);
+ renderBuffer.setManager(&bufferManager);
+
+ // THEN
+ QCOMPARE(renderer.dirtyBits(), 0);
+
+ // WHEN
+ simulateInitialization(&buffer, &renderBuffer);
+
+ // THEN
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::BuffersDirty);
+ }
};
diff --git a/tests/auto/render/commons/testrenderer.h b/tests/auto/render/commons/testrenderer.h
index 74f529fa0..031ca214b 100644
--- a/tests/auto/render/commons/testrenderer.h
+++ b/tests/auto/render/commons/testrenderer.h
@@ -60,6 +60,7 @@ public:
QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() Q_DECL_OVERRIDE { return QVector<Qt3DCore::QAspectJobPtr>(); }
Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() Q_DECL_OVERRIDE { return Qt3DCore::QAspectJobPtr(); }
Qt3DCore::QAspectJobPtr syncTextureLoadingJob() Q_DECL_OVERRIDE { return Qt3DCore::QAspectJobPtr(); }
+ Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() Q_DECL_OVERRIDE { return Qt3DCore::QAspectJobPtr(); }
void setSceneRoot(Qt3DCore::QBackendNodeFactory *factory, Qt3DRender::Render::Entity *root) Q_DECL_OVERRIDE { Q_UNUSED(factory); Q_UNUSED(root); }
Qt3DRender::Render::Entity *sceneRoot() const Q_DECL_OVERRIDE { return nullptr; }
Qt3DRender::Render::FrameGraphNode *frameGraphRoot() const Q_DECL_OVERRIDE { return nullptr; }
diff --git a/tests/auto/render/ddstextures/data/16x16-etc1.pkm b/tests/auto/render/ddstextures/data/16x16-etc1.pkm
new file mode 100644
index 000000000..62ae2a11f
--- /dev/null
+++ b/tests/auto/render/ddstextures/data/16x16-etc1.pkm
Binary files differ
diff --git a/tests/auto/render/ddstextures/data/16x16-etc2.pkm b/tests/auto/render/ddstextures/data/16x16-etc2.pkm
new file mode 100644
index 000000000..be391113e
--- /dev/null
+++ b/tests/auto/render/ddstextures/data/16x16-etc2.pkm
Binary files differ
diff --git a/tests/auto/render/ddstextures/ddstextures.pro b/tests/auto/render/ddstextures/ddstextures.pro
index e81fd80d8..62456561f 100644
--- a/tests/auto/render/ddstextures/ddstextures.pro
+++ b/tests/auto/render/ddstextures/ddstextures.pro
@@ -30,7 +30,9 @@ OTHER_FILES = \
data/16x16x1-6-lumi.dds \
data/16x16x1-6-lumi-nomips.dds \
data/16x16x1-6-rgb.dds \
- data/16x16x1-6-rgb-nomips.dds
+ data/16x16x1-6-rgb-nomips.dds \
+ data/16x16-etc1.pkm \
+ data/16x16-etc2.pkm
TESTDATA = data/*
diff --git a/tests/auto/render/ddstextures/tst_ddstextures.cpp b/tests/auto/render/ddstextures/tst_ddstextures.cpp
index 4d9a1fb32..1f33f20e2 100644
--- a/tests/auto/render/ddstextures/tst_ddstextures.cpp
+++ b/tests/auto/render/ddstextures/tst_ddstextures.cpp
@@ -73,6 +73,8 @@ void tst_DdsTextures::ddsImageData()
{ "data/16x16x1-6-bc1-dx10.dds", 16, 16, 1, 6, 5, QOpenGLTexture::RGBA_DXT1 },
{ "data/16x16x1-6-bc3-nomips-dx10.dds", 16, 16, 1, 6, 1, QOpenGLTexture::RGBA_DXT5 },
{ "data/16x16x1-6-bc3-dx10.dds", 16, 16, 1, 6, 5, QOpenGLTexture::RGBA_DXT5 },
+ { "data/16x16-etc1.pkm", 16, 16, 1, 1, 1, QOpenGLTexture::RGB8_ETC1 },
+ { "data/16x16-etc2.pkm", 16, 16, 1, 1, 1, QOpenGLTexture::RGB8_ETC2 },
};
for (unsigned i = 0; i < sizeof(textures)/sizeof(*textures); i++) {
diff --git a/tests/auto/render/entity/tst_entity.cpp b/tests/auto/render/entity/tst_entity.cpp
index d1a222c92..6ad958451 100644
--- a/tests/auto/render/entity/tst_entity.cpp
+++ b/tests/auto/render/entity/tst_entity.cpp
@@ -46,6 +46,7 @@
#include <Qt3DRender/QGeometryRenderer>
#include <Qt3DRender/QObjectPicker>
#include <Qt3DRender/QComputeCommand>
+#include <Qt3DCore/QArmature>
#include "testrenderer.h"
@@ -62,6 +63,7 @@ QNodeId materialUuid(Entity *entity) { return entity->componentUuid<Material>();
QNodeId geometryRendererUuid(Entity *entity) { return entity->componentUuid<GeometryRenderer>(); }
QNodeId objectPickerUuid(Entity *entity) { return entity->componentUuid<ObjectPicker>(); }
QNodeId computeJobUuid(Entity *entity) { return entity->componentUuid<ComputeCommand>(); }
+QNodeId armatureUuid(Entity *entity) { return entity->componentUuid<Armature>(); }
QVector<QNodeId> layersUuid(Entity *entity) { return entity->componentsUuid<Layer>(); }
QVector<QNodeId> shadersUuid(Entity *entity) { return entity->componentsUuid<ShaderData>(); }
@@ -89,7 +91,8 @@ private slots:
<< new QLayer
<< new QShaderData
<< new QComputeCommand
- << new QEnvironmentLight;
+ << new QEnvironmentLight
+ << new QArmature;
QTest::newRow("all components") << components;
}
@@ -116,8 +119,10 @@ private slots:
QVERIFY(entity.componentsUuid<Layer>().isEmpty());
QVERIFY(entity.componentsUuid<ShaderData>().isEmpty());
QVERIFY(entity.componentsUuid<EnvironmentLight>().isEmpty());
+ QVERIFY(entity.componentUuid<Armature>().isNull());
QVERIFY(!entity.isBoundingVolumeDirty());
QVERIFY(entity.childrenHandles().isEmpty());
+ QVERIFY(entity.layerIds().isEmpty());
// WHEN
Q_FOREACH (QComponent *component, components) {
@@ -144,10 +149,13 @@ private slots:
QVERIFY(!entity.componentsUuid<Layer>().isEmpty());
QVERIFY(!entity.componentsUuid<ShaderData>().isEmpty());
QVERIFY(!entity.componentsUuid<EnvironmentLight>().isEmpty());
+ QVERIFY(!entity.componentUuid<Armature>().isNull());
QVERIFY(entity.isBoundingVolumeDirty());
QVERIFY(!entity.childrenHandles().isEmpty());
+ QVERIFY(!entity.layerIds().isEmpty());
QVERIFY(renderer.dirtyBits() != 0);
- bool containsAll = entity.containsComponentsOfType<Transform, CameraLens, Material, GeometryRenderer, ObjectPicker, ComputeCommand>();
+ bool containsAll = entity.containsComponentsOfType<Transform,
+ CameraLens, Material, GeometryRenderer, ObjectPicker, ComputeCommand, Armature>();
QVERIFY(containsAll);
// WHEN
@@ -163,9 +171,12 @@ private slots:
QVERIFY(entity.componentsUuid<Layer>().isEmpty());
QVERIFY(entity.componentsUuid<ShaderData>().isEmpty());
QVERIFY(entity.componentsUuid<EnvironmentLight>().isEmpty());
+ QVERIFY(entity.componentUuid<Armature>().isNull());
QVERIFY(!entity.isBoundingVolumeDirty());
QVERIFY(entity.childrenHandles().isEmpty());
- containsAll = entity.containsComponentsOfType<Transform, CameraLens, Material, GeometryRenderer, ObjectPicker, ComputeCommand>();
+ QVERIFY(entity.layerIds().isEmpty());
+ containsAll = entity.containsComponentsOfType<Transform,
+ CameraLens, Material, GeometryRenderer, ObjectPicker, ComputeCommand, Armature>();
QVERIFY(!containsAll);
}
@@ -191,6 +202,9 @@ private slots:
component = new QComputeCommand;
QTest::newRow("computeJob") << component << reinterpret_cast<void*>(computeJobUuid);
+
+ component = new QArmature;
+ QTest::newRow("armature") << component << reinterpret_cast<void*>(armatureUuid);
}
void shouldHandleSingleComponentEvents()
diff --git a/tests/auto/render/filtercompatibletechniquejob/BLACKLIST b/tests/auto/render/filtercompatibletechniquejob/BLACKLIST
index c9313fd62..22cb59fab 100644
--- a/tests/auto/render/filtercompatibletechniquejob/BLACKLIST
+++ b/tests/auto/render/filtercompatibletechniquejob/BLACKLIST
@@ -1,4 +1,5 @@
-[checkRunRendererNotRunning]
-windows
-[checkRunRendererRunning]
+#[checkRunRendererNotRunning]
+#windows
+#[checkRunRendererRunning]
+#QTBUG-64271
windows
diff --git a/tests/auto/render/geometry/tst_geometry.cpp b/tests/auto/render/geometry/tst_geometry.cpp
index 6a8746f47..958edfd09 100644
--- a/tests/auto/render/geometry/tst_geometry.cpp
+++ b/tests/auto/render/geometry/tst_geometry.cpp
@@ -54,6 +54,7 @@ private Q_SLOTS:
{
// GIVEN
Qt3DRender::Render::Geometry renderGeometry;
+ TestRenderer renderer;
Qt3DRender::QGeometry geometry;
Qt3DRender::QAttribute attr1;
@@ -66,6 +67,7 @@ private Q_SLOTS:
geometry.addAttribute(&attr3);
geometry.addAttribute(&attr4);
geometry.setBoundingVolumePositionAttribute(&attr1);
+ renderGeometry.setRenderer(&renderer);
// WHEN
simulateInitialization(&geometry, &renderGeometry);
@@ -80,10 +82,31 @@ private Q_SLOTS:
QCOMPARE(geometry.attributes().at(i)->id(), renderGeometry.attributes().at(i));
}
+ void checkSetRendererDirtyOnInitialization()
+ {
+ // GIVEN
+ Qt3DRender::Render::Geometry renderGeometry;
+ Qt3DRender::QGeometry geometry;
+ TestRenderer renderer;
+
+ renderGeometry.setRenderer(&renderer);
+
+ // THEN
+ QCOMPARE(renderer.dirtyBits(), 0);
+
+ // WHEN
+ simulateInitialization(&geometry, &renderGeometry);
+
+ // THEN
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ }
+
void checkInitialAndCleanedUpState()
{
// GIVEN
+ TestRenderer renderer;
Qt3DRender::Render::Geometry renderGeometry;
+ renderGeometry.setRenderer(&renderer);
// THEN
QCOMPARE(renderGeometry.isDirty(), false);
@@ -131,6 +154,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderGeometry.attributes().count(), 1);
QVERIFY(renderGeometry.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
renderGeometry.unsetDirty();
QVERIFY(!renderGeometry.isDirty());
@@ -143,6 +168,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderGeometry.attributes().count(), 0);
QVERIFY(renderGeometry.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
renderGeometry.unsetDirty();
QVERIFY(!renderGeometry.isDirty());
@@ -157,6 +184,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderGeometry.boundingPositionAttribute(), boundingAttrId);
QVERIFY(!renderGeometry.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
};
diff --git a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
index d9ed000ab..af074def0 100644
--- a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
+++ b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
@@ -85,11 +85,13 @@ private Q_SLOTS:
Qt3DRender::QGeometry geometry;
Qt3DRender::QGeometryFactoryPtr factory(new TestFactory(1200));
Qt3DRender::Render::GeometryRendererManager geometryRendererManager;
+ TestRenderer renderer;
geometryRenderer.setInstanceCount(1584);
geometryRenderer.setVertexCount(1609);
geometryRenderer.setIndexOffset(750);
geometryRenderer.setFirstInstance(883);
+ geometryRenderer.setIndexBufferByteOffset(96);
geometryRenderer.setRestartIndexValue(65536);
geometryRenderer.setPrimitiveRestartEnabled(true);
geometryRenderer.setPrimitiveType(Qt3DRender::QGeometryRenderer::Patches);
@@ -98,6 +100,7 @@ private Q_SLOTS:
geometryRenderer.setEnabled(false);
// WHEN
+ renderGeometryRenderer.setRenderer(&renderer);
renderGeometryRenderer.setManager(&geometryRendererManager);
simulateInitialization(&geometryRenderer, &renderGeometryRenderer);
@@ -108,6 +111,7 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.vertexCount(), geometryRenderer.vertexCount());
QCOMPARE(renderGeometryRenderer.indexOffset(), geometryRenderer.indexOffset());
QCOMPARE(renderGeometryRenderer.firstInstance(), geometryRenderer.firstInstance());
+ QCOMPARE(renderGeometryRenderer.indexBufferByteOffset(), geometryRenderer.indexBufferByteOffset());
QCOMPARE(renderGeometryRenderer.restartIndexValue(), geometryRenderer.restartIndexValue());
QCOMPARE(renderGeometryRenderer.primitiveRestartEnabled(), geometryRenderer.primitiveRestartEnabled());
QCOMPARE(renderGeometryRenderer.primitiveType(), geometryRenderer.primitiveType());
@@ -131,6 +135,7 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.vertexCount(), 0);
QCOMPARE(renderGeometryRenderer.indexOffset(), 0);
QCOMPARE(renderGeometryRenderer.firstInstance(), 0);
+ QCOMPARE(renderGeometryRenderer.indexBufferByteOffset(), 0);
QCOMPARE(renderGeometryRenderer.restartIndexValue(), -1);
QCOMPARE(renderGeometryRenderer.primitiveRestartEnabled(), false);
QCOMPARE(renderGeometryRenderer.primitiveType(), Qt3DRender::QGeometryRenderer::Triangles);
@@ -141,12 +146,13 @@ private Q_SLOTS:
Qt3DRender::QGeometryRenderer geometryRenderer;
Qt3DRender::QGeometry geometry;
Qt3DRender::QGeometryFactoryPtr factory(new TestFactory(1200));
-
+ TestRenderer renderer;
geometryRenderer.setInstanceCount(454);
geometryRenderer.setVertexCount(350);
geometryRenderer.setIndexOffset(427);
geometryRenderer.setFirstInstance(383);
+ geometryRenderer.setIndexBufferByteOffset(96);
geometryRenderer.setRestartIndexValue(555);
geometryRenderer.setPrimitiveRestartEnabled(true);
geometryRenderer.setPrimitiveType(Qt3DRender::QGeometryRenderer::Patches);
@@ -155,6 +161,7 @@ private Q_SLOTS:
geometryRenderer.setEnabled(true);
// WHEN
+ renderGeometryRenderer.setRenderer(&renderer);
renderGeometryRenderer.setManager(&geometryRendererManager);
simulateInitialization(&geometryRenderer, &renderGeometryRenderer);
renderGeometryRenderer.cleanup();
@@ -166,6 +173,7 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.vertexCount(), 0);
QCOMPARE(renderGeometryRenderer.indexOffset(), 0);
QCOMPARE(renderGeometryRenderer.firstInstance(), 0);
+ QCOMPARE(renderGeometryRenderer.indexBufferByteOffset(), 0);
QCOMPARE(renderGeometryRenderer.restartIndexValue(), -1);
QCOMPARE(renderGeometryRenderer.primitiveRestartEnabled(), false);
QCOMPARE(renderGeometryRenderer.primitiveType(), Qt3DRender::QGeometryRenderer::Triangles);
@@ -191,7 +199,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(renderGeometryRenderer.instanceCount(), 2);
QVERIFY(renderGeometryRenderer.isDirty());
- QVERIFY(renderer.dirtyBits() != 0);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
@@ -206,6 +215,9 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.vertexCount(), 56);
QVERIFY(renderGeometryRenderer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
@@ -219,6 +231,9 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.indexOffset(), 65);
QVERIFY(renderGeometryRenderer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
@@ -232,6 +247,25 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.firstInstance(), 82);
QVERIFY(renderGeometryRenderer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+ renderGeometryRenderer.unsetDirty();
+ QVERIFY(!renderGeometryRenderer.isDirty());
+
+ // WHEN
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("indexBufferByteOffset");
+ updateChange->setValue(96);
+ renderGeometryRenderer.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(renderGeometryRenderer.indexBufferByteOffset(), 96);
+ QVERIFY(renderGeometryRenderer.isDirty());
+
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
@@ -245,6 +279,9 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.restartIndexValue(), 46);
QVERIFY(renderGeometryRenderer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
@@ -258,6 +295,9 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.primitiveRestartEnabled(), true);
QVERIFY(renderGeometryRenderer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
@@ -271,6 +311,9 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.primitiveType(), Qt3DRender::QGeometryRenderer::LineLoop);
QVERIFY(renderGeometryRenderer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
@@ -285,9 +328,23 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.geometryFactory(), factory);
QVERIFY(renderGeometryRenderer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
+ // WHEN we set an identical factory again
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("geometryFactory");
+ Qt3DRender::QGeometryFactoryPtr factory2(new TestFactory(1450));
+ updateChange->setValue(QVariant::fromValue(factory2));
+ renderGeometryRenderer.sceneChangeEvent(updateChange);
+
+ // THEN not dirty and still uses original factory
+ QCOMPARE(renderGeometryRenderer.geometryFactory(), factory);
+ QVERIFY(!renderGeometryRenderer.isDirty());
+
// WHEN
DummyGeometry geometry;
const Qt3DCore::QNodeId geometryId = geometry.id();
@@ -300,6 +357,9 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.geometryId(), geometryId);
QVERIFY(renderGeometryRenderer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
@@ -313,6 +373,9 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.geometryId(), Qt3DCore::QNodeId());
QVERIFY(renderGeometryRenderer.isDirty());
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
renderGeometryRenderer.unsetDirty();
QVERIFY(!renderGeometryRenderer.isDirty());
@@ -326,6 +389,27 @@ private Q_SLOTS:
QCOMPARE(renderGeometryRenderer.isEnabled(), true);
QVERIFY(!renderGeometryRenderer.isDirty());
}
+
+ void checkSetRendererDirtyOnInitialization()
+ {
+ // GIVEN
+ Qt3DRender::Render::GeometryRendererManager geometryRendererManager;
+ Qt3DRender::Render::GeometryRenderer renderGeometryRenderer;
+ Qt3DRender::QGeometryRenderer geometryRenderer;
+ TestRenderer renderer;
+
+ renderGeometryRenderer.setRenderer(&renderer);
+ renderGeometryRenderer.setManager(&geometryRendererManager);
+
+ // THEN
+ QCOMPARE(renderer.dirtyBits(), 0);
+
+ // WHEN
+ simulateInitialization(&geometryRenderer, &renderGeometryRenderer);
+
+ // THEN
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::GeometryDirty);
+ }
};
QTEST_APPLESS_MAIN(tst_RenderGeometryRenderer)
diff --git a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
index afd56e9bd..584b675ee 100644
--- a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
+++ b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
@@ -33,8 +33,10 @@
#include <Qt3DRender/private/attachmentpack_p.h>
#include <QtOpenGLExtensions/QOpenGLExtensions>
#include <QOpenGLContext>
+#include <QOpenGLBuffer>
#include <QOpenGLFunctions_2_0>
#include <QOpenGLShaderProgram>
+#include <QOpenGLVertexArrayObject>
#include <QSurfaceFormat>
#ifndef QT_OPENGL_ES_2
@@ -612,6 +614,33 @@ private Q_SLOTS:
// Not supported by GL2
}
+ void enableVertexAttribute()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+
+ // GIVEN
+ QOpenGLVertexArrayObject vao;
+ vao.create();
+ QOpenGLVertexArrayObject::Binder binder(&vao);
+
+ QOpenGLShaderProgram shaderProgram;
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode);
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeSamplers);
+ QVERIFY(shaderProgram.link());
+ shaderProgram.bind();
+
+ // WHEN
+ GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition");
+ GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord");
+ m_glHelper.enableVertexAttributeArray(positionLocation);
+ m_glHelper.enableVertexAttributeArray(texCoordLocation);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
void frontFace()
{
if (!m_initializationSuccessful)
@@ -1019,6 +1048,51 @@ private Q_SLOTS:
// Not available in 3.2
}
+ void vertexAttributePointer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ // GIVEN
+ QOpenGLVertexArrayObject vao;
+ vao.create();
+ QOpenGLVertexArrayObject::Binder binder(&vao);
+
+ QOpenGLShaderProgram shaderProgram;
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCode);
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeSamplers);
+ QVERIFY(shaderProgram.link());
+
+ GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition");
+ GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord");
+
+ const int vertexCount = 99;
+ QOpenGLBuffer positionBuffer(QOpenGLBuffer::VertexBuffer);
+ positionBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ positionBuffer.create();
+ positionBuffer.bind();
+ positionBuffer.allocate(vertexCount * sizeof(QVector3D));
+
+ QOpenGLBuffer texCoordBuffer(QOpenGLBuffer::VertexBuffer);
+ texCoordBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ texCoordBuffer.create();
+ texCoordBuffer.allocate(vertexCount * sizeof(QVector2D));
+
+ // WHEN
+ shaderProgram.bind();
+ positionBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(positionLocation);
+ m_glHelper.vertexAttributePointer(GL_FLOAT_VEC3, positionLocation, 3, GL_FLOAT, GL_TRUE, 0, 0);
+
+ texCoordBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(texCoordLocation);
+ m_glHelper.vertexAttributePointer(GL_FLOAT_VEC2, texCoordLocation, 2, GL_FLOAT, GL_TRUE, 0, 0);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
void glUniform1fv()
{
if (!m_initializationSuccessful)
@@ -1438,6 +1512,18 @@ private Q_SLOTS:
QCOMPARE(computed, expected);
}
+ void drawBuffer()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
+ void readBuffer()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
diff --git a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
index 1414d13b0..648eaaddb 100644
--- a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
+++ b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
@@ -31,8 +31,10 @@
#include <Qt3DRender/private/uniform_p.h>
#include <Qt3DRender/private/graphicshelpergl3_2_p.h>
#include <Qt3DRender/private/attachmentpack_p.h>
+#include <QOpenGLBuffer>
#include <QOpenGLFunctions_3_2_Core>
#include <QOpenGLShaderProgram>
+#include <QOpenGLVertexArrayObject>
#include <QSurfaceFormat>
#if !defined(QT_OPENGL_ES_2) && defined(QT_OPENGL_3_2)
@@ -139,6 +141,7 @@ const QByteArray fragCodeUniformsFloatMatrices = QByteArrayLiteral(
const QByteArray fragCodeUniformBuffer = QByteArrayLiteral(
"#version 150 core\n" \
"out vec4 color;\n" \
+ "in vec2 texCoord;\n" \
"flat in int colorIndex;\n" \
"uniform ColorArray\n" \
"{\n" \
@@ -146,7 +149,7 @@ const QByteArray fragCodeUniformBuffer = QByteArrayLiteral(
"};\n" \
"void main()\n" \
"{\n" \
- " color = colors[colorIndex];\n" \
+ " color = colors[colorIndex] + vec4(texCoord.s, texCoord.t, 0.0, 1.0);\n" \
"}\n");
const QByteArray fragCodeSamplers = QByteArrayLiteral(
@@ -823,6 +826,35 @@ private Q_SLOTS:
m_func->glDisable(GL_PRIMITIVE_RESTART);
}
+ void enableVertexAttribute()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 3.2 Core functions not supported");
+
+ // GIVEN
+ QOpenGLVertexArrayObject vao;
+ vao.create();
+ QOpenGLVertexArrayObject::Binder binder(&vao);
+
+ QOpenGLShaderProgram shaderProgram;
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer);
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer);
+ QVERIFY(shaderProgram.link());
+ shaderProgram.bind();
+
+ // WHEN
+ GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition");
+ GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord");
+ GLint colorIndexLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexColorIndex");
+ m_glHelper.enableVertexAttributeArray(positionLocation);
+ m_glHelper.enableVertexAttributeArray(texCoordLocation);
+ m_glHelper.enableVertexAttributeArray(colorIndexLocation);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
void frontFace()
{
if (!m_initializationSuccessful)
@@ -1318,6 +1350,61 @@ private Q_SLOTS:
// Not available in 3.2
}
+ void vertexAttributePointer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ // GIVEN
+ QOpenGLVertexArrayObject vao;
+ vao.create();
+ QOpenGLVertexArrayObject::Binder binder(&vao);
+
+ QOpenGLShaderProgram shaderProgram;
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer);
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer);
+ QVERIFY(shaderProgram.link());
+
+ GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition");
+ GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord");
+ GLint colorIndexLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexColorIndex");
+
+ const int vertexCount = 99;
+ QOpenGLBuffer positionBuffer(QOpenGLBuffer::VertexBuffer);
+ positionBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ positionBuffer.create();
+ positionBuffer.bind();
+ positionBuffer.allocate(vertexCount * sizeof(QVector3D));
+
+ QOpenGLBuffer texCoordBuffer(QOpenGLBuffer::VertexBuffer);
+ texCoordBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ texCoordBuffer.create();
+ texCoordBuffer.allocate(vertexCount * sizeof(QVector2D));
+
+ QOpenGLBuffer colorIndexBuffer(QOpenGLBuffer::VertexBuffer);
+ colorIndexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ colorIndexBuffer.create();
+ colorIndexBuffer.allocate(vertexCount * sizeof(int));
+
+ // WHEN
+ shaderProgram.bind();
+ positionBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(positionLocation);
+ m_glHelper.vertexAttributePointer(GL_FLOAT_VEC3, positionLocation, 3, GL_FLOAT, GL_TRUE, 0, 0);
+
+ texCoordBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(texCoordLocation);
+ m_glHelper.vertexAttributePointer(GL_FLOAT_VEC2, texCoordLocation, 2, GL_FLOAT, GL_TRUE, 0, 0);
+
+ colorIndexBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(colorIndexLocation);
+ m_glHelper.vertexAttributePointer(GL_INT, colorIndexLocation, 1, GL_INT, GL_TRUE, 0, 0);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
void glUniform1fv()
{
if (!m_initializationSuccessful)
@@ -2028,6 +2115,42 @@ private Q_SLOTS:
QCOMPARE(computed, expected);
}
+ void drawBuffer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 3.2 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ m_glHelper.drawBuffer(GL_FRONT);
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // THEN
+ GLint p;
+ m_func->glGetIntegerv(GL_DRAW_BUFFER, &p);
+ QCOMPARE(p, GL_FRONT);
+ }
+
+ void readBuffer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 3.2 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ m_glHelper.readBuffer(GL_FRONT);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ GLint p;
+ m_func->glGetIntegerv(GL_READ_BUFFER, &p);
+ QCOMPARE(p, GL_FRONT);
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
diff --git a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
index eea0e9f14..06a3c41cd 100644
--- a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
+++ b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
@@ -31,8 +31,10 @@
#include <Qt3DRender/private/uniform_p.h>
#include <Qt3DRender/private/graphicshelpergl3_3_p.h>
#include <Qt3DRender/private/attachmentpack_p.h>
+#include <QOpenGLBuffer>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>
+#include <QOpenGLVertexArrayObject>
#if !defined(QT_OPENGL_ES_2) && defined(QT_OPENGL_3_2)
@@ -138,6 +140,7 @@ const QByteArray fragCodeUniformsFloatMatrices = QByteArrayLiteral(
const QByteArray fragCodeUniformBuffer = QByteArrayLiteral(
"#version 330 core\n" \
"out vec4 color;\n" \
+ "in vec2 texCoord;\n" \
"flat in int colorIndex;\n" \
"uniform ColorArray\n" \
"{\n" \
@@ -145,7 +148,7 @@ const QByteArray fragCodeUniformBuffer = QByteArrayLiteral(
"};\n" \
"void main()\n" \
"{\n" \
- " color = colors[colorIndex];\n" \
+ " color = colors[colorIndex] + vec4(texCoord.s, texCoord.t, 0.0, 1.0);\n" \
"}\n");
const QByteArray fragCodeSamplers = QByteArrayLiteral(
@@ -922,6 +925,35 @@ private Q_SLOTS:
m_func->glDisable(GL_PRIMITIVE_RESTART);
}
+ void enableVertexAttribute()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 3.3 Core functions not supported");
+
+ // GIVEN
+ QOpenGLVertexArrayObject vao;
+ vao.create();
+ QOpenGLVertexArrayObject::Binder binder(&vao);
+
+ QOpenGLShaderProgram shaderProgram;
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer);
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer);
+ QVERIFY(shaderProgram.link());
+ shaderProgram.bind();
+
+ // WHEN
+ GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition");
+ GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord");
+ GLint colorIndexLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexColorIndex");
+ m_glHelper.enableVertexAttributeArray(positionLocation);
+ m_glHelper.enableVertexAttributeArray(texCoordLocation);
+ m_glHelper.enableVertexAttributeArray(colorIndexLocation);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
void frontFace()
{
if (!m_initializationSuccessful)
@@ -1417,6 +1449,61 @@ private Q_SLOTS:
QSKIP("Initialization failed, OpenGL 3.3 Core functions not supported");
}
+ void vertexAttributePointer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ // GIVEN
+ QOpenGLVertexArrayObject vao;
+ vao.create();
+ QOpenGLVertexArrayObject::Binder binder(&vao);
+
+ QOpenGLShaderProgram shaderProgram;
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer);
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer);
+ QVERIFY(shaderProgram.link());
+
+ GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition");
+ GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord");
+ GLint colorIndexLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexColorIndex");
+
+ const int vertexCount = 99;
+ QOpenGLBuffer positionBuffer(QOpenGLBuffer::VertexBuffer);
+ positionBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ positionBuffer.create();
+ positionBuffer.bind();
+ positionBuffer.allocate(vertexCount * sizeof(QVector3D));
+
+ QOpenGLBuffer texCoordBuffer(QOpenGLBuffer::VertexBuffer);
+ texCoordBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ texCoordBuffer.create();
+ texCoordBuffer.allocate(vertexCount * sizeof(QVector2D));
+
+ QOpenGLBuffer colorIndexBuffer(QOpenGLBuffer::VertexBuffer);
+ colorIndexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ colorIndexBuffer.create();
+ colorIndexBuffer.allocate(vertexCount * sizeof(int));
+
+ // WHEN
+ shaderProgram.bind();
+ positionBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(positionLocation);
+ m_glHelper.vertexAttributePointer(GL_FLOAT_VEC3, positionLocation, 3, GL_FLOAT, GL_TRUE, 0, 0);
+
+ texCoordBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(texCoordLocation);
+ m_glHelper.vertexAttributePointer(GL_FLOAT_VEC2, texCoordLocation, 2, GL_FLOAT, GL_TRUE, 0, 0);
+
+ colorIndexBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(colorIndexLocation);
+ m_glHelper.vertexAttributePointer(GL_INT, colorIndexLocation, 1, GL_INT, GL_TRUE, 0, 0);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
void glUniform1fv()
{
if (!m_initializationSuccessful)
@@ -2128,6 +2215,42 @@ private Q_SLOTS:
QCOMPARE(computed, expected);
}
+ void drawBuffer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 3.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ m_glHelper.drawBuffer(GL_FRONT);
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // THEN
+ GLint p;
+ m_func->glGetIntegerv(GL_DRAW_BUFFER, &p);
+ QCOMPARE(p, GL_FRONT);
+ }
+
+ void readBuffer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 3.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ m_glHelper.readBuffer(GL_FRONT);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ GLint p;
+ m_func->glGetIntegerv(GL_READ_BUFFER, &p);
+ QCOMPARE(p, GL_FRONT);
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
diff --git a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
index 84d261659..5a96cf116 100644
--- a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
+++ b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
@@ -31,8 +31,10 @@
#include <Qt3DRender/private/uniform_p.h>
#include <Qt3DRender/private/graphicshelpergl4_p.h>
#include <Qt3DRender/private/attachmentpack_p.h>
+#include <QOpenGLBuffer>
#include <QOpenGLFunctions_4_3_Core>
#include <QOpenGLShaderProgram>
+#include <QOpenGLVertexArrayObject>
#include <QSurfaceFormat>
#if !defined(QT_OPENGL_ES_2) && defined(QT_OPENGL_4_3)
@@ -60,11 +62,12 @@ const QByteArray vertCodeUniformBuffer = QByteArrayLiteral(
"layout(location = 1) in vec3 vertexPosition;\n" \
"layout(location = 2) in vec2 vertexTexCoord;\n" \
"layout(location = 3) in int vertexColorIndex;\n" \
+ "layout(location = 4) in double vertexTexCoordScale;\n" \
"out vec2 texCoord;\n" \
"flat out int colorIndex;\n" \
"void main()\n" \
"{\n" \
- " texCoord = vertexTexCoord;\n" \
+ " texCoord = vec2(vertexTexCoordScale * vertexTexCoord);\n" \
" colorIndex = vertexColorIndex;\n" \
" gl_Position = vec4(vertexPosition, 1.0);\n" \
"}\n");
@@ -139,6 +142,7 @@ const QByteArray fragCodeUniformsFloatMatrices = QByteArrayLiteral(
const QByteArray fragCodeUniformBuffer = QByteArrayLiteral(
"#version 430 core\n" \
"out vec4 color;\n" \
+ "in vec2 texCoord;\n" \
"flat in int colorIndex;\n" \
"layout(binding = 2, std140) uniform ColorArray\n" \
"{\n" \
@@ -146,7 +150,7 @@ const QByteArray fragCodeUniformBuffer = QByteArrayLiteral(
"};\n" \
"void main()\n" \
"{\n" \
- " color = colors[colorIndex];\n" \
+ " color = colors[colorIndex] + vec4(texCoord.s, texCoord.t, 0.0, 1.0);\n" \
"}\n");
const QByteArray fragCodeSamplers = QByteArrayLiteral(
@@ -1020,6 +1024,35 @@ private Q_SLOTS:
m_func->glDisable(GL_PRIMITIVE_RESTART);
}
+ void enableVertexAttribute()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ // GIVEN
+ QOpenGLVertexArrayObject vao;
+ vao.create();
+ QOpenGLVertexArrayObject::Binder binder(&vao);
+
+ QOpenGLShaderProgram shaderProgram;
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer);
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer);
+ QVERIFY(shaderProgram.link());
+ shaderProgram.bind();
+
+ // WHEN
+ GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition");
+ GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord");
+ GLint colorIndexLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexColorIndex");
+ m_glHelper.enableVertexAttributeArray(positionLocation);
+ m_glHelper.enableVertexAttributeArray(texCoordLocation);
+ m_glHelper.enableVertexAttributeArray(colorIndexLocation);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
void frontFace()
{
if (!m_initializationSuccessful)
@@ -1507,6 +1540,71 @@ private Q_SLOTS:
QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
}
+ void vertexAttributePointer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ // GIVEN
+ QOpenGLVertexArrayObject vao;
+ vao.create();
+ QOpenGLVertexArrayObject::Binder binder(&vao);
+
+ QOpenGLShaderProgram shaderProgram;
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertCodeUniformBuffer);
+ shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragCodeUniformBuffer);
+ QVERIFY(shaderProgram.link());
+
+ GLint positionLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexPosition");
+ GLint texCoordLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoord");
+ GLint colorIndexLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexColorIndex");
+ GLint texCoordScaleLocation = m_func->glGetAttribLocation(shaderProgram.programId(), "vertexTexCoordScale");
+
+ const int vertexCount = 99;
+ QOpenGLBuffer positionBuffer(QOpenGLBuffer::VertexBuffer);
+ positionBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ positionBuffer.create();
+ positionBuffer.bind();
+ positionBuffer.allocate(vertexCount * sizeof(QVector3D));
+
+ QOpenGLBuffer texCoordBuffer(QOpenGLBuffer::VertexBuffer);
+ texCoordBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ texCoordBuffer.create();
+ texCoordBuffer.allocate(vertexCount * sizeof(QVector2D));
+
+ QOpenGLBuffer colorIndexBuffer(QOpenGLBuffer::VertexBuffer);
+ colorIndexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ colorIndexBuffer.create();
+ colorIndexBuffer.allocate(vertexCount * sizeof(int));
+
+ QOpenGLBuffer scaleBuffer(QOpenGLBuffer::VertexBuffer);
+ scaleBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
+ scaleBuffer.create();
+ scaleBuffer.allocate(vertexCount * sizeof(double));
+
+ // WHEN
+ shaderProgram.bind();
+ positionBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(positionLocation);
+ m_glHelper.vertexAttributePointer(GL_FLOAT_VEC3, positionLocation, 3, GL_FLOAT, GL_TRUE, 0, 0);
+
+ texCoordBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(texCoordLocation);
+ m_glHelper.vertexAttributePointer(GL_FLOAT_VEC2, texCoordLocation, 2, GL_FLOAT, GL_TRUE, 0, 0);
+
+ colorIndexBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(colorIndexLocation);
+ m_glHelper.vertexAttributePointer(GL_INT, colorIndexLocation, 1, GL_INT, GL_TRUE, 0, 0);
+
+ scaleBuffer.bind();
+ m_glHelper.enableVertexAttributeArray(colorIndexLocation);
+ m_glHelper.vertexAttributePointer(GL_DOUBLE, texCoordScaleLocation, 1, GL_DOUBLE, GL_TRUE, 0, 0);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
void glUniform1fv()
{
if (!m_initializationSuccessful)
@@ -2196,6 +2294,42 @@ private Q_SLOTS:
QCOMPARE(computed, expected);
}
+ void drawBuffer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ m_glHelper.drawBuffer(GL_FRONT);
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // THEN
+ GLint p;
+ m_func->glGetIntegerv(GL_DRAW_BUFFER, &p);
+ QCOMPARE(p, GL_FRONT);
+ }
+
+ void readBuffer()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ m_glHelper.readBuffer(GL_FRONT);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ GLint p;
+ m_func->glGetIntegerv(GL_READ_BUFFER, &p);
+ QCOMPARE(p, GL_FRONT);
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
diff --git a/tests/auto/render/joint/joint.pro b/tests/auto/render/joint/joint.pro
new file mode 100644
index 000000000..9428ab5fd
--- /dev/null
+++ b/tests/auto/render/joint/joint.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+
+TARGET = tst_joint
+
+QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_joint.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/joint/tst_joint.cpp b/tests/auto/render/joint/tst_joint.cpp
new file mode 100644
index 000000000..13aa915d2
--- /dev/null
+++ b/tests/auto/render/joint/tst_joint.cpp
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** 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 <Qt3DRender/private/joint_p.h>
+#include <Qt3DRender/private/nodemanagers_p.h>
+#include <Qt3DCore/qjoint.h>
+#include <Qt3DCore/private/qnode_p.h>
+#include <Qt3DCore/private/qscene_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qpropertyupdatedchangebase_p.h>
+#include <Qt3DCore/qpropertynodeaddedchange.h>
+#include <Qt3DCore/qpropertynoderemovedchange.h>
+#include <QtGui/qmatrix4x4.h>
+#include <QtGui/qvector3d.h>
+#include <qbackendnodetester.h>
+#include <testpostmanarbiter.h>
+#include <testrenderer.h>
+
+using namespace Qt3DCore;
+using namespace Qt3DRender;
+using namespace Qt3DRender::Render;
+
+class tst_Joint : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void checkPeerPropertyMirroring()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ NodeManagers nodeManagers;
+ renderer.setNodeManagers(&nodeManagers);
+ Joint backendJoint;
+ backendJoint.setRenderer(&renderer);
+ backendJoint.setJointManager(nodeManagers.jointManager());
+ QJoint joint;
+
+ joint.setTranslation(QVector3D(1.0f, 2.0f, 3.0f));
+ joint.setScale(QVector3D(1.5f, 2.5f, 3.5));
+ joint.setRotation(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 45.0f));
+ QMatrix4x4 inverseBind;
+ inverseBind.rotate(-45.0f, 1.0f, 0.0, 0.0f);
+ joint.setInverseBindMatrix(inverseBind);
+
+ QVector<QJoint *> childJoints;
+ for (int i = 0; i < 10; ++i) {
+ const auto childJoint = new QJoint();
+ joint.addChildJoint(childJoint);
+ childJoints.push_back(childJoint);
+ }
+
+ // WHEN
+ simulateInitialization(&joint, &backendJoint);
+
+ // THEN
+ QCOMPARE(backendJoint.peerId(), joint.id());
+ QCOMPARE(backendJoint.isEnabled(), joint.isEnabled());
+ QCOMPARE(backendJoint.translation(), joint.translation());
+ QCOMPARE(backendJoint.rotation(), joint.rotation());
+ QCOMPARE(backendJoint.scale(), joint.scale());
+ QCOMPARE(backendJoint.inverseBindMatrix(), joint.inverseBindMatrix());
+ for (int i = 0; i < childJoints.size(); ++i) {
+ QCOMPARE(backendJoint.childJointIds()[i], childJoints[i]->id());
+ }
+ }
+
+ void checkInitialAndCleanedUpState()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ NodeManagers nodeManagers;
+ renderer.setNodeManagers(&nodeManagers);
+ Joint backendJoint;
+ backendJoint.setRenderer(&renderer);
+ backendJoint.setJointManager(nodeManagers.jointManager());
+
+ // THEN
+ QVERIFY(backendJoint.peerId().isNull());
+ QCOMPARE(backendJoint.isEnabled(), false);
+ QCOMPARE(backendJoint.translation(), QVector3D());
+ QCOMPARE(backendJoint.rotation(), QQuaternion());
+ QCOMPARE(backendJoint.scale(), QVector3D(1.0f, 1.0f, 1.0f));
+ QCOMPARE(backendJoint.inverseBindMatrix(), QMatrix4x4());
+ QCOMPARE(backendJoint.childJointIds(), QNodeIdVector());
+ QCOMPARE(backendJoint.owningSkeleton(), HSkeleton());
+
+ // GIVEN
+ QJoint joint;
+ joint.setTranslation(QVector3D(1.0f, 2.0f, 3.0f));
+ joint.setScale(QVector3D(1.5f, 2.5f, 3.5));
+ joint.setRotation(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 45.0f));
+ QMatrix4x4 inverseBind;
+ inverseBind.rotate(-45.0f, 1.0f, 0.0, 0.0f);
+ joint.setInverseBindMatrix(inverseBind);
+
+ QVector<QJoint *> childJoints;
+ for (int i = 0; i < 10; ++i) {
+ const auto childJoint = new QJoint();
+ joint.addChildJoint(childJoint);
+ childJoints.push_back(childJoint);
+ }
+
+ // WHEN
+ simulateInitialization(&joint, &backendJoint);
+ backendJoint.cleanup();
+
+ // THEN
+ QCOMPARE(backendJoint.isEnabled(), false);
+ QCOMPARE(backendJoint.translation(), QVector3D());
+ QCOMPARE(backendJoint.rotation(), QQuaternion());
+ QCOMPARE(backendJoint.scale(), QVector3D(1.0f, 1.0f, 1.0f));
+ QCOMPARE(backendJoint.inverseBindMatrix(), QMatrix4x4());
+ QCOMPARE(backendJoint.childJointIds(), QNodeIdVector());
+ QCOMPARE(backendJoint.owningSkeleton(), HSkeleton());
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ NodeManagers nodeManagers;
+ renderer.setNodeManagers(&nodeManagers);
+ Joint backendJoint;
+ backendJoint.setRenderer(&renderer);
+ backendJoint.setJointManager(nodeManagers.jointManager());
+ backendJoint.setSkeletonManager(nodeManagers.skeletonManager());
+ Qt3DCore::QPropertyUpdatedChangePtr updateChange;
+
+ // WHEN
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("enabled");
+ updateChange->setValue(true);
+ backendJoint.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendJoint.isEnabled(), true);
+
+ // WHEN
+ const QVector3D newTranslation = QVector3D(1.0f, 2.0f, 3.0f);
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("translation");
+ updateChange->setValue(newTranslation);
+ backendJoint.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendJoint.translation(), newTranslation);
+
+ // WHEN
+ const QQuaternion newRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 45.0f);
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("rotation");
+ updateChange->setValue(newRotation);
+ backendJoint.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendJoint.rotation(), newRotation);
+
+ // WHEN
+ const QVector3D newScale = QVector3D(1.5f, 2.5f, 3.5f);
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("scale");
+ updateChange->setValue(newScale);
+ backendJoint.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendJoint.scale(), newScale);
+
+ // WHEN
+ QMatrix4x4 newInverseBind;
+ newInverseBind.scale(5.4f);
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("inverseBindMatrix");
+ updateChange->setValue(newInverseBind);
+ backendJoint.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendJoint.inverseBindMatrix(), newInverseBind);
+
+ // WHEN
+ QVector<QJoint *> childJoints;
+ QPropertyNodeAddedChangePtr nodeAddedChange;
+ for (int i = 0; i < 10; ++i) {
+ const auto childJoint = new QJoint();
+ childJoints.push_back(childJoint);
+
+ nodeAddedChange.reset(new QPropertyNodeAddedChange(QNodeId(), childJoint));
+ nodeAddedChange->setPropertyName("childJoint");
+ backendJoint.sceneChangeEvent(nodeAddedChange);
+ }
+
+ // THEN
+ for (int i = 0; i < childJoints.size(); ++i) {
+ QCOMPARE(backendJoint.childJointIds()[i], childJoints[i]->id());
+ }
+
+ QPropertyNodeRemovedChangePtr nodeRemovedChange;
+ for (int i = 0; i < 10; ++i) {
+ // WHEN
+ const auto childJoint = childJoints.takeLast();
+
+ nodeRemovedChange.reset(new QPropertyNodeRemovedChange(QNodeId(), childJoint));
+ nodeRemovedChange->setPropertyName("childJoint");
+ backendJoint.sceneChangeEvent(nodeAddedChange);
+
+ // THEN
+ for (int i = 0; i < childJoints.size(); ++i) {
+ QCOMPARE(backendJoint.childJointIds()[i], childJoints[i]->id());
+ }
+ }
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_Joint)
+
+#include "tst_joint.moc"
diff --git a/tests/auto/render/layerfiltering/tst_layerfiltering.cpp b/tests/auto/render/layerfiltering/tst_layerfiltering.cpp
index c66b85c8c..c2651c477 100644
--- a/tests/auto/render/layerfiltering/tst_layerfiltering.cpp
+++ b/tests/auto/render/layerfiltering/tst_layerfiltering.cpp
@@ -34,6 +34,7 @@
#include <Qt3DRender/private/filterlayerentityjob_p.h>
#include <Qt3DRender/private/updatetreeenabledjob_p.h>
#include <Qt3DRender/qlayer.h>
+#include <Qt3DRender/qlayerfilter.h>
#include "testaspect.h"
class tst_LayerFiltering : public QObject
@@ -45,18 +46,19 @@ private Q_SLOTS:
{
// GIVEN
Qt3DRender::Render::FilterLayerEntityJob filterJob;
+ Qt3DRender::QLayer frontendLayer;
// THEN
QCOMPARE(filterJob.hasLayerFilter(), false);
QCOMPARE(filterJob.filteredEntities().size(), 0);
- QCOMPARE(filterJob.layers().size(), 0);
+ QCOMPARE(filterJob.layerFilters().size(), 0);
+ QCOMPARE(frontendLayer.recursive(), false);
}
void filterEntities_data()
{
QTest::addColumn<Qt3DCore::QEntity *>("entitySubtree");
- QTest::addColumn<Qt3DCore::QNodeIdVector>("layerIds");
- QTest::addColumn<bool>("hasLayerFilter");
+ QTest::addColumn<Qt3DCore::QNodeIdVector>("layerFilterIds");
QTest::addColumn<Qt3DCore::QNodeIdVector>("expectedSelectedEntities");
@@ -70,15 +72,14 @@ private Q_SLOTS:
Q_UNUSED(childEntity2);
Q_UNUSED(childEntity3);
- QTest::newRow("EntitiesNoLayerNoLayerFilter-ShouldSelectAll") << rootEntity
- << Qt3DCore::QNodeIdVector()
- << false
- << (Qt3DCore::QNodeIdVector()
- << rootEntity->id()
- << childEntity1->id()
- << childEntity2->id()
- << childEntity3->id()
- );
+ QTest::newRow("EntitiesNoLayerNoLayerFilterNoDiscardNoRecursive-ShouldSelectAll") << rootEntity
+ << Qt3DCore::QNodeIdVector()
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id()
+ << childEntity2->id()
+ << childEntity3->id()
+ );
}
{
@@ -87,14 +88,14 @@ private Q_SLOTS:
Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
Q_UNUSED(childEntity1);
Q_UNUSED(childEntity2);
Q_UNUSED(childEntity3);
QTest::newRow("EntityNoLayerWithLayerFilterWithNoFilter-ShouldSelectNone") << rootEntity
- << Qt3DCore::QNodeIdVector()
- << true
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
<< Qt3DCore::QNodeIdVector();
}
@@ -109,12 +110,13 @@ private Q_SLOTS:
Q_UNUSED(childEntity3);
Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
- QTest::newRow("NoLayerWithLayerFilterWithFilter-ShouldSelectNone") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id())
- << true
- << Qt3DCore::QNodeIdVector();
+ QTest::newRow("AcceptAny-NoLayerWithLayerFilterWithFilter-ShouldSelectNone") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << Qt3DCore::QNodeIdVector();
}
{
@@ -129,10 +131,12 @@ private Q_SLOTS:
childEntity2->addComponent(layer);
childEntity3->addComponent(layer);
- QTest::newRow("LayerWithLayerFilterWithFilter-ShouldSelectAllButRoot") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id())
- << true
- << (Qt3DCore::QNodeIdVector() << childEntity1->id() << childEntity2->id() << childEntity3->id());
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("AcceptAny-LayerWithLayerFilterWithFilter-ShouldSelectAllButRoot") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector() << childEntity1->id() << childEntity2->id() << childEntity3->id());
}
{
@@ -148,10 +152,13 @@ private Q_SLOTS:
childEntity2->addComponent(layer2);
childEntity3->addComponent(layer);
- QTest::newRow("LayerWithLayerFilterWithFilter-ShouldSelectChild2And3") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id() << layer2->id())
- << true
- << (Qt3DCore::QNodeIdVector() << childEntity2->id() << childEntity3->id());
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer2);
+
+ QTest::newRow("AcceptAny-LayerWithLayerFilterWithFilter-ShouldSelectChild2And3") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector() << childEntity2->id() << childEntity3->id());
}
{
@@ -167,10 +174,12 @@ private Q_SLOTS:
childEntity2->addComponent(layer);
childEntity3->addComponent(layer);
- QTest::newRow("LayerWithLayerFilterWithFilter-ShouldSelectNone") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer2->id())
- << true
- << Qt3DCore::QNodeIdVector();
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer2);
+
+ QTest::newRow("AcceptAny-LayerWithLayerFilterWithFilter-ShouldSelectNone") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << Qt3DCore::QNodeIdVector();
}
{
@@ -186,22 +195,436 @@ private Q_SLOTS:
childEntity2->addComponent(layer);
childEntity3->addComponent(layer);
- QTest::newRow("LayerWithEntityDisabled-ShouldSelectOnlyEntityEnabled") << rootEntity
- << (Qt3DCore::QNodeIdVector() << layer->id())
- << true
- << (Qt3DCore::QNodeIdVector() << childEntity2->id() << childEntity3->id());
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("AcceptAny-LayerWithEntityDisabled-ShouldSelectOnlyEntityEnabled") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector() << childEntity2->id() << childEntity3->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+ rootEntity->addComponent(layer);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("AcceptAny-RecursiveLayerOnRoot-ShouldSelectAll") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id()
+ << childEntity2->id()
+ << childEntity3->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Q_UNUSED(childEntity1);
+ Q_UNUSED(childEntity2);
+ Q_UNUSED(childEntity3);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+ rootEntity->addComponent(layer);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("DiscardAny-RecursiveLayerLayerFilterDiscardOnRoot-ShouldSelectNone") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ rootEntity->addComponent(layer);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter->addLayer(layer);
+
+ QTest::newRow("DiscardAny-LayerLayerFilterDiscardOnRoot-ShouldSelectAllButRoot") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id()
+ << childEntity2->id()
+ << childEntity3->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer2);
+ childEntity3->addComponent(layer3);
+ childEntity3->addComponent(layer);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter->addLayer(layer2);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("DiscardAny-LayerLayerFilterDiscardOnRoot-ShouldSelectRoot") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer3);
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer);
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer);
+ childEntity3->addComponent(layer2);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter->addLayer(layer2);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("AcceptAll-LayerFilterWith2LayersNonRecursive-ShouldSelectChild1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id());
}
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer3);
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer2);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("AcceptAll-LayerFilterWith2LayersRecursive-ShouldSelectChild12") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id()
+ << childEntity2->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer3);
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer);
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer2);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("AcceptAll-LayerFilterWith2LayersRecursiveAndDirectReferenceToRecursiveLayer-ShouldSelectChild12") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id()
+ << childEntity2->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer);
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer);
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer2);
+ childEntity3->addComponent(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAllMatchingLayers);
+ layerFilter->addLayer(layer2);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("DiscardAll-LayerFilterWith2Layers-ShouldSelectRootAndChild12") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id()
+ << childEntity2->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer2);
+
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("DiscardAll-LayerFilterWith2LayersRecursive-ShouldSelectRootAndChild1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer2);
+ childEntity1->addComponent(layer);
+
+ childEntity2->addComponent(layer3);
+
+ childEntity3->addComponent(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer3);
+
+ QTest::newRow("DiscardAll-LayerFilterWith2LayersRecursiveAndDirectReference-ShouldSelectRootAndChild1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer4 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer5 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer2);
+ childEntity1->addComponent(layer3);
+
+ childEntity2->addComponent(layer2);
+ childEntity2->addComponent(layer3);
+ childEntity2->addComponent(layer4);
+ childEntity2->addComponent(layer5);
+
+ childEntity3->addComponent(layer2);
+ childEntity3->addComponent(layer3);
+ childEntity3->addComponent(layer5);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter->addLayer(layer);
+ layerFilter->addLayer(layer2);
+ layerFilter->addLayer(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter2 = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter2->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter2->addLayer(layer4);
+ layerFilter2->addLayer(layer5);
+
+ QTest::newRow("NestedFiltering-SelectAllOfLayer123AndNoneOf45-ShouldChild1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id() << layerFilter2->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity4 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity5 = new Qt3DCore::QEntity(rootEntity);
+
+ Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(rootEntity);
+ layer->setRecursive(true);
+
+ Qt3DRender::QLayer *layer2 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer3 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer4 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer5 = new Qt3DRender::QLayer(rootEntity);
+ Qt3DRender::QLayer *layer6 = new Qt3DRender::QLayer(rootEntity);
+
+ rootEntity->addComponent(layer);
+
+ childEntity1->addComponent(layer2);
+ childEntity1->addComponent(layer3);
+
+ childEntity2->addComponent(layer2);
+ childEntity2->addComponent(layer3);
+ childEntity2->addComponent(layer4);
+ childEntity2->addComponent(layer5);
+
+ childEntity3->addComponent(layer2);
+ childEntity3->addComponent(layer5);
+
+ childEntity4->addComponent(layer2);
+ childEntity4->addComponent(layer);
+ childEntity4->addComponent(layer3);
+ childEntity4->addComponent(layer6);
+
+ childEntity5->addComponent(layer3);
+ childEntity5->addComponent(layer4);
+ childEntity5->addComponent(layer6);
+
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter->setFilterMode(Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers);
+ layerFilter->addLayer(layer5);
+ layerFilter->addLayer(layer4);
+
+ Qt3DRender::QLayerFilter *layerFilter2 = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter2->setFilterMode(Qt3DRender::QLayerFilter::AcceptAnyMatchingLayers);
+ layerFilter2->addLayer(layer2);
+ layerFilter2->addLayer(layer3);
+
+ Qt3DRender::QLayerFilter *layerFilter3 = new Qt3DRender::QLayerFilter(rootEntity);
+ layerFilter3->setFilterMode(Qt3DRender::QLayerFilter::AcceptAllMatchingLayers);
+ layerFilter3->addLayer(layer);
+ layerFilter3->addLayer(layer6);
+
+ QTest::newRow("NestedFiltering-SelectAllNoneOfAnyLayer45AndAnyOf23AndAllOf16-ShouldSelectChild4-Step1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id()
+ << childEntity4->id()
+ );
+
+ QTest::newRow("NestedFiltering-SelectAllNoneOfAnyLayer45AndAnyOf23AndAllOf16-ShouldSelectChild4-Step2") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id() << layerFilter2->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity1->id()
+ << childEntity4->id());
+
+ QTest::newRow("NestedFiltering-SelectAllNoneOfAnyLayer45AndAnyOf23AndAllOf16-ShouldSelectChild4-Step3") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << layerFilter->id() << layerFilter2->id() << layerFilter3->id())
+ << (Qt3DCore::QNodeIdVector()
+ << childEntity4->id());
+ }
}
void filterEntities()
{
//QSKIP("Skipping until TestAspect can be registered");
QFETCH(Qt3DCore::QEntity *, entitySubtree);
- QFETCH(Qt3DCore::QNodeIdVector, layerIds);
- QFETCH(bool, hasLayerFilter);
+ QFETCH(Qt3DCore::QNodeIdVector, layerFilterIds);
QFETCH(Qt3DCore::QNodeIdVector, expectedSelectedEntities);
+
// GIVEN
QScopedPointer<Qt3DRender::TestAspect> aspect(new Qt3DRender::TestAspect(entitySubtree));
@@ -213,16 +636,15 @@ private Q_SLOTS:
// WHEN
Qt3DRender::Render::FilterLayerEntityJob filterJob;
- filterJob.setHasLayerFilter(hasLayerFilter);
- filterJob.setLayers(layerIds);
+ filterJob.setLayerFilters(layerFilterIds);
filterJob.setManager(aspect->nodeManagers());
filterJob.run();
// THEN
const QVector<Qt3DRender::Render::Entity *> filterEntities = filterJob.filteredEntities();
- QCOMPARE(expectedSelectedEntities.size(), filterEntities.size());
+ QCOMPARE(filterEntities.size(), expectedSelectedEntities.size());
for (auto i = 0, m = expectedSelectedEntities.size(); i < m; ++i)
- QCOMPARE(expectedSelectedEntities.at(i), filterEntities.at(i)->peerId());
+ QCOMPARE(filterEntities.at(i)->peerId(), expectedSelectedEntities.at(i));
}
};
diff --git a/tests/auto/render/loadscenejob/tst_loadscenejob.cpp b/tests/auto/render/loadscenejob/tst_loadscenejob.cpp
index 08d1caace..bd9848928 100644
--- a/tests/auto/render/loadscenejob/tst_loadscenejob.cpp
+++ b/tests/auto/render/loadscenejob/tst_loadscenejob.cpp
@@ -50,8 +50,15 @@ public:
m_source = source;
}
- bool isFileTypeSupported(const QUrl &) const Q_DECL_OVERRIDE
+ void setData(const QByteArray& data, const QString &basePath) Q_DECL_OVERRIDE
{
+ Q_UNUSED(data);
+ Q_UNUSED(basePath);
+ }
+
+ bool areFileTypesSupported(const QStringList &extensions) const Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(extensions);
return m_supportsFormat;
}
@@ -99,7 +106,7 @@ private Q_SLOTS:
void checkInitialize()
{
// GIVEN
- const QUrl url(QStringLiteral("URL"));
+ const QUrl url(QStringLiteral("file:///URL"));
const Qt3DCore::QNodeId sceneId = Qt3DCore::QNodeId::createId();
Qt3DRender::Render::NodeManagers nodeManagers;
TestSceneImporter fakeImporter(true, true);
@@ -120,8 +127,10 @@ private Q_SLOTS:
void checkRunValidSourceSupportedFormat()
{
+ QSKIP("Can't test successful loading");
+
// GIVEN
- const QUrl url(QStringLiteral("URL"));
+ const QUrl url(QStringLiteral("file:///URL"));
TestArbiter arbiter;
Qt3DRender::Render::NodeManagers nodeManagers;
TestSceneImporter fakeImporter(true, false);
@@ -202,8 +211,11 @@ private Q_SLOTS:
void checkRunValidSourceUnsupportedFormat()
{
+ // no data is loaded so...
+ QSKIP("Can't differentiate between no data and unsupported data");
+
// GIVEN
- const QUrl url(QStringLiteral("URL"));
+ const QUrl url(QStringLiteral("file:///URL"));
TestArbiter arbiter;
Qt3DRender::Render::NodeManagers nodeManagers;
TestSceneImporter fakeImporter(false, false);
@@ -241,7 +253,7 @@ private Q_SLOTS:
void checkRunErrorAtLoading()
{
// GIVEN
- const QUrl url(QStringLiteral("URL"));
+ const QUrl url(QStringLiteral("file:///URL"));
TestArbiter arbiter;
Qt3DRender::Render::NodeManagers nodeManagers;
TestSceneImporter fakeImporter(true, true);
@@ -259,7 +271,7 @@ private Q_SLOTS:
loadSceneJob.run();
// THEN
- QCOMPARE(arbiter.events.count(), 4);
+ QCOMPARE(arbiter.events.count(), 3);
auto change = arbiter.events.at(0).staticCast<Qt3DCore::QPropertyUpdatedChange>();
QCOMPARE(change->subjectId(), scene->peerId());
QCOMPARE(change->propertyName(), "status");
@@ -267,16 +279,11 @@ private Q_SLOTS:
change = arbiter.events.at(1).staticCast<Qt3DCore::QPropertyUpdatedChange>();
QCOMPARE(change->subjectId(), scene->peerId());
- QCOMPARE(change->propertyName(), "status");
- QCOMPARE(change->value().value<Qt3DRender::QSceneLoader::Status>(), Qt3DRender::QSceneLoader::Loading);
-
- change = arbiter.events.at(2).staticCast<Qt3DCore::QPropertyUpdatedChange>();
- QCOMPARE(change->subjectId(), scene->peerId());
QCOMPARE(change->propertyName(), "scene");
QVERIFY(change->value().value<Qt3DCore::QEntity *>() == nullptr);
delete change->value().value<Qt3DCore::QEntity *>();
- change = arbiter.events.at(3).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ change = arbiter.events.at(2).staticCast<Qt3DCore::QPropertyUpdatedChange>();
QCOMPARE(change->subjectId(), scene->peerId());
QCOMPARE(change->propertyName(), "status");
QCOMPARE(change->value().value<Qt3DRender::QSceneLoader::Status>(), Qt3DRender::QSceneLoader::Error);
diff --git a/tests/auto/render/meshfunctors/tst_meshfunctors.cpp b/tests/auto/render/meshfunctors/tst_meshfunctors.cpp
index e2877b24b..fd430c5d8 100644
--- a/tests/auto/render/meshfunctors/tst_meshfunctors.cpp
+++ b/tests/auto/render/meshfunctors/tst_meshfunctors.cpp
@@ -32,6 +32,7 @@
#include <Qt3DRender/qgeometry.h>
#include <Qt3DRender/qmesh.h>
#include <Qt3DRender/private/qmesh_p.h>
+#include <Qt3DCore/qaspectengine.h>
class MeshFunctorA : public Qt3DRender::QGeometryFactory
{
@@ -124,14 +125,27 @@ private Q_SLOTS:
void checkMeshFunctorEquality()
{
// GIVEN
- const Qt3DRender::MeshFunctor functorA(QUrl::fromLocalFile(QLatin1String("/foo")),
- QLatin1String("bar"));
- const Qt3DRender::MeshFunctor functorB(QUrl::fromLocalFile(QLatin1String("/foo")),
- QLatin1String("baz"));
- const Qt3DRender::MeshFunctor functorC(QUrl::fromLocalFile(QLatin1String("/baz")),
- QLatin1String("bar"));
- const Qt3DRender::MeshFunctor functorD(QUrl::fromLocalFile(QLatin1String("/foo")),
- QLatin1String("bar"));
+ Qt3DCore::QAspectEngine engine;
+ auto meshA = new Qt3DRender::QMesh();
+ meshA->setSource(QUrl::fromLocalFile(QLatin1String("/foo")));
+ meshA->setMeshName(QLatin1String("bar"));
+
+ auto meshB = new Qt3DRender::QMesh();
+ meshB->setSource(QUrl::fromLocalFile(QLatin1String("/foo")));
+ meshB->setMeshName(QLatin1String("baz"));
+
+ auto meshC = new Qt3DRender::QMesh();
+ meshC->setSource(QUrl::fromLocalFile(QLatin1String("/baz")));
+ meshC->setMeshName(QLatin1String("bar"));
+
+ auto meshD = new Qt3DRender::QMesh();
+ meshD->setSource(QUrl::fromLocalFile(QLatin1String("/foo")));
+ meshD->setMeshName(QLatin1String("bar"));
+
+ const Qt3DRender::MeshLoaderFunctor functorA(meshA, &engine);
+ const Qt3DRender::MeshLoaderFunctor functorB(meshB, &engine);
+ const Qt3DRender::MeshLoaderFunctor functorC(meshC, &engine);
+ const Qt3DRender::MeshLoaderFunctor functorD(meshD, &engine);
// WHEN
const bool selfEquality = (functorA == functorA);
@@ -147,6 +161,6 @@ private Q_SLOTS:
}
};
-QTEST_APPLESS_MAIN(tst_MeshFunctors)
+QTEST_MAIN(tst_MeshFunctors)
#include "tst_meshfunctors.moc"
diff --git a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
index c60ddda27..d9d90a03d 100644
--- a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
+++ b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
@@ -46,6 +46,7 @@
#include <Qt3DRender/qrenderaspect.h>
#include <Qt3DRender/private/qrenderaspect_p.h>
#include <Qt3DRender/private/pickboundingvolumejob_p.h>
+#include <Qt3DRender/private/pickboundingvolumeutils_p.h>
#include <Qt3DRender/private/updatemeshtrianglelistjob_p.h>
#include <Qt3DRender/private/updateworldboundingvolumejob_p.h>
#include <Qt3DRender/private/updateworldtransformjob_p.h>
diff --git a/tests/auto/render/proximityfilter/proximityfilter.pro b/tests/auto/render/proximityfilter/proximityfilter.pro
new file mode 100644
index 000000000..74599e4f0
--- /dev/null
+++ b/tests/auto/render/proximityfilter/proximityfilter.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_proximityfilter
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_proximityfilter.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/proximityfilter/tst_proximityfilter.cpp b/tests/auto/render/proximityfilter/tst_proximityfilter.cpp
new file mode 100644
index 000000000..774e2dd1f
--- /dev/null
+++ b/tests/auto/render/proximityfilter/tst_proximityfilter.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Paul Lemire <paul.lemire350@gmail.com>
+** 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 <Qt3DRender/qproximityfilter.h>
+#include <Qt3DRender/private/qproximityfilter_p.h>
+#include <Qt3DRender/private/proximityfilter_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include "qbackendnodetester.h"
+#include "testrenderer.h"
+
+class tst_ProximityFilter : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void checkInitialState()
+ {
+ // GIVEN
+ Qt3DRender::Render::ProximityFilter backendProximityFilter;
+
+ // THEN
+ QCOMPARE(backendProximityFilter.isEnabled(), false);
+ QVERIFY(backendProximityFilter.peerId().isNull());
+ QCOMPARE(backendProximityFilter.distanceThreshold(), 0.0f);
+ QCOMPARE(backendProximityFilter.entityId(), Qt3DCore::QNodeId());
+ }
+
+ void checkInitializeFromPeer()
+ {
+ // GIVEN
+ Qt3DRender::QProximityFilter proximityFilter;
+ Qt3DCore::QEntity entity;
+ proximityFilter.setDistanceThreshold(1340.0f);
+ proximityFilter.setEntity(&entity);
+
+ {
+ // WHEN
+ Qt3DRender::Render::ProximityFilter backendProximityFilter;
+ simulateInitialization(&proximityFilter, &backendProximityFilter);
+
+ // THEN
+ QCOMPARE(backendProximityFilter.isEnabled(), true);
+ QCOMPARE(backendProximityFilter.peerId(), proximityFilter.id());
+ QCOMPARE(backendProximityFilter.distanceThreshold(), 1340.f);
+ QCOMPARE(backendProximityFilter.entityId(), entity.id());
+ }
+ {
+ // WHEN
+ Qt3DRender::Render::ProximityFilter backendProximityFilter;
+ proximityFilter.setEnabled(false);
+ simulateInitialization(&proximityFilter, &backendProximityFilter);
+
+ // THEN
+ QCOMPARE(backendProximityFilter.peerId(), proximityFilter.id());
+ QCOMPARE(backendProximityFilter.isEnabled(), false);
+ }
+ }
+
+ void checkSceneChangeEvents()
+ {
+ // GIVEN
+ Qt3DRender::Render::ProximityFilter backendProximityFilter;
+ TestRenderer renderer;
+ backendProximityFilter.setRenderer(&renderer);
+
+ {
+ // WHEN
+ const bool newValue = false;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("enabled");
+ change->setValue(newValue);
+ backendProximityFilter.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendProximityFilter.isEnabled(), newValue);
+ }
+ {
+ // WHEN
+ const float newValue = 383.0f;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("distanceThreshold");
+ change->setValue(QVariant::fromValue(newValue));
+ backendProximityFilter.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendProximityFilter.distanceThreshold(), newValue);
+ }
+ {
+ // WHEN
+ const Qt3DCore::QNodeId newValue = Qt3DCore::QNodeId::createId();
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("entity");
+ change->setValue(QVariant::fromValue(newValue));
+ backendProximityFilter.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendProximityFilter.entityId(), newValue);
+ }
+ }
+
+};
+
+QTEST_MAIN(tst_ProximityFilter)
+
+#include "tst_proximityfilter.moc"
diff --git a/tests/auto/render/proximityfiltering/proximityfiltering.pro b/tests/auto/render/proximityfiltering/proximityfiltering.pro
new file mode 100644
index 000000000..68b709ec5
--- /dev/null
+++ b/tests/auto/render/proximityfiltering/proximityfiltering.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+
+TARGET = tst_proximityfiltering
+
+QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_proximityfiltering.cpp
+
+CONFIG += useCommonTestAspect
+
+include(../commons/commons.pri)
diff --git a/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp b/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp
new file mode 100644
index 000000000..7a5648271
--- /dev/null
+++ b/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Paul Lemire
+** 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 <Qt3DCore/qentity.h>
+#include <Qt3DCore/qtransform.h>
+#include <Qt3DRender/private/nodemanagers_p.h>
+#include <Qt3DRender/private/managers_p.h>
+#include <Qt3DRender/private/entity_p.h>
+#include <Qt3DRender/private/filterproximitydistancejob_p.h>
+#include <Qt3DRender/private/updatetreeenabledjob_p.h>
+#include <Qt3DRender/qproximityfilter.h>
+
+#include "testaspect.h"
+
+namespace {
+
+Qt3DCore::QEntity *buildEntityAtDistance(float distance, Qt3DCore::QEntity *parent)
+{
+ Qt3DCore::QEntity *entity = new Qt3DCore::QEntity(parent);
+ Qt3DCore::QTransform *transform = new Qt3DCore::QTransform(parent);
+ const QVector3D t = QVector3D(1.0f, 0.0f, 0.0f) * distance;
+
+ transform->setTranslation(t);
+ entity->addComponent(transform);
+
+ return entity;
+}
+
+} // anonymous
+
+class tst_ProximityFiltering : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+
+ void checkInitialState()
+ {
+ // GIVEN
+ Qt3DRender::Render::FilterProximityDistanceJob filterJob;
+
+ // THEN
+ QCOMPARE(filterJob.hasProximityFilter(), false);
+ QCOMPARE(filterJob.filteredEntities().size(), 0);
+ QCOMPARE(filterJob.proximityFilterIds().size(), 0);
+ QVERIFY(filterJob.manager() == nullptr);
+ }
+
+ void filterEntities_data()
+ {
+ QTest::addColumn<Qt3DCore::QEntity *>("entitySubtree");
+ QTest::addColumn<Qt3DCore::QNodeIdVector>("proximityFilterIds");
+ QTest::addColumn<Qt3DCore::QNodeIdVector>("expectedSelectedEntities");
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+
+ QTest::newRow("ShouldSelectAll") << rootEntity
+ << Qt3DCore::QNodeIdVector()
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << childEntity1->id()
+ << childEntity2->id()
+ << childEntity3->id()
+ );
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *childEntity1 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity2 = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity3 = new Qt3DCore::QEntity(rootEntity);
+ Q_UNUSED(childEntity1);
+ Q_UNUSED(childEntity2);
+ Q_UNUSED(childEntity3);
+
+ Qt3DRender::QProximityFilter *proximityFilter = new Qt3DRender::QProximityFilter(rootEntity);
+
+ QTest::newRow("ShouldSelectNone") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << proximityFilter->id())
+ << (Qt3DCore::QNodeIdVector());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *targetEntity = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity1 = buildEntityAtDistance(50.0f, rootEntity);
+ Qt3DCore::QEntity *childEntity2 = buildEntityAtDistance(25.0f, rootEntity);
+ Qt3DCore::QEntity *childEntity3 = buildEntityAtDistance(75.0f, rootEntity);
+ Qt3DRender::QProximityFilter *proximityFilter = new Qt3DRender::QProximityFilter(rootEntity);
+ proximityFilter->setDistanceThreshold(30.0f);
+
+ // Note: rootEntity BoundingSphere will be centered in vec3(75.0f / 2.0, 0.0f 0.0f);
+
+ // Note: we cannot set rootEntity here as that would mean
+ // that the parent of the root would then be the proximity filter
+ // (since rootEntity has no parent) but this isn't valid in the way
+ // we have build the test
+ // Also rootEntity is centered based on the size of the child it contains
+ proximityFilter->setEntity(targetEntity);
+
+ Q_UNUSED(childEntity1);
+ Q_UNUSED(childEntity3);
+
+ QTest::newRow("ShouldSelectChild2") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << proximityFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << targetEntity->id()
+ << childEntity2->id()
+ );
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *targetEntity = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity1 = buildEntityAtDistance(50.0f, rootEntity);
+ Qt3DCore::QEntity *childEntity2 = buildEntityAtDistance(25.0f, rootEntity);
+ Qt3DCore::QEntity *childEntity3 = buildEntityAtDistance(49.9f, rootEntity);
+ Qt3DRender::QProximityFilter *proximityFilter = new Qt3DRender::QProximityFilter(rootEntity);
+ proximityFilter->setDistanceThreshold(50.0f);
+
+ // Note: rootEntity BoundingSphere will be centered in vec3(50.0f / 2.0, 0.0f 0.0f);
+
+ // Note: we cannot set rootEntity here as that would mean
+ // that the parent of the root would then be the proximity filter
+ // (since rootEntity has no parent) but this isn't valid in the way
+ // we have build the test
+ // Also rootEntity is centered based on the size of the child it contains
+ proximityFilter->setEntity(targetEntity);
+
+ QTest::newRow("ShouldSelectRootChild123") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << proximityFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << rootEntity->id()
+ << targetEntity->id()
+ << childEntity1->id()
+ << childEntity2->id()
+ << childEntity3->id()
+ );
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *targetEntity = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity1 = buildEntityAtDistance(51.0f, rootEntity);
+ Qt3DCore::QEntity *childEntity2 = buildEntityAtDistance(75.0f, rootEntity);
+ Qt3DCore::QEntity *childEntity3 = buildEntityAtDistance(883.0f, rootEntity);
+ Qt3DRender::QProximityFilter *proximityFilter = new Qt3DRender::QProximityFilter(rootEntity);
+ proximityFilter->setDistanceThreshold(50.0f);
+
+ // Note: rootEntity BoundingSphere will be centered in vec3(883.0f / 2.0, 0.0f 0.0f);
+
+ // Note: we cannot set rootEntity here as that would mean
+ // that the parent of the root would then be the proximity filter
+ // (since rootEntity has no parent) but this isn't valid in the way
+ // we have build the test
+ // Also rootEntity is centered based on the size of the child it contains
+ proximityFilter->setEntity(targetEntity);
+
+ Q_UNUSED(childEntity1);
+ Q_UNUSED(childEntity2);
+ Q_UNUSED(childEntity3);
+
+ QTest::newRow("ShouldSelectNoneButTarget") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << proximityFilter->id())
+ << (Qt3DCore::QNodeIdVector() << targetEntity->id());
+ }
+
+ {
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
+ Qt3DCore::QEntity *targetEntity = new Qt3DCore::QEntity(rootEntity);
+ Qt3DCore::QEntity *childEntity1 = buildEntityAtDistance(50.0f, rootEntity);
+ Qt3DCore::QEntity *childEntity2 = buildEntityAtDistance(150.0f, rootEntity);
+ Qt3DCore::QEntity *childEntity3 = buildEntityAtDistance(25.0f, rootEntity);
+
+ Qt3DRender::QProximityFilter *proximityFilter = new Qt3DRender::QProximityFilter(rootEntity);
+ proximityFilter->setDistanceThreshold(50.0f);
+
+ Qt3DRender::QProximityFilter *proximityFilter2 = new Qt3DRender::QProximityFilter(rootEntity);
+ proximityFilter2->setDistanceThreshold(30.0f);
+
+ // Note: rootEntity BoundingSphere will be centered in vec3(150.0f / 2.0, 0.0f 0.0f);
+
+ // Note: we cannot set rootEntity here as that would mean
+ // that the parent of the root would then be the proximity filter
+ // (since rootEntity has no parent) but this isn't valid in the way
+ // we have build the test
+ // Also rootEntity is centered based on the size of the child it contains
+ proximityFilter->setEntity(targetEntity);
+ proximityFilter2->setEntity(targetEntity);
+
+ Q_UNUSED(childEntity2);
+
+ QTest::newRow("Nested-Step1") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << proximityFilter->id())
+ << (Qt3DCore::QNodeIdVector()
+ << targetEntity->id()
+ << childEntity1->id()
+ << childEntity3->id()
+ );
+ QTest::newRow("Nested-Step2") << rootEntity
+ << (Qt3DCore::QNodeIdVector() << proximityFilter->id() << proximityFilter2->id())
+ << (Qt3DCore::QNodeIdVector()
+ << targetEntity->id()
+ << childEntity3->id()
+ );
+ }
+ }
+
+ void filterEntities()
+ {
+ QFETCH(Qt3DCore::QEntity *, entitySubtree);
+ QFETCH(Qt3DCore::QNodeIdVector, proximityFilterIds);
+ QFETCH(Qt3DCore::QNodeIdVector, expectedSelectedEntities);
+
+ // GIVEN
+ QScopedPointer<Qt3DRender::TestAspect> aspect(new Qt3DRender::TestAspect(entitySubtree));
+
+ // WHEN
+ Qt3DRender::Render::Entity *backendRoot = aspect->nodeManagers()->renderNodesManager()->getOrCreateResource(entitySubtree->id());
+ Qt3DRender::Render::UpdateTreeEnabledJob updateTreeEnabledJob;
+ updateTreeEnabledJob.setRoot(backendRoot);
+ updateTreeEnabledJob.run();
+
+ Qt3DRender::Render::UpdateWorldTransformJob updateWorldTransform;
+ updateWorldTransform.setRoot(backendRoot);
+ updateWorldTransform.run();
+
+ Qt3DRender::Render::CalculateBoundingVolumeJob calcBVolume;
+ calcBVolume.setManagers(aspect->nodeManagers());
+ calcBVolume.setRoot(backendRoot);
+ calcBVolume.run();
+
+ Qt3DRender::Render::UpdateWorldBoundingVolumeJob updateWorldBVolume;
+ updateWorldBVolume.setManager(aspect->nodeManagers()->renderNodesManager());
+ updateWorldBVolume.run();
+
+ Qt3DRender::Render::ExpandBoundingVolumeJob expandBVolume;
+ expandBVolume.setRoot(backendRoot);
+ expandBVolume.run();
+
+ // WHEN
+ Qt3DRender::Render::FilterProximityDistanceJob filterJob;
+ filterJob.setProximityFilterIds(proximityFilterIds);
+ filterJob.setManager(aspect->nodeManagers());
+ filterJob.run();
+
+ // THEN
+ const QVector<Qt3DRender::Render::Entity *> filterEntities = filterJob.filteredEntities();
+ QCOMPARE(filterEntities.size(), expectedSelectedEntities.size());
+
+ for (auto i = 0, m = expectedSelectedEntities.size(); i < m; ++i)
+ QCOMPARE(filterEntities.at(i)->peerId(), expectedSelectedEntities.at(i));
+ }
+};
+
+QTEST_MAIN(tst_ProximityFiltering)
+
+#include "tst_proximityfiltering.moc"
diff --git a/tests/auto/render/qattribute/tst_qattribute.cpp b/tests/auto/render/qattribute/tst_qattribute.cpp
index 66854acdd..23532c435 100644
--- a/tests/auto/render/qattribute/tst_qattribute.cpp
+++ b/tests/auto/render/qattribute/tst_qattribute.cpp
@@ -58,6 +58,8 @@ private Q_SLOTS:
QCOMPARE(Qt3DRender::QAttribute::defaultColorAttributeName(), QStringLiteral("vertexColor"));
QCOMPARE(Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName(), QStringLiteral("vertexTexCoord"));
QCOMPARE(Qt3DRender::QAttribute::defaultTangentAttributeName(), QStringLiteral("vertexTangent"));
+ QCOMPARE(Qt3DRender::QAttribute::defaultJointIndicesAttributeName(), QStringLiteral("vertexJointIndices"));
+ QCOMPARE(Qt3DRender::QAttribute::defaultJointWeightsAttributeName(), QStringLiteral("vertexJointWeights"));
QCOMPARE(attribute.property("defaultPositionAttributeName").toString(),
Qt3DRender::QAttribute::defaultPositionAttributeName());
@@ -69,6 +71,10 @@ private Q_SLOTS:
Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName());
QCOMPARE(attribute.property("defaultTangentAttributeName").toString(),
Qt3DRender::QAttribute::defaultTangentAttributeName());
+ QCOMPARE(attribute.property("defaultJointIndicesAttributeName").toString(),
+ Qt3DRender::QAttribute::defaultJointIndicesAttributeName());
+ QCOMPARE(attribute.property("defaultJointWeightsAttributeName").toString(),
+ Qt3DRender::QAttribute::defaultJointWeightsAttributeName());
}
void checkCloning_data()
diff --git a/tests/auto/render/qblitframebuffer/qblitframebuffer.pro b/tests/auto/render/qblitframebuffer/qblitframebuffer.pro
new file mode 100644
index 000000000..219bad3d2
--- /dev/null
+++ b/tests/auto/render/qblitframebuffer/qblitframebuffer.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+
+TARGET = tst_qblitframebuffer
+
+QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qblitframebuffer.cpp
+
+include(../../core/common/common.pri)
diff --git a/tests/auto/render/qblitframebuffer/tst_qblitframebuffer.cpp b/tests/auto/render/qblitframebuffer/tst_qblitframebuffer.cpp
new file mode 100644
index 000000000..26ef936f6
--- /dev/null
+++ b/tests/auto/render/qblitframebuffer/tst_qblitframebuffer.cpp
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** 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 <Qt3DCore/private/qnode_p.h>
+#include <Qt3DCore/private/qscene_p.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+
+#include <Qt3DRender/QBlitFramebuffer>
+#include <Qt3DRender/private/qblitframebuffer_p.h>
+
+#include "testpostmanarbiter.h"
+
+class tst_QBlitFrameBuffer: public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QBlitFrameBuffer() : QObject()
+ {
+ qRegisterMetaType<Qt3DRender::QRenderTarget*>();
+ }
+
+private Q_SLOTS:
+
+ void checkCreationData_data()
+ {
+ QTest::addColumn<Qt3DRender::QBlitFramebuffer *>("blitFramebuffer");
+
+ Qt3DRender::QBlitFramebuffer *defaultConstructed = new Qt3DRender::QBlitFramebuffer();
+ Qt3DRender::QRenderTarget *sourceRenderTarget = new Qt3DRender::QRenderTarget();
+ Qt3DRender::QRenderTarget *destinationRenderTarget = new Qt3DRender::QRenderTarget();
+ defaultConstructed->setSource(sourceRenderTarget);
+ defaultConstructed->setDestination(destinationRenderTarget);
+ QTest::newRow("defaultConstructed") << defaultConstructed;
+ }
+
+ void checkInitialState()
+ {
+ // GIVEN
+ Qt3DRender::QBlitFramebuffer blitFramebuffer;
+
+ // THEN
+ QCOMPARE(blitFramebuffer.source(), nullptr);
+ QCOMPARE(blitFramebuffer.destination(), nullptr);
+ QCOMPARE(blitFramebuffer.sourceRect(), QRect());
+ QCOMPARE(blitFramebuffer.destinationRect(), QRect());
+ QCOMPARE(blitFramebuffer.sourceAttachmentPoint(), Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0);
+ QCOMPARE(blitFramebuffer.destinationAttachmentPoint(), Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0);
+ QCOMPARE(blitFramebuffer.interpolationMethod(), Qt3DRender::QBlitFramebuffer::Linear);
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ QFETCH(Qt3DRender::QBlitFramebuffer *, blitFramebuffer);
+
+ // WHEN
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(blitFramebuffer);
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges = creationChangeGenerator.creationChanges();
+
+ // THEN
+ QCOMPARE(creationChanges.size(), 1);
+
+ const Qt3DCore::QNodeCreatedChangePtr<Qt3DRender::QBlitFramebufferData> creationChangeData =
+ qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QBlitFramebufferData>>(creationChanges.first());
+ const Qt3DRender::QBlitFramebufferData &cloneData = creationChangeData->data;
+
+ // THEN
+ QCOMPARE(blitFramebuffer->id(), creationChangeData->subjectId());
+ QCOMPARE(blitFramebuffer->isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(blitFramebuffer->metaObject(), creationChangeData->metaObject());
+ QCOMPARE(blitFramebuffer->source()->id(), cloneData.m_sourceRenderTargetId);
+ QCOMPARE(blitFramebuffer->destination()->id(), cloneData.m_destinationRenderTargetId);
+ QCOMPARE(blitFramebuffer->sourceRect(), cloneData.m_sourceRect);
+ QCOMPARE(blitFramebuffer->destinationRect(), cloneData.m_destinationRect);
+ QCOMPARE(blitFramebuffer->sourceAttachmentPoint(), cloneData.m_sourceAttachmentPoint);
+ QCOMPARE(blitFramebuffer->destinationAttachmentPoint(), cloneData.m_destinationAttachmentPoint);
+
+
+ delete blitFramebuffer;
+ }
+
+ void checkPropertyUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ QScopedPointer<Qt3DRender::QBlitFramebuffer> blitFramebuffer(new Qt3DRender::QBlitFramebuffer());
+ arbiter.setArbiterOnNode(blitFramebuffer.data());
+
+ Qt3DRender::QRenderTarget *sourceRenderTarget = new Qt3DRender::QRenderTarget;
+ Qt3DRender::QRenderTarget *destinationRenderTarget = new Qt3DRender::QRenderTarget;
+
+ // sourceRenderTarget
+ // WHEN
+ blitFramebuffer->setSource(sourceRenderTarget);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "source");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), sourceRenderTarget->id());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // WHEN
+ blitFramebuffer->setSource(sourceRenderTarget);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+
+ // WHEN
+ blitFramebuffer->setSource(nullptr);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "source");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), Qt3DCore::QNodeId());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // destinationRenderTarget
+ // WHEN
+ blitFramebuffer->setDestination(destinationRenderTarget);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "destination");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), destinationRenderTarget->id());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // WHEN
+ blitFramebuffer->setDestination(destinationRenderTarget);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+
+ // WHEN
+ blitFramebuffer->setDestination(nullptr);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "destination");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), Qt3DCore::QNodeId());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // sourceRect
+ // WHEN
+ blitFramebuffer->setSourceRect(QRect(0,0,1,1));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "sourceRect");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<QRect>(), QRect(0,0,1,1)) ;
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // WHEN
+ blitFramebuffer->setSourceRect(QRect(0,0,1,1));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+
+ // WHEN
+ blitFramebuffer->setSourceRect(QRect());
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "sourceRect");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<QRect>(), QRect());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // destinationRect
+ blitFramebuffer->setDestinationRect(QRect(0,0,1,1));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "destinationRect");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<QRect>(), QRect(0,0,1,1)) ;
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // WHEN
+ blitFramebuffer->setDestinationRect(QRect(0,0,1,1));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+
+ // WHEN
+ blitFramebuffer->setDestinationRect(QRect());
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "destinationRect");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<QRect>(), QRect());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // sourceAttachmentPoint
+ // WHEN
+ blitFramebuffer->setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "sourceAttachmentPoint");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(), Qt3DRender::QRenderTargetOutput::Color1);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // WHEN
+ blitFramebuffer->setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+
+ // WHEN
+ blitFramebuffer->setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color0);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "sourceAttachmentPoint");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(), Qt3DRender::QRenderTargetOutput::Color0);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // destinationAttachmentPoint
+ // WHEN
+ blitFramebuffer->setDestinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "destinationAttachmentPoint");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(), Qt3DRender::QRenderTargetOutput::Color1);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // WHEN
+ blitFramebuffer->setDestinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+
+ // WHEN
+ blitFramebuffer->setDestinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color0);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "destinationAttachmentPoint");
+ QCOMPARE(change->subjectId(), blitFramebuffer->id());
+ QCOMPARE(change->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(), Qt3DRender::QRenderTargetOutput::Color0);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+};
+
+QTEST_MAIN(tst_QBlitFrameBuffer)
+
+#include "tst_qblitframebuffer.moc"
diff --git a/tests/auto/render/qbuffer/tst_qbuffer.cpp b/tests/auto/render/qbuffer/tst_qbuffer.cpp
index fdc25cbca..719c6229f 100644
--- a/tests/auto/render/qbuffer/tst_qbuffer.cpp
+++ b/tests/auto/render/qbuffer/tst_qbuffer.cpp
@@ -112,7 +112,6 @@ private Q_SLOTS:
QCOMPARE(buffer->metaObject(), creationChangeData->metaObject());
QCOMPARE(buffer->data(), cloneData.data);
QCOMPARE(buffer->usage(), cloneData.usage);
- QCOMPARE(buffer->type(), cloneData.type);
QCOMPARE(buffer->dataGenerator(), cloneData.functor);
QCOMPARE(buffer->isSyncData(), cloneData.syncData);
if (buffer->dataGenerator()) {
diff --git a/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp b/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp
index 94f720097..edd767ad9 100644
--- a/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp
+++ b/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp
@@ -88,6 +88,7 @@ private Q_SLOTS:
geometry1->setInstanceCount(1);
geometry1->setIndexOffset(0);
geometry1->setFirstInstance(55);
+ geometry1->setIndexBufferByteOffset(48);
geometry1->setRestartIndexValue(-1);
geometry1->setPrimitiveRestartEnabled(false);
geometry1->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);
@@ -101,6 +102,7 @@ private Q_SLOTS:
geometry2->setInstanceCount(200);
geometry2->setIndexOffset(58);
geometry2->setFirstInstance(10);
+ geometry2->setIndexBufferByteOffset(96);
geometry2->setRestartIndexValue(65535);
geometry2->setVertexCount(2056);
geometry2->setPrimitiveRestartEnabled(true);
@@ -134,6 +136,7 @@ private Q_SLOTS:
QCOMPARE(cloneData.vertexCount, geometryRenderer->vertexCount());
QCOMPARE(cloneData.indexOffset, geometryRenderer->indexOffset());
QCOMPARE(cloneData.firstInstance, geometryRenderer->firstInstance());
+ QCOMPARE(cloneData.indexBufferByteOffset, geometryRenderer->indexBufferByteOffset());
QCOMPARE(cloneData.restartIndexValue, geometryRenderer->restartIndexValue());
QCOMPARE(cloneData.primitiveRestart, geometryRenderer->primitiveRestartEnabled());
QCOMPARE(cloneData.primitiveType, geometryRenderer->primitiveType());
@@ -207,6 +210,19 @@ private Q_SLOTS:
arbiter.events.clear();
// WHEN
+ geometryRenderer->setIndexBufferByteOffset(91);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "indexBufferByteOffset");
+ QCOMPARE(change->value().value<int>(), 91);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+
+ // WHEN
geometryRenderer->setRestartIndexValue(65535);
QCoreApplication::processEvents();
diff --git a/tests/auto/render/qgraphicsapifilter/tst_qgraphicsapifilter.cpp b/tests/auto/render/qgraphicsapifilter/tst_qgraphicsapifilter.cpp
index ac6f79b3f..9e0cb8e57 100644
--- a/tests/auto/render/qgraphicsapifilter/tst_qgraphicsapifilter.cpp
+++ b/tests/auto/render/qgraphicsapifilter/tst_qgraphicsapifilter.cpp
@@ -36,6 +36,13 @@
class tst_QGraphicsApiFilter : public QObject
{
Q_OBJECT
+public:
+ tst_QGraphicsApiFilter() : QObject()
+ {
+ qRegisterMetaType<Qt3DRender::QGraphicsApiFilter::Api>();
+ qRegisterMetaType<Qt3DRender::QGraphicsApiFilter::OpenGLProfile>();
+ }
+
private Q_SLOTS:
void defaultConstruction()
{
diff --git a/tests/auto/render/qmesh/tst_qmesh.cpp b/tests/auto/render/qmesh/tst_qmesh.cpp
index 2122d7eb5..127371750 100644
--- a/tests/auto/render/qmesh/tst_qmesh.cpp
+++ b/tests/auto/render/qmesh/tst_qmesh.cpp
@@ -34,6 +34,7 @@
#include <QSignalSpy>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DCore/qnodecreatedchange.h>
#include "testpostmanarbiter.h"
@@ -121,9 +122,8 @@ private Q_SLOTS:
const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QGeometryRendererData>>(creationChanges.first());
const Qt3DRender::QGeometryRendererData cloneData = creationChangeData->data;
- Qt3DRender::MeshFunctor meshFunctor(mesh.source(), mesh.meshName());
-
- QVERIFY(meshFunctor == *cloneData.geometryFactory);
+ // Geometry factory is null until the engine becomes available
+ QVERIFY(cloneData.geometryFactory == nullptr);
QCOMPARE(mesh.id(), creationChangeData->subjectId());
QCOMPARE(mesh.isEnabled(), true);
QCOMPARE(mesh.isEnabled(), creationChangeData->isNodeEnabled());
@@ -158,6 +158,13 @@ private Q_SLOTS:
Qt3DRender::QMesh mesh;
arbiter.setArbiterOnNode(&mesh);
+ Qt3DCore::QAspectEngine *engine = reinterpret_cast<Qt3DCore::QAspectEngine*>(0xdeadbeef);
+ Qt3DCore::QScene *scene = new Qt3DCore::QScene(engine);
+ Qt3DCore::QNodePrivate *meshd = Qt3DCore::QNodePrivate::get(&mesh);
+ meshd->setScene(scene);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+
{
// WHEN
mesh.setSource(QUrl(QStringLiteral("qrc:/toyplane.obj")));
@@ -165,13 +172,15 @@ private Q_SLOTS:
// THEN
QCOMPARE(arbiter.events.size(), 1);
- auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ auto change = arbiter.events.last().staticCast<Qt3DCore::QPropertyUpdatedChange>();
QCOMPARE(change->propertyName(), "geometryFactory");
QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
- Qt3DRender::MeshFunctor meshFunctor(mesh.source());
Qt3DRender::QGeometryFactoryPtr factory = change->value().value<Qt3DRender::QGeometryFactoryPtr>();
- QVERIFY(meshFunctor == *factory);
+ QSharedPointer<Qt3DRender::MeshLoaderFunctor> meshFunctor = qSharedPointerCast<Qt3DRender::MeshLoaderFunctor>(factory);
+ QVERIFY(meshFunctor != nullptr);
+ QCOMPARE(meshFunctor->m_mesh, mesh.id());
+ QCOMPARE(meshFunctor->m_sourcePath, mesh.source());
arbiter.events.clear();
}
@@ -194,6 +203,13 @@ private Q_SLOTS:
Qt3DRender::QMesh mesh;
arbiter.setArbiterOnNode(&mesh);
+ Qt3DCore::QAspectEngine *engine = reinterpret_cast<Qt3DCore::QAspectEngine*>(0xdeadbeef);
+ Qt3DCore::QScene *scene = new Qt3DCore::QScene(engine);
+ Qt3DCore::QNodePrivate *meshd = Qt3DCore::QNodePrivate::get(&mesh);
+ meshd->setScene(scene);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+
{
// WHEN
mesh.setMeshName(QStringLiteral("Phil"));
@@ -205,9 +221,11 @@ private Q_SLOTS:
QCOMPARE(change->propertyName(), "geometryFactory");
QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
- Qt3DRender::MeshFunctor meshFunctor(QUrl(), mesh.meshName());
Qt3DRender::QGeometryFactoryPtr factory = change->value().value<Qt3DRender::QGeometryFactoryPtr>();
- QVERIFY(meshFunctor == *factory);
+ QSharedPointer<Qt3DRender::MeshLoaderFunctor> meshFunctor = qSharedPointerCast<Qt3DRender::MeshLoaderFunctor>(factory);
+ QVERIFY(meshFunctor != nullptr);
+ QCOMPARE(meshFunctor->m_mesh, mesh.id());
+ QCOMPARE(meshFunctor->m_meshName, mesh.meshName());
arbiter.events.clear();
}
diff --git a/tests/auto/render/qproximityfilter/qproximityfilter.pro b/tests/auto/render/qproximityfilter/qproximityfilter.pro
new file mode 100644
index 000000000..4a12e244f
--- /dev/null
+++ b/tests/auto/render/qproximityfilter/qproximityfilter.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qproximityfilter
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qproximityfilter.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/qproximityfilter/tst_qproximityfilter.cpp b/tests/auto/render/qproximityfilter/tst_qproximityfilter.cpp
new file mode 100644
index 000000000..890d6ee3e
--- /dev/null
+++ b/tests/auto/render/qproximityfilter/tst_qproximityfilter.cpp
@@ -0,0 +1,270 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Paul Lemire <paul.lemire350@gmail.com>
+** 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 <Qt3DRender/qproximityfilter.h>
+#include <Qt3DRender/private/qproximityfilter_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include <Qt3DCore/qentity.h>
+#include "testpostmanarbiter.h"
+
+class tst_QProximityFilter : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QProximityFilter() : QObject()
+ {
+ qRegisterMetaType<Qt3DCore::QEntity*>();
+ }
+
+private Q_SLOTS:
+
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DRender::QProximityFilter proximityFilter;
+
+ // THEN
+ QVERIFY(proximityFilter.entity() == nullptr);
+ QCOMPARE(proximityFilter.distanceThreshold(), 0.0f);
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DRender::QProximityFilter proximityFilter;
+
+ {
+ // WHEN
+ Qt3DCore::QEntity entity;
+
+ QSignalSpy spy(&proximityFilter, SIGNAL(entityChanged(Qt3DCore::QEntity *)));
+ Qt3DCore::QEntity *newValue = &entity;
+ proximityFilter.setEntity(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(proximityFilter.entity(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ proximityFilter.setEntity(newValue);
+
+ // THEN
+ QCOMPARE(proximityFilter.entity(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&proximityFilter, SIGNAL(distanceThresholdChanged(float)));
+ const float newValue = 883.0f;
+ proximityFilter.setDistanceThreshold(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(proximityFilter.distanceThreshold(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ proximityFilter.setDistanceThreshold(newValue);
+
+ // THEN
+ QCOMPARE(proximityFilter.distanceThreshold(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DRender::QProximityFilter proximityFilter;
+ Qt3DCore::QEntity entity;
+
+ proximityFilter.setEntity(&entity);
+ proximityFilter.setDistanceThreshold(1584.0f);
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&proximityFilter);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 2); // Entity creation change is the second change
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QProximityFilterData>>(creationChanges.first());
+ const Qt3DRender::QProximityFilterData cloneData = creationChangeData->data;
+
+ QCOMPARE(proximityFilter.entity()->id(), cloneData.entityId);
+ QCOMPARE(proximityFilter.distanceThreshold(), cloneData.distanceThreshold);
+ QCOMPARE(proximityFilter.id(), creationChangeData->subjectId());
+ QCOMPARE(proximityFilter.isEnabled(), true);
+ QCOMPARE(proximityFilter.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(proximityFilter.metaObject(), creationChangeData->metaObject());
+ }
+
+ // WHEN
+ proximityFilter.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&proximityFilter);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 2); // Entity creation change is the second change
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QProximityFilterData>>(creationChanges.first());
+ const Qt3DRender::QProximityFilterData cloneData = creationChangeData->data;
+
+ QCOMPARE(proximityFilter.entity()->id(), cloneData.entityId);
+ QCOMPARE(proximityFilter.distanceThreshold(), cloneData.distanceThreshold);
+ QCOMPARE(proximityFilter.id(), creationChangeData->subjectId());
+ QCOMPARE(proximityFilter.isEnabled(), false);
+ QCOMPARE(proximityFilter.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(proximityFilter.metaObject(), creationChangeData->metaObject());
+ }
+ }
+
+ void checkEntityUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QProximityFilter proximityFilter;
+ arbiter.setArbiterOnNode(&proximityFilter);
+ Qt3DCore::QEntity entity;
+
+ {
+ // WHEN
+ proximityFilter.setEntity(&entity);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "entity");
+ QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), proximityFilter.entity()->id());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ proximityFilter.setEntity(&entity);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkDistanceThresholdUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QProximityFilter proximityFilter;
+ arbiter.setArbiterOnNode(&proximityFilter);
+
+ {
+ // WHEN
+ proximityFilter.setDistanceThreshold(454.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "distanceThreshold");
+ QCOMPARE(change->value().value<float>(), proximityFilter.distanceThreshold());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ proximityFilter.setDistanceThreshold(454.0f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkEntityBookkeeping()
+ {
+ // GIVEN
+ QScopedPointer<Qt3DRender::QProximityFilter> proximityFilter(new Qt3DRender::QProximityFilter);
+ {
+ // WHEN
+ Qt3DCore::QEntity entity;
+ proximityFilter->setEntity(&entity);
+
+ // THEN
+ QCOMPARE(entity.parent(), proximityFilter.data());
+ QCOMPARE(proximityFilter->entity(), &entity);
+ }
+
+ // THEN (Should not crash and parameter be unset)
+ QVERIFY(proximityFilter->entity() == nullptr);
+
+ {
+ // WHEN
+ Qt3DRender::QProximityFilter someOtherProximityFilter;
+ QScopedPointer<Qt3DCore::QEntity> entity(new Qt3DCore::QEntity(&someOtherProximityFilter));
+ proximityFilter->setEntity(entity.data());
+
+ // THEN
+ QCOMPARE(entity->parent(), &someOtherProximityFilter);
+ QCOMPARE(proximityFilter->entity(), entity.data());
+
+ // WHEN
+ proximityFilter.reset();
+ entity.reset();
+
+ // THEN Should not crash when the camera is destroyed (tests for failed removal of destruction helper)
+ }
+ }
+};
+
+QTEST_MAIN(tst_QProximityFilter)
+
+#include "tst_qproximityfilter.moc"
diff --git a/tests/auto/render/qrendercapture/tst_qrendercapture.cpp b/tests/auto/render/qrendercapture/tst_qrendercapture.cpp
index d4e603ea4..830615a95 100644
--- a/tests/auto/render/qrendercapture/tst_qrendercapture.cpp
+++ b/tests/auto/render/qrendercapture/tst_qrendercapture.cpp
@@ -67,7 +67,7 @@ private Q_SLOTS:
arbiter.setArbiterOnNode(renderCapture.data());
// WHEN
- QScopedPointer<Qt3DRender::QRenderCaptureReply> reply(renderCapture->requestCapture());
+ QScopedPointer<Qt3DRender::QRenderCaptureReply> reply(renderCapture->requestCapture(QRect(10, 15, 20, 50)));
// THEN
QCOMPARE(arbiter.events.size(), 1);
@@ -75,7 +75,10 @@ private Q_SLOTS:
QCOMPARE(change->propertyName(), "renderCaptureRequest");
QCOMPARE(change->subjectId(),renderCapture->id());
QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
- QCOMPARE(change->value().toInt(), 1);
+ QVERIFY(change->value().canConvert<Qt3DRender::QRenderCaptureRequest>());
+ const Qt3DRender::QRenderCaptureRequest request = change->value().value<Qt3DRender::QRenderCaptureRequest>();
+ QCOMPARE(request.captureId, 1);
+ QCOMPARE(request.rect, QRect(10, 15, 20, 50));
arbiter.events.clear();
}
diff --git a/tests/auto/render/qrendersettings/tst_qrendersettings.cpp b/tests/auto/render/qrendersettings/tst_qrendersettings.cpp
index 1f0a9f066..6f182cbeb 100644
--- a/tests/auto/render/qrendersettings/tst_qrendersettings.cpp
+++ b/tests/auto/render/qrendersettings/tst_qrendersettings.cpp
@@ -184,6 +184,7 @@ private Q_SLOTS:
pickingSettings->setPickMethod(Qt3DRender::QPickingSettings::TrianglePicking);
pickingSettings->setPickResultMode(Qt3DRender::QPickingSettings::AllPicks);
pickingSettings->setFaceOrientationPickingMode(Qt3DRender::QPickingSettings::FrontAndBackFace);
+ pickingSettings->setWorldSpaceTolerance(5.f);
// WHEN
QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
@@ -203,6 +204,7 @@ private Q_SLOTS:
QCOMPARE(renderSettings.pickingSettings()->pickMethod(), cloneData.pickMethod);
QCOMPARE(renderSettings.pickingSettings()->pickResultMode(), cloneData.pickResultMode);
QCOMPARE(renderSettings.pickingSettings()->faceOrientationPickingMode(), cloneData.faceOrientationPickingMode);
+ QCOMPARE(renderSettings.pickingSettings()->worldSpaceTolerance(), cloneData.pickWorldSpaceTolerance);
QCOMPARE(renderSettings.renderPolicy(), cloneData.renderPolicy);
QCOMPARE(renderSettings.activeFrameGraph()->id(), cloneData.activeFrameGraphId);
QCOMPARE(renderSettings.id(), creationChangeData->subjectId());
@@ -410,6 +412,41 @@ private Q_SLOTS:
}
+ void checkWorldSpaceToleranceUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QRenderSettings renderSettings;
+ Qt3DRender::QPickingSettings *pickingSettings = renderSettings.pickingSettings();
+
+ arbiter.setArbiterOnNode(&renderSettings);
+
+ {
+ // WHEN
+ pickingSettings->setWorldSpaceTolerance(5.f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "pickWorldSpaceTolerance");
+ QCOMPARE(change->value().toFloat(), pickingSettings->worldSpaceTolerance());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ pickingSettings->setWorldSpaceTolerance(5.f);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
};
QTEST_MAIN(tst_QRenderSettings)
diff --git a/tests/auto/render/qshaderprogrambuilder/qshaderprogrambuilder.pro b/tests/auto/render/qshaderprogrambuilder/qshaderprogrambuilder.pro
new file mode 100644
index 000000000..32fe88e9f
--- /dev/null
+++ b/tests/auto/render/qshaderprogrambuilder/qshaderprogrambuilder.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qshaderprogrambuilder
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qshaderprogrambuilder.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp
new file mode 100644
index 000000000..93bee22cc
--- /dev/null
+++ b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp
@@ -0,0 +1,601 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** 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 <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qshaderprogrambuilder.h>
+#include <Qt3DRender/private/qshaderprogrambuilder_p.h>
+#include <QObject>
+#include <QSignalSpy>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <Qt3DCore/qnodecreatedchange.h>
+#include "testpostmanarbiter.h"
+
+class tst_QShaderProgramBuilder : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QShaderProgramBuilder()
+ : QObject()
+ {
+ qRegisterMetaType<Qt3DRender::QShaderProgram*>("Qt3DRender::QShaderProgram*");
+ }
+
+private Q_SLOTS:
+ void checkDefaultConstruction()
+ {
+ // GIVEN
+ Qt3DRender::QShaderProgramBuilder builder;
+
+ // THEN
+ QVERIFY(!builder.shaderProgram());
+ QVERIFY(builder.enabledLayers().isEmpty());
+ QCOMPARE(builder.vertexShaderGraph(), QUrl());
+ QCOMPARE(builder.tessellationControlShaderGraph(), QUrl());
+ QCOMPARE(builder.tessellationEvaluationShaderGraph(), QUrl());
+ QCOMPARE(builder.geometryShaderGraph(), QUrl());
+ QCOMPARE(builder.fragmentShaderGraph(), QUrl());
+ QCOMPARE(builder.computeShaderGraph(), QUrl());
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ Qt3DRender::QShaderProgramBuilder builder;
+
+ {
+ // WHEN
+ QSignalSpy spy(&builder, SIGNAL(shaderProgramChanged(Qt3DRender::QShaderProgram*)));
+ auto newValue = new Qt3DRender::QShaderProgram(&builder);
+ builder.setShaderProgram(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(builder.shaderProgram(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ builder.setShaderProgram(newValue);
+
+ // THEN
+ QCOMPARE(builder.shaderProgram(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&builder, SIGNAL(enabledLayersChanged(QStringList)));
+ const auto newValue = QStringList() << "foo" << "bar";
+ builder.setEnabledLayers(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(builder.enabledLayers(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ builder.setEnabledLayers(newValue);
+
+ // THEN
+ QCOMPARE(builder.enabledLayers(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&builder, SIGNAL(vertexShaderGraphChanged(QUrl)));
+ const auto newValue = QUrl::fromEncoded("qrc:/vertex.json");
+ builder.setVertexShaderGraph(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(builder.vertexShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ builder.setVertexShaderGraph(newValue);
+
+ // THEN
+ QCOMPARE(builder.vertexShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&builder, SIGNAL(tessellationControlShaderGraphChanged(QUrl)));
+ const auto newValue = QUrl::fromEncoded("qrc:/tesscontrol.json");
+ builder.setTessellationControlShaderGraph(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(builder.tessellationControlShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ builder.setTessellationControlShaderGraph(newValue);
+
+ // THEN
+ QCOMPARE(builder.tessellationControlShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&builder, SIGNAL(tessellationEvaluationShaderGraphChanged(QUrl)));
+ const auto newValue = QUrl::fromEncoded("qrc:/tesseval.json");
+ builder.setTessellationEvaluationShaderGraph(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(builder.tessellationEvaluationShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ builder.setTessellationEvaluationShaderGraph(newValue);
+
+ // THEN
+ QCOMPARE(builder.tessellationEvaluationShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&builder, SIGNAL(geometryShaderGraphChanged(QUrl)));
+ const auto newValue = QUrl::fromEncoded("qrc:/geometry.json");
+ builder.setGeometryShaderGraph(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(builder.geometryShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ builder.setGeometryShaderGraph(newValue);
+
+ // THEN
+ QCOMPARE(builder.geometryShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&builder, SIGNAL(fragmentShaderGraphChanged(QUrl)));
+ const auto newValue = QUrl::fromEncoded("qrc:/fragment.json");
+ builder.setFragmentShaderGraph(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(builder.fragmentShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ builder.setFragmentShaderGraph(newValue);
+
+ // THEN
+ QCOMPARE(builder.fragmentShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ {
+ // WHEN
+ QSignalSpy spy(&builder, SIGNAL(computeShaderGraphChanged(QUrl)));
+ const auto newValue = QUrl::fromEncoded("qrc:/compute.json");
+ builder.setComputeShaderGraph(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(builder.computeShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ builder.setComputeShaderGraph(newValue);
+
+ // THEN
+ QCOMPARE(builder.computeShaderGraph(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ }
+
+ void checkShaderProgramBookkeeping()
+ {
+ // GIVEN
+ QScopedPointer<Qt3DRender::QShaderProgramBuilder> builder(new Qt3DRender::QShaderProgramBuilder);
+ {
+ // WHEN
+ Qt3DRender::QShaderProgram program;
+ builder->setShaderProgram(&program);
+
+ // THEN
+ QCOMPARE(program.parent(), builder.data());
+ QCOMPARE(builder->shaderProgram(), &program);
+ }
+ // THEN (Should not crash and effect be unset)
+ QVERIFY(!builder->shaderProgram());
+
+ {
+ // WHEN
+ Qt3DRender::QShaderProgramBuilder someOtherBuilder;
+ QScopedPointer<Qt3DRender::QShaderProgram> program(new Qt3DRender::QShaderProgram(&someOtherBuilder));
+ builder->setShaderProgram(program.data());
+
+ // THEN
+ QCOMPARE(program->parent(), &someOtherBuilder);
+ QCOMPARE(builder->shaderProgram(), program.data());
+
+ // WHEN
+ builder.reset();
+ program.reset();
+
+ // THEN Should not crash when the effect is destroyed (tests for failed removal of destruction helper)
+ }
+ }
+
+ void checkCreationData()
+ {
+ // GIVEN
+ Qt3DRender::QShaderProgramBuilder builder;
+
+ builder.setShaderProgram(new Qt3DRender::QShaderProgram(&builder));
+ builder.setEnabledLayers({"foo", "bar"});
+ builder.setVertexShaderGraph(QUrl::fromEncoded("qrc:/vertex.json"));
+ builder.setTessellationControlShaderGraph(QUrl::fromEncoded("qrc:/tesscontrol.json"));
+ builder.setTessellationEvaluationShaderGraph(QUrl::fromEncoded("qrc:/tesseval.json"));
+ builder.setGeometryShaderGraph(QUrl::fromEncoded("qrc:/geometry.json"));
+ builder.setFragmentShaderGraph(QUrl::fromEncoded("qrc:/fragment.json"));
+ builder.setComputeShaderGraph(QUrl::fromEncoded("qrc:/compute.json"));
+
+ // WHEN
+ QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&builder);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 2); // second one is for the shader program child
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QShaderProgramBuilderData>>(creationChanges.first());
+ const Qt3DRender::QShaderProgramBuilderData cloneData = creationChangeData->data;
+
+ QCOMPARE(builder.shaderProgram()->id(), cloneData.shaderProgramId);
+ QCOMPARE(builder.enabledLayers(), cloneData.enabledLayers);
+ QCOMPARE(builder.vertexShaderGraph(), cloneData.vertexShaderGraph);
+ QCOMPARE(builder.tessellationControlShaderGraph(), cloneData.tessellationControlShaderGraph);
+ QCOMPARE(builder.tessellationEvaluationShaderGraph(), cloneData.tessellationEvaluationShaderGraph);
+ QCOMPARE(builder.geometryShaderGraph(), cloneData.geometryShaderGraph);
+ QCOMPARE(builder.fragmentShaderGraph(), cloneData.fragmentShaderGraph);
+ QCOMPARE(builder.computeShaderGraph(), cloneData.computeShaderGraph);
+ QCOMPARE(builder.id(), creationChangeData->subjectId());
+ QCOMPARE(builder.isEnabled(), true);
+ QCOMPARE(builder.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(builder.metaObject(), creationChangeData->metaObject());
+ }
+
+ // WHEN
+ builder.setEnabled(false);
+
+ {
+ Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&builder);
+ creationChanges = creationChangeGenerator.creationChanges();
+ }
+
+ // THEN
+ {
+ QCOMPARE(creationChanges.size(), 2); // second one is for the shader program child
+
+ const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QShaderProgramBuilderData>>(creationChanges.first());
+ const Qt3DRender::QShaderProgramBuilderData cloneData = creationChangeData->data;
+
+ QCOMPARE(builder.shaderProgram()->id(), cloneData.shaderProgramId);
+ QCOMPARE(builder.enabledLayers(), cloneData.enabledLayers);
+ QCOMPARE(builder.vertexShaderGraph(), cloneData.vertexShaderGraph);
+ QCOMPARE(builder.tessellationControlShaderGraph(), cloneData.tessellationControlShaderGraph);
+ QCOMPARE(builder.tessellationEvaluationShaderGraph(), cloneData.tessellationEvaluationShaderGraph);
+ QCOMPARE(builder.geometryShaderGraph(), cloneData.geometryShaderGraph);
+ QCOMPARE(builder.fragmentShaderGraph(), cloneData.fragmentShaderGraph);
+ QCOMPARE(builder.computeShaderGraph(), cloneData.computeShaderGraph);
+ QCOMPARE(builder.id(), creationChangeData->subjectId());
+ QCOMPARE(builder.isEnabled(), false);
+ QCOMPARE(builder.isEnabled(), creationChangeData->isNodeEnabled());
+ QCOMPARE(builder.metaObject(), creationChangeData->metaObject());
+ }
+ }
+
+ void checkShaderProgramUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QShaderProgramBuilder builder;
+ arbiter.setArbiterOnNode(&builder);
+ auto program = new Qt3DRender::QShaderProgram(&builder);
+
+ {
+ // WHEN
+ builder.setShaderProgram(program);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "shaderProgram");
+ QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), builder.shaderProgram()->id());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ builder.setShaderProgram(program);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+
+ void checkEnabledLayersUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QShaderProgramBuilder builder;
+ arbiter.setArbiterOnNode(&builder);
+ const auto layers = QStringList() << "foo" << "bar";
+
+ {
+ // WHEN
+ builder.setEnabledLayers(layers);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "enabledLayers");
+ QCOMPARE(change->value().toStringList(), layers);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ builder.setEnabledLayers(layers);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+
+ void checkVertexShaderGraphUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QShaderProgramBuilder builder;
+ arbiter.setArbiterOnNode(&builder);
+
+ {
+ // WHEN
+ builder.setVertexShaderGraph(QUrl::fromEncoded("qrc:/vertex.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "vertexShaderGraph");
+ QCOMPARE(change->value().value<QUrl>(), builder.vertexShaderGraph());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ builder.setVertexShaderGraph(QUrl::fromEncoded("qrc:/vertex.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkTessellationControlShaderGraphUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QShaderProgramBuilder builder;
+ arbiter.setArbiterOnNode(&builder);
+
+ {
+ // WHEN
+ builder.setTessellationControlShaderGraph(QUrl::fromEncoded("qrc:/tesscontrol.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "tessellationControlShaderGraph");
+ QCOMPARE(change->value().value<QUrl>(), builder.tessellationControlShaderGraph());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ builder.setTessellationControlShaderGraph(QUrl::fromEncoded("qrc:/tesscontrol.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkTessellationEvaluationShaderGraphUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QShaderProgramBuilder builder;
+ arbiter.setArbiterOnNode(&builder);
+
+ {
+ // WHEN
+ builder.setTessellationEvaluationShaderGraph(QUrl::fromEncoded("qrc:/tesseval.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "tessellationEvaluationShaderGraph");
+ QCOMPARE(change->value().value<QUrl>(), builder.tessellationEvaluationShaderGraph());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ builder.setTessellationEvaluationShaderGraph(QUrl::fromEncoded("qrc:/tesseval.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkGeometryShaderGraphUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QShaderProgramBuilder builder;
+ arbiter.setArbiterOnNode(&builder);
+
+ {
+ // WHEN
+ builder.setGeometryShaderGraph(QUrl::fromEncoded("qrc:/geometry.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "geometryShaderGraph");
+ QCOMPARE(change->value().value<QUrl>(), builder.geometryShaderGraph());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ builder.setGeometryShaderGraph(QUrl::fromEncoded("qrc:/geometry.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkFragmentShaderGraphUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QShaderProgramBuilder builder;
+ arbiter.setArbiterOnNode(&builder);
+
+ {
+ // WHEN
+ builder.setFragmentShaderGraph(QUrl::fromEncoded("qrc:/fragment.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "fragmentShaderGraph");
+ QCOMPARE(change->value().value<QUrl>(), builder.fragmentShaderGraph());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ builder.setFragmentShaderGraph(QUrl::fromEncoded("qrc:/fragment.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+
+ void checkComputeShaderGraphUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QShaderProgramBuilder builder;
+ arbiter.setArbiterOnNode(&builder);
+
+ {
+ // WHEN
+ builder.setComputeShaderGraph(QUrl::fromEncoded("qrc:/compute.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "computeShaderGraph");
+ QCOMPARE(change->value().value<QUrl>(), builder.computeShaderGraph());
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ builder.setComputeShaderGraph(QUrl::fromEncoded("qrc:/compute.json"));
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ }
+};
+
+QTEST_MAIN(tst_QShaderProgramBuilder)
+
+#include "tst_qshaderprogrambuilder.moc"
diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro
index 5a82ee835..32a7b35fc 100644
--- a/tests/auto/render/render.pro
+++ b/tests/auto/render/render.pro
@@ -7,13 +7,13 @@ qtConfig(private_tests) {
renderpass \
qgraphicsutils \
shader \
+ shaderbuilder \
texture \
renderviewutils \
renderviews \
material \
vsyncframeadvanceservice \
meshfunctors \
- qmaterial \
qattribute \
qbuffer \
qgeometry \
@@ -23,7 +23,6 @@ qtConfig(private_tests) {
buffer \
attribute \
geometry \
- geometryloaders \
geometryrenderer \
raycasting \
qcameraselector \
@@ -44,11 +43,8 @@ qtConfig(private_tests) {
framegraphnode \
qobjectpicker \
objectpicker \
- picking \
# qboundingvolumedebug \
# boundingvolumedebug \
- boundingsphere \
- qdefaultmeshes \
trianglesextractor \
triangleboundingvolume \
ddstextures \
@@ -70,8 +66,6 @@ qtConfig(private_tests) {
graphicshelpergl3_3 \
graphicshelpergl3_2 \
graphicshelpergl2 \
- gltfplugins \
- pickboundingvolumejob \
sendrendercapturejob \
textures \
qparameter \
@@ -81,8 +75,6 @@ qtConfig(private_tests) {
qabstracttexture \
qabstracttextureimage \
qrendersettings \
- updatemeshtrianglelistjob \
- updateshaderdatatransformjob \
texturedatamanager \
rendertarget \
transform \
@@ -101,14 +93,43 @@ qtConfig(private_tests) {
renderviewbuilder \
filtercompatibletechniquejob \
rendercapture \
+ segmentvisitor \
trianglevisitor \
qmemorybarrier \
memorybarrier \
qshaderprogram \
- qscene2d \
- scene2d \
+ qshaderprogrambuilder \
coordinatereader \
- framegraphvisitor
+ framegraphvisitor \
+ renderer \
+ armature \
+ skeleton \
+ joint \
+ qproximityfilter \
+ proximityfilter \
+ proximityfiltering \
+ qblitframebuffer \
+ blitframebuffer
+
+ QT_FOR_CONFIG = 3dcore-private
+ qtConfig(qt3d-extras) {
+ SUBDIRS += \
+ qmaterial \
+ geometryloaders \
+ picking \
+ boundingsphere \
+ qdefaultmeshes \
+ pickboundingvolumejob \
+ gltfplugins \
+ updatemeshtrianglelistjob \
+ updateshaderdatatransformjob
+ }
+
+ qtConfig(qt3d-input) {
+ SUBDIRS += \
+ qscene2d \
+ scene2d
+ }
!macos: SUBDIRS += graphicshelpergl4
}
diff --git a/tests/auto/render/rendercapture/tst_rendercapture.cpp b/tests/auto/render/rendercapture/tst_rendercapture.cpp
index 4029ba136..799a7ccff 100644
--- a/tests/auto/render/rendercapture/tst_rendercapture.cpp
+++ b/tests/auto/render/rendercapture/tst_rendercapture.cpp
@@ -90,7 +90,7 @@ private Q_SLOTS:
QCOMPARE(renderCapture.wasCaptureRequested(), true);
}
- void checkAcknowledgeCaptureRequest()
+ void checkTakeCaptureRequest()
{
// GIVEN
Qt3DRender::Render::RenderCapture renderCapture;
@@ -99,22 +99,26 @@ private Q_SLOTS:
renderCapture.setEnabled(true);
// WHEN
- renderCapture.requestCapture(2);
- renderCapture.requestCapture(4);
+ renderCapture.requestCapture({ 2, QRect(10, 10, 20, 20) });
+ renderCapture.requestCapture({ 4, QRect(15, 15, 30, 30) });
// THEN
QCOMPARE(renderCapture.wasCaptureRequested(), true);
// WHEN
- renderCapture.acknowledgeCaptureRequest();
+ Qt3DRender::QRenderCaptureRequest r1 = renderCapture.takeCaptureRequest();
// THEN
+ QCOMPARE(r1.captureId, 2);
+ QCOMPARE(r1.rect, QRect(10, 10, 20, 20));
QCOMPARE(renderCapture.wasCaptureRequested(), true);
// WHEN
- renderCapture.acknowledgeCaptureRequest();
+ Qt3DRender::QRenderCaptureRequest r2 = renderCapture.takeCaptureRequest();
// THEN
+ QCOMPARE(r2.captureId, 4);
+ QCOMPARE(r2.rect, QRect(15, 15, 30, 30));
QCOMPARE(renderCapture.wasCaptureRequested(), false);
}
};
diff --git a/tests/auto/render/renderer/renderer.pro b/tests/auto/render/renderer/renderer.pro
new file mode 100644
index 000000000..cbafc156b
--- /dev/null
+++ b/tests/auto/render/renderer/renderer.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+
+TARGET = tst_renderer
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_renderer.cpp
diff --git a/tests/auto/render/renderer/tst_renderer.cpp b/tests/auto/render/renderer/tst_renderer.cpp
new file mode 100644
index 000000000..85d978926
--- /dev/null
+++ b/tests/auto/render/renderer/tst_renderer.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** 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/QtTest>
+#include <QMutex>
+#include <QWaitCondition>
+#include <QThread>
+#include <Qt3DRender/private/renderer_p.h>
+#include <Qt3DRender/private/viewportnode_p.h>
+#include <Qt3DRender/private/renderview_p.h>
+#include <Qt3DRender/private/renderviewbuilder_p.h>
+
+class tst_Renderer : public QObject
+{
+ Q_OBJECT
+public :
+ tst_Renderer() {}
+ ~tst_Renderer() {}
+
+private Q_SLOTS:
+ void checkRenderBinJobs()
+ {
+ // GIVEN
+ Qt3DRender::Render::NodeManagers nodeManagers;
+ Qt3DRender::Render::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
+ Qt3DRender::Render::RenderSettings settings;
+ // owned by FG manager
+ Qt3DRender::Render::ViewportNode *fgRoot = new Qt3DRender::Render::ViewportNode();
+ const Qt3DCore::QNodeId fgRootId = Qt3DCore::QNodeId::createId();
+
+ nodeManagers.frameGraphManager()->appendNode(fgRootId, fgRoot);
+ settings.setActiveFrameGraphId(fgRootId);
+
+ renderer.setNodeManagers(&nodeManagers);
+ renderer.setSettings(&settings);
+ renderer.initialize();
+
+ const int singleRenderViewJobCount = 11 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount();
+ // RenderViewBuilder renderViewJob,
+ // renderableEntityFilterJob,
+ // lightGatherJob,
+ // computableEntityFilterJob,
+ // syncRenderViewInitializationJob,
+ // syncFrustumCullingJob,
+ // filterEntityByLayerJob,
+ // filterProximityJob,
+ // setClearDrawBufferIndexJob,
+ // frustumCullingJob,
+ // syncRenderCommandBuldingJob,
+ // syncRenderViewCommandBuilderJob)
+ // n * (RenderViewCommandBuildJobs + MaterialGathererJobs
+
+ // WHEN (nothing dirty, no buffers)
+ QVector<Qt3DCore::QAspectJobPtr> jobs = renderer.renderBinJobs();
+
+ // THEN (level
+ QCOMPARE(jobs.size(),
+ 1 + // updateLevelOfDetailJob
+ 1 + // cleanupJob
+ 1 + // sendRenderCaptureJob
+ 1 + // sendBufferCaptureJob
+ 1 + // filterCompatibleTechniquesJob
+ 1 + // VAOGatherer
+ 1 + // updateSkinningPaletteJob
+ singleRenderViewJobCount); // Only valid for the first call to renderBinJobs(), since subsequent calls won't have the renderqueue reset
+
+
+ // WHEN
+ renderer.markDirty(Qt3DRender::Render::AbstractRenderer::EntityEnabledDirty, nullptr);
+ jobs = renderer.renderBinJobs();
+
+ // THEN (level
+ QCOMPARE(jobs.size(),
+ 1 + // updateLevelOfDetailJob
+ 1 + // cleanupJob
+ 1 + // sendRenderCaptureJob
+ 1 + // sendBufferCaptureJob
+ 1 + // filterCompatibleTechniquesJob
+ 1 + // VAOGatherer
+ 1 + // updateSkinningPaletteJob
+ 1); // EntityEnabledDirty
+
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+ // WHEN
+ renderer.markDirty(Qt3DRender::Render::AbstractRenderer::TransformDirty, nullptr);
+ jobs = renderer.renderBinJobs();
+
+ // THEN (level
+ QCOMPARE(jobs.size(),
+ 1 + // updateLevelOfDetailJob
+ 1 + // cleanupJob
+ 1 + // sendRenderCaptureJob
+ 1 + // sendBufferCaptureJob
+ 1 + // filterCompatibleTechniquesJob
+ 1 + // VAOGatherer
+ 1 + // WorldTransformJob
+ 1 + // UpdateWorldBoundingVolume
+ 1 + // UpdateShaderDataTransform
+ 1 + // updateSkinningPaletteJob
+ 1); // ExpandBoundingVolumeJob
+
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+ // WHEN
+ renderer.markDirty(Qt3DRender::Render::AbstractRenderer::GeometryDirty, nullptr);
+ jobs = renderer.renderBinJobs();
+
+ // THEN (level
+ QCOMPARE(jobs.size(),
+ 1 + // updateLevelOfDetailJob
+ 1 + // cleanupJob
+ 1 + // sendRenderCaptureJob
+ 1 + // sendBufferCaptureJob
+ 1 + // filterCompatibleTechniquesJob
+ 1 + // VAOGatherer
+ 1 + // CalculateBoundingVolumeJob
+ 1 + // UpdateMeshTriangleListJob
+ 1 + // updateSkinningPaletteJob
+ 1); // ExpandBoundingVolumeJob
+
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+ // WHEN
+ renderer.markDirty(Qt3DRender::Render::AbstractRenderer::BuffersDirty, nullptr);
+ jobs = renderer.renderBinJobs();
+
+ // THEN (level
+ QCOMPARE(jobs.size(),
+ 1 + // updateLevelOfDetailJob
+ 1 + // cleanupJob
+ 1 + // sendRenderCaptureJob
+ 1 + // sendBufferCaptureJob
+ 1 + // filterCompatibleTechniquesJob
+ 1 + // VAOGatherer
+ 1 + // updateSkinningPaletteJob
+ 1); // BufferGathererJob
+
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+ // WHEN
+ renderer.markDirty(Qt3DRender::Render::AbstractRenderer::ShadersDirty, nullptr);
+ jobs = renderer.renderBinJobs();
+
+ // THEN (level
+ QCOMPARE(jobs.size(),
+ 1 + // updateLevelOfDetailJob
+ 1 + // cleanupJob
+ 1 + // sendRenderCaptureJob
+ 1 + // sendBufferCaptureJob
+ 1 + // filterCompatibleTechniquesJob
+ 1 + // VAOGatherer
+ 1 + // updateSkinningPaletteJob
+ 1); // ShaderGathererJob
+
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+ // WHEN
+ renderer.markDirty(Qt3DRender::Render::AbstractRenderer::TexturesDirty, nullptr);
+ jobs = renderer.renderBinJobs();
+
+ // THEN (level
+ QCOMPARE(jobs.size(),
+ 1 + // updateLevelOfDetailJob
+ 1 + // cleanupJob
+ 1 + // sendRenderCaptureJob
+ 1 + // sendBufferCaptureJob
+ 1 + // filterCompatibleTechniquesJob
+ 1 + // VAOGatherer
+ 1 + // TexturesGathererJob
+ 1 + // updateSkinningPaletteJob
+ 1); // SyncTexturesGathererJob
+
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+ // WHEN
+ renderer.markDirty(Qt3DRender::Render::AbstractRenderer::AllDirty, nullptr);
+ jobs = renderer.renderBinJobs();
+
+ // THEN (level
+ QCOMPARE(jobs.size(),
+ 1 + // updateLevelOfDetailJob
+ 1 + // cleanupJob
+ 1 + // sendRenderCaptureJob
+ 1 + // sendBufferCaptureJob
+ 1 + // filterCompatibleTechniquesJob
+ 1 + // VAOGatherer
+ 1 + // EntityEnabledDirty
+ 1 + // WorldTransformJob
+ 1 + // UpdateWorldBoundingVolume
+ 1 + // UpdateShaderDataTransform
+ 1 + // ExpandBoundingVolumeJob
+ 1 + // CalculateBoundingVolumeJob
+ 1 + // UpdateMeshTriangleListJob
+ 1 + // BufferGathererJob
+ 1 + // ShaderGathererJob
+ 1 + // TexturesGathererJob
+ 1 + // updateSkinningPaletteJob
+ 1); // SyncTexturesGathererJob
+
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+
+ }
+};
+
+QTEST_MAIN(tst_Renderer)
+
+#include "tst_renderer.moc"
diff --git a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
index 1ab687b34..23861f3a9 100644
--- a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
+++ b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
@@ -179,27 +179,60 @@ private Q_SLOTS:
Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(clearBuffer->id());
QVERIFY(leafNode != nullptr);
- // WHEN
- Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ {
+ // WHEN
+ Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+
+ // THEN
+ QCOMPARE(renderViewBuilder.renderViewIndex(), 0);
+ QCOMPARE(renderViewBuilder.renderer(), testAspect.renderer());
+ QCOMPARE(renderViewBuilder.layerCacheNeedsToBeRebuilt(), false);
+ QVERIFY(!renderViewBuilder.renderViewJob().isNull());
+ QVERIFY(!renderViewBuilder.lightGathererJob().isNull());
+ QVERIFY(!renderViewBuilder.renderableEntityFilterJob().isNull());
+ QVERIFY(!renderViewBuilder.computableEntityFilterJob().isNull());
+ QVERIFY(!renderViewBuilder.frustumCullingJob().isNull());
+ QVERIFY(!renderViewBuilder.syncFrustumCullingJob().isNull());
+ QVERIFY(!renderViewBuilder.setClearDrawBufferIndexJob().isNull());
+
+ QVERIFY(renderViewBuilder.filterEntityByLayerJob().isNull());
+ QVERIFY(renderViewBuilder.syncFilterEntityByLayerJob().isNull());
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob().isNull());
+ QVERIFY(renderViewBuilder.syncRenderViewCommandBuildersJob().isNull());
+ QVERIFY(renderViewBuilder.syncRenderViewInitializationJob().isNull());
+
+ QCOMPARE(renderViewBuilder.renderViewBuilderJobs().size(), 0);
+ QCOMPARE(renderViewBuilder.materialGathererJobs().size(), 0);
+
+ // WHEN
+ renderViewBuilder.prepareJobs();
+
+ // THEN
+ QVERIFY(!renderViewBuilder.syncRenderCommandBuildingJob().isNull());
+ QVERIFY(!renderViewBuilder.syncRenderViewCommandBuildersJob().isNull());
+ QVERIFY(!renderViewBuilder.syncRenderViewInitializationJob().isNull());
+ QVERIFY(renderViewBuilder.filterEntityByLayerJob().isNull());
+ QVERIFY(renderViewBuilder.syncFilterEntityByLayerJob().isNull());
+
+ QCOMPARE(renderViewBuilder.renderViewBuilderJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
+ QCOMPARE(renderViewBuilder.materialGathererJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
+ QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 11 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
+ }
- // THEN
- QCOMPARE(renderViewBuilder.renderViewIndex(), 0);
- QCOMPARE(renderViewBuilder.renderer(), testAspect.renderer());
- QVERIFY(!renderViewBuilder.renderViewJob().isNull());
- QVERIFY(!renderViewBuilder.filterEntityByLayerJob().isNull());
- QVERIFY(!renderViewBuilder.lightGathererJob().isNull());
- QVERIFY(!renderViewBuilder.renderableEntityFilterJob().isNull());
- QVERIFY(!renderViewBuilder.computableEntityFilterJob().isNull());
- QVERIFY(!renderViewBuilder.frustumCullingJob().isNull());
- QVERIFY(!renderViewBuilder.syncRenderViewInitializationJob().isNull());
- QVERIFY(!renderViewBuilder.syncFrustumCullingJob().isNull());
- QVERIFY(!renderViewBuilder.syncRenderCommandBuildingJob().isNull());
- QVERIFY(!renderViewBuilder.syncRenderViewCommandBuildersJob().isNull());
- QVERIFY(!renderViewBuilder.setClearDrawBufferIndexJob().isNull());
- QCOMPARE(renderViewBuilder.renderViewBuilderJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
- QCOMPARE(renderViewBuilder.materialGathererJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
-
- QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 11 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
+ {
+ // WHEN
+ Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.setLayerCacheNeedsToBeRebuilt(true);
+ renderViewBuilder.prepareJobs();
+
+ // THEN
+ QCOMPARE(renderViewBuilder.layerCacheNeedsToBeRebuilt(), true);
+ QVERIFY(!renderViewBuilder.filterEntityByLayerJob().isNull());
+ QVERIFY(!renderViewBuilder.syncFilterEntityByLayerJob().isNull());
+
+ // mark jobs dirty and recheck
+ QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 13 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
+ }
}
void checkCheckJobDependencies()
@@ -213,66 +246,145 @@ private Q_SLOTS:
Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(clearBuffer->id());
QVERIFY(leafNode != nullptr);
- // WHEN
- Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
- renderViewBuilder.buildJobHierachy();
-
- // THEN
- // Step 1
- QCOMPARE(renderViewBuilder.renderViewJob()->dependencies().size(), 0);
- QCOMPARE(renderViewBuilder.lightGathererJob()->dependencies().size(), 0);
- QCOMPARE(renderViewBuilder.renderableEntityFilterJob()->dependencies().size(),0);
- QCOMPARE(renderViewBuilder.computableEntityFilterJob()->dependencies().size(), 0);
-
- // Step 2
- QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().size(), 1);
- QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().first().data(), renderViewBuilder.renderViewJob().data());
-
- // Step 3
- QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->dependencies().size(), 2);
- QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
- QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(testAspect.renderer()->updateTreeEnabledJob()));
-
- QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().size(), 1);
- QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().first().data(), renderViewBuilder.syncRenderViewInitializationJob().data());
-
- QCOMPARE(renderViewBuilder.syncFrustumCullingJob()->dependencies().size(), 3);
- QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
- QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateWorldTransformJob()));
- QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob()));
-
- for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
- QCOMPARE(materialGatherer->dependencies().size(), 2);
- QVERIFY(materialGatherer->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
- QVERIFY(materialGatherer->dependencies().contains(testAspect.renderer()->filterCompatibleTechniqueJob()));
- }
-
- // Step 4
- QCOMPARE(renderViewBuilder.frustumCullingJob()->dependencies().size(), 2);
- QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncFrustumCullingJob()));
- QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
-
- QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 6);
- QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
- QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.renderableEntityFilterJob()));
- QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.computableEntityFilterJob()));
- QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.filterEntityByLayerJob()));
- QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.lightGathererJob()));
- QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.frustumCullingJob()));
- for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
- QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(materialGatherer));
+ {
+ // WHEN
+ Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.prepareJobs();
+ renderViewBuilder.buildJobHierachy();
+
+ // THEN
+ // Step 1
+ QCOMPARE(renderViewBuilder.renderViewJob()->dependencies().size(), 1); // Depends upon skinning palette update
+ QCOMPARE(renderViewBuilder.lightGathererJob()->dependencies().size(), 0);
+ QCOMPARE(renderViewBuilder.renderableEntityFilterJob()->dependencies().size(),0);
+ QCOMPARE(renderViewBuilder.computableEntityFilterJob()->dependencies().size(), 0);
+
+ // Step 2
+ QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().size(), 1);
+ QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().first().data(), renderViewBuilder.renderViewJob().data());
+
+ // Step 3
+ QVERIFY(renderViewBuilder.filterEntityByLayerJob().isNull());
+ QVERIFY(renderViewBuilder.syncFilterEntityByLayerJob().isNull());
+
+ QCOMPARE(renderViewBuilder.filterProximityJob()->dependencies().size(), 2);
+ QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
+ QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
+
+ QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().size(), 1);
+ QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().first().data(), renderViewBuilder.syncRenderViewInitializationJob().data());
+
+ QCOMPARE(renderViewBuilder.syncFrustumCullingJob()->dependencies().size(), 3);
+ QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
+ QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateWorldTransformJob()));
+ QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob()));
+
+ for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
+ QCOMPARE(materialGatherer->dependencies().size(), 2);
+ QVERIFY(materialGatherer->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
+ QVERIFY(materialGatherer->dependencies().contains(testAspect.renderer()->filterCompatibleTechniqueJob()));
+ }
+
+ // Step 4
+ QCOMPARE(renderViewBuilder.frustumCullingJob()->dependencies().size(), 2);
+ QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncFrustumCullingJob()));
+ QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
+
+ QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 6);
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.renderableEntityFilterJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.computableEntityFilterJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.filterProximityJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.lightGathererJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.frustumCullingJob()));
+ for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(materialGatherer));
+ }
+
+ // Step 5
+ for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) {
+ QCOMPARE(renderViewBuilderJob->dependencies().size(), 1);
+ QCOMPARE(renderViewBuilderJob->dependencies().first().data(), renderViewBuilder.syncRenderCommandBuildingJob().data());
+ }
+
+ // Step 6
+ QCOMPARE(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().size(), renderViewBuilder.renderViewBuilderJobs().size());
+ for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) {
+ QVERIFY(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().contains(renderViewBuilderJob));
+ }
}
-
- // Step 5
- for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) {
- QCOMPARE(renderViewBuilderJob->dependencies().size(), 1);
- QCOMPARE(renderViewBuilderJob->dependencies().first().data(), renderViewBuilder.syncRenderCommandBuildingJob().data());
- }
-
- // Step 6
- QCOMPARE(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().size(), renderViewBuilder.renderViewBuilderJobs().size());
- for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) {
- QVERIFY(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().contains(renderViewBuilderJob));
+ {
+ // WHEN
+ Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.setLayerCacheNeedsToBeRebuilt(true);
+ renderViewBuilder.prepareJobs();
+ renderViewBuilder.buildJobHierachy();
+
+ // THEN
+ // Step 1
+ QCOMPARE(renderViewBuilder.renderViewJob()->dependencies().size(), 1); // Depends upon skinning palette update
+ QCOMPARE(renderViewBuilder.lightGathererJob()->dependencies().size(), 0);
+ QCOMPARE(renderViewBuilder.renderableEntityFilterJob()->dependencies().size(),0);
+ QCOMPARE(renderViewBuilder.computableEntityFilterJob()->dependencies().size(), 0);
+
+ // Step 2
+ QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().size(), 1);
+ QCOMPARE(renderViewBuilder.syncRenderViewInitializationJob()->dependencies().first().data(), renderViewBuilder.renderViewJob().data());
+
+ // Step 3
+ QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->dependencies().size(), 2);
+ QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
+ QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(testAspect.renderer()->updateTreeEnabledJob()));
+
+ QCOMPARE(renderViewBuilder.syncFilterEntityByLayerJob()->dependencies().size(), 1);
+ QVERIFY(renderViewBuilder.syncFilterEntityByLayerJob()->dependencies().contains(renderViewBuilder.filterEntityByLayerJob()));
+
+ QCOMPARE(renderViewBuilder.filterProximityJob()->dependencies().size(), 2);
+ QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
+ QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
+
+ QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().size(), 1);
+ QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().first().data(), renderViewBuilder.syncRenderViewInitializationJob().data());
+
+ QCOMPARE(renderViewBuilder.syncFrustumCullingJob()->dependencies().size(), 3);
+ QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
+ QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateWorldTransformJob()));
+ QVERIFY(renderViewBuilder.syncFrustumCullingJob()->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob()));
+
+ for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
+ QCOMPARE(materialGatherer->dependencies().size(), 2);
+ QVERIFY(materialGatherer->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
+ QVERIFY(materialGatherer->dependencies().contains(testAspect.renderer()->filterCompatibleTechniqueJob()));
+ }
+
+ // Step 4
+ QCOMPARE(renderViewBuilder.frustumCullingJob()->dependencies().size(), 2);
+ QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncFrustumCullingJob()));
+ QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
+
+ QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 7);
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.renderableEntityFilterJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.computableEntityFilterJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncFilterEntityByLayerJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.lightGathererJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.frustumCullingJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.filterProximityJob()));
+ for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(materialGatherer));
+ }
+
+ // Step 5
+ for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) {
+ QCOMPARE(renderViewBuilderJob->dependencies().size(), 1);
+ QCOMPARE(renderViewBuilderJob->dependencies().first().data(), renderViewBuilder.syncRenderCommandBuildingJob().data());
+ }
+
+ // Step 6
+ QCOMPARE(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().size(), renderViewBuilder.renderViewBuilderJobs().size());
+ for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) {
+ QVERIFY(renderViewBuilder.syncRenderViewCommandBuildersJob()->dependencies().contains(renderViewBuilderJob));
+ }
}
}
@@ -289,6 +401,7 @@ private Q_SLOTS:
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.prepareJobs();
renderViewBuilder.buildJobHierachy();
renderViewBuilder.renderViewJob()->run();
@@ -309,6 +422,7 @@ private Q_SLOTS:
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.prepareJobs();
renderViewBuilder.buildJobHierachy();
renderViewBuilder.renderableEntityFilterJob()->run();
@@ -329,6 +443,7 @@ private Q_SLOTS:
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.prepareJobs();
renderViewBuilder.buildJobHierachy();
renderViewBuilder.computableEntityFilterJob()->run();
@@ -354,30 +469,58 @@ private Q_SLOTS:
Qt3DRender::Render::FrameGraphNode *leafNode = testAspect.nodeManagers()->frameGraphManager()->lookupNode(renderPassFilter->id());
QVERIFY(leafNode != nullptr);
- // WHEN
- Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
- renderViewBuilder.buildJobHierachy();
-
- // THEN
- QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), false);
- QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), false);
- QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layers().size(), 0);
- for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
- QVERIFY(materialGatherer->techniqueFilter() == nullptr);
- QVERIFY(materialGatherer->renderPassFilter() == nullptr);
+ {
+ // WHEN
+ Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.prepareJobs();
+ renderViewBuilder.buildJobHierachy();
+
+ // THEN
+ QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), false);
+ for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
+ QVERIFY(materialGatherer->techniqueFilter() == nullptr);
+ QVERIFY(materialGatherer->renderPassFilter() == nullptr);
+ }
+
+ // WHEN
+ renderViewBuilder.renderViewJob()->run();
+ renderViewBuilder.syncRenderViewInitializationJob()->run();
+
+ // THEN
+ QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), true);
+ for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
+ QVERIFY(materialGatherer->techniqueFilter() != nullptr);
+ QVERIFY(materialGatherer->renderPassFilter() != nullptr);
+ }
}
-
- // WHEN
- renderViewBuilder.renderViewJob()->run();
- renderViewBuilder.syncRenderViewInitializationJob()->run();
-
- // THEN
- QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), true);
- QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), true);
- QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layers().size(), 1);
- for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
- QVERIFY(materialGatherer->techniqueFilter() != nullptr);
- QVERIFY(materialGatherer->renderPassFilter() != nullptr);
+ {
+ // WHEN
+ Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.setLayerCacheNeedsToBeRebuilt(true);
+ renderViewBuilder.prepareJobs();
+ renderViewBuilder.buildJobHierachy();
+
+ // THEN
+ QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), false);
+ QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), false);
+ QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 0);
+ for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
+ QVERIFY(materialGatherer->techniqueFilter() == nullptr);
+ QVERIFY(materialGatherer->renderPassFilter() == nullptr);
+ }
+
+ // WHEN
+ renderViewBuilder.renderViewJob()->run();
+ renderViewBuilder.syncRenderViewInitializationJob()->run();
+
+ // THEN
+ QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), true);
+ QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), true);
+ QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 1);
+ for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
+ QVERIFY(materialGatherer->techniqueFilter() != nullptr);
+ QVERIFY(materialGatherer->renderPassFilter() != nullptr);
+ }
}
}
@@ -399,6 +542,7 @@ private Q_SLOTS:
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.prepareJobs();
renderViewBuilder.buildJobHierachy();
// THEN
@@ -428,6 +572,8 @@ private Q_SLOTS:
// WHEN
Qt3DRender::Render::RenderViewBuilder renderViewBuilder(leafNode, 0, testAspect.renderer());
+ renderViewBuilder.setLayerCacheNeedsToBeRebuilt(true);
+ renderViewBuilder.prepareJobs();
renderViewBuilder.buildJobHierachy();
renderViewBuilder.renderViewJob()->run();
diff --git a/tests/auto/render/sceneloader/tst_sceneloader.cpp b/tests/auto/render/sceneloader/tst_sceneloader.cpp
index 18cfe0aeb..9aac50c73 100644
--- a/tests/auto/render/sceneloader/tst_sceneloader.cpp
+++ b/tests/auto/render/sceneloader/tst_sceneloader.cpp
@@ -79,7 +79,7 @@ private Q_SLOTS:
{
// GIVEN
Qt3DRender::QSceneLoader frontendSceneLoader;
- frontendSceneLoader.setSource(QUrl(QStringLiteral("CorvetteMuseum")));
+ frontendSceneLoader.setSource(QUrl(QStringLiteral("file:///CorvetteMuseum")));
Qt3DRender::Render::Scene sceneLoader;
Qt3DRender::Render::SceneManager sceneManager;
@@ -109,7 +109,7 @@ private Q_SLOTS:
// WHEN
Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
- const QUrl newUrl(QStringLiteral("Bownling_Green_KY"));
+ const QUrl newUrl(QStringLiteral("file:///Bownling_Green_KY"));
updateChange->setValue(newUrl);
updateChange->setPropertyName("source");
sceneLoader.sceneChangeEvent(updateChange);
diff --git a/tests/auto/render/segmentvisitor/segmentvisitor.pro b/tests/auto/render/segmentvisitor/segmentvisitor.pro
new file mode 100644
index 000000000..2f650aa0b
--- /dev/null
+++ b/tests/auto/render/segmentvisitor/segmentvisitor.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = segmentvisitor
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_segmentvisitor.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
new file mode 100644
index 000000000..d56daf159
--- /dev/null
+++ b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
@@ -0,0 +1,814 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** 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 <qbackendnodetester.h>
+#include <Qt3DRender/qgeometryrenderer.h>
+#include <Qt3DRender/qbuffer.h>
+#include <private/segmentsvisitor_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 "testrenderer.h"
+
+using namespace Qt3DRender::Render;
+
+class TestVisitor : public SegmentsVisitor
+{
+public:
+ TestVisitor(NodeManagers *manager)
+ : SegmentsVisitor(manager)
+ {
+
+ }
+
+ virtual void visit(uint andx, const QVector3D &a, uint bndx, const QVector3D &b)
+ {
+ m_segments.push_back(TestSegment(andx, a, bndx, b));
+ }
+
+ NodeManagers *nodeManagers() const
+ {
+ return m_manager;
+ }
+
+ Qt3DCore::QNodeId nodeId() const
+ {
+ return m_nodeId;
+ }
+
+ uint segmentCount() const
+ {
+ return m_segments.size();
+ }
+
+ bool verifySegment(uint segment, uint andx, uint bndx, QVector3D a, QVector3D b) const
+ {
+ if (segment >= uint(m_segments.size()))
+ return false;
+ if (andx != m_segments[segment].abcndx[0]
+ || bndx != m_segments[segment].abcndx[1])
+ return false;
+
+ if (!qFuzzyCompare(a, m_segments[segment].abc[0])
+ || !qFuzzyCompare(b, m_segments[segment].abc[1]))
+ return false;
+
+ return true;
+ }
+private:
+ struct TestSegment
+ {
+ uint abcndx[2];
+ QVector3D abc[2];
+ TestSegment()
+ {
+ abcndx[0] = abcndx[1] = uint(-1);
+ }
+
+ TestSegment(uint andx, const QVector3D &a, uint bndx, const QVector3D &b)
+ {
+ abcndx[0] = andx;
+ abcndx[1] = bndx;
+ abc[0] = a;
+ abc[1] = b;
+ }
+ };
+ QVector<TestSegment> m_segments;
+};
+
+class tst_SegmentVisitor : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+
+ void checkInitialize()
+ {
+ // WHEN
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ TestVisitor visitor(nodeManagers.data());
+
+ // THEN
+ QCOMPARE(visitor.nodeManagers(), nodeManagers.data());
+ }
+
+ void checkApplyEntity()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ QScopedPointer<Qt3DCore::QEntity> entity(new Qt3DCore::QEntity());
+ TestVisitor visitor(nodeManagers.data());
+
+ // WHEN
+ visitor.apply(entity.data());
+
+ // THEN
+ QCOMPARE(visitor.nodeId(), entity->id());
+ QCOMPARE(visitor.segmentCount(), uint(0));
+ }
+
+ void checkApplyGeometryRenderer()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ QScopedPointer<GeometryRenderer> geometryRenderer(new GeometryRenderer());
+ TestVisitor visitor(nodeManagers.data());
+
+ // WHEN
+ visitor.apply(geometryRenderer.data(), Qt3DCore::QNodeId());
+
+ // THEN
+ // tadaa, nothing should happen
+ }
+
+ void testVisitSegments()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry();
+ QScopedPointer<Qt3DRender::QGeometryRenderer> geometryRenderer(new Qt3DRender::QGeometryRenderer());
+ QScopedPointer<Qt3DRender::QAttribute> positionAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QBuffer> dataBuffer(new Qt3DRender::QBuffer());
+ TestVisitor visitor(nodeManagers.data());
+ TestRenderer renderer;
+
+ QByteArray data;
+ data.resize(sizeof(float) * 3 * 2 * 3);
+ float *dataPtr = reinterpret_cast<float *>(data.data());
+ dataPtr[0] = 0;
+ dataPtr[1] = 0;
+ dataPtr[2] = 1.0f;
+ dataPtr[3] = 1.0f;
+ dataPtr[4] = 0;
+ dataPtr[5] = 0;
+
+ dataPtr[6] = 0;
+ dataPtr[7] = 1.0f;
+ dataPtr[8] = 0;
+ dataPtr[9] = 0;
+ dataPtr[10] = 0;
+ dataPtr[11] = 1.0f;
+
+ dataPtr[12] = 1.0f;
+ dataPtr[13] = 0;
+ dataPtr[14] = 0;
+ dataPtr[15] = 0;
+ dataPtr[16] = 1.0f;
+ dataPtr[17] = 0;
+
+ dataBuffer->setData(data);
+ Buffer *backendBuffer = nodeManagers->bufferManager()->getOrCreateResource(dataBuffer->id());
+ backendBuffer->setRenderer(&renderer);
+ backendBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(dataBuffer.data(), backendBuffer);
+
+ positionAttribute->setBuffer(dataBuffer.data());
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setCount(6);
+ positionAttribute->setByteStride(3*4);
+ positionAttribute->setByteOffset(0);
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+ geometry->addAttribute(positionAttribute.data());
+
+ geometryRenderer->setGeometry(geometry);
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
+
+ Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
+ backendAttribute->setRenderer(&renderer);
+ simulateInitialization(positionAttribute.data(), backendAttribute);
+
+ 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.data(), backendRenderer);
+
+ // WHEN
+ visitor.apply(backendRenderer, Qt3DCore::QNodeId());
+
+ // THEN
+ QCOMPARE(visitor.segmentCount(), uint(3));
+ QVERIFY(visitor.verifySegment(0, 0,1, QVector3D(0,0,1), QVector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 2,3, QVector3D(0,1,0), QVector3D(0,0,1)));
+ QVERIFY(visitor.verifySegment(2, 4,5, QVector3D(1,0,0), QVector3D(0,1,0)));
+ }
+
+ void testVisitSegmentsIndexed()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry();
+ QScopedPointer<Qt3DRender::QGeometryRenderer> geometryRenderer(new Qt3DRender::QGeometryRenderer());
+ QScopedPointer<Qt3DRender::QAttribute> positionAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QAttribute> indexAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QBuffer> dataBuffer(new Qt3DRender::QBuffer());
+ QScopedPointer<Qt3DRender::QBuffer> indexDataBuffer(new Qt3DRender::QBuffer());
+ TestVisitor visitor(nodeManagers.data());
+ TestRenderer renderer;
+
+ QByteArray data;
+ data.resize(sizeof(float) * 3 * 4);
+ float *dataPtr = reinterpret_cast<float *>(data.data());
+ dataPtr[0] = 0;
+ dataPtr[1] = 0;
+ dataPtr[2] = 0.0f;
+ dataPtr[3] = 1.0f;
+ dataPtr[4] = 0;
+ dataPtr[5] = 0;
+ dataPtr[6] = 1.0;
+ dataPtr[7] = 1.0f;
+ dataPtr[8] = 0;
+ dataPtr[9] = 0;
+ dataPtr[10] = 1.0f;
+ dataPtr[11] = 0;
+ dataBuffer->setData(data);
+ Buffer *backendBuffer = nodeManagers->bufferManager()->getOrCreateResource(dataBuffer->id());
+ backendBuffer->setRenderer(&renderer);
+ backendBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(dataBuffer.data(), backendBuffer);
+
+ QByteArray indexData;
+ indexData.resize(sizeof(uint) * 2 * 5);
+ uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
+ iDataPtr[0] = 0;
+ iDataPtr[1] = 1;
+ iDataPtr[2] = 1;
+ iDataPtr[3] = 2;
+ iDataPtr[4] = 2;
+ iDataPtr[5] = 3;
+ iDataPtr[6] = 0;
+ iDataPtr[7] = 2;
+ iDataPtr[8] = 1;
+ iDataPtr[9] = 3;
+ indexDataBuffer->setData(indexData);
+
+ Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
+ backendIndexBuffer->setRenderer(&renderer);
+ backendIndexBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(indexDataBuffer.data(), backendIndexBuffer);
+
+ positionAttribute->setBuffer(dataBuffer.data());
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setCount(4);
+ positionAttribute->setByteStride(3*sizeof(float));
+ positionAttribute->setByteOffset(0);
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+
+ indexAttribute->setBuffer(indexDataBuffer.data());
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
+ indexAttribute->setCount(2*5);
+ indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
+
+ geometry->addAttribute(positionAttribute.data());
+ geometry->addAttribute(indexAttribute.data());
+
+ geometryRenderer->setGeometry(geometry);
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
+
+ Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
+ backendAttribute->setRenderer(&renderer);
+ simulateInitialization(positionAttribute.data(), backendAttribute);
+
+ Attribute *backendIndexAttribute = nodeManagers->attributeManager()->getOrCreateResource(indexAttribute->id());
+ backendIndexAttribute->setRenderer(&renderer);
+ simulateInitialization(indexAttribute.data(), backendIndexAttribute);
+
+ 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.data(), backendRenderer);
+
+ // WHEN
+ visitor.apply(backendRenderer, Qt3DCore::QNodeId());
+
+ // THEN
+ QCOMPARE(visitor.segmentCount(), uint(5));
+ QVERIFY(visitor.verifySegment(0, 0,1, QVector3D(0,0,0), QVector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, QVector3D(1,0,0), QVector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, QVector3D(1,1,0), QVector3D(0,1,0)));
+ QVERIFY(visitor.verifySegment(3, 0,2, QVector3D(0,0,0), QVector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(4, 1,3, QVector3D(1,0,0), QVector3D(0,1,0)));
+ }
+
+ void testVisitLineStrip()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry();
+ QScopedPointer<Qt3DRender::QGeometryRenderer> geometryRenderer(new Qt3DRender::QGeometryRenderer());
+ QScopedPointer<Qt3DRender::QAttribute> positionAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QBuffer> dataBuffer(new Qt3DRender::QBuffer());
+ TestVisitor visitor(nodeManagers.data());
+ TestRenderer renderer;
+
+ QByteArray data;
+ data.resize(sizeof(float) * 3 * 4);
+ float *dataPtr = reinterpret_cast<float *>(data.data());
+ dataPtr[0] = 0;
+ dataPtr[1] = 0;
+ dataPtr[2] = 0.0f;
+ dataPtr[3] = 1.0f;
+ dataPtr[4] = 0;
+ dataPtr[5] = 0;
+ dataPtr[6] = 1.0f;
+ dataPtr[7] = 1.0f;
+ dataPtr[8] = 0;
+ dataPtr[9] = 0;
+ dataPtr[10] = 1.0f;
+ dataPtr[11] = 0;
+ dataBuffer->setData(data);
+ Buffer *backendBuffer = nodeManagers->bufferManager()->getOrCreateResource(dataBuffer->id());
+ backendBuffer->setRenderer(&renderer);
+ backendBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(dataBuffer.data(), backendBuffer);
+
+ positionAttribute->setBuffer(dataBuffer.data());
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setCount(4);
+ positionAttribute->setByteStride(3*4);
+ positionAttribute->setByteOffset(0);
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+ geometry->addAttribute(positionAttribute.data());
+
+ geometryRenderer->setGeometry(geometry);
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineStrip);
+
+ Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
+ backendAttribute->setRenderer(&renderer);
+ simulateInitialization(positionAttribute.data(), backendAttribute);
+
+ 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.data(), backendRenderer);
+
+ // WHEN
+ visitor.apply(backendRenderer, Qt3DCore::QNodeId());
+
+ // THEN
+ QCOMPARE(visitor.segmentCount(), uint(3));
+ QVERIFY(visitor.verifySegment(0, 0,1, QVector3D(0,0,0), QVector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, QVector3D(1,0,0), QVector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, QVector3D(1,1,0), QVector3D(0,1,0)));
+ }
+
+ void testVisitListStripIndexed()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry();
+ QScopedPointer<Qt3DRender::QGeometryRenderer> geometryRenderer(new Qt3DRender::QGeometryRenderer());
+ QScopedPointer<Qt3DRender::QAttribute> positionAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QAttribute> indexAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QBuffer> dataBuffer(new Qt3DRender::QBuffer());
+ QScopedPointer<Qt3DRender::QBuffer> indexDataBuffer(new Qt3DRender::QBuffer());
+ TestVisitor visitor(nodeManagers.data());
+ TestRenderer renderer;
+
+ QByteArray data;
+ data.resize(sizeof(float) * 3 * 4);
+ float *dataPtr = reinterpret_cast<float *>(data.data());
+ dataPtr[0] = 0;
+ dataPtr[1] = 0;
+ dataPtr[2] = 0.0f;
+ dataPtr[3] = 1.0f;
+ dataPtr[4] = 0;
+ dataPtr[5] = 0;
+ dataPtr[6] = 1.0;
+ dataPtr[7] = 1.0f;
+ dataPtr[8] = 0;
+ dataPtr[9] = 0;
+ dataPtr[10] = 1.0f;
+ dataPtr[11] = 0;
+ dataBuffer->setData(data);
+ Buffer *backendBuffer = nodeManagers->bufferManager()->getOrCreateResource(dataBuffer->id());
+ backendBuffer->setRenderer(&renderer);
+ backendBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(dataBuffer.data(), backendBuffer);
+
+ QByteArray indexData;
+ indexData.resize(sizeof(uint) * 2 * 4);
+ uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
+ iDataPtr[0] = 0;
+ iDataPtr[1] = 1;
+ iDataPtr[2] = 2;
+ iDataPtr[3] = 3;
+ indexDataBuffer->setData(indexData);
+
+ Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
+ backendIndexBuffer->setRenderer(&renderer);
+ backendIndexBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(indexDataBuffer.data(), backendIndexBuffer);
+
+ positionAttribute->setBuffer(dataBuffer.data());
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setCount(4);
+ positionAttribute->setByteStride(3*sizeof(float));
+ positionAttribute->setByteOffset(0);
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+
+ indexAttribute->setBuffer(indexDataBuffer.data());
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
+ indexAttribute->setCount(4);
+ indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
+
+ geometry->addAttribute(positionAttribute.data());
+ geometry->addAttribute(indexAttribute.data());
+
+ geometryRenderer->setGeometry(geometry);
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineStrip);
+
+ Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
+ backendAttribute->setRenderer(&renderer);
+ simulateInitialization(positionAttribute.data(), backendAttribute);
+
+ Attribute *backendIndexAttribute = nodeManagers->attributeManager()->getOrCreateResource(indexAttribute->id());
+ backendIndexAttribute->setRenderer(&renderer);
+ simulateInitialization(indexAttribute.data(), backendIndexAttribute);
+
+ 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.data(), backendRenderer);
+
+ // WHEN
+ visitor.apply(backendRenderer, Qt3DCore::QNodeId());
+
+ // THEN
+ QCOMPARE(visitor.segmentCount(), uint(3));
+ QVERIFY(visitor.verifySegment(0, 0,1, QVector3D(0,0,0), QVector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, QVector3D(1,0,0), QVector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, QVector3D(1,1,0), QVector3D(0,1,0)));
+ }
+
+ void testVisitLineLoop()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry();
+ QScopedPointer<Qt3DRender::QGeometryRenderer> geometryRenderer(new Qt3DRender::QGeometryRenderer());
+ QScopedPointer<Qt3DRender::QAttribute> positionAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QBuffer> dataBuffer(new Qt3DRender::QBuffer());
+ TestVisitor visitor(nodeManagers.data());
+ TestRenderer renderer;
+
+ QByteArray data;
+ data.resize(sizeof(float) * 3 * 4);
+ float *dataPtr = reinterpret_cast<float *>(data.data());
+ dataPtr[0] = 0;
+ dataPtr[1] = 0;
+ dataPtr[2] = 0.0f;
+ dataPtr[3] = 1.0f;
+ dataPtr[4] = 0;
+ dataPtr[5] = 0;
+ dataPtr[6] = 1.0f;
+ dataPtr[7] = 1.0f;
+ dataPtr[8] = 0;
+ dataPtr[9] = 0;
+ dataPtr[10] = 1.0f;
+ dataPtr[11] = 0;
+ dataBuffer->setData(data);
+ Buffer *backendBuffer = nodeManagers->bufferManager()->getOrCreateResource(dataBuffer->id());
+ backendBuffer->setRenderer(&renderer);
+ backendBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(dataBuffer.data(), backendBuffer);
+
+ positionAttribute->setBuffer(dataBuffer.data());
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setCount(4);
+ positionAttribute->setByteStride(3*4);
+ positionAttribute->setByteOffset(0);
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+ geometry->addAttribute(positionAttribute.data());
+
+ geometryRenderer->setGeometry(geometry);
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineLoop);
+
+ Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
+ backendAttribute->setRenderer(&renderer);
+ simulateInitialization(positionAttribute.data(), backendAttribute);
+
+ 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.data(), backendRenderer);
+
+ // WHEN
+ visitor.apply(backendRenderer, Qt3DCore::QNodeId());
+
+ // THEN
+ QCOMPARE(visitor.segmentCount(), uint(4));
+ QVERIFY(visitor.verifySegment(0, 0,1, QVector3D(0,0,0), QVector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, QVector3D(1,0,0), QVector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, QVector3D(1,1,0), QVector3D(0,1,0)));
+ QVERIFY(visitor.verifySegment(3, 3,0, QVector3D(0,1,0), QVector3D(0,0,0)));
+ }
+
+ void testVisitLineLoopIndexed()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry();
+ QScopedPointer<Qt3DRender::QGeometryRenderer> geometryRenderer(new Qt3DRender::QGeometryRenderer());
+ QScopedPointer<Qt3DRender::QAttribute> positionAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QAttribute> indexAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QBuffer> dataBuffer(new Qt3DRender::QBuffer());
+ QScopedPointer<Qt3DRender::QBuffer> indexDataBuffer(new Qt3DRender::QBuffer());
+ TestVisitor visitor(nodeManagers.data());
+ TestRenderer renderer;
+
+ QByteArray data;
+ data.resize(sizeof(float) * 3 * 4);
+ float *dataPtr = reinterpret_cast<float *>(data.data());
+ dataPtr[0] = 0;
+ dataPtr[1] = 0;
+ dataPtr[2] = 0.0f;
+ dataPtr[3] = 1.0f;
+ dataPtr[4] = 0;
+ dataPtr[5] = 0;
+ dataPtr[6] = 1.0;
+ dataPtr[7] = 1.0f;
+ dataPtr[8] = 0;
+ dataPtr[9] = 0;
+ dataPtr[10] = 1.0f;
+ dataPtr[11] = 0;
+ dataBuffer->setData(data);
+ Buffer *backendBuffer = nodeManagers->bufferManager()->getOrCreateResource(dataBuffer->id());
+ backendBuffer->setRenderer(&renderer);
+ backendBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(dataBuffer.data(), backendBuffer);
+
+ QByteArray indexData;
+ indexData.resize(sizeof(uint) * 2 * 4);
+ uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
+ iDataPtr[0] = 0;
+ iDataPtr[1] = 1;
+ iDataPtr[2] = 2;
+ iDataPtr[3] = 3;
+ indexDataBuffer->setData(indexData);
+
+ Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
+ backendIndexBuffer->setRenderer(&renderer);
+ backendIndexBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(indexDataBuffer.data(), backendIndexBuffer);
+
+ positionAttribute->setBuffer(dataBuffer.data());
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setCount(4);
+ positionAttribute->setByteStride(3*sizeof(float));
+ positionAttribute->setByteOffset(0);
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+
+ indexAttribute->setBuffer(indexDataBuffer.data());
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
+ indexAttribute->setCount(4);
+ indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
+
+ geometry->addAttribute(positionAttribute.data());
+ geometry->addAttribute(indexAttribute.data());
+
+ geometryRenderer->setGeometry(geometry);
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineLoop);
+
+ Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
+ backendAttribute->setRenderer(&renderer);
+ simulateInitialization(positionAttribute.data(), backendAttribute);
+
+ Attribute *backendIndexAttribute = nodeManagers->attributeManager()->getOrCreateResource(indexAttribute->id());
+ backendIndexAttribute->setRenderer(&renderer);
+ simulateInitialization(indexAttribute.data(), backendIndexAttribute);
+
+ 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.data(), backendRenderer);
+
+ // WHEN
+ visitor.apply(backendRenderer, Qt3DCore::QNodeId());
+
+ // THEN
+ QCOMPARE(visitor.segmentCount(), uint(4));
+ QVERIFY(visitor.verifySegment(0, 0,1, QVector3D(0,0,0), QVector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, QVector3D(1,0,0), QVector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, QVector3D(1,1,0), QVector3D(0,1,0)));
+ QVERIFY(visitor.verifySegment(3, 3,0, QVector3D(0,1,0), QVector3D(0,0,0)));
+ }
+
+ void testVisitLineAdjacency()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry();
+ QScopedPointer<Qt3DRender::QGeometryRenderer> geometryRenderer(new Qt3DRender::QGeometryRenderer());
+ QScopedPointer<Qt3DRender::QAttribute> positionAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QBuffer> dataBuffer(new Qt3DRender::QBuffer());
+ TestVisitor visitor(nodeManagers.data());
+ TestRenderer renderer;
+
+ QByteArray data;
+ data.resize(sizeof(float) * 3 * 2 * 2);
+ float *dataPtr = reinterpret_cast<float *>(data.data());
+ dataPtr[0] = 0;
+ dataPtr[1] = 0;
+ dataPtr[2] = 1.0f;
+ dataPtr[3] = 1.0f;
+ dataPtr[4] = 0;
+ dataPtr[5] = 0;
+
+ dataPtr[6] = 0;
+ dataPtr[7] = 1.0f;
+ dataPtr[8] = 0;
+ dataPtr[9] = 1.0f;
+ dataPtr[10] = 0;
+ dataPtr[12] = 0;
+ dataBuffer->setData(data);
+ Buffer *backendBuffer = nodeManagers->bufferManager()->getOrCreateResource(dataBuffer->id());
+ backendBuffer->setRenderer(&renderer);
+ backendBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(dataBuffer.data(), backendBuffer);
+
+ positionAttribute->setBuffer(dataBuffer.data());
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setCount(4);
+ positionAttribute->setByteStride(3*4);
+ positionAttribute->setByteOffset(0);
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+ geometry->addAttribute(positionAttribute.data());
+
+ geometryRenderer->setGeometry(geometry);
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LinesAdjacency);
+
+ Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
+ backendAttribute->setRenderer(&renderer);
+ simulateInitialization(positionAttribute.data(), backendAttribute);
+
+ 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.data(), backendRenderer);
+
+ // WHEN
+ visitor.apply(backendRenderer, Qt3DCore::QNodeId());
+
+ // THEN
+ QCOMPARE(visitor.segmentCount(), uint(1));
+ QVERIFY(visitor.verifySegment(0, 1, 2, QVector3D(1,0,0), QVector3D(0,1,0)));
+ }
+
+ void testVisitLinesAdjacencyIndexed()
+ {
+ QScopedPointer<NodeManagers> nodeManagers(new NodeManagers());
+ Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry();
+ QScopedPointer<Qt3DRender::QGeometryRenderer> geometryRenderer(new Qt3DRender::QGeometryRenderer());
+ QScopedPointer<Qt3DRender::QAttribute> positionAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QAttribute> indexAttribute(new Qt3DRender::QAttribute());
+ QScopedPointer<Qt3DRender::QBuffer> dataBuffer(new Qt3DRender::QBuffer());
+ QScopedPointer<Qt3DRender::QBuffer> indexDataBuffer(new Qt3DRender::QBuffer());
+ TestVisitor visitor(nodeManagers.data());
+ TestRenderer renderer;
+
+ QByteArray data;
+ data.resize(sizeof(float) * 3 * 2 * 2);
+ float *dataPtr = reinterpret_cast<float *>(data.data());
+ dataPtr[0] = 0;
+ dataPtr[1] = 0;
+ dataPtr[2] = 1.0f;
+ dataPtr[3] = 1.0f;
+ dataPtr[4] = 0;
+ dataPtr[5] = 0;
+
+ dataPtr[6] = 0;
+ dataPtr[7] = 1.0f;
+ dataPtr[8] = 0;
+ dataPtr[9] = 1.0f;
+ dataPtr[10] = 0;
+ dataPtr[12] = 0;
+ dataBuffer->setData(data);
+ Buffer *backendBuffer = nodeManagers->bufferManager()->getOrCreateResource(dataBuffer->id());
+ backendBuffer->setRenderer(&renderer);
+ backendBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(dataBuffer.data(), backendBuffer);
+
+ QByteArray indexData;
+ indexData.resize(sizeof(uint) * 2);
+ uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
+ iDataPtr[0] = 0;
+ iDataPtr[1] = 1;
+ iDataPtr[2] = 2;
+ iDataPtr[3] = 3;
+ indexDataBuffer->setData(indexData);
+
+ Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
+ backendIndexBuffer->setRenderer(&renderer);
+ backendIndexBuffer->setManager(nodeManagers->bufferManager());
+ simulateInitialization(indexDataBuffer.data(), backendIndexBuffer);
+
+ positionAttribute->setBuffer(dataBuffer.data());
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setCount(4);
+ positionAttribute->setByteStride(3*sizeof(float));
+ positionAttribute->setByteOffset(0);
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+
+ indexAttribute->setBuffer(indexDataBuffer.data());
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
+ indexAttribute->setCount(4);
+ indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
+
+ geometry->addAttribute(positionAttribute.data());
+ geometry->addAttribute(indexAttribute.data());
+
+ geometryRenderer->setGeometry(geometry);
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LinesAdjacency);
+
+ Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
+ backendAttribute->setRenderer(&renderer);
+ simulateInitialization(positionAttribute.data(), backendAttribute);
+
+ Attribute *backendIndexAttribute = nodeManagers->attributeManager()->getOrCreateResource(indexAttribute->id());
+ backendIndexAttribute->setRenderer(&renderer);
+ simulateInitialization(indexAttribute.data(), backendIndexAttribute);
+
+ 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.data(), backendRenderer);
+
+ // WHEN
+ visitor.apply(backendRenderer, Qt3DCore::QNodeId());
+
+ // THEN
+ QCOMPARE(visitor.segmentCount(), uint(1));
+ QVERIFY(visitor.verifySegment(0, 1, 2, QVector3D(1,0,0), QVector3D(0,1,0)));
+ }
+};
+
+QTEST_MAIN(tst_SegmentVisitor)
+
+#include "tst_segmentvisitor.moc"
diff --git a/tests/auto/render/sendrendercapturejob/tst_sendrendercapturejob.cpp b/tests/auto/render/sendrendercapturejob/tst_sendrendercapturejob.cpp
index 3310941ed..c6bd65324 100644
--- a/tests/auto/render/sendrendercapturejob/tst_sendrendercapturejob.cpp
+++ b/tests/auto/render/sendrendercapturejob/tst_sendrendercapturejob.cpp
@@ -55,9 +55,9 @@ private Q_SLOTS:
renderer.setNodeManagers(&nodeManagers);
job.setManagers(&nodeManagers);
- renderCapture->requestCapture(42);
- renderCapture->acknowledgeCaptureRequest();
- renderCapture->addRenderCapture(image);
+ renderCapture->requestCapture({ 42, QRect() });
+ auto request = renderCapture->takeCaptureRequest();
+ renderCapture->addRenderCapture(request.captureId, image);
renderer.addRenderCaptureSendRequest(renderCapture->peerId());
//WHEN
diff --git a/tests/auto/render/shader/shader.pro b/tests/auto/render/shader/shader.pro
index 7c908e0f6..6e8a8ec2e 100644
--- a/tests/auto/render/shader/shader.pro
+++ b/tests/auto/render/shader/shader.pro
@@ -9,3 +9,4 @@ CONFIG += testcase
SOURCES += tst_shader.cpp
include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/shader/tst_shader.cpp b/tests/auto/render/shader/tst_shader.cpp
index f6ed41a8b..067db55e7 100644
--- a/tests/auto/render/shader/tst_shader.cpp
+++ b/tests/auto/render/shader/tst_shader.cpp
@@ -30,6 +30,7 @@
#include <qbackendnodetester.h>
#include <Qt3DRender/private/shader_p.h>
#include <Qt3DRender/qshaderprogram.h>
+#include "testrenderer.h"
class tst_RenderShader : public Qt3DCore::QBackendNodeTester
{
@@ -39,6 +40,11 @@ private slots:
void hasCoherentInitialState();
void matchesFrontendPeer();
void cleanupLeavesACoherentState();
+ void dealWithPropertyChanges_data();
+ void dealWithPropertyChanges();
+ void checkSetRendererDirtyOnInitialization();
+ void allowToChangeShaderCode_data();
+ void allowToChangeShaderCode();
};
@@ -86,36 +92,180 @@ void tst_RenderShader::hasCoherentInitialState()
void tst_RenderShader::matchesFrontendPeer()
{
- Qt3DRender::QShaderProgram *frontend = createFrontendShader();
- Qt3DRender::Render::Shader *backend = new Qt3DRender::Render::Shader();
+ QScopedPointer<Qt3DRender::QShaderProgram> frontend(createFrontendShader());
+ TestRenderer renderer;
+ Qt3DRender::Render::Shader backend;
- simulateInitialization(frontend, backend);
- QCOMPARE(backend->isLoaded(), false);
- QVERIFY(backend->dna() != 0U);
+ backend.setRenderer(&renderer);
+ simulateInitialization(frontend.data(), &backend);
+ QCOMPARE(backend.isLoaded(), false);
+ QVERIFY(backend.dna() != 0U);
for (int i = Qt3DRender::QShaderProgram::Vertex; i <= Qt3DRender::QShaderProgram::Compute; ++i)
- QCOMPARE(backend->shaderCode()[i],
+ QCOMPARE(backend.shaderCode()[i],
frontend->shaderCode( static_cast<const Qt3DRender::QShaderProgram::ShaderType>(i)));
}
void tst_RenderShader::cleanupLeavesACoherentState()
{
- Qt3DRender::QShaderProgram *frontend = createFrontendShader();
- Qt3DRender::Render::Shader *shader = new Qt3DRender::Render::Shader();
+ QScopedPointer<Qt3DRender::QShaderProgram> frontend(createFrontendShader());
+ TestRenderer renderer;
+ Qt3DRender::Render::Shader shader;
- simulateInitialization(frontend, shader);
+ shader.setRenderer(&renderer);
+ simulateInitialization(frontend.data(), &shader);
- shader->cleanup();
+ shader.cleanup();
- QCOMPARE(shader->isLoaded(), false);
- QCOMPARE(shader->dna(), 0U);
- QVERIFY(shader->uniformsNames().isEmpty());
- QVERIFY(shader->attributesNames().isEmpty());
- QVERIFY(shader->uniformBlockNames().isEmpty());
- QVERIFY(shader->uniforms().isEmpty());
- QVERIFY(shader->attributes().isEmpty());
- QVERIFY(shader->uniformBlocks().isEmpty());
- QCOMPARE(shader->status(), Qt3DRender::QShaderProgram::NotReady);
+ QCOMPARE(shader.isLoaded(), false);
+ QCOMPARE(shader.dna(), 0U);
+ QVERIFY(shader.uniformsNames().isEmpty());
+ QVERIFY(shader.attributesNames().isEmpty());
+ QVERIFY(shader.uniformBlockNames().isEmpty());
+ QVERIFY(shader.uniforms().isEmpty());
+ QVERIFY(shader.attributes().isEmpty());
+ QVERIFY(shader.uniformBlocks().isEmpty());
+ QCOMPARE(shader.status(), Qt3DRender::QShaderProgram::NotReady);
+}
+
+void tst_RenderShader::dealWithPropertyChanges_data()
+{
+ QTest::addColumn<QByteArray>("property");
+ QTest::addColumn<Qt3DRender::QShaderProgram::ShaderType>("type");
+
+ QTest::newRow("vertex") << QByteArrayLiteral("vertexShaderCode")
+ << Qt3DRender::QShaderProgram::Vertex;
+
+ QTest::newRow("tessControl") << QByteArrayLiteral("tessellationControlShaderCode")
+ << Qt3DRender::QShaderProgram::TessellationControl;
+
+ QTest::newRow("tessEval") << QByteArrayLiteral("tessellationEvaluationShaderCode")
+ << Qt3DRender::QShaderProgram::TessellationEvaluation;
+
+ QTest::newRow("geometry") << QByteArrayLiteral("geometryShaderCode")
+ << Qt3DRender::QShaderProgram::Geometry;
+
+ QTest::newRow("fragment") << QByteArrayLiteral("fragmentShaderCode")
+ << Qt3DRender::QShaderProgram::Fragment;
+
+ QTest::newRow("compute") << QByteArrayLiteral("computeShaderCode")
+ << Qt3DRender::QShaderProgram::Compute;
+}
+
+void tst_RenderShader::dealWithPropertyChanges()
+{
+ // GIVEN
+ QFETCH(QByteArray, property);
+ QFETCH(Qt3DRender::QShaderProgram::ShaderType, type);
+
+ Qt3DRender::Render::Shader backend;
+ backend.setLoaded(true);
+ TestRenderer renderer;
+ backend.setRenderer(&renderer);
+
+ // WHEN
+ auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(QStringLiteral("foo"));
+ updateChange->setPropertyName(property);
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.shaderCode().at(type), QStringLiteral("foo"));
+ QVERIFY(!backend.isLoaded());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+ backend.setLoaded(true);
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(QStringLiteral("foo"));
+ updateChange->setPropertyName(property);
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.shaderCode().at(type), QStringLiteral("foo"));
+ QVERIFY(backend.isLoaded());
+ QCOMPARE(renderer.dirtyBits(), 0);
+ renderer.resetDirty();
+ backend.setLoaded(true);
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(QStringLiteral("bar"));
+ updateChange->setPropertyName(property);
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.shaderCode().at(type), QStringLiteral("bar"));
+ QVERIFY(!backend.isLoaded());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+ backend.setLoaded(true);
+}
+
+void tst_RenderShader::checkSetRendererDirtyOnInitialization()
+{
+ // GIVEN
+ QScopedPointer<Qt3DRender::QShaderProgram> frontend(createFrontendShader());
+ Qt3DRender::Render::Shader shader;
+ TestRenderer renderer;
+
+ shader.setRenderer(&renderer);
+
+ // THEN
+ QCOMPARE(renderer.dirtyBits(), 0);
+
+ // WHEN
+ simulateInitialization(frontend.data(), &shader);
+
+ // THEN
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+}
+
+void tst_RenderShader::allowToChangeShaderCode_data()
+{
+ dealWithPropertyChanges_data();
+}
+
+void tst_RenderShader::allowToChangeShaderCode()
+{
+ // GIVEN
+ QFETCH(Qt3DRender::QShaderProgram::ShaderType, type);
+
+ Qt3DRender::Render::Shader backend;
+ backend.setLoaded(true);
+ TestRenderer renderer;
+ backend.setRenderer(&renderer);
+
+ // WHEN
+ backend.setShaderCode(type, QByteArrayLiteral("foo"));
+
+ // THEN
+ QCOMPARE(backend.shaderCode().at(type), QStringLiteral("foo"));
+ QVERIFY(!backend.isLoaded());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+ backend.setLoaded(true);
+
+ // WHEN
+ backend.setShaderCode(type, QByteArrayLiteral("foo"));
+
+ // THEN
+ QCOMPARE(backend.shaderCode().at(type), QStringLiteral("foo"));
+ QVERIFY(backend.isLoaded());
+ QCOMPARE(renderer.dirtyBits(), 0);
+ renderer.resetDirty();
+ backend.setLoaded(true);
+
+ // WHEN
+ backend.setShaderCode(type, QByteArrayLiteral("bar"));
+
+ // THEN
+ QCOMPARE(backend.shaderCode().at(type), QStringLiteral("bar"));
+ QVERIFY(!backend.isLoaded());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+ backend.setLoaded(true);
}
QTEST_APPLESS_MAIN(tst_RenderShader)
diff --git a/tests/auto/render/shaderbuilder/input.json b/tests/auto/render/shaderbuilder/input.json
new file mode 100644
index 000000000..5437bd5b5
--- /dev/null
+++ b/tests/auto/render/shaderbuilder/input.json
@@ -0,0 +1,90 @@
+{
+ "nodes": [
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000001}",
+ "type": "worldPosition"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000002}",
+ "type": "texture"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000003}",
+ "type": "texCoord"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000004}",
+ "type": "lightIntensity"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000005}",
+ "type": "exposure"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000006}",
+ "type": "fragColor"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000007}",
+ "type": "sampleTexture"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000008}",
+ "type": "lightModel"
+ },
+ {
+ "uuid": "{00000000-0000-0000-0000-000000000009}",
+ "type": "exposureFunction"
+ }
+ ],
+ "edges": [
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000002}",
+ "sourcePort": "texture",
+ "targetUuid": "{00000000-0000-0000-0000-000000000007}",
+ "targetPort": "sampler"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000003}",
+ "sourcePort": "texCoord",
+ "targetUuid": "{00000000-0000-0000-0000-000000000007}",
+ "targetPort": "coord"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000001}",
+ "sourcePort": "worldPosition",
+ "targetUuid": "{00000000-0000-0000-0000-000000000008}",
+ "targetPort": "position"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000007}",
+ "sourcePort": "color",
+ "targetUuid": "{00000000-0000-0000-0000-000000000008}",
+ "targetPort": "baseColor"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000004}",
+ "sourcePort": "lightIntensity",
+ "targetUuid": "{00000000-0000-0000-0000-000000000008}",
+ "targetPort": "lightIntensity"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000008}",
+ "sourcePort": "outputColor",
+ "targetUuid": "{00000000-0000-0000-0000-000000000009}",
+ "targetPort": "inputColor"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000005}",
+ "sourcePort": "exposure",
+ "targetUuid": "{00000000-0000-0000-0000-000000000009}",
+ "targetPort": "exposure"
+ },
+ {
+ "sourceUuid": "{00000000-0000-0000-0000-000000000009}",
+ "sourcePort": "outputColor",
+ "targetUuid": "{00000000-0000-0000-0000-000000000006}",
+ "targetPort": "fragColor"
+ }
+ ]
+}
diff --git a/tests/auto/render/shaderbuilder/lightmodel.es2.inc b/tests/auto/render/shaderbuilder/lightmodel.es2.inc
new file mode 100644
index 000000000..8e603d9a8
--- /dev/null
+++ b/tests/auto/render/shaderbuilder/lightmodel.es2.inc
@@ -0,0 +1,6 @@
+highp vec4 lightModel(const in highp vec3 baseColor,
+ const in highp vec3 pos,
+ const in highp float intensity)
+{
+ ...
+}
diff --git a/tests/auto/render/shaderbuilder/lightmodel.gl3.inc b/tests/auto/render/shaderbuilder/lightmodel.gl3.inc
new file mode 100644
index 000000000..31615dfcd
--- /dev/null
+++ b/tests/auto/render/shaderbuilder/lightmodel.gl3.inc
@@ -0,0 +1,6 @@
+vec4 lightModel(const in vec3 baseColor,
+ const in vec3 pos,
+ const in float intensity)
+{
+ ...
+}
diff --git a/tests/auto/render/shaderbuilder/output.es2 b/tests/auto/render/shaderbuilder/output.es2
new file mode 100644
index 000000000..b543bc5ee
--- /dev/null
+++ b/tests/auto/render/shaderbuilder/output.es2
@@ -0,0 +1,36 @@
+#version 100
+
+varying highp vec3 worldPosition;
+uniform sampler2D texture;
+varying highp vec2 texCoord;
+uniform highp float lightIntensity;
+uniform highp float exposure;
+highp vec4 lightModel(const in highp vec3 baseColor,
+ const in highp vec3 pos,
+ const in highp float intensity)
+{
+ ...
+}
+
+#line 9
+highp vec4 lightModel(const in highp vec3 baseColor,
+ const in highp vec3 pos,
+ const in highp float intensity)
+{
+ ...
+}
+
+#line 11
+
+void main()
+{
+ highp vec2 v2 = texCoord;
+ sampler2D v1 = texture;
+ highp float v3 = lightIntensity;
+ highp vec4 v5 = texture2D(v1, v2);
+ highp vec3 v0 = worldPosition;
+ highp float v4 = exposure;
+ highp vec4 v6 = lightModel(v5, v0, v3);
+ highp vec4 v7 = v6 * pow(2.0, v4);
+ gl_fragColor = v7;
+}
diff --git a/tests/auto/render/shaderbuilder/output.gl3 b/tests/auto/render/shaderbuilder/output.gl3
new file mode 100644
index 000000000..95a9c53fd
--- /dev/null
+++ b/tests/auto/render/shaderbuilder/output.gl3
@@ -0,0 +1,37 @@
+#version 150 core
+
+in vec3 worldPosition;
+uniform sampler2D texture;
+in vec2 texCoord;
+uniform float lightIntensity;
+uniform float exposure;
+out vec4 fragColor;
+vec4 lightModel(const in vec3 baseColor,
+ const in vec3 pos,
+ const in float intensity)
+{
+ ...
+}
+
+#line 10
+vec4 lightModel(const in vec3 baseColor,
+ const in vec3 pos,
+ const in float intensity)
+{
+ ...
+}
+
+#line 12
+
+void main()
+{
+ vec2 v2 = texCoord;
+ sampler2D v1 = texture;
+ float v3 = lightIntensity;
+ vec4 v5 = texture2D(v1, v2);
+ vec3 v0 = worldPosition;
+ float v4 = exposure;
+ vec4 v6 = lightModel(v5, v0, v3);
+ vec4 v7 = v6 * pow(2.0, v4);
+ fragColor = v7;
+}
diff --git a/tests/auto/render/shaderbuilder/prototypes.json b/tests/auto/render/shaderbuilder/prototypes.json
new file mode 100644
index 000000000..e9bf2e802
--- /dev/null
+++ b/tests/auto/render/shaderbuilder/prototypes.json
@@ -0,0 +1,237 @@
+{
+ "worldPosition": {
+ "outputs": [
+ "worldPosition"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec3 $worldPosition = worldPosition;",
+ "headerSnippets": [ "varying highp vec3 worldPosition;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 2
+ },
+ "substitution": "vec3 $worldPosition = worldPosition;",
+ "headerSnippets": [ "in vec3 worldPosition;" ]
+ }
+ ]
+ },
+ "texture": {
+ "outputs": [
+ "texture"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "sampler2D $texture = texture;",
+ "headerSnippets": [ "uniform sampler2D texture;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 2
+ },
+ "substitution": "sampler2D $texture = texture;",
+ "headerSnippets": [ "uniform sampler2D texture;" ]
+ }
+ ]
+ },
+ "texCoord": {
+ "outputs": [
+ "texCoord"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec2 $texCoord = texCoord;",
+ "headerSnippets": [ "varying highp vec2 texCoord;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 2
+ },
+ "substitution": "vec2 $texCoord = texCoord;",
+ "headerSnippets": [ "in vec2 texCoord;" ]
+ }
+ ]
+ },
+ "lightIntensity": {
+ "outputs": [
+ "lightIntensity"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp float $lightIntensity = lightIntensity;",
+ "headerSnippets": [ "uniform highp float lightIntensity;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 2
+ },
+ "substitution": "float $lightIntensity = lightIntensity;",
+ "headerSnippets": [ "uniform float lightIntensity;" ]
+ }
+ ]
+ },
+ "exposure": {
+ "outputs": [
+ "exposure"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp float $exposure = exposure;",
+ "headerSnippets": [ "uniform highp float exposure;" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 2
+ },
+ "substitution": "float $exposure = exposure;",
+ "headerSnippets": [ "uniform float exposure;" ]
+ }
+ ]
+ },
+ "fragColor": {
+ "inputs": [
+ "fragColor"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "gl_fragColor = $fragColor;"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 2
+ },
+ "substitution": "fragColor = $fragColor;",
+ "headerSnippets": [ "out vec4 fragColor;" ]
+ }
+ ]
+ },
+ "sampleTexture": {
+ "inputs": [
+ "sampler",
+ "coord"
+ ],
+ "outputs": [
+ "color"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $color = texture2D($sampler, $coord);"
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 2
+ },
+ "substitution": "vec4 $color = texture2D($sampler, $coord);"
+ }
+ ]
+ },
+ "lightModel": {
+ "inputs": [
+ "baseColor",
+ "position",
+ "lightIntensity"
+ ],
+ "outputs": [
+ "outputColor"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $outputColor = lightModel($baseColor, $position, $lightIntensity);",
+ "headerSnippets": [ "#pragma include lightmodel.es2.inc" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 2
+ },
+ "substitution": "vec4 $outputColor = lightModel($baseColor, $position, $lightIntensity);",
+ "headerSnippets": [ "#pragma include lightmodel.gl3.inc" ]
+ }
+ ]
+ },
+ "exposureFunction": {
+ "inputs": [
+ "inputColor",
+ "exposure"
+ ],
+ "outputs": [
+ "outputColor"
+ ],
+ "rules": [
+ {
+ "format": {
+ "api": "OpenGLES",
+ "major": 2,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $outputColor = $inputColor * pow(2.0, $exposure);",
+ "headerSnippets": [ "#pragma include :/lightmodel.es2.inc" ]
+ },
+ {
+ "format": {
+ "api": "OpenGLCoreProfile",
+ "major": 3,
+ "minor": 2
+ },
+ "substitution": "vec4 $outputColor = $inputColor * pow(2.0, $exposure);",
+ "headerSnippets": [ "#pragma include :/lightmodel.gl3.inc" ]
+ }
+ ]
+ }
+}
diff --git a/tests/auto/render/shaderbuilder/shaderbuilder.pro b/tests/auto/render/shaderbuilder/shaderbuilder.pro
new file mode 100644
index 000000000..bd5f7dfe2
--- /dev/null
+++ b/tests/auto/render/shaderbuilder/shaderbuilder.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+
+TARGET = tst_shaderbuilder
+
+QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_shaderbuilder.cpp
+RESOURCES += shaderbuilder.qrc
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/shaderbuilder/shaderbuilder.qrc b/tests/auto/render/shaderbuilder/shaderbuilder.qrc
new file mode 100644
index 000000000..92ab0405c
--- /dev/null
+++ b/tests/auto/render/shaderbuilder/shaderbuilder.qrc
@@ -0,0 +1,10 @@
+<RCC>
+ <qresource prefix="/">
+ <file>prototypes.json</file>
+ <file>input.json</file>
+ <file>output.gl3</file>
+ <file>output.es2</file>
+ <file>lightmodel.gl3.inc</file>
+ <file>lightmodel.es2.inc</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp
new file mode 100644
index 000000000..6557acb6c
--- /dev/null
+++ b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp
@@ -0,0 +1,548 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** 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 <qbackendnodetester.h>
+#include <Qt3DRender/private/shaderbuilder_p.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qshaderprogrambuilder.h>
+#include "testrenderer.h"
+
+Q_DECLARE_METATYPE(Qt3DRender::Render::ShaderBuilder::ShaderType)
+
+class tst_ShaderBuilder : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+private slots:
+ void shouldHaveGlobalDefaultPrototypes()
+ {
+ // GIVEN
+
+ // THEN
+ QCOMPARE(Qt3DRender::Render::ShaderBuilder::getPrototypesFile(), QStringLiteral(":/prototypes/default.json"));
+ QVERIFY(!Qt3DRender::Render::ShaderBuilder::getPrototypeNames().isEmpty());
+
+ // WHEN
+ Qt3DRender::Render::ShaderBuilder::setPrototypesFile(":/prototypes.json");
+
+ // THEN
+ QCOMPARE(Qt3DRender::Render::ShaderBuilder::getPrototypesFile(), QStringLiteral(":/prototypes.json"));
+ auto prototypeNames = Qt3DRender::Render::ShaderBuilder::getPrototypeNames();
+ prototypeNames.sort();
+ const auto expectedPrototypeNames = QStringList() << "exposure"
+ << "exposureFunction"
+ << "fragColor"
+ << "lightIntensity"
+ << "lightModel"
+ << "sampleTexture"
+ << "texCoord"
+ << "texture"
+ << "worldPosition";
+ QCOMPARE(prototypeNames, expectedPrototypeNames);
+ }
+
+ void shouldHaveInitialState()
+ {
+ // GIVEN
+ Qt3DRender::Render::ShaderBuilder shaderBuilder;
+
+ // THEN
+ QVERIFY(!shaderBuilder.isEnabled());
+ QVERIFY(shaderBuilder.enabledLayers().isEmpty());
+ for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) {
+ const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i);
+ QCOMPARE(shaderBuilder.shaderGraph(type), QUrl());
+ QCOMPARE(shaderBuilder.shaderCode(type), QByteArray());
+ QVERIFY(!shaderBuilder.isShaderCodeDirty(type));
+ }
+ }
+
+ void shouldHavePropertiesMirroringFromItsPeer_data()
+ {
+ QTest::addColumn<Qt3DRender::QShaderProgramBuilder*>("frontend");
+
+ {
+ auto frontend = new Qt3DRender::QShaderProgramBuilder;
+ QTest::newRow("empty") << frontend;
+ }
+ {
+ auto frontend = new Qt3DRender::QShaderProgramBuilder;
+ auto program = new Qt3DRender::QShaderProgram(frontend);
+ frontend->setShaderProgram(program);
+ QTest::newRow("shaderProgram") << frontend;
+ }
+ {
+ auto frontend = new Qt3DRender::QShaderProgramBuilder;
+ frontend->setEnabledLayers({"foo", "bar"});
+ QTest::newRow("enabledLayers") << frontend;
+ }
+ {
+ auto frontend = new Qt3DRender::QShaderProgramBuilder;
+ frontend->setVertexShaderGraph(QUrl::fromEncoded("qrc:/vertex.json"));
+ QTest::newRow("vertex") << frontend;
+ }
+ {
+ auto frontend = new Qt3DRender::QShaderProgramBuilder;
+ frontend->setTessellationControlShaderGraph(QUrl::fromEncoded("qrc:/tesscontrol.json"));
+ QTest::newRow("tessellationControl") << frontend;
+ }
+ {
+ auto frontend = new Qt3DRender::QShaderProgramBuilder;
+ frontend->setTessellationEvaluationShaderGraph(QUrl::fromEncoded("qrc:/tesseval.json"));
+ QTest::newRow("tessellationEvaluation") << frontend;
+ }
+ {
+ auto frontend = new Qt3DRender::QShaderProgramBuilder;
+ frontend->setGeometryShaderGraph(QUrl::fromEncoded("qrc:/geometry.json"));
+ QTest::newRow("geometry") << frontend;
+ }
+ {
+ auto frontend = new Qt3DRender::QShaderProgramBuilder;
+ frontend->setFragmentShaderGraph(QUrl::fromEncoded("qrc:/fragment.json"));
+ QTest::newRow("fragment") << frontend;
+ }
+ {
+ auto frontend = new Qt3DRender::QShaderProgramBuilder;
+ frontend->setComputeShaderGraph(QUrl::fromEncoded("qrc:/compute.json"));
+ QTest::newRow("compute") << frontend;
+ }
+ }
+
+ void shouldHavePropertiesMirroringFromItsPeer()
+ {
+ // GIVEN
+ QFETCH(Qt3DRender::QShaderProgramBuilder*, frontend);
+ Qt3DRender::Render::ShaderBuilder backend;
+
+ // WHEN
+ simulateInitialization(frontend, &backend);
+
+ // THEN
+ QVERIFY(backend.isEnabled() == frontend->isEnabled());
+
+ if (frontend->shaderProgram())
+ QCOMPARE(backend.shaderProgramId(), frontend->shaderProgram()->id());
+ else
+ QVERIFY(backend.shaderProgramId().isNull());
+
+ QCOMPARE(backend.enabledLayers(), frontend->enabledLayers());
+
+ QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::Vertex), frontend->vertexShaderGraph());
+ QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::Vertex), QByteArray());
+ QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::Vertex), !frontend->vertexShaderGraph().isEmpty());
+
+ QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::TessellationControl), frontend->tessellationControlShaderGraph());
+ QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::TessellationControl), QByteArray());
+ QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::TessellationControl), !frontend->tessellationControlShaderGraph().isEmpty());
+
+ QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::TessellationEvaluation), frontend->tessellationEvaluationShaderGraph());
+ QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::TessellationEvaluation), QByteArray());
+ QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::TessellationEvaluation), !frontend->tessellationEvaluationShaderGraph().isEmpty());
+
+ QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::Geometry), frontend->geometryShaderGraph());
+ QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::Geometry), QByteArray());
+ QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::Geometry), !frontend->geometryShaderGraph().isEmpty());
+
+ QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::Fragment), frontend->fragmentShaderGraph());
+ QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::Fragment), QByteArray());
+ QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::Fragment), !frontend->fragmentShaderGraph().isEmpty());
+
+ QCOMPARE(backend.shaderGraph(Qt3DRender::Render::ShaderBuilder::Compute), frontend->computeShaderGraph());
+ QCOMPARE(backend.shaderCode(Qt3DRender::Render::ShaderBuilder::Compute), QByteArray());
+ QCOMPARE(backend.isShaderCodeDirty(Qt3DRender::Render::ShaderBuilder::Compute), !frontend->computeShaderGraph().isEmpty());
+
+ // WHEN
+ backend.cleanup();
+
+ // THEN
+ QVERIFY(!backend.isEnabled());
+ QVERIFY(backend.enabledLayers().isEmpty());
+ for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) {
+ const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i);
+ QCOMPARE(backend.shaderGraph(type), QUrl());
+ QCOMPARE(backend.shaderCode(type), QByteArray());
+ QVERIFY(!backend.isShaderCodeDirty(type));
+ }
+
+ delete frontend;
+ }
+
+ void shouldHandleEnablePropertyChange()
+ {
+ // GIVEN
+ Qt3DRender::Render::ShaderBuilder backend;
+ TestRenderer renderer;
+ backend.setRenderer(&renderer);
+
+ // WHEN
+ auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(true);
+ updateChange->setPropertyName("enabled");
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QVERIFY(backend.isEnabled());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(false);
+ updateChange->setPropertyName("enabled");
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QVERIFY(!backend.isEnabled());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(true);
+ updateChange->setPropertyName("enabled");
+ backend.sceneChangeEvent(updateChange);
+ // AND
+ backend.cleanup();
+
+ // THEN
+ QVERIFY(!backend.isEnabled());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+ }
+
+ void shouldHandleShaderProgramPropertyChange()
+ {
+ // GIVEN
+ Qt3DRender::Render::ShaderBuilder backend;
+ TestRenderer renderer;
+ backend.setRenderer(&renderer);
+ const auto programId = Qt3DCore::QNodeId::createId();
+
+ // WHEN
+ auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(QVariant::fromValue(programId));
+ updateChange->setPropertyName("shaderProgram");
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.shaderProgramId(), programId);
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(QVariant::fromValue(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("shaderProgram");
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QVERIFY(backend.shaderProgramId().isNull());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(QVariant::fromValue(programId));
+ updateChange->setPropertyName("shaderProgram");
+ backend.sceneChangeEvent(updateChange);
+ // AND
+ backend.cleanup();
+
+ // THEN
+ QVERIFY(backend.shaderProgramId().isNull());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+ }
+
+ void shouldHandleEnabledLayersPropertyChange()
+ {
+ // GIVEN
+ Qt3DRender::Render::ShaderBuilder backend;
+ TestRenderer renderer;
+ backend.setRenderer(&renderer);
+ const auto layers = QStringList() << "foo" << "bar";
+
+ for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) {
+ const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i);
+ const auto graphUrl = QUrl::fromEncoded("qrc:/input.json");
+ backend.setShaderGraph(type, graphUrl);
+ }
+
+ // WHEN
+ auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(layers);
+ updateChange->setPropertyName("enabledLayers");
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.enabledLayers(), layers);
+ for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) {
+ const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i);
+ QVERIFY(backend.isShaderCodeDirty(type));
+ backend.generateCode(type); // Resets the dirty flag
+ }
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(layers);
+ updateChange->setPropertyName("enabledLayers");
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.enabledLayers(), layers);
+ for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) {
+ const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i);
+ QVERIFY(!backend.isShaderCodeDirty(type));
+ backend.generateCode(type); // Resets the dirty flag
+ }
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(QStringList());
+ updateChange->setPropertyName("enabledLayers");
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QVERIFY(backend.shaderProgramId().isNull());
+ for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) {
+ const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i);
+ QVERIFY(backend.isShaderCodeDirty(type));
+ backend.generateCode(type); // Resets the dirty flag
+ }
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(layers);
+ updateChange->setPropertyName("enabledLayers");
+ backend.sceneChangeEvent(updateChange);
+ // AND
+ backend.cleanup();
+
+ // THEN
+ QVERIFY(backend.enabledLayers().isEmpty());
+ for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) {
+ const auto type = static_cast<Qt3DRender::Render::ShaderBuilder::ShaderType>(i);
+ QVERIFY(!backend.isShaderCodeDirty(type));
+ backend.generateCode(type); // Resets the dirty flag
+ }
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+ }
+
+ void shouldHandleShaderGraphPropertiesChanges_data()
+ {
+ QTest::addColumn<QByteArray>("property");
+ QTest::addColumn<Qt3DRender::Render::ShaderBuilder::ShaderType>("type");
+ QTest::addColumn<QUrl>("graphUrl");
+
+ QTest::newRow("vertex") << QByteArrayLiteral("vertexShaderGraph")
+ << Qt3DRender::Render::ShaderBuilder::Vertex
+ << QUrl::fromEncoded("qrc:/vertex.json");
+
+ QTest::newRow("tessControl") << QByteArrayLiteral("tessellationControlShaderGraph")
+ << Qt3DRender::Render::ShaderBuilder::TessellationControl
+ << QUrl::fromEncoded("qrc:/tesscontrol.json");
+
+ QTest::newRow("tessEval") << QByteArrayLiteral("tessellationEvaluationShaderGraph")
+ << Qt3DRender::Render::ShaderBuilder::TessellationEvaluation
+ << QUrl::fromEncoded("qrc:/tesseval.json");
+
+ QTest::newRow("geometry") << QByteArrayLiteral("geometryShaderGraph")
+ << Qt3DRender::Render::ShaderBuilder::Geometry
+ << QUrl::fromEncoded("qrc:/geometry.json");
+
+ QTest::newRow("fragment") << QByteArrayLiteral("fragmentShaderGraph")
+ << Qt3DRender::Render::ShaderBuilder::Fragment
+ << QUrl::fromEncoded("qrc:/fragment.json");
+
+ QTest::newRow("compute") << QByteArrayLiteral("computeShaderGraph")
+ << Qt3DRender::Render::ShaderBuilder::Compute
+ << QUrl::fromEncoded("qrc:/compute.json");
+ }
+
+ void shouldHandleShaderGraphPropertiesChanges()
+ {
+ // GIVEN
+ QFETCH(QByteArray, property);
+ QFETCH(Qt3DRender::Render::ShaderBuilder::ShaderType, type);
+ QFETCH(QUrl, graphUrl);
+
+ Qt3DRender::Render::ShaderBuilder backend;
+ TestRenderer renderer;
+ backend.setRenderer(&renderer);
+
+ // WHEN
+ auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(QUrl());
+ updateChange->setPropertyName(property);
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), QUrl());
+ QVERIFY(!backend.isShaderCodeDirty(type));
+ QVERIFY(backend.shaderCode(type).isEmpty());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(graphUrl);
+ updateChange->setPropertyName(property);
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), graphUrl);
+ QVERIFY(backend.isShaderCodeDirty(type));
+ QVERIFY(backend.shaderCode(type).isEmpty());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(QUrl());
+ updateChange->setPropertyName(property);
+ backend.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), QUrl());
+ QVERIFY(backend.isShaderCodeDirty(type));
+ QVERIFY(backend.shaderCode(type).isEmpty());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+
+ // WHEN
+ updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ updateChange->setValue(graphUrl);
+ updateChange->setPropertyName(property);
+ backend.sceneChangeEvent(updateChange);
+ // AND
+ backend.cleanup();
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), QUrl());
+ QVERIFY(!backend.isShaderCodeDirty(type));
+ QVERIFY(backend.shaderCode(type).isEmpty());
+ QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty);
+ renderer.resetDirty();
+ }
+
+ void shouldHandleShaderCodeGeneration_data()
+ {
+ QTest::addColumn<Qt3DRender::Render::ShaderBuilder::ShaderType>("type");
+
+ QTest::newRow("vertex") << Qt3DRender::Render::ShaderBuilder::Vertex;
+ QTest::newRow("tessControl") << Qt3DRender::Render::ShaderBuilder::TessellationControl;
+ QTest::newRow("tessEval") << Qt3DRender::Render::ShaderBuilder::TessellationEvaluation;
+ QTest::newRow("geometry") << Qt3DRender::Render::ShaderBuilder::Geometry;
+ QTest::newRow("fragment") << Qt3DRender::Render::ShaderBuilder::Fragment;
+ QTest::newRow("compute") << Qt3DRender::Render::ShaderBuilder::Compute;
+ }
+
+ void shouldHandleShaderCodeGeneration()
+ {
+ // GIVEN
+ Qt3DRender::Render::ShaderBuilder::setPrototypesFile(":/prototypes.json");
+ QVERIFY(!Qt3DRender::Render::ShaderBuilder::getPrototypeNames().isEmpty());
+
+ QFETCH(Qt3DRender::Render::ShaderBuilder::ShaderType, type);
+
+ const auto gl3Api = []{
+ auto api = Qt3DRender::GraphicsApiFilterData();
+ api.m_api = Qt3DRender::QGraphicsApiFilter::OpenGL;
+ api.m_profile = Qt3DRender::QGraphicsApiFilter::CoreProfile;
+ api.m_major = 3;
+ api.m_minor = 2;
+ return api;
+ }();
+
+ const auto es2Api = []{
+ auto api = Qt3DRender::GraphicsApiFilterData();
+ api.m_api = Qt3DRender::QGraphicsApiFilter::OpenGLES;
+ api.m_major = 2;
+ api.m_minor = 0;
+ return api;
+ }();
+
+ const auto readCode = [](const QString &suffix) -> QString {
+ const auto filePath = QStringLiteral(":/output.") + suffix;
+ QFile file(filePath);
+ if (!file.open(QFile::ReadOnly | QFile::Text))
+ qFatal("File open failed: %s", qPrintable(filePath));
+ return file.readAll();
+ };
+
+ const auto gl3Code = readCode("gl3");
+ const auto es2Code = readCode("es2");
+
+ Qt3DRender::Render::ShaderBuilder backend;
+
+ // WHEN
+ const auto graphUrl = QUrl::fromEncoded("qrc:/input.json");
+ backend.setShaderGraph(type, graphUrl);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), graphUrl);
+ QVERIFY(backend.isShaderCodeDirty(type));
+ QVERIFY(backend.shaderCode(type).isEmpty());
+
+ // WHEN
+ backend.setGraphicsApi(gl3Api);
+ backend.generateCode(type);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), graphUrl);
+ QVERIFY(!backend.isShaderCodeDirty(type));
+ QCOMPARE(backend.shaderCode(type), gl3Code);
+
+ // WHEN
+ backend.setGraphicsApi(es2Api);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), graphUrl);
+ QVERIFY(backend.isShaderCodeDirty(type));
+ QCOMPARE(backend.shaderCode(type), gl3Code);
+
+ // WHEN
+ backend.generateCode(type);
+
+ // THEN
+ QCOMPARE(backend.shaderGraph(type), graphUrl);
+ QVERIFY(!backend.isShaderCodeDirty(type));
+// QCOMPARE(backend.shaderCode(type), es2Code);
+ }
+};
+
+QTEST_MAIN(tst_ShaderBuilder)
+
+#include "tst_shaderbuilder.moc"
diff --git a/tests/auto/render/skeleton/skeleton.pro b/tests/auto/render/skeleton/skeleton.pro
new file mode 100644
index 000000000..8dbd1b3df
--- /dev/null
+++ b/tests/auto/render/skeleton/skeleton.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+
+TARGET = tst_skeleton
+
+QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_skeleton.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/skeleton/tst_skeleton.cpp b/tests/auto/render/skeleton/tst_skeleton.cpp
new file mode 100644
index 000000000..499bb7cc7
--- /dev/null
+++ b/tests/auto/render/skeleton/tst_skeleton.cpp
@@ -0,0 +1,405 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** 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 <Qt3DRender/private/skeleton_p.h>
+#include <Qt3DRender/private/nodemanagers_p.h>
+#include <Qt3DCore/qjoint.h>
+#include <Qt3DCore/qskeleton.h>
+#include <Qt3DCore/qskeletonloader.h>
+#include <Qt3DCore/private/qnode_p.h>
+#include <Qt3DCore/private/qscene_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DCore/private/qbackendnode_p.h>
+#include <Qt3DCore/private/qpropertyupdatedchangebase_p.h>
+#include <qbackendnodetester.h>
+#include <testpostmanarbiter.h>
+#include <testrenderer.h>
+
+using namespace Qt3DCore;
+using namespace Qt3DRender;
+using namespace Qt3DRender::Render;
+
+Q_DECLARE_METATYPE(Qt3DRender::Render::JointInfo)
+Q_DECLARE_METATYPE(Qt3DRender::Render::SkeletonData)
+Q_DECLARE_METATYPE(Qt3DCore::Sqt)
+
+namespace {
+
+void linearizeTreeHelper(QJoint *joint, QVector<QJoint *> &joints)
+{
+ joints.push_back(joint);
+ for (const auto child : joint->childJoints())
+ linearizeTreeHelper(child, joints);
+}
+
+QVector<QJoint *> linearizeTree(QJoint *rootJoint)
+{
+ QVector<QJoint *> joints;
+ linearizeTreeHelper(rootJoint, joints);
+ return joints;
+}
+
+}
+
+class tst_Skeleton : public Qt3DCore::QBackendNodeTester
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void checkPeerPropertyMirroring()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ NodeManagers nodeManagers;
+ renderer.setNodeManagers(&nodeManagers);
+ Skeleton backendSkeleton;
+ backendSkeleton.setRenderer(&renderer);
+ backendSkeleton.setSkeletonManager(nodeManagers.skeletonManager());
+ QSkeletonLoader skeleton;
+
+ skeleton.setSource(QUrl::fromLocalFile("funnybones.json"));
+
+ // WHEN
+ simulateInitialization(&skeleton, &backendSkeleton);
+
+ // THEN
+ QCOMPARE(backendSkeleton.peerId(), skeleton.id());
+ QCOMPARE(backendSkeleton.isEnabled(), skeleton.isEnabled());
+ QCOMPARE(backendSkeleton.source(), skeleton.source());
+ QCOMPARE(backendSkeleton.rootJointId(), QNodeId());
+
+ // GIVEN
+ Skeleton backendSkeleton2;
+ backendSkeleton2.setRenderer(&renderer);
+ backendSkeleton2.setSkeletonManager(nodeManagers.skeletonManager());
+ QSkeleton skeleton2;
+
+ QJoint *joint = new QJoint();
+ skeleton2.setRootJoint(joint);
+
+ // WHEN
+ simulateInitialization(&skeleton2, &backendSkeleton2);
+
+ // THEN
+ QCOMPARE(backendSkeleton2.peerId(), skeleton2.id());
+ QCOMPARE(backendSkeleton2.isEnabled(), skeleton2.isEnabled());
+ QCOMPARE(backendSkeleton2.source(), QUrl());
+ QCOMPARE(backendSkeleton2.rootJointId(), joint->id());
+ }
+
+ void checkInitialAndCleanedUpState()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ NodeManagers nodeManagers;
+ renderer.setNodeManagers(&nodeManagers);
+ Skeleton backendSkeleton;
+ backendSkeleton.setRenderer(&renderer);
+ backendSkeleton.setSkeletonManager(nodeManagers.skeletonManager());
+
+ // THEN
+ QVERIFY(backendSkeleton.peerId().isNull());
+ QCOMPARE(backendSkeleton.isEnabled(), false);
+ QCOMPARE(backendSkeleton.source(), QUrl());
+ QCOMPARE(backendSkeleton.status(), QSkeletonLoader::NotReady);
+ QCOMPARE(backendSkeleton.rootJointId(), QNodeId());
+
+ // GIVEN
+ QSkeletonLoader skeleton;
+ skeleton.setSource(QUrl::fromLocalFile("skeleton1.json"));
+
+ // WHEN
+ simulateInitialization(&skeleton, &backendSkeleton);
+ backendSkeleton.cleanup();
+
+ // THEN
+ QCOMPARE(backendSkeleton.source(), QUrl());
+ QCOMPARE(backendSkeleton.isEnabled(), false);
+ QCOMPARE(backendSkeleton.status(), QSkeletonLoader::NotReady);
+ QCOMPARE(backendSkeleton.rootJointId(), QNodeId());
+ }
+
+ void checkPropertyChanges()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ NodeManagers nodeManagers;
+ renderer.setNodeManagers(&nodeManagers);
+ Skeleton backendSkeleton;
+ backendSkeleton.setRenderer(&renderer);
+ backendSkeleton.setSkeletonManager(nodeManagers.skeletonManager());
+ backendSkeleton.setDataType(Skeleton::File);
+ Qt3DCore::QPropertyUpdatedChangePtr updateChange;
+
+ // Initialize to ensure skeleton manager is set
+ QSkeletonLoader skeleton;
+ skeleton.setSource(QUrl::fromLocalFile("skeleton1.json"));
+ simulateInitialization(&skeleton, &backendSkeleton);
+
+ // WHEN
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("enabled");
+ updateChange->setValue(true);
+ backendSkeleton.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendSkeleton.isEnabled(), true);
+
+ // WHEN
+ const QUrl newSource = QUrl::fromLocalFile("terminator.json");
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("source");
+ updateChange->setValue(newSource);
+ backendSkeleton.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendSkeleton.source(), newSource);
+
+ // WHEN
+ const QNodeId newRootJointId = QNodeId::createId();
+ updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange->setPropertyName("rootJoint");
+ updateChange->setValue(QVariant::fromValue(newRootJointId));
+ backendSkeleton.sceneChangeEvent(updateChange);
+
+ // THEN
+ QCOMPARE(backendSkeleton.rootJointId(), newRootJointId);
+ }
+
+ void checkStatusPropertyBackendNotification()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ NodeManagers nodeManagers;
+ renderer.setNodeManagers(&nodeManagers);
+ TestArbiter arbiter;
+ Skeleton backendSkeleton;
+ backendSkeleton.setRenderer(&renderer);
+ backendSkeleton.setSkeletonManager(nodeManagers.skeletonManager());
+ backendSkeleton.setEnabled(true);
+ Qt3DCore::QBackendNodePrivate::get(&backendSkeleton)->setArbiter(&arbiter);
+
+ // WHEN
+ backendSkeleton.setStatus(QSkeletonLoader::Error);
+
+ // THEN
+ QCOMPARE(backendSkeleton.status(), QSkeletonLoader::Error);
+ QCOMPARE(arbiter.events.count(), 1);
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "status");
+ QCOMPARE(change->value().value<QSkeletonLoader::Status>(), backendSkeleton.status());
+ QCOMPARE(Qt3DCore::QPropertyUpdatedChangeBasePrivate::get(change.data())->m_isIntermediate,
+ false);
+
+ arbiter.events.clear();
+
+ // WHEN
+ backendSkeleton.setStatus(QSkeletonLoader::Error);
+
+ // THEN
+ QCOMPARE(backendSkeleton.status(), QSkeletonLoader::Error);
+ QCOMPARE(arbiter.events.count(), 0);
+
+ arbiter.events.clear();
+ }
+
+ void checkCreateFrontendJoint_data()
+ {
+ QTest::addColumn<QMatrix4x4>("inverseBindMatrix");
+ QTest::addColumn<Qt3DCore::Sqt>("localPose");
+ QTest::addColumn<QString>("jointName");
+ QTest::addColumn<QJoint *>("expectedJoint");
+
+ QMatrix4x4 m;
+ Qt3DCore::Sqt localPose;
+ QTest::newRow("default") << m << localPose << QString() << new QJoint();
+
+ const QVector3D t(1.0f, 2.0f, 3.0f);
+ const QQuaternion r = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 45.0f);
+ const QVector3D s(1.5f, 2.5f, 3.5f);
+ localPose.scale = s;
+ localPose.rotation = r;
+ localPose.translation = t;
+
+
+ QString name = QLatin1String("Foo");
+ QJoint *joint = new QJoint();
+ joint->setTranslation(t);
+ joint->setRotation(r);
+ joint->setScale(s);
+ joint->setName(name);
+ joint->setInverseBindMatrix(m);
+ QTest::newRow("localPose") << m << localPose << name << joint;
+
+ m.rotate(r);
+ m.scale(QVector3D(1.0f, 1.0f, 1.0f) / s);
+ m.translate(-t);
+ name = QLatin1String("Bar");
+
+ joint = new QJoint();
+ joint->setTranslation(t);
+ joint->setRotation(r);
+ joint->setScale(s);
+ joint->setInverseBindMatrix(m);
+ joint->setName(name);
+ QTest::newRow("inverseBind") << m << localPose << name << joint;
+ }
+
+ void checkCreateFrontendJoint()
+ {
+ // GIVEN
+ Skeleton backendSkeleton;
+ QFETCH(QMatrix4x4, inverseBindMatrix);
+ QFETCH(Qt3DCore::Sqt, localPose);
+ QFETCH(QString, jointName);
+ QFETCH(QJoint *, expectedJoint);
+
+ // WHEN
+ const QJoint *actualJoint = backendSkeleton.createFrontendJoint(jointName, localPose, inverseBindMatrix);
+
+ // THEN
+ QCOMPARE(actualJoint->scale(), expectedJoint->scale());
+ QCOMPARE(actualJoint->rotation(), expectedJoint->rotation());
+ QCOMPARE(actualJoint->translation(), expectedJoint->translation());
+ QCOMPARE(actualJoint->inverseBindMatrix(), expectedJoint->inverseBindMatrix());
+ QCOMPARE(actualJoint->name(), expectedJoint->name());
+
+ // Cleanup
+ delete actualJoint;
+ delete expectedJoint;
+ }
+
+ void checkCreateFrontendJoints_data()
+ {
+ QTest::addColumn<SkeletonData>("skeletonData");
+ QTest::addColumn<QJoint *>("expectedRootJoint");
+
+ QTest::newRow("empty") << SkeletonData() << (QJoint*)nullptr;
+
+ SkeletonData skeletonData;
+ JointInfo rootJointInfo;
+ skeletonData.joints.push_back(rootJointInfo);
+ skeletonData.jointNames.push_back(QLatin1String("rootJoint"));
+ skeletonData.localPoses.push_back(Qt3DCore::Sqt());
+ const int childCount = 10;
+ for (int i = 0; i < childCount; ++i) {
+ JointInfo childJointInfo;
+ childJointInfo.parentIndex = 0;
+ skeletonData.joints.push_back(childJointInfo);
+
+ const float x = static_cast<float>(i);
+ Qt3DCore::Sqt localPose;
+ localPose.translation = QVector3D(x, x, x);
+ skeletonData.localPoses.push_back(localPose);
+
+ skeletonData.jointNames.push_back(QString("Child-%1").arg(i));
+ }
+
+ QJoint *rootJoint = new QJoint();
+ for (int i = 0; i < childCount; ++i) {
+ QJoint *childJoint = new QJoint();
+ const float x = static_cast<float>(i);
+ childJoint->setTranslation(QVector3D(x, x, x));
+ rootJoint->addChildJoint(childJoint);
+ }
+
+ QTest::newRow("wide") << skeletonData << rootJoint;
+
+ skeletonData.joints.clear();
+ skeletonData.joints.push_back(rootJointInfo);
+ for (int i = 0; i < childCount; ++i) {
+ JointInfo childJointInfo;
+ childJointInfo.parentIndex = i;
+ skeletonData.joints.push_back(childJointInfo);
+
+ const float x = static_cast<float>(i);
+ Qt3DCore::Sqt localPose;
+ localPose.translation = QVector3D(x, x, x);
+ skeletonData.localPoses.push_back(localPose);
+
+ skeletonData.jointNames.push_back(QString("Child-%1").arg(i));
+ }
+
+ rootJoint = new QJoint();
+ QJoint *previousJoint = rootJoint;
+ for (int i = 0; i < childCount; ++i) {
+ QJoint *childJoint = new QJoint();
+ const float x = static_cast<float>(i);
+ childJoint->setTranslation(QVector3D(x, x, x));
+ previousJoint->addChildJoint(childJoint);
+ previousJoint = childJoint;
+ }
+
+ QTest::newRow("deep") << skeletonData << rootJoint;
+ }
+
+ void checkCreateFrontendJoints()
+ {
+ // GIVEN
+ Skeleton backendSkeleton;
+ QFETCH(SkeletonData, skeletonData);
+ QFETCH(QJoint *, expectedRootJoint);
+
+ // WHEN
+ QJoint *actualRootJoint = backendSkeleton.createFrontendJoints(skeletonData);
+
+ // THEN
+ if (skeletonData.joints.isEmpty()) {
+ QVERIFY(actualRootJoint == expectedRootJoint); // nullptr
+ return;
+ }
+
+ // Linearise the tree of joints and check them against the skeletonData
+ QVector<QJoint *> joints = linearizeTree(actualRootJoint);
+ QCOMPARE(joints.size(), skeletonData.joints.size());
+ for (int i = 0; i < joints.size(); ++i) {
+ // Check the translations match
+ QCOMPARE(joints[i]->translation(), skeletonData.localPoses[i].translation);
+ }
+
+ // Now we know the order of Joints match. Check the parents match too
+ for (int i = 0; i < joints.size(); ++i) {
+ // Get parent index from joint info
+ const int parentIndex = skeletonData.joints[i].parentIndex;
+ if (parentIndex == -1) {
+ QVERIFY(joints[i]->parent() == nullptr);
+ } else {
+ QCOMPARE(joints[i]->parent(), joints[parentIndex]);
+ }
+ }
+
+ // Cleanup
+ delete actualRootJoint;
+ delete expectedRootJoint;
+ }
+};
+
+QTEST_APPLESS_MAIN(tst_Skeleton)
+
+#include "tst_skeleton.moc"
diff --git a/tests/auto/render/texture/tst_texture.cpp b/tests/auto/render/texture/tst_texture.cpp
index 9a84714a6..784186690 100644
--- a/tests/auto/render/texture/tst_texture.cpp
+++ b/tests/auto/render/texture/tst_texture.cpp
@@ -223,6 +223,8 @@ void tst_RenderTexture::checkPropertyChanges()
// THEN
QCOMPARE(backend.properties().width, 256);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TexturesDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
@@ -232,6 +234,8 @@ void tst_RenderTexture::checkPropertyChanges()
// THEN
QCOMPARE(backend.properties().height, 128);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TexturesDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
@@ -241,6 +245,8 @@ void tst_RenderTexture::checkPropertyChanges()
// THEN
QCOMPARE(backend.properties().depth, 16);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TexturesDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
@@ -250,6 +256,8 @@ void tst_RenderTexture::checkPropertyChanges()
// THEN
QCOMPARE(backend.properties().layers, 32);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TexturesDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
@@ -259,6 +267,8 @@ void tst_RenderTexture::checkPropertyChanges()
// THEN
QCOMPARE(backend.properties().samples, 64);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TexturesDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
QTEST_APPLESS_MAIN(tst_RenderTexture)
diff --git a/tests/auto/render/transform/tst_transform.cpp b/tests/auto/render/transform/tst_transform.cpp
index 26916b2ab..ebb27953d 100644
--- a/tests/auto/render/transform/tst_transform.cpp
+++ b/tests/auto/render/transform/tst_transform.cpp
@@ -127,6 +127,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendTransform.isEnabled(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TransformDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -138,6 +140,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendTransform.rotation(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TransformDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -149,6 +153,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendTransform.scale(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TransformDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -160,6 +166,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendTransform.translation(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::TransformDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
}
diff --git a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
index 1e76751cc..9b6481423 100644
--- a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
+++ b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
@@ -191,8 +191,8 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
positionAttribute->setByteStride(3*4);
positionAttribute->setByteOffset(0);
@@ -291,15 +291,15 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
positionAttribute->setByteStride(3*sizeof(float));
positionAttribute->setByteOffset(0);
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
indexAttribute->setBuffer(indexDataBuffer.data());
- indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedInt);
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(3*5);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
@@ -378,8 +378,8 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
positionAttribute->setByteStride(3*4);
positionAttribute->setByteOffset(0);
@@ -477,15 +477,15 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
positionAttribute->setByteStride(3*sizeof(float));
positionAttribute->setByteOffset(0);
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
indexAttribute->setBuffer(indexDataBuffer.data());
- indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedInt);
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(3*4);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
@@ -567,8 +567,8 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
positionAttribute->setByteStride(3*4);
positionAttribute->setByteOffset(0);
@@ -660,15 +660,15 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
positionAttribute->setByteStride(3*sizeof(float));
positionAttribute->setByteOffset(0);
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
indexAttribute->setBuffer(indexDataBuffer.data());
- indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedInt);
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(3*2);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
@@ -746,8 +746,8 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
positionAttribute->setByteStride(3*4);
positionAttribute->setByteOffset(0);
@@ -843,15 +843,15 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
positionAttribute->setByteStride(3*sizeof(float));
positionAttribute->setByteOffset(0);
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
indexAttribute->setBuffer(indexDataBuffer.data());
- indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedInt);
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(3*4);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
@@ -940,8 +940,8 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(8);
positionAttribute->setByteStride(3*4);
positionAttribute->setByteOffset(0);
@@ -1034,15 +1034,15 @@ private Q_SLOTS:
positionAttribute->setBuffer(dataBuffer.data());
positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
- positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
- positionAttribute->setDataSize(3);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
positionAttribute->setByteStride(3*sizeof(float));
positionAttribute->setByteOffset(0);
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
indexAttribute->setBuffer(indexDataBuffer.data());
- indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedInt);
+ indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(8);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
diff --git a/tests/auto/render/uniform/tst_uniform.cpp b/tests/auto/render/uniform/tst_uniform.cpp
index 47e64eafe..b8578b294 100644
--- a/tests/auto/render/uniform/tst_uniform.cpp
+++ b/tests/auto/render/uniform/tst_uniform.cpp
@@ -123,6 +123,26 @@ private Q_SLOTS:
QCOMPARE(v.constData<float>()[2], 1340.0f);
QCOMPARE(v.constData<float>()[3], 1603.0f);
}
+ {
+ // GIVEN
+ const QMatrix4x4 m1;
+ QMatrix4x4 m2;
+ m2.rotate(90.0f, 1.0f, 0.0f, 0.0f);
+ QMatrix4x4 m3;
+ m3.scale(2.5f);
+ QMatrix4x4 m4;
+ m4.translate(1.0f, 2.0f, 3.0f);
+
+ const QVector<QMatrix4x4> matrices = (QVector<QMatrix4x4>() << m1 << m2 << m3 << m4);
+ UniformValue v(matrices);
+
+ // THEN
+ for (int j = 0; j < matrices.size(); ++j) {
+ for (int i = 0; i < 16; ++i) {
+ QCOMPARE(v.constData<float>()[16 * j + i], matrices[j].constData()[i]);
+ }
+ }
+ }
}
void checkFromVariant()
@@ -345,6 +365,51 @@ private Q_SLOTS:
QVERIFY(!(v1 == v2));
QVERIFY(v1 != v2);
}
+
+ void checkSetData()
+ {
+ // GIVEN
+ const QMatrix4x4 m1;
+ QMatrix4x4 m2;
+ m2.rotate(90.0f, 1.0f, 0.0f, 0.0f);
+ QMatrix4x4 m3;
+ m3.scale(2.5f);
+ QMatrix4x4 m4;
+ m4.translate(1.0f, 2.0f, 3.0f);
+
+ const QVector<QMatrix4x4> matrices1 = (QVector<QMatrix4x4>() << m1 << m2 << m3 << m4);
+ UniformValue v(matrices1);
+
+ // WHEN
+ const QVector<QMatrix4x4> matrices2 = (QVector<QMatrix4x4>() << m4 << m3 << m2 << m1 << m4);
+ v.setData(matrices2);
+
+ // THEN
+ for (int j = 0; j < matrices2.size(); ++j) {
+ for (int i = 0; i < 16; ++i) {
+ QCOMPARE(v.constData<float>()[16 * j + i], matrices2[j].constData()[i]);
+ }
+ }
+
+ // GIVEN
+ const int positionCount = 10;
+ QVector<QVector3D> positions(positionCount);
+ for (int i = 0; i < positionCount; ++i) {
+ const QVector3D p(float(i), 10.0f * i, 100.0f * i);
+ positions[i] = p;
+ }
+
+ UniformValue positionsUniform;
+
+ // WHEN
+ positionsUniform.setData(positions);
+
+ // THEN
+ const QVector3D *data = positionsUniform.constData<QVector3D>();
+ for (int i = 0; i < positionCount; ++i) {
+ QCOMPARE(*(data + i), positions[i]);
+ }
+ }
};