diff options
Diffstat (limited to 'tests')
135 files changed, 13192 insertions, 204 deletions
diff --git a/tests/auto/animation/animation.pro b/tests/auto/animation/animation.pro index b48fd347b..4bc1c9252 100644 --- a/tests/auto/animation/animation.pro +++ b/tests/auto/animation/animation.pro @@ -13,7 +13,8 @@ SUBDIRS += \ qkeyframeanimation \ qmorphinganimation \ qmorphtarget \ - qvertexblendanimation + qvertexblendanimation \ + qclock qtConfig(private_tests) { SUBDIRS += \ @@ -34,5 +35,6 @@ qtConfig(private_tests) { additiveclipblend \ clipblendvalue \ animationutils \ - qabstractanimation + qabstractanimation \ + clock } diff --git a/tests/auto/animation/animationutils/tst_animationutils.cpp b/tests/auto/animation/animationutils/tst_animationutils.cpp index e7a0f343d..14181b893 100644 --- a/tests/auto/animation/animationutils/tst_animationutils.cpp +++ b/tests/auto/animation/animationutils/tst_animationutils.cpp @@ -30,6 +30,7 @@ #include <Qt3DAnimation/private/animationclip_p.h> #include <Qt3DAnimation/private/animationutils_p.h> #include <Qt3DAnimation/private/blendedclipanimator_p.h> +#include <Qt3DAnimation/private/clock_p.h> #include <Qt3DAnimation/private/channelmapper_p.h> #include <Qt3DAnimation/private/channelmapping_p.h> #include <Qt3DAnimation/private/clipblendvalue_p.h> @@ -51,6 +52,7 @@ using namespace Qt3DAnimation::Animation; Q_DECLARE_METATYPE(Qt3DAnimation::Animation::Handler*) Q_DECLARE_METATYPE(QVector<ChannelMapping *>) +Q_DECLARE_METATYPE(Clock *) Q_DECLARE_METATYPE(ChannelMapper *) Q_DECLARE_METATYPE(AnimationClip *) Q_DECLARE_METATYPE(QVector<MappingData>) @@ -61,6 +63,7 @@ Q_DECLARE_METATYPE(ClipEvaluationData) Q_DECLARE_METATYPE(ClipAnimator *) Q_DECLARE_METATYPE(BlendedClipAnimator *) Q_DECLARE_METATYPE(QVector<ChannelNameAndType>) +Q_DECLARE_METATYPE(QVector<AnimationCallbackAndValue>) namespace { @@ -122,6 +125,12 @@ bool fuzzyCompare(float x1, float x2) } } +class DummyCallback : public Qt3DAnimation::QAnimationCallback +{ +public: + void valueChanged(const QVariant &) override { } +}; + } // anonymous @@ -1105,6 +1114,117 @@ private Q_SLOTS: } } + void checkPrepareCallbacks_data() + { + QTest::addColumn<QVector<MappingData>>("mappingData"); + QTest::addColumn<QVector<float>>("channelResults"); + QTest::addColumn<QVector<AnimationCallbackAndValue> >("expectedValues"); + + QVector<MappingData> mappingData; + QVector<float> channelResults; + QVector<AnimationCallbackAndValue> expectedValues; + + // vec3 + { + DummyCallback callback; // safe since the object is never used, just the address + MappingData mapping; + mapping.targetId = Qt3DCore::QNodeId::createId(); + mapping.propertyName = "translation"; + mapping.type = static_cast<int>(QVariant::Vector3D); + mapping.channelIndices = QVector<int>() << 0 << 1 << 2; + mapping.callback = &callback; + mapping.callbackFlags = 0; + mappingData.push_back(mapping); + channelResults = QVector<float>() << 1.0f << 2.0f << 3.0f; + + AnimationCallbackAndValue cbv; + cbv.callback = mapping.callback; + cbv.flags = mapping.callbackFlags; + cbv.value = QVariant::fromValue<QVector3D>(QVector3D(1.0f, 2.0f, 3.0f)); + expectedValues.push_back(cbv); + + QTest::newRow("vec3 translation, no flags") << mappingData << channelResults << expectedValues; + + mappingData.clear(); + channelResults.clear(); + expectedValues.clear(); + } + + // double + { + DummyCallback callback; + MappingData mapping; + mapping.targetId = Qt3DCore::QNodeId::createId(); + mapping.propertyName = "something"; + mapping.type = static_cast<int>(QVariant::Double); + mapping.channelIndices = QVector<int>() << 0; + mapping.callback = &callback; + mapping.callbackFlags = 0; + mappingData.push_back(mapping); + channelResults = QVector<float>() << 1.0f; + + AnimationCallbackAndValue cbv; + cbv.callback = mapping.callback; + cbv.flags = mapping.callbackFlags; + cbv.value = QVariant(double(1.0)); + expectedValues.push_back(cbv); + + QTest::newRow("double, no flags") << mappingData << channelResults << expectedValues; + + mappingData.clear(); + channelResults.clear(); + expectedValues.clear(); + } + + // float, set a flag + { + DummyCallback callback; + MappingData mapping; + mapping.targetId = Qt3DCore::QNodeId::createId(); + mapping.propertyName = "opacity"; + mapping.type = static_cast<int>(QMetaType::Float); + mapping.channelIndices = QVector<int>() << 0; + mapping.callback = &callback; + mapping.callbackFlags = Qt3DAnimation::QAnimationCallback::OnThreadPool; + mappingData.push_back(mapping); + channelResults = QVector<float>() << 0.5f; + + AnimationCallbackAndValue cbv; + cbv.callback = mapping.callback; + cbv.flags = mapping.callbackFlags; + cbv.value = QVariant(float(0.5f)); + expectedValues.push_back(cbv); + + QTest::newRow("float, OnThreadPool") << mappingData << channelResults << expectedValues; + + mappingData.clear(); + channelResults.clear(); + expectedValues.clear(); + } + } + + void checkPrepareCallbacks() + { + // GIVEN + QFETCH(QVector<MappingData>, mappingData); + QFETCH(QVector<float>, channelResults); + QFETCH(QVector<AnimationCallbackAndValue>, expectedValues); + + // WHEN + QVector<AnimationCallbackAndValue> callbacks = prepareCallbacks(mappingData, channelResults); + + // THEN + QCOMPARE(callbacks.size(), expectedValues.size()); + for (int i = 0; i < callbacks.size(); ++i) { + auto expected = expectedValues[i]; + auto actual = callbacks[i]; + + QCOMPARE(actual.callback, expected.callback); + QCOMPARE(actual.flags, expected.flags); + QCOMPARE(actual.value, expected.value); + } + } + void checkEvaluateClipAtLocalTime_data() { QTest::addColumn<Handler *>("handler"); @@ -1355,6 +1475,31 @@ private Q_SLOTS: QVector<char> suffixes; QVector<int> expectedResults; + // already sorted vec3, no component names, with and without offset + { + channel = Channel(); + channel.name = QLatin1String("Location"); + channel.channelComponents.resize(3); + // leave 'name' empty + + dataType = static_cast<int>(QVariant::Vector3D); + offset = 0; + // suffixes expected to be ignored + expectedResults = (QVector<int>() << 0 << 1 << 2); + + QTest::newRow("vec3 location, pre-sorted, no component names, offset = 0") + << channel << dataType << offset << suffixes << expectedResults; + + expectedResults.clear(); + + offset = 4; + expectedResults = (QVector<int>() << 4 << 5 << 6); + QTest::newRow("vec3 location, pre-sorted, no component names, offset = 4") + << channel << dataType << offset << suffixes << expectedResults; + + expectedResults.clear(); + } + // vec3 with and without offset { channel = Channel(); @@ -1693,6 +1838,7 @@ private Q_SLOTS: AnimationClip *clip; AnimatorEvaluationData animatorData; ClipEvaluationData clipData; + auto* clock = new Clock; { handler = new Handler(); @@ -1701,7 +1847,7 @@ private Q_SLOTS: const int loops = 1; auto animator = createClipAnimator(handler, globalStartTimeNS, loops); const qint64 globalTimeNS = 0; - animatorData = evaluationDataForAnimator(animator, globalTimeNS); // Tested elsewhere + animatorData = evaluationDataForAnimator(animator, clock, globalTimeNS); // Tested elsewhere clipData.localTime = localTimeFromGlobalTime(animatorData.globalTime, animatorData.startTime, @@ -1722,7 +1868,7 @@ private Q_SLOTS: const int loops = 1; auto animator = createClipAnimator(handler, globalStartTimeNS, loops); const qint64 globalTimeNS = (clip->duration() + 1.0) * 1.0e9; // +1 to ensure beyond end of clip - animatorData = evaluationDataForAnimator(animator, globalTimeNS); // Tested elsewhere + animatorData = evaluationDataForAnimator(animator, nullptr, globalTimeNS); // Tested elsewhere clipData.localTime = localTimeFromGlobalTime(animatorData.globalTime, animatorData.startTime, @@ -1743,7 +1889,7 @@ private Q_SLOTS: const int loops = 0; // Infinite loops auto animator = createClipAnimator(handler, globalStartTimeNS, loops); const qint64 globalTimeNS = 2.0 * clip->duration() * 1.0e9; - animatorData = evaluationDataForAnimator(animator, globalTimeNS); // Tested elsewhere + animatorData = evaluationDataForAnimator(animator, clock, globalTimeNS); // Tested elsewhere clipData.localTime = localTimeFromGlobalTime(animatorData.globalTime, animatorData.startTime, @@ -1764,7 +1910,7 @@ private Q_SLOTS: const int loops = 2; auto animator = createClipAnimator(handler, globalStartTimeNS, loops); const qint64 globalTimeNS = (2.0 * clip->duration() + 1.0) * 1.0e9; // +1 to ensure beyond end of clip - animatorData = evaluationDataForAnimator(animator, globalTimeNS); // Tested elsewhere + animatorData = evaluationDataForAnimator(animator, nullptr, globalTimeNS); // Tested elsewhere clipData.localTime = localTimeFromGlobalTime(animatorData.globalTime, animatorData.startTime, @@ -1885,7 +2031,7 @@ private Q_SLOTS: QFETCH(AnimatorEvaluationData, expectedAnimatorData); // WHEN - AnimatorEvaluationData actualAnimatorData = evaluationDataForAnimator(animator, globalTimeNS); + AnimatorEvaluationData actualAnimatorData = evaluationDataForAnimator(animator, nullptr, globalTimeNS); // THEN QCOMPARE(actualAnimatorData.loopCount, expectedAnimatorData.loopCount); diff --git a/tests/auto/animation/clipanimator/tst_clipanimator.cpp b/tests/auto/animation/clipanimator/tst_clipanimator.cpp index e837a2a82..168cba050 100644 --- a/tests/auto/animation/clipanimator/tst_clipanimator.cpp +++ b/tests/auto/animation/clipanimator/tst_clipanimator.cpp @@ -30,6 +30,7 @@ #include <Qt3DAnimation/private/clipanimator_p.h> #include <Qt3DAnimation/qanimationcliploader.h> #include <Qt3DAnimation/qclipanimator.h> +#include <Qt3DAnimation/qclock.h> #include <Qt3DCore/private/qnode_p.h> #include <Qt3DCore/private/qscene_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> @@ -50,8 +51,10 @@ private Q_SLOTS: backendAnimator.setHandler(&handler); Qt3DAnimation::QClipAnimator animator; auto clip = new Qt3DAnimation::QAnimationClipLoader(); + auto clock = new Qt3DAnimation::QClock(); animator.setClip(clip); + animator.setClock(clock); animator.setLoopCount(10); // WHEN @@ -61,6 +64,7 @@ private Q_SLOTS: QCOMPARE(backendAnimator.peerId(), animator.id()); QCOMPARE(backendAnimator.isEnabled(), animator.isEnabled()); QCOMPARE(backendAnimator.clipId(), clip->id()); + QCOMPARE(backendAnimator.clockId(), clock->id()); QCOMPARE(backendAnimator.isRunning(), animator.isRunning()); QCOMPARE(backendAnimator.loops(), animator.loopCount()); } @@ -76,23 +80,28 @@ private Q_SLOTS: QVERIFY(backendAnimator.peerId().isNull()); QCOMPARE(backendAnimator.isEnabled(), false); QCOMPARE(backendAnimator.clipId(), Qt3DCore::QNodeId()); + QCOMPARE(backendAnimator.clockId(), Qt3DCore::QNodeId()); QCOMPARE(backendAnimator.isRunning(), false); QCOMPARE(backendAnimator.loops(), 1); // GIVEN Qt3DAnimation::QClipAnimator animator; auto clip = new Qt3DAnimation::QAnimationClipLoader(); + auto clock = new Qt3DAnimation::QClock(); animator.setClip(clip); + animator.setClock(clock); animator.setRunning(true); animator.setLoopCount(25); // WHEN simulateInitialization(&animator, &backendAnimator); backendAnimator.setClipId(Qt3DCore::QNodeId::createId()); + backendAnimator.setClockId(Qt3DCore::QNodeId::createId()); backendAnimator.cleanup(); // THEN QCOMPARE(backendAnimator.clipId(), Qt3DCore::QNodeId()); + QCOMPARE(backendAnimator.clockId(), Qt3DCore::QNodeId()); QCOMPARE(backendAnimator.isEnabled(), false); QCOMPARE(backendAnimator.isRunning(), false); QCOMPARE(backendAnimator.loops(), 1); @@ -126,6 +135,16 @@ private Q_SLOTS: QCOMPARE(backendAnimator.clipId(), newClip->id()); // WHEN + auto clock = new Qt3DAnimation::QClock(); + updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId()); + updateChange->setPropertyName("clock"); + updateChange->setValue(QVariant::fromValue(clock->id())); + backendAnimator.sceneChangeEvent(updateChange); + + // THEN + QCOMPARE(backendAnimator.clockId(), clock->id()); + + // WHEN updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId()); updateChange->setPropertyName("running"); updateChange->setValue(true); diff --git a/tests/auto/animation/clock/clock.pro b/tests/auto/animation/clock/clock.pro new file mode 100644 index 000000000..26b7a4b21 --- /dev/null +++ b/tests/auto/animation/clock/clock.pro @@ -0,0 +1,12 @@ +TEMPLATE = app + +TARGET = tst_clock + +QT += core-private 3dcore 3dcore-private 3danimation 3danimation-private testlib + +CONFIG += testcase + +SOURCES += \ + tst_clock.cpp + +include(../../core/common/common.pri) diff --git a/tests/auto/animation/clock/tst_clock.cpp b/tests/auto/animation/clock/tst_clock.cpp new file mode 100644 index 000000000..547ec6a12 --- /dev/null +++ b/tests/auto/animation/clock/tst_clock.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** 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 <Qt3DAnimation/qclock.h> +#include <Qt3DAnimation/private/clock_p.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> + +class tst_Clock: public Qt3DCore::QBackendNodeTester +{ + Q_OBJECT + +private Q_SLOTS: + void checkPeerPropertyMirroring() + { + // GIVEN + Qt3DAnimation::Animation::Clock backendClock; + Qt3DAnimation::QClock clock; + + clock.setPlaybackRate(10.5); + + // WHEN + simulateInitialization(&clock, &backendClock); + + // THEN + QCOMPARE(backendClock.playbackRate(), clock.playbackRate()); + } + + void checkInitialAndCleanedUpState() + { + // GIVEN + Qt3DAnimation::Animation::Clock backendClock; + + // THEN + QCOMPARE(backendClock.playbackRate(), 1.0); + + // GIVEN + Qt3DAnimation::QClock clock; + clock.setPlaybackRate(10.5); + + // WHEN + simulateInitialization(&clock, &backendClock); + backendClock.cleanup(); + + // THEN + QCOMPARE(backendClock.playbackRate(), 1.0); + } +}; + +QTEST_APPLESS_MAIN(tst_Clock) + +#include "tst_clock.moc" diff --git a/tests/auto/animation/qclipanimator/tst_qclipanimator.cpp b/tests/auto/animation/qclipanimator/tst_qclipanimator.cpp index 1ed4b8f13..6a46b7008 100644 --- a/tests/auto/animation/qclipanimator/tst_qclipanimator.cpp +++ b/tests/auto/animation/qclipanimator/tst_qclipanimator.cpp @@ -30,6 +30,7 @@ #include <QtTest/QTest> #include <Qt3DAnimation/qanimationcliploader.h> #include <Qt3DAnimation/qchannelmapper.h> +#include <Qt3DAnimation/qclock.h> #include <Qt3DAnimation/qclipanimator.h> #include <Qt3DAnimation/private/qanimationclip_p.h> #include <Qt3DAnimation/private/qclipanimator_p.h> @@ -49,6 +50,7 @@ private Q_SLOTS: { qRegisterMetaType<Qt3DAnimation::QAbstractAnimationClip*>(); qRegisterMetaType<Qt3DAnimation::QChannelMapper*>(); + qRegisterMetaType<Qt3DAnimation::QClock*>(); } void checkDefaultConstruction() @@ -59,6 +61,7 @@ private Q_SLOTS: // THEN QCOMPARE(animator.clip(), static_cast<Qt3DAnimation::QAbstractAnimationClip *>(nullptr)); QCOMPARE(animator.channelMapper(), static_cast<Qt3DAnimation::QChannelMapper *>(nullptr)); + QCOMPARE(animator.clock(), static_cast<Qt3DAnimation::QClock*>(nullptr)); QCOMPARE(animator.loopCount(), 1); } @@ -111,6 +114,27 @@ private Q_SLOTS: { // WHEN + QSignalSpy spy(&animator, SIGNAL(clockChanged(Qt3DAnimation::QClock *))); + auto clock = new Qt3DAnimation::QClock(); + animator.setClock(clock); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(animator.clock(), clock); + QCOMPARE(clock->parent(), &animator); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + animator.setClock(clock); + + // THEN + QCOMPARE(animator.clock(), clock); + QCOMPARE(spy.count(), 0); + } + + { + // WHEN QSignalSpy spy(&animator, SIGNAL(loopCountChanged(int))); const int newValue = 5; animator.setLoopCount(newValue); @@ -138,6 +162,8 @@ private Q_SLOTS: animator.setClip(clip); auto mapper = new Qt3DAnimation::QChannelMapper(); animator.setChannelMapper(mapper); + auto clock = new Qt3DAnimation::QClock(); + animator.setClock(clock); // WHEN QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges; @@ -148,7 +174,7 @@ private Q_SLOTS: // THEN { - QCOMPARE(creationChanges.size(), 3); + QCOMPARE(creationChanges.size(), 4); const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QClipAnimatorData>>(creationChanges.first()); const Qt3DAnimation::QClipAnimatorData data = creationChangeData->data; @@ -159,6 +185,7 @@ private Q_SLOTS: QCOMPARE(animator.metaObject(), creationChangeData->metaObject()); QCOMPARE(animator.clip()->id(), data.clipId); QCOMPARE(animator.channelMapper()->id(), data.mapperId); + QCOMPARE(animator.clock()->id(), data.clockId); QCOMPARE(animator.loopCount(), data.loops); } @@ -171,7 +198,7 @@ private Q_SLOTS: // THEN { - QCOMPARE(creationChanges.size(), 3); + QCOMPARE(creationChanges.size(), 4); const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QClipAnimatorData>>(creationChanges.first()); @@ -240,6 +267,32 @@ private Q_SLOTS: QCOMPARE(arbiter.events.size(), 0); } + // GIVEN + auto clock = new Qt3DAnimation::QClock; + { + // WHEN + animator.setClock(clock); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "clock"); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), clock->id()); + + arbiter.events.clear(); + } + + { + // WHEN + animator.setClock(clock); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + { // WHEN animator.setLoopCount(10); diff --git a/tests/auto/animation/qclock/qclock.pro b/tests/auto/animation/qclock/qclock.pro new file mode 100644 index 000000000..2b1194860 --- /dev/null +++ b/tests/auto/animation/qclock/qclock.pro @@ -0,0 +1,12 @@ +TEMPLATE = app + +TARGET = tst_qclock + +QT += 3dcore 3dcore-private 3danimation 3danimation-private testlib + +CONFIG += testcase + +SOURCES += \ + tst_qclock.cpp + +include(../../core/common/common.pri) diff --git a/tests/auto/animation/qclock/tst_qclock.cpp b/tests/auto/animation/qclock/tst_qclock.cpp new file mode 100644 index 000000000..34c70da7b --- /dev/null +++ b/tests/auto/animation/qclock/tst_qclock.cpp @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** 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 <Qt3DAnimation/qclock.h> +#include <Qt3DAnimation/private/qclock_p.h> +#include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DCore/qnodecreatedchange.h> +#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h> +#include <QObject> +#include <QSignalSpy> +#include <testpostmanarbiter.h> + +class tst_QClock : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void initTestCase() + { + qRegisterMetaType<Qt3DAnimation::QClock*>(); + } + + void checkDefaultConstruction() + { + // GIVEN + Qt3DAnimation::QClock clock; + + // THEN + QCOMPARE(clock.playbackRate(), 1.0); + } + + void checkPropertyChanges() + { + // GIVEN + Qt3DAnimation::QClock clock; + + // WHEN + QSignalSpy spy(&clock, SIGNAL(playbackRateChanged(double))); + const double newValue = 5.5; + clock.setPlaybackRate(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(clock.playbackRate(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + clock.setPlaybackRate(newValue); + + // THEN + QCOMPARE(clock.playbackRate(), newValue); + QCOMPARE(spy.count(), 0); + } + + void checkCreationData() + { + // GIVEN + Qt3DAnimation::QClock clock; + clock.setPlaybackRate(10.f); + + // WHEN + QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges; + { + Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&clock); + creationChanges = creationChangeGenerator.creationChanges(); + } + + // THEN + { + QCOMPARE(creationChanges.size(), 1); + + const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QClockData>>(creationChanges.first()); + const Qt3DAnimation::QClockData data = creationChangeData->data; + + QCOMPARE(clock.id(), creationChangeData->subjectId()); + QCOMPARE(clock.isEnabled(), true); + QCOMPARE(clock.isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(clock.metaObject(), creationChangeData->metaObject()); + QCOMPARE(clock.playbackRate(), data.playbackRate); + } + + // WHEN + clock.setEnabled(false); + { + Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&clock); + creationChanges = creationChangeGenerator.creationChanges(); + } + + // THEN + { + QCOMPARE(creationChanges.size(), 1); + + const auto creationChangeData = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DAnimation::QClockData>>(creationChanges.first()); + + QCOMPARE(clock.id(), creationChangeData->subjectId()); + QCOMPARE(clock.isEnabled(), false); + QCOMPARE(clock.isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(clock.metaObject(), creationChangeData->metaObject()); + } + } + + void checkPropertyUpdate() + { + // GIVEN + TestArbiter arbiter; + Qt3DAnimation::QClock clock; + arbiter.setArbiterOnNode(&clock); + + { + // WHEN + clock.setPlaybackRate(10.5); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "playbackRate"); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + QCOMPARE(change->value().value<double>(), clock.playbackRate()); + + arbiter.events.clear(); + } + + { + // WHEN + clock.setPlaybackRate(10.5f); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + } +}; + +QTEST_MAIN(tst_QClock) + +#include "tst_qclock.moc" diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index cc7e5590a..2d7ec9cb3 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -3,15 +3,17 @@ TEMPLATE = subdirs SUBDIRS = \ coretest \ core \ - render \ - quick3d \ - cmake \ - input \ - animation \ - extras + cmake installed_cmake.depends = cmake +QT_FOR_CONFIG += 3dcore +qtConfig(qt3d-render): SUBDIRS += render +qtConfig(qt3d-input): SUBDIRS += input +qtConfig(qt3d-animation): SUBDIRS += animation +qtConfig(qt3d-extras): SUBDIRS += extras +qtConfig(qt3d-render):qtConfig(qt3d-input): SUBDIRS += quick3d + for(subdir, SUBDIRS) { !equals(subdir, coretest) { $${subdir}.depends += coretest diff --git a/tests/auto/core/aspectcommanddebugger/tst_aspectcommanddebugger.cpp b/tests/auto/core/aspectcommanddebugger/tst_aspectcommanddebugger.cpp index 1bcaced2c..f13fa2e03 100644 --- a/tests/auto/core/aspectcommanddebugger/tst_aspectcommanddebugger.cpp +++ b/tests/auto/core/aspectcommanddebugger/tst_aspectcommanddebugger.cpp @@ -29,16 +29,13 @@ #include <QtTest/QTest> #include <Qt3DCore/private/aspectcommanddebugger_p.h> -#ifdef QT3D_JOBS_RUN_STATS using namespace Qt3DCore::Debug; -#endif class tst_AspectCommandDebugger : public QObject { Q_OBJECT private slots: -#ifdef QT3D_JOBS_RUN_STATS void checkReadBufferInitialState() { // GIVEN @@ -92,7 +89,6 @@ private slots: QCOMPARE(buffer.size(), 16 * 1024); QCOMPARE(hugeFakeData, QByteArray(buffer.buffer.constData(), 1024 * 16)); } -#endif }; QTEST_APPLESS_MAIN(tst_AspectCommandDebugger) diff --git a/tests/auto/core/core.pro b/tests/auto/core/core.pro index 637ee086e..4ac74471e 100644 --- a/tests/auto/core/core.pro +++ b/tests/auto/core/core.pro @@ -12,14 +12,27 @@ SUBDIRS = \ qaspectjob \ qchangearbiter \ qscene \ - qservicelocator + qservicelocator \ + qjoint \ + qskeletonloader \ + qskeleton \ + qarmature qtConfig(private_tests) { SUBDIRS += \ - qentity \ - qframeallocator \ - qtransform \ - threadpooler \ - aspectcommanddebugger \ - qpostman + qentity \ + qframeallocator \ + qtransform \ + threadpooler \ + qpostman \ + vector4d_base \ + vector3d_base + + QT_FOR_CONFIG += 3dcore-private + qtConfig(qt3d-profile-jobs): SUBDIRS += aspectcommanddebugger + qtConfig(qt3d-simd-sse2) { + SUBDIRS += \ + vector4d_sse \ + vector3d_sse + } } diff --git a/tests/auto/core/qarmature/qarmature.pro b/tests/auto/core/qarmature/qarmature.pro new file mode 100644 index 000000000..1d4769310 --- /dev/null +++ b/tests/auto/core/qarmature/qarmature.pro @@ -0,0 +1,11 @@ +TEMPLATE = app + +TARGET = tst_qarmature + +QT += core-private 3dcore 3dcore-private testlib + +CONFIG += testcase + +SOURCES += tst_qarmature.cpp + +include(../common/common.pri) diff --git a/tests/auto/core/qarmature/tst_qarmature.cpp b/tests/auto/core/qarmature/tst_qarmature.cpp new file mode 100644 index 000000000..f624b998f --- /dev/null +++ b/tests/auto/core/qarmature/tst_qarmature.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** 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/qarmature.h> +#include <Qt3DCore/private/qarmature_p.h> +#include <Qt3DCore/qskeleton.h> +#include <Qt3DCore/qpropertyupdatedchange.h> + +#include <Qt3DCore/private/qnode_p.h> +#include <Qt3DCore/private/qscene_p.h> +#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h> + +#include "testpostmanarbiter.h" + +using namespace Qt3DCore; + +class tst_QArmature: public QObject +{ + Q_OBJECT +public: + tst_QArmature() + { + qRegisterMetaType<Qt3DCore::QAbstractSkeleton*>(); + } + +private Q_SLOTS: + + void checkCreationChange_data() + { + QTest::addColumn<QArmature *>("armature"); + + QArmature *defaultConstructed = new QArmature(); + QTest::newRow("defaultConstructed") << defaultConstructed; + + QArmature *armatureWithSkeleton = new QArmature(); + armatureWithSkeleton->setSkeleton(new QSkeleton()); + QTest::newRow("skeletonWithOneJoint") << armatureWithSkeleton; + } + + void checkCreationChange() + { + // GIVEN + QFETCH(QArmature *, armature); + + // WHEN + QNodeCreatedChangeGenerator creationChangeGenerator(armature); + QVector<QNodeCreatedChangeBasePtr> creationChanges = creationChangeGenerator.creationChanges(); + + const int skeletonCount = armature->skeleton() ? 1 : 0; + + // THEN + QCOMPARE(creationChanges.size(), 1 + skeletonCount); + + const auto creationChangeData = qSharedPointerCast<QNodeCreatedChange<QArmatureData>>(creationChanges.first()); + const QArmatureData &data = creationChangeData->data; + + // THEN + QCOMPARE(armature->id(), creationChangeData->subjectId()); + QCOMPARE(armature->isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(armature->metaObject(), creationChangeData->metaObject()); + if (armature->skeleton()) { + QCOMPARE(armature->skeleton()->id(), data.skeletonId); + } + } + + void checkPropertyUpdates() + { + // GIVEN + TestArbiter arbiter; + QScopedPointer<QArmature> armature(new QArmature()); + arbiter.setArbiterOnNode(armature.data()); + + // WHEN + QSkeleton *skeleton = new QSkeleton(armature.data()); + QCoreApplication::processEvents(); + arbiter.events.clear(); + + armature->setSkeleton(skeleton); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "skeleton"); + QCOMPARE(change->value().value<QNodeId>(), skeleton->id()); + QCOMPARE(change->type(), PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + armature->setSkeleton(nullptr); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "skeleton"); + QCOMPARE(change->value().value<QNodeId>(), QNodeId()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + } + + void checkSkeletonBookkeeping() + { + // GIVEN + QScopedPointer<QArmature> armature(new QArmature); + { + // WHEN + QSkeleton skeleton; + armature->setSkeleton(&skeleton); + + // THEN + QCOMPARE(skeleton.parent(), armature.data()); + QCOMPARE(armature->skeleton(), &skeleton); + } + // THEN (Should not crash and parameter be unset) + QVERIFY(armature->skeleton() == nullptr); + + { + // WHEN + QArmature someOtherArmature; + QScopedPointer<QSkeleton> skeleton(new QSkeleton(&someOtherArmature)); + armature->setSkeleton(skeleton.data()); + + // THEN + QCOMPARE(skeleton->parent(), &someOtherArmature); + QCOMPARE(armature->skeleton(), skeleton.data()); + + // WHEN + armature.reset(); + skeleton.reset(); + + // THEN Should not crash when the joint is destroyed (tests for failed removal of destruction helper) + } + } +}; + +QTEST_MAIN(tst_QArmature) + +#include "tst_qarmature.moc" diff --git a/tests/auto/core/qjoint/qjoint.pro b/tests/auto/core/qjoint/qjoint.pro new file mode 100644 index 000000000..e25d57102 --- /dev/null +++ b/tests/auto/core/qjoint/qjoint.pro @@ -0,0 +1,12 @@ +TEMPLATE = app + +TARGET = tst_qjoint + +QT += 3dcore 3dcore-private testlib + +CONFIG += testcase + +SOURCES += \ + tst_qjoint.cpp + +include(../common/common.pri) diff --git a/tests/auto/core/qjoint/tst_qjoint.cpp b/tests/auto/core/qjoint/tst_qjoint.cpp new file mode 100644 index 000000000..a63d275c5 --- /dev/null +++ b/tests/auto/core/qjoint/tst_qjoint.cpp @@ -0,0 +1,406 @@ +/**************************************************************************** +** +** 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 <Qt3DCore/qjoint.h> +#include <Qt3DCore/private/qjoint_p.h> +#include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DCore/qnodecreatedchange.h> +#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h> +#include <QObject> +#include <QSignalSpy> +#include <testpostmanarbiter.h> + +using namespace Qt3DCore; + +class tst_QJoint : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void checkDefaultConstruction() + { + // GIVEN + QJoint joint; + + // THEN + QCOMPARE(joint.scale(), QVector3D(1.0f, 1.0f, 1.0f)); + QCOMPARE(joint.rotation(), QQuaternion()); + QCOMPARE(joint.translation(), QVector3D(0.0f, 0.0f, 0.0f)); + QCOMPARE(joint.inverseBindMatrix(), QMatrix4x4()); + QCOMPARE(joint.rotationX(), 0.0f); + QCOMPARE(joint.rotationY(), 0.0f); + QCOMPARE(joint.rotationZ(), 0.0f); + } + + void checkPropertyChanges() + { + // GIVEN + QJoint joint; + + { + // WHEN + QSignalSpy spy(&joint, SIGNAL(scaleChanged(QVector3D))); + const QVector3D newValue(2.5f, 2.0f, 1.3f); + joint.setScale(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(joint.scale(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + joint.setScale(newValue); + + // THEN + QCOMPARE(joint.scale(), newValue); + QCOMPARE(spy.count(), 0); + } + + { + // WHEN + QSignalSpy spy(&joint, SIGNAL(rotationChanged(QQuaternion))); + const auto newValue = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 45.0f); + joint.setRotation(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(joint.rotation(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + joint.setRotation(newValue); + + // THEN + QCOMPARE(joint.rotation(), newValue); + QCOMPARE(spy.count(), 0); + } + + { + // WHEN + QSignalSpy spy(&joint, SIGNAL(translationChanged(QVector3D))); + const QVector3D newValue(1.0f, 2.0f, 3.0f); + joint.setTranslation(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(joint.translation(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + joint.setTranslation(newValue); + + // THEN + QCOMPARE(joint.translation(), newValue); + QCOMPARE(spy.count(), 0); + } + + { + // WHEN + QSignalSpy spy(&joint, SIGNAL(inverseBindMatrixChanged(QMatrix4x4))); + QMatrix4x4 newValue; + newValue.scale(3.5f); + joint.setInverseBindMatrix(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(joint.inverseBindMatrix(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + joint.setInverseBindMatrix(newValue); + + // THEN + QCOMPARE(joint.inverseBindMatrix(), newValue); + QCOMPARE(spy.count(), 0); + } + + { + // WHEN + QSignalSpy spy(&joint, SIGNAL(rotationChanged(QQuaternion))); + QSignalSpy spyEuler(&joint, SIGNAL(rotationXChanged(float))); + const auto newValue = 45.0f; + const auto newValueAsQuaternion = QQuaternion::fromEulerAngles(newValue, 0.0f, 0.0f); + joint.setRotationX(newValue); + + // THEN + QVERIFY(spy.isValid()); + QVERIFY(spyEuler.isValid()); + QCOMPARE(joint.rotationX(), newValue); + QCOMPARE(joint.rotation(), newValueAsQuaternion); + QCOMPARE(spy.count(), 1); + QCOMPARE(spyEuler.count(), 1); + + // WHEN + spy.clear(); + spyEuler.clear(); + joint.setRotationX(newValue); + + // THEN + QCOMPARE(joint.rotationX(), newValue); + QCOMPARE(joint.rotation(), newValueAsQuaternion); + QCOMPARE(spy.count(), 0); + QCOMPARE(spyEuler.count(), 0); + + joint.setRotationX(0.0f); + } + + { + // WHEN + QSignalSpy spy(&joint, SIGNAL(rotationChanged(QQuaternion))); + QSignalSpy spyEuler(&joint, SIGNAL(rotationYChanged(float))); + const auto newValue = 45.0f; + const auto newValueAsQuaternion = QQuaternion::fromEulerAngles(0.0f, newValue, 0.0f); + joint.setRotationY(newValue); + + // THEN + QVERIFY(spy.isValid()); + QVERIFY(spyEuler.isValid()); + QCOMPARE(joint.rotationY(), newValue); + QCOMPARE(joint.rotation(), newValueAsQuaternion); + QCOMPARE(spy.count(), 1); + QCOMPARE(spyEuler.count(), 1); + + // WHEN + spy.clear(); + spyEuler.clear(); + joint.setRotationY(newValue); + + // THEN + QCOMPARE(joint.rotationY(), newValue); + QCOMPARE(joint.rotation(), newValueAsQuaternion); + QCOMPARE(spy.count(), 0); + QCOMPARE(spyEuler.count(), 0); + + joint.setRotationY(0.0f); + } + + { + // WHEN + QSignalSpy spy(&joint, SIGNAL(rotationChanged(QQuaternion))); + QSignalSpy spyEuler(&joint, SIGNAL(rotationZChanged(float))); + const auto newValue = 45.0f; + const auto newValueAsQuaternion = QQuaternion::fromEulerAngles(0.0f, 0.0f, newValue); + joint.setRotationZ(newValue); + + // THEN + QVERIFY(spy.isValid()); + QVERIFY(spyEuler.isValid()); + QCOMPARE(joint.rotationZ(), newValue); + QCOMPARE(joint.rotation(), newValueAsQuaternion); + QCOMPARE(spy.count(), 1); + QCOMPARE(spyEuler.count(), 1); + + // WHEN + spy.clear(); + spyEuler.clear(); + joint.setRotationZ(newValue); + + // THEN + QCOMPARE(joint.rotationZ(), newValue); + QCOMPARE(joint.rotation(), newValueAsQuaternion); + QCOMPARE(spy.count(), 0); + QCOMPARE(spyEuler.count(), 0); + + joint.setRotationZ(0.0f); + } + } + + void checkCreationData() + { + // GIVEN + QJoint joint; + + joint.setScale(QVector3D(3.5f, 2.0f, 1.3f)); + joint.setRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 30.0f)); + joint.setTranslation(QVector3D(3.0f, 2.0f, 1.0f)); + QMatrix4x4 ibm; + ibm.scale(5.2f); + joint.setInverseBindMatrix(ibm); + + // WHEN + QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges; + + { + Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&joint); + creationChanges = creationChangeGenerator.creationChanges(); + } + + // THEN + { + QCOMPARE(creationChanges.size(), 1); + + const auto creationChangeData + = qSharedPointerCast<QNodeCreatedChange<QJointData>>(creationChanges.first()); + const QJointData data = creationChangeData->data; + + QCOMPARE(joint.id(), creationChangeData->subjectId()); + QCOMPARE(joint.isEnabled(), true); + QCOMPARE(joint.isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(joint.metaObject(), creationChangeData->metaObject()); + QCOMPARE(joint.scale(), data.scale); + QCOMPARE(joint.rotation(), data.rotation); + QCOMPARE(joint.translation(), data.translation); + QCOMPARE(joint.inverseBindMatrix(), data.inverseBindMatrix); + } + + // WHEN + joint.setEnabled(false); + + { + Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(&joint); + creationChanges = creationChangeGenerator.creationChanges(); + } + + // THEN + { + QCOMPARE(creationChanges.size(), 1); + + const auto creationChangeData + = qSharedPointerCast<QNodeCreatedChange<QJointData>>(creationChanges.first()); + const QJointData data = creationChangeData->data; + + QCOMPARE(joint.id(), creationChangeData->subjectId()); + QCOMPARE(joint.isEnabled(), false); + QCOMPARE(joint.isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(joint.metaObject(), creationChangeData->metaObject()); + QCOMPARE(joint.scale(), data.scale); + QCOMPARE(joint.rotation(), data.rotation); + QCOMPARE(joint.translation(), data.translation); + QCOMPARE(joint.inverseBindMatrix(), data.inverseBindMatrix); + } + } + + void checkPropertyUpdateChanges() + { + // GIVEN + TestArbiter arbiter; + QJoint joint; + arbiter.setArbiterOnNode(&joint); + + { + // WHEN + joint.setScale(QVector3D(2.0f, 1.0f, 3.0f)); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "scale"); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + QCOMPARE(change->value().value<QVector3D>(), joint.scale()); + + arbiter.events.clear(); + + // WHEN + joint.setScale(QVector3D(2.0f, 1.0f, 3.0f)); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + + { + // WHEN + const auto newValue = QQuaternion::fromAxisAndAngle(1.0f, 1.0f, 1.0f, 45.0f); + joint.setRotation(newValue); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "rotation"); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + QCOMPARE(change->value().value<QQuaternion>(), newValue); + + arbiter.events.clear(); + + // WHEN + joint.setRotation(newValue); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + + { + // WHEN + const QVector3D newValue(1.0f, 2.0f, 3.0f); + joint.setTranslation(newValue); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "translation"); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + QCOMPARE(change->value().value<QVector3D>(), newValue); + + arbiter.events.clear(); + + // WHEN + joint.setTranslation(newValue); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + + { + // WHEN + QMatrix4x4 newValue; + newValue.rotate(90.0f, 1.0f, 0.0f, 0.0f); + joint.setInverseBindMatrix(newValue); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "inverseBindMatrix"); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + QCOMPARE(change->value().value<QMatrix4x4>(), newValue); + + arbiter.events.clear(); + + // WHEN + joint.setInverseBindMatrix(newValue); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + } +}; + +QTEST_MAIN(tst_QJoint) + +#include "tst_qjoint.moc" diff --git a/tests/auto/core/qskeleton/qskeleton.pro b/tests/auto/core/qskeleton/qskeleton.pro new file mode 100644 index 000000000..3bbb48a3c --- /dev/null +++ b/tests/auto/core/qskeleton/qskeleton.pro @@ -0,0 +1,11 @@ +TEMPLATE = app + +TARGET = tst_qskeleton + +QT += core-private 3dcore 3dcore-private testlib + +CONFIG += testcase + +SOURCES += tst_qskeleton.cpp + +include(../common/common.pri) diff --git a/tests/auto/core/qskeleton/tst_qskeleton.cpp b/tests/auto/core/qskeleton/tst_qskeleton.cpp new file mode 100644 index 000000000..f66e07cbe --- /dev/null +++ b/tests/auto/core/qskeleton/tst_qskeleton.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** 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/qskeleton.h> +#include <Qt3DCore/private/qskeleton_p.h> +#include <Qt3DCore/qjoint.h> +#include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DCore/qpropertynodeaddedchange.h> +#include <Qt3DCore/qpropertynoderemovedchange.h> + +#include <Qt3DCore/private/qnode_p.h> +#include <Qt3DCore/private/qscene_p.h> +#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h> + +#include <QSignalSpy> +#include <testpostmanarbiter.h> + +using namespace Qt3DCore; + +class tst_QSkeleton: public QSkeleton +{ + Q_OBJECT +public: + tst_QSkeleton() + { + qRegisterMetaType<Qt3DCore::QJoint*>(); + } + +private Q_SLOTS: + void checkDefaultConstruction() + { + // GIVEN + QSkeleton skeleton; + + // THEN + QCOMPARE(skeleton.jointCount(), 0); + } + + void checkCreationChange_data() + { + QTest::addColumn<QSkeleton *>("skeleton"); + + QSkeleton *defaultConstructed = new QSkeleton(); + QTest::newRow("defaultConstructed") << defaultConstructed; + + QSkeleton *skeletonWithOneJoint = new QSkeleton(); + skeletonWithOneJoint->setRootJoint(new QJoint()); + QTest::newRow("skeletonWithOneJoint") << skeletonWithOneJoint; + } + + void checkCreationChange() + { + // GIVEN + QFETCH(QSkeleton *, skeleton); + + // WHEN + QNodeCreatedChangeGenerator creationChangeGenerator(skeleton); + QVector<QNodeCreatedChangeBasePtr> creationChanges = creationChangeGenerator.creationChanges(); + + const int jointCount = skeleton->rootJoint() ? 1 : 0; + + // THEN + QCOMPARE(creationChanges.size(), 1 + jointCount); + + const auto creationChangeData = qSharedPointerCast<QNodeCreatedChange<QSkeletonData>>(creationChanges.first()); + const QSkeletonData &data = creationChangeData->data; + + // THEN + QCOMPARE(skeleton->id(), creationChangeData->subjectId()); + QCOMPARE(skeleton->isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(skeleton->metaObject(), creationChangeData->metaObject()); + if (skeleton->rootJoint()) { + QCOMPARE(skeleton->rootJoint()->id(), data.rootJointId); + } + } + + void checkPropertyUpdates() + { + // GIVEN + TestArbiter arbiter; + QScopedPointer<QSkeleton> skeleton(new QSkeleton()); + arbiter.setArbiterOnNode(skeleton.data()); + + // WHEN + QJoint *joint = new QJoint(skeleton.data()); + QCoreApplication::processEvents(); + arbiter.events.clear(); + + skeleton->setRootJoint(joint); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "rootJoint"); + QCOMPARE(change->value().value<QNodeId>(), joint->id()); + QCOMPARE(change->type(), PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + skeleton->setRootJoint(nullptr); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "rootJoint"); + QCOMPARE(change->value().value<QNodeId>(), QNodeId()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + } + + void checkRootJointBookkeeping() + { + // GIVEN + QScopedPointer<QSkeleton> skeleton(new QSkeleton); + { + // WHEN + QJoint joint; + skeleton->setRootJoint(&joint); + + // THEN + QCOMPARE(joint.parent(), skeleton.data()); + QCOMPARE(skeleton->rootJoint(), &joint); + } + // THEN (Should not crash and parameter be unset) + QVERIFY(skeleton->rootJoint() == nullptr); + + { + // WHEN + QSkeleton someOtherSkeleton; + QScopedPointer<QJoint> joint(new QJoint(&someOtherSkeleton)); + skeleton->setRootJoint(joint.data()); + + // THEN + QCOMPARE(joint->parent(), &someOtherSkeleton); + QCOMPARE(skeleton->rootJoint(), joint.data()); + + // WHEN + skeleton.reset(); + joint.reset(); + + // THEN Should not crash when the joint is destroyed (tests for failed removal of destruction helper) + } + } + + void checkJointCountPropertyUpdate() + { + // GIVEN + TestArbiter arbiter; + arbiter.setArbiterOnNode(this); + QSignalSpy spy(this, SIGNAL(jointCountChanged(int))); + const int newJointCount = 99; + + // THEN + QVERIFY(spy.isValid()); + + // WHEN + auto valueChange = QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); + valueChange->setPropertyName("jointCount"); + valueChange->setValue(QVariant(newJointCount)); + sceneChangeEvent(valueChange); + + // THEN + QCOMPARE(spy.count(), 1); + QCOMPARE(arbiter.events.size(), 0); + QCOMPARE(jointCount(), newJointCount); + + // WHEN + spy.clear(); + sceneChangeEvent(valueChange); + + // THEN + QCOMPARE(spy.count(), 0); + QCOMPARE(arbiter.events.size(), 0); + QCOMPARE(jointCount(), newJointCount); + } +}; + +QTEST_MAIN(tst_QSkeleton) + +#include "tst_qskeleton.moc" diff --git a/tests/auto/core/qskeletonloader/qskeletonloader.pro b/tests/auto/core/qskeletonloader/qskeletonloader.pro new file mode 100644 index 000000000..6172906c2 --- /dev/null +++ b/tests/auto/core/qskeletonloader/qskeletonloader.pro @@ -0,0 +1,12 @@ +TEMPLATE = app + +TARGET = tst_qskeletonloader + +QT += 3dcore 3dcore-private testlib + +CONFIG += testcase + +SOURCES += \ + tst_qskeletonloader.cpp + +include(../common/common.pri) diff --git a/tests/auto/core/qskeletonloader/tst_qskeletonloader.cpp b/tests/auto/core/qskeletonloader/tst_qskeletonloader.cpp new file mode 100644 index 000000000..1386429d4 --- /dev/null +++ b/tests/auto/core/qskeletonloader/tst_qskeletonloader.cpp @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** 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 <Qt3DCore/qskeletonloader.h> +#include <Qt3DCore/qjoint.h> +#include <Qt3DCore/private/qskeletonloader_p.h> +#include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DCore/qnodecreatedchange.h> +#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h> +#include <QObject> +#include <QSignalSpy> +#include <testpostmanarbiter.h> + +using namespace Qt3DCore; + +class tst_QSkeletonLoader : public QSkeletonLoader +{ + Q_OBJECT + +private Q_SLOTS: + void checkDefaultConstruction() + { + // GIVEN + QSkeletonLoader skeleton; + + // THEN + QCOMPARE(skeleton.source(), QUrl()); + QCOMPARE(skeleton.status(), QSkeletonLoader::NotReady); + QCOMPARE(skeleton.isCreateJointsEnabled(), false); + } + + void checkPropertyChanges() + { + // GIVEN + QSkeletonLoader skeleton; + + { + // WHEN + QSignalSpy spy(&skeleton, SIGNAL(sourceChanged(QUrl))); + const QUrl newValue(QStringLiteral("qrc:/zergling.skel")); + skeleton.setSource(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(skeleton.source(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + skeleton.setSource(newValue); + + // THEN + QCOMPARE(skeleton.source(), newValue); + QCOMPARE(spy.count(), 0); + } + + { + // WHEN + QSignalSpy spy(&skeleton, SIGNAL(createJointsEnabledChanged(bool))); + const bool newValue(true); + skeleton.setCreateJointsEnabled(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(skeleton.isCreateJointsEnabled(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + skeleton.setCreateJointsEnabled(newValue); + + // THEN + QCOMPARE(skeleton.isCreateJointsEnabled(), newValue); + QCOMPARE(spy.count(), 0); + } + } + + void checkCreationData() + { + // GIVEN + QSkeletonLoader skeleton; + + skeleton.setSource(QUrl(QStringLiteral("http://someRemoteURL.com/dem-bones.skel"))); + + // WHEN + QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges; + + { + QNodeCreatedChangeGenerator creationChangeGenerator(&skeleton); + creationChanges = creationChangeGenerator.creationChanges(); + } + + // THEN + { + QCOMPARE(creationChanges.size(), 1); + + const auto creationChangeData = qSharedPointerCast<QNodeCreatedChange<QSkeletonLoaderData>>(creationChanges.first()); + const QSkeletonLoaderData data = creationChangeData->data; + + QCOMPARE(skeleton.id(), creationChangeData->subjectId()); + QCOMPARE(skeleton.isEnabled(), true); + QCOMPARE(skeleton.isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(skeleton.metaObject(), creationChangeData->metaObject()); + QCOMPARE(skeleton.source(), data.source); + QCOMPARE(skeleton.isCreateJointsEnabled(), data.createJoints); + } + + // WHEN + skeleton.setEnabled(false); + + { + QNodeCreatedChangeGenerator creationChangeGenerator(&skeleton); + creationChanges = creationChangeGenerator.creationChanges(); + } + + // THEN + { + QCOMPARE(creationChanges.size(), 1); + + const auto creationChangeData = qSharedPointerCast<QNodeCreatedChange<QSkeletonLoaderData>>(creationChanges.first()); + const QSkeletonLoaderData data = creationChangeData->data; + + QCOMPARE(skeleton.id(), creationChangeData->subjectId()); + QCOMPARE(skeleton.isEnabled(), false); + QCOMPARE(skeleton.isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(skeleton.metaObject(), creationChangeData->metaObject()); + QCOMPARE(skeleton.source(), data.source); + QCOMPARE(skeleton.isCreateJointsEnabled(), data.createJoints); + } + } + + void checkPropertyUpdates() + { + // GIVEN + TestArbiter arbiter; + QSkeletonLoader skeleton; + arbiter.setArbiterOnNode(&skeleton); + + { + // WHEN + skeleton.setSource(QUrl(QStringLiteral("qrc:/hydralisk.skel"))); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "source"); + QCOMPARE(change->type(), PropertyUpdated); + + arbiter.events.clear(); + } + + { + // WHEN + skeleton.setSource(QStringLiteral("qrc:/hydralisk.skel")); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + + + { + // WHEN + skeleton.setCreateJointsEnabled(true); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast<QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "createJointsEnabled"); + QCOMPARE(change->type(), PropertyUpdated); + + arbiter.events.clear(); + } + + { + // WHEN + skeleton.setCreateJointsEnabled(true); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + } + + void checkStatusPropertyUpdate() + { + // GIVEN + qRegisterMetaType<Qt3DCore::QSkeletonLoader::Status>("Status"); + TestArbiter arbiter; + arbiter.setArbiterOnNode(this); + QSignalSpy spy(this, SIGNAL(statusChanged(Status))); + const QSkeletonLoader::Status newStatus = QSkeletonLoader::Error; + + // THEN + QVERIFY(spy.isValid()); + + // WHEN + QPropertyUpdatedChangePtr valueChange(new QPropertyUpdatedChange(QNodeId())); + valueChange->setPropertyName("status"); + valueChange->setValue(QVariant::fromValue(newStatus)); + sceneChangeEvent(valueChange); + + // THEN + QCOMPARE(spy.count(), 1); + QCOMPARE(arbiter.events.size(), 0); + QCOMPARE(status(), newStatus); + + // WHEN + spy.clear(); + sceneChangeEvent(valueChange); + + // THEN + QCOMPARE(spy.count(), 0); + QCOMPARE(arbiter.events.size(), 0); + QCOMPARE(status(), newStatus); + } + + void checkRootJointPropertyUpdate() + { + // GIVEN + qRegisterMetaType<Qt3DCore::QJoint*>(); + TestArbiter arbiter; + arbiter.setArbiterOnNode(this); + QSignalSpy spy(this, SIGNAL(rootJointChanged(Qt3DCore::QJoint*))); + std::unique_ptr<QJoint> root(new QJoint()); + + // THEN + QVERIFY(spy.isValid()); + QVERIFY(rootJoint() == nullptr); + + // WHEN + auto valueChange = QJointChangePtr::create(id()); + valueChange->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes); + valueChange->setPropertyName("rootJoint"); + valueChange->data = std::move(root); + sceneChangeEvent(valueChange); + + // THEN + QCOMPARE(spy.count(), 1); + QCOMPARE(arbiter.events.size(), 1); + QVERIFY(rootJoint() != nullptr); + } +}; + +QTEST_MAIN(tst_QSkeletonLoader) + +#include "tst_qskeletonloader.moc" diff --git a/tests/auto/core/vector3d_base/tst_vector3d_base.cpp b/tests/auto/core/vector3d_base/tst_vector3d_base.cpp new file mode 100644 index 000000000..c3e5390a9 --- /dev/null +++ b/tests/auto/core/vector3d_base/tst_vector3d_base.cpp @@ -0,0 +1,705 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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/QtTest> +#include <Qt3DCore/private/vector3d_p.h> + +class tst_Vector3D_Base: public QObject +{ + Q_OBJECT +private Q_SLOTS: + void defaultConstruction() + { + // GIVEN + QVector3D vec3; + + // THEN + QCOMPARE(vec3.x(), 0.0f); + QCOMPARE(vec3.y(), 0.0f); + QCOMPARE(vec3.z(), 0.0f); + } + + void checkExplicitConstruction() + { + // GIVEN + QVector3D vec3(427.0f, 454.0f, 383.0f); + + // THEN + QCOMPARE(vec3.x(), 427.0f); + QCOMPARE(vec3.y(), 454.0f); + QCOMPARE(vec3.z(), 383.0f); + } + + void checkSelfAddition_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f + << 1.0f << 5.0f << 8.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f + << 5.0f << -8.0f << 4.0f + << 0.0f << 0.0f << 0.0f; + } + + void checkSelfAddition() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D vo(xO, yO, zO); + + // WHEN + vo += QVector3D(xA, yA, zA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfSubstraction_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f + << -1.0f << -5.0f << -8.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f + << 5.0f << -8.0f << 4.0f + << -10.0f << 16.0f << -8.0f; + } + + void checkSelfSubstraction() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D vo(xO, yO, zO); + + // WHEN + vo -= QVector3D(xA, yA, zA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfMultiplication_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f << 5.0f << 8.0f + << 0.0f << 0.0f << 16.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f + << 5.0f << -8.0f << 4.0f + << -25.0f << -64.0f << 16.0f; + } + + void checkSelfMultiplication() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D vo(xO, yO, zO); + + // WHEN + vo *= QVector3D(xA, yA, zA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfDivision_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f << 5.0f << 8.0f + << 0.0f << 0.0f << 0.25f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f + << 5.0f << -8.0f << 4.0f + << -1.0f << -1.0f << 1.0f; + } + + void checkSelfDivision() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D vo(xO, yO, zO); + + // WHEN + vo /= QVector3D(xA, yA, zA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfDivisionFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f + << 0.0f << 0.0f << 2.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f + << 5.0f + << -1.0f << 4.0f << -5.0f; + } + + void checkSelfDivisionFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D vo(xO, yO, zO); + + // WHEN + vo /= factor; + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfMultiplicationFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << -3.0f << 2.0f + << 1.0f + << 0.0f << -3.0f << 2.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f + << 5.0f + << -25.0f << 100.0f << -125.0f; + } + + void checkSelfMultiplicationFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D vo(xO, yO, zO); + + // WHEN + vo *= factor; + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkAddition_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f + << 1.0f << 5.0f << 8.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f + << 5.0f << -8.0f << 4.0f + << 0.0f << 0.0f << 0.0f; + } + + void checkAddition() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D v0(xO, yO, zO); + QVector3D v1(xA, yA, zA); + + // WHEN + QVector3D v2 = v0 + v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkSubstraction_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f + << -1.0f << -5.0f << -8.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f + << 5.0f << -8.0f << 4.0f + << -10.0f << 16.0f << -8.0f; + } + + void checkSubstraction() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D v0(xO, yO, zO); + QVector3D v1(xA, yA, zA); + + // WHEN + QVector3D v2 = v0 - v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkMultiplication_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f << 5.0f << 8.0f + << 0.0f << 0.0f << 16.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f + << 5.0f << -8.0f << 4.0f + << -25.0f << -64.0f << 16.0f; + } + + void checkMultiplication() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D v0(xO, yO, zO); + QVector3D v1(xA, yA, zA); + + // WHEN + QVector3D v2 = v0 * v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkDivision_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f << 5.0f << 8.0f + << 0.0f << 0.0f << 0.25f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f + << 5.0f << -8.0f << 4.0f + << -1.0f << -1.0f << 1.0f; + } + + void checkDivision() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D v0(xO, yO, zO); + QVector3D v1(xA, yA, zA); + + // WHEN + QVector3D v2 = v0 / v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkDivisionFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f + << 0.0f << 0.0f << 2.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f + << 5.0f + << -1.0f << 4.0f << -5.0f; + } + + void checkDivisionFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D v0(xO, yO, zO); + + // WHEN + QVector3D v2 = v0 / factor; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkMultiplicationFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << -3.0f << 2.0f + << 1.0f + << 0.0f << -3.0f << 2.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f + << 5.0f + << -25.0f << 100.0f << -125.0f; + } + + void checkMultiplicationFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + QVector3D v0(xO, yO, zO); + + // WHEN + QVector3D v2 = v0 * factor; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkEquality() + { + { + // GIVEN + QVector3D v0; + QVector3D v1; + + // THEN + QVERIFY(v0 == v1); + } + { + // GIVEN + QVector3D v0(1.0f, 2.0f, -5.0f); + QVector3D v1(1.0f, 2.0f, -5.0f); + + // THEN + QVERIFY(v0 == v1); + } + } + + void checkInequality() + { + { + // GIVEN + QVector3D v0; + QVector3D v1; + + // THEN + QVERIFY(!(v0 != v1)); + } + { + // GIVEN + QVector3D v0(1.0f, 2.0f, -5.0f); + QVector3D v1(1.0f, 5.0f, -5.0f); + + // THEN + QVERIFY(v0 != v1); + } + } + + void checkToQQVector3D() + { + { + // GIVEN + QVector3D v0; + + // WHEN + QVector3D v1 = v0; + + // THEN + QCOMPARE(v0.x(), v1.x()); + QCOMPARE(v0.y(), v1.y()); + QCOMPARE(v0.z(), v1.z()); + } + { + // GIVEN + QVector3D v0(1.0f, 2.0f, -5.0f); + + // WHEN + QVector3D v1 = v0; + + // THEN + QCOMPARE(v0.x(), v1.x()); + QCOMPARE(v0.y(), v1.y()); + QCOMPARE(v0.z(), v1.z()); + } + } +}; + +QTEST_MAIN(tst_Vector3D_Base) + +#include "tst_vector3d_base.moc" diff --git a/tests/auto/core/vector3d_base/vector3d_base.pro b/tests/auto/core/vector3d_base/vector3d_base.pro new file mode 100644 index 000000000..fa1ee87df --- /dev/null +++ b/tests/auto/core/vector3d_base/vector3d_base.pro @@ -0,0 +1,7 @@ +TARGET = tst_vector3d_base +CONFIG += testcase +QT += testlib 3dcore 3dcore-private + +SOURCES += \ + tst_vector3d_base.cpp + diff --git a/tests/auto/core/vector3d_sse/tst_vector3d_sse.cpp b/tests/auto/core/vector3d_sse/tst_vector3d_sse.cpp new file mode 100644 index 000000000..be9fbc347 --- /dev/null +++ b/tests/auto/core/vector3d_sse/tst_vector3d_sse.cpp @@ -0,0 +1,816 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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/QtTest> +#include <Qt3DCore/private/vector3d_sse_p.h> + +using namespace Qt3DCore; + +class tst_Vector3D_SSE: public QObject +{ + Q_OBJECT +private Q_SLOTS: + void defaultConstruction() + { + // GIVEN + Vector3D_SSE vec3; + + // THEN + QCOMPARE(vec3.x(), 0.0f); + QCOMPARE(vec3.y(), 0.0f); + QCOMPARE(vec3.z(), 0.0f); + } + + void checkExplicitConstruction() + { + // GIVEN + Vector3D_SSE vec3(427.0f, 454.0f, 383.0f); + + // THEN + QCOMPARE(vec3.x(), 427.0f); + QCOMPARE(vec3.y(), 454.0f); + QCOMPARE(vec3.z(), 383.0f); + } + + void checkSetters() + { + // GIVEN + Vector3D_SSE vec3; + + // WHEN + vec3.setX(427.0f); + vec3.setY(454.0f); + vec3.setZ(383.0f); + + // THEN + QCOMPARE(vec3.x(), 427.0f); + QCOMPARE(vec3.y(), 454.0f); + QCOMPARE(vec3.z(), 383.0f); + } + + + void checkSelfAddition_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f + << 1.0f << 5.0f << 8.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f + << 5.0f << -8.0f << 4.0f + << 0.0f << 0.0f << 0.0f; + } + + void checkSelfAddition() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE vo(xO, yO, zO); + + // WHEN + vo += Vector3D_SSE(xA, yA, zA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfSubstraction_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f + << -1.0f << -5.0f << -8.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f + << 5.0f << -8.0f << 4.0f + << -10.0f << 16.0f << -8.0f; + } + + void checkSelfSubstraction() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE vo(xO, yO, zO); + + // WHEN + vo -= Vector3D_SSE(xA, yA, zA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfMultiplication_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f << 5.0f << 8.0f + << 0.0f << 0.0f << 16.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f + << 5.0f << -8.0f << 4.0f + << -25.0f << -64.0f << 16.0f; + } + + void checkSelfMultiplication() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE vo(xO, yO, zO); + + // WHEN + vo *= Vector3D_SSE(xA, yA, zA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfDivision_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f << 5.0f << 8.0f + << 0.0f << 0.0f << 0.25f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f + << 5.0f << -8.0f << 4.0f + << -1.0f << -1.0f << 1.0f; + } + + void checkSelfDivision() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE vo(xO, yO, zO); + + // WHEN + vo /= Vector3D_SSE(xA, yA, zA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfDivisionFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f + << 0.0f << 0.0f << 2.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f + << 5.0f + << -1.0f << 4.0f << -5.0f; + } + + void checkSelfDivisionFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE vo(xO, yO, zO); + + // WHEN + vo /= factor; + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkSelfMultiplicationFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << -3.0f << 2.0f + << 1.0f + << 0.0f << -3.0f << 2.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f + << 5.0f + << -25.0f << 100.0f << -125.0f; + } + + void checkSelfMultiplicationFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE vo(xO, yO, zO); + + // WHEN + vo *= factor; + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + } + + void checkAddition_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f + << 1.0f << 5.0f << 8.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f + << 5.0f << -8.0f << 4.0f + << 0.0f << 0.0f << 0.0f; + } + + void checkAddition() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE v0(xO, yO, zO); + Vector3D_SSE v1(xA, yA, zA); + + // WHEN + Vector3D_SSE v2 = v0 + v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkSubstraction_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f + << -1.0f << -5.0f << -8.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f + << 5.0f << -8.0f << 4.0f + << -10.0f << 16.0f << -8.0f; + } + + void checkSubstraction() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE v0(xO, yO, zO); + Vector3D_SSE v1(xA, yA, zA); + + // WHEN + Vector3D_SSE v2 = v0 - v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkMultiplication_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f << 5.0f << 8.0f + << 0.0f << 0.0f << 16.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f + << 5.0f << -8.0f << 4.0f + << -25.0f << -64.0f << 16.0f; + } + + void checkMultiplication() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE v0(xO, yO, zO); + Vector3D_SSE v1(xA, yA, zA); + + // WHEN + Vector3D_SSE v2 = v0 * v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkDivision_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f << 5.0f << 8.0f + << 0.0f << 0.0f << 0.25f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f + << 5.0f << -8.0f << 4.0f + << -1.0f << -1.0f << 1.0f; + } + + void checkDivision() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE v0(xO, yO, zO); + Vector3D_SSE v1(xA, yA, zA); + + // WHEN + Vector3D_SSE v2 = v0 / v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkDivisionFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f + << 1.0f + << 0.0f << 0.0f << 2.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f + << 5.0f + << -1.0f << 4.0f << -5.0f; + } + + void checkDivisionFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE v0(xO, yO, zO); + + // WHEN + Vector3D_SSE v2 = v0 / factor; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkMultiplicationFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + + QTest::newRow("sample_1") << 0.0f << -3.0f << 2.0f + << 1.0f + << 0.0f << -3.0f << 2.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f + << 5.0f + << -25.0f << 100.0f << -125.0f; + } + + void checkMultiplicationFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + + // GIVEN + Vector3D_SSE v0(xO, yO, zO); + + // WHEN + Vector3D_SSE v2 = v0 * factor; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + } + + void checkEquality() + { + { + // GIVEN + Vector3D_SSE v0; + Vector3D_SSE v1; + + // THEN + QVERIFY(v0 == v1); + } + { + // GIVEN + Vector3D_SSE v0(1.0f, 2.0f, -5.0f); + Vector3D_SSE v1(1.0f, 2.0f, -5.0f); + + // THEN + QVERIFY(v0 == v1); + } + } + + void checkInequality() + { + { + // GIVEN + Vector3D_SSE v0; + Vector3D_SSE v1; + + // THEN + QVERIFY(!(v0 != v1)); + } + { + // GIVEN + Vector3D_SSE v0(1.0f, 2.0f, -5.0f); + Vector3D_SSE v1(1.0f, 5.0f, -5.0f); + + // THEN + QVERIFY(v0 != v1); + } + } + + void checkToQVector3D_SSE() + { + { + // GIVEN + Vector3D_SSE v0; + + // WHEN + QVector3D v1 = v0.toQVector3D(); + + // THEN + QCOMPARE(v0.x(), v1.x()); + QCOMPARE(v0.y(), v1.y()); + QCOMPARE(v0.z(), v1.z()); + } + { + // GIVEN + Vector3D_SSE v0(1.0f, 2.0f, -5.0f); + + // WHEN + QVector3D v1 = v0.toQVector3D(); + + // THEN + QCOMPARE(v0.x(), v1.x()); + QCOMPARE(v0.y(), v1.y()); + QCOMPARE(v0.z(), v1.z()); + } + } + + void checkLengthSquared() + { + { + // GIVEN + Vector3D_SSE v0(10.0f, 10.0f, 10.0f); + + // THEN + QCOMPARE(v0.lengthSquared(), 300.0f); + } + { + // GIVEN + Vector3D_SSE v0(3.0f, 1.0f, 2.0f); + + // THEN + QCOMPARE(v0.lengthSquared(), 14.0f); + } + } + + void checkLength() + { + { + // GIVEN + Vector3D_SSE v0(3.0f, 0.0f, 0.0f); + + // THEN + QCOMPARE(v0.length(), 3.0f); + } + { + // GIVEN + Vector3D_SSE v0(0.0f, 10.0f, 0.0f); + + // THEN + QCOMPARE(v0.length(), 10.0f); + } + { + // GIVEN + Vector3D_SSE v0(0.0f, 0.0f, 9.0f); + + // THEN + QCOMPARE(v0.length(), 9.0f); + } + } + + void checkNormalize() + { + { + // GIVEN + Vector3D_SSE v0(10.0f, 0.0f, 0.0f); + + // WHEN + v0.normalize(); + + // THEN + QCOMPARE(v0, Vector3D_SSE(1.0f, 0.0f, 0.0f)); + } + { + // GIVEN + Vector3D_SSE v0(3.0f, 0.0f, 3.0f); + + // WHEN + v0.normalize(); + + // THEN + // (0.707107 == sqrt(2) / 2) + Vector3D_SSE v2(0.707107f, 0.0f, 0.707107f); + QCOMPARE(qFuzzyCompare(v0, v2), true); + } + } + + void checkNormalized() + { + + } + + void checkIsNull() + { + { + // GIVEN + Vector3D_SSE v0; + + // THEN + QVERIFY(v0.isNull()); + } + { + // GIVEN + Vector3D_SSE v0(1.0f, 1.0f, 1.0f); + + // THEN + QVERIFY(!v0.isNull()); + } + } +}; + +QTEST_APPLESS_MAIN(tst_Vector3D_SSE) + +#include "tst_vector3d_sse.moc" diff --git a/tests/auto/core/vector3d_sse/vector3d_sse.pro b/tests/auto/core/vector3d_sse/vector3d_sse.pro new file mode 100644 index 000000000..6afc4a863 --- /dev/null +++ b/tests/auto/core/vector3d_sse/vector3d_sse.pro @@ -0,0 +1,8 @@ +TARGET = tst_vector3d_sse +CONFIG += testcase simd +QT += testlib 3dcore 3dcore-private + +SOURCES += \ + tst_vector3d_sse.cpp + +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2 diff --git a/tests/auto/core/vector4d_base/tst_vector4d_base.cpp b/tests/auto/core/vector4d_base/tst_vector4d_base.cpp new file mode 100644 index 000000000..e152625fe --- /dev/null +++ b/tests/auto/core/vector4d_base/tst_vector4d_base.cpp @@ -0,0 +1,785 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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/QtTest> +#include <Qt3DCore/private/vector4d_p.h> + +class tst_Vector4D_Base: public QObject +{ + Q_OBJECT +private Q_SLOTS: + void defaultConstruction() + { + // GIVEN + QVector4D vec4; + + // THEN + QCOMPARE(vec4.x(), 0.0f); + QCOMPARE(vec4.y(), 0.0f); + QCOMPARE(vec4.z(), 0.0f); + QCOMPARE(vec4.w(), 0.0f); + } + + void checkExplicitConstruction() + { + // GIVEN + QVector4D vec4(427.0f, 454.0f, 383.0f, 350.0f); + + // THEN + QCOMPARE(vec4.x(), 427.0f); + QCOMPARE(vec4.y(), 454.0f); + QCOMPARE(vec4.z(), 383.0f); + QCOMPARE(vec4.w(), 350.0f); + } + + void checkSelfAddition_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 1.0f << 5.0f << 8.0f << -5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << -6.0f + << 0.0f << 0.0f << 0.0f << 0.0f; + } + + void checkSelfAddition() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D vo(xO, yO, zO, wO); + + // WHEN + vo += QVector4D(xA, yA, zA, wA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfSubstraction_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << -1.0f << -5.0f << -8.0f << 5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << -6.0f + << -10.0f << 16.0f << -8.0f << 12.0f; + } + + void checkSelfSubstraction() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D vo(xO, yO, zO, wO); + + // WHEN + vo -= QVector4D(xA, yA, zA, wA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfMultiplication_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 0.0f << 0.0f << 16.0f << -5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << 6.0f + << -25.0f << -64.0f << 16.0f << 36.0f; + } + + void checkSelfMultiplication() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D vo(xO, yO, zO, wO); + + // WHEN + vo *= QVector4D(xA, yA, zA, wA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfDivision_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 0.0f << 0.0f << 0.25f << -0.20f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << 6.0f + << -1.0f << -1.0f << 1.0f << 1.0f; + } + + void checkSelfDivision() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D vo(xO, yO, zO, wO); + + // WHEN + vo /= QVector4D(xA, yA, zA, wA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfDivisionFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f + << 0.0f << 0.0f << 2.0f << 1.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f << 10.0f + << 5.0f + << -1.0f << 4.0f << -5.0f << 2.0f; + } + + void checkSelfDivisionFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D vo(xO, yO, zO, wO); + + // WHEN + vo /= factor; + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfMultiplicationFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << -3.0f << 2.0f << 1.0f + << 1.0f + << 0.0f << -3.0f << 2.0f << 1.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f << 10.0f + << 5.0f + << -25.0f << 100.0f << -125.0f << 50.0f; + } + + void checkSelfMultiplicationFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D vo(xO, yO, zO, wO); + + // WHEN + vo *= factor; + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkAddition_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 1.0f << 5.0f << 8.0f << -5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << -6.0f + << 0.0f << 0.0f << 0.0f << 0.0f; + } + + void checkAddition() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D v0(xO, yO, zO, wO); + QVector4D v1(xA, yA, zA, wA); + + // WHEN + QVector4D v2 = v0 + v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkSubstraction_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << -1.0f << -5.0f << -8.0f << 5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << -6.0f + << -10.0f << 16.0f << -8.0f << 12.0f; + } + + void checkSubstraction() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D v0(xO, yO, zO, wO); + QVector4D v1(xA, yA, zA, wA); + + // WHEN + QVector4D v2 = v0 - v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkMultiplication_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 0.0f << 0.0f << 16.0f << -5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << 6.0f + << -25.0f << -64.0f << 16.0f << 36.0f; + } + + void checkMultiplication() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D v0(xO, yO, zO, wO); + QVector4D v1(xA, yA, zA, wA); + + // WHEN + QVector4D v2 = v0 * v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkDivision_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 0.0f << 0.0f << 0.25f << -0.20f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << 6.0f + << -1.0f << -1.0f << 1.0f << 1.0f; + } + + void checkDivision() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D v0(xO, yO, zO, wO); + QVector4D v1(xA, yA, zA, wA); + + // WHEN + QVector4D v2 = v0 / v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkDivisionFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f + << 0.0f << 0.0f << 2.0f << 1.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f << 10.0f + << 5.0f + << -1.0f << 4.0f << -5.0f << 2.0f; + } + + void checkDivisionFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D v0(xO, yO, zO, wO); + + // WHEN + QVector4D v2 = v0 / factor; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkMultiplicationFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << -3.0f << 2.0f << 1.0f + << 1.0f + << 0.0f << -3.0f << 2.0f << 1.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f << 10.0f + << 5.0f + << -25.0f << 100.0f << -125.0f << 50.0f; + } + + void checkMultiplicationFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + QVector4D v0(xO, yO, zO, wO); + + // WHEN + QVector4D v2 = v0 * factor; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkEquality() + { + { + // GIVEN + QVector4D v0; + QVector4D v1; + + // THEN + QVERIFY(v0 == v1); + } + { + // GIVEN + QVector4D v0(1.0f, 2.0f, -5.0f, 10.0f); + QVector4D v1(1.0f, 2.0f, -5.0f, 10.0f); + + // THEN + QVERIFY(v0 == v1); + } + } + + void checkInequality() + { + { + // GIVEN + QVector4D v0; + QVector4D v1; + + // THEN + QVERIFY(!(v0 != v1)); + } + { + // GIVEN + QVector4D v0(1.0f, 2.0f, -5.0f, 10.0f); + QVector4D v1(1.0f, 5.0f, -5.0f, 10.0f); + + // THEN + QVERIFY(v0 != v1); + } + } + + void checkToQQVector4D() + { + { + // GIVEN + QVector4D v0; + + // WHEN + QVector4D v1 = v0; + + // THEN + QCOMPARE(v0.x(), v1.x()); + QCOMPARE(v0.y(), v1.y()); + QCOMPARE(v0.z(), v1.z()); + QCOMPARE(v0.w(), v1.w()); + } + { + // GIVEN + QVector4D v0(1.0f, 2.0f, -5.0f, 10.0f); + + // WHEN + QVector4D v1 = v0; + + // THEN + QCOMPARE(v0.x(), v1.x()); + QCOMPARE(v0.y(), v1.y()); + QCOMPARE(v0.z(), v1.z()); + QCOMPARE(v0.w(), v1.w()); + } + } +}; + +QTEST_APPLESS_MAIN(tst_Vector4D_Base) + +#include "tst_vector4d_base.moc" diff --git a/tests/auto/core/vector4d_base/vector4d_base.pro b/tests/auto/core/vector4d_base/vector4d_base.pro new file mode 100644 index 000000000..9afaff092 --- /dev/null +++ b/tests/auto/core/vector4d_base/vector4d_base.pro @@ -0,0 +1,7 @@ +TARGET = tst_vector4d_base +CONFIG += testcase + +SOURCES += \ + tst_vector4d_base.cpp + +QT += testlib 3dcore 3dcore-private diff --git a/tests/auto/core/vector4d_sse/tst_vector4d_sse.cpp b/tests/auto/core/vector4d_sse/tst_vector4d_sse.cpp new file mode 100644 index 000000000..e7b58c8cf --- /dev/null +++ b/tests/auto/core/vector4d_sse/tst_vector4d_sse.cpp @@ -0,0 +1,830 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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/QtTest> +#include <Qt3DCore/private/vector4d_sse_p.h> +#include <Qt3DCore/qt3dcore-config.h> + +using namespace Qt3DCore; + +class tst_Vector4D_SSE: public QObject +{ + Q_OBJECT +private Q_SLOTS: + void defaultConstruction() + { + // GIVEN + Vector4D_SSE vec4; + + // THEN + QCOMPARE(vec4.x(), 0.0f); + QCOMPARE(vec4.y(), 0.0f); + QCOMPARE(vec4.z(), 0.0f); + QCOMPARE(vec4.w(), 0.0f); + } + + void checkExplicitConstruction() + { + // GIVEN + Vector4D_SSE vec4(427.0f, 454.0f, 383.0f, 350.0f); + + // THEN + QCOMPARE(vec4.x(), 427.0f); + QCOMPARE(vec4.y(), 454.0f); + QCOMPARE(vec4.z(), 383.0f); + QCOMPARE(vec4.w(), 350.0f); + } + + void checkSetters() + { + // GIVEN + Vector4D_SSE vec4; + + // WHEN + vec4.setX(427.0f); + + // THEN + QCOMPARE(vec4.x(), 427.0f); + QCOMPARE(vec4.y(), 0.0f); + QCOMPARE(vec4.z(), 0.0f); + QCOMPARE(vec4.w(), 0.0f); + + // WHEN + vec4.setY(454.0f); + + // THEN + QCOMPARE(vec4.x(), 427.0f); + QCOMPARE(vec4.y(), 454.0f); + QCOMPARE(vec4.z(), 0.0f); + QCOMPARE(vec4.w(), 0.0f); + + // WHEN + vec4.setZ(383.0f); + + // THEN + QCOMPARE(vec4.x(), 427.0f); + QCOMPARE(vec4.y(), 454.0f); + QCOMPARE(vec4.z(), 383.0f); + QCOMPARE(vec4.w(), 0.0f); + + // WHEN + vec4.setW(350.0f); + + // THEN + QCOMPARE(vec4.x(), 427.0f); + QCOMPARE(vec4.y(), 454.0f); + QCOMPARE(vec4.z(), 383.0f); + QCOMPARE(vec4.w(), 350.0f); + } + + void checkSelfAddition_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 1.0f << 5.0f << 8.0f << -5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << -6.0f + << 0.0f << 0.0f << 0.0f << 0.0f; + } + + void checkSelfAddition() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE vo(xO, yO, zO, wO); + + // WHEN + vo += Vector4D_SSE(xA, yA, zA, wA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfSubstraction_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << -1.0f << -5.0f << -8.0f << 5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << -6.0f + << -10.0f << 16.0f << -8.0f << 12.0f; + } + + void checkSelfSubstraction() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE vo(xO, yO, zO, wO); + + // WHEN + vo -= Vector4D_SSE(xA, yA, zA, wA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfMultiplication_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 0.0f << 0.0f << 16.0f << -5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << 6.0f + << -25.0f << -64.0f << 16.0f << 36.0f; + } + + void checkSelfMultiplication() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE vo(xO, yO, zO, wO); + + // WHEN + vo *= Vector4D_SSE(xA, yA, zA, wA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfDivision_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 0.0f << 0.0f << 0.25f << -0.20f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << 6.0f + << -1.0f << -1.0f << 1.0f << 1.0f; + } + + void checkSelfDivision() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE vo(xO, yO, zO, wO); + + // WHEN + vo /= Vector4D_SSE(xA, yA, zA, wA); + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfDivisionFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f + << 0.0f << 0.0f << 2.0f << 1.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f << 10.0f + << 5.0f + << -1.0f << 4.0f << -5.0f << 2.0f; + } + + void checkSelfDivisionFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE vo(xO, yO, zO, wO); + + // WHEN + vo /= factor; + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkSelfMultiplicationFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << -3.0f << 2.0f << 1.0f + << 1.0f + << 0.0f << -3.0f << 2.0f << 1.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f << 10.0f + << 5.0f + << -25.0f << 100.0f << -125.0f << 50.0f; + } + + void checkSelfMultiplicationFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE vo(xO, yO, zO, wO); + + // WHEN + vo *= factor; + + // THEN + QCOMPARE(vo.x(), xR); + QCOMPARE(vo.y(), yR); + QCOMPARE(vo.z(), zR); + QCOMPARE(vo.w(), wR); + } + + void checkAddition_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 1.0f << 5.0f << 8.0f << -5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << -6.0f + << 0.0f << 0.0f << 0.0f << 0.0f; + } + + void checkAddition() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE v0(xO, yO, zO, wO); + Vector4D_SSE v1(xA, yA, zA, wA); + + // WHEN + Vector4D_SSE v2 = v0 + v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkSubstraction_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 0.0f << 0.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << -1.0f << -5.0f << -8.0f << 5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << -4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << -6.0f + << -10.0f << 16.0f << -8.0f << 12.0f; + } + + void checkSubstraction() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE v0(xO, yO, zO, wO); + Vector4D_SSE v1(xA, yA, zA, wA); + + // WHEN + Vector4D_SSE v2 = v0 - v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkMultiplication_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 0.0f << 0.0f << 16.0f << -5.0f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << 6.0f + << -25.0f << -64.0f << 16.0f << 36.0f; + } + + void checkMultiplication() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE v0(xO, yO, zO, wO); + Vector4D_SSE v1(xA, yA, zA, wA); + + // WHEN + Vector4D_SSE v2 = v0 * v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkDivision_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("xA"); + QTest::addColumn<float>("yA"); + QTest::addColumn<float>("zA"); + QTest::addColumn<float>("wA"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f << 5.0f << 8.0f << -5.0f + << 0.0f << 0.0f << 0.25f << -0.20f; + + QTest::newRow("sample_2") << -5.0f << 8.0f << 4.0f << 6.0f + << 5.0f << -8.0f << 4.0f << 6.0f + << -1.0f << -1.0f << 1.0f << 1.0f; + } + + void checkDivision() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, xA); + QFETCH(float, yA); + QFETCH(float, zA); + QFETCH(float, wA); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE v0(xO, yO, zO, wO); + Vector4D_SSE v1(xA, yA, zA, wA); + + // WHEN + Vector4D_SSE v2 = v0 / v1; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkDivisionFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << 0.0f << 2.0f << 1.0f + << 1.0f + << 0.0f << 0.0f << 2.0f << 1.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f << 10.0f + << 5.0f + << -1.0f << 4.0f << -5.0f << 2.0f; + } + + void checkDivisionFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE v0(xO, yO, zO, wO); + + // WHEN + Vector4D_SSE v2 = v0 / factor; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkMultiplicationFactor_data() + { + QTest::addColumn<float>("xO"); + QTest::addColumn<float>("yO"); + QTest::addColumn<float>("zO"); + QTest::addColumn<float>("wO"); + + QTest::addColumn<float>("factor"); + + QTest::addColumn<float>("xR"); + QTest::addColumn<float>("yR"); + QTest::addColumn<float>("zR"); + QTest::addColumn<float>("wR"); + + QTest::newRow("sample_1") << 0.0f << -3.0f << 2.0f << 1.0f + << 1.0f + << 0.0f << -3.0f << 2.0f << 1.0f; + + QTest::newRow("sample_2") << -5.0f << 20.0f << -25.0f << 10.0f + << 5.0f + << -25.0f << 100.0f << -125.0f << 50.0f; + } + + void checkMultiplicationFactor() + { + QFETCH(float, xO); + QFETCH(float, yO); + QFETCH(float, zO); + QFETCH(float, wO); + + QFETCH(float, factor); + + QFETCH(float, xR); + QFETCH(float, yR); + QFETCH(float, zR); + QFETCH(float, wR); + + // GIVEN + Vector4D_SSE v0(xO, yO, zO, wO); + + // WHEN + Vector4D_SSE v2 = v0 * factor; + + // THEN + QCOMPARE(v2.x(), xR); + QCOMPARE(v2.y(), yR); + QCOMPARE(v2.z(), zR); + QCOMPARE(v2.w(), wR); + } + + void checkEquality() + { + { + // GIVEN + Vector4D_SSE v0; + Vector4D_SSE v1; + + // THEN + QVERIFY(v0 == v1); + } + { + // GIVEN + Vector4D_SSE v0(1.0f, 2.0f, -5.0f, 10.0f); + Vector4D_SSE v1(1.0f, 2.0f, -5.0f, 10.0f); + + // THEN + QVERIFY(v0 == v1); + } + } + + void checkInequality() + { + { + // GIVEN + Vector4D_SSE v0; + Vector4D_SSE v1; + + // THEN + QVERIFY(!(v0 != v1)); + } + { + // GIVEN + Vector4D_SSE v0(1.0f, 2.0f, -5.0f, 10.0f); + Vector4D_SSE v1(1.0f, 5.0f, -5.0f, 10.0f); + + // THEN + QVERIFY(v0 != v1); + } + } + + void checkToQVector4D_SSE() + { + { + // GIVEN + Vector4D_SSE v0; + + // WHEN + QVector4D v1 = v0.toQVector4D(); + + // THEN + QCOMPARE(v0.x(), v1.x()); + QCOMPARE(v0.y(), v1.y()); + QCOMPARE(v0.z(), v1.z()); + QCOMPARE(v0.w(), v1.w()); + } + { + // GIVEN + Vector4D_SSE v0(1.0f, 2.0f, -5.0f, 10.0f); + + // WHEN + QVector4D v1 = v0.toQVector4D(); + + // THEN + QCOMPARE(v0.x(), v1.x()); + QCOMPARE(v0.y(), v1.y()); + QCOMPARE(v0.z(), v1.z()); + QCOMPARE(v0.w(), v1.w()); + } + } +}; + +QTEST_APPLESS_MAIN(tst_Vector4D_SSE) + +#include "tst_vector4d_sse.moc" diff --git a/tests/auto/core/vector4d_sse/vector4d_sse.pro b/tests/auto/core/vector4d_sse/vector4d_sse.pro new file mode 100644 index 000000000..76c425548 --- /dev/null +++ b/tests/auto/core/vector4d_sse/vector4d_sse.pro @@ -0,0 +1,9 @@ +TARGET = tst_vector4d_sse +CONFIG += testcase simd + +SOURCES += \ + tst_vector4d_sse.cpp + +QT += testlib 3dcore 3dcore-private + +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2 diff --git a/tests/auto/quick3d/3dcore/3dcore.qml b/tests/auto/quick3d/3dcore/3dcore.qml index df9dd429b..72514591c 100644 --- a/tests/auto/quick3d/3dcore/3dcore.qml +++ b/tests/auto/quick3d/3dcore/3dcore.qml @@ -29,6 +29,7 @@ import Qt3D.Core 2.0 as QQ3Core20 import Qt3D.Core 2.9 as QQ3Core29 +import Qt3D.Core 2.10 as QQ3Core210 import QtQuick 2.0 Item { @@ -42,4 +43,8 @@ Item { QQ3Core20.QuaternionAnimation {} //Qt3DCore::Quick::QQuaternionAnimation QQ3Core29.Entity {} //Qt3DCore::QEntity, Qt3DCore::Quick::Quick3DEntity + + QQ3Core210.Armature {} + QQ3Core210.SkeletonLoader {} + QQ3Core210.Joint {} } diff --git a/tests/auto/quick3d/3drender/3drender.qml b/tests/auto/quick3d/3drender/3drender.qml index 92461fe8d..112031282 100644 --- a/tests/auto/quick3d/3drender/3drender.qml +++ b/tests/auto/quick3d/3drender/3drender.qml @@ -29,6 +29,7 @@ import Qt3D.Render 2.0 as QQ3Render20 import Qt3D.Render 2.1 as QQ3Render21 +import Qt3D.Render 2.10 as QQ3Render210 import QtQuick 2.0 Item { @@ -120,6 +121,7 @@ Item { QQ3Render20.DispatchCompute {} //Qt3DRender::QDispatchCompute QQ3Render21.RenderCapture {} //Qt3DRender::QRenderCapture //QQ3Render21.RenderCaptureReply // (uncreatable) Qt3DRender::QRenderCaptureReply + QQ3Render210.ProximityFilter {} //Q3DRender::QProximityFilter // RenderTarget QQ3Render20.RenderTargetOutput {} //Qt3DRender::QRenderTargetOutput 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..7af342264 100644 --- a/tests/auto/render/buffer/tst_buffer.cpp +++ b/tests/auto/render/buffer/tst_buffer.cpp @@ -73,11 +73,14 @@ 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); @@ -160,6 +163,8 @@ private Q_SLOTS: 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())); @@ -167,11 +172,15 @@ private Q_SLOTS: updateChange->setPropertyName("type"); renderBuffer.sceneChangeEvent(updateChange); + // THEN QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::IndexBuffer); QVERIFY(renderer.dirtyBits() != 0); QVERIFY(renderBuffer.isDirty()); + QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::BuffersDirty); + renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); + renderBuffer.unsetDirty(); QVERIFY(!renderBuffer.isDirty()); @@ -185,6 +194,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 +213,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 +231,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 +247,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 +280,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 +293,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 +312,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 Binary files differnew file mode 100644 index 000000000..62ae2a11f --- /dev/null +++ b/tests/auto/render/ddstextures/data/16x16-etc1.pkm diff --git a/tests/auto/render/ddstextures/data/16x16-etc2.pkm b/tests/auto/render/ddstextures/data/16x16-etc2.pkm Binary files differnew file mode 100644 index 000000000..be391113e --- /dev/null +++ b/tests/auto/render/ddstextures/data/16x16-etc2.pkm 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/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 5a6f87e23..292bcfba3 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) @@ -1013,6 +1042,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) @@ -1432,6 +1506,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..22fdb36a3 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((GLenum)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((GLenum)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/pickboundingvolumejob/tst_pickboundingvolumejob.cpp b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp index 1d391101e..e2cc190df 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/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..c0513da3f --- /dev/null +++ b/tests/auto/render/qshaderprogrambuilder/tst_qshaderprogrambuilder.cpp @@ -0,0 +1,545 @@ +/**************************************************************************** +** +** 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()); + 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(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.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.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.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 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..855b07797 --- /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 = 12 + 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..b781ff04d 100644 --- a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp +++ b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp @@ -199,7 +199,7 @@ private Q_SLOTS: 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()); + QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 12 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount()); } void checkCheckJobDependencies() @@ -219,7 +219,7 @@ private Q_SLOTS: // THEN // Step 1 - QCOMPARE(renderViewBuilder.renderViewJob()->dependencies().size(), 0); + 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); @@ -233,6 +233,10 @@ private Q_SLOTS: QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob())); QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(testAspect.renderer()->updateTreeEnabledJob())); + 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()); @@ -252,7 +256,7 @@ private Q_SLOTS: QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncFrustumCullingJob())); QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob())); - QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 6); + 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())); @@ -361,7 +365,7 @@ private Q_SLOTS: // THEN QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), false); QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), false); - QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layers().size(), 0); + QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 0); for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { QVERIFY(materialGatherer->techniqueFilter() == nullptr); QVERIFY(materialGatherer->renderPassFilter() == nullptr); @@ -374,7 +378,7 @@ private Q_SLOTS: // THEN QCOMPARE(renderViewBuilder.frustumCullingJob()->isActive(), true); QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->hasLayerFilter(), true); - QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layers().size(), 1); + QCOMPARE(renderViewBuilder.filterEntityByLayerJob()->layerFilters().size(), 1); for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) { QVERIFY(materialGatherer->techniqueFilter() != nullptr); QVERIFY(materialGatherer->renderPassFilter() != nullptr); 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..c381f328e --- /dev/null +++ b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp @@ -0,0 +1,458 @@ +/**************************************************************************** +** +** 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()); + 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->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.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()); + 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 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..1cfa44e6b --- /dev/null +++ b/tests/auto/render/skeleton/tst_skeleton.cpp @@ -0,0 +1,382 @@ +/**************************************************************************** +** +** 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) + +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<JointInfo>("jointInfo"); + QTest::addColumn<QJoint *>("expectedJoint"); + + QTest::newRow("default") << JointInfo() << 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); + JointInfo jointInfo; + jointInfo.localPose.scale = s; + jointInfo.localPose.rotation = r; + jointInfo.localPose.translation = t; + + QJoint *joint = new QJoint(); + joint->setTranslation(t); + joint->setRotation(r); + joint->setScale(s); + QTest::newRow("localPose") << jointInfo << joint; + + QMatrix4x4 m; + m.rotate(r); + m.scale(QVector3D(1.0f, 1.0f, 1.0f) / s); + m.translate(-t); + jointInfo.inverseBindPose = m; + + joint = new QJoint(); + joint->setTranslation(t); + joint->setRotation(r); + joint->setScale(s); + joint->setInverseBindMatrix(m); + QTest::newRow("inverseBind") << jointInfo << joint; + } + + void checkCreateFrontendJoint() + { + // GIVEN + Skeleton backendSkeleton; + QFETCH(JointInfo, jointInfo); + QFETCH(QJoint *, expectedJoint); + + // WHEN + const QJoint *actualJoint = backendSkeleton.createFrontendJoint(jointInfo); + + // THEN + QCOMPARE(actualJoint->scale(), expectedJoint->scale()); + QCOMPARE(actualJoint->rotation(), expectedJoint->rotation()); + QCOMPARE(actualJoint->translation(), expectedJoint->translation()); + QCOMPARE(actualJoint->inverseBindMatrix(), expectedJoint->inverseBindMatrix()); + + // 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); + const int childCount = 10; + for (int i = 0; i < childCount; ++i) { + JointInfo childJointInfo; + const float x = static_cast<float>(i); + childJointInfo.localPose.translation = QVector3D(x, x, x); + childJointInfo.parentIndex = 0; + skeletonData.joints.push_back(childJointInfo); + } + + 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; + const float x = static_cast<float>(i); + childJointInfo.localPose.translation = QVector3D(x, x, x); + childJointInfo.parentIndex = i; + skeletonData.joints.push_back(childJointInfo); + } + + 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.joints[i].localPose.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]); + } + } }; diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index bcaf713c6..7dfc52eec 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -1,4 +1,7 @@ TEMPLATE = subdirs SUBDIRS = \ - core \ - render + core + +QT_FOR_CONFIG += 3dcore + +qtConfig(qt3d-render): SUBDIRS += render diff --git a/tests/benchmarks/render/layerfiltering/tst_bench_layerfiltering.cpp b/tests/benchmarks/render/layerfiltering/tst_bench_layerfiltering.cpp index 78f264349..d1ef468b2 100644 --- a/tests/benchmarks/render/layerfiltering/tst_bench_layerfiltering.cpp +++ b/tests/benchmarks/render/layerfiltering/tst_bench_layerfiltering.cpp @@ -26,7 +26,7 @@ ** ****************************************************************************/ -#include <QtTest/QTest> +#include <QtTest/QtTest> #include <Qt3DCore/qentity.h> #include <Qt3DCore/private/qnodecreatedchangegenerator_p.h> #include <Qt3DCore/private/qaspectjobmanager_p.h> @@ -38,6 +38,7 @@ #include <Qt3DRender/private/qrenderaspect_p.h> #include <Qt3DRender/private/filterlayerentityjob_p.h> #include <Qt3DRender/qlayer.h> +#include <Qt3DRender/qlayerfilter.h> QT_BEGIN_NAMESPACE @@ -85,26 +86,28 @@ namespace { Qt3DCore::QEntity *buildTestScene(int layersCount, int entityCount, - QVector<Qt3DCore::QNodeId> &layerIds, + QVector<Qt3DCore::QNodeId> &layerFilterIds, bool alwaysEnabled = true) { Qt3DCore::QEntity *root = new Qt3DCore::QEntity(); + Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(root); + layerFilterIds.push_back(layerFilter->id()); QVector<Qt3DRender::QLayer *> layers; layers.reserve(layersCount); - layerIds.reserve(layersCount); + for (int i = 0; i < layersCount; ++i) { Qt3DRender::QLayer *layer = new Qt3DRender::QLayer(root); layers.push_back(layer); - layerIds.push_back(layer->id()); + layerFilter->addLayer(layer); } for (int i = 0; i < entityCount; ++i) { Qt3DCore::QEntity *entity = new Qt3DCore::QEntity(root); if (layersCount > 0) - entity->addComponent(layers.at(qrand() % layersCount)); + entity->addComponent(layers.at(QRandomGenerator::bounded(layersCount))); if (!alwaysEnabled && i % 128 == 0) entity->setEnabled(false); @@ -123,43 +126,38 @@ private Q_SLOTS: void filterEntities_data() { QTest::addColumn<Qt3DCore::QEntity *>("entitySubtree"); - QTest::addColumn<Qt3DCore::QNodeIdVector>("layerIds"); - QTest::addColumn<bool>("hasLayerFilter"); + QTest::addColumn<Qt3DCore::QNodeIdVector>("layerFilterIds"); { - Qt3DCore::QNodeIdVector layerIds; - Qt3DCore::QEntity *rootEntity = buildTestScene(0, 5000, layerIds); + Qt3DCore::QNodeIdVector layerFilterIds; + Qt3DCore::QEntity *rootEntity = buildTestScene(0, 5000, layerFilterIds); QTest::newRow("Filter-NoLayerFilterAllEnabled") << rootEntity - << layerIds - << (layerIds.size() != 0); + << layerFilterIds; } { - Qt3DCore::QNodeIdVector layerIds; - Qt3DCore::QEntity *rootEntity = buildTestScene(0, 5000, layerIds, false); + Qt3DCore::QNodeIdVector layerFilterIds; + Qt3DCore::QEntity *rootEntity = buildTestScene(0, 5000, layerFilterIds, false); QTest::newRow("Filter-NoLayerFilterSomeDisabled") << rootEntity - << layerIds - << (layerIds.size() != 0); + << layerFilterIds; } { - Qt3DCore::QNodeIdVector layerIds; - Qt3DCore::QEntity *rootEntity = buildTestScene(10, 5000, layerIds); + Qt3DCore::QNodeIdVector layerFilterIds; + Qt3DCore::QEntity *rootEntity = buildTestScene(10, 5000, layerFilterIds); QTest::newRow("FilterLayerFilterAllEnabled") << rootEntity - << layerIds - << (layerIds.size() != 0); + << layerFilterIds; } { - Qt3DCore::QNodeIdVector layerIds; - Qt3DCore::QEntity *rootEntity = buildTestScene(10, 5000, layerIds, false); + Qt3DCore::QNodeIdVector layerFilterIds; + Qt3DCore::QEntity *rootEntity = buildTestScene(10, 5000, layerFilterIds, false); QTest::newRow("FilterLayerFilterSomeDisabled") << rootEntity - << layerIds - << (layerIds.size() != 0); + << layerFilterIds; } } @@ -167,16 +165,14 @@ private Q_SLOTS: void filterEntities() { QFETCH(Qt3DCore::QEntity *, entitySubtree); - QFETCH(Qt3DCore::QNodeIdVector, layerIds); - QFETCH(bool, hasLayerFilter); + QFETCH(Qt3DCore::QNodeIdVector, layerFilterIds); // GIVEN QScopedPointer<Qt3DRender::TestAspect> aspect(new Qt3DRender::TestAspect(entitySubtree)); // WHEN Qt3DRender::Render::FilterLayerEntityJob filterJob; - filterJob.setHasLayerFilter(hasLayerFilter); - filterJob.setLayers(layerIds); + filterJob.setLayerFilters(layerFilterIds); filterJob.setManager(aspect->nodeManagers()); QBENCHMARK { diff --git a/tests/manual/bigscene-instanced-qml/instanced.vert b/tests/manual/bigscene-instanced-qml/instanced.vert index f713957e3..141cf9927 100644 --- a/tests/manual/bigscene-instanced-qml/instanced.vert +++ b/tests/manual/bigscene-instanced-qml/instanced.vert @@ -1,6 +1,6 @@ #version 150 core -#define M_PI 3.14159 +#define M_PI 3.14159265358979323846 in vec3 vertexPosition; in vec3 vertexNormal; diff --git a/tests/manual/blitframebuffer-qml/blitframebuffer-qml.pro b/tests/manual/blitframebuffer-qml/blitframebuffer-qml.pro new file mode 100644 index 000000000..c115cbeaf --- /dev/null +++ b/tests/manual/blitframebuffer-qml/blitframebuffer-qml.pro @@ -0,0 +1,14 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dquick 3dlogic qml quick 3dquickextras + +SOURCES += \ + main.cpp + +OTHER_FILES += \ + main.qml + +RESOURCES += \ + blitframebuffer-qml.qrc diff --git a/tests/manual/blitframebuffer-qml/blitframebuffer-qml.qrc b/tests/manual/blitframebuffer-qml/blitframebuffer-qml.qrc new file mode 100644 index 000000000..5f6483ac3 --- /dev/null +++ b/tests/manual/blitframebuffer-qml/blitframebuffer-qml.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/blitframebuffer-qml/main.cpp b/tests/manual/blitframebuffer-qml/main.cpp new file mode 100644 index 000000000..3d85df6eb --- /dev/null +++ b/tests/manual/blitframebuffer-qml/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <Qt3DQuickExtras/qt3dquickwindow.h> +#include <QGuiApplication> + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Quick::Qt3DQuickWindow view; + + + QSurfaceFormat format; + format.setVersion(4, 3); + format.setProfile(QSurfaceFormat::CoreProfile); + format.setDepthBufferSize(24); + format.setSamples(1); + format.setStencilBufferSize(8); + view.setFormat(format); + + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/blitframebuffer-qml/main.qml b/tests/manual/blitframebuffer-qml/main.qml new file mode 100644 index 000000000..4b3c1915b --- /dev/null +++ b/tests/manual/blitframebuffer-qml/main.qml @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 as QQ2 +import Qt3D.Core 2.0 +import Qt3D.Render 2.10 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.0 + +Entity { + id: sceneRoot + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + aspectRatio: 16/9 + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, -40.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + RenderTarget { + id: intermediateRenderTarget + attachments : [ + RenderTargetOutput { + objectName : "color" + attachmentPoint : RenderTargetOutput.Color0 + texture : Texture2D { + id : colorAttachment0 + width : 1024 + height : 768 + format : Texture.R32F + generateMipMaps : false + magnificationFilter : Texture.Linear + minificationFilter : Texture.Linear + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + } + }, + RenderTargetOutput { + objectName : "color" + attachmentPoint : RenderTargetOutput.Color1 + texture : Texture2D { + id : colorAttachment1 + width : 1024 + height : 1024 + format : Texture.R32F + generateMipMaps : false + magnificationFilter : Texture.Linear + minificationFilter : Texture.Linear + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + } + } + ] + } + + components: [ + RenderSettings { + activeFrameGraph: RenderSurfaceSelector { + Viewport { + RenderTargetSelector { + target: intermediateRenderTarget + NoDraw {} + } + + RenderTargetSelector { + target: RenderTarget { + id: renderTarget + attachments : [ + RenderTargetOutput { + objectName : "color" + attachmentPoint : RenderTargetOutput.Color0 + texture : Texture2D { + id : colorAttachment + width : 1024 + height : 768 + format : Texture.RGBA32F + generateMipMaps : false + magnificationFilter : Texture.Linear + minificationFilter : Texture.Linear + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + } + }, + RenderTargetOutput { + objectName : "depth" + attachmentPoint : RenderTargetOutput.Depth + texture : Texture2D { + id : depthAttachment + width : 1024 + height : 1024 + format : Texture.D32F + generateMipMaps : false + magnificationFilter : Texture.Linear + minificationFilter : Texture.Linear + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + } + } + ] + } + ClearBuffers { + clearColor: "white" + buffers: ClearBuffers.ColorDepthBuffer + CameraSelector { + camera: camera + } + } + } + + NoDraw{ + + BlitFramebuffer { + source: renderTarget + destination: intermediateRenderTarget + sourceRect: Qt.rect(0,0,1024,768) + destinationRect: Qt.rect(0,0,1024,1024) + sourceAttachmentPoint: RenderTargetOutput.Color0 + destinationAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Linear + } + + BlitFramebuffer { + source: intermediateRenderTarget + sourceRect: Qt.rect(0,0,1024,1024) + destinationRect: Qt.rect(0,0,512,384) + sourceAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Linear + } + + BlitFramebuffer { + source: renderTarget + sourceRect: Qt.rect(0,0,1024,768) + destinationRect: Qt.rect(0,384,512,384) + sourceAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Linear + } + + BlitFramebuffer { + source: renderTarget + sourceRect: Qt.rect(128,200,256,256) + destinationRect: Qt.rect(512,384,512,384) + sourceAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Linear + } + + BlitFramebuffer { + source: renderTarget + sourceRect: Qt.rect(128,200,256,256) + destinationRect: Qt.rect(512,0,512,384) + sourceAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Nearest + } + } + } + } + } + ] + + PhongMaterial { + id: material + } + + TorusMesh { + id: torusMesh + radius: 5 + minorRadius: 1 + rings: 100 + slices: 20 + } + + Transform { + id: torusTransform + scale3D: Qt.vector3d(1.5, 1, 0.5) + rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45) + } + + Entity { + id: torusEntity + components: [ torusMesh, material, torusTransform ] + } + + SphereMesh { + id: sphereMesh + radius: 3 + } + + Transform { + id: sphereTransform + property real userAngle: 0.0 + matrix: { + var m = Qt.matrix4x4(); + m.rotate(userAngle, Qt.vector3d(0, 1, 0)); + m.translate(Qt.vector3d(20, 0, 0)); + return m; + } + } + + QQ2.NumberAnimation { + target: sphereTransform + property: "userAngle" + duration: 10000 + from: 0 + to: 360 + + loops: QQ2.Animation.Infinite + running: true + } + + Entity { + id: sphereEntity + components: [ sphereMesh, material, sphereTransform ] + } +} diff --git a/tests/manual/buffercapture-qml/bufferSetter.comp b/tests/manual/buffercapture-qml/bufferSetter.comp index d7c383669..d7c383669 100755..100644 --- a/tests/manual/buffercapture-qml/bufferSetter.comp +++ b/tests/manual/buffercapture-qml/bufferSetter.comp diff --git a/tests/manual/custom-mesh-update-data-cpp/main.cpp b/tests/manual/custom-mesh-update-data-cpp/main.cpp index c7f5742dc..80ee2088d 100644 --- a/tests/manual/custom-mesh-update-data-cpp/main.cpp +++ b/tests/manual/custom-mesh-update-data-cpp/main.cpp @@ -277,7 +277,7 @@ int main(int argc, char* argv[]) void TimerObject::timeout() { - angle += float(M_PI / 360.0); + angle += qDegreesToRadians(0.5f); QByteArray updateData; updateData.resize(3*sizeof(float)); diff --git a/tests/manual/downloading/downloading.pro b/tests/manual/downloading/downloading.pro new file mode 100644 index 000000000..6f1b6e3d5 --- /dev/null +++ b/tests/manual/downloading/downloading.pro @@ -0,0 +1,14 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dquick qml quick 3dquickextras + +SOURCES += \ + main.cpp + +OTHER_FILES += \ + main.qml + +RESOURCES += \ + downloading.qrc diff --git a/tests/manual/downloading/downloading.qrc b/tests/manual/downloading/downloading.qrc new file mode 100644 index 000000000..5f6483ac3 --- /dev/null +++ b/tests/manual/downloading/downloading.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/downloading/main.cpp b/tests/manual/downloading/main.cpp new file mode 100644 index 000000000..dba6e0bff --- /dev/null +++ b/tests/manual/downloading/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <Qt3DQuickExtras/qt3dquickwindow.h> +#include <QGuiApplication> + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Quick::Qt3DQuickWindow view; + + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/downloading/main.qml b/tests/manual/downloading/main.qml new file mode 100644 index 000000000..47d1c09fb --- /dev/null +++ b/tests/manual/downloading/main.qml @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.0 + +Entity { + id: sceneRoot + + Camera { + id: camera + position: Qt.vector3d( 0.0, 0.5, 15.0 ) + viewCenter: Qt.vector3d( 0.0, 0.5, 0.0 ) + } + + OrbitCameraController { camera: camera } + + RenderSettings { + id : external_forward_renderer + activeFrameGraph : ForwardRenderer { + camera: camera + clearColor: "white" + } + } + + // Event Source will be set by the Qt3DQuickWindow + InputSettings { id: inputSettings } + + DirectionalLight { id: light; worldDirection: camera.viewVector } + + components: [external_forward_renderer, inputSettings, light] + + Mesh { + id: mesh + source: "https://codereview.qt-project.org/gitweb?p=qt/qt3d.git;a=blob_plain;hb=refs/heads/dev;f=examples/qt3d/exampleresources/assets/chest/Chest.obj" + } + + Transform { + id: transform + scale: 0.03 + rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 30) + } + + DiffuseMapMaterial { + id: material + diffuse: TextureLoader { source: "https://codereview.qt-project.org/gitweb?p=qt/qt3d.git;a=blob_plain;hb=refs/heads/dev;f=examples/qt3d/planets-qml/images/solarsystemscope/earthmap2k.jpg" } + specular: Qt.rgba( 0.2, 0.2, 0.2, 1.0 ) + shininess: 2.0 + } + + Entity { + id: mainEntity + objectName: "mainEntity" + components: [ mesh, material, transform ] + } +} diff --git a/tests/manual/layerfilter-qml/layerfilter-qml.pro b/tests/manual/layerfilter-qml/layerfilter-qml.pro new file mode 100644 index 000000000..edeb4c6e2 --- /dev/null +++ b/tests/manual/layerfilter-qml/layerfilter-qml.pro @@ -0,0 +1,14 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dquick qml quick 3dquickextras + +SOURCES += \ + main.cpp + +OTHER_FILES += \ + main.qml + +RESOURCES += \ + layerfilter-qml.qrc diff --git a/tests/manual/layerfilter-qml/layerfilter-qml.qrc b/tests/manual/layerfilter-qml/layerfilter-qml.qrc new file mode 100644 index 000000000..5f6483ac3 --- /dev/null +++ b/tests/manual/layerfilter-qml/layerfilter-qml.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/layerfilter-qml/main.cpp b/tests/manual/layerfilter-qml/main.cpp new file mode 100644 index 000000000..dba6e0bff --- /dev/null +++ b/tests/manual/layerfilter-qml/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <Qt3DQuickExtras/qt3dquickwindow.h> +#include <QGuiApplication> + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Quick::Qt3DQuickWindow view; + + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/layerfilter-qml/main.qml b/tests/manual/layerfilter-qml/main.qml new file mode 100644 index 000000000..8a5977faa --- /dev/null +++ b/tests/manual/layerfilter-qml/main.qml @@ -0,0 +1,221 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.0 + +Entity { + id: sceneRoot + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + aspectRatio: 16/9 + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, 3.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + Camera { + id: backgroundCamera + projectionType: CameraLens.OrthographicProjection + left: -0.25 + bottom: -0.25 + top: 0.25 + right: 0.25 + nearPlane: 0.1 + farPlane: 1.5 + position: Qt.vector3d( 0.0, 0.0, 1.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + Layer { + id: backgroundLayer + recursive: true + } + + Layer { + id: sceneLayer + recursive: true + } + + Layer { + id: secondBackgroundLayer + } + + RenderSettings { + id : external_forward_renderer + activeFrameGraph : + + RenderSurfaceSelector { + Viewport { + normalizedRect: Qt.rect(0,0,1,1) + + ClearBuffers { + buffers: ClearBuffers.ColorDepthStencilBuffer + clearColor: "white" + + LayerFilter { + layers: [ + backgroundLayer, + secondBackgroundLayer + ] + + CameraSelector { + camera: backgroundCamera + } + } + } + + ClearBuffers { + buffers: ClearBuffers.DepthStencilBuffer + + LayerFilter { + layers: [ + backgroundLayer, + ] + discard: true + + CameraSelector { + camera: camera + } + } + } + } + } + } + + OrbitCameraController { + camera: camera + } + + InputSettings { + id: inputSettings + } + + components: [external_forward_renderer, inputSettings] + + PlaneMesh { + id: backgroundMesh + width: 0.5 + height: 0.5 + } + + Transform { + id: backgroundTransform + rotation: fromAxisAndAngle(Qt.vector3d(1,0,0), 90) + } + + Transform { + id: smallBackgroundTransform + translation: Qt.vector3d(0,0.5,0) + scale: 0.5 + } + + PhongMaterial { + id: backgroundMaterial + ambient: "black" + } + + PhongMaterial { + id: smallBackgroundMaterial + ambient: "red" + } + + PlaneMesh { + id: mesh + width: 1 + height: 1 + } + + Transform { + id: transform + translation: Qt.vector3d(0,0,-1) + rotation: fromAxisAndAngle(Qt.vector3d(1,0,0), 90) + } + + PhongMaterial { + id: material + ambient: "blue" + } + + Entity { + id: backgroundFilterEntity + components: [backgroundLayer] + + Entity { + id: backgroundEntity + objectName: "backgroundEntity" + components: [backgroundMesh, backgroundMaterial, backgroundTransform] + + Entity { + id: smallBackground + objectName: "smallBackground" + components: [backgroundMesh, smallBackgroundMaterial, smallBackgroundTransform] + } + } + } + + Entity { + components: [sceneLayer] + + Entity { + id: mainEntity + objectName: "mainEntity" + components: [ mesh, material, transform ] + } + } +} diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 7eedbe05e..2b13bd896 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -16,6 +16,7 @@ SUBDIRS += \ cylinder-qml \ deferred-renderer-cpp \ deferred-renderer-qml \ + downloading \ dragging \ dynamicscene-cpp \ enabled-qml \ @@ -28,11 +29,13 @@ SUBDIRS += \ multiplewindows-qml \ picking-qml \ plasma \ + pointlinesize \ scene3d-loader \ simple-shaders-qml \ skybox \ tessellation-modes \ transforms-qml \ + spritegrid \ transparency-qml \ transparency-qml-scene3d \ rendercapture-qml \ @@ -48,7 +51,12 @@ SUBDIRS += \ mesh-morphing \ anim-viewer \ animation-keyframe-programmatic \ - rendercapture-qml-fbo + layerfilter-qml \ + skinned-mesh \ + proximityfilter \ + rendercapture-qml-fbo \ + blitframebuffer-qml \ + skinned-mesh qtHaveModule(widgets): { SUBDIRS += \ diff --git a/tests/manual/pointlinesize/Scene.qml b/tests/manual/pointlinesize/Scene.qml new file mode 100644 index 000000000..94f3bf351 --- /dev/null +++ b/tests/manual/pointlinesize/Scene.qml @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt3D.Core 2.0 +import Qt3D.Render 2.10 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.0 +import QtQuick 2.0 as QQ2; + +Entity { + id: sceneRoot + + property real width : 1 + property alias smooth : lineWidth.smooth + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + aspectRatio: 16/9 + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, 2.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + FirstPersonCameraController { + camera: camera + linearSpeed: 1.0 + } + + components: [ + RenderSettings { + activeFrameGraph : RenderStateSet { + renderStates: [ + PointSize { + value: sceneRoot.width + sizeMode: PointSize.Fixed + }, + LineWidth { + id: lineWidth + value: sceneRoot.width / 3.0 + } + + ] + + ForwardRenderer { + camera: camera + clearColor: "black" + } + } + }, + InputSettings { + } + ] + + SphereGeometry { + id: sphere + rings: 4 + slices: 4 + radius: 1 + } + + Entity { + components: [ + GeometryRenderer { + // abuse PlaneGeometry to give us some lines + geometry: sphere + primitiveType: GeometryRenderer.LineStrip + }, + PhongMaterial { + ambient: "white" + } + ] + } + + Entity { + components: [ + GeometryRenderer { + // abuse PlaneGeometry to give us some points + geometry: sphere + primitiveType: GeometryRenderer.Points + }, + PhongMaterial { + ambient: "red" + } + ] + } + +} diff --git a/tests/manual/pointlinesize/main.cpp b/tests/manual/pointlinesize/main.cpp new file mode 100644 index 000000000..5ede02f15 --- /dev/null +++ b/tests/manual/pointlinesize/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQuickView> +#include <QOpenGLContext> + +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + QSurfaceFormat format; + format.setVersion(2, 0); + format.setProfile(QSurfaceFormat::CompatibilityProfile); + format.setDepthBufferSize(24); + + QQuickView view; + view.setFormat(format); + view.resize(1200, 600); + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/pointlinesize/main.qml b/tests/manual/pointlinesize/main.qml new file mode 100644 index 000000000..a0180391f --- /dev/null +++ b/tests/manual/pointlinesize/main.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Scene3D 2.0 + +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +Item { + id: root + + Scene3D { + anchors.fill: parent + focus: true + aspects: ["input", "logic", "render"] + cameraAspectRatioMode: Scene3D.AutomaticAspectRatio + + Scene { + id: scene + width : root.lineWidth + } + } + + property real wMin : 0.5 + property real wMax : 64.0 + property real lineWidth : wMin * Math.exp(Math.log(wMax / wMin) * slider.value) + + Text { + id: sliderLabel + anchors.top: parent.top + anchors.right: parent.right + anchors.margins: 20 + font.pixelSize: 20 + color: "white" + text: "width = " + lineWidth.toFixed(2) + } + + Slider { + id: slider + anchors.top: sliderLabel.bottom + anchors.right: parent.right + anchors.margins: 20 + width: 200 + value: 0.0 + } + + Text { + anchors.top: slider.bottom + anchors.right: parent.right + anchors.margins: 20 + color: scene.smooth ? "white" : "lightgray" + text: scene.smooth ? "Line Smoothing enabled" : "Line Smoothing disabled" + font.pixelSize: 20 + MouseArea { + anchors.fill: parent + onClicked: scene.smooth = !scene.smooth + } + } +} diff --git a/tests/manual/pointlinesize/pointlinesize.pro b/tests/manual/pointlinesize/pointlinesize.pro new file mode 100644 index 000000000..7ebde2e11 --- /dev/null +++ b/tests/manual/pointlinesize/pointlinesize.pro @@ -0,0 +1,15 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dquick qml quick 3dquickextras + +SOURCES += \ + main.cpp + +OTHER_FILES += \ + Scene.qml \ + main.qml + +RESOURCES += \ + pointlinesize.qrc diff --git a/tests/manual/pointlinesize/pointlinesize.qrc b/tests/manual/pointlinesize/pointlinesize.qrc new file mode 100644 index 000000000..72868031a --- /dev/null +++ b/tests/manual/pointlinesize/pointlinesize.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>Scene.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/proximityfilter/main.cpp b/tests/manual/proximityfilter/main.cpp new file mode 100644 index 000000000..41d2f08a5 --- /dev/null +++ b/tests/manual/proximityfilter/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <Qt3DQuickExtras/qt3dquickwindow.h> +#include <QGuiApplication> + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Quick::Qt3DQuickWindow view; + + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/proximityfilter/main.qml b/tests/manual/proximityfilter/main.qml new file mode 100644 index 000000000..05c2e4415 --- /dev/null +++ b/tests/manual/proximityfilter/main.qml @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.9 +import Qt3D.Core 2.10 +import Qt3D.Render 2.10 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.9 + +Entity { + id: sceneRoot + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + aspectRatio: 16/9 + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, 150.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + OrbitCameraController { camera: camera } + + components: [ + RenderSettings { + activeFrameGraph: RenderSurfaceSelector { + Viewport { + normalizedRect: Qt.rect(0, 0, 1, 1) + + ClearBuffers { + buffers: ClearBuffers.ColorDepthBuffer + clearColor: Qt.rgba(0.6, 0.6, 0.6, 1.0) + NoDraw {} + } + + FrustumCulling { + CameraSelector { + camera: camera + ProximityFilter { + entity: proximityTarget + distanceThreshold: 30 + } + } + } + } + } + }, + // Event Source will be set by the Qt3DQuickWindow + InputSettings { } + ] + + SphereMesh { + id: sphereMesh + } + + PhongMaterial { + id: phongMaterial + diffuse: "orange" + } + + NodeInstantiator { + id: instantiator + model: 64 + Entity { + readonly property real angle: Math.PI * 2.0 * model.index % 8 + readonly property real radius: 20 + readonly property real verticalStep: 10 + readonly property color meshColor: Qt.hsla(model.index / instantiator.count, 0.5, 0.5, 1.0); + + readonly property Transform transform: Transform { + translation: Qt.vector3d(radius * Math.cos(angle), + (-(instantiator.count / (8 * 2)) + model.index / 8) * verticalStep, + radius * Math.sin(angle)) + } + readonly property Material material: Material { + effect: phongMaterial.effect + parameters: Parameter { name: "kd"; value: meshColor } + } + readonly property SphereMesh mesh: sphereMesh + components: [ transform, mesh, material ] + } + } + + Entity { + id: proximityTarget + readonly property Transform transform: Transform + { + property real y: 0; + SequentialAnimation on y { + NumberAnimation { from: -50; to: 50; duration: 2000; easing.type: Easing.InOutQuart } + NumberAnimation { from: 50; to: -50; duration: 2000; easing.type: Easing.InOutQuart } + loops: Animation.Infinite + } + translation: Qt.vector3d(0.0, y, 0.0) + } + components: [ sphereMesh, phongMaterial, transform ] + } +} diff --git a/tests/manual/proximityfilter/proximityfilter.pro b/tests/manual/proximityfilter/proximityfilter.pro new file mode 100644 index 000000000..2e3f19157 --- /dev/null +++ b/tests/manual/proximityfilter/proximityfilter.pro @@ -0,0 +1,11 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dquick quick 3dquickextras + +SOURCES += \ + main.cpp + +RESOURCES += \ + proximityfilter.qrc diff --git a/tests/manual/proximityfilter/proximityfilter.qrc b/tests/manual/proximityfilter/proximityfilter.qrc new file mode 100644 index 000000000..5f6483ac3 --- /dev/null +++ b/tests/manual/proximityfilter/proximityfilter.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/rendercapture-qml/main.cpp b/tests/manual/rendercapture-qml/main.cpp index 5c581c88e..9f8a8ed24 100644 --- a/tests/manual/rendercapture-qml/main.cpp +++ b/tests/manual/rendercapture-qml/main.cpp @@ -65,6 +65,12 @@ int main(int argc, char* argv[]) RenderCaptureProvider *provider = new RenderCaptureProvider; qmlRegisterType<RenderCaptureProvider>("Extras", 1, 0, "RenderCaptureProvider"); + QSurfaceFormat format; + format.setVersion(3, 2); + format.setProfile(QSurfaceFormat::CoreProfile); + format.setDepthBufferSize(24); + view.setFormat(format); + view.engine()->rootContext()->setContextProperty("_renderCaptureProvider", provider); view.engine()->addImageProvider("rendercapture", provider); diff --git a/tests/manual/skinned-mesh/DefaultSceneEntity.qml b/tests/manual/skinned-mesh/DefaultSceneEntity.qml new file mode 100644 index 000000000..26760fa51 --- /dev/null +++ b/tests/manual/skinned-mesh/DefaultSceneEntity.qml @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt3D.Core 2.10 +import Qt3D.Render 2.10 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.10 + +Entity { + id: root + + components: [ + RenderSettings { + activeFrameGraph: ForwardRenderer { + camera: mainCamera + } + }, + // Event Source will be set by the Qt3DQuickWindow + InputSettings { } + ] + + Camera { + id: mainCamera + position: Qt.vector3d(0, 0.8, 2) + viewCenter: Qt.vector3d(0, 0.8, 0) + fieldOfView: 60 + } + + OrbitCameraController { + camera: mainCamera + linearSpeed: 10 + lookSpeed: 180 + } + + Entity { + components: [ + PointLight { + enabled: parent.enabled + color: "black" + intensity: 0 + }, + EnvironmentLight { + enabled: parent.enabled + + irradiance: TextureLoader { + source: "qrc:/assets/envmaps/cedar-bridge/cedar_bridge_irradiance.dds" + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + generateMipMaps: false + } + specular: TextureLoader { + source: "qrc:/assets/envmaps/cedar-bridge/cedar_bridge_specular.dds" + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + generateMipMaps: false + } + } + ] + + SkyboxEntity { + baseName: "qrc:/assets/envmaps/cedar-bridge/cedar_bridge_irradiance" + extension: ".dds" + } + } +} diff --git a/tests/manual/skinned-mesh/SkinnedEntity.qml b/tests/manual/skinned-mesh/SkinnedEntity.qml new file mode 100644 index 000000000..47f2bae7b --- /dev/null +++ b/tests/manual/skinned-mesh/SkinnedEntity.qml @@ -0,0 +1,40 @@ +import Qt3D.Core 2.10 +import Qt3D.Render 2.10 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.10 + +Entity { + id: root + + property Effect effect: skinnedPbrEffect + property url source: "" + property alias createJointsEnabled: skeleton.createJointsEnabled + property alias transform: transform + property color baseColor: "red" + property alias rootJoint: skeleton.rootJoint + + components: [ + Transform { + id: transform + rotationX: -90 + }, + Mesh { + source: root.source + }, + Armature { + skeleton: SkeletonLoader { + id: skeleton + source: root.source + onStatusChanged: console.log("skeleton loader status: " + status) + onJointCountChanged: console.log("skeleton has " + jointCount + " joints") + } + }, + Material { + effect: root.effect + + parameters: [ + Parameter { name: "baseColor"; value: root.baseColor } + ] + } + ] +} diff --git a/tests/manual/skinned-mesh/SkinnedPbrEffect.qml b/tests/manual/skinned-mesh/SkinnedPbrEffect.qml new file mode 100644 index 000000000..79e4f7757 --- /dev/null +++ b/tests/manual/skinned-mesh/SkinnedPbrEffect.qml @@ -0,0 +1,38 @@ +import Qt3D.Core 2.10 +import Qt3D.Render 2.10 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.10 + +Effect { + id: skinnedPbrEffect + parameters: [ + Parameter { name: "baseColor"; value: "red" }, + Parameter { name: "metalness"; value: 0.1 }, + Parameter { name: "roughness"; value: 0.2 } + ] + + techniques: [ + Technique { + filterKeys: FilterKey { name: "renderingStyle"; value: "forward" } + + graphicsApiFilter { + api: GraphicsApiFilter.OpenGL + majorVersion: 3 + minorVersion: 1 + profile: GraphicsApiFilter.CoreProfile + } + + renderPasses: RenderPass { + shaderProgram: ShaderProgram { + id: prog + vertexShaderCode: loadSource("qrc:/skinnedPbr.vert") + } + + ShaderProgramBuilder { + shaderProgram: prog + fragmentShaderGraph: "qrc:/shaders/graphs/metalroughuniform.frag.json" + } + } + } + ] +} diff --git a/tests/manual/skinned-mesh/main.cpp b/tests/manual/skinned-mesh/main.cpp new file mode 100644 index 000000000..dba6e0bff --- /dev/null +++ b/tests/manual/skinned-mesh/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <Qt3DQuickExtras/qt3dquickwindow.h> +#include <QGuiApplication> + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Quick::Qt3DQuickWindow view; + + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/skinned-mesh/main.qml b/tests/manual/skinned-mesh/main.qml new file mode 100644 index 000000000..6e8adbf50 --- /dev/null +++ b/tests/manual/skinned-mesh/main.qml @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt3D.Core 2.10 +import Qt3D.Render 2.10 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.10 +import QtQuick 2.9 + +DefaultSceneEntity { + id: scene + + SkinnedPbrEffect { + id: skinnedPbrEffect + } + + SkinnedEntity { + id: riggedFigure + effect: skinnedPbrEffect + source: "qrc:/assets/gltf/2.0/RiggedFigure/RiggedFigure.gltf" + } + + SkinnedEntity { + id: riggedSimple + effect: skinnedPbrEffect + source: "qrc:/assets/gltf/2.0/RiggedSimple/RiggedSimple.gltf" + baseColor: "blue" + transform.scale: 0.05 + transform.translation: Qt.vector3d(0.5, 0.25, 0.0) + createJointsEnabled: true + + onRootJointChanged: { + var animation = animationComp.createObject(rootJoint) + var targetJoint = rootJoint.childJoints[0] + animation.target = targetJoint + animation.running = true + } + + Component { + id: animationComp + SequentialAnimation { + id: sequentialAnimation + property variant target: null + property real dz: 30.0 + loops: Animation.Infinite + + NumberAnimation { + target: sequentialAnimation.target + property: "rotationZ" + from: -dz + to: dz + duration: 600 + easing.type: Easing.OutCubic + } + NumberAnimation { + target: sequentialAnimation.target + property: "rotationZ" + from: dz + to: -dz + duration: 600 + easing.type: Easing.OutCubic + } + } + } + } +} diff --git a/tests/manual/skinned-mesh/skinned-mesh.pro b/tests/manual/skinned-mesh/skinned-mesh.pro new file mode 100644 index 000000000..dc5fd3730 --- /dev/null +++ b/tests/manual/skinned-mesh/skinned-mesh.pro @@ -0,0 +1,23 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dquick qml quick 3dquickextras + +SOURCES += \ + main.cpp + +OTHER_FILES += \ + main.qml \ + DefaultSceneEntity.qml \ + SkinnedEntity.qml \ + SkinnedPbrEffect.qml + +RESOURCES += \ + skinned-mesh.qrc \ + ../../../examples/qt3d/exampleresources/cubemaps.qrc \ + ../../../examples/qt3d/exampleresources/envmaps.qrc \ + ../../../examples/qt3d/exampleresources/gltf.qrc + +DISTFILES += \ + skinnedPbr.vert diff --git a/tests/manual/skinned-mesh/skinned-mesh.qrc b/tests/manual/skinned-mesh/skinned-mesh.qrc new file mode 100644 index 000000000..e062e6be4 --- /dev/null +++ b/tests/manual/skinned-mesh/skinned-mesh.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>DefaultSceneEntity.qml</file> + <file>skinnedPbr.vert</file> + <file>SkinnedEntity.qml</file> + <file>SkinnedPbrEffect.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/skinned-mesh/skinnedPbr.vert b/tests/manual/skinned-mesh/skinnedPbr.vert new file mode 100644 index 000000000..94cb3417c --- /dev/null +++ b/tests/manual/skinned-mesh/skinnedPbr.vert @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#version 150 + +in vec3 vertexPosition; +in vec3 vertexNormal; +in vec4 vertexTangent; +in vec2 vertexTexCoord; +in ivec4 vertexJointIndices; +in vec4 vertexJointWeights; + +out vec3 worldPosition; +out vec3 worldNormal; +out vec4 worldTangent; +out vec2 texCoord; + +uniform mat4 modelMatrix; +uniform mat3 modelNormalMatrix; +uniform mat4 mvp; + +const int maxJoints = 100; +uniform mat4 skinningPalette[maxJoints]; + +void main() +{ + // Pass the texture coordinates through + texCoord = vertexTexCoord; + + // Perform the skinning + mat4 skinningMatrix = skinningPalette[vertexJointIndices[0]] * vertexJointWeights[0]; + skinningMatrix += skinningPalette[vertexJointIndices[1]] * vertexJointWeights[1]; + skinningMatrix += skinningPalette[vertexJointIndices[2]] * vertexJointWeights[2]; + skinningMatrix += skinningPalette[vertexJointIndices[3]] * vertexJointWeights[3]; + + vec4 skinnedPosition = skinningMatrix * vec4(vertexPosition, 1.0); + vec3 skinnedNormal = vec3(skinningMatrix * vec4(vertexNormal, 0.0)); + vec3 skinnedTangent = vec3(skinningMatrix * vec4(vertexTangent.xyz, 0.0)); + + // Transform position, normal, and tangent to world space + worldPosition = vec3(modelMatrix * skinnedPosition); + worldNormal = normalize(modelNormalMatrix * skinnedNormal); + worldTangent.xyz = normalize(vec3(modelMatrix * vec4(skinnedTangent, 0.0))); + worldTangent.w = vertexTangent.w; + + gl_Position = mvp * skinnedPosition; +} diff --git a/tests/manual/spritegrid/main.cpp b/tests/manual/spritegrid/main.cpp new file mode 100644 index 000000000..70a8ec467 --- /dev/null +++ b/tests/manual/spritegrid/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2014 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <Qt3DQuickExtras/qt3dquickwindow.h> +#include <QGuiApplication> + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Quick::Qt3DQuickWindow view; + + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/spritegrid/main.qml b/tests/manual/spritegrid/main.qml new file mode 100644 index 000000000..ca3d7fd92 --- /dev/null +++ b/tests/manual/spritegrid/main.qml @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2014 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.10 +import QtQuick 2.5 + +Entity { + id: sceneRoot + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + aspectRatio: 16/9 + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, 20.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + OrbitCameraController { camera: camera } + + RenderSettings { + id : external_forward_renderer + activeFrameGraph : ForwardRenderer { + camera: camera + clearColor: "lightgrey" + } + } + + // Event Source will be set by the Qt3DQuickWindow + InputSettings { id: inputSettings } + + components: [external_forward_renderer, inputSettings] + + PlaneMesh { + id: mesh + } + + SpriteGrid { + id: spriteGrid + rows: 2 + columns: 6 + texture: textureLoader + } + + SpriteSheet { + id:spriteSheet + texture: textureLoader + + SpriteItem { x: 0; y: 0; width: 250; height: 172 } + SpriteItem { x: 276; y: 0; width: 250; height: 172 } + SpriteItem { x: 550; y: 0; width: 250; height: 172 } + SpriteItem { x: 826; y: 0; width: 250; height: 172 } + SpriteItem { x: 1100; y: 0; width: 250; height: 172 } + SpriteItem { x: 1376; y: 0; width: 250; height: 172 } + SpriteItem { x: 0; y: 198; width: 250; height: 172 } + SpriteItem { x: 276; y: 198; width: 250; height: 172 } + SpriteItem { x: 550; y: 198; width: 250; height: 172 } + SpriteItem { x: 826; y: 198; width: 250; height: 172 } + SpriteItem { x: 1100; y: 198; width: 250; height: 172 } + SpriteItem { x: 1376; y: 198; width: 250; height: 172 } + } + + Transform { + id: transform1 + scale: 8 + rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45) + translation: Qt.vector3d(-6, 0, 0) + } + + TextureMaterial { + id: material1 + texture: TextureLoader { + id: textureLoader + source: "spritegrid.png" + mirrored: false + } + textureTransform: spriteGrid.textureTransform + } + + Entity { + components: [ mesh, material1, transform1 ] + } + + + Transform { + id: transform2 + scale: 8 + rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45) + translation: Qt.vector3d(6, 0, 0) + } + + TextureMaterial { + id: material2 + texture: material1.texture + textureTransform: spriteSheet.textureTransform + } + + Entity { + components: [ mesh, material2, transform2 ] + } + + + Transform { + id: transform3 + scale3D: Qt.vector3d(12, 4, 4) + rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 90) + translation: Qt.vector3d(0, -6, 0) + } + + TextureMaterial { + id: material3 + texture: material1.texture + } + + Entity { + components: [ mesh, material3, transform3 ] + } + + + Timer { + interval: 1000 + repeat: true + running: true + onTriggered: { + spriteGrid.currentIndex = (spriteGrid.currentIndex + 1) % (spriteGrid.rows * spriteGrid.columns) + spriteSheet.currentIndex = (spriteSheet.currentIndex + 1) % (spriteSheet.sprites.length) + } + } +} diff --git a/tests/manual/spritegrid/spritegrid.png b/tests/manual/spritegrid/spritegrid.png Binary files differnew file mode 100644 index 000000000..47c7f5577 --- /dev/null +++ b/tests/manual/spritegrid/spritegrid.png diff --git a/tests/manual/spritegrid/spritegrid.pro b/tests/manual/spritegrid/spritegrid.pro new file mode 100644 index 000000000..8e4a1f2a7 --- /dev/null +++ b/tests/manual/spritegrid/spritegrid.pro @@ -0,0 +1,14 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dquick qml quick 3dquickextras + +SOURCES += \ + main.cpp + +OTHER_FILES += \ + main.qml + +RESOURCES += \ + spritegrid.qrc diff --git a/tests/manual/spritegrid/spritegrid.qrc b/tests/manual/spritegrid/spritegrid.qrc new file mode 100644 index 000000000..5e648adf2 --- /dev/null +++ b/tests/manual/spritegrid/spritegrid.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>spritegrid.png</file> + </qresource> +</RCC> diff --git a/tests/tests.pro b/tests/tests.pro index 2ab283fc2..157bdcea5 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -1,8 +1,11 @@ TEMPLATE = subdirs -!package: SUBDIRS += \ - auto \ - manual +QT_FOR_CONFIG += 3dcore + +!package { + SUBDIRS += auto + qtConfig(qt3d-extras): SUBDIRS += manual +} # Benchmarks make sense in release mode only. # Disable them for code coverage. |