summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/animation/doc/src/qt3danimation-module.qdoc3
-rw-r--r--src/animation/frontend/qanimationcliploader.cpp20
-rw-r--r--src/animation/frontend/qclipblendvalue.cpp5
-rw-r--r--src/animation/frontend/qclock.cpp5
-rw-r--r--src/core/changes/qcomponentaddedchange.cpp12
-rw-r--r--src/core/changes/qcomponentaddedchange.h2
-rw-r--r--src/core/changes/qcomponentremovedchange.cpp13
-rw-r--r--src/core/changes/qcomponentremovedchange.h2
-rw-r--r--src/core/configure.json4
-rw-r--r--src/core/nodes/qcomponent.cpp4
-rw-r--r--src/core/nodes/qnode.cpp47
-rw-r--r--src/core/resources/qresourcemanager_p.h25
-rw-r--r--src/core/transforms/matrix4x4_p.h12
-rw-r--r--src/core/transforms/vector3d_p.h12
-rw-r--r--src/core/transforms/vector4d_p.h12
-rw-r--r--src/extras/defaults/qabstractcameracontroller.h1
-rw-r--r--src/extras/doc/src/qt3dextras-module.qdoc2
-rw-r--r--src/input/frontend/qphysicaldevicecreatedchange.cpp2
-rw-r--r--src/plugins/sceneparsers/assimp/assimpimporter.cpp19
-rw-r--r--src/plugins/sceneparsers/assimp/assimpimporter.h1
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer.cpp8
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer_p.h1
-rw-r--r--src/quick3d/quick3dscene2d/items/scene2d.cpp8
-rw-r--r--src/render/aligned_malloc_p.h81
-rw-r--r--src/render/backend/abstractrenderer_p.h10
-rw-r--r--src/render/backend/buffervisitor_p.h12
-rw-r--r--src/render/backend/cameralens.cpp22
-rw-r--r--src/render/backend/cameralens_p.h12
-rw-r--r--src/render/backend/entity.cpp4
-rw-r--r--src/render/backend/entity_p.h4
-rw-r--r--src/render/backend/handle_types_p.h5
-rw-r--r--src/render/backend/managers_p.h3
-rw-r--r--src/render/backend/nodemanagers.cpp2
-rw-r--r--src/render/backend/pointsvisitor.cpp4
-rw-r--r--src/render/backend/pointsvisitor_p.h3
-rw-r--r--src/render/backend/render-backend.pri6
-rw-r--r--src/render/backend/renderbarrierjob.cpp111
-rw-r--r--src/render/backend/renderbarrierjob_p.h91
-rw-r--r--src/render/backend/renderer.cpp590
-rw-r--r--src/render/backend/renderer_p.h52
-rw-r--r--src/render/backend/renderqueue.cpp1
-rw-r--r--src/render/backend/renderview.cpp91
-rw-r--r--src/render/backend/renderview_p.h42
-rw-r--r--src/render/backend/renderviewbuilder.cpp25
-rw-r--r--src/render/backend/segmentsvisitor.cpp12
-rw-r--r--src/render/backend/segmentsvisitor_p.h5
-rw-r--r--src/render/backend/shaderparameterpack.cpp6
-rw-r--r--src/render/backend/shaderparameterpack_p.h10
-rw-r--r--src/render/backend/transform.cpp6
-rw-r--r--src/render/backend/transform_p.h6
-rw-r--r--src/render/backend/triangleboundingvolume.cpp54
-rw-r--r--src/render/backend/triangleboundingvolume_p.h37
-rw-r--r--src/render/backend/trianglesextractor.cpp2
-rw-r--r--src/render/backend/trianglesextractor_p.h6
-rw-r--r--src/render/backend/trianglesvisitor.cpp44
-rw-r--r--src/render/backend/trianglesvisitor_p.h10
-rw-r--r--src/render/backend/uniform.cpp34
-rw-r--r--src/render/backend/uniform_p.h37
-rw-r--r--src/render/frontend/qrenderaspect.cpp68
-rw-r--r--src/render/frontend/qrenderaspect_p.h4
-rw-r--r--src/render/frontend/sphere.cpp48
-rw-r--r--src/render/frontend/sphere_p.h38
-rw-r--r--src/render/geometry/geometryrenderer.cpp2
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp32
-rw-r--r--src/render/graphicshelpers/graphicscontext_p.h2
-rw-r--r--src/render/jobs/abstractpickingjob.cpp49
-rw-r--r--src/render/jobs/abstractpickingjob_p.h12
-rw-r--r--src/render/jobs/calcboundingvolumejob.cpp55
-rw-r--r--src/render/jobs/frustumcullingjob.cpp12
-rw-r--r--src/render/jobs/frustumcullingjob_p.h11
-rw-r--r--src/render/jobs/job_common_p.h9
-rw-r--r--src/render/jobs/loadtexturedatajob.cpp30
-rw-r--r--src/render/jobs/loadtexturedatajob_p.h6
-rw-r--r--src/render/jobs/pickboundingvolumejob.cpp84
-rw-r--r--src/render/jobs/pickboundingvolumejob_p.h15
-rw-r--r--src/render/jobs/pickboundingvolumeutils.cpp159
-rw-r--r--src/render/jobs/pickboundingvolumeutils_p.h13
-rw-r--r--src/render/jobs/raycastingjob.cpp19
-rw-r--r--src/render/jobs/renderviewjobutils_p.h5
-rw-r--r--src/render/jobs/updatelevelofdetailjob.cpp18
-rw-r--r--src/render/jobs/updatelevelofdetailjob_p.h1
-rw-r--r--src/render/jobs/updateworldtransformjob.cpp6
-rw-r--r--src/render/materialsystem/qparameter.cpp27
-rw-r--r--src/render/materialsystem/shadercache.cpp18
-rw-r--r--src/render/materialsystem/shadercache_p.h2
-rw-r--r--src/render/materialsystem/shaderdata.cpp10
-rw-r--r--src/render/materialsystem/shaderdata_p.h10
-rw-r--r--src/render/picking/pickeventfilter.cpp10
-rw-r--r--src/render/picking/pickeventfilter_p.h4
-rw-r--r--src/render/raycasting/boundingsphere_p.h3
-rw-r--r--src/render/raycasting/qabstractcollisionqueryservice.cpp4
-rw-r--r--src/render/raycasting/qabstractcollisionqueryservice_p.h4
-rw-r--r--src/render/raycasting/qboundingvolume_p.h5
-rw-r--r--src/render/raycasting/qcollisionqueryresult.cpp4
-rw-r--r--src/render/raycasting/qcollisionqueryresult_p.h12
-rw-r--r--src/render/raycasting/qray3d.cpp43
-rw-r--r--src/render/raycasting/qray3d_p.h34
-rw-r--r--src/render/raycasting/qraycastingservice.cpp4
-rw-r--r--src/render/render.pro13
-rw-r--r--src/render/services/vsyncframeadvanceservice.cpp2
-rw-r--r--tests/auto/core/common/common.pri10
-rw-r--r--tests/auto/core/matrix4x4_avx2/matrix4x4_avx2.pro2
-rw-r--r--tests/auto/core/matrix4x4_avx2/tst_matrix4x4_avx2.cpp3
-rw-r--r--tests/auto/core/nodes/tst_nodes.cpp34
-rw-r--r--tests/auto/core/vector3d_sse/tst_vector3d_sse.cpp13
-rw-r--r--tests/auto/core/vector4d_sse/tst_vector4d_sse.cpp92
-rw-r--r--tests/auto/render/boundingsphere/tst_boundingsphere.cpp93
-rw-r--r--tests/auto/render/commons/testrenderer.h10
-rw-r--r--tests/auto/render/coordinatereader/tst_coordinatereader.cpp38
-rw-r--r--tests/auto/render/filtercompatibletechniquejob/tst_filtercompatibletechniquejob.cpp3
-rw-r--r--tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp3
-rw-r--r--tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc2
-rw-r--r--tests/auto/render/pickboundingvolumejob/testscene_cameraposition.qml115
-rw-r--r--tests/auto/render/pickboundingvolumejob/testscene_viewports.qml158
-rw-r--r--tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp259
-rw-r--r--tests/auto/render/qcamera/tst_qcamera.cpp6
-rw-r--r--tests/auto/render/qray3d/tst_qray3d.cpp312
-rw-r--r--tests/auto/render/raycasting/tst_raycasting.cpp74
-rw-r--r--tests/auto/render/render.pro17
-rw-r--r--tests/auto/render/renderbarrierjob/renderbarrierjob.pro9
-rw-r--r--tests/auto/render/renderbarrierjob/tst_renderbarrierjob.cpp118
-rw-r--r--tests/auto/render/renderer/tst_renderer.cpp158
-rw-r--r--tests/auto/render/renderqueue/renderqueue.pro2
-rw-r--r--tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp25
-rw-r--r--tests/auto/render/renderviews/tst_renderviews.cpp17
-rw-r--r--tests/auto/render/renderviewutils/tst_renderviewutils.cpp36
-rw-r--r--tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp56
-rw-r--r--tests/auto/render/shadercache/tst_shadercache.cpp13
-rw-r--r--tests/auto/render/transform/tst_transform.cpp6
-rw-r--r--tests/auto/render/triangleboundingvolume/triangleboundingvolume.pro1
-rw-r--r--tests/auto/render/triangleboundingvolume/tst_triangleboundingvolume.cpp140
-rw-r--r--tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp8
-rw-r--r--tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp78
-rw-r--r--tests/auto/render/uniform/tst_uniform.cpp10
-rw-r--r--tests/auto/render/updateshaderdatatransformjob/tst_updateshaderdatatransformjob.cpp6
135 files changed, 3023 insertions, 1471 deletions
diff --git a/src/animation/doc/src/qt3danimation-module.qdoc b/src/animation/doc/src/qt3danimation-module.qdoc
index a056447e8..3aaf819db 100644
--- a/src/animation/doc/src/qt3danimation-module.qdoc
+++ b/src/animation/doc/src/qt3danimation-module.qdoc
@@ -29,8 +29,9 @@
/*!
\module Qt3DAnimation
\title Qt 3D Animation C++ Classes
+
\keyword Qt 3D Animation
- \brief The Qt 3D Animation modules provides a set of prebuilt elements to help
+ \brief The Qt 3D Animation module provides a set of prebuilt elements to help
you get started with Qt 3D.
This module is still in tech preview. This means it is unstable, likely to
diff --git a/src/animation/frontend/qanimationcliploader.cpp b/src/animation/frontend/qanimationcliploader.cpp
index 8c59a4e10..f71ca40f7 100644
--- a/src/animation/frontend/qanimationcliploader.cpp
+++ b/src/animation/frontend/qanimationcliploader.cpp
@@ -61,7 +61,7 @@ void QAnimationClipLoaderPrivate::setStatus(QAnimationClipLoader::Status status)
}
/*!
- \enum QAnimationClipLoader::Status
+ \enum Qt3DAnimation::QAnimationClipLoader::Status
This enum identifies the status of animation clip.
@@ -70,7 +70,17 @@ void QAnimationClipLoaderPrivate::setStatus(QAnimationClipLoader::Status status)
\value Error An error occurred while loading the clip
*/
/*!
- \class QAnimationClipLoader
+ \property Qt3DAnimation::QAnimationClipLoader::status
+
+ This property contains the status of the animation clip.
+*/
+/*!
+ \property Qt3DAnimation::QAnimationClipLoader::source
+
+ Holds the source URL from which to load the animation clip.
+*/
+/*!
+ \class Qt3DAnimation::QAnimationClipLoader
\inherits QAbstractAnimationClip
\inmodule Qt3DAnimation
\brief Enables loading key frame animation data from a file
@@ -103,6 +113,9 @@ QUrl QAnimationClipLoader::source() const
return d->m_source;
}
+/*!
+ Returns the status of the animation clip.
+*/
QAnimationClipLoader::Status QAnimationClipLoader::status() const
{
Q_D(const QAnimationClipLoader);
@@ -119,6 +132,9 @@ void QAnimationClipLoader::setSource(const QUrl &source)
emit sourceChanged(source);
}
+/*!
+ \internal
+*/
void QAnimationClipLoader::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
{
Q_D(QAnimationClipLoader);
diff --git a/src/animation/frontend/qclipblendvalue.cpp b/src/animation/frontend/qclipblendvalue.cpp
index a17c63a69..c20609050 100644
--- a/src/animation/frontend/qclipblendvalue.cpp
+++ b/src/animation/frontend/qclipblendvalue.cpp
@@ -58,6 +58,11 @@ QClipBlendValuePrivate::QClipBlendValuePrivate()
\inmodule Qt3DAnimation
\brief Class used for including a clip in a blend tree.
*/
+/*!
+ \property Qt3DAnimation::QClipBlendValue::clip
+
+ The animation clip that needs to be included in the blend tree.
+*/
QClipBlendValue::QClipBlendValue(Qt3DCore::QNode *parent)
: QAbstractClipBlendNode(*new QClipBlendValuePrivate(), parent)
{
diff --git a/src/animation/frontend/qclock.cpp b/src/animation/frontend/qclock.cpp
index 6dd851b88..717982902 100644
--- a/src/animation/frontend/qclock.cpp
+++ b/src/animation/frontend/qclock.cpp
@@ -61,6 +61,11 @@ QClock::QClock(QClockPrivate &dd, Qt3DCore::QNode *parent)
QClock::~QClock()
{
}
+/*!
+ \property Qt3DAnimation::QClock::playbackRate
+
+ The playback speed of the animation.
+*/
double QClock::playbackRate() const
{
diff --git a/src/core/changes/qcomponentaddedchange.cpp b/src/core/changes/qcomponentaddedchange.cpp
index e00c4ffab..41f7a2340 100644
--- a/src/core/changes/qcomponentaddedchange.cpp
+++ b/src/core/changes/qcomponentaddedchange.cpp
@@ -75,7 +75,7 @@ QComponentAddedChangePrivate::QComponentAddedChangePrivate(const QEntity *entity
*/
/*!
- * Constructs a new QComponentAddedChange with with \a entity and \a component.
+ * Constructs a new QComponentAddedChange which will notify \a entity that \a component was added
*/
QComponentAddedChange::QComponentAddedChange(const QEntity *entity,
const QComponent *component)
@@ -84,6 +84,16 @@ QComponentAddedChange::QComponentAddedChange(const QEntity *entity,
{
}
+/*!
+ * Constructs a new QComponentAddedChange which will notify \a component that it was added to \a entity
+ */
+QComponentAddedChange::QComponentAddedChange(const QComponent *component,
+ const QEntity *entity)
+ : QSceneChange(*new QComponentAddedChangePrivate(entity, component),
+ ComponentAdded, component->id())
+{
+}
+
QComponentAddedChange::~QComponentAddedChange()
{
}
diff --git a/src/core/changes/qcomponentaddedchange.h b/src/core/changes/qcomponentaddedchange.h
index a62cac116..e7676a026 100644
--- a/src/core/changes/qcomponentaddedchange.h
+++ b/src/core/changes/qcomponentaddedchange.h
@@ -55,6 +55,8 @@ class QT3DCORESHARED_EXPORT QComponentAddedChange : public QSceneChange
public:
explicit QComponentAddedChange(const QEntity *entity,
const QComponent *component);
+ explicit QComponentAddedChange(const QComponent *component,
+ const QEntity *entity);
~QComponentAddedChange();
QNodeId entityId() const Q_DECL_NOTHROW;
diff --git a/src/core/changes/qcomponentremovedchange.cpp b/src/core/changes/qcomponentremovedchange.cpp
index 5e5dfa5aa..e2129169a 100644
--- a/src/core/changes/qcomponentremovedchange.cpp
+++ b/src/core/changes/qcomponentremovedchange.cpp
@@ -75,7 +75,7 @@ QComponentRemovedChangePrivate::QComponentRemovedChangePrivate(const QEntity *en
*/
/*!
- * Constructs a new QComponentRemovedChange with \a entity and \a component.
+ * Constructs a new QComponentRemovedChange which will notify \a entity that \a component was removed.
*/
QComponentRemovedChange::QComponentRemovedChange(const QEntity *entity,
const QComponent *component)
@@ -84,6 +84,17 @@ QComponentRemovedChange::QComponentRemovedChange(const QEntity *entity,
{
}
+/*!
+ * Constructs a new QComponentRemovedChange which will notify \a component that it was removed from \a entity
+ */
+QComponentRemovedChange::QComponentRemovedChange(const QComponent *component,
+ const QEntity *entity)
+ : QSceneChange(*new QComponentRemovedChangePrivate(entity, component),
+ ComponentRemoved, component->id())
+{
+
+}
+
QComponentRemovedChange::~QComponentRemovedChange()
{
}
diff --git a/src/core/changes/qcomponentremovedchange.h b/src/core/changes/qcomponentremovedchange.h
index 3c57fe26f..66743b1ae 100644
--- a/src/core/changes/qcomponentremovedchange.h
+++ b/src/core/changes/qcomponentremovedchange.h
@@ -55,6 +55,8 @@ class QT3DCORESHARED_EXPORT QComponentRemovedChange : public QSceneChange
public:
explicit QComponentRemovedChange(const QEntity *entity,
const QComponent *component);
+ explicit QComponentRemovedChange(const QComponent *component,
+ const QEntity *entity);
~QComponentRemovedChange();
QNodeId entityId() const Q_DECL_NOTHROW;
diff --git a/src/core/configure.json b/src/core/configure.json
index 871f6bfa4..fc938444a 100644
--- a/src/core/configure.json
+++ b/src/core/configure.json
@@ -86,7 +86,7 @@
"purpose": "Use SSE2 SIMD instructions to accelerate matrix operations",
"autoDetect": "features.sse2",
"enable": "input.qt3d-simd == 'sse2' || input.qt3d-simd == 'avx2'",
- "disable": "input.qt3d-simd == 'no' || (config.win32 && arch.i386)",
+ "disable": "input.qt3d-simd == 'no' || arch.i386",
"output": [ "privateFeature" ]
},
"qt3d-simd-avx2": {
@@ -94,7 +94,7 @@
"purpose": "Use AVX2 SIMD instructions to accelerate matrix operations",
"autoDetect": false,
"enable": "input.qt3d-simd == 'avx2'",
- "disable": "input.qt3d-simd == 'sse2' || input.qt3d-simd == 'no' || (config.win32 && arch.i386)",
+ "disable": "input.qt3d-simd == 'sse2' || input.qt3d-simd == 'no' || arch.i386",
"output": [ "privateFeature" ]
}
},
diff --git a/src/core/nodes/qcomponent.cpp b/src/core/nodes/qcomponent.cpp
index 8e337adf6..f4e59e058 100644
--- a/src/core/nodes/qcomponent.cpp
+++ b/src/core/nodes/qcomponent.cpp
@@ -73,7 +73,7 @@ void QComponentPrivate::addEntity(QEntity *entity)
m_scene->addEntityForComponent(m_id, entity->id());
}
- const auto componentAddedChange = QComponentAddedChangePtr::create(entity, q);
+ const auto componentAddedChange = QComponentAddedChangePtr::create(q, entity);
notifyObservers(componentAddedChange);
Q_EMIT q->addedToEntity(entity);
}
@@ -86,7 +86,7 @@ void QComponentPrivate::removeEntity(QEntity *entity)
m_entities.removeAll(entity);
- const auto componentRemovedChange = QComponentRemovedChangePtr::create(entity, q);
+ const auto componentRemovedChange = QComponentRemovedChangePtr::create(q, entity);
notifyObservers(componentRemovedChange);
Q_EMIT q->removedFromEntity(entity);
}
diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp
index e5a3aca71..083fda7df 100644
--- a/src/core/nodes/qnode.cpp
+++ b/src/core/nodes/qnode.cpp
@@ -388,28 +388,43 @@ void QNodePrivate::propertyChanged(int propertyIndex)
if (m_blockNotifications)
return;
+ const auto toBackendValue = [this](const QVariant &data) -> QVariant
+ {
+ if (data.canConvert<QNode*>()) {
+ QNode *node = data.value<QNode*>();
+
+ // Ensure the node has issued a node creation change. We can end
+ // up here if a newly created node with a parent is immediately set
+ // as a property on another node. In this case the deferred call to
+ // _q_postConstructorInit() will not have happened yet as the event
+ // loop will still be blocked. So force it here and we catch this
+ // eventuality in the _q_postConstructorInit() function so that we
+ // do not repeat the creation and new child scene change events.
+ if (node)
+ QNodePrivate::get(node)->_q_postConstructorInit();
+
+ const QNodeId id = node ? node->id() : QNodeId();
+ return QVariant::fromValue(id);
+ }
+
+ return data;
+ };
+
Q_Q(QNode);
const QMetaProperty property = q->metaObject()->property(propertyIndex);
const QVariant data = property.read(q);
- if (data.canConvert<QNode*>()) {
- QNode *node = data.value<QNode*>();
-
- // Ensure the node has issued a node creation change. We can end
- // up here if a newly created node with a parent is immediately set
- // as a property on another node. In this case the deferred call to
- // _q_postConstructorInit() will not have happened yet as the event
- // loop will still be blocked. So force it here and we catch this
- // eventuality in the _q_postConstructorInit() function so that we
- // do not repeat the creation and new child scene change events.
- if (node)
- QNodePrivate::get(node)->_q_postConstructorInit();
-
- const QNodeId id = node ? node->id() : QNodeId();
- notifyPropertyChange(property.name(), QVariant::fromValue(id));
+
+ if (data.type() == QVariant::List) {
+ QSequentialIterable iterable = data.value<QSequentialIterable>();
+ QVariantList variants;
+ variants.reserve(iterable.size());
+ for (const auto &v : iterable)
+ variants.append(toBackendValue(v));
+ notifyPropertyChange(property.name(), variants);
} else {
- notifyPropertyChange(property.name(), data);
+ notifyPropertyChange(property.name(), toBackendValue(data));
}
}
diff --git a/src/core/resources/qresourcemanager_p.h b/src/core/resources/qresourcemanager_p.h
index 038f3d551..e620b40d1 100644
--- a/src/core/resources/qresourcemanager_p.h
+++ b/src/core/resources/qresourcemanager_p.h
@@ -60,6 +60,8 @@
#include <limits>
#include <Qt3DCore/private/qhandle_p.h>
+#include <QtCore/private/qsimd_p.h>
+#include <Qt3DCore/private/qt3dcore-config_p.h>
// Silence complaints about unreferenced local variables in
// ArrayAllocatingPolicy::deallocateBuckets() when the compiler
@@ -313,7 +315,17 @@ private:
void allocateBucket()
{
// no free handle, allocate a new
- Bucket *b = new Bucket;
+ Bucket *b = nullptr;
+ // allocate aligned memory
+#if QT_CONFIG(qt3d_simd_avx2) && defined(__AVX2__) && defined(QT_COMPILER_SUPPORTS_AVX2)
+ b = static_cast<Bucket*>(_mm_malloc(sizeof(Bucket), 32));
+#elif QT_CONFIG(qt3d_simd_sse2) && defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSE2)
+ b = static_cast<Bucket*>(_mm_malloc(sizeof(Bucket), 16));
+#else
+ b = static_cast<Bucket*>(malloc(sizeof(Bucket)));
+#endif
+ // placement new
+ new (b) Bucket;
b->header.next = firstBucket;
firstBucket = b;
@@ -329,7 +341,16 @@ private:
Bucket *b = firstBucket;
while (b) {
Bucket *n = b->header.next;
- delete b;
+ // Call dtor explicitly
+ b->~Bucket();
+ // Release aligned memory
+#if QT_CONFIG(qt3d_simd_avx2) && defined(__AVX2__) && defined(QT_COMPILER_SUPPORTS_AVX2)
+ _mm_free(b);
+#elif QT_CONFIG(qt3d_simd_sse2) && defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSE2)
+ _mm_free(b);
+#else
+ free(b);
+#endif
b = n;
}
}
diff --git a/src/core/transforms/matrix4x4_p.h b/src/core/transforms/matrix4x4_p.h
index 18f5db4c3..d100d3d3b 100644
--- a/src/core/transforms/matrix4x4_p.h
+++ b/src/core/transforms/matrix4x4_p.h
@@ -83,4 +83,16 @@ QT_END_NAMESPACE
#endif
+template<typename UsingType>
+Q_ALWAYS_INLINE QMatrix4x4 convertToQMatrix4x4(const UsingType &v)
+{
+ return v.toQMatrix4x4();
+}
+
+template<>
+Q_ALWAYS_INLINE QMatrix4x4 convertToQMatrix4x4<QMatrix4x4>(const QMatrix4x4 &v)
+{
+ return v;
+}
+
#endif // QT3DCORE_MATRIX4X4_P_H
diff --git a/src/core/transforms/vector3d_p.h b/src/core/transforms/vector3d_p.h
index 6467d7686..80e936903 100644
--- a/src/core/transforms/vector3d_p.h
+++ b/src/core/transforms/vector3d_p.h
@@ -74,4 +74,16 @@ QT_END_NAMESPACE
#endif
+template<typename UsingType>
+Q_ALWAYS_INLINE QVector3D convertToQVector3D(const UsingType &v)
+{
+ return v.toQVector3D();
+}
+
+template<>
+Q_ALWAYS_INLINE QVector3D convertToQVector3D<QVector3D>(const QVector3D &v)
+{
+ return v;
+}
+
#endif // QT3DCORE_VECTOR3D_P_H
diff --git a/src/core/transforms/vector4d_p.h b/src/core/transforms/vector4d_p.h
index a03dc234f..dbfaffffd 100644
--- a/src/core/transforms/vector4d_p.h
+++ b/src/core/transforms/vector4d_p.h
@@ -74,4 +74,16 @@ QT_END_NAMESPACE
#endif
+template<typename UsingType>
+Q_ALWAYS_INLINE QVector4D convertToQVector4D(const UsingType &v)
+{
+ return v.toQVector4D();
+}
+
+template<>
+Q_ALWAYS_INLINE QVector4D convertToQVector4D<QVector4D>(const QVector4D &v)
+{
+ return v;
+}
+
#endif // QT3DCORE_VECTOR4D_P_H
diff --git a/src/extras/defaults/qabstractcameracontroller.h b/src/extras/defaults/qabstractcameracontroller.h
index f13079f5f..e5d14745a 100644
--- a/src/extras/defaults/qabstractcameracontroller.h
+++ b/src/extras/defaults/qabstractcameracontroller.h
@@ -96,6 +96,7 @@ protected:
Qt3DInput::QKeyboardDevice *keyboardDevice() const;
Qt3DInput::QMouseDevice *mouseDevice() const;
+public:
struct InputState
{
float rxAxisValue;
diff --git a/src/extras/doc/src/qt3dextras-module.qdoc b/src/extras/doc/src/qt3dextras-module.qdoc
index 5461a5b09..a90d29a51 100644
--- a/src/extras/doc/src/qt3dextras-module.qdoc
+++ b/src/extras/doc/src/qt3dextras-module.qdoc
@@ -42,7 +42,7 @@
\title Qt 3D Extras C++ Classes
\keyword Qt 3D Extras
- \brief The Qt 3D Extras modules provides a set of prebuilt elements to help
+ \brief The Qt 3D Extras module provides a set of prebuilt elements to help
you get started with Qt 3D.
This module is still in tech preview. This means it is unstable, likely to
diff --git a/src/input/frontend/qphysicaldevicecreatedchange.cpp b/src/input/frontend/qphysicaldevicecreatedchange.cpp
index 0abeea520..807fdc014 100644
--- a/src/input/frontend/qphysicaldevicecreatedchange.cpp
+++ b/src/input/frontend/qphysicaldevicecreatedchange.cpp
@@ -71,7 +71,7 @@ QPhysicalDeviceCreatedChangeBase::~QPhysicalDeviceCreatedChangeBase()
/*!
Returns a list of node ids.
*/
-Qt3DCore::QNodeIdVector QPhysicalDeviceCreatedChangeBase::axisSettingIds() const
+Qt3DCore::QNodeIdVector Qt3DInput::QPhysicalDeviceCreatedChangeBase::axisSettingIds() const
{
Q_D(const QPhysicalDeviceCreatedChangeBase);
return d->m_axisSettingIds;
diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
index 219a75ce4..ad53916fd 100644
--- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp
+++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
@@ -227,13 +227,13 @@ QAttribute *createAttribute(QBuffer *buffer,
return attribute;
}
-QAttribute *createAttribute(QBuffer *buffer,
- QAttribute::VertexBaseType vertexBaseType,
- uint vertexSize,
- uint count,
- uint byteOffset = 0,
- uint byteStride = 0,
- QNode *parent = nullptr)
+QAttribute *createIndexAttribute(QBuffer *buffer,
+ QAttribute::VertexBaseType vertexBaseType,
+ uint vertexSize,
+ uint count,
+ uint byteOffset = 0,
+ uint byteStride = 0,
+ QNode *parent = nullptr)
{
QAttribute *attribute = QAbstractNodeFactory::createNode<QAttribute>("QAttribute");
attribute->setBuffer(buffer);
@@ -603,7 +603,8 @@ void AssimpImporter::readSceneFile(const QString &path)
aiProcess_GenSmoothNormals|
aiProcess_FlipUVs);
if (m_scene->m_aiScene == nullptr) {
- qCWarning(AssimpImporterLog) << "Assimp scene import failed";
+ qCWarning(AssimpImporterLog) << "Assimp scene import failed" << m_scene->m_importer->GetErrorString();
+ QSceneImporter::logError(QString::fromUtf8(m_scene->m_importer->GetErrorString()));
return ;
}
parse();
@@ -828,7 +829,7 @@ QGeometryRenderer *AssimpImporter::loadMesh(uint meshIndex)
indexBuffer->setData(ibufferContent);
// Add indices attributes
- QAttribute *indexAttribute = createAttribute(indexBuffer, indiceType, 1, indices);
+ QAttribute *indexAttribute = createIndexAttribute(indexBuffer, indiceType, 1, indices);
indexAttribute->setAttributeType(QAttribute::IndexAttribute);
meshGeometry->addAttribute(indexAttribute);
diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.h b/src/plugins/sceneparsers/assimp/assimpimporter.h
index 5cbace362..9a020b3e3 100644
--- a/src/plugins/sceneparsers/assimp/assimpimporter.h
+++ b/src/plugins/sceneparsers/assimp/assimpimporter.h
@@ -143,7 +143,6 @@ private:
QHash<aiTextureType, QString> m_textureToParameterName;
QVector<Qt3DAnimation::QKeyframeAnimation *> m_animations;
QVector<Qt3DAnimation::QMorphingAnimation *> m_morphAnimations;
-// QMap<aiNode*, Light*> m_lights;
};
QDir m_sceneDir;
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp
index 1c9fec4d2..b2e541d35 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer.cpp
+++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp
@@ -135,7 +135,6 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
, m_multisample(false) // this value is not used, will be synced from the Scene3DItem instead
, m_lastMultisample(false)
, m_needsShutdown(true)
- , m_blocking(false)
{
Q_CHECK_PTR(m_item);
Q_CHECK_PTR(m_item->window());
@@ -155,9 +154,6 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
ContextSaver saver;
static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderInitialize(saver.context());
scheduleRootEntityChange();
-
- const bool blockingRendermode = !qgetenv("SCENE3D_BLOCKING_RENDERMODE").isEmpty();
- m_blocking = blockingRendermode;
}
Scene3DRenderer::~Scene3DRenderer()
@@ -207,6 +203,8 @@ void Scene3DRenderer::shutdown()
// would return early
m_item = nullptr;
+ static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->abortRenderJobs();
+
// Exit the simulation loop so no more jobs are asked for. Once this
// returns it is safe to shutdown the renderer.
if (m_aspectEngine) {
@@ -311,7 +309,7 @@ void Scene3DRenderer::render()
m_finalFBO->bind();
// Render Qt3D Scene
- static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderSynchronous(m_blocking);
+ static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->tryRenderSynchronous();
// We may have called doneCurrent() so restore the context if the rendering surface was changed
// Note: keep in mind that the ContextSave also restores the surface when destroyed
diff --git a/src/quick3d/imports/scene3d/scene3drenderer_p.h b/src/quick3d/imports/scene3d/scene3drenderer_p.h
index eb2b930ef..7a85bc774 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer_p.h
+++ b/src/quick3d/imports/scene3d/scene3drenderer_p.h
@@ -109,7 +109,6 @@ private:
bool m_multisample;
bool m_lastMultisample;
bool m_needsShutdown;
- bool m_blocking;
friend class Scene3DCleaner;
};
diff --git a/src/quick3d/quick3dscene2d/items/scene2d.cpp b/src/quick3d/quick3dscene2d/items/scene2d.cpp
index 1147abf68..7e3334f00 100644
--- a/src/quick3d/quick3dscene2d/items/scene2d.cpp
+++ b/src/quick3d/quick3dscene2d/items/scene2d.cpp
@@ -469,10 +469,10 @@ void Scene2D::handlePickEvent(int type, const Qt3DRender::QPickEventPtr &ev)
CoordinateReader reader(renderer()->nodeManagers());
if (reader.setGeometry(entity->renderComponent<GeometryRenderer>(),
QAttribute::defaultTextureCoordinateAttributeName())) {
- QVector4D c0 = reader.getCoordinate(pickTriangle->vertex1Index());
- QVector4D c1 = reader.getCoordinate(pickTriangle->vertex2Index());
- QVector4D c2 = reader.getCoordinate(pickTriangle->vertex3Index());
- QVector4D ci = c0 * pickTriangle->uvw().x()
+ Vector4D c0 = reader.getCoordinate(pickTriangle->vertex1Index());
+ Vector4D c1 = reader.getCoordinate(pickTriangle->vertex2Index());
+ Vector4D c2 = reader.getCoordinate(pickTriangle->vertex3Index());
+ Vector4D ci = c0 * pickTriangle->uvw().x()
+ c1 * pickTriangle->uvw().y() + c2 * pickTriangle->uvw().z();
ci.setW(1.0f);
diff --git a/src/render/aligned_malloc_p.h b/src/render/aligned_malloc_p.h
new file mode 100644
index 000000000..a2a619b03
--- /dev/null
+++ b/src/render/aligned_malloc_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DRENDER_RENDER_ALIGNED_MALLOC_P_H
+#define QT3DRENDER_RENDER_ALIGNED_MALLOC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qsimd_p.h>
+#include <Qt3DCore/private/qt3dcore-config_p.h>
+
+#if QT_CONFIG(qt3d_simd_avx2) && defined(__AVX2__) && defined(QT_COMPILER_SUPPORTS_AVX2)
+# define QT3D_ALIGNED_MALLOC(s) _mm_malloc(s, 32)
+#elif QT_CONFIG(qt3d_simd_sse2) && defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSE2)
+# define QT3D_ALIGNED_MALLOC(s) _mm_malloc(s, 16)
+#else
+ #define QT3D_ALIGNED_MALLOC(s) malloc(s)
+#endif
+
+#if (QT_CONFIG(qt3d_simd_avx2) && defined(__AVX2__) && defined(QT_COMPILER_SUPPORTS_AVX2)) || (QT_CONFIG(qt3d_simd_sse2) && defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSE2))
+# define QT3D_ALIGNED_FREE(ptr) _mm_free(ptr)
+#else
+# define QT3D_ALIGNED_FREE(ptr) free(ptr)
+#endif
+
+#define QT3D_ALIGNED_MALLOC_AND_FREE() \
+ static void *operator new(size_t s) \
+ { \
+ return QT3D_ALIGNED_MALLOC(s); \
+ } \
+ static void operator delete(void *ptr) \
+ { \
+ QT3D_ALIGNED_FREE(ptr); \
+ }
+
+#endif // QT3DRENDER_RENDER_ALIGNED_MALLOC_P_H
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h
index 54f37ea21..bf05bdec8 100644
--- a/src/render/backend/abstractrenderer_p.h
+++ b/src/render/backend/abstractrenderer_p.h
@@ -134,7 +134,7 @@ public:
// Threaded renderer
virtual void render() = 0;
// Synchronous renderer
- virtual void doRender(bool scene3dBlocking = false) = 0;
+ virtual void doRender() = 0;
virtual void cleanGraphicsResources() = 0;
@@ -151,7 +151,7 @@ public:
virtual QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() = 0;
virtual Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() = 0;
virtual Qt3DCore::QAspectJobPtr rayCastingJob() = 0;
- virtual Qt3DCore::QAspectJobPtr syncTextureLoadingJob() = 0;
+ virtual Qt3DCore::QAspectJobPtr syncSkeletonLoadingJob() = 0;
virtual Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() = 0;
virtual void setSceneRoot(Qt3DCore::QBackendNodeFactory *factory, Entity *root) = 0;
@@ -170,6 +170,12 @@ public:
virtual void setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) = 0;
virtual QSurfaceFormat format() = 0;
virtual QOpenGLContext *shareContext() const = 0;
+
+ virtual void lockSurfaceAndRender() = 0;
+ virtual bool releaseRendererAndRequestPromiseToRender() = 0;
+ virtual bool waitForRenderJobs() = 0;
+ virtual bool tryWaitForRenderJobs(int timeout) = 0;
+ virtual void abortRenderJobs() = 0;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractRenderer::BackendNodeDirtySet)
diff --git a/src/render/backend/buffervisitor_p.h b/src/render/backend/buffervisitor_p.h
index 4870171b1..98749b62c 100644
--- a/src/render/backend/buffervisitor_p.h
+++ b/src/render/backend/buffervisitor_p.h
@@ -195,7 +195,7 @@ protected:
const uint byteStride,
const uint count)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 2;
for (uint ndx = 0; ndx < count; ++ndx) {
visit(ndx, coordinates[0], coordinates[1]);
coordinates += stride;
@@ -211,7 +211,7 @@ protected:
bool primitiveRestartEnabled,
int primitiveRestartIndex)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 2;
for (uint i = 0; i < count; ++i) {
if (!primitiveRestartEnabled || indices[i] != primitiveRestartIndex) {
const uint n = stride * indices[i];
@@ -225,7 +225,7 @@ protected:
const uint byteStride,
const uint count)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 3;
for (uint ndx = 0; ndx < count; ++ndx) {
visit(ndx, coordinates[0], coordinates[1], coordinates[2]);
coordinates += stride;
@@ -240,7 +240,7 @@ protected:
bool primitiveRestartEnabled,
int primitiveRestartIndex)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 3;
for (uint i = 0; i < count; ++i) {
if (!primitiveRestartEnabled || indices[i] != primitiveRestartIndex) {
const uint n = stride * indices[i];
@@ -254,7 +254,7 @@ protected:
const uint byteStride,
const uint count)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 4;
for (uint ndx = 0; ndx < count; ++ndx) {
visit(ndx, coordinates[0], coordinates[1], coordinates[2], coordinates[3]);
coordinates += stride;
@@ -269,7 +269,7 @@ protected:
bool primitiveRestartEnabled,
int primitiveRestartIndex)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 4;
for (uint i = 0; i < count; ++i) {
if (!primitiveRestartEnabled || indices[i] != primitiveRestartIndex) {
const uint n = stride * indices[i];
diff --git a/src/render/backend/cameralens.cpp b/src/render/backend/cameralens.cpp
index e127b5885..b540b24c8 100644
--- a/src/render/backend/cameralens.cpp
+++ b/src/render/backend/cameralens.cpp
@@ -105,23 +105,25 @@ void CameraLens::setRenderAspect(QRenderAspect *renderAspect)
m_renderAspect = renderAspect;
}
-QMatrix4x4 CameraLens::viewMatrix(const QMatrix4x4 &worldTransform)
+Matrix4x4 CameraLens::viewMatrix(const Matrix4x4 &worldTransform)
{
- const QVector4D position = worldTransform * QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
+ const Vector4D position = worldTransform * Vector4D(0.0f, 0.0f, 0.0f, 1.0f);
// OpenGL convention is looking down -Z
- const QVector4D viewDirection = worldTransform * QVector4D(0.0f, 0.0f, -1.0f, 0.0f);
- const QVector4D upVector = worldTransform * QVector4D(0.0f, 1.0f, 0.0f, 0.0f);
+ const Vector4D viewDirection = worldTransform * Vector4D(0.0f, 0.0f, -1.0f, 0.0f);
+ const Vector4D upVector = worldTransform * Vector4D(0.0f, 1.0f, 0.0f, 0.0f);
QMatrix4x4 m;
- m.lookAt(position.toVector3D(), (position + viewDirection).toVector3D(), upVector.toVector3D());
- return m;
+ m.lookAt(convertToQVector3D(Vector3D(position)),
+ convertToQVector3D(Vector3D(position + viewDirection)),
+ convertToQVector3D(Vector3D(upVector)));
+ return Matrix4x4(m);
}
void CameraLens::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
{
const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QCameraLensData>>(change);
const auto &data = typedChange->data;
- m_projection = data.projectionMatrix;
+ m_projection = Matrix4x4(data.projectionMatrix);
m_exposure = data.exposure;
}
@@ -160,7 +162,7 @@ void CameraLens::notifySceneBoundingVolume(const Sphere &sphere, QNodeCommand::C
}
}
-void CameraLens::setProjection(const QMatrix4x4 &projection)
+void CameraLens::setProjection(const Matrix4x4 &projection)
{
m_projection = projection;
}
@@ -178,7 +180,7 @@ void CameraLens::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
if (propertyChange->propertyName() == QByteArrayLiteral("projectionMatrix")) {
QMatrix4x4 projectionMatrix = propertyChange->value().value<QMatrix4x4>();
- m_projection = projectionMatrix;
+ m_projection = Matrix4x4(projectionMatrix);
} else if (propertyChange->propertyName() == QByteArrayLiteral("exposure")) {
setExposure(propertyChange->value().toFloat());
}
@@ -212,7 +214,7 @@ void CameraLens::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
}
bool CameraLens::viewMatrixForCamera(EntityManager* manager, Qt3DCore::QNodeId cameraId,
- QMatrix4x4 &viewMatrix, QMatrix4x4 &projectionMatrix)
+ Matrix4x4 &viewMatrix, Matrix4x4 &projectionMatrix)
{
Entity *camNode = manager->lookupResource(cameraId);
if (!camNode)
diff --git a/src/render/backend/cameralens_p.h b/src/render/backend/cameralens_p.h
index 9e237cfda..d00358fb8 100644
--- a/src/render/backend/cameralens_p.h
+++ b/src/render/backend/cameralens_p.h
@@ -53,7 +53,7 @@
#include <Qt3DRender/private/backendnode_p.h>
#include <Qt3DCore/private/qnodecommand_p.h>
-#include <QMatrix4x4>
+#include <Qt3DCore/private/matrix4x4_p.h>
#include <QRectF>
QT_BEGIN_NAMESPACE
@@ -89,10 +89,10 @@ public:
void setRenderAspect(QRenderAspect* renderAspect);
- QMatrix4x4 viewMatrix(const QMatrix4x4 &worldTransform);
+ Matrix4x4 viewMatrix(const Matrix4x4 &worldTransform);
- void setProjection(const QMatrix4x4 &projection);
- inline QMatrix4x4 projection() const { return m_projection; }
+ void setProjection(const Matrix4x4 &projection);
+ inline Matrix4x4 projection() const { return m_projection; }
void setExposure(float exposure);
inline float exposure() const { return m_exposure; }
@@ -101,7 +101,7 @@ public:
void notifySceneBoundingVolume(const Sphere &sphere, Qt3DCore::QNodeCommand::CommandId commandId);
static bool viewMatrixForCamera(EntityManager *manager, Qt3DCore::QNodeId cameraId,
- QMatrix4x4 &viewMatrix, QMatrix4x4 &projectionMatrix);
+ Matrix4x4 &viewMatrix, Matrix4x4 &projectionMatrix);
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
@@ -110,8 +110,8 @@ private:
Qt3DCore::QNodeCommand::CommandId commandId);
QRenderAspect *m_renderAspect;
- QMatrix4x4 m_projection;
Qt3DCore::QNodeCommand::CommandId m_pendingViewAllCommand;
+ Matrix4x4 m_projection;
float m_exposure;
};
diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp
index 1a0e877d6..85334d1d3 100644
--- a/src/render/backend/entity.cpp
+++ b/src/render/backend/entity.cpp
@@ -291,12 +291,12 @@ QVector<Entity *> Entity::children() const
return childrenVector;
}
-QMatrix4x4 *Entity::worldTransform()
+Matrix4x4 *Entity::worldTransform()
{
return m_nodeManagers->worldMatrixManager()->data(m_worldTransform);
}
-const QMatrix4x4 *Entity::worldTransform() const
+const Matrix4x4 *Entity::worldTransform() const
{
return m_nodeManagers->worldMatrixManager()->data(m_worldTransform);
}
diff --git a/src/render/backend/entity_p.h b/src/render/backend/entity_p.h
index 5448b5297..075871d85 100644
--- a/src/render/backend/entity_p.h
+++ b/src/render/backend/entity_p.h
@@ -104,8 +104,8 @@ public:
QVector<Entity *> children() const;
bool hasChildren() const { return !m_childrenHandles.empty(); }
- QMatrix4x4 *worldTransform();
- const QMatrix4x4 *worldTransform() const;
+ Matrix4x4 *worldTransform();
+ const Matrix4x4 *worldTransform() const;
Sphere *localBoundingVolume() const { return m_localBoundingVolume.data(); }
Sphere *worldBoundingVolume() const { return m_worldBoundingVolume.data(); }
Sphere *worldBoundingVolumeWithChildren() const { return m_worldBoundingVolumeWithChildren.data(); }
diff --git a/src/render/backend/handle_types_p.h b/src/render/backend/handle_types_p.h
index bec2e3a9a..035bbfc91 100644
--- a/src/render/backend/handle_types_p.h
+++ b/src/render/backend/handle_types_p.h
@@ -53,11 +53,10 @@
#include <Qt3DRender/qt3drender_global.h>
#include <Qt3DCore/private/qhandle_p.h>
+#include <Qt3DCore/private/matrix4x4_p.h>
QT_BEGIN_NAMESPACE
-class QMatrix4x4;
-
namespace Qt3DRender {
class QTextureImageData;
@@ -109,7 +108,7 @@ typedef Qt3DCore::QHandle<FrameGraphNode *> HFrameGraphNode;
typedef Qt3DCore::QHandle<Layer> HLayer;
typedef Qt3DCore::QHandle<LevelOfDetail> HLevelOfDetail;
typedef Qt3DCore::QHandle<Material> HMaterial;
-typedef Qt3DCore::QHandle<QMatrix4x4> HMatrix;
+typedef Qt3DCore::QHandle<Matrix4x4> HMatrix;
typedef Qt3DCore::QHandle<OpenGLVertexArrayObject> HVao;
typedef Qt3DCore::QHandle<Shader> HShader;
typedef Qt3DCore::QHandle<ShaderBuilder> HShaderBuilder;
diff --git a/src/render/backend/managers_p.h b/src/render/backend/managers_p.h
index b3e7b6f27..c9bcb799e 100644
--- a/src/render/backend/managers_p.h
+++ b/src/render/backend/managers_p.h
@@ -52,6 +52,7 @@
//
#include <Qt3DCore/private/qresourcemanager_p.h>
+#include <Qt3DCore/private/matrix4x4_p.h>
#include <Qt3DRender/private/rendertargetoutput_p.h>
#include <Qt3DRender/private/cameralens_p.h>
#include <Qt3DRender/private/filterkey_p.h>
@@ -189,7 +190,7 @@ public:
};
class MatrixManager : public Qt3DCore::QResourceManager<
- QMatrix4x4,
+ Matrix4x4,
Qt3DCore::QNodeId,
Qt3DCore::NonLockingPolicy>
{
diff --git a/src/render/backend/nodemanagers.cpp b/src/render/backend/nodemanagers.cpp
index 035d4d8d4..5db35082d 100644
--- a/src/render/backend/nodemanagers.cpp
+++ b/src/render/backend/nodemanagers.cpp
@@ -174,7 +174,7 @@ MaterialManager *NodeManagers::manager<Material>() const Q_DECL_NOTHROW
}
template<>
-MatrixManager *NodeManagers::manager<QMatrix4x4*>() const Q_DECL_NOTHROW
+MatrixManager *NodeManagers::manager<Matrix4x4>() const Q_DECL_NOTHROW
{
return m_worldMatrixManager;
}
diff --git a/src/render/backend/pointsvisitor.cpp b/src/render/backend/pointsvisitor.cpp
index 663488357..750182b19 100644
--- a/src/render/backend/pointsvisitor.cpp
+++ b/src/render/backend/pointsvisitor.cpp
@@ -72,7 +72,7 @@ void traverseCoordinatesIndexed(Index *indices,
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx;
- QVector3D abc;
+ Vector3D abc;
while (i < indexInfo.count) {
ndx = indices[i];
const uint idx = ndx * verticesStride;
@@ -94,7 +94,7 @@ void traverseCoordinates(Vertex *vertices,
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx = 0;
- QVector3D abc;
+ Vector3D abc;
while (ndx < vertexInfo.count) {
const uint idx = ndx * verticesStride;
for (uint j = 0; j < maxVerticesDataSize; ++j)
diff --git a/src/render/backend/pointsvisitor_p.h b/src/render/backend/pointsvisitor_p.h
index 9d44ffec5..1614f185b 100644
--- a/src/render/backend/pointsvisitor_p.h
+++ b/src/render/backend/pointsvisitor_p.h
@@ -52,6 +52,7 @@
//
#include <Qt3DCore/qnodeid.h>
+#include <Qt3DCore/private/vector3d_p.h>
QT_BEGIN_NAMESPACE
@@ -75,7 +76,7 @@ public:
void apply(const Qt3DCore::QEntity *entity);
void apply(const GeometryRenderer *renderer, const Qt3DCore::QNodeId id);
- virtual void visit(uint ndx, const QVector3D &c) = 0;
+ virtual void visit(uint ndx, const Vector3D &c) = 0;
protected:
NodeManagers *m_manager;
diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri
index f7f30b5c9..a3df90f8c 100644
--- a/src/render/backend/render-backend.pri
+++ b/src/render/backend/render-backend.pri
@@ -45,7 +45,8 @@ HEADERS += \
$$PWD/visitorutils_p.h \
$$PWD/segmentsvisitor_p.h \
$$PWD/pointsvisitor_p.h \
- $$PWD/renderercache_p.h
+ $$PWD/renderercache_p.h \
+ $$PWD/renderbarrierjob_p.h
SOURCES += \
$$PWD/renderthread.cpp \
@@ -82,7 +83,8 @@ SOURCES += \
$$PWD/resourceaccessor.cpp \
$$PWD/segmentsvisitor.cpp \
$$PWD/commandthread.cpp \
- $$PWD/pointsvisitor.cpp
+ $$PWD/pointsvisitor.cpp \
+ $$PWD/renderbarrierjob.cpp
include($$QT3D_BUILD_ROOT/src/core/qt3dcore-config.pri)
QT_FOR_CONFIG += 3dcore-private
diff --git a/src/render/backend/renderbarrierjob.cpp b/src/render/backend/renderbarrierjob.cpp
new file mode 100644
index 000000000..c60c9f368
--- /dev/null
+++ b/src/render/backend/renderbarrierjob.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderbarrierjob_p.h"
+
+#include <Qt3DRender/private/renderlogging_p.h>
+
+#include <QtCore/QThread>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+namespace Render {
+
+QDebug operator<<(QDebug debug, JobTypes::JobType type)
+{
+ switch (type) {
+ case JobTypes::ReadRenderQueueSizeBarrier:
+ debug << "ReadRenderQueueSize";
+ break;
+ case JobTypes::BeginDrawingBarrier:
+ debug << "BeginDrawing";
+ break;
+ case JobTypes::UpdateGLResourcesBarrier:
+ debug << "UpdateGLResources";
+ break;
+ case JobTypes::PrepareCommandSubmissionBarrier:
+ debug << "PrepareCommandSubmission";
+ break;
+ case JobTypes::EndDrawingBarrier:
+ debug << "EndDrawing";
+ break;
+ default:
+ break;
+ }
+ return debug;
+}
+
+RenderBarrierJob::RenderBarrierJob(JobTypes::JobType type)
+ : QAspectJob()
+ , m_type(type)
+ , m_begin(0)
+ , m_end(0)
+{
+ SET_JOB_RUN_STAT_TYPE(this, type, 0);
+}
+
+void RenderBarrierJob::waitForDependencies()
+{
+ qCDebug(Jobs) << Q_FUNC_INFO << m_type << "waiting for job on" << QThread::currentThread();
+ m_begin.acquire();
+ qCDebug(Jobs) << Q_FUNC_INFO << m_type << "done waiting for job on" << QThread::currentThread();
+ Q_ASSERT(m_begin.available() == 0);
+}
+
+void RenderBarrierJob::allowToProceed()
+{
+ qCDebug(Jobs) << Q_FUNC_INFO << m_type << "releasing job on" << QThread::currentThread();
+ m_end.release();
+}
+
+void RenderBarrierJob::run()
+{
+ qCDebug(Jobs) << Q_FUNC_INFO << m_type << "job releasing render thread on" << QThread::currentThread();
+ m_begin.release();
+ qCDebug(Jobs) << Q_FUNC_INFO << m_type << "job waiting for render thread on" << QThread::currentThread();
+ m_end.acquire();
+ qCDebug(Jobs) << Q_FUNC_INFO << m_type << "job done on" << QThread::currentThread();
+ Q_ASSERT(m_end.available() == 0);
+}
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
diff --git a/src/render/backend/renderbarrierjob_p.h b/src/render/backend/renderbarrierjob_p.h
new file mode 100644
index 000000000..a39b2aa83
--- /dev/null
+++ b/src/render/backend/renderbarrierjob_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and 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 Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** 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-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DRENDER_RENDER_RENDERBARRIERJOB_P_H
+#define QT3DRENDER_RENDER_RENDERBARRIERJOB_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DCore/QAspectJob>
+
+#include <Qt3DRender/private/qt3drender_global_p.h>
+#include <Qt3DRender/private/job_common_p.h>
+
+#include <QtCore/qsemaphore.h>
+
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+namespace Render {
+
+class QT3DRENDERSHARED_PRIVATE_EXPORT RenderBarrierJob : public Qt3DCore::QAspectJob
+{
+public:
+ RenderBarrierJob(JobTypes::JobType type);
+ // Called from render thread
+ void waitForDependencies();
+ // Called from render thread
+ void allowToProceed();
+
+ void run() final;
+private:
+ JobTypes::JobType m_type;
+ QSemaphore m_begin;
+ QSemaphore m_end;
+};
+
+using RenderBarrierJobPtr = QSharedPointer<RenderBarrierJob>;
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+#endif // QT3DRENDER_RENDER_RENDERBARRIERJOB_P_H
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index bb0585e6f..d89813f57 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -89,11 +89,14 @@
#include <Qt3DRender/private/buffercapture_p.h>
#include <Qt3DRender/private/offscreensurfacehelper_p.h>
#include <Qt3DRender/private/renderviewbuilder_p.h>
+#include <Qt3DRender/private/loadtexturedatajob_p.h>
+#include <Qt3DRender/private/renderbarrierjob_p.h>
#include <Qt3DRender/qcameralens.h>
#include <Qt3DCore/private/qeventfilterservice_p.h>
#include <Qt3DCore/private/qabstractaspectjobmanager_p.h>
#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
+#include <private/rendersurfaceselector_p.h>
#if QT_CONFIG(qt3d_profile_jobs)
#include <Qt3DCore/private/aspectcommanddebugger_p.h>
@@ -185,10 +188,16 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_bufferGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering))
, m_vaoGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering))
, m_textureGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering))
+ , m_loadTextureJob(Render::LoadTextureDataJobPtr::create())
, m_shaderGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyShaders(); }, JobTypes::DirtyShaderGathering))
- , m_syncTextureLoadingJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncTextureLoading))
+ , m_syncSkeletonLoadingJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncSkeletonLoading))
, m_ownedContext(false)
, m_offscreenHelper(nullptr)
+ , m_readRenderQueueSizeBarrierJob(RenderBarrierJobPtr::create(JobTypes::ReadRenderQueueSizeBarrier))
+ , m_beginDrawingBarrierJob(RenderBarrierJobPtr::create(JobTypes::BeginDrawingBarrier))
+ , m_updateGLResourcesBarrierJob(RenderBarrierJobPtr::create(JobTypes::UpdateGLResourcesBarrier))
+ , m_prepareCommandSubmissionBarrierJob(RenderBarrierJobPtr::create(JobTypes::PrepareCommandSubmissionBarrier))
+ , m_endDrawingBarrierJob(RenderBarrierJobPtr::create(JobTypes::EndDrawingBarrier))
#if QT_CONFIG(qt3d_profile_jobs)
, m_commandExecuter(new Qt3DRender::Debug::CommandExecuter(this))
#endif
@@ -199,27 +208,49 @@ Renderer::Renderer(QRenderAspect::RenderType type)
if (m_renderThread)
m_renderThread->waitForStart();
+ // Render thread barrier interdependencies
+ m_beginDrawingBarrierJob->addDependency(m_readRenderQueueSizeBarrierJob);
+ m_updateGLResourcesBarrierJob->addDependency(m_beginDrawingBarrierJob);
+ m_prepareCommandSubmissionBarrierJob->addDependency(m_updateGLResourcesBarrierJob);
+ m_endDrawingBarrierJob->addDependency(m_prepareCommandSubmissionBarrierJob);
+
// Create jobs to update transforms and bounding volumes
// We can only update bounding volumes once all world transforms are known
- m_calculateBoundingVolumeJob->addDependency(m_updateTreeEnabledJob);
m_updateWorldBoundingVolumeJob->addDependency(m_worldTransformJob);
m_updateWorldBoundingVolumeJob->addDependency(m_calculateBoundingVolumeJob);
m_expandBoundingVolumeJob->addDependency(m_updateWorldBoundingVolumeJob);
m_updateShaderDataTransformJob->addDependency(m_worldTransformJob);
m_pickBoundingVolumeJob->addDependency(m_expandBoundingVolumeJob);
-
- // Dirty texture gathering depends on m_syncTextureLoadingJob
- // m_syncTextureLoadingJob will depend on the texture loading jobs
- m_textureGathererJob->addDependency(m_syncTextureLoadingJob);
+ // m_calculateBoundingVolumeJob's dependency on m_updateTreeEnabledJob is set in renderBinJobs
// Ensures all skeletons are loaded before we try to update them
- m_updateSkinningPaletteJob->addDependency(m_syncTextureLoadingJob);
+ m_updateSkinningPaletteJob->addDependency(m_syncSkeletonLoadingJob);
// All world stuff depends on the RenderEntity's localBoundingVolume
m_updateLevelOfDetailJob->addDependency(m_updateMeshTriangleListJob);
m_pickBoundingVolumeJob->addDependency(m_updateMeshTriangleListJob);
m_rayCastingJob->addDependency(m_updateMeshTriangleListJob);
+ // Independent job dependencies
+ m_beginDrawingBarrierJob->addDependency(m_vaoGathererJob);
+
+ // Make sure we do not try to filter techniques before we have proper context
+ m_filterCompatibleTechniqueJob->addDependency(m_beginDrawingBarrierJob);
+
+ // Make sure we have gathered dirty shaders, textures and buffers before calling updateGLResources
+ m_updateGLResourcesBarrierJob->addDependency(m_bufferGathererJob);
+ m_updateGLResourcesBarrierJob->addDependency(m_shaderGathererJob);
+ m_updateGLResourcesBarrierJob->addDependency(m_textureGathererJob);
+
+ // Make sure we load textures after gathering
+ m_loadTextureJob->addDependency(m_updateGLResourcesBarrierJob);
+ m_loadTextureJob->addDependency(m_textureGathererJob);
+
+ // Make sure we prepare command submission after textures are loaded
+ m_prepareCommandSubmissionBarrierJob->addDependency(m_loadTextureJob);
+
+ // Make sure we have found compatible techniques before gathering shaders
+ m_updateGLResourcesBarrierJob->addDependency(m_filterCompatibleTechniqueJob);
m_shaderGathererJob->addDependency(m_filterCompatibleTechniqueJob);
m_filterCompatibleTechniqueJob->setRenderer(this);
@@ -288,6 +319,7 @@ void Renderer::setNodeManagers(NodeManagers *managers)
m_updateSkinningPaletteJob->setManagers(m_nodesManager);
m_updateMeshTriangleListJob->setManagers(m_nodesManager);
m_filterCompatibleTechniqueJob->setManager(m_nodesManager->techniqueManager());
+ m_loadTextureJob->setNodeManagers(m_nodesManager);
}
void Renderer::setServices(QServiceLocator *services)
@@ -406,12 +438,17 @@ void Renderer::shutdown()
m_renderQueue->reset();
if (!m_renderThread) {
+ // Make sure the aspect thread is not left behind
+ m_willRenderPromise.store(0);
+ m_rendererReadySemaphore.release();
releaseGraphicsResources();
} else {
// Wake up the render thread in case it is waiting for some renderviews
// to be ready. The isReadyToSubmit() function checks for a shutdown
// having been requested.
- m_submitRenderViewsSemaphore.release(1);
+ m_willRenderPromise.store(0);
+ m_rendererReadySemaphore.release(1);
+ m_renderJobsReadySemaphore.release(1);
m_renderThread->wait();
}
}
@@ -527,7 +564,7 @@ void Renderer::setSceneRoot(QBackendNodeFactory *factory, Entity *sgRoot)
m_updateTreeEnabledJob->setRoot(m_renderSceneRoot);
// Set all flags to dirty
- m_dirtyBits.marked |= AbstractRenderer::AllDirty;
+ m_dirtyBits |= AbstractRenderer::AllDirty;
}
void Renderer::registerEventFilter(QEventFilterService *service)
@@ -546,6 +583,123 @@ RenderSettings *Renderer::settings() const
return m_settings;
}
+bool Renderer::createSurfaceLockAndMakeCurrent()
+{
+ FrameGraphVisitor visitor(nodeManagers()->frameGraphManager());
+ const QVector<FrameGraphNode *> fgLeaves = visitor.traverse(frameGraphRoot());
+ for (FrameGraphNode *leafNode : fgLeaves) {
+ FrameGraphNode *node = leafNode;
+ while (node) {
+ if (!node->isEnabled() || node->nodeType() != FrameGraphNode::Surface) {
+ node = node->parent();
+ continue;
+ }
+ const auto *surfaceSelector = static_cast<const RenderSurfaceSelector *>(node);
+ auto locker = QSharedPointer<SurfaceLocker>::create(surfaceSelector->surface());
+ if (!locker->isSurfaceValid())
+ return false;
+
+ m_surfaceLockers.append(locker);
+ node = node->parent();
+
+ if (!m_graphicsContext->makeCurrent(surfaceSelector->surface()))
+ return false;
+
+ // TODO: The same surface may appear twice here, so we return early to avoid a deadlock.
+ // We may want to fix this at some point and make sure we properly lock multiple
+ // surfaces.
+ return true;
+ }
+ }
+ // No surface found
+ return false;
+}
+
+// Called by render() or Scene3D on render thread
+void Renderer::lockSurfaceAndRender()
+{
+ // Make sure we can lock the surface before rendering. This cannot be done in a job,
+ // because we would otherwise risk rendering into a surface that could get destroyed.
+ // We could lock/unlock while rendering, but that requires a fair amount of extra
+ // logic to be able to recover gracefully from a partially completed render.
+ if (!createSurfaceLockAndMakeCurrent()) {
+ m_surfaceLockers.clear();
+ abortRenderJobs();
+ // We cannot render because we could not lock the surface or the surface is a nullptr.
+ // However, the surface might change in the next frontend/backend sync.
+ // We therefore need to make sure the aspect thread does not get stuck waiting for
+ // the next frame.
+ m_vsyncFrameAdvanceService->proceedToNextFrame();
+ return;
+ }
+ // Let the aspect thread know that we promise to render
+ m_willRenderPromise.store(1);
+ // Release the aspect thread
+ m_rendererReadySemaphore.release();
+ doRender();
+ // Release the surface lockers
+ m_surfaceLockers.clear();
+}
+
+/*!
+ * \internal
+ * Called by RenderAspect on aspect thread, returns false if
+ * the render thread has not promised to render the next frame.
+ *
+ * If this function returns false, the aspect thread
+ * bails out and does not issue the renderBinJobs.
+ *
+ * This keeps us from ending up in a deadlock where the barriers are
+ * waiting for doRender to release them.
+*/
+bool Renderer::releaseRendererAndRequestPromiseToRender()
+{
+ // Release the render thread, which could be waiting in waitForRenderJobs
+ // or is about to call tryWaitForRenderJobs
+ m_renderJobsReadySemaphore.release();
+ // Wait for the render thread to allow us to continue
+ m_rendererReadySemaphore.acquire();
+ // Check if the render thread has promised to call doRender
+ return m_willRenderPromise.testAndSetOrdered(1, 0);
+}
+
+/*!
+ * \internal
+ * Called by render(), returns false if we are no longer running
+*/
+bool Renderer::waitForRenderJobs()
+{
+ // Wait for the aspect thread to arrive at releaseRendererAndRequestPromiseToRender,
+ // which is right before it will create the renderBinJobs
+ m_renderJobsReadySemaphore.acquire();
+ // Check if we have not shut down in the meantime and rather want to bail out
+ return m_running.load();
+}
+
+/*!
+ * \internal
+ * Called by Scene3D, returns true if we could acquire
+*/
+bool Renderer::tryWaitForRenderJobs(int timeout)
+{
+ // See if the aspect thread has arrived at releaseRendererAndRequestPromiseToRender.
+ // If not, Scene3D needs to continue to avoid locking up the render thread.
+ return m_renderJobsReadySemaphore.tryAcquire(1, timeout) && m_running.load();
+}
+
+/*!
+ * \internal
+ * Called by Scene3D, in shutdown
+*/
+void Renderer::abortRenderJobs()
+{
+ // Make sure the aspect does not start render jobs
+ m_willRenderPromise.store(0);
+ // Release the aspect so it gets out of the job creation
+ m_rendererReadySemaphore.release();
+}
+
+
void Renderer::render()
{
// Traversing the framegraph tree from root to lead node
@@ -562,168 +716,102 @@ void Renderer::render()
// One scene description
// One framegraph description
- while (m_running.load() > 0) {
- doRender();
+ while (waitForRenderJobs()) {
+ lockSurfaceAndRender();
// TO DO: Restore windows exposed detection
// Probably needs to happens some place else though
}
}
-void Renderer::doRender(bool scene3dBlocking)
+/*!
+ * \internal
+ * The doRender function is called either by Renderer::render or
+ * QRenderAspect::tryRenderSynchronous (Scene3D).
+ * Jobs that it depends on are guaranteed to have been spawned by the aspect thread.
+ * It will run once for each set of renderBinJobs.
+ * Throughout the function call, the jobs are kept in sync using barriers.
+ * This guarantees the state of the GL context for the jobs.
+ * It is therefore important that any job that needs this function to be in at a specific point
+ * in the executio depends on the right barrier.
+*/
+void Renderer::doRender()
{
- Renderer::ViewSubmissionResultData submissionData;
- bool hasCleanedQueueAndProceeded = false;
- bool preprocessingComplete = false;
- bool beganDrawing = false;
- const bool canSubmit = isReadyToSubmit();
-
- // Lock the mutex to protect access to the renderQueue while we look for its state
- QMutexLocker locker(m_renderQueue->mutex());
- bool queueIsComplete = m_renderQueue->isFrameQueueComplete();
+ m_readRenderQueueSizeBarrierJob->waitForDependencies();
+ const bool queueIsComplete = m_renderQueue->isFrameQueueComplete();
const bool queueIsEmpty = m_renderQueue->targetRenderViewCount() == 0;
+ Q_ASSERT(queueIsComplete && !queueIsEmpty);
+ m_readRenderQueueSizeBarrierJob->allowToProceed();
- // Scene3D Blocking Mode
- if (scene3dBlocking && !queueIsComplete && !queueIsEmpty) {
- int i = 0;
- // We wait at most 10ms to avoid a case we could never recover from
- while (!queueIsComplete && i++ < 10) {
- QThread::msleep(1);
- qCDebug(Backend) << Q_FUNC_INFO << "Waiting for ready queue (try:" << i << "/ 10)";
- locker.unlock();
- queueIsComplete = m_renderQueue->isFrameQueueComplete();
- locker.relock();
- }
- }
-
- // When using synchronous rendering (QtQuick)
- // We are not sure that the frame queue is actually complete
- // Since a call to render may not be synched with the completions
- // of the RenderViewJobs
- // In such a case we return early, waiting for a next call with
- // the frame queue complete at this point
-
- // RenderQueue is complete (but that means it may be of size 0)
- if (canSubmit && (queueIsComplete && !queueIsEmpty)) {
- const QVector<Render::RenderView *> renderViews = m_renderQueue->nextFrameQueue();
-
+ const QVector<Render::RenderView *> renderViews = m_renderQueue->nextFrameQueue();
#if QT_CONFIG(qt3d_profile_jobs)
- // Save start of frame
- JobRunStats submissionStatsPart1;
- JobRunStats submissionStatsPart2;
- submissionStatsPart1.jobId.typeAndInstance[0] = JobTypes::FrameSubmissionPart1;
- submissionStatsPart1.jobId.typeAndInstance[1] = 0;
- submissionStatsPart1.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
- submissionStatsPart1.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- submissionStatsPart2.jobId.typeAndInstance[0] = JobTypes::FrameSubmissionPart2;
- submissionStatsPart2.jobId.typeAndInstance[1] = 0;
- submissionStatsPart2.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
+ // Save start of frame
+ JobRunStats submissionStatsPart1;
+ JobRunStats submissionStatsPart2;
+ submissionStatsPart1.jobId.typeAndInstance[0] = JobTypes::FrameSubmissionPart1;
+ submissionStatsPart1.jobId.typeAndInstance[1] = 0;
+ submissionStatsPart1.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
+ submissionStatsPart1.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
+ submissionStatsPart2.jobId.typeAndInstance[0] = JobTypes::FrameSubmissionPart2;
+ submissionStatsPart2.jobId.typeAndInstance[1] = 0;
+ submissionStatsPart2.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
#endif
- if (canRender()) {
- { // Scoped to destroy surfaceLock
- QSurface *surface = nullptr;
- for (const Render::RenderView *rv: renderViews) {
- surface = rv->surface();
- if (surface)
- break;
- }
-
- SurfaceLocker surfaceLock(surface);
- const bool surfaceIsValid = (surface && surfaceLock.isSurfaceValid());
- if (surfaceIsValid) {
- // Reset state for each draw if we don't have complete control of the context
- if (!m_ownedContext)
- m_graphicsContext->setCurrentStateSet(nullptr);
- beganDrawing = m_graphicsContext->beginDrawing(surface);
- if (beganDrawing) {
- // 1) Execute commands for buffer uploads, texture updates, shader loading first
- updateGLResources();
- // 2) Update VAO and copy data into commands to allow concurrent submission
- prepareCommandsSubmission(renderViews);
- preprocessingComplete = true;
- }
- }
- }
- // 2) Proceed to next frame and start preparing frame n + 1
- m_renderQueue->reset();
- locker.unlock(); // Done protecting RenderQueue
- m_vsyncFrameAdvanceService->proceedToNextFrame();
- hasCleanedQueueAndProceeded = true;
+ // Reset state for each draw if we don't have complete control of the context
+ if (!m_ownedContext)
+ m_graphicsContext->setCurrentStateSet(nullptr);
+ // Initialize context
+ m_beginDrawingBarrierJob->waitForDependencies();
+ m_graphicsContext->beginDrawing();
+ m_beginDrawingBarrierJob->allowToProceed();
+ // Execute commands for buffer uploads, texture updates, shader loading first
+ m_updateGLResourcesBarrierJob->waitForDependencies();
+ updateGLResources();
+ m_updateGLResourcesBarrierJob->allowToProceed();
+ // Update VAO and copy data into commands to allow concurrent submission
+ m_prepareCommandSubmissionBarrierJob->waitForDependencies();
+ prepareCommandsSubmission(renderViews);
+ m_prepareCommandSubmissionBarrierJob->allowToProceed();
+
+ // Proceed to next frame and start preparing frame n + 1
+ m_renderQueue->reset();
+ m_vsyncFrameAdvanceService->proceedToNextFrame();
#if QT_CONFIG(qt3d_profile_jobs)
- if (preprocessingComplete) {
- submissionStatsPart2.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- submissionStatsPart1.endTime = submissionStatsPart2.startTime;
- }
+ submissionStatsPart2.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
+ submissionStatsPart1.endTime = submissionStatsPart2.startTime;
#endif
- // Only try to submit the RenderViews if the preprocessing was successful
- // This part of the submission is happening in parallel to the RV building for the next frame
- if (preprocessingComplete) {
- // 3) Submit the render commands for frame n (making sure we never reference something that could be changing)
- // Render using current device state and renderer configuration
- submissionData = submitRenderViews(renderViews);
-
- // Perform any required cleanup of the Graphics resources (Buffers deleted, Shader deleted...)
- cleanGraphicsResources();
- }
- }
+ // Submit the render commands for frame n (making sure we never reference something that could be changing)
+ // Render using current device state and renderer configuration
+ Renderer::ViewSubmissionResultData submissionData = submitRenderViews(renderViews);
+ // Perform any required cleanup of the Graphics resources (Buffers deleted, Shader deleted...)
+ cleanGraphicsResources();
#if QT_CONFIG(qt3d_profile_jobs)
- // Execute the pending shell commands
- m_commandExecuter->performAsynchronousCommandExecution(renderViews);
+ // Execute the pending shell commands
+ m_commandExecuter->performAsynchronousCommandExecution(renderViews);
#endif
- // Delete all the RenderViews which will clear the allocators
- // that were used for their allocation
- qDeleteAll(renderViews);
+ // Delete all the RenderViews which will clear the allocators
+ // that were used for their allocation
+ qDeleteAll(renderViews);
#if QT_CONFIG(qt3d_profile_jobs)
- if (preprocessingComplete) {
- // Save submission elapsed time
- submissionStatsPart2.endTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- // Note this is safe since proceedToNextFrame is the one going to trigger
- // the write to the file, and this is performed after this step
- Qt3DCore::QThreadPooler::addSubmissionLogStatsEntry(submissionStatsPart1);
- Qt3DCore::QThreadPooler::addSubmissionLogStatsEntry(submissionStatsPart2);
- Profiling::GLTimeRecorder::writeResults();
- }
+ // Save submission elapsed time
+ submissionStatsPart2.endTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
+ // Note this is safe since proceedToNextFrame is the one going to trigger
+ // the write to the file, and this is performed after this step
+ Qt3DCore::QThreadPooler::addSubmissionLogStatsEntry(submissionStatsPart1);
+ Qt3DCore::QThreadPooler::addSubmissionLogStatsEntry(submissionStatsPart2);
+ Profiling::GLTimeRecorder::writeResults();
#endif
- }
-
- // Only reset renderQueue and proceed to next frame if the submission
- // succeeded or if we are using a render thread and that is wasn't performed
- // already
-
- // If hasCleanedQueueAndProceeded isn't true this implies that something went wrong
- // with the rendering and/or the renderqueue is incomplete from some reason
- // (in the case of scene3d the render jobs may be taking too long ....)
- // or alternatively it could be complete but empty (RenderQueue of size 0)
- if (!hasCleanedQueueAndProceeded &&
- (m_renderThread || queueIsComplete || queueIsEmpty)) {
- // RenderQueue was full but something bad happened when
- // trying to render it and therefore proceedToNextFrame was not called
- // Note: in this case the renderQueue mutex is still locked
-
- // Reset the m_renderQueue so that we won't try to render
- // with a queue used by a previous frame with corrupted content
- // if the current queue was correctly submitted
- m_renderQueue->reset();
-
- // We allow the RenderTickClock service to proceed to the next frame
- // In turn this will allow the aspect manager to request a new set of jobs
- // to be performed for each aspect
- m_vsyncFrameAdvanceService->proceedToNextFrame();
- }
// Perform the last swapBuffers calls after the proceedToNextFrame
// as this allows us to gain a bit of time for the preparation of the
// next frame
// Finish up with last surface used in the list of RenderViews
- if (beganDrawing) {
- SurfaceLocker surfaceLock(submissionData.surface);
- // Finish up with last surface used in the list of RenderViews
- m_graphicsContext->endDrawing(submissionData.lastBoundFBOId == m_graphicsContext->defaultFBO() && surfaceLock.isSurfaceValid());
- }
+ m_endDrawingBarrierJob->waitForDependencies();
+ m_graphicsContext->endDrawing(submissionData.lastBoundFBOId == m_graphicsContext->defaultFBO());
+ m_endDrawingBarrierJob->allowToProceed();
}
// Called by RenderViewJobs
@@ -738,48 +826,8 @@ void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder
// could be invalid since depending on the order of execution
// the counter could be complete but the renderview not yet added to the
// buffer depending on whichever order the cpu decides to process this
- const bool isQueueComplete = m_renderQueue->queueRenderView(renderView, submitOrder);
+ m_renderQueue->queueRenderView(renderView, submitOrder);
locker.unlock(); // We're done protecting the queue at this point
- if (isQueueComplete) {
- if (m_renderThread && m_running.load())
- Q_ASSERT(m_submitRenderViewsSemaphore.available() == 0);
- m_submitRenderViewsSemaphore.release(1);
- }
-}
-
-bool Renderer::canRender() const
-{
- // Make sure that we've not been told to terminate
- if (m_renderThread && !m_running.load()) {
- qCDebug(Rendering) << "RenderThread termination requested whilst waiting";
- return false;
- }
-
- // TO DO: Check if all surfaces have been destroyed...
- // It may be better if the last window to be closed trigger a call to shutdown
- // Rather than having checks for the surface everywhere
-
- return true;
-}
-
-bool Renderer::isReadyToSubmit()
-{
- // If we are using a render thread, make sure that
- // we've been told to render before rendering
- if (m_renderThread) { // Prevent ouf of order execution
- m_submitRenderViewsSemaphore.acquire(1);
-
- // Check if shutdown has been requested
- if (m_running.load() == 0)
- return false;
-
- // When using Thread rendering, the semaphore should only
- // be released when the frame queue is complete and there's
- // something to render
- // The case of shutdown should have been handled just before
- Q_ASSERT(m_renderQueue->isFrameQueueComplete());
- }
- return true;
}
// Main thread
@@ -890,6 +938,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView
const QVector<Qt3DCore::QNodeId> attributeIds = rGeometry->attributes();
for (Qt3DCore::QNodeId attributeId : attributeIds) {
Attribute *attribute = m_nodesManager->attributeManager()->lookupResource(attributeId);
+ Q_ASSERT(attribute);
switch (attribute->attributeType()) {
case QAttribute::IndexAttribute:
indexAttribute = attribute;
@@ -922,6 +971,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderView
if (command->m_drawIndirect) {
command->m_indirectAttributeByteOffset = indirectAttribute->byteOffset();
command->m_indirectDrawBuffer = m_nodesManager->bufferManager()->lookupHandle(indirectAttribute->bufferId());
+ Q_ASSERT(!command->m_indirectDrawBuffer.isNull());
} else {
// Use the count specified by the GeometryRender
// If not specify use the indexAttribute count if present
@@ -1037,6 +1087,7 @@ void Renderer::lookForDirtyShaders()
RenderPass *renderPass = m_nodesManager->renderPassManager()->lookupResource(passId);
HShader shaderHandle = m_nodesManager->shaderManager()->lookupHandle(renderPass->shaderProgram());
Shader *shader = m_nodesManager->shaderManager()->data(shaderHandle);
+ Q_ASSERT(renderPass && shader);
ShaderBuilder *shaderBuilder = nullptr;
for (const HShaderBuilder &builderHandle : activeBuilders) {
@@ -1103,6 +1154,7 @@ void Renderer::updateGLResources()
const QVector<HBuffer> dirtyBufferHandles = std::move(m_dirtyBuffers);
for (const HBuffer &handle: dirtyBufferHandles) {
Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
+ Q_ASSERT(buffer);
// Forces creation if it doesn't exit
// Also note the binding point doesn't really matter here, we just upload data
if (!m_graphicsContext->hasGLBufferForBuffer(buffer))
@@ -1119,6 +1171,7 @@ void Renderer::updateGLResources()
ShaderManager *shaderManager = m_nodesManager->shaderManager();
for (const HShader &handle: dirtyShaderHandles) {
Shader *shader = shaderManager->data(handle);
+ Q_ASSERT(shader);
// Compile shader
m_graphicsContext->loadShader(shader, shaderManager);
}
@@ -1129,6 +1182,7 @@ void Renderer::updateGLResources()
const QVector<HTexture> activeTextureHandles = std::move(m_dirtyTextures);
for (const HTexture &handle: activeTextureHandles) {
Texture *texture = m_nodesManager->textureManager()->data(handle);
+ Q_ASSERT(texture);
// Upload/Update texture
updateTexture(texture);
}
@@ -1236,6 +1290,7 @@ void Renderer::updateTexture(Texture *texture)
// Render Thread
void Renderer::cleanupTexture(const Texture *texture)
{
+ Q_ASSERT(texture);
GLTextureManager *glTextureManager = m_nodesManager->glTextureManager();
GLTexture *glTexture = glTextureManager->lookupResource(texture->peerId());
@@ -1288,7 +1343,6 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// If not, we have to free up the context from the previous surface
// and make the context current on the new surface
surface = renderView->surface();
- SurfaceLocker surfaceLock(surface);
// TO DO: Make sure that the surface we are rendering too has not been unset
@@ -1296,7 +1350,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// TODO: Investigate if it's worth providing a fallback offscreen surface
// to use when surface is null. Or if we should instead expose an
// offscreensurface to Qt3D.
- if (!surface || !surfaceLock.isSurfaceValid()) {
+ if (!surface) {
m_lastFrameCorrect.store(0);
continue;
}
@@ -1313,12 +1367,14 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
if (surfaceHasChanged) {
// If we can't make the context current on the surface, skip to the
// next RenderView. We won't get the full frame but we may get something
- if (!m_graphicsContext->beginDrawing(surface)) {
+ if (!m_graphicsContext->makeCurrent(surface)) {
qWarning() << "Failed to make OpenGL context current on surface";
m_lastFrameCorrect.store(0);
continue;
}
+ m_graphicsContext->beginDrawing();
+
previousSurface = surface;
lastBoundFBOId = m_graphicsContext->boundFrameBufferObject();
}
@@ -1457,39 +1513,35 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
void Renderer::markDirty(BackendNodeDirtySet changes, BackendNode *node)
{
Q_UNUSED(node);
- m_dirtyBits.marked |= changes;
+ m_dirtyBits|= changes;
}
Renderer::BackendNodeDirtySet Renderer::dirtyBits()
{
- return m_dirtyBits.marked;
+ return m_dirtyBits;
}
#if defined(QT_BUILD_INTERNAL)
void Renderer::clearDirtyBits(BackendNodeDirtySet changes)
{
- m_dirtyBits.remaining &= ~changes;
- m_dirtyBits.marked &= ~changes;
+ m_dirtyBits &= ~changes;
}
#endif
bool Renderer::shouldRender()
{
+ if (!m_settings)
+ return false;
// Only render if something changed during the last frame, or the last frame
// was not rendered successfully (or render-on-demand is disabled)
return (m_settings->renderPolicy() == QRenderSettings::Always
- || m_dirtyBits.marked != 0
- || m_dirtyBits.remaining != 0
+ || m_dirtyBits != 0
|| !m_lastFrameCorrect.load());
}
void Renderer::skipNextFrame()
{
- Q_ASSERT(m_settings->renderPolicy() != QRenderSettings::Always);
-
- // make submitRenderViews() actually run
- m_renderQueue->setNoRender();
- m_submitRenderViewsSemaphore.release(1);
+ m_vsyncFrameAdvanceService->proceedToNextFrame();
}
// Waits to be told to create jobs for the next frame
@@ -1500,28 +1552,46 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
{
QVector<QAspectJobPtr> renderBinJobs;
- // Create the jobs to build the frame
- const QVector<QAspectJobPtr> bufferJobs = createRenderBufferJobs();
-
// Remove previous dependencies
m_calculateBoundingVolumeJob->removeDependency(QWeakPointer<QAspectJob>());
m_cleanupJob->removeDependency(QWeakPointer<QAspectJob>());
- // Set dependencies
- for (const QAspectJobPtr &bufferJob : bufferJobs)
- m_calculateBoundingVolumeJob->addDependency(bufferJob);
+ // Render thread barrier jobs
+ renderBinJobs.append(m_readRenderQueueSizeBarrierJob);
+ renderBinJobs.append(m_beginDrawingBarrierJob);
+ renderBinJobs.append(m_updateGLResourcesBarrierJob);
+ renderBinJobs.append(m_prepareCommandSubmissionBarrierJob);
+ renderBinJobs.append(m_endDrawingBarrierJob);
+ // Jobs independent of dirty bits
+ renderBinJobs.push_back(m_updateSkinningPaletteJob);
+ renderBinJobs.push_back(m_updateLevelOfDetailJob);
+ renderBinJobs.push_back(m_cleanupJob);
+ renderBinJobs.push_back(m_sendRenderCaptureJob);
+ renderBinJobs.push_back(m_sendBufferCaptureJob);
+ renderBinJobs.push_back(m_vaoGathererJob);
+
+ // Independent job properties
+ m_updateSkinningPaletteJob->setDirtyJoints(m_nodesManager->jointManager()->dirtyJoints());
m_updateLevelOfDetailJob->setFrameGraphRoot(frameGraphRoot());
- const BackendNodeDirtySet dirtyBitsForFrame = m_dirtyBits.marked | m_dirtyBits.remaining;
- m_dirtyBits.marked = 0;
- m_dirtyBits.remaining = 0;
- BackendNodeDirtySet notCleared = 0;
+ // Buffer jobs, depends on dirty buffers
+ const QVector<QAspectJobPtr> bufferJobs = createRenderBufferJobs();
+ for (const QAspectJobPtr &bufferJob : bufferJobs) {
+ m_calculateBoundingVolumeJob->addDependency(bufferJob);
+ m_beginDrawingBarrierJob->addDependency(bufferJob);
+ }
+ renderBinJobs.append(bufferJobs);
+
+ // Jobs dependent on dirty bits
+ const BackendNodeDirtySet dirtyBitsForFrame = m_dirtyBits;
+ m_dirtyBits = 0;
- // Add jobs
const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty;
if (entitiesEnabledDirty) {
renderBinJobs.push_back(m_updateTreeEnabledJob);
+ // This dependency is added here because we clear all dependencies
+ // at the start of this function.
m_calculateBoundingVolumeJob->addDependency(m_updateTreeEnabledJob);
}
@@ -1541,80 +1611,55 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
renderBinJobs.push_back(m_expandBoundingVolumeJob);
}
- m_updateSkinningPaletteJob->setDirtyJoints(m_nodesManager->jointManager()->dirtyJoints());
- renderBinJobs.push_back(m_updateSkinningPaletteJob);
- renderBinJobs.push_back(m_updateLevelOfDetailJob);
- renderBinJobs.push_back(m_cleanupJob);
- renderBinJobs.push_back(m_sendRenderCaptureJob);
- renderBinJobs.push_back(m_sendBufferCaptureJob);
- renderBinJobs.append(bufferJobs);
-
- // Jobs to prepare GL Resource upload
- renderBinJobs.push_back(m_vaoGathererJob);
-
if (dirtyBitsForFrame & AbstractRenderer::BuffersDirty)
renderBinJobs.push_back(m_bufferGathererJob);
if (dirtyBitsForFrame & AbstractRenderer::TexturesDirty) {
- renderBinJobs.push_back(m_syncTextureLoadingJob);
+ renderBinJobs.push_back(m_loadTextureJob);
renderBinJobs.push_back(m_textureGathererJob);
}
+ if (dirtyBitsForFrame & AbstractRenderer::SkeletonDataDirty)
+ renderBinJobs.push_back(m_syncSkeletonLoadingJob);
+
+ if (dirtyBitsForFrame & AbstractRenderer::TechniquesDirty )
+ renderBinJobs.push_back(m_filterCompatibleTechniqueJob);
+
+ if (dirtyBitsForFrame & AbstractRenderer::ShadersDirty)
+ renderBinJobs.push_back(m_shaderGathererJob);
// Layer cache is dependent on layers, layer filters and the enabled flag
// on entities
const bool layersDirty = dirtyBitsForFrame & AbstractRenderer::LayersDirty;
const bool layersCacheNeedsToBeRebuilt = layersDirty || entitiesEnabledDirty;
-
const bool materialDirty = dirtyBitsForFrame & AbstractRenderer::MaterialDirty;
- QMutexLocker lock(m_renderQueue->mutex());
- if (m_renderQueue->wasReset()) { // Have we rendered yet? (Scene3D case)
- // Traverse the current framegraph. For each leaf node create a
- // RenderView and set its configuration then create a job to
- // populate the RenderView with a set of RenderCommands that get
- // their details from the RenderNodes that are visible to the
- // Camera selected by the framegraph configuration
- FrameGraphVisitor visitor(m_nodesManager->frameGraphManager());
- const QVector<FrameGraphNode *> fgLeaves = visitor.traverse(frameGraphRoot());
-
- // Remove leaf nodes that no longer exist from cache
- const QList<FrameGraphNode *> keys = m_cache.leafNodeCache.keys();
- for (FrameGraphNode *leafNode : keys) {
- if (!fgLeaves.contains(leafNode))
- m_cache.leafNodeCache.remove(leafNode);
- }
-
- const int fgBranchCount = fgLeaves.size();
- for (int i = 0; i < fgBranchCount; ++i) {
- RenderViewBuilder builder(fgLeaves.at(i), i, this);
- builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt);
- builder.setMaterialGathererCacheNeedsToBeRebuilt(materialDirty);
- builder.prepareJobs();
- renderBinJobs.append(builder.buildJobHierachy());
- }
-
- // Set target number of RenderViews
- m_renderQueue->setTargetRenderViewCount(fgBranchCount);
- } else {
- // FilterLayerEntityJob is part of the RenderViewBuilder jobs and must be run later
- // if none of those jobs are started this frame
- notCleared |= AbstractRenderer::EntityEnabledDirty;
- notCleared |= AbstractRenderer::LayersDirty;
+ // Traverse the current framegraph. For each leaf node create a
+ // RenderView and set its configuration then create a job to
+ // populate the RenderView with a set of RenderCommands that get
+ // their details from the RenderNodes that are visible to the
+ // Camera selected by the framegraph configuration
+ FrameGraphVisitor visitor(m_nodesManager->frameGraphManager());
+ const QVector<FrameGraphNode *> fgLeaves = visitor.traverse(frameGraphRoot());
+
+ // Remove leaf nodes that no longer exist from cache
+ const QList<FrameGraphNode *> keys = m_cache.leafNodeCache.keys();
+ for (FrameGraphNode *leafNode : keys) {
+ if (!fgLeaves.contains(leafNode))
+ m_cache.leafNodeCache.remove(leafNode);
}
- if (isRunning() && m_graphicsContext->isInitialized()) {
- if (dirtyBitsForFrame & AbstractRenderer::TechniquesDirty )
- renderBinJobs.push_back(m_filterCompatibleTechniqueJob);
- if (dirtyBitsForFrame & AbstractRenderer::ShadersDirty)
- renderBinJobs.push_back(m_shaderGathererJob);
- } else {
- notCleared |= AbstractRenderer::TechniquesDirty;
- notCleared |= AbstractRenderer::ShadersDirty;
- notCleared |= AbstractRenderer::MaterialDirty;
+ const int fgBranchCount = fgLeaves.size();
+ for (int i = 0; i < fgBranchCount; ++i) {
+ RenderViewBuilder builder(fgLeaves.at(i), i, this);
+ builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt);
+ builder.setMaterialGathererCacheNeedsToBeRebuilt(materialDirty);
+ builder.prepareJobs();
+ renderBinJobs.append(builder.buildJobHierachy());
}
- m_dirtyBits.remaining = dirtyBitsForFrame & notCleared;
+ // Set target number of RenderViews
+ m_renderQueue->setTargetRenderViewCount(fgBranchCount);
return renderBinJobs;
}
@@ -1645,9 +1690,9 @@ QAspectJobPtr Renderer::rayCastingJob()
return m_rayCastingJob;
}
-QAspectJobPtr Renderer::syncTextureLoadingJob()
+QAspectJobPtr Renderer::syncSkeletonLoadingJob()
{
- return m_syncTextureLoadingJob;
+ return m_syncSkeletonLoadingJob;
}
QAspectJobPtr Renderer::expandBoundingVolumeJob()
@@ -1752,7 +1797,7 @@ void Renderer::performCompute(const RenderView *, RenderCommand *command)
command->m_workGroups[2]);
}
// HACK: Reset the compute flag to dirty
- m_dirtyBits.marked |= AbstractRenderer::ComputeDirty;
+ m_dirtyBits |= AbstractRenderer::ComputeDirty;
#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG)
int err = m_graphicsContext->openGLContext()->functions()->glGetError();
@@ -1888,11 +1933,13 @@ bool Renderer::updateVAOWithAttributes(Geometry *geometry,
for (QNodeId attributeId : attributeIds) {
// TO DO: Improvement we could store handles and use the non locking policy on the attributeManager
Attribute *attribute = m_nodesManager->attributeManager()->lookupResource(attributeId);
+ Q_ASSERT(attribute);
if (attribute == nullptr)
return false;
Buffer *buffer = m_nodesManager->bufferManager()->lookupResource(attribute->bufferId());
+ Q_ASSERT(buffer);
// Buffer update was already performed at this point
// Just make sure the attribute reference a valid buffer
@@ -1945,6 +1992,7 @@ bool Renderer::requiresVAOAttributeUpdate(Geometry *geometry,
for (QNodeId attributeId : attributeIds) {
// TO DO: Improvement we could store handles and use the non locking policy on the attributeManager
Attribute *attribute = m_nodesManager->attributeManager()->lookupResource(attributeId);
+ Q_ASSERT(attribute);
if (attribute == nullptr)
continue;
@@ -1986,7 +2034,7 @@ void Renderer::cleanGraphicsResources()
}
}
-QList<QMouseEvent> Renderer::pendingPickingEvents() const
+QList<QPair<QObject *, QMouseEvent>> Renderer::pendingPickingEvents() const
{
return m_pickEventFilter->pendingMouseEvents();
}
diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h
index 521d17e80..fbb29dc7c 100644
--- a/src/render/backend/renderer_p.h
+++ b/src/render/backend/renderer_p.h
@@ -144,6 +144,10 @@ class NodeManagers;
class UpdateLevelOfDetailJob;
typedef QSharedPointer<UpdateLevelOfDetailJob> UpdateLevelOfDetailJobPtr;
+class LoadTextureDataJob;
+using LoadTextureDataJobPtr = QSharedPointer<LoadTextureDataJob>;
+class RenderBarrierJob;
+using RenderBarrierJobPtr = QSharedPointer<RenderBarrierJob>;
using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>;
@@ -171,7 +175,7 @@ public:
void releaseGraphicsResources() override;
void render() override;
- void doRender(bool scene3dBlocking = false) override;
+ void doRender() override;
void cleanGraphicsResources() override;
bool isRunning() const override { return m_running.load(); }
@@ -188,17 +192,29 @@ public:
void clearDirtyBits(BackendNodeDirtySet changes) override;
#endif
+ void lockSurfaceAndRender() override;
+ bool releaseRendererAndRequestPromiseToRender() override;
+ bool waitForRenderJobs() override;
+ bool tryWaitForRenderJobs(int timeout) override;
+ void abortRenderJobs() override;
+
bool shouldRender() override;
void skipNextFrame() override;
QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override;
Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override;
Qt3DCore::QAspectJobPtr rayCastingJob() override;
- Qt3DCore::QAspectJobPtr syncTextureLoadingJob() override;
+ Qt3DCore::QAspectJobPtr syncSkeletonLoadingJob() override;
Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() override;
QVector<Qt3DCore::QAspectJobPtr> createRenderBufferJobs() const;
+ inline RenderBarrierJobPtr readRenderQueueSizeBarrierJob() const { return m_readRenderQueueSizeBarrierJob; }
+ inline RenderBarrierJobPtr beginDrawingBarrierJob() const { return m_beginDrawingBarrierJob; }
+ inline RenderBarrierJobPtr updateGLResourcesBarrierJob() const { return m_updateGLResourcesBarrierJob; }
+ inline RenderBarrierJobPtr prepareCommandSubmissionBarrierJob() const { return m_prepareCommandSubmissionBarrierJob; }
+ inline RenderBarrierJobPtr endDrawingBarrierJob() const { return m_endDrawingBarrierJob; }
+
inline FrameCleanupJobPtr frameCleanupJob() const { return m_cleanupJob; }
inline UpdateShaderDataTransformJobPtr updateShaderDataTransformJob() const { return m_updateShaderDataTransformJob; }
inline CalculateBoundingVolumeJobPtr calculateBoundingVolumeJob() const { return m_calculateBoundingVolumeJob; }
@@ -208,8 +224,9 @@ public:
inline UpdateLevelOfDetailJobPtr updateLevelOfDetailJob() const { return m_updateLevelOfDetailJob; }
inline UpdateMeshTriangleListJobPtr updateMeshTriangleListJob() const { return m_updateMeshTriangleListJob; }
inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; }
- inline SynchronizerJobPtr textureLoadSyncJob() const { return m_syncTextureLoadingJob; }
+ inline SynchronizerJobPtr textureLoadSyncJob() const { return m_syncSkeletonLoadingJob; }
inline UpdateSkinningPaletteJobPtr updateSkinningPaletteJob() const { return m_updateSkinningPaletteJob; }
+ inline LoadTextureDataJobPtr loadTextureJob() const {return m_loadTextureJob; }
Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override;
@@ -245,14 +262,13 @@ public:
inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; }
- QList<QMouseEvent> pendingPickingEvents() const;
+ QList<QPair<QObject*, QMouseEvent>> pendingPickingEvents() const;
QList<QKeyEvent> pendingKeyEvents() const;
void addRenderCaptureSendRequest(Qt3DCore::QNodeId nodeId);
const QVector<Qt3DCore::QNodeId> takePendingRenderCaptureSendRequests();
void enqueueRenderView(RenderView *renderView, int submitOrder);
- bool isReadyToSubmit();
QVariant executeCommand(const QStringList &args) override;
void setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) override;
@@ -279,7 +295,7 @@ public:
private:
#endif
- bool canRender() const;
+ bool hasBeenAskedToTerminate() const;
Qt3DCore::QServiceLocator *m_services;
NodeManagers *m_nodesManager;
@@ -301,7 +317,6 @@ private:
QScopedPointer<RenderThread> m_renderThread;
QScopedPointer<VSyncFrameAdvanceService> m_vsyncFrameAdvanceService;
- QSemaphore m_submitRenderViewsSemaphore;
QSemaphore m_waitForInitializationToBeCompleted;
QAtomicInt m_running;
@@ -312,11 +327,7 @@ private:
QVector<Geometry *> m_dirtyGeometry;
QAtomicInt m_exposed;
- struct DirtyBits {
- BackendNodeDirtySet marked = 0; // marked dirty since last job build
- BackendNodeDirtySet remaining = 0; // remaining dirty after jobs have finished
- };
- DirtyBits m_dirtyBits;
+ BackendNodeDirtySet m_dirtyBits;
QAtomicInt m_lastFrameCorrect;
QOpenGLContext *m_glContext;
@@ -354,15 +365,18 @@ private:
GenericLambdaJobPtr<std::function<void ()>> m_bufferGathererJob;
GenericLambdaJobPtr<std::function<void ()>> m_vaoGathererJob;
GenericLambdaJobPtr<std::function<void ()>> m_textureGathererJob;
+ LoadTextureDataJobPtr m_loadTextureJob;
+
GenericLambdaJobPtr<std::function<void ()>> m_shaderGathererJob;
- SynchronizerJobPtr m_syncTextureLoadingJob;
+ SynchronizerJobPtr m_syncSkeletonLoadingJob;
void lookForAbandonedVaos();
void lookForDirtyBuffers();
void lookForDownloadableBuffers();
void lookForDirtyTextures();
void lookForDirtyShaders();
+ bool createSurfaceLockAndMakeCurrent();
QMutex m_abandonedVaosMutex;
QVector<HVao> m_abandonedVaos;
@@ -384,6 +398,18 @@ private:
QMetaObject::Connection m_contextConnection;
RendererCache m_cache;
+
+ RenderBarrierJobPtr m_readRenderQueueSizeBarrierJob;
+ RenderBarrierJobPtr m_beginDrawingBarrierJob;
+ RenderBarrierJobPtr m_updateGLResourcesBarrierJob;
+ RenderBarrierJobPtr m_prepareCommandSubmissionBarrierJob;
+ RenderBarrierJobPtr m_endDrawingBarrierJob;
+
+ QAtomicInt m_willRenderPromise;
+ QSemaphore m_rendererReadySemaphore;
+ QSemaphore m_renderJobsReadySemaphore;
+
+ QVector<QSharedPointer<SurfaceLocker>> m_surfaceLockers;
};
} // namespace Render
diff --git a/src/render/backend/renderqueue.cpp b/src/render/backend/renderqueue.cpp
index 2fa1cb7d2..db75558a4 100644
--- a/src/render/backend/renderqueue.cpp
+++ b/src/render/backend/renderqueue.cpp
@@ -90,7 +90,6 @@ bool RenderQueue::queueRenderView(RenderView *renderView, uint submissionOrderIn
Q_ASSERT(!m_noRender);
m_currentWorkQueue[submissionOrderIndex] = renderView;
++m_currentRenderViewCount;
- Q_ASSERT(m_currentRenderViewCount <= m_targetRenderViewCount);
return isFrameQueueComplete();
}
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 055c14143..84de728d4 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -148,16 +148,16 @@ static QRectF resolveViewport(const QRectF &fractionalViewport, const QSize &sur
fractionalViewport.height() * surfaceSize.height());
}
-static QMatrix4x4 getProjectionMatrix(const CameraLens *lens)
+static Matrix4x4 getProjectionMatrix(const CameraLens *lens)
{
if (!lens)
qWarning() << "[Qt3D Renderer] No Camera Lens found. Add a CameraSelector to your Frame Graph or make sure that no entities will be rendered.";
- return lens ? lens->projection() : QMatrix4x4();
+ return lens ? lens->projection() : Matrix4x4();
}
UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standardUniformType,
Entity *entity,
- const QMatrix4x4 &model) const
+ const Matrix4x4 &model) const
{
switch (standardUniformType) {
case ModelMatrix:
@@ -182,24 +182,26 @@ UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standa
case InverseModelViewMatrix:
return UniformValue((m_data.m_viewMatrix * model).inverted());
case InverseViewProjectionMatrix: {
- const QMatrix4x4 viewProjectionMatrix = getProjectionMatrix(m_data.m_renderCameraLens) * m_data.m_viewMatrix;
+ const Matrix4x4 viewProjectionMatrix = getProjectionMatrix(m_data.m_renderCameraLens) * m_data.m_viewMatrix;
return UniformValue(viewProjectionMatrix.inverted());
}
case InverseModelViewProjectionMatrix:
- return UniformValue((m_data.m_viewProjectionMatrix * model).inverted(0));
+ return UniformValue((m_data.m_viewProjectionMatrix * model).inverted());
case ModelNormalMatrix:
- return UniformValue(model.normalMatrix());
+ return UniformValue(convertToQMatrix4x4(model).normalMatrix());
case ModelViewNormalMatrix:
- return UniformValue((m_data.m_viewMatrix * model).normalMatrix());
+ return UniformValue(convertToQMatrix4x4(m_data.m_viewMatrix * model).normalMatrix());
case ViewportMatrix: {
QMatrix4x4 viewportMatrix;
+ // TO DO: Implement on Matrix4x4
viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize));
- return UniformValue(viewportMatrix);
+ return UniformValue(Matrix4x4(viewportMatrix));
}
case InverseViewportMatrix: {
QMatrix4x4 viewportMatrix;
+ // TO DO: Implement on Matrix4x4
viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize));
- return UniformValue(viewportMatrix.inverted());
+ return UniformValue(Matrix4x4(viewportMatrix.inverted()));
}
case AspectRatio:
return float(m_surfaceSize.width()) / float(m_surfaceSize.height());
@@ -518,20 +520,6 @@ void RenderView::setRenderer(Renderer *renderer)
m_manager = renderer->nodeManagers();
}
-class LightSourceCompare
-{
-public:
- LightSourceCompare(Entity *node) { p = node->worldBoundingVolume()->center(); }
- bool operator()(const LightSource &a, const LightSource &b) const {
- const float distA = p.distanceToPoint(a.entity->worldBoundingVolume()->center());
- const float distB = p.distanceToPoint(b.entity->worldBoundingVolume()->center());
- return distA < distB;
- }
-
-private:
- QVector3D p;
-};
-
void RenderView::addClearBuffers(const ClearBuffers *cb) {
QClearBuffers::BufferTypeFlags type = cb->type();
@@ -603,7 +591,7 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
// Project the camera-to-object-center vector onto the camera
// view vector. This gives a depth value suitable as the key
// for BackToFront sorting.
- command->m_depth = QVector3D::dotProduct(entity->worldBoundingVolume()->center() - m_data.m_eyePos, m_data.m_eyeViewDir);
+ command->m_depth = Vector3D::dotProduct(entity->worldBoundingVolume()->center() - m_data.m_eyePos, m_data.m_eyeViewDir);
command->m_geometry = geometryHandle;
command->m_geometryRenderer = geometryRendererHandle;
@@ -629,8 +617,15 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
// Replace with more sophisticated mechanisms later.
// Copy vector so that we can sort it concurrently and we only want to sort the one for the current command
QVector<LightSource> lightSources = m_lightSources;
- if (lightSources.size() > 1)
- std::sort(lightSources.begin(), lightSources.end(), LightSourceCompare(entity));
+ if (lightSources.size() > 1) {
+ const Vector3D entityCenter = entity->worldBoundingVolume()->center();
+ std::sort(lightSources.begin(), lightSources.end(),
+ [&] (const LightSource &a, const LightSource &b) {
+ const float distA = entityCenter.distanceToPoint(a.entity->worldBoundingVolume()->center());
+ const float distB = entityCenter.distanceToPoint(b.entity->worldBoundingVolume()->center());
+ return distA < distB;
+ });
+ }
ParameterInfoList globalParameters = passData.parameterInfo;
// setShaderAndUniforms can initialize a localData
@@ -653,6 +648,7 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
const QVector<Qt3DCore::QNodeId> attributeIds = geometry->attributes();
for (Qt3DCore::QNodeId attributeId : attributeIds) {
Attribute *attribute = m_manager->attributeManager()->lookupResource(attributeId);
+ Q_ASSERT(attribute != nullptr);
if (attribute->attributeType() == QAttribute::IndexAttribute)
indexAttribute = attribute;
else if (command->m_attributes.contains(attribute->nameId()))
@@ -755,21 +751,21 @@ QVector<RenderCommand *> RenderView::buildComputeRenderCommands(const QVector<En
void RenderView::updateMatrices()
{
if (m_data.m_renderCameraNode && m_data.m_renderCameraLens && m_data.m_renderCameraLens->isEnabled()) {
- const QMatrix4x4 cameraWorld = *(m_data.m_renderCameraNode->worldTransform());
+ const Matrix4x4 cameraWorld = *(m_data.m_renderCameraNode->worldTransform());
setViewMatrix(m_data.m_renderCameraLens->viewMatrix(cameraWorld));
setViewProjectionMatrix(m_data.m_renderCameraLens->projection() * viewMatrix());
//To get the eyePosition of the camera, we need to use the inverse of the
//camera's worldTransform matrix.
- const QMatrix4x4 inverseWorldTransform = viewMatrix().inverted();
- const QVector3D eyePosition(inverseWorldTransform.column(3));
+ const Matrix4x4 inverseWorldTransform = viewMatrix().inverted();
+ const Vector3D eyePosition(inverseWorldTransform.column(3));
setEyePosition(eyePosition);
// Get the viewing direction of the camera. Use the normal matrix to
// ensure non-uniform scale works too.
- QMatrix3x3 normalMat = m_data.m_viewMatrix.normalMatrix();
+ const QMatrix3x3 normalMat = convertToQMatrix4x4(m_data.m_viewMatrix).normalMatrix();
// dir = normalize(QVector3D(0, 0, -1) * normalMat)
- setEyeViewDirection(QVector3D(-normalMat(2, 0), -normalMat(2, 1), -normalMat(2, 2)).normalized());
+ setEyeViewDirection(Vector3D(-normalMat(2, 0), -normalMat(2, 1), -normalMat(2, 2)).normalized());
}
}
@@ -780,14 +776,19 @@ void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, c
// ShaderData/Buffers would be handled as UBO/SSBO and would therefore
// not be in the default uniform block
if (value.valueType() == UniformValue::NodeId) {
- const Qt3DCore::QNodeId texId = *value.constData<Qt3DCore::QNodeId>();
- const Texture *tex = m_manager->textureManager()->lookupResource(texId);
- if (tex != nullptr) {
- uniformPack.setTexture(nameId, texId);
- UniformValue::Texture textureValue;
- textureValue.nodeId = texId;
- uniformPack.setUniform(nameId, UniformValue(textureValue));
+ const Qt3DCore::QNodeId *nodeIds = value.constData<Qt3DCore::QNodeId>();
+
+ const int uniformArraySize = value.byteSize() / sizeof(Qt3DCore::QNodeId);
+ for (int i = 0; i < uniformArraySize; ++i) {
+ const Qt3DCore::QNodeId texId = nodeIds[i];
+ const Texture *tex = m_manager->textureManager()->lookupResource(texId);
+ if (tex != nullptr)
+ uniformPack.setTexture(nameId, i, texId);
}
+
+ UniformValue textureValue(uniformArraySize * sizeof(int), UniformValue::TextureValue);
+ std::fill(textureValue.data<int>(), textureValue.data<int>() + uniformArraySize, -1);
+ uniformPack.setUniform(nameId, textureValue);
} else {
uniformPack.setUniform(nameId, value);
}
@@ -797,7 +798,7 @@ void RenderView::setStandardUniformValue(ShaderParameterPack &uniformPack,
int glslNameId,
int nameId,
Entity *entity,
- const QMatrix4x4 &worldTransform) const
+ const Matrix4x4 &worldTransform) const
{
uniformPack.setUniform(glslNameId, standardUniformValue(ms_standardUniformSetters[nameId], entity, worldTransform));
}
@@ -963,7 +964,7 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
!shaderStorageBlockNamesIds.isEmpty() || !attributeNamesIds.isEmpty()) {
// Set default standard uniforms without bindings
- QMatrix4x4 worldTransform = *(entity->worldTransform());
+ const Matrix4x4 worldTransform = *(entity->worldTransform());
for (const int uniformNameId : uniformNamesIds) {
if (ms_standardUniformSetters.contains(uniformNameId))
setStandardUniformValue(command->m_parameterPack, uniformNameId, uniformNameId, entity, worldTransform);
@@ -1010,7 +1011,7 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
if (lightIdx == MAX_LIGHTS)
break;
Entity *lightEntity = lightSource.entity;
- const QVector3D worldPos = lightEntity->worldBoundingVolume()->center();
+ const Vector3D worldPos = lightEntity->worldBoundingVolume()->center();
for (Light *light : lightSource.lights) {
if (!light->isEnabled())
continue;
@@ -1025,13 +1026,13 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
// Note: implicit conversion of values to UniformValue
setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos);
setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], QVector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], 0.5f);
// There is no risk in doing that even if multithreaded
// since we are sure that a shaderData is unique for a given light
// and won't ever be referenced as a Component either
- QMatrix4x4 *worldTransform = lightEntity->worldTransform();
+ Matrix4x4 *worldTransform = lightEntity->worldTransform();
if (worldTransform)
shaderData->updateWorldTransform(*worldTransform);
@@ -1046,9 +1047,9 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
// If no active light sources and no environment light, add a default light
if (activeLightSources.isEmpty() && !environmentLight) {
// Note: implicit conversion of values to UniformValue
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], QVector3D(10.0f, 10.0f, 0.0f));
+ setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], QVector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[0], 0.5f);
}
diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h
index b684cbb85..cb3c74917 100644
--- a/src/render/backend/renderview_p.h
+++ b/src/render/backend/renderview_p.h
@@ -67,6 +67,7 @@
#include <Qt3DRender/private/qblitframebuffer_p.h>
#include <Qt3DCore/private/qframeallocator_p.h>
+#include <Qt3DRender/private/aligned_malloc_p.h>
// TODO: Move out once this is all refactored
#include <Qt3DRender/private/renderviewjobutils_p.h>
@@ -98,14 +99,14 @@ typedef QPair<QString, ActivePropertyContent > ActiveProperty;
struct Q_AUTOTEST_EXPORT Plane
{
- explicit Plane(const QVector4D &planeEquation)
+ explicit Plane(const Vector4D &planeEquation)
: planeEquation(planeEquation)
- , normal(planeEquation.toVector3D().normalized())
- , d(planeEquation.w() / planeEquation.toVector3D().length())
+ , normal(Vector3D(planeEquation).normalized())
+ , d(planeEquation.w() / Vector3D(planeEquation).length())
{}
- const QVector4D planeEquation;
- const QVector3D normal;
+ const Vector4D planeEquation;
+ const Vector3D normal;
const float d;
};
@@ -136,6 +137,8 @@ public:
RenderView();
~RenderView();
+ QT3D_ALIGNED_MALLOC_AND_FREE()
+
// TODO: Add a way to specify a sort predicate for the RenderCommands
void sort();
@@ -153,17 +156,17 @@ public:
inline void setRenderCameraEntity(Entity *renderCameraNode) Q_DECL_NOTHROW { m_data.m_renderCameraNode = renderCameraNode; }
inline Entity *renderCameraEntity() const Q_DECL_NOTHROW { return m_data.m_renderCameraNode; }
- inline void setViewMatrix(const QMatrix4x4 &viewMatrix) Q_DECL_NOTHROW { m_data.m_viewMatrix = viewMatrix; }
- inline QMatrix4x4 viewMatrix() const Q_DECL_NOTHROW { return m_data.m_viewMatrix; }
+ inline void setViewMatrix(const Matrix4x4 &viewMatrix) Q_DECL_NOTHROW { m_data.m_viewMatrix = viewMatrix; }
+ inline Matrix4x4 viewMatrix() const Q_DECL_NOTHROW { return m_data.m_viewMatrix; }
- inline void setViewProjectionMatrix(const QMatrix4x4 &viewProjectionMatrix) Q_DECL_NOTHROW { m_data.m_viewProjectionMatrix = viewProjectionMatrix; }
- inline QMatrix4x4 viewProjectionMatrix() const Q_DECL_NOTHROW { return m_data.m_viewProjectionMatrix; }
+ inline void setViewProjectionMatrix(const Matrix4x4 &viewProjectionMatrix) Q_DECL_NOTHROW { m_data.m_viewProjectionMatrix = viewProjectionMatrix; }
+ inline Matrix4x4 viewProjectionMatrix() const Q_DECL_NOTHROW { return m_data.m_viewProjectionMatrix; }
- inline void setEyePosition(const QVector3D &eyePos) Q_DECL_NOTHROW { m_data.m_eyePos = eyePos; }
- inline QVector3D eyePosition() const Q_DECL_NOTHROW { return m_data.m_eyePos; }
+ inline void setEyePosition(const Vector3D &eyePos) Q_DECL_NOTHROW { m_data.m_eyePos = eyePos; }
+ inline Vector3D eyePosition() const Q_DECL_NOTHROW { return m_data.m_eyePos; }
- inline void setEyeViewDirection(const QVector3D &dir) Q_DECL_NOTHROW { m_data.m_eyeViewDir = dir; }
- inline QVector3D eyeViewDirection() const Q_DECL_NOTHROW { return m_data.m_eyeViewDir; }
+ inline void setEyeViewDirection(const Vector3D &dir) Q_DECL_NOTHROW { m_data.m_eyeViewDir = dir; }
+ inline Vector3D eyeViewDirection() const Q_DECL_NOTHROW { return m_data.m_eyeViewDir; }
inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) Q_DECL_NOTHROW { m_data.m_layerFilterIds.push_back(layerFilterId); }
inline Qt3DCore::QNodeIdVector layerFilters() const Q_DECL_NOTHROW { return m_data.m_layerFilterIds; }
@@ -260,12 +263,12 @@ public:
Entity *m_renderCameraNode;
const TechniqueFilter *m_techniqueFilter;
const RenderPassFilter *m_passFilter;
- QMatrix4x4 m_viewMatrix;
- QMatrix4x4 m_viewProjectionMatrix;
+ Matrix4x4 m_viewMatrix;
+ Matrix4x4 m_viewProjectionMatrix;
Qt3DCore::QNodeIdVector m_layerFilterIds;
QVector<Qt3DRender::QSortPolicy::SortType> m_sortingTypes;
- QVector3D m_eyePos;
- QVector3D m_eyeViewDir;
+ Vector3D m_eyePos;
+ Vector3D m_eyeViewDir;
Qt3DCore::QNodeIdVector m_proximityFilterIds;
};
@@ -285,7 +288,6 @@ private:
Entity *entity,
const QVector<LightSource> &activeLightSources,
EnvironmentLight *environmentLight) const;
-
mutable QThreadStorage<UniformBlockValueBuilder*> m_localData;
Qt3DCore::QNodeId m_renderCaptureNodeId;
@@ -360,14 +362,14 @@ private:
UniformValue standardUniformValue(StandardUniform standardUniformType,
Entity *entity,
- const QMatrix4x4 &model) const;
+ const Matrix4x4 &model) const;
void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const;
void setStandardUniformValue(ShaderParameterPack &uniformPack,
int glslNameId,
int nameId,
Entity *entity,
- const QMatrix4x4 &worldTransform) const;
+ const Matrix4x4 &worldTransform) const;
void setUniformBlockValue(ShaderParameterPack &uniformPack,
Shader *shader,
const ShaderUniformBlock &block,
diff --git a/src/render/backend/renderviewbuilder.cpp b/src/render/backend/renderviewbuilder.cpp
index 0682018fc..495b666f5 100644
--- a/src/render/backend/renderviewbuilder.cpp
+++ b/src/render/backend/renderviewbuilder.cpp
@@ -39,6 +39,8 @@
#include "renderviewbuilder_p.h"
+#include <Qt3DRender/private/renderbarrierjob_p.h>
+
#include <QThread>
QT_BEGIN_NAMESPACE
@@ -81,9 +83,6 @@ public:
// Sort the commands
rv->sort();
-
- // Enqueue our fully populated RenderView with the RenderThread
- m_renderer->enqueueRenderView(rv, m_renderViewJob->submitOrderIndex());
}
private:
@@ -125,13 +124,15 @@ public:
const FilterLayerEntityJobPtr &filterEntityByLayerJob,
const FilterProximityDistanceJobPtr &filterProximityJob,
const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
- const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs)
+ const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs,
+ Renderer *renderer)
: m_renderViewJob(renderViewJob)
, m_frustumCullingJob(frustumCullingJob)
, m_filterEntityByLayerJob(filterEntityByLayerJob)
, m_filterProximityJob(filterProximityJob)
, m_materialGathererJobs(materialGathererJobs)
, m_renderViewBuilderJobs(renderViewBuilderJobs)
+ , m_renderer(renderer)
{}
void operator()()
@@ -157,6 +158,9 @@ public:
// Set whether frustum culling is enabled or not
m_frustumCullingJob->setActive(rv->frustumCulling());
+
+ // Enqueue RenderView with the renderer
+ m_renderer->enqueueRenderView(rv, m_renderViewJob->submitOrderIndex());
}
private:
@@ -166,6 +170,7 @@ private:
FilterProximityDistanceJobPtr m_filterProximityJob;
QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
+ Renderer *m_renderer;
};
class SyncRenderCommandBuilding
@@ -355,7 +360,7 @@ RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int rende
, m_lightGathererJob(Render::LightGathererPtr::create())
, m_renderableEntityFilterJob(RenderableEntityFilterPtr::create())
, m_computableEntityFilterJob(ComputableEntityFilterPtr::create())
- , m_frustumCullingJob(Render::FrustumCullingJobPtr::create())
+ , m_frustumCullingJob(new Render::FrustumCullingJob())
, m_syncFrustumCullingJob(SynchronizerJobPtr::create(SyncFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling))
, m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create(SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex))
, m_syncFilterEntityByLayerJob()
@@ -519,7 +524,8 @@ void RenderViewBuilder::prepareJobs()
m_filterEntityByLayerJob,
m_filterProximityJob,
m_materialGathererJobs,
- m_renderViewBuilderJobs),
+ m_renderViewBuilderJobs,
+ m_renderer),
JobTypes::SyncRenderViewInitialization);
}
@@ -545,11 +551,13 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
m_setClearDrawBufferIndexJob->addDependency(m_syncRenderViewInitializationJob);
+ m_renderer->readRenderQueueSizeBarrierJob()->addDependency(m_syncRenderViewInitializationJob);
m_syncRenderViewInitializationJob->addDependency(m_renderViewJob);
m_filterProximityJob->addDependency(m_renderer->expandBoundingVolumeJob());
m_filterProximityJob->addDependency(m_syncRenderViewInitializationJob);
+ m_syncRenderCommandBuildingJob->addDependency(m_renderer->updateGLResourcesBarrierJob());
m_syncRenderCommandBuildingJob->addDependency(m_syncRenderViewInitializationJob);
m_syncRenderCommandBuildingJob->addDependency(m_renderableEntityFilterJob);
m_syncRenderCommandBuildingJob->addDependency(m_computableEntityFilterJob);
@@ -558,10 +566,15 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
m_syncRenderCommandBuildingJob->addDependency(m_frustumCullingJob);
for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) {
+ renderViewCommandBuilder->addDependency(m_renderer->updateSkinningPaletteJob());
+ renderViewCommandBuilder->addDependency(m_renderer->updateWorldBoundingVolumeJob());
+ renderViewCommandBuilder->addDependency(m_renderer->updateShaderDataTransformJob());
renderViewCommandBuilder->addDependency(m_syncRenderCommandBuildingJob);
+
m_syncRenderViewCommandBuildersJob->addDependency(renderViewCommandBuilder);
}
+ m_renderer->prepareCommandSubmissionBarrierJob()->addDependency(m_syncRenderViewCommandBuildersJob);
m_renderer->frameCleanupJob()->addDependency(m_syncRenderViewCommandBuildersJob);
m_renderer->frameCleanupJob()->addDependency(m_setClearDrawBufferIndexJob);
diff --git a/src/render/backend/segmentsvisitor.cpp b/src/render/backend/segmentsvisitor.cpp
index 96e2b3b6c..a3a5d059c 100644
--- a/src/render/backend/segmentsvisitor.cpp
+++ b/src/render/backend/segmentsvisitor.cpp
@@ -86,7 +86,7 @@ void traverseSegmentsIndexed(Index *indices,
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2];
- QVector3D abc[2];
+ Vector3D abc[2];
while (i < indexInfo.count) {
for (uint u = 0; u < 2; ++u) {
ndx[u] = indices[i + u];
@@ -112,7 +112,7 @@ void traverseSegments(Vertex *vertices,
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2];
- QVector3D abc[2];
+ Vector3D abc[2];
while (i < vertexInfo.count) {
for (uint u = 0; u < 2; ++u) {
ndx[u] = (i + u);
@@ -139,7 +139,7 @@ void traverseSegmentStripIndexed(Index *indices,
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2];
- QVector3D abc[2];
+ Vector3D abc[2];
ndx[0] = indices[0];
uint idx = ndx[0] * verticesStride;
for (uint j = 0; j < maxVerticesDataSize; ++j)
@@ -180,7 +180,7 @@ void traverseSegmentStrip(Vertex *vertices,
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2];
- QVector3D abc[2];
+ Vector3D abc[2];
ndx[0] = i;
uint idx = ndx[0] * verticesStride;
for (uint j = 0; j < maxVerticesDataSize; ++j)
@@ -218,7 +218,7 @@ void traverseSegmentAdjacencyIndexed(Index *indices,
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2];
- QVector3D abc[2];
+ Vector3D abc[2];
while (i < n) {
for (uint u = 0; u < 2; ++u) {
ndx[u] = indices[i + u];
@@ -245,7 +245,7 @@ void traverseSegmentAdjacency(Vertex *vertices,
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2];
- QVector3D abc[2];
+ Vector3D abc[2];
while (i < n) {
for (uint u = 0; u < 2; ++u) {
ndx[u] = (i + u);
diff --git a/src/render/backend/segmentsvisitor_p.h b/src/render/backend/segmentsvisitor_p.h
index 21867b0d5..cd5df1268 100644
--- a/src/render/backend/segmentsvisitor_p.h
+++ b/src/render/backend/segmentsvisitor_p.h
@@ -52,6 +52,7 @@
//
#include <Qt3DCore/qnodeid.h>
+#include <Qt3DCore/private/vector3d_p.h>
QT_BEGIN_NAMESPACE
@@ -75,8 +76,8 @@ public:
void apply(const Qt3DCore::QEntity *entity);
void apply(const GeometryRenderer *renderer, const Qt3DCore::QNodeId id);
- virtual void visit(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b) = 0;
+ virtual void visit(uint andx, const Vector3D &a,
+ uint bndx, const Vector3D &b) = 0;
protected:
NodeManagers *m_manager;
diff --git a/src/render/backend/shaderparameterpack.cpp b/src/render/backend/shaderparameterpack.cpp
index 01a977aee..f78e45a5e 100644
--- a/src/render/backend/shaderparameterpack.cpp
+++ b/src/render/backend/shaderparameterpack.cpp
@@ -65,17 +65,17 @@ void ShaderParameterPack::setUniform(const int glslNameId, const UniformValue &v
m_uniforms.insert(glslNameId, val);
}
-void ShaderParameterPack::setTexture(const int glslNameId, Qt3DCore::QNodeId texId)
+void ShaderParameterPack::setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId texId)
{
for (int t=0; t<m_textures.size(); ++t) {
- if (m_textures[t].glslNameId != glslNameId)
+ if (m_textures[t].glslNameId != glslNameId || m_textures[t].uniformArrayIndex != uniformArrayIndex)
continue;
m_textures[t].texId = texId;
return;
}
- m_textures.append(NamedTexture(glslNameId, texId));
+ m_textures.append(NamedTexture(glslNameId, texId, uniformArrayIndex));
}
// Contains Uniform Block Index and QNodeId of the ShaderData (UBO)
diff --git a/src/render/backend/shaderparameterpack_p.h b/src/render/backend/shaderparameterpack_p.h
index c0ab05e57..abd63a187 100644
--- a/src/render/backend/shaderparameterpack_p.h
+++ b/src/render/backend/shaderparameterpack_p.h
@@ -96,7 +96,7 @@ public:
~ShaderParameterPack();
void setUniform(const int glslNameId, const UniformValue &val);
- void setTexture(const int glslNameId, Qt3DCore::QNodeId id);
+ void setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id);
void setUniformBuffer(BlockToUBO blockToUBO);
void setShaderStorageBuffer(BlockToSSBO blockToSSBO);
void setSubmissionUniform(const ShaderUniform &uniform);
@@ -108,13 +108,15 @@ public:
struct NamedTexture
{
NamedTexture() {}
- NamedTexture(const int nm, Qt3DCore::QNodeId t)
- : glslNameId(nm)
- , texId(t)
+ NamedTexture(const int glslNameId, Qt3DCore::QNodeId texId, int uniformArrayIndex)
+ : glslNameId(glslNameId)
+ , texId(texId)
+ , uniformArrayIndex(uniformArrayIndex)
{ }
int glslNameId;
Qt3DCore::QNodeId texId;
+ int uniformArrayIndex;
};
inline QVector<NamedTexture> textures() const { return m_textures; }
diff --git a/src/render/backend/transform.cpp b/src/render/backend/transform.cpp
index 636c2d103..20574d6f7 100644
--- a/src/render/backend/transform.cpp
+++ b/src/render/backend/transform.cpp
@@ -64,7 +64,7 @@ void Transform::cleanup()
m_rotation = QQuaternion();
m_scale = QVector3D();
m_translation = QVector3D();
- m_transformMatrix = QMatrix4x4();
+ m_transformMatrix = Matrix4x4();
QBackendNode::setEnabled(false);
}
@@ -78,7 +78,7 @@ void Transform::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &ch
updateMatrix();
}
-QMatrix4x4 Transform::transformMatrix() const
+Matrix4x4 Transform::transformMatrix() const
{
return m_transformMatrix;
}
@@ -125,7 +125,7 @@ void Transform::updateMatrix()
m.translate(m_translation);
m.rotate(m_rotation);
m.scale(m_scale);
- m_transformMatrix = m;
+ m_transformMatrix = Matrix4x4(m);
}
} // namespace Render
diff --git a/src/render/backend/transform_p.h b/src/render/backend/transform_p.h
index ce026da9d..8e3e9d639 100644
--- a/src/render/backend/transform_p.h
+++ b/src/render/backend/transform_p.h
@@ -54,7 +54,7 @@
#include <Qt3DRender/private/backendnode_p.h>
#include <QtGui/qquaternion.h>
#include <QtGui/qvector3d.h>
-#include <QMatrix4x4>
+#include <Qt3DCore/private/matrix4x4_p.h>
QT_BEGIN_NAMESPACE
@@ -71,7 +71,7 @@ public:
Transform();
void cleanup();
- QMatrix4x4 transformMatrix() const;
+ Matrix4x4 transformMatrix() const;
QVector3D scale() const;
QQuaternion rotation() const;
QVector3D translation() const;
@@ -83,7 +83,7 @@ public:
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final;
- QMatrix4x4 m_transformMatrix;
+ Matrix4x4 m_transformMatrix;
QQuaternion m_rotation;
QVector3D m_scale;
QVector3D m_translation;
diff --git a/src/render/backend/triangleboundingvolume.cpp b/src/render/backend/triangleboundingvolume.cpp
index ca2d26897..be5206657 100644
--- a/src/render/backend/triangleboundingvolume.cpp
+++ b/src/render/backend/triangleboundingvolume.cpp
@@ -49,35 +49,35 @@ namespace Render {
// Note: a, b, c in clockwise order
// RealTime Collision Detection page 192
bool intersectsSegmentTriangle(const RayCasting::QRay3D &ray,
- const QVector3D &a,
- const QVector3D &b,
- const QVector3D &c,
- QVector3D &uvw,
+ const Vector3D &a,
+ const Vector3D &b,
+ const Vector3D &c,
+ Vector3D &uvw,
float &t)
{
- const QVector3D ab = b - a;
- const QVector3D ac = c - a;
- const QVector3D qp = (ray.origin() - ray.point(ray.distance()));
+ const Vector3D ab = b - a;
+ const Vector3D ac = c - a;
+ const Vector3D qp = (ray.origin() - ray.point(ray.distance()));
- const QVector3D n = QVector3D::crossProduct(ab, ac);
- const float d = QVector3D::dotProduct(qp, n);
+ const Vector3D n = Vector3D::crossProduct(ab, ac);
+ const float d = Vector3D::dotProduct(qp, n);
if (d <= 0.0f)
return false;
- const QVector3D ap = ray.origin() - a;
- t = QVector3D::dotProduct(ap, n);
+ const Vector3D ap = ray.origin() - a;
+ t = Vector3D::dotProduct(ap, n);
if (t < 0.0f || t > d)
return false;
- const QVector3D e = QVector3D::crossProduct(qp, ap);
- uvw.setY(QVector3D::dotProduct(ac, e));
+ const Vector3D e = Vector3D::crossProduct(qp, ap);
+ uvw.setY(Vector3D::dotProduct(ac, e));
if (uvw.y() < 0.0f || uvw.y() > d)
return false;
- uvw.setZ(-QVector3D::dotProduct(ab, e));
+ uvw.setZ(-Vector3D::dotProduct(ab, e));
if (uvw.z() < 0.0f || uvw.y() + uvw.z() > d)
return false;
@@ -99,7 +99,7 @@ TriangleBoundingVolume::TriangleBoundingVolume()
/*!
The vertices a, b, c are assumed to be in counter clockwise order.
*/
-TriangleBoundingVolume::TriangleBoundingVolume(Qt3DCore::QNodeId id, const QVector3D &a, const QVector3D &b, const QVector3D &c)
+TriangleBoundingVolume::TriangleBoundingVolume(Qt3DCore::QNodeId id, const Vector3D &a, const Vector3D &b, const Vector3D &c)
: QBoundingVolume()
, m_id(id)
, m_a(a)
@@ -112,10 +112,10 @@ Qt3DCore::QNodeId TriangleBoundingVolume::id() const
return m_id;
}
-bool TriangleBoundingVolume::intersects(const RayCasting::QRay3D &ray, QVector3D *q, QVector3D *uvw) const
+bool TriangleBoundingVolume::intersects(const RayCasting::QRay3D &ray, Vector3D *q, Vector3D *uvw) const
{
float t = 0.0f;
- QVector3D uvwr;
+ Vector3D uvwr;
const float intersected = intersectsSegmentTriangle(ray, m_c, m_b, m_a, uvwr, t);
if (intersected) {
@@ -132,41 +132,41 @@ TriangleBoundingVolume::Type TriangleBoundingVolume::type() const
return RayCasting::QBoundingVolume::Triangle;
}
-QVector3D TriangleBoundingVolume::a() const
+Vector3D TriangleBoundingVolume::a() const
{
return m_a;
}
-QVector3D TriangleBoundingVolume::b() const
+Vector3D TriangleBoundingVolume::b() const
{
return m_b;
}
-QVector3D TriangleBoundingVolume::c() const
+Vector3D TriangleBoundingVolume::c() const
{
return m_c;
}
-void TriangleBoundingVolume::setA(const QVector3D &a)
+void TriangleBoundingVolume::setA(const Vector3D &a)
{
m_a = a;
}
-void TriangleBoundingVolume::setB(const QVector3D &b)
+void TriangleBoundingVolume::setB(const Vector3D &b)
{
m_b = b;
}
-void TriangleBoundingVolume::setC(const QVector3D &c)
+void TriangleBoundingVolume::setC(const Vector3D &c)
{
m_c = c;
}
-TriangleBoundingVolume TriangleBoundingVolume::transformed(const QMatrix4x4 &mat) const
+TriangleBoundingVolume TriangleBoundingVolume::transformed(const Matrix4x4 &mat) const
{
- const QVector3D tA = mat * m_a;
- const QVector3D tB = mat * m_b;
- const QVector3D tC = mat * m_c;
+ const Vector3D tA = mat * m_a;
+ const Vector3D tB = mat * m_b;
+ const Vector3D tC = mat * m_c;
return TriangleBoundingVolume(id(), tA, tB, tC);
}
diff --git a/src/render/backend/triangleboundingvolume_p.h b/src/render/backend/triangleboundingvolume_p.h
index 4735a1522..a45a5ed7c 100644
--- a/src/render/backend/triangleboundingvolume_p.h
+++ b/src/render/backend/triangleboundingvolume_p.h
@@ -53,6 +53,7 @@
#include <Qt3DRender/private/qboundingvolume_p.h>
#include <Qt3DCore/qnodeid.h>
+#include <Qt3DCore/private/matrix4x4_p.h>
#include <QVector3D>
QT_BEGIN_NAMESPACE
@@ -62,10 +63,10 @@ namespace Qt3DRender {
namespace Render {
Q_AUTOTEST_EXPORT bool intersectsSegmentTriangle(const RayCasting::QRay3D &ray,
- const QVector3D &a,
- const QVector3D &b,
- const QVector3D &c,
- QVector3D &uvw,
+ const Vector3D &a,
+ const Vector3D &b,
+ const Vector3D &c,
+ Vector3D &uvw,
float &t);
class Q_AUTOTEST_EXPORT TriangleBoundingVolume : public RayCasting::QBoundingVolume
@@ -73,25 +74,25 @@ class Q_AUTOTEST_EXPORT TriangleBoundingVolume : public RayCasting::QBoundingVol
public:
TriangleBoundingVolume();
explicit TriangleBoundingVolume(Qt3DCore::QNodeId id,
- const QVector3D &a,
- const QVector3D &b,
- const QVector3D &c);
+ const Vector3D &a,
+ const Vector3D &b,
+ const Vector3D &c);
Qt3DCore::QNodeId id() const final;
- bool intersects(const RayCasting::QRay3D &ray, QVector3D *q, QVector3D *uvw) const final;
- Type type() const final;
+ bool intersects(const RayCasting::QRay3D &ray, Vector3D *q, Vector3D *uvw) const final;
+ Type type() const final;
- QVector3D a() const;
- QVector3D b() const;
- QVector3D c() const;
+ Vector3D a() const;
+ Vector3D b() const;
+ Vector3D c() const;
- void setA(const QVector3D &a);
- void setB(const QVector3D &b);
- void setC(const QVector3D &c);
+ void setA(const Vector3D &a);
+ void setB(const Vector3D &b);
+ void setC(const Vector3D &c);
- TriangleBoundingVolume transformed(const QMatrix4x4 &mat) const;
+ TriangleBoundingVolume transformed(const Matrix4x4 &mat) const;
- inline TriangleBoundingVolume &transform(const QMatrix4x4 &mat)
+ inline TriangleBoundingVolume &transform(const Matrix4x4 &mat)
{
*this = transformed(mat);
return *this;
@@ -99,7 +100,7 @@ public:
private:
Qt3DCore::QNodeId m_id;
- QVector3D m_a, m_b, m_c;
+ Vector3D m_a, m_b, m_c;
};
} // namespace Render
diff --git a/src/render/backend/trianglesextractor.cpp b/src/render/backend/trianglesextractor.cpp
index e7a36dab3..2ddb425a0 100644
--- a/src/render/backend/trianglesextractor.cpp
+++ b/src/render/backend/trianglesextractor.cpp
@@ -68,7 +68,7 @@ QVector<RayCasting::QBoundingVolume *> TrianglesExtractor::extract(const Qt3DCor
return m_volumes;
}
-void TrianglesExtractor::visit(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c)
+void TrianglesExtractor::visit(uint andx, const Vector3D &a, uint bndx, const Vector3D &b, uint cndx, const Vector3D &c)
{
Q_UNUSED(andx); Q_UNUSED(bndx); Q_UNUSED(cndx);
m_volumes.push_back(new TriangleBoundingVolume(m_nodeId, a, b, c));
diff --git a/src/render/backend/trianglesextractor_p.h b/src/render/backend/trianglesextractor_p.h
index 857c4c638..df4c20466 100644
--- a/src/render/backend/trianglesextractor_p.h
+++ b/src/render/backend/trianglesextractor_p.h
@@ -71,9 +71,9 @@ public:
QVector<RayCasting::QBoundingVolume *> extract(const Qt3DCore::QNodeId id);
private:
- void visit(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b,
- uint cndx, const QVector3D &c) override;
+ void visit(uint andx, const Vector3D &a,
+ uint bndx, const Vector3D &b,
+ uint cndx, const Vector3D &c) override;
GeometryRenderer *m_renderer;
QVector<RayCasting::QBoundingVolume *> m_volumes;
diff --git a/src/render/backend/trianglesvisitor.cpp b/src/render/backend/trianglesvisitor.cpp
index 57538c8d7..87ba7bde9 100644
--- a/src/render/backend/trianglesvisitor.cpp
+++ b/src/render/backend/trianglesvisitor.cpp
@@ -85,11 +85,11 @@ void traverseTrianglesIndexed(index *indices,
TrianglesVisitor* visitor)
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
- QVector3D abc[3];
+ Vector3D abc[3];
while (i < indexInfo.count) {
for (uint u = 0; u < 3; ++u) {
ndx[u] = indices[i + u];
@@ -111,11 +111,11 @@ void traverseTriangles(vertex *vertices,
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
- QVector3D abc[3];
+ Vector3D abc[3];
while (i < vertexInfo.count) {
for (uint u = 0; u < 3; ++u) {
ndx[u] = (i + u);
@@ -147,11 +147,11 @@ void traverseTriangleStripIndexed(index *indices,
TrianglesVisitor* visitor)
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
- QVector3D abc[3];
+ Vector3D abc[3];
while (i < indexInfo.count - 2) {
bool degenerate = false;
for (uint u = 0; u < 3; ++u) {
@@ -178,11 +178,11 @@ void traverseTriangleStrip(vertex *vertices,
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
- QVector3D abc[3];
+ Vector3D abc[3];
while (i < vertexInfo.count - 2) {
for (uint u = 0; u < 3; ++u) {
ndx[u] = (i + u);
@@ -204,11 +204,11 @@ void traverseTriangleFanIndexed(index *indices,
const BufferInfo &vertexInfo,
TrianglesVisitor* visitor)
{
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
- QVector3D abc[3];
+ Vector3D abc[3];
for (uint j = 0; j < maxVerticesDataSize; ++j) {
abc[0][j] = vertices[static_cast<int>(indices[0]) * verticesStride + j];
@@ -234,11 +234,11 @@ void traverseTriangleFan(vertex *vertices,
const BufferInfo &vertexInfo,
TrianglesVisitor* visitor)
{
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
- QVector3D abc[3];
+ Vector3D abc[3];
for (uint j = 0; j < maxVerticesDataSize; ++j) {
abc[0][j] = vertices[j];
@@ -268,11 +268,11 @@ void traverseTriangleAdjacencyIndexed(index *indices,
TrianglesVisitor* visitor)
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
- QVector3D abc[3];
+ Vector3D abc[3];
while (i < indexInfo.count) {
for (uint u = 0; u < 6; u += 2) {
ndx[u / 2] = indices[i + u];
@@ -294,11 +294,11 @@ void traverseTriangleAdjacency(Vertex *vertices,
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(Vertex) : maxVerticesDataSize;
uint ndx[3];
- QVector3D abc[3];
+ Vector3D abc[3];
while (i < vertexInfo.count) {
for (uint u = 0; u < 6; u += 2) {
ndx[u / 2] = (i + u);
@@ -313,10 +313,10 @@ void traverseTriangleAdjacency(Vertex *vertices,
}
template<typename Coordinate>
-QVector4D readCoordinate(const BufferInfo &info, Coordinate *coordinates, uint index)
+Vector4D readCoordinate(const BufferInfo &info, Coordinate *coordinates, uint index)
{
- const uint stride = info.byteStride / sizeof(Coordinate);
- QVector4D ret(0, 0, 0, 1.0f);
+ const uint stride = info.byteStride ? info.byteStride / sizeof(Coordinate) : info.dataSize;
+ Vector4D ret(0, 0, 0, 1.0f);
coordinates += stride * index;
for (uint e = 0; e < info.dataSize; ++e)
ret[e] = coordinates[e];
@@ -340,7 +340,7 @@ typename EnumToType<v>::type *castToType(const QByteArray &u, uint byteOffset)
return reinterpret_cast< typename EnumToType<v>::type *>(u.constData() + byteOffset);
}
-QVector4D readBuffer(const BufferInfo &info, uint index)
+Vector4D readBuffer(const BufferInfo &info, uint index)
{
switch (info.type) {
case QAttribute::Byte:
@@ -362,7 +362,7 @@ QVector4D readBuffer(const BufferInfo &info, uint index)
default:
break;
}
- return QVector4D();
+ return Vector4D();
}
template<typename Index, typename Visitor>
@@ -509,7 +509,7 @@ bool CoordinateReader::setGeometry(const GeometryRenderer *renderer, const QStri
return true;
}
-QVector4D CoordinateReader::getCoordinate(uint vertexIndex)
+Vector4D CoordinateReader::getCoordinate(uint vertexIndex)
{
return readBuffer(m_bufferInfo, vertexIndex);
}
diff --git a/src/render/backend/trianglesvisitor_p.h b/src/render/backend/trianglesvisitor_p.h
index 9428857ac..ee206f1c9 100644
--- a/src/render/backend/trianglesvisitor_p.h
+++ b/src/render/backend/trianglesvisitor_p.h
@@ -54,6 +54,8 @@
#include <Qt3DCore/qnodeid.h>
#include <Qt3DRender/QAttribute>
#include <Qt3DRender/private/bufferutils_p.h>
+#include <Qt3DCore/private/vector3d_p.h>
+#include <Qt3DCore/private/vector4d_p.h>
#include <private/qt3drender_global_p.h>
@@ -81,9 +83,9 @@ public:
void apply(const Qt3DCore::QEntity *entity);
void apply(const GeometryRenderer *renderer, const Qt3DCore::QNodeId id);
- virtual void visit(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b,
- uint cndx, const QVector3D &c) = 0;
+ virtual void visit(uint andx, const Vector3D &a,
+ uint bndx, const Vector3D &b,
+ uint cndx, const Vector3D &c) = 0;
protected:
NodeManagers *m_manager;
@@ -102,7 +104,7 @@ public:
bool setGeometry(const GeometryRenderer *renderer, const QString &attributeName);
- QVector4D getCoordinate(uint vertexIndex);
+ Vector4D getCoordinate(uint vertexIndex);
protected:
NodeManagers *m_manager;
diff --git a/src/render/backend/uniform.cpp b/src/render/backend/uniform.cpp
index 03220a219..41ee24967 100644
--- a/src/render/backend/uniform.cpp
+++ b/src/render/backend/uniform.cpp
@@ -47,10 +47,22 @@ namespace Render {
namespace {
const int qNodeIdTypeId = qMetaTypeId<Qt3DCore::QNodeId>();
+const int qVector3DTypeId = qMetaTypeId<Vector3D>();
+const int qVector4DTypeId = qMetaTypeId<Vector4D>();
+const int qMatrix4x4TypeId = qMetaTypeId<Matrix4x4>();
// glUniform*fv/glUniform*iv/glUniform*uiv -> only handles sizeof(float)/sizeof(int)
int byteSizeForMetaType(int type)
{
+ if (type == qMatrix4x4TypeId)
+ return sizeof(Matrix4x4);
+ if (type == qVector3DTypeId)
+ return sizeof(Vector3D);
+ if (type == qVector4DTypeId)
+ return sizeof(Vector4D);
+ if (type == qNodeIdTypeId)
+ return sizeof(Qt3DCore::QNodeId);
+
switch (type) {
case QMetaType::Bool:
case QMetaType::Int:
@@ -88,9 +100,9 @@ int byteSizeForMetaType(int type)
case QMetaType::QVector4D:
case QMetaType::QColor:
return 4 * sizeof(float);
-
case QMetaType::QMatrix4x4:
return 16 * sizeof(float);
+
default:
Q_UNREACHABLE();
return -1;
@@ -102,11 +114,22 @@ int byteSizeForMetaType(int type)
UniformValue UniformValue::fromVariant(const QVariant &variant)
{
// Texture/Buffer case
- if (variant.userType() == qNodeIdTypeId)
+ const int type = variant.userType();
+
+ if (type == qNodeIdTypeId)
return UniformValue(variant.value<Qt3DCore::QNodeId>());
+ if (type == qMatrix4x4TypeId)
+ return UniformValue(variant.value<Matrix4x4>());
+
+ if (type == qVector3DTypeId)
+ return UniformValue(variant.value<Vector3D>());
+
+ if (type == qVector4DTypeId)
+ return UniformValue(variant.value<Vector4D>());
+
UniformValue v;
- switch (variant.userType()) {
+ switch (type) {
case QMetaType::Bool:
v.data<bool>()[0] = variant.toBool();
break;
@@ -209,6 +232,11 @@ UniformValue UniformValue::fromVariant(const QVariant &variant)
break;
const int listEntryType = variants.first().userType();
+
+ // array of textures
+ if (listEntryType == qNodeIdTypeId)
+ v.m_valueType = NodeId;
+
const int stride = byteSizeForMetaType(listEntryType) / sizeof(float);
// Resize v.m_data
v.m_data.resize(stride * variants.size());
diff --git a/src/render/backend/uniform_p.h b/src/render/backend/uniform_p.h
index e0d8fedeb..e31aaa609 100644
--- a/src/render/backend/uniform_p.h
+++ b/src/render/backend/uniform_p.h
@@ -53,6 +53,9 @@
#include <qt3drender_global.h>
#include <Qt3DCore/qnodeid.h>
+#include <Qt3DCore/private/matrix4x4_p.h>
+#include <Qt3DCore/private/vector3d_p.h>
+#include <Qt3DCore/private/vector4d_p.h>
#include <QMatrix4x4>
#include <QVector2D>
@@ -111,11 +114,6 @@ public:
BufferValue
};
- struct Texture {
- int textureId = 0; // Set first so that glUniform1iv will work
- Qt3DCore::QNodeId nodeId;
- };
-
// UniformValue implicitely converts doubles to floats to ensure
// correct rendering behavior for the cases where Qt3D parameters created from
// a double or QVariant(double) are used to fill uniform values that in reality
@@ -135,8 +133,8 @@ public:
UniformValue(double d) : UniformValue() { data<float>()[0] = d; } // Double to float conversion
UniformValue(bool b) : UniformValue() { data<bool>()[0] = b; }
UniformValue(const QVector2D &vec2) : UniformValue() { memcpy(m_data.data(), &vec2, sizeof(QVector2D)); }
- UniformValue(const QVector3D &vec3) : UniformValue() { memcpy(m_data.data(), &vec3, sizeof(QVector3D)); }
- UniformValue(const QVector4D &vec4) : m_data(4) { memcpy(m_data.data(), &vec4, sizeof(QVector4D)); }
+ UniformValue(const Vector3D &vec3) : UniformValue() { memcpy(m_data.data(), &vec3, sizeof(Vector3D)); }
+ UniformValue(const Vector4D &vec4) : m_data(sizeof(Vector4D) / sizeof(float)) { memcpy(m_data.data(), &vec4, sizeof(Vector4D)); }
UniformValue(const QMatrix3x3 &mat33)
: m_data(9)
@@ -145,12 +143,22 @@ public:
memcpy(m_data.data(), mat33.constData(), 9 * sizeof(float));
}
+ // We don t want the QMatrix4x4 builder to use sizeof since QMatrix4x4 contains a type flag
+#if defined(__SSE2__) || defined(__AVX2__)
+ UniformValue(const Matrix4x4 &mat44)
+ : m_data(sizeof(Matrix4x4) / sizeof(float))
+ {
+ // Use constData because we want column-major layout
+ memcpy(m_data.data(), &mat44, sizeof(Matrix4x4));
+ }
+#else
UniformValue(const QMatrix4x4 &mat44)
: m_data(16)
{
// Use constData because we want column-major layout
memcpy(m_data.data(), mat44.constData(), 16 * sizeof(float));
}
+#endif
UniformValue(const QVector<QMatrix4x4> &v)
: m_data(16 * v.size())
@@ -164,6 +172,13 @@ public:
}
}
+ // Reserve data to be filled in later
+ UniformValue(int byteSize, ValueType valueType)
+ : m_data(byteSize / sizeof(float))
+ , m_valueType(valueType)
+ {
+ }
+
// For nodes which will later be replaced by a Texture or Buffer
UniformValue(Qt3DCore::QNodeId id)
: UniformValue()
@@ -172,14 +187,6 @@ public:
memcpy(m_data.data(), &id, sizeof(Qt3DCore::QNodeId));
}
- // For textures
- UniformValue(UniformValue::Texture t)
- : UniformValue()
- {
- m_valueType = TextureValue;
- memcpy(m_data.data(), &t, sizeof(Texture));
- }
-
ValueType valueType() const { return m_valueType; }
UniformType storedType() const { return m_storedType; }
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 3b63f43eb..5e1fea288 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -153,6 +153,8 @@
#include <private/qrenderpluginfactory_p.h>
#include <private/qrenderplugin_p.h>
+#include <private/framegraphvisitor_p.h>
+#include <private/platformsurfacefilter_p.h>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>
@@ -188,7 +190,12 @@ QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type)
, m_initialized(false)
, m_renderType(type)
, m_offscreenHelper(nullptr)
+ , m_blockingRendermode(false)
{
+ // The blocking mode can be enabled to make sure we render even while
+ // waiting for geometries to load. This is necessary if we want
+ // to call doRender for every QtQuick frame when using Scene3D frame.
+ m_blockingRendermode = !qgetenv("SCENE3D_BLOCKING_RENDERMODE").isEmpty();
m_instances.append(this);
loadSceneParsers();
}
@@ -374,6 +381,11 @@ void QRenderAspectPrivate::registerBackendType(const QMetaObject &obj,
q->registerBackendType(obj, functor);
}
+void QRenderAspectPrivate::abortRenderJobs()
+{
+ m_renderer->abortRenderJobs();
+}
+
/*!
* The constructor creates a new QRenderAspect::QRenderAspect instance with the
* specified \a parent.
@@ -412,9 +424,17 @@ void QRenderAspectPrivate::renderInitialize(QOpenGLContext *context)
}
/*! \internal */
-void QRenderAspectPrivate::renderSynchronous(bool blocking)
+void QRenderAspectPrivate::tryRenderSynchronous()
{
- m_renderer->doRender(blocking);
+ // If the render aspect is slow for some reason and does not build jobs
+ // immediately, we might want to wait for it to make sure we render
+ // one Qt3D frame for each QtQuick frame. If blocking mode is enabled,
+ // we will wait a short time.
+ // TODO By allowing the aspect thread to skip a couple of frames that
+ // are not rendered without being in sync with the QtQuick scene graph,
+ // we can make this into a blocking call and get rid of the timeout.
+ if (m_renderer->tryWaitForRenderJobs(m_blockingRendermode ? 20 : 0))
+ m_renderer->lockSurfaceAndRender();
}
/*!
@@ -450,36 +470,16 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
// asked for jobs to execute (this function). If that is the case, the RenderSettings will
// be null and we should not generate any jobs.
if (d->m_renderer->isRunning() && d->m_renderer->settings()) {
-
Render::NodeManagers *manager = d->m_renderer->nodeManagers();
- QAspectJobPtr textureLoadingSync = d->m_renderer->syncTextureLoadingJob();
- textureLoadingSync->removeDependency(QWeakPointer<QAspectJob>());
-
- // Launch texture generator jobs
- const QVector<QTextureImageDataGeneratorPtr> pendingImgGen = manager->textureImageDataManager()->pendingGenerators();
- for (const QTextureImageDataGeneratorPtr &imgGen : pendingImgGen) {
- auto loadTextureJob = Render::LoadTextureDataJobPtr::create(imgGen);
- textureLoadingSync->addDependency(loadTextureJob);
- loadTextureJob->setNodeManagers(manager);
- jobs.append(loadTextureJob);
- }
- const QVector<QTextureGeneratorPtr> pendingTexGen = manager->textureDataManager()->pendingGenerators();
- for (const QTextureGeneratorPtr &texGen : pendingTexGen) {
- auto loadTextureJob = Render::LoadTextureDataJobPtr::create(texGen);
- textureLoadingSync->addDependency(loadTextureJob);
- loadTextureJob->setNodeManagers(manager);
- jobs.append(loadTextureJob);
- }
-
- // Launch skeleton loader jobs. We join on the syncTextureLoadingJob for now
- // which should likely be renamed to something more generic or we introduce
- // another synchronizing job for skeleton loading
+ QAspectJobPtr assetLoadingSync = d->m_renderer->syncSkeletonLoadingJob();
+ assetLoadingSync->removeDependency(QWeakPointer<QAspectJob>());
+ // Launch skeleton loader jobs
const QVector<Render::HSkeleton> skeletonsToLoad =
manager->skeletonManager()->dirtySkeletons(Render::SkeletonManager::SkeletonDataDirty);
for (const auto &skeletonHandle : skeletonsToLoad) {
auto loadSkeletonJob = Render::LoadSkeletonJobPtr::create(skeletonHandle);
loadSkeletonJob->setNodeManagers(manager);
- textureLoadingSync->addDependency(loadSkeletonJob);
+ assetLoadingSync->addDependency(loadSkeletonJob);
jobs.append(loadSkeletonJob);
}
@@ -510,12 +510,16 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
return jobs;
}
- // Traverse the current framegraph and create jobs to populate
- // RenderBins with RenderCommands
- // All jobs needed to create the frame and their dependencies are set by
- // renderBinJobs()
- const QVector<QAspectJobPtr> renderBinJobs = d->m_renderer->renderBinJobs();
- jobs.append(renderBinJobs);
+ // Let the rendering thread know that we are ready to spawn jobs if it
+ // can promise us that it will in fact call doRender.
+ if (d->m_renderer->releaseRendererAndRequestPromiseToRender()) {
+ // Traverse the current framegraph and create jobs to populate
+ // RenderBins with RenderCommands
+ // All jobs needed to create the frame and their dependencies are set by
+ // renderBinJobs()
+ const QVector<QAspectJobPtr> renderBinJobs = d->m_renderer->renderBinJobs();
+ jobs.append(renderBinJobs);
+ }
}
return jobs;
}
diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h
index 26ca091f6..d18ce8b4f 100644
--- a/src/render/frontend/qrenderaspect_p.h
+++ b/src/render/frontend/qrenderaspect_p.h
@@ -90,9 +90,10 @@ public:
void loadSceneParsers();
void loadRenderPlugin(const QString &pluginName);
void renderInitialize(QOpenGLContext *context);
- void renderSynchronous(bool blocking = false);
+ void tryRenderSynchronous();
void renderShutdown();
void registerBackendType(const QMetaObject &, const Qt3DCore::QBackendNodeMapperPtr &functor);
+ void abortRenderJobs();
QVector<Qt3DCore::QAspectJobPtr> createGeometryRendererJobs();
Render::NodeManagers *m_nodeManagers;
@@ -104,6 +105,7 @@ public:
QVector<Render::QRenderPlugin *> m_renderPlugins;
QRenderAspect::RenderType m_renderType;
Render::OffscreenSurfaceHelper *m_offscreenHelper;
+ bool m_blockingRendermode;
static QMutex m_pluginLock;
static QVector<QString> m_pluginConfig;
diff --git a/src/render/frontend/sphere.cpp b/src/render/frontend/sphere.cpp
index 2c22e0da4..740626163 100644
--- a/src/render/frontend/sphere.cpp
+++ b/src/render/frontend/sphere.cpp
@@ -53,18 +53,18 @@ namespace {
// Intersects ray r = p + td, |d| = 1, with sphere s and, if intersecting,
// returns true and intersection point q; false otherwise
-bool intersectRaySphere(const Qt3DRender::RayCasting::QRay3D &ray, const Qt3DRender::Render::Sphere &s, QVector3D *q = nullptr)
+bool intersectRaySphere(const Qt3DRender::RayCasting::QRay3D &ray, const Qt3DRender::Render::Sphere &s, Vector3D *q = nullptr)
{
- const QVector3D p = ray.origin();
- const QVector3D d = ray.direction();
- const QVector3D m = p - s.center();
- const float c = QVector3D::dotProduct(m, m) - s.radius() * s.radius();
+ const Vector3D p = ray.origin();
+ const Vector3D d = ray.direction();
+ const Vector3D m = p - s.center();
+ const float c = Vector3D::dotProduct(m, m) - s.radius() * s.radius();
// If there is definitely at least one real root, there must be an intersection
if (q == nullptr && c <= 0.0f)
return true;
- const float b = QVector3D::dotProduct(m, d);
+ const float b = Vector3D::dotProduct(m, d);
// Exit if r’s origin outside s (c > 0) and r pointing away from s (b > 0)
if (c > 0.0f && b > 0.0f)
return false;
@@ -89,12 +89,12 @@ bool intersectRaySphere(const Qt3DRender::RayCasting::QRay3D &ray, const Qt3DRen
return true;
}
-inline QPair<int, int> findExtremePoints(const QVector<QVector3D> &points)
+inline QPair<int, int> findExtremePoints(const QVector<Vector3D> &points)
{
// Find indices of extreme points along x, y, and z axes
int xMin = 0, xMax = 0, yMin = 0, yMax = 0, zMin = 0, zMax = 0;
for (int i = 1; i < points.size(); ++i) {
- const QVector3D &p = points.at(i);
+ const Vector3D &p = points.at(i);
if (p.x() < points[xMin].x())
xMin = i;
if (p.x() > points[xMax].x())
@@ -124,20 +124,20 @@ inline QPair<int, int> findExtremePoints(const QVector<QVector3D> &points)
return extremeIndices;
}
-inline void sphereFromExtremePoints(Qt3DRender::Render::Sphere &s, const QVector<QVector3D> &points)
+inline void sphereFromExtremePoints(Qt3DRender::Render::Sphere &s, const QVector<Vector3D> &points)
{
// Find two most separated points on any of the basis vectors
QPair<int, int> extremeIndices = findExtremePoints(points);
// Construct sphere to contain these two points
- const QVector3D &p = points.at(extremeIndices.first);
- const QVector3D &q = points.at(extremeIndices.second);
- const QVector3D c = 0.5f * (p + q);
+ const Vector3D &p = points.at(extremeIndices.first);
+ const Vector3D &q = points.at(extremeIndices.second);
+ const Vector3D c = 0.5f * (p + q);
s.setCenter(c);
s.setRadius((q - c).length());
}
-inline void constructRitterSphere(Qt3DRender::Render::Sphere &s, const QVector<QVector3D> &points)
+inline void constructRitterSphere(Qt3DRender::Render::Sphere &s, const QVector<Vector3D> &points)
{
// Calculate the sphere encompassing two axially extreme points
sphereFromExtremePoints(s, points);
@@ -154,22 +154,22 @@ namespace Render {
const float Sphere::ms_epsilon = 1.0e-7f;
-Sphere Sphere::fromPoints(const QVector<QVector3D> &points)
+Sphere Sphere::fromPoints(const QVector<Vector3D> &points)
{
Sphere s;
s.initializeFromPoints(points);
return s;
}
-void Sphere::initializeFromPoints(const QVector<QVector3D> &points)
+void Sphere::initializeFromPoints(const QVector<Vector3D> &points)
{
if (!points.isEmpty())
constructRitterSphere(*this, points);
}
-void Sphere::expandToContain(const QVector3D &p)
+void Sphere::expandToContain(const Vector3D &p)
{
- const QVector3D d = p - m_center;
+ const Vector3D d = p - m_center;
const float dist2 = d.lengthSquared();
if (dist2 > m_radius * m_radius) {
@@ -184,7 +184,7 @@ void Sphere::expandToContain(const QVector3D &p)
void Sphere::expandToContain(const Sphere &sphere)
{
- const QVector3D d(sphere.m_center - m_center);
+ const Vector3D d(sphere.m_center - m_center);
const float dist2 = d.lengthSquared();
const float dr = sphere.m_radius - m_radius;
@@ -204,16 +204,16 @@ void Sphere::expandToContain(const Sphere &sphere)
}
}
-Sphere Sphere::transformed(const QMatrix4x4 &mat) const
+Sphere Sphere::transformed(const Matrix4x4 &mat) const
{
// Transform extremities in x, y, and z directions to find extremities
// of the resulting ellipsoid
- QVector3D x = mat.map(m_center + QVector3D(m_radius, 0.0f, 0.0f));
- QVector3D y = mat.map(m_center + QVector3D(0.0f, m_radius, 0.0f));
- QVector3D z = mat.map(m_center + QVector3D(0.0f, 0.0f, m_radius));
+ Vector3D x = mat.map(m_center + Vector3D(m_radius, 0.0f, 0.0f));
+ Vector3D y = mat.map(m_center + Vector3D(0.0f, m_radius, 0.0f));
+ Vector3D z = mat.map(m_center + Vector3D(0.0f, 0.0f, m_radius));
// Transform center and find maximum radius of ellipsoid
- QVector3D c = mat.map(m_center);
+ Vector3D c = mat.map(m_center);
float rSquared = qMax(qMax((x - c).lengthSquared(), (y - c).lengthSquared()), (z - c).lengthSquared());
return Sphere(c, sqrt(rSquared), id());
}
@@ -223,7 +223,7 @@ Qt3DCore::QNodeId Sphere::id() const
return m_id;
}
-bool Sphere::intersects(const RayCasting::QRay3D &ray, QVector3D *q, QVector3D *uvw) const
+bool Sphere::intersects(const RayCasting::QRay3D &ray, Vector3D *q, Vector3D *uvw) const
{
Q_UNUSED(uvw);
return intersectRaySphere(ray, *this, q);
diff --git a/src/render/frontend/sphere_p.h b/src/render/frontend/sphere_p.h
index 1590b2f29..0592d8d05 100644
--- a/src/render/frontend/sphere_p.h
+++ b/src/render/frontend/sphere_p.h
@@ -53,10 +53,10 @@
#include <Qt3DRender/private/qt3drender_global_p.h>
#include <Qt3DCore/qnodeid.h>
+#include <Qt3DCore/private/matrix4x4_p.h>
#include <Qt3DRender/private/boundingsphere_p.h>
#include <QMatrix4x4>
-#include <QVector3D>
QT_BEGIN_NAMESPACE
@@ -73,58 +73,58 @@ public:
, m_id(i)
{}
- inline Sphere(const QVector3D &c, float r, Qt3DCore::QNodeId i = Qt3DCore::QNodeId())
+ inline Sphere(const Vector3D &c, float r, Qt3DCore::QNodeId i = Qt3DCore::QNodeId())
: m_center(c)
, m_radius(r)
, m_id(i)
{}
- void setCenter(const QVector3D &c);
- QVector3D center() const override;
+ void setCenter(const Vector3D &c);
+ Vector3D center() const override;
- inline bool isNull() { return m_center == QVector3D() && m_radius == 0.0f; }
+ inline bool isNull() { return m_center == Vector3D() && m_radius == 0.0f; }
void setRadius(float r);
float radius() const override;
void clear();
- void initializeFromPoints(const QVector<QVector3D> &points);
- void expandToContain(const QVector3D &point);
- inline void expandToContain(const QVector<QVector3D> &points)
+ void initializeFromPoints(const QVector<Vector3D> &points);
+ void expandToContain(const Vector3D &point);
+ inline void expandToContain(const QVector<Vector3D> &points)
{
- for (const QVector3D &p : points)
+ for (const Vector3D &p : points)
expandToContain(p);
}
void expandToContain(const Sphere &sphere);
- Sphere transformed(const QMatrix4x4 &mat) const;
- inline Sphere &transform(const QMatrix4x4 &mat)
+ Sphere transformed(const Matrix4x4 &mat) const;
+ inline Sphere &transform(const Matrix4x4 &mat)
{
*this = transformed(mat);
return *this;
}
Qt3DCore::QNodeId id() const final;
- bool intersects(const RayCasting::QRay3D &ray, QVector3D *q, QVector3D *uvw = nullptr) const final;
+ bool intersects(const RayCasting::QRay3D &ray, Vector3D *q, Vector3D *uvw = nullptr) const final;
Type type() const final;
- static Sphere fromPoints(const QVector<QVector3D> &points);
+ static Sphere fromPoints(const QVector<Vector3D> &points);
private:
- QVector3D m_center;
+ Vector3D m_center;
float m_radius;
Qt3DCore::QNodeId m_id;
static const float ms_epsilon;
};
-inline void Sphere::setCenter(const QVector3D &c)
+inline void Sphere::setCenter(const Vector3D &c)
{
m_center = c;
}
-inline QVector3D Sphere::center() const
+inline Vector3D Sphere::center() const
{
return m_center;
}
@@ -141,15 +141,15 @@ inline float Sphere::radius() const
inline void Sphere::clear()
{
- m_center = QVector3D();
+ m_center = Vector3D();
m_radius = 0.0f;
}
inline bool intersects(const Sphere &a, const Sphere &b)
{
// Calculate squared distance between sphere centers
- const QVector3D d = a.center() - b.center();
- const float distSq = QVector3D::dotProduct(d, d);
+ const Vector3D d = a.center() - b.center();
+ const float distSq = Vector3D::dotProduct(d, d);
// Spheres intersect if squared distance is less than squared
// sum of radii
diff --git a/src/render/geometry/geometryrenderer.cpp b/src/render/geometry/geometryrenderer.cpp
index ea059c6ee..a73589507 100644
--- a/src/render/geometry/geometryrenderer.cpp
+++ b/src/render/geometry/geometryrenderer.cpp
@@ -42,6 +42,8 @@
#include <Qt3DRender/private/qboundingvolume_p.h>
#include <Qt3DRender/private/qgeometryrenderer_p.h>
#include <Qt3DRender/private/qmesh_p.h>
+#include <Qt3DRender/private/managers_p.h>
+#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp
index 9e8e3d610..5c3128f30 100644
--- a/src/render/graphicshelpers/graphicscontext.cpp
+++ b/src/render/graphicshelpers/graphicscontext.cpp
@@ -232,13 +232,10 @@ void GraphicsContext::resolveRenderTargetFormat()
#undef RGBA_BITS
}
-bool GraphicsContext::beginDrawing(QSurface *surface)
+void GraphicsContext::beginDrawing()
{
- Q_ASSERT(surface);
Q_ASSERT(m_gl);
- m_surface = surface;
-
// TO DO: Find a way to make to pause work if the window is not exposed
// if (m_surface && m_surface->surfaceClass() == QSurface::Window) {
// qDebug() << Q_FUNC_INFO << 1;
@@ -247,12 +244,6 @@ bool GraphicsContext::beginDrawing(QSurface *surface)
// qDebug() << Q_FUNC_INFO << 2;
// }
- // Makes the surface current on the OpenGLContext
- // and sets the right glHelper
- m_ownCurrent = !(m_gl->surface() == m_surface);
- if (m_ownCurrent && !makeCurrent(m_surface))
- return false;
-
// TODO: cache surface format somewhere rather than doing this every time render surface changes
resolveRenderTargetFormat();
@@ -293,8 +284,6 @@ bool GraphicsContext::beginDrawing(QSurface *surface)
const int shaderPurgePeriod = 600;
if (callCount % shaderPurgePeriod == 0)
m_shaderCache.purge();
-
- return true;
}
void GraphicsContext::clearBackBuffer(QClearBuffers::BufferTypeFlags buffers)
@@ -453,6 +442,7 @@ bool GraphicsContext::makeCurrent(QSurface *surface)
m_glHelper = resolveHighestOpenGLFunctions();
m_glHelpers.insert(surface, m_glHelper);
}
+ m_surface = surface;
return true;
}
@@ -509,14 +499,14 @@ void GraphicsContext::introspectShaderInterface(Shader *shader, QOpenGLShaderPro
void GraphicsContext::loadShader(Shader *shader, ShaderManager *manager)
{
- QOpenGLShaderProgram *shaderProgram = m_shaderCache.getShaderProgramAndAddRef(shader->dna(), shader->peerId());
- if (!shaderProgram) {
+ bool wasPresent = false;
+ QOpenGLShaderProgram *shaderProgram = m_shaderCache.getShaderProgramAndAddRef(shader->dna(), shader->peerId(), &wasPresent);
+ if (!shaderProgram && !wasPresent) {
// No matching QOpenGLShader in the cache so create one
shaderProgram = createShaderProgram(shader);
- // Store in cache
- if (shaderProgram)
- m_shaderCache.insert(shader->dna(), shader->peerId(), shaderProgram);
+ // Store in cache (even when failed and shaderProgram is null)
+ m_shaderCache.insert(shader->dna(), shader->peerId(), shaderProgram);
}
// Ensure the Shader node knows about the program interface
@@ -544,7 +534,6 @@ void GraphicsContext::loadShader(Shader *shader, ShaderManager *manager)
shader->setGraphicsContext(this);
shader->setLoaded(true);
- shader->markDirty(AbstractRenderer::AllDirty);
}
}
@@ -1224,7 +1213,7 @@ bool GraphicsContext::setParameters(ShaderParameterPack &parameterPack)
UniformValue &texUniform = uniformValues[namedTex.glslNameId];
Q_ASSERT(texUniform.valueType() == UniformValue::TextureValue);
const int texUnit = activateTexture(TextureScopeMaterial, t);
- texUniform.data<UniformValue::Texture>()->textureId = texUnit;
+ texUniform.data<int>()[namedTex.uniformArrayIndex] = texUnit;
// if the texture data from generators may not be available yet,
// make sure that the next frame is rendered
if (texUnit == -1)
@@ -1274,11 +1263,10 @@ bool GraphicsContext::setParameters(ShaderParameterPack &parameterPack)
for (const ShaderUniform &uniform : activeUniforms) {
// We can use [] as we are sure the the uniform wouldn't
// be un activeUniforms if there wasn't a matching value
- const auto &v = values[uniform.m_nameId];
+ const UniformValue &v = values[uniform.m_nameId];
// skip invalid textures
- if (v.valueType() == UniformValue::TextureValue &&
- v.constData<UniformValue::Texture>()->textureId == -1)
+ if (v.valueType() == UniformValue::TextureValue && *v.constData<int>() == -1)
continue;
applyUniform(uniform, v);
diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h
index 24b08e45e..bca841f53 100644
--- a/src/render/graphicshelpers/graphicscontext_p.h
+++ b/src/render/graphicshelpers/graphicscontext_p.h
@@ -113,7 +113,7 @@ public:
int id() const; // unique, small integer ID of this context
- bool beginDrawing(QSurface *surface);
+ void beginDrawing();
void clearBackBuffer(QClearBuffers::BufferTypeFlags buffers);
void endDrawing(bool swapBuffers);
diff --git a/src/render/jobs/abstractpickingjob.cpp b/src/render/jobs/abstractpickingjob.cpp
index 417ac6b65..ccb190cff 100644
--- a/src/render/jobs/abstractpickingjob.cpp
+++ b/src/render/jobs/abstractpickingjob.cpp
@@ -48,6 +48,8 @@
#include <Qt3DRender/private/rendersettings_p.h>
#include <Qt3DRender/private/trianglesvisitor_p.h>
#include <Qt3DRender/private/job_common_p.h>
+#include <QtGui/qoffscreensurface.h>
+#include <QtGui/qwindow.h>
QT_BEGIN_NAMESPACE
@@ -89,12 +91,12 @@ void AbstractPickingJob::run()
runHelper();
}
-RayCasting::QRay3D AbstractPickingJob::intersectionRay(const QPoint &pos, const QMatrix4x4 &viewMatrix,
- const QMatrix4x4 &projectionMatrix, const QRect &viewport)
+RayCasting::QRay3D AbstractPickingJob::intersectionRay(const QPoint &pos, const Matrix4x4 &viewMatrix,
+ const Matrix4x4 &projectionMatrix, const QRect &viewport)
{
- QVector3D nearPos = QVector3D(pos.x(), pos.y(), 0.0f);
+ Vector3D nearPos = Vector3D(pos.x(), pos.y(), 0.0f);
nearPos = nearPos.unproject(viewMatrix, projectionMatrix, viewport);
- QVector3D farPos = QVector3D(pos.x(), pos.y(), 1.0f);
+ Vector3D farPos = Vector3D(pos.x(), pos.y(), 1.0f);
farPos = farPos.unproject(viewMatrix, projectionMatrix, viewport);
return RayCasting::QRay3D(nearPos,
@@ -115,18 +117,39 @@ QRect AbstractPickingJob::windowViewport(const QSize &area, const QRectF &relati
return relativeViewport.toRect();
}
-RayCasting::QRay3D AbstractPickingJob::rayForViewportAndCamera(const QSize &area,
- const QPoint &pos,
- const QRectF &relativeViewport,
- const Qt3DCore::QNodeId cameraId) const
+RayCasting::QRay3D AbstractPickingJob::rayForViewportAndCamera(const PickingUtils::ViewportCameraAreaDetails &vca,
+ QObject *eventSource,
+ const QPoint &pos) const
{
- QMatrix4x4 viewMatrix;
- QMatrix4x4 projectionMatrix;
- Render::CameraLens::viewMatrixForCamera(m_manager->renderNodesManager(), cameraId, viewMatrix, projectionMatrix);
- const QRect viewport = windowViewport(area, relativeViewport);
+ static RayCasting::QRay3D invalidRay({}, {}, 0.f);
+ Matrix4x4 viewMatrix;
+ Matrix4x4 projectionMatrix;
+ Render::CameraLens::viewMatrixForCamera(m_manager->renderNodesManager(),
+ vca.cameraId,
+ viewMatrix,
+ projectionMatrix);
+ const QRect viewport = windowViewport(vca.area, vca.viewport);
+
+ if (vca.area.isValid() && !viewport.contains(pos))
+ return invalidRay;
+ if (vca.surface) {
+ QSurface *surface = nullptr;
+ if (eventSource) {
+ QWindow *window = qobject_cast<QWindow *>(eventSource);
+ if (window) {
+ surface = static_cast<QSurface *>(window);
+ } else {
+ QOffscreenSurface *offscreen = qobject_cast<QOffscreenSurface *>(eventSource);
+ if (offscreen)
+ surface = static_cast<QSurface *>(offscreen);
+ }
+ }
+ if (surface && vca.surface != surface)
+ return invalidRay;
+ }
// In GL the y is inverted compared to Qt
- const QPoint glCorrectPos = QPoint(pos.x(), area.isValid() ? area.height() - pos.y() : pos.y());
+ const QPoint glCorrectPos = QPoint(pos.x(), vca.area.isValid() ? vca.area.height() - pos.y() : pos.y());
const auto ray = intersectionRay(glCorrectPos, viewMatrix, projectionMatrix, viewport);
return ray;
}
diff --git a/src/render/jobs/abstractpickingjob_p.h b/src/render/jobs/abstractpickingjob_p.h
index b527d754a..059c87aa7 100644
--- a/src/render/jobs/abstractpickingjob_p.h
+++ b/src/render/jobs/abstractpickingjob_p.h
@@ -56,6 +56,7 @@
#include <Qt3DRender/private/handle_types_p.h>
#include <Qt3DRender/private/qboundingvolumeprovider_p.h>
#include <Qt3DRender/private/qcollisionqueryresult_p.h>
+#include <Qt3DRender/private/pickboundingvolumeutils_p.h>
QT_BEGIN_NAMESPACE
@@ -84,8 +85,8 @@ public:
// public for unit tests
virtual bool runHelper() = 0;
static RayCasting::QRay3D intersectionRay(const QPoint &pos,
- const QMatrix4x4 &viewMatrix,
- const QMatrix4x4 &projectionMatrix,
+ const Matrix4x4 &viewMatrix,
+ const Matrix4x4 &projectionMatrix,
const QRect &viewport);
protected:
@@ -99,10 +100,9 @@ protected:
bool m_oneEnabledAtLeast;
QRect windowViewport(const QSize &area, const QRectF &relativeViewport) const;
- RayCasting::QRay3D rayForViewportAndCamera(const QSize &area,
- const QPoint &pos,
- const QRectF &relativeViewport,
- const Qt3DCore::QNodeId cameraId) const;
+ RayCasting::QRay3D rayForViewportAndCamera(const PickingUtils::ViewportCameraAreaDetails &vca,
+ QObject *eventSource,
+ const QPoint &pos) const;
};
} // namespace Render
diff --git a/src/render/jobs/calcboundingvolumejob.cpp b/src/render/jobs/calcboundingvolumejob.cpp
index 021478396..841a158b6 100644
--- a/src/render/jobs/calcboundingvolumejob.cpp
+++ b/src/render/jobs/calcboundingvolumejob.cpp
@@ -88,9 +88,10 @@ public:
int primitiveRestartIndex)
{
FindExtremePoints findExtremePoints(m_manager);
- if (!findExtremePoints.apply(positionAttribute, indexAttribute,
- drawVertexCount, primitiveRestartEnabled, primitiveRestartIndex))
+ if (!findExtremePoints.apply(positionAttribute, indexAttribute, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex)) {
return false;
+ }
// Calculate squared distance for the pairs of points
const float xDist2 = (findExtremePoints.xMaxPt - findExtremePoints.xMinPt).lengthSquared();
@@ -98,8 +99,8 @@ public:
const float zDist2 = (findExtremePoints.zMaxPt - findExtremePoints.zMinPt).lengthSquared();
// Select most distant pair
- QVector3D p = findExtremePoints.xMinPt;
- QVector3D q = findExtremePoints.xMaxPt;
+ Vector3D p = findExtremePoints.xMinPt;
+ Vector3D q = findExtremePoints.xMaxPt;
if (yDist2 > xDist2 && yDist2 > zDist2) {
p = findExtremePoints.yMinPt;
q = findExtremePoints.yMaxPt;
@@ -109,13 +110,13 @@ public:
q = findExtremePoints.zMaxPt;
}
- const QVector3D c = 0.5f * (p + q);
+ const Vector3D c = 0.5f * (p + q);
m_volume.setCenter(c);
m_volume.setRadius((q - c).length());
ExpandSphere expandSphere(m_manager, m_volume);
- if (!expandSphere.apply(positionAttribute, indexAttribute,
- drawVertexCount, primitiveRestartEnabled, primitiveRestartIndex))
+ if (!expandSphere.apply(positionAttribute, indexAttribute, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex))
return false;
return true;
@@ -134,40 +135,40 @@ private:
{ }
float xMin, xMax, yMin, yMax, zMin, zMax;
- QVector3D xMinPt, xMaxPt, yMinPt, yMaxPt, zMinPt, zMaxPt;
+ Vector3D xMinPt, xMaxPt, yMinPt, yMaxPt, zMinPt, zMaxPt;
void visit(uint ndx, float x, float y, float z) override
{
if (ndx) {
if (x < xMin) {
xMin = x;
- xMinPt = QVector3D(x, y, z);
+ xMinPt = Vector3D(x, y, z);
}
if (x > xMax) {
xMax = x;
- xMaxPt = QVector3D(x, y, z);
+ xMaxPt = Vector3D(x, y, z);
}
if (y < yMin) {
yMin = y;
- yMinPt = QVector3D(x, y, z);
+ yMinPt = Vector3D(x, y, z);
}
if (y > yMax) {
yMax = y;
- yMaxPt = QVector3D(x, y, z);
+ yMaxPt = Vector3D(x, y, z);
}
if (z < zMin) {
zMin = z;
- zMinPt = QVector3D(x, y, z);
+ zMinPt = Vector3D(x, y, z);
}
if (z > zMax) {
zMax = z;
- zMaxPt = QVector3D(x, y, z);
+ zMaxPt = Vector3D(x, y, z);
}
} else {
xMin = xMax = x;
yMin = yMax = y;
zMin = zMax = z;
- xMinPt = xMaxPt = yMinPt = yMaxPt = zMinPt = zMaxPt = QVector3D(x, y, z);
+ xMinPt = xMaxPt = yMinPt = yMaxPt = zMinPt = zMaxPt = Vector3D(x, y, z);
}
}
};
@@ -183,7 +184,7 @@ private:
void visit(uint ndx, float x, float y, float z) override
{
Q_UNUSED(ndx);
- m_volume.expandToContain(QVector3D(x, y, z));
+ m_volume.expandToContain(Vector3D(x, y, z));
}
};
};
@@ -197,7 +198,7 @@ void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
return;
GeometryRenderer *gRenderer = node->renderComponent<GeometryRenderer>();
- if (gRenderer) {
+ if (gRenderer && gRenderer->primitiveType() != QGeometryRenderer::Patches) {
Geometry *geom = manager->lookupResource<Geometry, GeometryManager>(gRenderer->geometryId());
if (geom) {
@@ -265,18 +266,16 @@ void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
// in a job executed after this one
// We need to recompute the bounding volume
// If anything in the GeometryRenderer has changed
- if (buf->isDirty() ||
- node->isBoundingVolumeDirty() ||
- positionAttribute->isDirty() ||
- geom->isDirty() ||
- gRenderer->isDirty() ||
- (indexAttribute && indexAttribute->isDirty()) ||
- (indexBuf && indexBuf->isDirty()))
- {
+ if (buf->isDirty()
+ || node->isBoundingVolumeDirty()
+ || positionAttribute->isDirty()
+ || geom->isDirty()
+ || gRenderer->isDirty()
+ || (indexAttribute && indexAttribute->isDirty())
+ || (indexBuf && indexBuf->isDirty())) {
BoundingVolumeCalculator reader(manager);
- if (reader.apply(positionAttribute, indexAttribute,
- drawVertexCount, gRenderer->primitiveRestartEnabled(), gRenderer->restartIndexValue()))
- {
+ if (reader.apply(positionAttribute, indexAttribute, drawVertexCount,
+ gRenderer->primitiveRestartEnabled(), gRenderer->restartIndexValue())) {
node->localBoundingVolume()->setCenter(reader.result().center());
node->localBoundingVolume()->setRadius(reader.result().radius());
node->unsetBoundingVolumeDirty();
diff --git a/src/render/jobs/frustumcullingjob.cpp b/src/render/jobs/frustumcullingjob.cpp
index 85c6b5cad..1a03b691d 100644
--- a/src/render/jobs/frustumcullingjob.cpp
+++ b/src/render/jobs/frustumcullingjob.cpp
@@ -86,17 +86,17 @@ void FrustumCullingJob::cullScene(Entity *e, const Plane *planes)
const Sphere *s = e->worldBoundingVolumeWithChildren();
// Unrolled loop
- if (QVector3D::dotProduct(s->center(), planes[0].normal) + planes[0].d < -s->radius())
+ if (Vector3D::dotProduct(s->center(), planes[0].normal) + planes[0].d < -s->radius())
return;
- if (QVector3D::dotProduct(s->center(), planes[1].normal) + planes[1].d < -s->radius())
+ if (Vector3D::dotProduct(s->center(), planes[1].normal) + planes[1].d < -s->radius())
return;
- if (QVector3D::dotProduct(s->center(), planes[2].normal) + planes[2].d < -s->radius())
+ if (Vector3D::dotProduct(s->center(), planes[2].normal) + planes[2].d < -s->radius())
return;
- if (QVector3D::dotProduct(s->center(), planes[3].normal) + planes[3].d < -s->radius())
+ if (Vector3D::dotProduct(s->center(), planes[3].normal) + planes[3].d < -s->radius())
return;
- if (QVector3D::dotProduct(s->center(), planes[4].normal) + planes[4].d < -s->radius())
+ if (Vector3D::dotProduct(s->center(), planes[4].normal) + planes[4].d < -s->radius())
return;
- if (QVector3D::dotProduct(s->center(), planes[5].normal) + planes[5].d < -s->radius())
+ if (Vector3D::dotProduct(s->center(), planes[5].normal) + planes[5].d < -s->radius())
return;
m_visibleEntities.push_back(e);
diff --git a/src/render/jobs/frustumcullingjob_p.h b/src/render/jobs/frustumcullingjob_p.h
index 8b0bc7150..f81e4c5b9 100644
--- a/src/render/jobs/frustumcullingjob_p.h
+++ b/src/render/jobs/frustumcullingjob_p.h
@@ -41,7 +41,8 @@
#define QT3DRENDER_RENDER_FRUSTUMCULLINGJOB_P_H
#include <Qt3DCore/qaspectjob.h>
-#include <QMatrix4x4>
+#include <Qt3DCore/private/matrix4x4_p.h>
+#include <Qt3DRender/private/aligned_malloc_p.h>
//
// W A R N I N G
@@ -69,11 +70,13 @@ class FrustumCullingJob : public Qt3DCore::QAspectJob
public:
FrustumCullingJob();
+ QT3D_ALIGNED_MALLOC_AND_FREE()
+
inline void setRoot(Entity *root) Q_DECL_NOTHROW { m_root = root; }
inline void setActive(bool active) Q_DECL_NOTHROW { m_active = active; }
inline bool isActive() const Q_DECL_NOTHROW { return m_active; }
- inline void setViewProjection(const QMatrix4x4 &viewProjection) Q_DECL_NOTHROW { m_viewProjection = viewProjection; }
- inline QMatrix4x4 viewProjection() const Q_DECL_NOTHROW { return m_viewProjection; }
+ inline void setViewProjection(const Matrix4x4 &viewProjection) Q_DECL_NOTHROW { m_viewProjection = viewProjection; }
+ inline Matrix4x4 viewProjection() const Q_DECL_NOTHROW { return m_viewProjection; }
QVector<Entity *> visibleEntities() const Q_DECL_NOTHROW { return m_visibleEntities; }
@@ -81,7 +84,7 @@ public:
private:
void cullScene(Entity *e, const Plane *planes);
- QMatrix4x4 m_viewProjection;
+ Matrix4x4 m_viewProjection;
Entity *m_root;
QVector<Entity *> m_visibleEntities;
bool m_active;
diff --git a/src/render/jobs/job_common_p.h b/src/render/jobs/job_common_p.h
index 0e570ca19..7fd88a697 100644
--- a/src/render/jobs/job_common_p.h
+++ b/src/render/jobs/job_common_p.h
@@ -100,12 +100,17 @@ namespace JobTypes {
UpdateMeshTriangleList,
FilterCompatibleTechniques,
UpdateLevelOfDetail,
- SyncTextureLoading,
+ SyncSkeletonLoading,
LoadSkeleton,
UpdateSkinningPalette,
ProximityFiltering,
SyncFilterEntityByLayer,
- SyncMaterialGatherer
+ SyncMaterialGatherer,
+ ReadRenderQueueSizeBarrier,
+ BeginDrawingBarrier,
+ UpdateGLResourcesBarrier,
+ PrepareCommandSubmissionBarrier,
+ EndDrawingBarrier
};
} // JobTypes
diff --git a/src/render/jobs/loadtexturedatajob.cpp b/src/render/jobs/loadtexturedatajob.cpp
index 55232d74f..790e41998 100644
--- a/src/render/jobs/loadtexturedatajob.cpp
+++ b/src/render/jobs/loadtexturedatajob.cpp
@@ -49,16 +49,7 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Render {
-LoadTextureDataJob::LoadTextureDataJob(const QTextureGeneratorPtr &texGen)
- : m_texGen(texGen)
- , m_imgDataGen(nullptr)
-{
- SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadTextureData, 0);
-}
-
-LoadTextureDataJob::LoadTextureDataJob(const QTextureImageDataGeneratorPtr &imgDataGen)
- : m_texGen(nullptr)
- , m_imgDataGen(imgDataGen)
+LoadTextureDataJob::LoadTextureDataJob()
{
SET_JOB_RUN_STAT_TYPE(this, JobTypes::LoadTextureData, 0);
}
@@ -69,13 +60,20 @@ LoadTextureDataJob::~LoadTextureDataJob()
void LoadTextureDataJob::run()
{
- if (m_texGen) {
- QTextureDataPtr texData = (*m_texGen)();
- m_manager->textureDataManager()->assignData(m_texGen, texData);
+ // NOTE: This must run after Renderer::updateGLResources(),
+ // because that is where pendingGenerators is populated.
+ // We are therefore not able to create one job for each texture
+ // before we add the ability for running jobs (like this) to
+ // spawn new jobs.
+ const QVector<QTextureImageDataGeneratorPtr> pendingImgGen = m_manager->textureImageDataManager()->pendingGenerators();
+ for (const QTextureImageDataGeneratorPtr &imgGen : pendingImgGen) {
+ QTextureImageDataPtr imgData = (*imgGen)();
+ m_manager->textureImageDataManager()->assignData(imgGen, imgData);
}
- if (m_imgDataGen) {
- QTextureImageDataPtr imgData = (*m_imgDataGen)();
- m_manager->textureImageDataManager()->assignData(m_imgDataGen, imgData);
+ const QVector<QTextureGeneratorPtr> pendingTexGen = m_manager->textureDataManager()->pendingGenerators();
+ for (const QTextureGeneratorPtr &texGen : pendingTexGen) {
+ QTextureDataPtr texData = (*texGen)();
+ m_manager->textureDataManager()->assignData(texGen, texData);
}
}
diff --git a/src/render/jobs/loadtexturedatajob_p.h b/src/render/jobs/loadtexturedatajob_p.h
index 607068712..7272bbc1d 100644
--- a/src/render/jobs/loadtexturedatajob_p.h
+++ b/src/render/jobs/loadtexturedatajob_p.h
@@ -67,8 +67,7 @@ class NodeManagers;
class LoadTextureDataJob : public Qt3DCore::QAspectJob
{
public:
- LoadTextureDataJob(const QTextureGeneratorPtr &texGen);
- LoadTextureDataJob(const QTextureImageDataGeneratorPtr &imgDataGen);
+ LoadTextureDataJob();
~LoadTextureDataJob();
inline void setNodeManagers(NodeManagers *manager) { m_manager = manager; }
@@ -77,9 +76,6 @@ protected:
void run() final;
private:
- QTextureGeneratorPtr m_texGen;
- QTextureImageDataGeneratorPtr m_imgDataGen;
-
NodeManagers *m_manager;
};
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp
index 1805f6d43..5884a8f67 100644
--- a/src/render/jobs/pickboundingvolumejob.cpp
+++ b/src/render/jobs/pickboundingvolumejob.cpp
@@ -54,6 +54,10 @@
#include <Qt3DRender/private/qpickevent_p.h>
#include <Qt3DRender/private/pickboundingvolumeutils_p.h>
+#include <QSurface>
+#include <QWindow>
+#include <QOffscreenSurface>
+
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
@@ -111,7 +115,12 @@ PickBoundingVolumeJob::PickBoundingVolumeJob()
SET_JOB_RUN_STAT_TYPE(this, JobTypes::PickBoundingVolume, 0);
}
-void PickBoundingVolumeJob::setMouseEvents(const QList<QMouseEvent> &pendingEvents)
+void PickBoundingVolumeJob::setRoot(Entity *root)
+{
+ m_node = root;
+}
+
+void PickBoundingVolumeJob::setMouseEvents(const QList<QPair<QObject*, QMouseEvent>> &pendingEvents)
{
m_pendingMouseEvents = pendingEvents;
}
@@ -159,8 +168,8 @@ bool PickBoundingVolumeJob::runHelper()
bool hasMoveEvent = false;
bool hasOtherEvent = false;
// Quickly look which types of events we've got
- for (const QMouseEvent &event : mouseEvents) {
- const bool isMove = (event.type() == QEvent::MouseMove);
+ for (const auto &event : mouseEvents) {
+ const bool isMove = (event.second.type() == QEvent::MouseMove);
hasMoveEvent |= isMove;
hasOtherEvent |= !isMove;
}
@@ -188,10 +197,10 @@ bool PickBoundingVolumeJob::runHelper()
PickingUtils::ViewportCameraAreaGatherer vcaGatherer;
// TO DO: We could cache this and only gather when we know the FrameGraph tree has changed
- const QVector<PickingUtils::ViewportCameraAreaTriplet> vcaTriplets = vcaGatherer.gather(m_frameGraphRoot);
+ const QVector<PickingUtils::ViewportCameraAreaDetails> vcaDetails = vcaGatherer.gather(m_frameGraphRoot);
// If we have no viewport / camera or area, return early
- if (vcaTriplets.empty())
+ if (vcaDetails.empty())
return false;
// TO DO:
@@ -210,19 +219,21 @@ bool PickBoundingVolumeJob::runHelper()
const float pickWorldSpaceTolerance = m_renderSettings->pickWorldSpaceTolerance();
// For each mouse event
- for (const QMouseEvent &event : mouseEvents) {
+ for (const auto &event : mouseEvents) {
m_hoveredPickersToClear = m_hoveredPickers;
QPickEvent::Buttons eventButton = QPickEvent::NoButton;
int eventButtons = 0;
int eventModifiers = QPickEvent::NoModifier;
- setEventButtonAndModifiers(event, eventButton, eventButtons, eventModifiers);
+ setEventButtonAndModifiers(event.second, eventButton, eventButtons, eventModifiers);
- // For each triplet of Viewport / Camera and Area
- for (const PickingUtils::ViewportCameraAreaTriplet &vca : vcaTriplets) {
+ // For each Viewport / Camera and Area entry
+ for (const PickingUtils::ViewportCameraAreaDetails &vca : vcaDetails) {
PickingUtils::HitList sphereHits;
- QRay3D ray = rayForViewportAndCamera(vca.area, event.pos(), vca.viewport, vca.cameraId);
+ QRay3D ray = rayForViewportAndCamera(vca, event.first, event.second.pos());
+ if (!ray.isValid())
+ continue;
PickingUtils::HierarchicalEntityPicker entityPicker(ray);
if (entityPicker.collectHits(m_manager, m_node)) {
@@ -259,7 +270,7 @@ bool PickBoundingVolumeJob::runHelper()
}
// Dispatch events based on hit results
- dispatchPickEvents(event, sphereHits, eventButton, eventButtons, eventModifiers, allHitsRequested);
+ dispatchPickEvents(event.second, sphereHits, eventButton, eventButtons, eventModifiers, allHitsRequested);
}
}
@@ -309,39 +320,48 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event,
}
// Send the corresponding event
- QVector3D localIntersection = hit.m_intersection;
+ Vector3D localIntersection = hit.m_intersection;
if (entity && entity->worldTransform())
localIntersection = entity->worldTransform()->inverted() * hit.m_intersection;
QPickEventPtr pickEvent;
switch (hit.m_type) {
case QCollisionQueryResult::Hit::Triangle:
- pickEvent = QPickTriangleEventPtr::create(event.localPos(), hit.m_intersection,
- localIntersection, hit.m_distance,
- hit.m_primitiveIndex,
- hit.m_vertexIndex[0],
- hit.m_vertexIndex[1],
- hit.m_vertexIndex[2],
- eventButton, eventButtons,
- eventModifiers, hit.m_uvw);
+ pickEvent.reset(new QPickTriangleEvent(event.localPos(),
+ convertToQVector3D(hit.m_intersection),
+ convertToQVector3D(localIntersection),
+ hit.m_distance,
+ hit.m_primitiveIndex,
+ hit.m_vertexIndex[0],
+ hit.m_vertexIndex[1],
+ hit.m_vertexIndex[2],
+ eventButton, eventButtons,
+ eventModifiers,
+ convertToQVector3D(hit.m_uvw)));
break;
case QCollisionQueryResult::Hit::Edge:
- pickEvent = QPickLineEventPtr::create(event.localPos(), hit.m_intersection,
- localIntersection, hit.m_distance,
- hit.m_primitiveIndex,
- hit.m_vertexIndex[0], hit.m_vertexIndex[1],
- eventButton, eventButtons, eventModifiers);
+ pickEvent.reset(new QPickLineEvent(event.localPos(),
+ convertToQVector3D(hit.m_intersection),
+ convertToQVector3D(localIntersection),
+ hit.m_distance,
+ hit.m_primitiveIndex,
+ hit.m_vertexIndex[0], hit.m_vertexIndex[1],
+ eventButton, eventButtons, eventModifiers));
break;
case QCollisionQueryResult::Hit::Point:
- pickEvent = QPickPointEventPtr::create(event.localPos(), hit.m_intersection,
- localIntersection, hit.m_distance,
- hit.m_vertexIndex[0],
- eventButton, eventButtons, eventModifiers);
+ pickEvent.reset(new QPickPointEvent(event.localPos(),
+ convertToQVector3D(hit.m_intersection),
+ convertToQVector3D(localIntersection),
+ hit.m_distance,
+ hit.m_vertexIndex[0],
+ eventButton, eventButtons, eventModifiers));
break;
case QCollisionQueryResult::Hit::Entity:
- pickEvent = QPickEventPtr::create(event.localPos(), hit.m_intersection,
- localIntersection, hit.m_distance,
- eventButton, eventButtons, eventModifiers);
+ pickEvent.reset(new QPickEvent(event.localPos(),
+ convertToQVector3D(hit.m_intersection),
+ convertToQVector3D(localIntersection),
+ hit.m_distance,
+ eventButton, eventButtons, eventModifiers));
break;
default:
Q_UNREACHABLE();
diff --git a/src/render/jobs/pickboundingvolumejob_p.h b/src/render/jobs/pickboundingvolumejob_p.h
index 407cc37a5..2c38c400b 100644
--- a/src/render/jobs/pickboundingvolumejob_p.h
+++ b/src/render/jobs/pickboundingvolumejob_p.h
@@ -52,6 +52,12 @@
//
#include "abstractpickingjob_p.h"
+#include <Qt3DCore/qaspectjob.h>
+#include <Qt3DRender/private/qray3d_p.h>
+#include <Qt3DRender/private/handle_types_p.h>
+#include <Qt3DRender/private/qboundingvolumeprovider_p.h>
+#include <Qt3DRender/private/qcollisionqueryresult_p.h>
+#include <Qt3DRender/private/pickboundingvolumeutils_p.h>
#include <Qt3DRender/qpickevent.h>
#include <QMouseEvent>
#include <QKeyEvent>
@@ -71,7 +77,8 @@ class Q_AUTOTEST_EXPORT PickBoundingVolumeJob : public AbstractPickingJob
public:
PickBoundingVolumeJob();
- void setMouseEvents(const QList<QMouseEvent> &pendingEvents);
+ void setRoot(Entity *root);
+ void setMouseEvents(const QList<QPair<QObject*, QMouseEvent>> &pendingEvents);
void setKeyEvents(const QList<QKeyEvent> &pendingEvents);
void markPickersDirty();
bool pickersDirty() const { return m_pickersDirty; }
@@ -90,15 +97,15 @@ protected:
bool allHitsRequested);
private:
- QList<QMouseEvent> m_pendingMouseEvents;
+ void clearPreviouslyHoveredPickers();
+
+ QList<QPair<QObject*, QMouseEvent>> m_pendingMouseEvents;
QList<QKeyEvent> m_pendingKeyEvents;
bool m_pickersDirty;
bool m_oneHoverAtLeast;
HObjectPicker m_currentPicker;
QVector<HObjectPicker> m_hoveredPickers;
QVector<HObjectPicker> m_hoveredPickersToClear;
-
- void clearPreviouslyHoveredPickers();
};
typedef QSharedPointer<PickBoundingVolumeJob> PickBoundingVolumeJobPtr;
diff --git a/src/render/jobs/pickboundingvolumeutils.cpp b/src/render/jobs/pickboundingvolumeutils.cpp
index ba88e5691..21255819f 100644
--- a/src/render/jobs/pickboundingvolumeutils.cpp
+++ b/src/render/jobs/pickboundingvolumeutils.cpp
@@ -73,9 +73,9 @@ void ViewportCameraAreaGatherer::visit(FrameGraphNode *node)
m_leaves.push_back(node);
}
-ViewportCameraAreaTriplet ViewportCameraAreaGatherer::gatherUpViewportCameraAreas(Render::FrameGraphNode *node) const
+ViewportCameraAreaDetails ViewportCameraAreaGatherer::gatherUpViewportCameraAreas(Render::FrameGraphNode *node) const
{
- ViewportCameraAreaTriplet vca;
+ ViewportCameraAreaDetails vca;
vca.viewport = QRectF(0.0f, 0.0f, 1.0f, 1.0f);
while (node) {
@@ -87,9 +87,12 @@ ViewportCameraAreaTriplet ViewportCameraAreaGatherer::gatherUpViewportCameraArea
case FrameGraphNode::Viewport:
vca.viewport = computeViewport(vca.viewport, static_cast<const ViewportNode *>(node));
break;
- case FrameGraphNode::Surface:
- vca.area = static_cast<const RenderSurfaceSelector *>(node)->renderTargetSize();
+ case FrameGraphNode::Surface: {
+ auto selector = static_cast<const RenderSurfaceSelector *>(node);
+ vca.area = selector->renderTargetSize();
+ vca.surface = selector->surface();
break;
+ }
default:
break;
}
@@ -99,29 +102,32 @@ ViewportCameraAreaTriplet ViewportCameraAreaGatherer::gatherUpViewportCameraArea
return vca;
}
-QVector<ViewportCameraAreaTriplet> ViewportCameraAreaGatherer::gather(FrameGraphNode *root)
+QVector<ViewportCameraAreaDetails> ViewportCameraAreaGatherer::gather(FrameGraphNode *root)
{
// Retrieve all leaves
visit(root);
- QVector<ViewportCameraAreaTriplet> vcaTriplets;
+ QVector<ViewportCameraAreaDetails> vcaTriplets;
vcaTriplets.reserve(m_leaves.count());
// Find all viewport/camera pairs by traversing from leaf to root
for (Render::FrameGraphNode *leaf : qAsConst(m_leaves)) {
- ViewportCameraAreaTriplet vcaTriplet = gatherUpViewportCameraAreas(leaf);
- if (!m_targetCamera.isNull() && vcaTriplet.cameraId != m_targetCamera)
+ ViewportCameraAreaDetails vcaDetails = gatherUpViewportCameraAreas(leaf);
+ if (!m_targetCamera.isNull() && vcaDetails.cameraId != m_targetCamera)
continue;
- if (!vcaTriplet.cameraId.isNull() && isUnique(vcaTriplets, vcaTriplet))
- vcaTriplets.push_back(vcaTriplet);
+ if (!vcaDetails.cameraId.isNull() && isUnique(vcaTriplets, vcaDetails))
+ vcaTriplets.push_back(vcaDetails);
}
return vcaTriplets;
}
-bool ViewportCameraAreaGatherer::isUnique(const QVector<ViewportCameraAreaTriplet> &vcaTriplets,
- const ViewportCameraAreaTriplet &vca) const
+bool ViewportCameraAreaGatherer::isUnique(const QVector<ViewportCameraAreaDetails> &vcaList,
+ const ViewportCameraAreaDetails &vca) const
{
- for (const ViewportCameraAreaTriplet &triplet : vcaTriplets) {
- if (vca.cameraId == triplet.cameraId && vca.viewport == triplet.viewport && vca.area == triplet.area)
+ for (const ViewportCameraAreaDetails &listItem : vcaList) {
+ if (vca.cameraId == listItem.cameraId &&
+ vca.viewport == listItem.viewport &&
+ vca.surface == listItem.surface &&
+ vca.area == listItem.area)
return false;
}
return true;
@@ -155,7 +161,6 @@ QVector<Entity *> EntityGatherer::entities() const
return m_entities;
}
-
class TriangleCollisionVisitor : public TrianglesVisitor
{
public:
@@ -175,20 +180,20 @@ private:
bool m_frontFaceRequested;
bool m_backFaceRequested;
- void visit(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b,
- uint cndx, const QVector3D &c) override;
- bool intersectsSegmentTriangle(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b,
- uint cndx, const QVector3D &c);
+ void visit(uint andx, const Vector3D &a,
+ uint bndx, const Vector3D &b,
+ uint cndx, const Vector3D &c) override;
+ bool intersectsSegmentTriangle(uint andx, const Vector3D &a,
+ uint bndx, const Vector3D &b,
+ uint cndx, const Vector3D &c);
};
-void TriangleCollisionVisitor::visit(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c)
+void TriangleCollisionVisitor::visit(uint andx, const Vector3D &a, uint bndx, const Vector3D &b, uint cndx, const Vector3D &c)
{
- const QMatrix4x4 &mat = *m_root->worldTransform();
- const QVector3D tA = mat * a;
- const QVector3D tB = mat * b;
- const QVector3D tC = mat * c;
+ const Matrix4x4 &mat = *m_root->worldTransform();
+ const Vector3D tA = mat * a;
+ const Vector3D tB = mat * b;
+ const Vector3D tC = mat * c;
bool intersected = m_frontFaceRequested &&
intersectsSegmentTriangle(cndx, tC, bndx, tB, andx, tA); // front facing
@@ -199,10 +204,11 @@ void TriangleCollisionVisitor::visit(uint andx, const QVector3D &a, uint bndx, c
m_triangleIndex++;
}
-bool TriangleCollisionVisitor::intersectsSegmentTriangle(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c)
+
+bool TriangleCollisionVisitor::intersectsSegmentTriangle(uint andx, const Vector3D &a, uint bndx, const Vector3D &b, uint cndx, const Vector3D &c)
{
float t = 0.0f;
- QVector3D uvw;
+ Vector3D uvw;
bool intersected = Render::intersectsSegmentTriangle(m_ray, a, b, c, uvw, t);
if (intersected) {
QCollisionQueryResult::Hit queryResult;
@@ -238,30 +244,30 @@ private:
uint m_segmentIndex;
float m_pickWorldSpaceTolerance;
- void visit(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b) override;
- bool intersectsSegmentSegment(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b);
- bool rayToLineSegment(const QVector3D& lineStart,const QVector3D& lineEnd,
- float &distance, QVector3D &intersection) const;
+ void visit(uint andx, const Vector3D &a,
+ uint bndx, const Vector3D &b) override;
+ bool intersectsSegmentSegment(uint andx, const Vector3D &a,
+ uint bndx, const Vector3D &b);
+ bool rayToLineSegment(const Vector3D& lineStart,const Vector3D& lineEnd,
+ float &distance, Vector3D &intersection) const;
};
-void LineCollisionVisitor::visit(uint andx, const QVector3D &a, uint bndx, const QVector3D &b)
+void LineCollisionVisitor::visit(uint andx, const Vector3D &a, uint bndx, const Vector3D &b)
{
- const QMatrix4x4 &mat = *m_root->worldTransform();
- const QVector3D tA = mat * a;
- const QVector3D tB = mat * b;
+ const Matrix4x4 &mat = *m_root->worldTransform();
+ const Vector3D tA = mat * a;
+ const Vector3D tB = mat * b;
intersectsSegmentSegment(andx, tA, bndx, tB);
m_segmentIndex++;
}
-bool LineCollisionVisitor::intersectsSegmentSegment(uint andx, const QVector3D &a,
- uint bndx, const QVector3D &b)
+bool LineCollisionVisitor::intersectsSegmentSegment(uint andx, const Vector3D &a,
+ uint bndx, const Vector3D &b)
{
float distance = 0.f;
- QVector3D intersection;
+ Vector3D intersection;
bool res = rayToLineSegment(a, b, distance, intersection);
if (res) {
QCollisionQueryResult::Hit queryResult;
@@ -278,19 +284,19 @@ bool LineCollisionVisitor::intersectsSegmentSegment(uint andx, const QVector3D &
return false;
}
-bool LineCollisionVisitor::rayToLineSegment(const QVector3D& lineStart,const QVector3D& lineEnd,
- float &distance, QVector3D &intersection) const
+bool LineCollisionVisitor::rayToLineSegment(const Vector3D& lineStart,const Vector3D& lineEnd,
+ float &distance, Vector3D &intersection) const
{
const float epsilon = 0.00000001f;
- const QVector3D u = m_ray.direction() * m_ray.distance();
- const QVector3D v = lineEnd - lineStart;
- const QVector3D w = m_ray.origin() - lineStart;
- const float a = QVector3D::dotProduct(u, u);
- const float b = QVector3D::dotProduct(u, v);
- const float c = QVector3D::dotProduct(v, v);
- const float d = QVector3D::dotProduct(u, w);
- const float e = QVector3D::dotProduct(v, w);
+ const Vector3D u = m_ray.direction() * m_ray.distance();
+ const Vector3D v = lineEnd - lineStart;
+ const Vector3D w = m_ray.origin() - lineStart;
+ const float a = Vector3D::dotProduct(u, u);
+ const float b = Vector3D::dotProduct(u, v);
+ const float c = Vector3D::dotProduct(v, v);
+ const float d = Vector3D::dotProduct(u, w);
+ const float e = Vector3D::dotProduct(v, w);
const float D = a * c - b * b;
float sc, sN, sD = D;
float tc, tN, tD = D;
@@ -331,7 +337,7 @@ bool LineCollisionVisitor::rayToLineSegment(const QVector3D& lineStart,const QVe
sc = (qAbs(sN) < epsilon ? 0.0f : sN / sD);
tc = (qAbs(tN) < epsilon ? 0.0f : tN / tD);
- const QVector3D dP = w + (sc * u) - (tc * v);
+ const Vector3D dP = w + (sc * u) - (tc * v);
const float f = dP.length();
if (f < m_pickWorldSpaceTolerance) {
distance = sc * u.length();
@@ -359,23 +365,23 @@ private:
uint m_pointIndex;
float m_pickWorldSpaceTolerance;
- void visit(uint ndx, const QVector3D &p) override;
+ void visit(uint ndx, const Vector3D &p) override;
- double pointToRayDistance(const QVector3D &a, QVector3D &p)
+ double pointToRayDistance(const Vector3D &a, Vector3D &p)
{
- const QVector3D v = a - m_ray.origin();
- const double t = QVector3D::dotProduct(v, m_ray.direction());
+ const Vector3D v = a - m_ray.origin();
+ const double t = Vector3D::dotProduct(v, m_ray.direction());
p = m_ray.origin() + t * m_ray.direction();
return (p - a).length();
}
};
-void PointCollisionVisitor::visit(uint ndx, const QVector3D &p)
+void PointCollisionVisitor::visit(uint ndx, const Vector3D &p)
{
- const QMatrix4x4 &mat = *m_root->worldTransform();
- const QVector3D tP = mat * p;
- QVector3D intersection;
+ const Matrix4x4 &mat = *m_root->worldTransform();
+ const Vector3D tP = mat * p;
+ Vector3D intersection;
float d = pointToRayDistance(tP, intersection);
if (d < m_pickWorldSpaceTolerance) {
@@ -464,10 +470,32 @@ void AbstractCollisionGathererFunctor::sortHits(HitList &results)
std::sort(results.begin(), results.end(), compareHitsDistance);
}
+namespace {
+
+// Workaround to avoid passing *this into the blockMappedReduce calls for the
+// mapFunctor which would cause an SSE alignment error on Windows Also note
+// that a lambda doesn't work since we need the typedef result_type defined to
+// work with QtConcurrent
+struct MapFunctorHolder
+{
+ MapFunctorHolder(const AbstractCollisionGathererFunctor *gatherer)
+ : m_gatherer(gatherer)
+ {}
+
+ // This define is required to work with QtConcurrent
+ typedef HitList result_type;
+ HitList operator ()(const Entity *e) const { return m_gatherer->operator ()(e); }
+
+ const AbstractCollisionGathererFunctor *m_gatherer;
+};
+
+} // anonymous
+
HitList EntityCollisionGathererFunctor::computeHits(const QVector<Entity *> &entities, bool allHitsRequested)
{
const auto reducerOp = allHitsRequested ? PickingUtils::reduceToAllHits : PickingUtils::reduceToFirstHit;
- return QtConcurrent::blockingMappedReduced<HitList>(entities, *this, reducerOp);
+ const MapFunctorHolder holder(this);
+ return QtConcurrent::blockingMappedReduced<HitList>(entities, holder, reducerOp);
}
HitList EntityCollisionGathererFunctor::pick(const Entity *entity) const
@@ -485,7 +513,8 @@ HitList EntityCollisionGathererFunctor::pick(const Entity *entity) const
HitList TriangleCollisionGathererFunctor::computeHits(const QVector<Entity *> &entities, bool allHitsRequested)
{
const auto reducerOp = allHitsRequested ? PickingUtils::reduceToAllHits : PickingUtils::reduceToFirstHit;
- return QtConcurrent::blockingMappedReduced<HitList>(entities, *this, reducerOp);
+ const MapFunctorHolder holder(this);
+ return QtConcurrent::blockingMappedReduced<HitList>(entities, holder, reducerOp);
}
HitList TriangleCollisionGathererFunctor::pick(const Entity *entity) const
@@ -510,7 +539,8 @@ HitList TriangleCollisionGathererFunctor::pick(const Entity *entity) const
HitList LineCollisionGathererFunctor::computeHits(const QVector<Entity *> &entities, bool allHitsRequested)
{
const auto reducerOp = allHitsRequested ? PickingUtils::reduceToAllHits : PickingUtils::reduceToFirstHit;
- return QtConcurrent::blockingMappedReduced<HitList>(entities, *this, reducerOp);
+ const MapFunctorHolder holder(this);
+ return QtConcurrent::blockingMappedReduced<HitList>(entities, holder, reducerOp);
}
HitList LineCollisionGathererFunctor::pick(const Entity *entity) const
@@ -534,7 +564,8 @@ HitList LineCollisionGathererFunctor::pick(const Entity *entity) const
HitList PointCollisionGathererFunctor::computeHits(const QVector<Entity *> &entities, bool allHitsRequested)
{
const auto reducerOp = allHitsRequested ? PickingUtils::reduceToAllHits : PickingUtils::reduceToFirstHit;
- return QtConcurrent::blockingMappedReduced<HitList>(entities, *this, reducerOp);
+ const MapFunctorHolder holder(this);
+ return QtConcurrent::blockingMappedReduced<HitList>(entities, holder, reducerOp);
}
HitList PointCollisionGathererFunctor::pick(const Entity *entity) const
diff --git a/src/render/jobs/pickboundingvolumeutils_p.h b/src/render/jobs/pickboundingvolumeutils_p.h
index 47ab6c3bd..780c16cc8 100644
--- a/src/render/jobs/pickboundingvolumeutils_p.h
+++ b/src/render/jobs/pickboundingvolumeutils_p.h
@@ -59,6 +59,8 @@
QT_BEGIN_NAMESPACE
+class QSurface;
+
namespace Qt3DRender {
namespace RayCasting {
class QAbstractCollisionQueryService;
@@ -73,27 +75,28 @@ class NodeManagers;
namespace PickingUtils {
-struct Q_AUTOTEST_EXPORT ViewportCameraAreaTriplet
+struct Q_AUTOTEST_EXPORT ViewportCameraAreaDetails
{
Qt3DCore::QNodeId cameraId;
QRectF viewport;
QSize area;
+ QSurface *surface = nullptr;
};
-QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, PickingUtils, ViewportCameraAreaTriplet, Q_PRIMITIVE_TYPE)
+QT3D_DECLARE_TYPEINFO_3(Qt3DRender, Render, PickingUtils, ViewportCameraAreaDetails, Q_PRIMITIVE_TYPE)
class Q_AUTOTEST_EXPORT ViewportCameraAreaGatherer
{
public:
ViewportCameraAreaGatherer(const Qt3DCore::QNodeId &nodeId = Qt3DCore::QNodeId()) : m_targetCamera(nodeId) { }
- QVector<ViewportCameraAreaTriplet> gather(FrameGraphNode *root);
+ QVector<ViewportCameraAreaDetails> gather(FrameGraphNode *root);
private:
Qt3DCore::QNodeId m_targetCamera;
QVector<FrameGraphNode *> m_leaves;
void visit(FrameGraphNode *node);
- ViewportCameraAreaTriplet gatherUpViewportCameraAreas(Render::FrameGraphNode *node) const;
- bool isUnique(const QVector<ViewportCameraAreaTriplet> &vcaTriplets, const ViewportCameraAreaTriplet &vca) const;
+ ViewportCameraAreaDetails gatherUpViewportCameraAreas(Render::FrameGraphNode *node) const;
+ bool isUnique(const QVector<ViewportCameraAreaDetails> &vcaList, const ViewportCameraAreaDetails &vca) const;
};
class Q_AUTOTEST_EXPORT EntityGatherer
diff --git a/src/render/jobs/raycastingjob.cpp b/src/render/jobs/raycastingjob.cpp
index c9fe5cac0..0fbaed219 100644
--- a/src/render/jobs/raycastingjob.cpp
+++ b/src/render/jobs/raycastingjob.cpp
@@ -148,19 +148,24 @@ bool RayCastingJob::runHelper()
const EntityCasterGatherer::EntityCasterList &entities = gatherer.result();
PickingUtils::ViewportCameraAreaGatherer vcaGatherer;
- const QVector<PickingUtils::ViewportCameraAreaTriplet> vcaTriplets = vcaGatherer.gather(m_frameGraphRoot);
+ const QVector<PickingUtils::ViewportCameraAreaDetails> vcaDetails = vcaGatherer.gather(m_frameGraphRoot);
for (const EntityCasterGatherer::EntityCasterList::value_type &pair: entities) {
QVector<QRay3D> rays;
switch (pair.second->type()) {
case QAbstractRayCasterPrivate::WorldSpaceRayCaster:
- rays << QRay3D(pair.second->origin(), pair.second->direction(), pair.second->length());
+ rays << QRay3D(Vector3D(pair.second->origin()),
+ Vector3D(pair.second->direction()),
+ pair.second->length());
rays.back().transform(*pair.first->worldTransform());
break;
case QAbstractRayCasterPrivate::ScreenScapeRayCaster:
- for (const PickingUtils::ViewportCameraAreaTriplet &vca : vcaTriplets)
- rays << rayForViewportAndCamera(vca.area, pair.second->position(), vca.viewport, vca.cameraId);
+ for (const PickingUtils::ViewportCameraAreaDetails &vca : vcaDetails) {
+ // TODO: Fix this properly by not passing null for the eventSource
+ rays << rayForViewportAndCamera(vca, nullptr, pair.second->position());
+ //rays << rayForViewportAndCamera(vca.area, pair.second->position(), vca.viewport, vca.cameraId);
+ }
break;
default:
Q_UNREACHABLE();
@@ -216,7 +221,7 @@ void RayCastingJob::dispatchHits(RayCaster *rayCaster, const PickingUtils::HitLi
QAbstractRayCaster::Hits hits;
for (const PickingUtils::HitList::value_type &sphereHit: sphereHits) {
Entity *entity = m_manager->renderNodesManager()->lookupResource(sphereHit.m_entityId);
- QVector3D localIntersection = sphereHit.m_intersection;
+ Vector3D localIntersection = sphereHit.m_intersection;
if (entity && entity->worldTransform())
localIntersection = entity->worldTransform()->inverted() * localIntersection;
@@ -240,8 +245,8 @@ void RayCastingJob::dispatchHits(RayCaster *rayCaster, const PickingUtils::HitLi
hitType,
sphereHit.m_entityId,
sphereHit.m_distance,
- localIntersection,
- sphereHit.m_intersection,
+ convertToQVector3D(localIntersection),
+ convertToQVector3D(sphereHit.m_intersection),
sphereHit.m_primitiveIndex,
sphereHit.m_vertexIndex[0],
sphereHit.m_vertexIndex[1],
diff --git a/src/render/jobs/renderviewjobutils_p.h b/src/render/jobs/renderviewjobutils_p.h
index 15f3bb71c..468a95bfd 100644
--- a/src/render/jobs/renderviewjobutils_p.h
+++ b/src/render/jobs/renderviewjobutils_p.h
@@ -58,6 +58,7 @@
#include <QMatrix4x4>
#include <Qt3DRender/private/uniform_p.h>
#include <Qt3DRender/private/handle_types_p.h>
+#include <Qt3DRender/private/aligned_malloc_p.h>
QT_BEGIN_NAMESPACE
@@ -160,6 +161,8 @@ struct Q_AUTOTEST_EXPORT UniformBlockValueBuilder
UniformBlockValueBuilder();
~UniformBlockValueBuilder();
+ QT3D_ALIGNED_MALLOC_AND_FREE()
+
void buildActiveUniformNameValueMapHelper(ShaderData *currentShaderData,
const QString &blockName,
const QString &qmlPropertyName,
@@ -173,7 +176,7 @@ struct Q_AUTOTEST_EXPORT UniformBlockValueBuilder
UniformBlockValueBuilderHash activeUniformNamesToValue;
ShaderDataManager *shaderDataManager;
TextureManager *textureManager;
- QMatrix4x4 viewMatrix;
+ Matrix4x4 viewMatrix;
};
} // namespace Render
diff --git a/src/render/jobs/updatelevelofdetailjob.cpp b/src/render/jobs/updatelevelofdetailjob.cpp
index 8b604229a..141d65c22 100644
--- a/src/render/jobs/updatelevelofdetailjob.cpp
+++ b/src/render/jobs/updatelevelofdetailjob.cpp
@@ -140,20 +140,20 @@ void UpdateLevelOfDetailJob::updateEntityLod(Entity *entity)
void UpdateLevelOfDetailJob::updateEntityLodByDistance(Entity *entity, LevelOfDetail *lod)
{
- QMatrix4x4 viewMatrix;
- QMatrix4x4 projectionMatrix;
+ Matrix4x4 viewMatrix;
+ Matrix4x4 projectionMatrix;
if (!Render::CameraLens::viewMatrixForCamera(m_manager->renderNodesManager(), lod->camera(), viewMatrix, projectionMatrix))
return;
const QVector<qreal> thresholds = lod->thresholds();
- QVector3D center = lod->center();
+ Vector3D center(lod->center());
if (lod->hasBoundingVolumeOverride() || entity->worldBoundingVolume() == nullptr) {
center = *entity->worldTransform() * center;
} else {
center = entity->worldBoundingVolume()->center();
}
- const QVector3D tcenter = viewMatrix * center;
+ const Vector3D tcenter = viewMatrix * center;
const float dist = tcenter.length();
const int n = thresholds.size();
for (int i=0; i<n; ++i) {
@@ -169,20 +169,20 @@ void UpdateLevelOfDetailJob::updateEntityLodByDistance(Entity *entity, LevelOfDe
void UpdateLevelOfDetailJob::updateEntityLodByScreenArea(Entity *entity, LevelOfDetail *lod)
{
- QMatrix4x4 viewMatrix;
- QMatrix4x4 projectionMatrix;
+ Matrix4x4 viewMatrix;
+ Matrix4x4 projectionMatrix;
if (!Render::CameraLens::viewMatrixForCamera(m_manager->renderNodesManager(), lod->camera(), viewMatrix, projectionMatrix))
return;
PickingUtils::ViewportCameraAreaGatherer vcaGatherer(lod->camera());
- const QVector<PickingUtils::ViewportCameraAreaTriplet> vcaTriplets = vcaGatherer.gather(m_frameGraphRoot);
+ const QVector<PickingUtils::ViewportCameraAreaDetails> vcaTriplets = vcaGatherer.gather(m_frameGraphRoot);
if (vcaTriplets.isEmpty())
return;
- const PickingUtils::ViewportCameraAreaTriplet &vca = vcaTriplets.front();
+ const PickingUtils::ViewportCameraAreaDetails &vca = vcaTriplets.front();
const QVector<qreal> thresholds = lod->thresholds();
- Sphere bv(lod->center(), lod->radius());
+ Sphere bv(Vector3D(lod->center()), lod->radius());
if (!lod->hasBoundingVolumeOverride() && entity->worldBoundingVolume() != nullptr) {
bv = *(entity->worldBoundingVolume());
} else {
diff --git a/src/render/jobs/updatelevelofdetailjob_p.h b/src/render/jobs/updatelevelofdetailjob_p.h
index 02967458b..4c80a3205 100644
--- a/src/render/jobs/updatelevelofdetailjob_p.h
+++ b/src/render/jobs/updatelevelofdetailjob_p.h
@@ -84,6 +84,7 @@ private:
void updateEntityLod(Entity *entity);
void updateEntityLodByDistance(Entity *entity, LevelOfDetail *lod);
void updateEntityLodByScreenArea(Entity *entity, LevelOfDetail *lod);
+
QRect windowViewport(const QSize &area, const QRectF &relativeViewport) const;
NodeManagers *m_manager;
diff --git a/src/render/jobs/updateworldtransformjob.cpp b/src/render/jobs/updateworldtransformjob.cpp
index 8b11cd309..c56ed8507 100644
--- a/src/render/jobs/updateworldtransformjob.cpp
+++ b/src/render/jobs/updateworldtransformjob.cpp
@@ -54,9 +54,9 @@ namespace Render {
namespace {
-void updateWorldTransformAndBounds(Qt3DRender::Render::Entity *node, const QMatrix4x4 &parentTransform)
+void updateWorldTransformAndBounds(Qt3DRender::Render::Entity *node, const Matrix4x4 &parentTransform)
{
- QMatrix4x4 worldTransform(parentTransform);
+ Matrix4x4 worldTransform(parentTransform);
Transform *nodeTransform = node->renderComponent<Transform>();
if (nodeTransform != nullptr && nodeTransform->isEnabled())
@@ -94,7 +94,7 @@ void UpdateWorldTransformJob::run()
qCDebug(Jobs) << "Entering" << Q_FUNC_INFO << QThread::currentThread();
- QMatrix4x4 parentTransform;
+ Matrix4x4 parentTransform;
Entity *parent = m_node->parent();
if (parent != nullptr)
parentTransform = *(parent->worldTransform());
diff --git a/src/render/materialsystem/qparameter.cpp b/src/render/materialsystem/qparameter.cpp
index b9bfa44e7..2b2dd29d5 100644
--- a/src/render/materialsystem/qparameter.cpp
+++ b/src/render/materialsystem/qparameter.cpp
@@ -179,13 +179,30 @@ QParameterPrivate::QParameterPrivate()
{
}
+namespace {
+
+/*! \internal */
+inline QVariant toBackendValue(const QVariant &v)
+{
+ if (auto nodeValue = v.value<Qt3DCore::QNode*>())
+ return QVariant::fromValue(nodeValue->id());
+ return v;
+}
+
+} // anonymous
+
void QParameterPrivate::setValue(const QVariant &v)
{
- Qt3DCore::QNode *nodeValue = v.value<Qt3DCore::QNode *>();
- if (nodeValue != nullptr)
- m_backendValue = QVariant::fromValue(nodeValue->id());
- else
- m_backendValue = v;
+ if (v.type() == QVariant::List) {
+ QSequentialIterable iterable = v.value<QSequentialIterable>();
+ QVariantList variants;
+ variants.reserve(iterable.size());
+ for (const auto &v : iterable)
+ variants.append(toBackendValue(v));
+ m_backendValue = variants;
+ } else {
+ m_backendValue = toBackendValue(v);
+ }
m_value = v;
}
diff --git a/src/render/materialsystem/shadercache.cpp b/src/render/materialsystem/shadercache.cpp
index 4ddf26799..ce29622ad 100644
--- a/src/render/materialsystem/shadercache.cpp
+++ b/src/render/materialsystem/shadercache.cpp
@@ -62,18 +62,28 @@ ShaderCache::~ShaderCache()
*
* \return A pointer to the shader program if it is cached, nullptr otherwise
*/
-QOpenGLShaderProgram *ShaderCache::getShaderProgramAndAddRef(ProgramDNA dna, Qt3DCore::QNodeId shaderPeerId)
+QOpenGLShaderProgram *ShaderCache::getShaderProgramAndAddRef(ProgramDNA dna, Qt3DCore::QNodeId shaderPeerId, bool *wasPresent)
{
- auto shaderProgram = m_programHash.value(dna, nullptr);
- if (shaderProgram) {
+ auto shaderProgram = m_programHash.constFind(dna);
+
+ // Some callers may wish to differentiate between a result of null due to
+ // not having anything in the cache and a result of null due to the cache
+ // containing a program the shaders of which failed to compile.
+ if (wasPresent)
+ *wasPresent = shaderProgram != m_programHash.constEnd();
+
+ if (shaderProgram != m_programHash.constEnd()) {
// Ensure we store the fact that shaderPeerId references this shader
QMutexLocker lock(&m_refsMutex);
QVector<Qt3DCore::QNodeId> &programRefs = m_programRefs[dna];
auto it = std::lower_bound(programRefs.begin(), programRefs.end(), shaderPeerId);
if (*it != shaderPeerId)
programRefs.insert(it, shaderPeerId);
+
+ return *shaderProgram;
}
- return shaderProgram;
+
+ return nullptr;
}
/*!
diff --git a/src/render/materialsystem/shadercache_p.h b/src/render/materialsystem/shadercache_p.h
index 24a55876e..bda629ee5 100644
--- a/src/render/materialsystem/shadercache_p.h
+++ b/src/render/materialsystem/shadercache_p.h
@@ -71,7 +71,7 @@ class QT3DRENDERSHARED_PRIVATE_EXPORT ShaderCache
public:
~ShaderCache();
- QOpenGLShaderProgram *getShaderProgramAndAddRef(ProgramDNA dna, Qt3DCore::QNodeId shaderPeerId);
+ QOpenGLShaderProgram *getShaderProgramAndAddRef(ProgramDNA dna, Qt3DCore::QNodeId shaderPeerId, bool *wasPresent = nullptr);
void insert(ProgramDNA dna, Qt3DCore::QNodeId shaderPeerId, QOpenGLShaderProgram *program);
void removeRef(ProgramDNA dna, Qt3DCore::QNodeId shaderPeerId);
void purge();
diff --git a/src/render/materialsystem/shaderdata.cpp b/src/render/materialsystem/shaderdata.cpp
index fec1e66ac..de423c3c2 100644
--- a/src/render/materialsystem/shaderdata.cpp
+++ b/src/render/materialsystem/shaderdata.cpp
@@ -171,7 +171,7 @@ void ShaderData::cleanup(NodeManagers *managers)
m_updatedShaderData.clear();
}
-QVariant ShaderData::getTransformedProperty(const QString &name, const QMatrix4x4 &viewMatrix)
+QVariant ShaderData::getTransformedProperty(const QString &name, const Matrix4x4 &viewMatrix)
{
// Note protecting m_worldMatrix at this point as we assume all world updates
// have been performed when reaching this point
@@ -180,11 +180,11 @@ QVariant ShaderData::getTransformedProperty(const QString &name, const QMatrix4x
const TransformType transformType = it.value();
switch (transformType) {
case ModelToEye:
- return QVariant::fromValue(viewMatrix * m_worldMatrix * m_originalProperties.value(name).value<QVector3D>());
+ return QVariant::fromValue(viewMatrix * m_worldMatrix * Vector3D(m_originalProperties.value(name).value<QVector3D>()));
case ModelToWorld:
- return QVariant::fromValue(m_worldMatrix * m_originalProperties.value(it.key()).value<QVector3D>());
+ return QVariant::fromValue(m_worldMatrix * Vector3D(m_originalProperties.value(it.key()).value<QVector3D>()));
case ModelToWorldDirection:
- return QVariant::fromValue((m_worldMatrix * QVector4D(m_originalProperties.value(it.key()).value<QVector3D>(), 0.0f)).toVector3D());
+ return QVariant::fromValue(Vector3D(m_worldMatrix * Vector4D(m_originalProperties.value(it.key()).value<QVector3D>(), 0.0f)));
case NoTransform:
break;
}
@@ -193,7 +193,7 @@ QVariant ShaderData::getTransformedProperty(const QString &name, const QMatrix4x
}
// Called by FramePreparationJob or by RenderView when dealing with lights
-void ShaderData::updateWorldTransform(const QMatrix4x4 &worldMatrix)
+void ShaderData::updateWorldTransform(const Matrix4x4 &worldMatrix)
{
QMutexLocker lock(&m_mutex);
if (m_worldMatrix != worldMatrix) {
diff --git a/src/render/materialsystem/shaderdata_p.h b/src/render/materialsystem/shaderdata_p.h
index 168335f63..f9c3ecc79 100644
--- a/src/render/materialsystem/shaderdata_p.h
+++ b/src/render/materialsystem/shaderdata_p.h
@@ -55,7 +55,7 @@
#include <Qt3DRender/private/shadervariables_p.h>
#include <Qt3DRender/qshaderdata.h>
#include <QMutex>
-#include <QMatrix4x4>
+#include <Qt3DCore/private/matrix4x4_p.h>
QT_BEGIN_NAMESPACE
@@ -83,13 +83,13 @@ public:
QHash<QString, QVariant> properties() const { return m_originalProperties; }
// Called by FramePreparationJob
- void updateWorldTransform(const QMatrix4x4 &worldMatrix);
+ void updateWorldTransform(const Matrix4x4 &worldMatrix);
// Call by RenderViewJob
void markDirty();
TransformType propertyTransformType(const QString &name) const;
- QVariant getTransformedProperty(const QString &name, const QMatrix4x4 &viewMatrix);
+ QVariant getTransformedProperty(const QString &name, const Matrix4x4 &viewMatrix);
// Called by FrameCleanupJob
static void cleanup(NodeManagers *managers);
@@ -114,8 +114,8 @@ protected:
QMutex m_mutex;
static QVector<Qt3DCore::QNodeId> m_updatedShaderData;
- QMatrix4x4 m_worldMatrix;
- QMatrix4x4 m_viewMatrix;
+ Matrix4x4 m_worldMatrix;
+ Matrix4x4 m_viewMatrix;
NodeManagers *m_managers;
void clearUpdatedProperties();
diff --git a/src/render/picking/pickeventfilter.cpp b/src/render/picking/pickeventfilter.cpp
index 297911e45..b10383c72 100644
--- a/src/render/picking/pickeventfilter.cpp
+++ b/src/render/picking/pickeventfilter.cpp
@@ -62,10 +62,10 @@ PickEventFilter::~PickEventFilter()
Called from a worker thread in the thread pool so be sure to
mutex protect the data.
*/
-QList<QMouseEvent> PickEventFilter::pendingMouseEvents()
+QList<QPair<QObject *, QMouseEvent> > PickEventFilter::pendingMouseEvents()
{
QMutexLocker locker(&m_mutex);
- QList<QMouseEvent> pendingEvents(m_pendingMouseEvents);
+ QList<QPair<QObject*, QMouseEvent>> pendingEvents(m_pendingMouseEvents);
m_pendingMouseEvents.clear();
return pendingEvents;
}
@@ -90,14 +90,14 @@ bool PickEventFilter::eventFilter(QObject *obj, QEvent *e)
case QEvent::MouseButtonRelease:
case QEvent::MouseMove: {
QMutexLocker locker(&m_mutex);
- m_pendingMouseEvents.push_back(QMouseEvent(*static_cast<QMouseEvent *>(e)));
+ m_pendingMouseEvents.push_back({obj, QMouseEvent(*static_cast<QMouseEvent *>(e))});
} break;
case QEvent::HoverMove: {
QMutexLocker locker(&m_mutex);
QHoverEvent *he = static_cast<QHoverEvent *>(e);
- m_pendingMouseEvents.push_back(QMouseEvent(QEvent::MouseMove,
+ m_pendingMouseEvents.push_back({obj, QMouseEvent(QEvent::MouseMove,
he->pos(), Qt::NoButton, Qt::NoButton,
- he->modifiers()));
+ he->modifiers())});
} break;
case QEvent::KeyPress:
case QEvent::KeyRelease: {
diff --git a/src/render/picking/pickeventfilter_p.h b/src/render/picking/pickeventfilter_p.h
index c4ede4681..dfd8c1b99 100644
--- a/src/render/picking/pickeventfilter_p.h
+++ b/src/render/picking/pickeventfilter_p.h
@@ -69,14 +69,14 @@ public:
explicit PickEventFilter(QObject *parent = nullptr);
~PickEventFilter();
- QList<QMouseEvent> pendingMouseEvents();
+ QList<QPair<QObject*, QMouseEvent>> pendingMouseEvents();
QList<QKeyEvent> pendingKeyEvents();
protected:
bool eventFilter(QObject *obj, QEvent *e) final;
private:
- QList<QMouseEvent> m_pendingMouseEvents;
+ QList<QPair<QObject*, QMouseEvent>> m_pendingMouseEvents;
QList<QKeyEvent> m_pendingKeyEvents;
QMutex m_mutex;
};
diff --git a/src/render/raycasting/boundingsphere_p.h b/src/render/raycasting/boundingsphere_p.h
index 63bd8a562..bcffbaa19 100644
--- a/src/render/raycasting/boundingsphere_p.h
+++ b/src/render/raycasting/boundingsphere_p.h
@@ -53,6 +53,7 @@
#include <Qt3DRender/qt3drender_global.h>
#include <Qt3DRender/private/qboundingvolume_p.h>
+#include <Qt3DCore/private/vector3d_p.h>
QT_BEGIN_NAMESPACE
@@ -65,7 +66,7 @@ public:
BoundingSphere();
~BoundingSphere();
- virtual QVector3D center() const = 0;
+ virtual Vector3D center() const = 0;
virtual float radius() const = 0;
};
diff --git a/src/render/raycasting/qabstractcollisionqueryservice.cpp b/src/render/raycasting/qabstractcollisionqueryservice.cpp
index 993ad840e..5148df911 100644
--- a/src/render/raycasting/qabstractcollisionqueryservice.cpp
+++ b/src/render/raycasting/qabstractcollisionqueryservice.cpp
@@ -62,8 +62,8 @@ void QAbstractCollisionQueryService::setResultHandle(QCollisionQueryResult &resu
}
void QAbstractCollisionQueryService::addEntityHit(QCollisionQueryResult &result, Qt3DCore::QNodeId entity,
- const QVector3D& intersection, float distance,
- const QVector3D& uvw)
+ const Vector3D& intersection, float distance,
+ const Vector3D& uvw)
{
result.d_func()->addEntityHit(entity, intersection, distance, uvw);
}
diff --git a/src/render/raycasting/qabstractcollisionqueryservice_p.h b/src/render/raycasting/qabstractcollisionqueryservice_p.h
index 1c1261937..fa35792d0 100644
--- a/src/render/raycasting/qabstractcollisionqueryservice_p.h
+++ b/src/render/raycasting/qabstractcollisionqueryservice_p.h
@@ -97,8 +97,8 @@ protected:
QAbstractCollisionQueryService(QAbstractCollisionQueryServicePrivate &dd);
void setResultHandle(QCollisionQueryResult &result, const QQueryHandle &handle);
- void addEntityHit(QCollisionQueryResult &result, Qt3DCore::QNodeId entity, const QVector3D &intersection,
- float distance, const QVector3D &uvw);
+ void addEntityHit(QCollisionQueryResult &result, Qt3DCore::QNodeId entity, const Vector3D &intersection,
+ float distance, const Vector3D &uvw);
private:
Q_DECLARE_PRIVATE(QAbstractCollisionQueryService)
diff --git a/src/render/raycasting/qboundingvolume_p.h b/src/render/raycasting/qboundingvolume_p.h
index 8267c2b18..b63463f23 100644
--- a/src/render/raycasting/qboundingvolume_p.h
+++ b/src/render/raycasting/qboundingvolume_p.h
@@ -53,6 +53,7 @@
#include <Qt3DRender/qt3drender_global.h>
#include <Qt3DCore/qnodeid.h>
+#include <Qt3DCore/private/vector3d_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
@@ -72,8 +73,8 @@ public:
};
virtual Qt3DCore::QNodeId id() const = 0;
- virtual bool intersects(const QRay3D &ray, QVector3D *q = nullptr,
- QVector3D *uvw = nullptr) const = 0;
+ virtual bool intersects(const QRay3D &ray, Vector3D *q = nullptr,
+ Vector3D *uvw = nullptr) const = 0;
virtual Type type() const = 0;
};
diff --git a/src/render/raycasting/qcollisionqueryresult.cpp b/src/render/raycasting/qcollisionqueryresult.cpp
index 62975200c..9d1e484b6 100644
--- a/src/render/raycasting/qcollisionqueryresult.cpp
+++ b/src/render/raycasting/qcollisionqueryresult.cpp
@@ -56,8 +56,8 @@ QCollisionQueryResultPrivate::QCollisionQueryResultPrivate(const QCollisionQuery
{
}
-void QCollisionQueryResultPrivate::addEntityHit(Qt3DCore::QNodeId entity, const QVector3D& intersection,
- float distance, const QVector3D& uvw)
+void QCollisionQueryResultPrivate::addEntityHit(Qt3DCore::QNodeId entity, const Vector3D& intersection,
+ float distance, const Vector3D& uvw)
{
m_hits.append(QCollisionQueryResult::Hit(entity, intersection, distance, uvw));
}
diff --git a/src/render/raycasting/qcollisionqueryresult_p.h b/src/render/raycasting/qcollisionqueryresult_p.h
index 1a430e019..24371d30e 100644
--- a/src/render/raycasting/qcollisionqueryresult_p.h
+++ b/src/render/raycasting/qcollisionqueryresult_p.h
@@ -53,8 +53,8 @@
#include <Qt3DRender/qt3drender_global.h>
#include <Qt3DCore/qnodeid.h>
+#include <Qt3DCore/private/vector3d_p.h>
#include <QVector>
-#include <QVector3D>
#include <QSharedData>
QT_BEGIN_NAMESPACE
@@ -84,7 +84,7 @@ public:
m_vertexIndex[0] = m_vertexIndex[1] = m_vertexIndex[2] = 0;
}
- Hit(Qt3DCore::QNodeId entity, const QVector3D &intersection, float distance, const QVector3D &uvw)
+ Hit(Qt3DCore::QNodeId entity, const Vector3D &intersection, float distance, const Vector3D &uvw)
: m_entityId(entity)
, m_intersection(intersection)
, m_distance(distance)
@@ -94,11 +94,11 @@ public:
Qt3DCore::QNodeId m_entityId;
HitType m_type;
- QVector3D m_intersection;
+ Vector3D m_intersection;
float m_distance;
uint m_primitiveIndex;
uint m_vertexIndex[3];
- QVector3D m_uvw;
+ Vector3D m_uvw;
};
QCollisionQueryResult();
@@ -146,8 +146,8 @@ public:
explicit QCollisionQueryResultPrivate(const QCollisionQueryResultPrivate &copy);
void setHandle(const QQueryHandle &handle);
- void addEntityHit(Qt3DCore::QNodeId entity, const QVector3D& intersection, float distance,
- const QVector3D& uvw);
+ void addEntityHit(Qt3DCore::QNodeId entity, const Vector3D& intersection, float distance,
+ const Vector3D& uvw);
QQueryHandle m_handle;
QVector<QCollisionQueryResult::Hit> m_hits;
diff --git a/src/render/raycasting/qray3d.cpp b/src/render/raycasting/qray3d.cpp
index 3f136deb8..40d16bc73 100644
--- a/src/render/raycasting/qray3d.cpp
+++ b/src/render/raycasting/qray3d.cpp
@@ -93,7 +93,7 @@ QRay3D::QRay3D()
QRay3D thruAB(pointA, pointB - pointA);
\endcode
*/
-QRay3D::QRay3D(const QVector3D &origin, const QVector3D &direction, float distance)
+QRay3D::QRay3D(const Vector3D &origin, const Vector3D &direction, float distance)
: m_origin(origin)
, m_direction(direction)
, m_distance(distance)
@@ -110,7 +110,7 @@ QRay3D::~QRay3D()
\sa setOrigin(), direction()
*/
-QVector3D QRay3D::origin() const
+Vector3D QRay3D::origin() const
{
return m_origin;
}
@@ -122,7 +122,7 @@ QVector3D QRay3D::origin() const
\sa origin(), setDirection()
*/
-void QRay3D::setOrigin(const QVector3D &value)
+void QRay3D::setOrigin(const Vector3D &value)
{
m_origin = value;
}
@@ -134,7 +134,7 @@ void QRay3D::setOrigin(const QVector3D &value)
\sa setDirection(), origin()
*/
-QVector3D QRay3D::direction() const
+Vector3D QRay3D::direction() const
{
return m_direction;
}
@@ -146,7 +146,7 @@ QVector3D QRay3D::direction() const
\sa direction(), setOrigin()
*/
-void QRay3D::setDirection(const QVector3D &value)
+void QRay3D::setDirection(const Vector3D &value)
{
if (value.isNull())
return;
@@ -164,12 +164,12 @@ void QRay3D::setDistance(float distance)
m_distance = distance;
}
-QVector3D QRay3D::point(float t) const
+Vector3D QRay3D::point(float t) const
{
return m_origin + t * m_direction;
}
-QRay3D &QRay3D::transform(const QMatrix4x4 &matrix)
+QRay3D &QRay3D::transform(const Matrix4x4 &matrix)
{
m_origin = matrix * m_origin;
m_direction = matrix.mapVector(m_direction);
@@ -177,7 +177,7 @@ QRay3D &QRay3D::transform(const QMatrix4x4 &matrix)
return *this;
}
-QRay3D QRay3D::transformed(const QMatrix4x4 &matrix) const
+QRay3D QRay3D::transformed(const Matrix4x4 &matrix) const
{
return QRay3D(matrix * m_origin, matrix.mapVector(m_direction));
}
@@ -195,12 +195,12 @@ bool QRay3D::operator!=(const QRay3D &other) const
/*!
Returns true if \a point lies on this ray; false otherwise.
*/
-bool QRay3D::contains(const QVector3D &point) const
+bool QRay3D::contains(const Vector3D &point) const
{
- QVector3D ppVec(point - m_origin);
+ Vector3D ppVec(point - m_origin);
if (ppVec.isNull()) // point coincides with origin
return true;
- const float dot = QVector3D::dotProduct(ppVec, m_direction);
+ const float dot = Vector3D ::dotProduct(ppVec, m_direction);
if (qFuzzyIsNull(dot))
return false;
return qFuzzyCompare(dot*dot, ppVec.lengthSquared() * m_direction.lengthSquared());
@@ -213,7 +213,7 @@ bool QRay3D::contains(const QVector3D &point) const
*/
bool QRay3D::contains(const QRay3D &ray) const
{
- const float dot = QVector3D::dotProduct(m_direction, ray.direction());
+ const float dot = Vector3D ::dotProduct(m_direction, ray.direction());
if (!qFuzzyCompare(dot*dot, m_direction.lengthSquared() * ray.direction().lengthSquared()))
return false;
return contains(ray.origin());
@@ -247,11 +247,11 @@ bool QRay3D::contains(const QRay3D &ray) const
\sa point(), project()
*/
-float QRay3D::projectedDistance(const QVector3D &point) const
+float QRay3D::projectedDistance(const Vector3D &point) const
{
Q_ASSERT(!m_direction.isNull());
- return QVector3D::dotProduct(point - m_origin, m_direction) /
+ return Vector3D ::dotProduct(point - m_origin, m_direction) /
m_direction.lengthSquared();
}
@@ -264,10 +264,10 @@ float QRay3D::projectedDistance(const QVector3D &point) const
\sa projectedDistance()
*/
-QVector3D QRay3D::project(const QVector3D &vector) const
+Vector3D QRay3D::project(const Vector3D &vector) const
{
- QVector3D norm = m_direction.normalized();
- return QVector3D::dotProduct(vector, norm) * norm;
+ Vector3D norm = m_direction.normalized();
+ return Vector3D ::dotProduct(vector, norm) * norm;
}
/*!
@@ -277,7 +277,7 @@ QVector3D QRay3D::project(const QVector3D &vector) const
\sa point()
*/
-float QRay3D::distance(const QVector3D &point) const
+float QRay3D::distance(const Vector3D &point) const
{
float t = projectedDistance(point);
return (point - (m_origin + t * m_direction)).length();
@@ -350,8 +350,8 @@ QDebug operator<<(QDebug dbg, const QRay3D &ray)
*/
QDataStream &operator<<(QDataStream &stream, const QRay3D &ray)
{
- stream << ray.origin();
- stream << ray.direction();
+ stream << convertToQVector3D(ray.origin());
+ stream << convertToQVector3D(ray.direction());
return stream;
}
@@ -364,9 +364,10 @@ QDataStream &operator<<(QDataStream &stream, const QRay3D &ray)
QDataStream &operator>>(QDataStream &stream, QRay3D &ray)
{
QVector3D origin, direction;
+
stream >> origin;
stream >> direction;
- ray = QRay3D(origin, direction);
+ ray = QRay3D(Vector3D(origin), Vector3D(direction));
return stream;
}
diff --git a/src/render/raycasting/qray3d_p.h b/src/render/raycasting/qray3d_p.h
index 7c1156b76..8b7852cc3 100644
--- a/src/render/raycasting/qray3d_p.h
+++ b/src/render/raycasting/qray3d_p.h
@@ -53,8 +53,8 @@
//
#include <Qt3DRender/qt3drender_global.h>
-#include <QtGui/qvector3d.h>
-#include <QtGui/qmatrix4x4.h>
+#include <Qt3DCore/private/matrix4x4_p.h>
+#include <Qt3DCore/private/vector3d_p.h>
QT_BEGIN_NAMESPACE
@@ -65,37 +65,39 @@ class QT3DRENDERSHARED_EXPORT QRay3D
{
public:
QRay3D();
- explicit QRay3D(const QVector3D &origin, const QVector3D &direction = QVector3D(0.0f, 0.0f, 1.0f), float distance = 1.0f);
+ explicit QRay3D(const Vector3D &origin, const Vector3D &direction = Vector3D(0.0f, 0.0f, 1.0f), float distance = 1.0f);
~QRay3D();
- QVector3D origin() const;
- void setOrigin(const QVector3D &value);
+ Vector3D origin() const;
+ void setOrigin(const Vector3D &value);
- QVector3D direction() const;
- void setDirection(const QVector3D &value);
+ Vector3D direction() const;
+ void setDirection(const Vector3D &value);
float distance() const;
void setDistance(float distance);
- bool contains(const QVector3D &point) const;
+ bool contains(const Vector3D &point) const;
bool contains(const QRay3D &ray) const;
- QVector3D point(float t) const;
- float projectedDistance(const QVector3D &point) const;
+ Vector3D point(float t) const;
+ float projectedDistance(const Vector3D &point) const;
- QVector3D project(const QVector3D &vector) const;
+ Vector3D project(const Vector3D &vector) const;
- float distance(const QVector3D &point) const;
+ float distance(const Vector3D &point) const;
- QRay3D &transform(const QMatrix4x4 &matrix);
- QRay3D transformed(const QMatrix4x4 &matrix) const;
+ QRay3D &transform(const Matrix4x4 &matrix);
+ QRay3D transformed(const Matrix4x4 &matrix) const;
bool operator==(const QRay3D &other) const;
bool operator!=(const QRay3D &other) const;
+ bool isValid() const { return !m_direction.isNull() && !qFuzzyIsNull(m_distance); }
+
private:
- QVector3D m_origin;
- QVector3D m_direction;
+ Vector3D m_origin;
+ Vector3D m_direction;
float m_distance;
};
QT3D_DECLARE_TYPEINFO_2(Qt3DRender, RayCasting, QRay3D, Q_MOVABLE_TYPE)
diff --git a/src/render/raycasting/qraycastingservice.cpp b/src/render/raycasting/qraycastingservice.cpp
index e0c7b6199..8debeac6a 100644
--- a/src/render/raycasting/qraycastingservice.cpp
+++ b/src/render/raycasting/qraycastingservice.cpp
@@ -67,8 +67,8 @@ struct Hit
bool intersects;
float distance;
Qt3DCore::QNodeId id;
- QVector3D intersection;
- QVector3D uvw;
+ Vector3D intersection;
+ Vector3D uvw;
};
bool compareHitsDistance(const Hit &a, const Hit &b)
diff --git a/src/render/render.pro b/src/render/render.pro
index 29110abea..3929cb121 100644
--- a/src/render/render.pro
+++ b/src/render/render.pro
@@ -28,10 +28,21 @@ gcov {
QMAKE_LFLAGS += -fprofile-arcs -ftest-coverage
}
+qtConfig(qt3d-simd-avx2) {
+ CONFIG += simd
+ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AVX2
+}
+
+qtConfig(qt3d-simd-sse2):!qtConfig(qt3d-simd-avx2) {
+ CONFIG += simd
+ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2
+}
+
HEADERS += \
renderlogging_p.h \
qt3drender_global.h \
- qt3drender_global_p.h
+ qt3drender_global_p.h \
+ aligned_malloc_p.h
SOURCES += \
renderlogging.cpp
diff --git a/src/render/services/vsyncframeadvanceservice.cpp b/src/render/services/vsyncframeadvanceservice.cpp
index 8749a54ab..c8437e20d 100644
--- a/src/render/services/vsyncframeadvanceservice.cpp
+++ b/src/render/services/vsyncframeadvanceservice.cpp
@@ -89,7 +89,7 @@ qint64 VSyncFrameAdvanceService::waitForNextFrame()
if (d->m_drivenByRenderThread)
d->m_semaphore.acquire(1);
else
- d->m_semaphore.acquire(d->m_semaphore.available() + 1);
+ d->m_semaphore.acquire(d->m_semaphore.available());
const quint64 currentTime = d->m_elapsed.nsecsElapsed();
qCDebug(VSyncAdvanceService) << "Elapsed nsecs since last call " << currentTime - d->m_elapsedTimeSincePreviousFrame;
diff --git a/tests/auto/core/common/common.pri b/tests/auto/core/common/common.pri
index 3a85df875..9b761b8e0 100644
--- a/tests/auto/core/common/common.pri
+++ b/tests/auto/core/common/common.pri
@@ -15,3 +15,13 @@ qtConfig(private_tests) {
}
QT += core-private 3dcore 3dcore-private
+
+qtConfig(qt3d-simd-avx2) {
+ CONFIG += simd
+ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AVX2
+}
+
+qtConfig(qt3d-simd-sse2):!qtConfig(qt3d-simd-avx2) {
+ CONFIG += simd
+ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2
+}
diff --git a/tests/auto/core/matrix4x4_avx2/matrix4x4_avx2.pro b/tests/auto/core/matrix4x4_avx2/matrix4x4_avx2.pro
index 4a97ab2a9..4db8a1975 100644
--- a/tests/auto/core/matrix4x4_avx2/matrix4x4_avx2.pro
+++ b/tests/auto/core/matrix4x4_avx2/matrix4x4_avx2.pro
@@ -1,6 +1,6 @@
TARGET = tst_matrix4x4_avx2
CONFIG += testcase
-QT += testlib 3dcore 3dcore-private
+QT += testlib 3dcore 3dcore-private 3drender-private
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AVX2
diff --git a/tests/auto/core/matrix4x4_avx2/tst_matrix4x4_avx2.cpp b/tests/auto/core/matrix4x4_avx2/tst_matrix4x4_avx2.cpp
index 41b0c535c..144df6711 100644
--- a/tests/auto/core/matrix4x4_avx2/tst_matrix4x4_avx2.cpp
+++ b/tests/auto/core/matrix4x4_avx2/tst_matrix4x4_avx2.cpp
@@ -28,12 +28,15 @@
#include <QtTest/QtTest>
#include <Qt3DCore/private/matrix4x4_avx2_p.h>
+#include <Qt3DRender/private/aligned_malloc_p.h>
using namespace Qt3DCore;
class tst_Matrix4x4_AVX2: public QObject
{
Q_OBJECT
+public:
+ QT3D_ALIGNED_MALLOC_AND_FREE()
private Q_SLOTS:
diff --git a/tests/auto/core/nodes/tst_nodes.cpp b/tests/auto/core/nodes/tst_nodes.cpp
index 2e73e6c34..baf7010b0 100644
--- a/tests/auto/core/nodes/tst_nodes.cpp
+++ b/tests/auto/core/nodes/tst_nodes.cpp
@@ -1041,15 +1041,22 @@ void tst_Nodes::appendingParentlessComponentToEntity()
// return early in such a case.
// Check that we received ComponentAdded
- for (const auto event: { entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>(),
- componentSpy.events.takeLast().change().dynamicCast<Qt3DCore::QComponentAddedChange>() })
{
+ const auto event = entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>();
QCOMPARE(event->type(), Qt3DCore::ComponentAdded);
QCOMPARE(event->subjectId(), entity->id());
QCOMPARE(event->entityId(), entity->id());
QCOMPARE(event->componentId(), comp->id());
QCOMPARE(event->componentMetaObject(), comp->metaObject());
}
+ {
+ const auto event = componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>();
+ QCOMPARE(event->type(), Qt3DCore::ComponentAdded);
+ QCOMPARE(event->subjectId(), comp->id());
+ QCOMPARE(event->entityId(), entity->id());
+ QCOMPARE(event->componentId(), comp->id());
+ QCOMPARE(event->componentMetaObject(), comp->metaObject());
+ }
}
}
@@ -1080,15 +1087,22 @@ void tst_Nodes::appendingComponentToEntity()
QVERIFY(comp->parentNode() == entity.data());
QCOMPARE(entitySpy.events.size(), 1);
QVERIFY(entitySpy.events.first().wasLocked());
- for (const auto event: { entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>(),
- componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>() })
{
+ const auto event = entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>();
QCOMPARE(event->type(), Qt3DCore::ComponentAdded);
QCOMPARE(event->subjectId(), entity->id());
QCOMPARE(event->entityId(), entity->id());
QCOMPARE(event->componentId(), comp->id());
QCOMPARE(event->componentMetaObject(), comp->metaObject());
}
+ {
+ const auto event = componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>();
+ QCOMPARE(event->type(), Qt3DCore::ComponentAdded);
+ QCOMPARE(event->subjectId(), comp->id());
+ QCOMPARE(event->entityId(), entity->id());
+ QCOMPARE(event->componentId(), comp->id());
+ QCOMPARE(event->componentMetaObject(), comp->metaObject());
+ }
}
}
@@ -1123,14 +1137,22 @@ void tst_Nodes::removingComponentFromEntity()
QCOMPARE(entitySpy.events.size(), 1);
QVERIFY(entitySpy.events.first().wasLocked());
QCOMPARE(componentSpy.events.size(), 1);
- for (const auto event: { entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentRemovedChange>(),
- componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentRemovedChange>() }) {
+ {
+ const auto event = entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentRemovedChange>();
QCOMPARE(event->type(), Qt3DCore::ComponentRemoved);
QCOMPARE(event->subjectId(), entity->id());
QCOMPARE(event->entityId(), entity->id());
QCOMPARE(event->componentId(), comp->id());
QCOMPARE(event->componentMetaObject(), comp->metaObject());
}
+ {
+ const auto event = componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentRemovedChange>();
+ QCOMPARE(event->type(), Qt3DCore::ComponentRemoved);
+ QCOMPARE(event->subjectId(), comp->id());
+ QCOMPARE(event->entityId(), entity->id());
+ QCOMPARE(event->componentId(), comp->id());
+ QCOMPARE(event->componentMetaObject(), comp->metaObject());
+ }
}
}
diff --git a/tests/auto/core/vector3d_sse/tst_vector3d_sse.cpp b/tests/auto/core/vector3d_sse/tst_vector3d_sse.cpp
index be9fbc347..7ea79a5f5 100644
--- a/tests/auto/core/vector3d_sse/tst_vector3d_sse.cpp
+++ b/tests/auto/core/vector3d_sse/tst_vector3d_sse.cpp
@@ -668,6 +668,14 @@ private Q_SLOTS:
// THEN
QVERIFY(v0 == v1);
}
+ {
+ // GIVEN
+ Vector3D_SSE v0(6.0f, 6.0f, 6.0f);
+ Vector3D_SSE v1(6.0f, 6.0f, 6.0f);
+
+ // THEN
+ QVERIFY(v0 == v1);
+ }
}
void checkInequality()
@@ -787,11 +795,6 @@ private Q_SLOTS:
}
}
- void checkNormalized()
- {
-
- }
-
void checkIsNull()
{
{
diff --git a/tests/auto/core/vector4d_sse/tst_vector4d_sse.cpp b/tests/auto/core/vector4d_sse/tst_vector4d_sse.cpp
index e7b58c8cf..ed9722ffb 100644
--- a/tests/auto/core/vector4d_sse/tst_vector4d_sse.cpp
+++ b/tests/auto/core/vector4d_sse/tst_vector4d_sse.cpp
@@ -823,6 +823,98 @@ private Q_SLOTS:
QCOMPARE(v0.w(), v1.w());
}
}
+
+ void checkLengthSquared()
+ {
+ {
+ // GIVEN
+ Vector4D_SSE v0(10.0f, 10.0f, 10.0f, 10.0f);
+
+ // THEN
+ QCOMPARE(v0.lengthSquared(), 400.0f);
+ }
+ {
+ // GIVEN
+ Vector4D_SSE v0(3.0f, 1.0f, 2.0f, 4.0f);
+
+ // THEN
+ QCOMPARE(v0.lengthSquared(), 30.0f);
+ }
+ }
+
+ void checkLength()
+ {
+ {
+ // GIVEN
+ Vector4D_SSE v0(3.0f, 0.0f, 0.0f, 0.0f);
+
+ // THEN
+ QCOMPARE(v0.length(), 3.0f);
+ }
+ {
+ // GIVEN
+ Vector4D_SSE v0(0.0f, 10.0f, 0.0f, 0.0f);
+
+ // THEN
+ QCOMPARE(v0.length(), 10.0f);
+ }
+ {
+ // GIVEN
+ Vector4D_SSE v0(0.0f, 0.0f, 9.0f, 0.0f);
+
+ // THEN
+ QCOMPARE(v0.length(), 9.0f);
+ }
+ {
+ // GIVEN
+ Vector4D_SSE v0(0.0f, 0.0f, 0.0f, 8.0f);
+
+ // THEN
+ QCOMPARE(v0.length(), 8.0f);
+ }
+ }
+
+ void checkNormalize()
+ {
+ {
+ // GIVEN
+ Vector4D_SSE v0(10.0f, 0.0f, 0.0f, 0.0f);
+
+ // WHEN
+ v0.normalize();
+
+ // THEN
+ QCOMPARE(v0, Vector4D_SSE(1.0f, 0.0f, 0.0f, 0.0f));
+ }
+ {
+ // GIVEN
+ Vector4D_SSE v0(0.0f, 0.0f, 3.0f, 0.0f);
+
+ // WHEN
+ v0.normalize();
+
+ // THEN
+ QCOMPARE(v0, Vector4D_SSE(0.0, 0.0f, 1.0f, 0.0f));
+ }
+ }
+
+ void checkIsNull()
+ {
+ {
+ // GIVEN
+ Vector4D_SSE v0;
+
+ // THEN
+ QVERIFY(v0.isNull());
+ }
+ {
+ // GIVEN
+ Vector4D_SSE v0(1.0f, 1.0f, 1.0f, 1.0f);
+
+ // THEN
+ QVERIFY(!v0.isNull());
+ }
+ }
};
QTEST_APPLESS_MAIN(tst_Vector4D_SSE)
diff --git a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp
index ce55db432..992e643d2 100644
--- a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp
+++ b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp
@@ -330,7 +330,98 @@ private Q_SLOTS:
calcBVolume.setRoot(test->sceneRoot());
calcBVolume.run();
- QVector3D center = entityBackend->localBoundingVolume()->center();
+ Vector3D center = entityBackend->localBoundingVolume()->center();
+ float radius = entityBackend->localBoundingVolume()->radius();
+ qDebug() << radius << center;
+
+ // truncate and compare integers only
+ QVERIFY(int(radius) == int(expectedRadius));
+ QVERIFY(int(center.x()) == int(expectedCenter.x()));
+ QVERIFY(int(center.y()) == int(expectedCenter.y()));
+ QVERIFY(int(center.z()) == int(expectedCenter.z()));
+ }
+
+ void checkCustomPackedGeometry()
+ {
+ int drawVertexCount = 6;
+ QVector3D expectedCenter(-0.488892f, 0.0192147f, -75.4804f);
+ float expectedRadius = 25.5442f;
+
+ // two triangles with different Z
+ QByteArray vdata;
+ vdata.resize(6 * 3 * sizeof(float));
+ float *vp = reinterpret_cast<float *>(vdata.data());
+ *vp++ = -1.0f;
+ *vp++ = 1.0f;
+ *vp++ = -100.0f;
+ *vp++ = 0.0f;
+ *vp++ = 0.0f;
+ *vp++ = -100.0f;
+ *vp++ = 1.0f;
+ *vp++ = 1.0f;
+ *vp++ = -100.0f;
+
+ *vp++ = -1.0f;
+ *vp++ = -1.0f;
+ *vp++ = -50.0f;
+ *vp++ = 0.0f;
+ *vp++ = 0.0f;
+ *vp++ = -50.0f;
+ *vp++ = 1.0f;
+ *vp++ = -1.0f;
+ *vp++ = -50.0f;
+
+ QScopedPointer<Qt3DCore::QEntity> entity(new Qt3DCore::QEntity);
+ QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(entity.data()));
+ Qt3DRender::QBuffer *vbuffer = new Qt3DRender::QBuffer;
+
+ vbuffer->setData(vdata);
+ Qt3DRender::Render::Buffer *vbufferBackend = test->nodeManagers()->bufferManager()->getOrCreateResource(vbuffer->id());
+ vbufferBackend->setRenderer(test->renderer());
+ vbufferBackend->setManager(test->nodeManagers()->bufferManager());
+ simulateInitialization(vbuffer, vbufferBackend);
+
+ Qt3DRender::QGeometry *g = new Qt3DRender::QGeometry;
+ g->addAttribute(new Qt3DRender::QAttribute);
+
+ const QVector<Qt3DRender::QAttribute *> attrs = g->attributes();
+ Qt3DRender::QAttribute *attr = attrs[0];
+ attr->setBuffer(vbuffer);
+ attr->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ attr->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ attr->setVertexSize(3);
+ attr->setCount(6);
+ attr->setByteOffset(0);
+ attr->setByteStride(0);
+
+ Qt3DRender::QGeometryRenderer *gr = new Qt3DRender::QGeometryRenderer;
+ gr->setVertexCount(drawVertexCount);
+ gr->setGeometry(g);
+ entity->addComponent(gr);
+
+ Qt3DRender::Render::Attribute *attr0Backend = test->nodeManagers()->attributeManager()->getOrCreateResource(attrs[0]->id());
+ attr0Backend->setRenderer(test->renderer());
+ simulateInitialization(attrs[0], attr0Backend);
+
+ Qt3DRender::Render::Geometry *gBackend = test->nodeManagers()->geometryManager()->getOrCreateResource(g->id());
+ gBackend->setRenderer(test->renderer());
+ simulateInitialization(g, gBackend);
+
+ Qt3DRender::Render::GeometryRenderer *grBackend = test->nodeManagers()->geometryRendererManager()->getOrCreateResource(gr->id());
+ grBackend->setRenderer(test->renderer());
+ grBackend->setManager(test->nodeManagers()->geometryRendererManager());
+ simulateInitialization(gr, grBackend);
+
+ Qt3DRender::Render::Entity *entityBackend = test->nodeManagers()->renderNodesManager()->getOrCreateResource(entity->id());
+ entityBackend->setRenderer(test->renderer());
+ simulateInitialization(entity.data(), entityBackend);
+
+ Qt3DRender::Render::CalculateBoundingVolumeJob calcBVolume;
+ calcBVolume.setManagers(test->nodeManagers());
+ calcBVolume.setRoot(test->sceneRoot());
+ calcBVolume.run();
+
+ Vector3D center = entityBackend->localBoundingVolume()->center();
float radius = entityBackend->localBoundingVolume()->radius();
qDebug() << radius << center;
diff --git a/tests/auto/render/commons/testrenderer.h b/tests/auto/render/commons/testrenderer.h
index b3f602dc2..9624f129a 100644
--- a/tests/auto/render/commons/testrenderer.h
+++ b/tests/auto/render/commons/testrenderer.h
@@ -52,7 +52,7 @@ public:
void shutdown() override {}
void releaseGraphicsResources() override {}
void render() override {}
- void doRender(bool scene3dBlocking = false) override { Q_UNUSED(scene3dBlocking); }
+ void doRender() override {}
void cleanGraphicsResources() override {}
bool isRunning() const override { return true; }
bool shouldRender() override { return true; }
@@ -60,7 +60,7 @@ public:
QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); }
Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override { return Qt3DCore::QAspectJobPtr(); }
Qt3DCore::QAspectJobPtr rayCastingJob() override { return Qt3DCore::QAspectJobPtr(); }
- Qt3DCore::QAspectJobPtr syncTextureLoadingJob() override { return Qt3DCore::QAspectJobPtr(); }
+ Qt3DCore::QAspectJobPtr syncSkeletonLoadingJob() override { return Qt3DCore::QAspectJobPtr(); }
Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() override { return Qt3DCore::QAspectJobPtr(); }
void setSceneRoot(Qt3DCore::QBackendNodeFactory *factory, Qt3DRender::Render::Entity *root) override { Q_UNUSED(factory); Q_UNUSED(root); }
Qt3DRender::Render::Entity *sceneRoot() const override { return nullptr; }
@@ -81,6 +81,12 @@ public:
void setOffscreenSurfaceHelper(Qt3DRender::Render::OffscreenSurfaceHelper *helper) override;
QSurfaceFormat format() override;
+ void lockSurfaceAndRender() override {}
+ bool releaseRendererAndRequestPromiseToRender() override { return true; }
+ bool waitForRenderJobs() override { return true; }
+ bool tryWaitForRenderJobs(int timeout) override { Q_UNUSED(timeout); return true; }
+ void abortRenderJobs() override {}
+
protected:
Qt3DRender::Render::AbstractRenderer::BackendNodeDirtySet m_changes;
Qt3DRender::Render::NodeManagers *m_managers;
diff --git a/tests/auto/render/coordinatereader/tst_coordinatereader.cpp b/tests/auto/render/coordinatereader/tst_coordinatereader.cpp
index 7dfe3ceba..afb18fe55 100644
--- a/tests/auto/render/coordinatereader/tst_coordinatereader.cpp
+++ b/tests/auto/render/coordinatereader/tst_coordinatereader.cpp
@@ -67,7 +67,7 @@ public:
{
return m_bufferInfo;
}
- bool verifyCoordinate(uint index, QVector4D value)
+ bool verifyCoordinate(uint index, Vector4D value)
{
return qFuzzyCompare(getCoordinate(index), value);
}
@@ -270,12 +270,12 @@ private Q_SLOTS:
// THEN
QCOMPARE(ret, true);
- QVERIFY(reader.verifyCoordinate(0, QVector4D(0, 0, 1, 1)));
- QVERIFY(reader.verifyCoordinate(1, QVector4D(1, 0, 0, 1)));
- QVERIFY(reader.verifyCoordinate(2, QVector4D(0, 1, 0, 1)));
- QVERIFY(reader.verifyCoordinate(3, QVector4D(0, 0, 1, 1)));
- QVERIFY(reader.verifyCoordinate(4, QVector4D(1, 0, 0, 1)));
- QVERIFY(reader.verifyCoordinate(5, QVector4D(0, 1, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(0, Vector4D(0, 0, 1, 1)));
+ QVERIFY(reader.verifyCoordinate(1, Vector4D(1, 0, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(2, Vector4D(0, 1, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(3, Vector4D(0, 0, 1, 1)));
+ QVERIFY(reader.verifyCoordinate(4, Vector4D(1, 0, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(5, Vector4D(0, 1, 0, 1)));
}
void testReadCoordinateVec4()
@@ -364,12 +364,12 @@ private Q_SLOTS:
// THEN
QCOMPARE(ret, true);
- QVERIFY(reader.verifyCoordinate(0, QVector4D(0, 0, 1, 1)));
- QVERIFY(reader.verifyCoordinate(1, QVector4D(1, 0, 0, 1)));
- QVERIFY(reader.verifyCoordinate(2, QVector4D(0, 1, 0, 0)));
- QVERIFY(reader.verifyCoordinate(3, QVector4D(0, 0, 1, 0)));
- QVERIFY(reader.verifyCoordinate(4, QVector4D(1, 0, 0, 0)));
- QVERIFY(reader.verifyCoordinate(5, QVector4D(0, 1, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(0, Vector4D(0, 0, 1, 1)));
+ QVERIFY(reader.verifyCoordinate(1, Vector4D(1, 0, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(2, Vector4D(0, 1, 0, 0)));
+ QVERIFY(reader.verifyCoordinate(3, Vector4D(0, 0, 1, 0)));
+ QVERIFY(reader.verifyCoordinate(4, Vector4D(1, 0, 0, 0)));
+ QVERIFY(reader.verifyCoordinate(5, Vector4D(0, 1, 0, 1)));
}
void testReadCoordinateFromAttribute()
@@ -468,9 +468,9 @@ private Q_SLOTS:
// THEN
QCOMPARE(ret, true);
- QVERIFY(reader.verifyCoordinate(0, QVector4D(0, 0, 1, 1)));
- QVERIFY(reader.verifyCoordinate(1, QVector4D(0, 1, 0, 1)));
- QVERIFY(reader.verifyCoordinate(2, QVector4D(1, 0, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(0, Vector4D(0, 0, 1, 1)));
+ QVERIFY(reader.verifyCoordinate(1, Vector4D(0, 1, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(2, Vector4D(1, 0, 0, 1)));
// WHEN
ret = reader.setGeometry(backendRenderer,
@@ -479,9 +479,9 @@ private Q_SLOTS:
// THEN
QCOMPARE(ret, true);
- QVERIFY(reader.verifyCoordinate(0, QVector4D(1, 0, 0, 1)));
- QVERIFY(reader.verifyCoordinate(1, QVector4D(0, 0, 1, 1)));
- QVERIFY(reader.verifyCoordinate(2, QVector4D(0, 1, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(0, Vector4D(1, 0, 0, 1)));
+ QVERIFY(reader.verifyCoordinate(1, Vector4D(0, 0, 1, 1)));
+ QVERIFY(reader.verifyCoordinate(2, Vector4D(0, 1, 0, 1)));
}
};
diff --git a/tests/auto/render/filtercompatibletechniquejob/tst_filtercompatibletechniquejob.cpp b/tests/auto/render/filtercompatibletechniquejob/tst_filtercompatibletechniquejob.cpp
index 4d4a08a34..803d57fa9 100644
--- a/tests/auto/render/filtercompatibletechniquejob/tst_filtercompatibletechniquejob.cpp
+++ b/tests/auto/render/filtercompatibletechniquejob/tst_filtercompatibletechniquejob.cpp
@@ -93,7 +93,8 @@ public:
{
renderer()->setOpenGLContext(&m_glContext);
d_func()->m_renderer->initialize();
- renderer()->graphicsContext()->beginDrawing(m_window.data());
+ renderer()->graphicsContext()->makeCurrent(m_window.data());
+ renderer()->graphicsContext()->beginDrawing();
}
Render::Renderer *renderer() const
diff --git a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
index d07ec9914..e61fdf6e5 100644
--- a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
+++ b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
@@ -30,6 +30,7 @@
#include <qbackendnodetester.h>
#include <Qt3DRender/private/geometryrenderer_p.h>
#include <Qt3DRender/private/geometryrenderermanager_p.h>
+#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/qgeometry.h>
#include <Qt3DRender/qgeometryfactory.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
@@ -186,6 +187,8 @@ private Q_SLOTS:
// GIVEN
Qt3DRender::Render::GeometryRenderer renderGeometryRenderer;
TestRenderer renderer;
+ Qt3DRender::Render::NodeManagers nodeManagers;
+
renderGeometryRenderer.setRenderer(&renderer);
QVERIFY(!renderGeometryRenderer.isDirty());
diff --git a/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc b/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc
index c2b0c7fff..feef480e2 100644
--- a/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc
+++ b/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc
@@ -8,5 +8,7 @@
<file>testscene_pickersdisabled.qml</file>
<file>testscene_dragenabledoverlapping.qml</file>
<file>testscene_parententity.qml</file>
+ <file>testscene_viewports.qml</file>
+ <file>testscene_cameraposition.qml</file>
</qresource>
</RCC>
diff --git a/tests/auto/render/pickboundingvolumejob/testscene_cameraposition.qml b/tests/auto/render/pickboundingvolumejob/testscene_cameraposition.qml
new file mode 100644
index 000000000..87e7a8aac
--- /dev/null
+++ b/tests/auto/render/pickboundingvolumejob/testscene_cameraposition.qml
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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.Extras 2.0
+import QtQuick.Window 2.0
+
+Entity {
+ id: sceneRoot
+
+ Window {
+ id: win
+ width: 600
+ height: 600
+ visible: true
+ }
+
+ Camera {
+ id: camera
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ 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( 5.0, 3.0, 1.0 )
+ }
+
+ components: [
+ RenderSettings {
+ Viewport {
+ normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
+
+ RenderSurfaceSelector {
+
+ surface: win
+
+ ClearBuffers {
+ buffers : ClearBuffers.ColorDepthBuffer
+ NoDraw {}
+ }
+
+ CameraSelector {
+ camera: camera
+ }
+ }
+ }
+ }
+ ]
+
+ CuboidMesh { id: cubeMesh }
+ PhongMaterial { id: material }
+
+ Entity {
+ property ObjectPicker picker: ObjectPicker {
+ objectName: "Picker"
+ }
+
+ property Transform transform: Transform {
+ translation: camera.viewCenter
+ scale: 2.0
+ }
+
+ components: [cubeMesh, material, picker, transform]
+ }
+
+}
diff --git a/tests/auto/render/pickboundingvolumejob/testscene_viewports.qml b/tests/auto/render/pickboundingvolumejob/testscene_viewports.qml
new file mode 100644
index 000000000..daafc0edd
--- /dev/null
+++ b/tests/auto/render/pickboundingvolumejob/testscene_viewports.qml
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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.Extras 2.0
+import QtQuick.Window 2.0
+
+Entity {
+ id: sceneRoot
+
+ Window {
+ id: _view
+ width: 600
+ height: 600
+ visible: true
+ }
+
+ Camera {
+ id: camera
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ aspectRatio: _view.width / 2 / _view.height
+ nearPlane : 0.1
+ farPlane : 1000.0
+ position: Qt.vector3d( 0.0, 0.0, -10.0 )
+ upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
+ viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
+ }
+
+ Camera {
+ id: camera2
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ aspectRatio: _view.width / _view.height
+ 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 )
+ }
+
+ FirstPersonCameraController {
+ camera: camera
+ }
+
+ DirectionalLight {
+ worldDirection: camera.viewVector.times(-1)
+ }
+
+ // Draw 2 viewports
+ // one with the content, the other with content + debug volumes
+ components: [
+ RenderSettings {
+ Viewport {
+ normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
+
+ RenderSurfaceSelector {
+ surface: _view
+
+ Viewport {
+ normalizedRect: Qt.rect(0.0, 0.0, 0.5, 1.0)
+ ClearBuffers {
+ buffers : ClearBuffers.ColorDepthBuffer
+ clearColor: "white"
+ CameraSelector {
+ camera: camera
+ }
+ }
+ }
+
+ Viewport {
+ normalizedRect: Qt.rect(0.5, 0.0, 0.5, 1.0)
+ CameraSelector {
+ camera: camera2
+ }
+ }
+ }
+ }
+ }
+ ]
+
+ CuboidMesh { id: cubeMesh }
+
+ Entity {
+ readonly property ObjectPicker objectPicker: ObjectPicker {
+ onClicked: console.log("o1")
+ }
+ readonly property Transform transform: Transform {
+ scale: 3
+ translation: Qt.vector3d(3, 0, 0)
+ }
+ readonly property PhongMaterial material: PhongMaterial { diffuse: "red" }
+
+ components: [cubeMesh, transform, material, objectPicker ]
+ }
+
+ Entity {
+ readonly property ObjectPicker objectPicker: ObjectPicker {
+ objectName: "Picker2"
+ onClicked: console.log("o2")
+ }
+ readonly property Transform transform: Transform {
+ scale: 3
+ translation: Qt.vector3d(-3, 0, 0)
+ }
+ readonly property PhongMaterial material: PhongMaterial { diffuse: "green" }
+
+ components: [cubeMesh, transform, material, objectPicker ]
+ }
+}
diff --git a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
index a14bccefc..b86df05a4 100644
--- a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
+++ b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
@@ -234,7 +234,7 @@ private Q_SLOTS:
// WHEN
Qt3DRender::Render::PickingUtils::ViewportCameraAreaGatherer gatherer;
- QVector<Qt3DRender::Render::PickingUtils::ViewportCameraAreaTriplet> results = gatherer.gather(test->frameGraphRoot());
+ QVector<Qt3DRender::Render::PickingUtils::ViewportCameraAreaDetails> results = gatherer.gather(test->frameGraphRoot());
// THEN
QCOMPARE(results.size(), 1);
@@ -329,8 +329,8 @@ private Q_SLOTS:
QVERIFY(pickBVJob.currentPicker().isNull());
// WHEN
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *,QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
bool earlyReturn = !pickBVJob.runHelper();
@@ -343,7 +343,7 @@ private Q_SLOTS:
// WHEN
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -353,7 +353,7 @@ private Q_SLOTS:
// WHEN
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(390.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(390.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -366,7 +366,7 @@ private Q_SLOTS:
// WHEN
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(390.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(390.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -425,8 +425,9 @@ private Q_SLOTS:
QVERIFY(earlyReturn);
// WHEN
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 440.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 440.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -474,8 +475,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
// THEN
@@ -530,9 +532,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f),
- Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
bool earlyReturn = !pickBVJob.runHelper();
@@ -580,8 +582,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
bool earlyReturn = !pickBVJob.runHelper();
@@ -591,7 +594,8 @@ private Q_SLOTS:
// WHEN
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -639,8 +643,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
bool earlyReturn = !pickBVJob.runHelper();
@@ -650,7 +655,8 @@ private Q_SLOTS:
// WHEN
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -698,8 +704,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
const bool earlyReturn = !pickBVJob.runHelper();
@@ -764,8 +771,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
bool earlyReturn = !pickBVJob.runHelper();
@@ -785,7 +793,8 @@ private Q_SLOTS:
// WHEN -> Move on same object
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -805,7 +814,8 @@ private Q_SLOTS:
// WHEN -> Release on object
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -832,8 +842,10 @@ private Q_SLOTS:
// WHEN -> Release outside of object
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(0.0f, 0.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -900,8 +912,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::HoverMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::HoverMove, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
bool earlyReturn = !pickBVJob.runHelper();
@@ -916,7 +929,8 @@ private Q_SLOTS:
// WHEN -> HoverMove Out
events.clear();
- events.push_back(QMouseEvent(QEvent::HoverMove, QPointF(20.0f, 40.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QEvent::HoverMove, QPointF(20.0f, 40.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -931,8 +945,10 @@ private Q_SLOTS:
// WHEN -> HoverMove In + Pressed other
events.clear();
- events.push_back(QMouseEvent(QEvent::HoverMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
- events.push_back(QMouseEvent(QEvent::MouseButtonPress, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QEvent::HoverMove, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ events.push_back({nullptr, QMouseEvent(QEvent::MouseButtonPress, QPointF(0.0f, 0.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -1001,8 +1017,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
bool earlyReturn = !pickBVJob.runHelper();
@@ -1017,7 +1034,8 @@ private Q_SLOTS:
// WHEN -> Move on same object
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(400.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -1032,7 +1050,8 @@ private Q_SLOTS:
// WHEN -> Release on object
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(400.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -1049,8 +1068,10 @@ private Q_SLOTS:
// WHEN -> Release outside of object
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(0.0f, 0.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -1126,8 +1147,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(320.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(320.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
bool earlyReturn = !pickBVJob.runHelper();
@@ -1141,7 +1163,8 @@ private Q_SLOTS:
// WHEN -> Move on next object, show stay on previous picker unless all picks are requested
events.clear();
- events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(280.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(280.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
earlyReturn = !pickBVJob.runHelper();
@@ -1200,8 +1223,9 @@ private Q_SLOTS:
Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
initializePickBoundingVolumeJob(&pickBVJob, test.data());
- QList<QMouseEvent> events;
- events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
pickBVJob.setMouseEvents(events);
bool earlyReturn = !pickBVJob.runHelper();
@@ -1212,6 +1236,155 @@ private Q_SLOTS:
Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
QCOMPARE(change->propertyName(), "pressed");
}
+
+ void checkPickerAndViewports()
+ {
+ // GIVEN
+ QmlSceneReader sceneReader(QUrl("qrc:/testscene_viewports.qml"));
+ QScopedPointer<Qt3DCore::QNode> root(qobject_cast<Qt3DCore::QNode *>(sceneReader.root()));
+ QVERIFY(root);
+
+ QList<Qt3DRender::QRenderSettings *> renderSettings = root->findChildren<Qt3DRender::QRenderSettings *>();
+ QCOMPARE(renderSettings.size(), 1);
+ Qt3DRender::QPickingSettings *settings = renderSettings.first()->pickingSettings();
+
+ settings->setPickMethod(Qt3DRender::QPickingSettings::TrianglePicking);
+ settings->setPickResultMode(Qt3DRender::QPickingSettings::NearestPick);
+ settings->setFaceOrientationPickingMode(Qt3DRender::QPickingSettings::FrontFace);
+
+ QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(root.data()));
+ TestArbiter arbiter;
+
+ // Runs Required jobs
+ runRequiredJobs(test.data());
+
+ // THEN
+ // object partially obscured by another viewport, make sure only visible portion is pickable
+ QList<Qt3DRender::QObjectPicker *> pickers = root->findChildren<Qt3DRender::QObjectPicker *>();
+ QCOMPARE(pickers.size(), 2);
+
+ Qt3DRender::QObjectPicker *picker = pickers.last();
+ QCOMPARE(picker->objectName(), QLatin1String("Picker2"));
+
+ Qt3DRender::Render::ObjectPicker *backendPicker = test->nodeManagers()->objectPickerManager()->lookupResource(picker->id());
+ QVERIFY(backendPicker);
+ Qt3DCore::QBackendNodePrivate::get(backendPicker)->setArbiter(&arbiter);
+
+ // WHEN -> Pressed on object in vp1
+ Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
+ initializePickBoundingVolumeJob(&pickBVJob, test.data());
+
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(280.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ bool earlyReturn = !pickBVJob.runHelper();
+
+ // THEN -> Pressed
+ QVERIFY(!earlyReturn);
+ QVERIFY(backendPicker->isPressed());
+ QCOMPARE(arbiter.events.count(), 1);
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "pressed");
+
+ // WHEN reset -> Presset on object in vp2
+ backendPicker->cleanup();
+ backendPicker->setEnabled(true);
+ events.clear();
+ arbiter.events.clear();
+
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(320.0f, 300.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ earlyReturn = !pickBVJob.runHelper();
+
+ // THEN -> Nothing happened
+ QVERIFY(!earlyReturn);
+ QVERIFY(!backendPicker->isPressed());
+ QCOMPARE(arbiter.events.count(), 0);
+ }
+
+ void checkMultipleRayDirections_data()
+ {
+ QTest::addColumn<QVector3D>("cameraOrigin");
+ QTest::addColumn<QVector3D>("cameraUpVector");
+
+ int k = 0;
+ const int n = 10;
+ for (int j=0; j<n; j++) {
+ QMatrix4x4 m;
+ m.rotate(360.f / (float)n * (float)j, 0.f, 0.f, 1.f);
+ for (int i=0; i<n; i++) {
+ const double angle = M_PI * 2. / (double)n * i;
+ const double x = std::sin(angle) * 10.;
+ const double z = std::cos(angle) * 10.;
+ QVector3D pos(x, 0, z);
+ QVector3D up(0, 1, 0);
+ QTest::newRow(QString::number(k++).toLatin1().data()) << m * pos << m * up;
+ }
+ }
+ }
+
+ void checkMultipleRayDirections()
+ {
+ // GIVEN
+ QmlSceneReader sceneReader(QUrl("qrc:/testscene_cameraposition.qml"));
+ QScopedPointer<Qt3DCore::QNode> root(qobject_cast<Qt3DCore::QNode *>(sceneReader.root()));
+ QVERIFY(root);
+
+ QList<Qt3DRender::QRenderSettings *> renderSettings = root->findChildren<Qt3DRender::QRenderSettings *>();
+ QCOMPARE(renderSettings.size(), 1);
+ Qt3DRender::QPickingSettings *settings = renderSettings.first()->pickingSettings();
+
+ settings->setPickMethod(Qt3DRender::QPickingSettings::TrianglePicking);
+
+ QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(root.data()));
+ TestArbiter arbiter;
+
+ QList<Qt3DRender::QCamera *> cameras = root->findChildren<Qt3DRender::QCamera *>();
+ QCOMPARE(cameras.size(), 1);
+ Qt3DRender::QCamera *camera = cameras.first();
+
+ QFETCH(QVector3D, cameraUpVector);
+ camera->setUpVector(cameraUpVector);
+
+ QFETCH(QVector3D, cameraOrigin);
+ camera->setPosition(cameraOrigin);
+
+ // Runs Required jobs
+ runRequiredJobs(test.data());
+
+ // THEN
+ QList<Qt3DRender::QObjectPicker *> pickers = root->findChildren<Qt3DRender::QObjectPicker *>();
+ QCOMPARE(pickers.size(), 1);
+
+ Qt3DRender::QObjectPicker *picker = pickers.front();
+
+ Qt3DRender::Render::ObjectPicker *backendPicker = test->nodeManagers()->objectPickerManager()->lookupResource(picker->id());
+ QVERIFY(backendPicker);
+ Qt3DCore::QBackendNodePrivate::get(backendPicker)->setArbiter(&arbiter);
+
+ // WHEN -> Pressed on object
+ Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
+ initializePickBoundingVolumeJob(&pickBVJob, test.data());
+
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(303.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ bool earlyReturn = !pickBVJob.runHelper();
+
+ // THEN -> Pressed
+ QVERIFY(!earlyReturn);
+ QVERIFY(backendPicker->isPressed());
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "pressed");
+ Qt3DRender::QPickEventPtr pickEvent = change->value().value<Qt3DRender::QPickEventPtr>();
+ QVERIFY(pickEvent);
+
+ arbiter.events.clear();
+ }
+
};
QTEST_MAIN(tst_PickBoundingVolumeJob)
diff --git a/tests/auto/render/qcamera/tst_qcamera.cpp b/tests/auto/render/qcamera/tst_qcamera.cpp
index 82a6d8b89..b630c447a 100644
--- a/tests/auto/render/qcamera/tst_qcamera.cpp
+++ b/tests/auto/render/qcamera/tst_qcamera.cpp
@@ -165,7 +165,7 @@ private Q_SLOTS:
Qt3DRender::Render::Entity *cameraEntity = test->nodeManagers()->lookupResource<Qt3DRender::Render::Entity, Qt3DRender::Render::EntityManager>(camera->id());
// THEN
- QVERIFY(qFuzzyCompare(*cameraEntity->worldTransform(), parentTransform->matrix()));
+ QVERIFY(qFuzzyCompare(convertToQMatrix4x4(*cameraEntity->worldTransform()), convertToQMatrix4x4(parentTransform->matrix())));
}
void checkTransformWithParentAndLookAt()
@@ -193,7 +193,7 @@ private Q_SLOTS:
m.translate(0.f, 1.f, 0.f); // 90 deg z-rotation + x-translation = y-translation
m.rotate(90.f, QVector3D(0.f, 0.f, 1.f));
- const QMatrix4x4 worldTransform = *cameraEntity->worldTransform();
+ const QMatrix4x4 worldTransform = convertToQMatrix4x4(*cameraEntity->worldTransform());
fuzzyCompareMatrix(worldTransform, m);
}
@@ -234,7 +234,7 @@ private Q_SLOTS:
m.translate(3.f, 2.f, -1.f); // child's world translation
m.rotate(90.f, QVector3D(0.f, 1.f, 0.f)); // camera's rotation
- fuzzyCompareMatrix(*childEntity->worldTransform(), m);
+ fuzzyCompareMatrix(convertToQMatrix4x4(*childEntity->worldTransform()), m);
}
};
diff --git a/tests/auto/render/qray3d/tst_qray3d.cpp b/tests/auto/render/qray3d/tst_qray3d.cpp
index e6ab02af0..e9d4d3033 100644
--- a/tests/auto/render/qray3d/tst_qray3d.cpp
+++ b/tests/auto/render/qray3d/tst_qray3d.cpp
@@ -70,7 +70,7 @@ static inline bool fuzzyCompare(float p1, float p2)
return (qAbs(p1 - p2) <= (qIsNull(fac) ? 0.00001f : 0.00001f * fac));
}
-static inline bool fuzzyCompare(const QVector3D &lhs, const QVector3D &rhs)
+static inline bool fuzzyCompare(const Vector3D &lhs, const Vector3D &rhs)
{
if (fuzzyCompare(lhs.x(), rhs.x()) &&
fuzzyCompare(lhs.y(), rhs.y()) &&
@@ -85,59 +85,59 @@ static inline bool fuzzyCompare(const QVector3D &lhs, const QVector3D &rhs)
void tst_QRay3D::create_data()
{
- QTest::addColumn<QVector3D>("point");
- QTest::addColumn<QVector3D>("direction");
+ QTest::addColumn<Vector3D>("point");
+ QTest::addColumn<Vector3D>("direction");
// normalized direction vectors
QTest::newRow("line on x-axis from origin")
- << QVector3D()
- << QVector3D(1.0f, 0.0f, 0.0f);
+ << Vector3D()
+ << Vector3D(1.0f, 0.0f, 0.0f);
QTest::newRow("line parallel -z-axis from 3,3,3")
- << QVector3D(3.0f, 3.0f, 3.0f)
- << QVector3D(0.0f, 0.0f, -1.0f);
+ << Vector3D(3.0f, 3.0f, 3.0f)
+ << Vector3D(0.0f, 0.0f, -1.0f);
QTest::newRow("vertical line (parallel to y-axis)")
- << QVector3D(0.5f, 0.0f, 0.5f)
- << QVector3D(0.0f, 1.0f, 0.0f);
+ << Vector3D(0.5f, 0.0f, 0.5f)
+ << Vector3D(0.0f, 1.0f, 0.0f);
QTest::newRow("equidistant from all 3 axes")
- << QVector3D(0.5f, 0.0f, 0.5f)
- << QVector3D(0.57735026919f, 0.57735026919f, 0.57735026919f);
+ << Vector3D(0.5f, 0.0f, 0.5f)
+ << Vector3D(0.57735026919f, 0.57735026919f, 0.57735026919f);
// non-normalized direction vectors
QTest::newRow("line on x-axis from origin - B")
- << QVector3D()
- << QVector3D(2.0f, 0.0f, 0.0f);
+ << Vector3D()
+ << Vector3D(2.0f, 0.0f, 0.0f);
QTest::newRow("line parallel -z-axis from 3,3,3 - B")
- << QVector3D(3.0f, 3.0f, 3.0f)
- << QVector3D(0.0f, 0.0f, -0.7f);
+ << Vector3D(3.0f, 3.0f, 3.0f)
+ << Vector3D(0.0f, 0.0f, -0.7f);
QTest::newRow("vertical line (parallel to y-axis) - B")
- << QVector3D(0.5f, 0.0f, 0.5f)
- << QVector3D(0.0f, 5.3f, 0.0f);
+ << Vector3D(0.5f, 0.0f, 0.5f)
+ << Vector3D(0.0f, 5.3f, 0.0f);
QTest::newRow("equidistant from all 3 axes - B")
- << QVector3D(0.5f, 0.0f, 0.5f)
- << QVector3D(1.0f, 1.0f, 1.0f);
+ << Vector3D(0.5f, 0.0f, 0.5f)
+ << Vector3D(1.0f, 1.0f, 1.0f);
QTest::newRow("negative direction")
- << QVector3D(-3.0f, -3.0f, -3.0f)
- << QVector3D(-1.2f, -1.8f, -2.4f);
+ << Vector3D(-3.0f, -3.0f, -3.0f)
+ << Vector3D(-1.2f, -1.8f, -2.4f);
}
void tst_QRay3D::create()
{
- QFETCH(QVector3D, point);
- QFETCH(QVector3D, direction);
+ QFETCH(Vector3D, point);
+ QFETCH(Vector3D, direction);
Qt3DRender::RayCasting::QRay3D ray(point, direction);
QVERIFY(fuzzyCompare(ray.direction(), direction));
QVERIFY(fuzzyCompare(ray.origin(), point));
Qt3DRender::RayCasting::QRay3D ray2;
- QCOMPARE(ray2.origin(), QVector3D(0, 0, 0));
- QCOMPARE(ray2.direction(), QVector3D(0, 0, 1));
+ QCOMPARE(ray2.origin(), Vector3D(0, 0, 0));
+ QCOMPARE(ray2.direction(), Vector3D(0, 0, 1));
ray2.setOrigin(point);
ray2.setDirection(direction);
QVERIFY(fuzzyCompare(ray.direction(), direction));
@@ -146,97 +146,97 @@ void tst_QRay3D::create()
void tst_QRay3D::projection_data()
{
- QTest::addColumn<QVector3D>("point");
- QTest::addColumn<QVector3D>("direction");
- QTest::addColumn<QVector3D>("vector");
- QTest::addColumn<QVector3D>("expected");
+ QTest::addColumn<Vector3D>("point");
+ QTest::addColumn<Vector3D>("direction");
+ QTest::addColumn<Vector3D>("vector");
+ QTest::addColumn<Vector3D>("expected");
QTest::newRow("line on x-axis from origin")
- << QVector3D()
- << QVector3D(2.0f, 0.0f, 0.0f)
- << QVector3D(0.6f, 0.0f, 0.0f)
- << QVector3D(0.6f, 0.0f, 0.0f);
+ << Vector3D()
+ << Vector3D(2.0f, 0.0f, 0.0f)
+ << Vector3D(0.6f, 0.0f, 0.0f)
+ << Vector3D(0.6f, 0.0f, 0.0f);
QTest::newRow("line parallel -z-axis from 3,3,3")
- << QVector3D(3.0f, 3.0f, 3.0f)
- << QVector3D(0.0f, 0.0f, -0.7f)
- << QVector3D(3.0f, 3.0f, 2.4f)
- << QVector3D(0.0f, 0.0f, 2.4f);
+ << Vector3D(3.0f, 3.0f, 3.0f)
+ << Vector3D(0.0f, 0.0f, -0.7f)
+ << Vector3D(3.0f, 3.0f, 2.4f)
+ << Vector3D(0.0f, 0.0f, 2.4f);
QTest::newRow("vertical line (parallel to y-axis)")
- << QVector3D(0.5f, 0.0f, 0.5f)
- << QVector3D(0.0f, 5.3f, 0.0f)
- << QVector3D(0.5f, 0.6f, 0.5f)
- << QVector3D(0.0f, 0.6f, 0.0f);
+ << Vector3D(0.5f, 0.0f, 0.5f)
+ << Vector3D(0.0f, 5.3f, 0.0f)
+ << Vector3D(0.5f, 0.6f, 0.5f)
+ << Vector3D(0.0f, 0.6f, 0.0f);
QTest::newRow("equidistant from all 3 axes, project y-axis (with some z & x)")
- << QVector3D(0.5f, 0.0f, 0.5f)
- << QVector3D(1.0f, 1.0f, 1.0f)
- << QVector3D(0.5f, 5.0f, 0.5f)
- << QVector3D(2.0f, 2.0f, 2.0f);
+ << Vector3D(0.5f, 0.0f, 0.5f)
+ << Vector3D(1.0f, 1.0f, 1.0f)
+ << Vector3D(0.5f, 5.0f, 0.5f)
+ << Vector3D(2.0f, 2.0f, 2.0f);
QTest::newRow("negative direction line, project +ve y-axis (with some z & x)")
- << QVector3D(-3.0f, -3.0f, -3.0f)
- << QVector3D(-1.2f, -1.8f, -2.4f)
- << QVector3D(0.5f, 5.0f, 0.5f)
- << QVector3D(1.241379261016846f, 1.862068772315979f, 2.48275852203369f);
+ << Vector3D(-3.0f, -3.0f, -3.0f)
+ << Vector3D(-1.2f, -1.8f, -2.4f)
+ << Vector3D(0.5f, 5.0f, 0.5f)
+ << Vector3D(1.241379261016846f, 1.862068772315979f, 2.48275852203369f);
}
void tst_QRay3D::projection()
{
- QFETCH(QVector3D, point);
- QFETCH(QVector3D, direction);
- QFETCH(QVector3D, vector);
- QFETCH(QVector3D, expected);
+ QFETCH(Vector3D, point);
+ QFETCH(Vector3D, direction);
+ QFETCH(Vector3D, vector);
+ QFETCH(Vector3D, expected);
Qt3DRender::RayCasting::QRay3D line(point, direction);
- QVector3D result = line.project(vector);
+ Vector3D result = line.project(vector);
QVERIFY(fuzzyCompare(result, expected));
}
void tst_QRay3D::point_data()
{
- QTest::addColumn<QVector3D>("point");
- QTest::addColumn<QVector3D>("direction");
- QTest::addColumn<QVector3D>("point_on_line_pos_0_6");
- QTest::addColumn<QVector3D>("point_on_line_neg_7_2");
+ QTest::addColumn<Vector3D>("point");
+ QTest::addColumn<Vector3D>("direction");
+ QTest::addColumn<Vector3D>("point_on_line_pos_0_6");
+ QTest::addColumn<Vector3D>("point_on_line_neg_7_2");
QTest::newRow("line on x-axis from origin")
- << QVector3D()
- << QVector3D(2.0f, 0.0f, 0.0f)
- << QVector3D(1.2f, 0.0f, 0.0f)
- << QVector3D(-14.4f, 0.0f, 0.0f);
+ << Vector3D()
+ << Vector3D(2.0f, 0.0f, 0.0f)
+ << Vector3D(1.2f, 0.0f, 0.0f)
+ << Vector3D(-14.4f, 0.0f, 0.0f);
QTest::newRow("line parallel -z-axis from 3,3,3")
- << QVector3D(3.0f, 3.0f, 3.0f)
- << QVector3D(0.0f, 0.0f, -0.7f)
- << QVector3D(3.0f, 3.0f, 2.58f)
- << QVector3D(3.0f, 3.0f, 8.04f);
+ << Vector3D(3.0f, 3.0f, 3.0f)
+ << Vector3D(0.0f, 0.0f, -0.7f)
+ << Vector3D(3.0f, 3.0f, 2.58f)
+ << Vector3D(3.0f, 3.0f, 8.04f);
QTest::newRow("vertical line (parallel to y-axis)")
- << QVector3D(0.5f, 0.0f, 0.5f)
- << QVector3D(0.0f, 5.3f, 0.0f)
- << QVector3D(0.5f, 3.18f, 0.5f)
- << QVector3D(0.5f, -38.16f, 0.5f);
+ << Vector3D(0.5f, 0.0f, 0.5f)
+ << Vector3D(0.0f, 5.3f, 0.0f)
+ << Vector3D(0.5f, 3.18f, 0.5f)
+ << Vector3D(0.5f, -38.16f, 0.5f);
QTest::newRow("equidistant from all 3 axes")
- << QVector3D(0.5f, 0.0f, 0.5f)
- << QVector3D(1.0f, 1.0f, 1.0f)
- << QVector3D(1.1f, 0.6f, 1.1f)
- << QVector3D(-6.7f, -7.2f, -6.7f);
+ << Vector3D(0.5f, 0.0f, 0.5f)
+ << Vector3D(1.0f, 1.0f, 1.0f)
+ << Vector3D(1.1f, 0.6f, 1.1f)
+ << Vector3D(-6.7f, -7.2f, -6.7f);
QTest::newRow("negative direction")
- << QVector3D(-3.0f, -3.0f, -3.0f)
- << QVector3D(-1.2f, -1.8f, -2.4f)
- << QVector3D(-3.72f, -4.08f, -4.44f)
- << QVector3D(5.64f, 9.96f, 14.28f);
+ << Vector3D(-3.0f, -3.0f, -3.0f)
+ << Vector3D(-1.2f, -1.8f, -2.4f)
+ << Vector3D(-3.72f, -4.08f, -4.44f)
+ << Vector3D(5.64f, 9.96f, 14.28f);
}
void tst_QRay3D::point()
{
- QFETCH(QVector3D, point);
- QFETCH(QVector3D, direction);
- QFETCH(QVector3D, point_on_line_pos_0_6);
- QFETCH(QVector3D, point_on_line_neg_7_2);
+ QFETCH(Vector3D, point);
+ QFETCH(Vector3D, direction);
+ QFETCH(Vector3D, point_on_line_pos_0_6);
+ QFETCH(Vector3D, point_on_line_neg_7_2);
Qt3DRender::RayCasting::QRay3D line(point, direction);
QVERIFY(fuzzyCompare(line.point(0.6f), point_on_line_pos_0_6));
QVERIFY(fuzzyCompare(line.point(-7.2f), point_on_line_neg_7_2));
@@ -246,39 +246,39 @@ void tst_QRay3D::point()
void tst_QRay3D::contains_point_data()
{
- QTest::addColumn<QVector3D>("origin");
- QTest::addColumn<QVector3D>("direction");
- QTest::addColumn<QVector3D>("point");
+ QTest::addColumn<Vector3D>("origin");
+ QTest::addColumn<Vector3D>("direction");
+ QTest::addColumn<Vector3D>("point");
QTest::addColumn<bool>("contains");
QTest::newRow("bogus this line with null direction")
- << QVector3D(1.0, 3.0, 3.0)
- << QVector3D(0.0, 0.0, 0.0)
- << QVector3D(1.0, 2.0, 4.0)
+ << Vector3D(1.0, 3.0, 3.0)
+ << Vector3D(0.0, 0.0, 0.0)
+ << Vector3D(1.0, 2.0, 4.0)
<< false;
QTest::newRow("point at the origin")
- << QVector3D(0.0, 0.0, 0.0)
- << QVector3D(1.0, 3.0, 3.0)
- << QVector3D(0.0, 0.0, 0.0)
+ << Vector3D(0.0, 0.0, 0.0)
+ << Vector3D(1.0, 3.0, 3.0)
+ << Vector3D(0.0, 0.0, 0.0)
<< true;
QTest::newRow("close to the origin")
- << QVector3D(1.0, 1.0, 1.0)
- << QVector3D(1.0, 3.0, 3.0)
- << QVector3D(1.0005f, 1.0005f, 1.0)
+ << Vector3D(1.0, 1.0, 1.0)
+ << Vector3D(1.0, 3.0, 3.0)
+ << Vector3D(1.0005f, 1.0005f, 1.0)
<< false;
QTest::newRow("45 line line in plane x=1")
- << QVector3D(1.0, 3.0, 3.0)
- << QVector3D(0.0, -1.0, -1.0)
- << QVector3D(1.0, 4.0, 4.0)
+ << Vector3D(1.0, 3.0, 3.0)
+ << Vector3D(0.0, -1.0, -1.0)
+ << Vector3D(1.0, 4.0, 4.0)
<< true;
{
// This is to prove that the constructed approach give the
// same results
- QVector3D p(1.0, 3.0, 3.0);
- QVector3D v(0.0, -1.0, -1.0);
+ Vector3D p(1.0, 3.0, 3.0);
+ Vector3D v(0.0, -1.0, -1.0);
QTest::newRow("constructed 45 line line in plane x=1")
<< p
@@ -288,20 +288,20 @@ void tst_QRay3D::contains_point_data()
}
QTest::newRow("intersection with negative s in plane z=-1")
- << QVector3D(1.0f, 2.0f, -1.0f)
- << QVector3D(1.0f, 1.0f, 0.0f)
- << QVector3D(2.0f, 1.0f, 0.0f)
+ << Vector3D(1.0f, 2.0f, -1.0f)
+ << Vector3D(1.0f, 1.0f, 0.0f)
+ << Vector3D(2.0f, 1.0f, 0.0f)
<< false;
QTest::newRow("45 angled line")
- << QVector3D(3.0f, 0.0f, -1.0f)
- << QVector3D(1.0f, -1.0f, 1.0f)
- << QVector3D(6.0f, -3.0f, 2.0f)
+ << Vector3D(3.0f, 0.0f, -1.0f)
+ << Vector3D(1.0f, -1.0f, 1.0f)
+ << Vector3D(6.0f, -3.0f, 2.0f)
<< true;
{
- QVector3D p(-10.0, 3.0, 3.0);
- QVector3D v(0.0, 20.0, -1.0);
+ Vector3D p(-10.0, 3.0, 3.0);
+ Vector3D v(0.0, 20.0, -1.0);
QTest::newRow("constructed vector close to axis")
<< p
<< v
@@ -310,8 +310,8 @@ void tst_QRay3D::contains_point_data()
}
{
- QVector3D p(1.0, 3.0, 3.0);
- QVector3D v(40.0, 500.0, -1.0);
+ Vector3D p(1.0, 3.0, 3.0);
+ Vector3D v(40.0, 500.0, -1.0);
QTest::newRow("constructed larger values close to axis")
<< p
<< v
@@ -322,9 +322,9 @@ void tst_QRay3D::contains_point_data()
void tst_QRay3D::contains_point()
{
- QFETCH(QVector3D, origin);
- QFETCH(QVector3D, direction);
- QFETCH(QVector3D, point);
+ QFETCH(Vector3D, origin);
+ QFETCH(Vector3D, direction);
+ QFETCH(Vector3D, point);
QFETCH(bool, contains);
Qt3DRender::RayCasting::QRay3D line(origin, direction);
@@ -338,9 +338,9 @@ void tst_QRay3D::contains_ray_data()
void tst_QRay3D::contains_ray()
{
- QFETCH(QVector3D, origin);
- QFETCH(QVector3D, direction);
- QFETCH(QVector3D, point);
+ QFETCH(Vector3D, origin);
+ QFETCH(Vector3D, direction);
+ QFETCH(Vector3D, point);
QFETCH(bool, contains);
Qt3DRender::RayCasting::QRay3D line(origin, direction);
@@ -355,7 +355,7 @@ void tst_QRay3D::contains_ray()
QVERIFY(line2.contains(line));
// Different direction.
- Qt3DRender::RayCasting::QRay3D line4(point, QVector3D(direction.y(), direction.x(), direction.z()));
+ Qt3DRender::RayCasting::QRay3D line4(point, Vector3D(direction.y(), direction.x(), direction.z()));
QVERIFY(!line.contains(line4));
QVERIFY(!line4.contains(line));
} else {
@@ -367,41 +367,41 @@ void tst_QRay3D::contains_ray()
void tst_QRay3D::distance_data()
{
- QTest::addColumn<QVector3D>("origin");
- QTest::addColumn<QVector3D>("direction");
- QTest::addColumn<QVector3D>("point");
+ QTest::addColumn<Vector3D>("origin");
+ QTest::addColumn<Vector3D>("direction");
+ QTest::addColumn<Vector3D>("point");
QTest::addColumn<float>("distance");
QTest::newRow("axis-x")
- << QVector3D(6.0f, 0.0f, 0.0f)
- << QVector3D(1.0f, 0.0f, 0.0f)
- << QVector3D(0.0f, 0.0f, 0.0f)
+ << Vector3D(6.0f, 0.0f, 0.0f)
+ << Vector3D(1.0f, 0.0f, 0.0f)
+ << Vector3D(0.0f, 0.0f, 0.0f)
<< 0.0f;
QTest::newRow("axis-x to 1")
- << QVector3D(6.0f, 0.0f, 0.0f)
- << QVector3D(1.0f, 0.0f, 0.0f)
- << QVector3D(0.0f, 1.0f, 0.0f)
+ << Vector3D(6.0f, 0.0f, 0.0f)
+ << Vector3D(1.0f, 0.0f, 0.0f)
+ << Vector3D(0.0f, 1.0f, 0.0f)
<< 1.0f;
QTest::newRow("neg-axis-y")
- << QVector3D(0.0f, 6.0f, 0.0f)
- << QVector3D(0.0f, -1.5f, 0.0f)
- << QVector3D(0.0f, 100.0f, 0.0f)
+ << Vector3D(0.0f, 6.0f, 0.0f)
+ << Vector3D(0.0f, -1.5f, 0.0f)
+ << Vector3D(0.0f, 100.0f, 0.0f)
<< 0.0f;
QTest::newRow("neg-axis-y to 2")
- << QVector3D(0.0f, 6.0f, 0.0f)
- << QVector3D(0.0f, -1.5f, 0.0f)
- << QVector3D(2.0f, 0.0f, 0.0f)
+ << Vector3D(0.0f, 6.0f, 0.0f)
+ << Vector3D(0.0f, -1.5f, 0.0f)
+ << Vector3D(2.0f, 0.0f, 0.0f)
<< 2.0f;
}
void tst_QRay3D::distance()
{
- QFETCH(QVector3D, origin);
- QFETCH(QVector3D, direction);
- QFETCH(QVector3D, point);
+ QFETCH(Vector3D, origin);
+ QFETCH(Vector3D, direction);
+ QFETCH(Vector3D, point);
QFETCH(float, distance);
Qt3DRender::RayCasting::QRay3D line(origin, direction);
@@ -410,9 +410,9 @@ void tst_QRay3D::distance()
void tst_QRay3D::compare()
{
- Qt3DRender::RayCasting::QRay3D ray1(QVector3D(10, 20, 30), QVector3D(-3, -4, -5));
- Qt3DRender::RayCasting::QRay3D ray2(QVector3D(10, 20, 30), QVector3D(1.5f, 2.0f, 2.5f));
- Qt3DRender::RayCasting::QRay3D ray3(QVector3D(0, 20, 30), QVector3D(-3, -4, -5));
+ Qt3DRender::RayCasting::QRay3D ray1(Vector3D(10, 20, 30), Vector3D(-3, -4, -5));
+ Qt3DRender::RayCasting::QRay3D ray2(Vector3D(10, 20, 30), Vector3D(1.5f, 2.0f, 2.5f));
+ Qt3DRender::RayCasting::QRay3D ray3(Vector3D(0, 20, 30), Vector3D(-3, -4, -5));
QVERIFY(ray1 == ray1);
QVERIFY(!(ray1 != ray1));
QVERIFY(qFuzzyCompare(ray1, ray1));
@@ -427,7 +427,7 @@ void tst_QRay3D::compare()
void tst_QRay3D::dataStream()
{
#ifndef QT_NO_DATASTREAM
- Qt3DRender::RayCasting::QRay3D ray(QVector3D(1.0f, 2.0f, 3.0f), QVector3D(4.0f, 5.0f, 6.0f));
+ Qt3DRender::RayCasting::QRay3D ray(Vector3D(1.0f, 2.0f, 3.0f), Vector3D(4.0f, 5.0f, 6.0f));
QByteArray data;
{
@@ -452,13 +452,17 @@ void tst_QRay3D::transform_data()
void tst_QRay3D::transform()
{
- QFETCH(QVector3D, point);
- QFETCH(QVector3D, direction);
+ QFETCH(Vector3D, point);
+ QFETCH(Vector3D, direction);
- QMatrix4x4 m;
- m.translate(-1.0f, 2.5f, 5.0f);
- m.rotate(45.0f, 1.0f, 1.0f, 1.0f);
- m.scale(23.5f);
+ Matrix4x4 m;
+ {
+ QMatrix4x4 c;
+ c.translate(-1.0f, 2.5f, 5.0f);
+ c.rotate(45.0f, 1.0f, 1.0f, 1.0f);
+ c.scale(23.5f);
+ m = Matrix4x4(c);
+ }
Qt3DRender::RayCasting::QRay3D ray1(point, direction);
Qt3DRender::RayCasting::QRay3D ray2(ray1);
@@ -495,19 +499,19 @@ void tst_QRay3D::properties()
qRegisterMetaType<Qt3DRender::RayCasting::QRay3D>();
- obj.setRay(Qt3DRender::RayCasting::QRay3D(QVector3D(1, 2, 3), QVector3D(4, 5, 6)));
+ obj.setRay(Qt3DRender::RayCasting::QRay3D(Vector3D(1, 2, 3), Vector3D(4, 5, 6)));
Qt3DRender::RayCasting::QRay3D r = qvariant_cast<Qt3DRender::RayCasting::QRay3D>(obj.property("ray"));
- QCOMPARE(r.origin(), QVector3D(1, 2, 3));
- QCOMPARE(r.direction(), QVector3D(4, 5, 6));
+ QCOMPARE(r.origin(), Vector3D(1, 2, 3));
+ QCOMPARE(r.direction(), Vector3D(4, 5, 6));
obj.setProperty("ray",
qVariantFromValue
- (Qt3DRender::RayCasting::QRay3D(QVector3D(-1, -2, -3), QVector3D(-4, -5, -6))));
+ (Qt3DRender::RayCasting::QRay3D(Vector3D(-1, -2, -3), Vector3D(-4, -5, -6))));
r = qvariant_cast<Qt3DRender::RayCasting::QRay3D>(obj.property("ray"));
- QCOMPARE(r.origin(), QVector3D(-1, -2, -3));
- QCOMPARE(r.direction(), QVector3D(-4, -5, -6));
+ QCOMPARE(r.origin(), Vector3D(-1, -2, -3));
+ QCOMPARE(r.direction(), Vector3D(-4, -5, -6));
}
void tst_QRay3D::metaTypes()
@@ -523,14 +527,14 @@ void tst_QRay3D::shouldNotAllowNullDirection()
// GIVEN
Qt3DRender::RayCasting::QRay3D ray;
- QCOMPARE(ray.origin(), QVector3D(0, 0, 0));
- QCOMPARE(ray.direction(), QVector3D(0, 0, 1));
+ QCOMPARE(ray.origin(), Vector3D(0, 0, 0));
+ QCOMPARE(ray.direction(), Vector3D(0, 0, 1));
// WHEN
- ray.setDirection(QVector3D(0, 0, 0));
+ ray.setDirection(Vector3D(0, 0, 0));
// THEN
- QCOMPARE(ray.direction(), QVector3D(0, 0, 1));
+ QCOMPARE(ray.direction(), Vector3D(0, 0, 1));
}
QTEST_APPLESS_MAIN(tst_QRay3D)
diff --git a/tests/auto/render/raycasting/tst_raycasting.cpp b/tests/auto/render/raycasting/tst_raycasting.cpp
index 0f3d04962..d14bcddcb 100644
--- a/tests/auto/render/raycasting/tst_raycasting.cpp
+++ b/tests/auto/render/raycasting/tst_raycasting.cpp
@@ -72,15 +72,15 @@ void tst_RayCasting::shouldIntersect_data()
QTest::addColumn<Sphere>("sphere");
QTest::addColumn<bool>("shouldIntersect");
- QRay3D ray(QVector3D(1, 1, 1), QVector3D(0, 0, 1));
+ QRay3D ray(Vector3D(1, 1, 1), Vector3D(0, 0, 1));
- Sphere sphere1(QVector3D(1, 1, 1), 2);
- Sphere sphere2(QVector3D(0, 0, 0), 3);
- Sphere sphere3(QVector3D(0, 1, 3), 1);
- Sphere sphere4(QVector3D(4, 4, 5), 1);
- Sphere sphere5(QVector3D(2, 2, 11), 5);
- Sphere sphere6(QVector3D(2, 2, 13), 1);
- Sphere sphere7(QVector3D(2, 2, 15), 5);
+ Sphere sphere1(Vector3D(1, 1, 1), 2);
+ Sphere sphere2(Vector3D(0, 0, 0), 3);
+ Sphere sphere3(Vector3D(0, 1, 3), 1);
+ Sphere sphere4(Vector3D(4, 4, 5), 1);
+ Sphere sphere5(Vector3D(2, 2, 11), 5);
+ Sphere sphere6(Vector3D(2, 2, 13), 1);
+ Sphere sphere7(Vector3D(2, 2, 15), 5);
QTest::newRow("Ray starts inside sphere") << ray << sphere1 << true;
QTest::newRow("Ray starts inside sphere") << ray << sphere2 << true;
@@ -97,7 +97,7 @@ void tst_RayCasting::shouldIntersect()
QFETCH(Sphere, sphere);
QFETCH(bool, shouldIntersect);
- QVector3D intersectionPoint;
+ Vector3D intersectionPoint;
QCOMPARE(sphere.intersects(ray, &intersectionPoint), shouldIntersect);
}
@@ -206,16 +206,16 @@ void tst_RayCasting::shouldReturnHits_data()
QTest::addColumn<QVector<QNodeId> >("hits");
QTest::addColumn<QAbstractCollisionQueryService::QueryMode >("queryMode");
- QRay3D ray(QVector3D(1, 1, 1), QVector3D(0, 0, 1));
+ QRay3D ray(Vector3D(1, 1, 1), Vector3D(0, 0, 1));
this->boundingVolumes.clear();
- this->boundingVolumes.append(QVector<Sphere>() << Sphere(QVector3D(1, 1, 1), 3, QNodeId::createId())
- << Sphere(QVector3D(0, 0, 0), 3, QNodeId::createId())
- << Sphere(QVector3D(0, 1, 3), 1, QNodeId::createId())
- << Sphere(QVector3D(4, 4, 5), 1, QNodeId::createId())
- << Sphere(QVector3D(2, 2, 11), 5, QNodeId::createId())
- << Sphere(QVector3D(2, 2, 13), 1, QNodeId::createId())
- << Sphere(QVector3D(2, 2, 15), 5, QNodeId::createId()));
+ this->boundingVolumes.append(QVector<Sphere>() << Sphere(Vector3D(1, 1, 1), 3, QNodeId::createId())
+ << Sphere(Vector3D(0, 0, 0), 3, QNodeId::createId())
+ << Sphere(Vector3D(0, 1, 3), 1, QNodeId::createId())
+ << Sphere(Vector3D(4, 4, 5), 1, QNodeId::createId())
+ << Sphere(Vector3D(2, 2, 11), 5, QNodeId::createId())
+ << Sphere(Vector3D(2, 2, 13), 1, QNodeId::createId())
+ << Sphere(Vector3D(2, 2, 15), 5, QNodeId::createId()));
QTest::newRow("All hits, One sphere intersect") << ray
<< (QVector<QBoundingVolume *> () << volumeAt(0) << volumeAt(3))
@@ -276,11 +276,11 @@ void tst_RayCasting::shouldReturnHits()
void tst_RayCasting::shouldUseProvidedBoudingVolumes()
{
// GIVEN
- QRay3D ray(QVector3D(1, 1, 1), QVector3D(0, 0, 1));
+ QRay3D ray(Vector3D(1, 1, 1), Vector3D(0, 0, 1));
- Sphere sphere1(QVector3D(1, 1, 1), 3);
- Sphere sphere3(QVector3D(0, 1, 3), 1);
- Sphere sphere4(QVector3D(4, 4, 5), 1);
+ Sphere sphere1(Vector3D(1, 1, 1), 3);
+ Sphere sphere3(Vector3D(0, 1, 3), 1);
+ Sphere sphere4(Vector3D(4, 4, 5), 1);
MyBoudingVolumesProvider provider(QVector<QBoundingVolume *>() << &sphere1 << &sphere4 << &sphere3);
QVector<QNodeId> hits(QVector<QNodeId>() << sphere1.id() << sphere3.id());
@@ -325,10 +325,10 @@ void tst_RayCasting::mousePicking()
// Window center on near plane
QRay3D ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.center().toPoint(),
- camera.viewMatrix(),
- camera.projectionMatrix(),
- viewport.toRect());
- Qt3DRender::Render::Sphere s(QVector3D(0.0f, 0.5f, 0.0f), 1.0f);
+ Matrix4x4(camera.viewMatrix()),
+ Matrix4x4(camera.projectionMatrix()),
+ viewport.toRect());
+ Qt3DRender::Render::Sphere s(Vector3D(0.0f, 0.5f, 0.0f), 1.0f);
// WHEN
bool intersects = s.intersects(ray, nullptr);
@@ -338,9 +338,9 @@ void tst_RayCasting::mousePicking()
// WHEN
ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.topLeft().toPoint(),
- camera.viewMatrix(),
- camera.projectionMatrix(),
- viewport.toRect());
+ Matrix4x4(camera.viewMatrix()),
+ Matrix4x4(camera.projectionMatrix()),
+ viewport.toRect());
intersects = s.intersects(ray, nullptr);
// THEN
@@ -348,9 +348,9 @@ void tst_RayCasting::mousePicking()
// WHEN
ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.topRight().toPoint(),
- camera.viewMatrix(),
- camera.projectionMatrix(),
- viewport.toRect());
+ Matrix4x4(camera.viewMatrix()),
+ Matrix4x4(camera.projectionMatrix()),
+ viewport.toRect());
intersects = s.intersects(ray, nullptr);
// THEN
@@ -358,9 +358,9 @@ void tst_RayCasting::mousePicking()
// WHEN
ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.bottomLeft().toPoint(),
- camera.viewMatrix(),
- camera.projectionMatrix(),
- viewport.toRect());
+ Matrix4x4(camera.viewMatrix()),
+ Matrix4x4(camera.projectionMatrix()),
+ viewport.toRect());
intersects = s.intersects(ray, nullptr);
// THEN
@@ -368,9 +368,9 @@ void tst_RayCasting::mousePicking()
// WHEN
ray = Qt3DRender::Render::AbstractPickingJob::intersectionRay(viewport.bottomRight().toPoint(),
- camera.viewMatrix(),
- camera.projectionMatrix(),
- viewport.toRect());
+ Matrix4x4(camera.viewMatrix()),
+ Matrix4x4(camera.projectionMatrix()),
+ viewport.toRect());
intersects = s.intersects(ray, nullptr);
// THEN
diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro
index 2fcebaa3c..ef147ba7f 100644
--- a/tests/auto/render/render.pro
+++ b/tests/auto/render/render.pro
@@ -24,14 +24,12 @@ qtConfig(private_tests) {
attribute \
geometry \
geometryrenderer \
- raycasting \
qcameraselector \
qclearbuffers \
qframegraphnode \
qlayerfilter \
qabstractlight \
qenvironmentlight \
- qray3d \
qrenderpassfilter \
qrenderstate \
qrendertargetselector \
@@ -45,8 +43,6 @@ qtConfig(private_tests) {
objectpicker \
# qboundingvolumedebug \
# boundingvolumedebug \
- trianglesextractor \
- triangleboundingvolume \
ddstextures \
shadercache \
layerfiltering \
@@ -113,9 +109,20 @@ qtConfig(private_tests) {
qraycaster \
raycaster \
raycastingjob \
- qcamera
+ qcamera \
+ renderbarrierjob
QT_FOR_CONFIG = 3dcore-private
+ # TO DO: These could be restored to be executed in all cases
+ # when aligned-malloc.pri becomes part of the test framework
+ !qtConfig(qt3d-simd-avx2): {
+ SUBDIRS += \
+ qray3d \
+ raycasting \
+ trianglesextractor \
+ triangleboundingvolume \
+ }
+
qtConfig(qt3d-extras) {
SUBDIRS += \
qmaterial \
diff --git a/tests/auto/render/renderbarrierjob/renderbarrierjob.pro b/tests/auto/render/renderbarrierjob/renderbarrierjob.pro
new file mode 100644
index 000000000..5a988144f
--- /dev/null
+++ b/tests/auto/render/renderbarrierjob/renderbarrierjob.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+
+TARGET = tst_renderbarrierjob
+
+QT += 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_renderbarrierjob.cpp
diff --git a/tests/auto/render/renderbarrierjob/tst_renderbarrierjob.cpp b/tests/auto/render/renderbarrierjob/tst_renderbarrierjob.cpp
new file mode 100644
index 000000000..e3b49edd4
--- /dev/null
+++ b/tests/auto/render/renderbarrierjob/tst_renderbarrierjob.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QMutex>
+#include <QWaitCondition>
+#include <QThread>
+#include <Qt3DRender/private/renderbarrierjob_p.h>
+#include <Qt3DRender/private/job_common_p.h>
+
+class TestRenderThread : public QThread
+{
+public:
+ TestRenderThread(Qt3DRender::Render::RenderBarrierJobPtr barrier)
+ : m_barrier(barrier)
+ {}
+
+ void run() override
+ {
+ m_started.store(1);
+ m_writeSemaphore.release();
+ m_readSemaphore.acquire();
+
+ m_barrier->allowToProceed();
+ m_released.store(1);
+ m_writeSemaphore.release();
+ m_readSemaphore.acquire();
+
+ m_barrier->waitForDependencies();
+ m_completed.store(1);
+ }
+
+ Qt3DRender::Render::RenderBarrierJobPtr m_barrier;
+ QSemaphore m_writeSemaphore;
+ QSemaphore m_readSemaphore;
+
+ QAtomicInt m_started;
+ QAtomicInt m_released;
+ QAtomicInt m_completed;
+};
+
+class tst_RenderBarrierJob : public QObject
+{
+ Q_OBJECT
+public :
+ tst_RenderBarrierJob() {}
+ ~tst_RenderBarrierJob() {}
+
+private Q_SLOTS:
+ void shouldControlRenderThread()
+ {
+ // GIVEN a barrier (of any type)
+ auto barrier = Qt3DRender::Render::RenderBarrierJobPtr::create(Qt3DRender::Render::JobTypes::BeginDrawingBarrier);
+ TestRenderThread testThread(barrier);
+
+ // THEN
+ QVERIFY(testThread.m_started.load() == 0);
+ QVERIFY(testThread.m_released.load() == 0);
+ QVERIFY(testThread.m_completed.load() == 0);
+
+ // WHEN
+ testThread.start();
+ testThread.m_writeSemaphore.acquire();
+
+ // THEN thread should have started
+ QVERIFY(testThread.m_started.load() == 1);
+ QVERIFY(testThread.m_released.load() == 0);
+ QVERIFY(testThread.m_completed.load() == 0);
+ testThread.m_readSemaphore.release();
+
+ // WHEN
+ testThread.m_writeSemaphore.acquire();
+
+ // THEN job should be released
+ QVERIFY(testThread.m_started.load() == 1);
+ QVERIFY(testThread.m_released.load() == 1);
+ QVERIFY(testThread.m_completed.load() == 0);
+ testThread.m_readSemaphore.release();
+
+ // WHEN job runs and we wait for thread
+ barrier->run();
+ testThread.wait();
+
+ // THEN thread should be finished
+ QVERIFY(testThread.m_started.load() == 1);
+ QVERIFY(testThread.m_released.load() == 1);
+ QVERIFY(testThread.m_completed.load() == 1);
+ }
+};
+
+QTEST_MAIN(tst_RenderBarrierJob)
+
+#include "tst_renderbarrierjob.moc"
diff --git a/tests/auto/render/renderer/tst_renderer.cpp b/tests/auto/render/renderer/tst_renderer.cpp
index cfccf8b78..b941a2ac4 100644
--- a/tests/auto/render/renderer/tst_renderer.cpp
+++ b/tests/auto/render/renderer/tst_renderer.cpp
@@ -34,6 +34,9 @@
#include <Qt3DRender/private/viewportnode_p.h>
#include <Qt3DRender/private/renderview_p.h>
#include <Qt3DRender/private/renderviewbuilder_p.h>
+#include <Qt3DRender/private/offscreensurfacehelper_p.h>
+#include <Qt3DRender/private/loadtexturedatajob_p.h>
+#include <Qt3DRender/private/renderbarrierjob_p.h>
class tst_Renderer : public QObject
{
@@ -63,47 +66,62 @@ private Q_SLOTS:
// NOTE: FilterCompatibleTechniqueJob and ShaderGathererJob cannot run because the context
// is not initialized in this test
- const int singleRenderViewJobCount = 11 + 1 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount();
+ const int renderBarrierJobCount = 5;
+ // Barriers: readRenderQueueSize
+ // beginDrawing
+ // updateGLResources
+ // prepareCommandSubmission
+ // endDrawing
+
+ const int renderViewJobCount = 13 + 1 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount();
// RenderViewBuilder renderViewJob,
// renderableEntityFilterJob,
// lightGatherJob,
// computableEntityFilterJob,
// syncRenderViewInitializationJob,
- // syncFrustumCullingJob,
// filterEntityByLayerJob,
+ // syncFilterEntityByLayerJob,
+ // syncFrustumCullingJob,
// filterProximityJob,
// setClearDrawBufferIndexJob,
// frustumCullingJob,
// syncRenderCommandBuldingJob,
- // syncRenderViewCommandBuilderJob)
- // n * (RenderViewCommandBuildJobs + MaterialGathererJobs
+ // syncRenderViewCommandBuilderJob
+ // n * RenderViewCommandBuildJobs
+
+ const int flagIndependentRendererJobCount = 6;
+ // Flag independent: updateLevelOfDetailJob
+ // cleanupJob
+ // sendRenderCaptureJob
+ // sendBufferCaptureJob
+ // VAOGatherer
+ // updateSkinningPaletteJob
+
+ const int flagIndependetRenderViewJobCount = renderViewJobCount - 2;
+ // Cached: filterEntityByLayerJob,
+ // syncFilterEntityByLayerJob,
+
// WHEN (nothing dirty, no buffers)
QVector<Qt3DCore::QAspectJobPtr> jobs = renderer.renderBinJobs();
- // THEN (level
+ // THEN
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
- 1 + // cleanupJob
- 1 + // sendRenderCaptureJob
- 1 + // sendBufferCaptureJob
- 1 + // VAOGatherer
- 1 + // updateSkinningPaletteJob
- singleRenderViewJobCount); // Only valid for the first call to renderBinJobs(), since subsequent calls won't have the renderqueue reset
-
+ flagIndependetRenderViewJobCount +
+ renderBarrierJobCount +
+ flagIndependentRendererJobCount);
// WHEN
renderer.markDirty(Qt3DRender::Render::AbstractRenderer::EntityEnabledDirty, nullptr);
jobs = renderer.renderBinJobs();
- // THEN (level
+ // THEN
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
- 1 + // cleanupJob
- 1 + // sendRenderCaptureJob
- 1 + // sendBufferCaptureJob
- 1 + // VAOGatherer
- 1 + // updateSkinningPaletteJob
+ flagIndependetRenderViewJobCount +
+ renderBarrierJobCount +
+ flagIndependentRendererJobCount +
+ 1 + // filterEntityByLayerJob
+ 1 + // syncFilterEntityByLayerJob
1); // EntityEnabledDirty
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
@@ -112,17 +130,14 @@ private Q_SLOTS:
renderer.markDirty(Qt3DRender::Render::AbstractRenderer::TransformDirty, nullptr);
jobs = renderer.renderBinJobs();
- // THEN (level
+ // THEN
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
- 1 + // cleanupJob
- 1 + // sendRenderCaptureJob
- 1 + // sendBufferCaptureJob
- 1 + // VAOGatherer
+ flagIndependetRenderViewJobCount +
+ renderBarrierJobCount +
+ flagIndependentRendererJobCount +
1 + // WorldTransformJob
1 + // UpdateWorldBoundingVolume
1 + // UpdateShaderDataTransform
- 1 + // updateSkinningPaletteJob
1); // ExpandBoundingVolumeJob
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
@@ -131,16 +146,13 @@ private Q_SLOTS:
renderer.markDirty(Qt3DRender::Render::AbstractRenderer::GeometryDirty, nullptr);
jobs = renderer.renderBinJobs();
- // THEN (level
+ // THEN
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
- 1 + // cleanupJob
- 1 + // sendRenderCaptureJob
- 1 + // sendBufferCaptureJob
- 1 + // VAOGatherer
+ flagIndependetRenderViewJobCount +
+ renderBarrierJobCount +
+ flagIndependentRendererJobCount +
1 + // CalculateBoundingVolumeJob
1 + // UpdateMeshTriangleListJob
- 1 + // updateSkinningPaletteJob
1); // ExpandBoundingVolumeJob
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
@@ -149,14 +161,11 @@ private Q_SLOTS:
renderer.markDirty(Qt3DRender::Render::AbstractRenderer::BuffersDirty, nullptr);
jobs = renderer.renderBinJobs();
- // THEN (level
+ // THEN
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
- 1 + // cleanupJob
- 1 + // sendRenderCaptureJob
- 1 + // sendBufferCaptureJob
- 1 + // VAOGatherer
- 1 + // updateSkinningPaletteJob
+ flagIndependetRenderViewJobCount +
+ renderBarrierJobCount +
+ flagIndependentRendererJobCount +
1); // BufferGathererJob
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
@@ -165,16 +174,26 @@ private Q_SLOTS:
renderer.markDirty(Qt3DRender::Render::AbstractRenderer::TexturesDirty, nullptr);
jobs = renderer.renderBinJobs();
- // THEN (level
+ // THEN
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
- 1 + // cleanupJob
- 1 + // sendRenderCaptureJob
- 1 + // sendBufferCaptureJob
- 1 + // VAOGatherer
- 1 + // TexturesGathererJob
- 1 + // updateSkinningPaletteJob
- 1); // SyncTexturesGathererJob
+ flagIndependetRenderViewJobCount +
+ renderBarrierJobCount +
+ flagIndependentRendererJobCount +
+ 1 + // LoadTextureDataJob
+ 1); // TexturesGathererJob
+
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+ // WHEN
+ renderer.markDirty(Qt3DRender::Render::AbstractRenderer::SkeletonDataDirty, nullptr);
+ jobs = renderer.renderBinJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ flagIndependetRenderViewJobCount +
+ renderBarrierJobCount +
+ flagIndependentRendererJobCount +
+ 1); // SyncSkeletonLoadingJob
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
@@ -182,28 +201,47 @@ private Q_SLOTS:
renderer.markDirty(Qt3DRender::Render::AbstractRenderer::AllDirty, nullptr);
jobs = renderer.renderBinJobs();
- // THEN (level
+ // THEN
QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
- 1 + // cleanupJob
- 1 + // sendRenderCaptureJob
- 1 + // sendBufferCaptureJob
- 1 + // VAOGatherer
- 1 + // EntityEnabledDirty
+ renderViewJobCount +
+ renderBarrierJobCount +
+ flagIndependentRendererJobCount +
+ 1 + // UpdateTreeEnablee
1 + // WorldTransformJob
1 + // UpdateWorldBoundingVolume
1 + // UpdateShaderDataTransform
- 1 + // ExpandBoundingVolumeJob
1 + // CalculateBoundingVolumeJob
1 + // UpdateMeshTriangleListJob
+ 1 + // ExpandBoundingVolumeJob
1 + // BufferGathererJob
+ 1 + // LoadTextureDataJob
1 + // TexturesGathererJob
- 1 + // updateSkinningPaletteJob
- 1); // SyncTexturesGathererJob
+ 1 + // SyncSkeletonLoadingJob
+ 1 + // FilterCompatibleTechniqueJob
+ 1 + // ShaderGathererJob
+ Qt3DRender::Render::RenderViewBuilder::optimalJobCount() + // MaterialGathererJobs
+ 1); // syncMaterialGathererJob
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+ }
+
+ void checkRenderBarrierJobDependencies()
+ {
+ // GIVEN
+ Qt3DRender::Render::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
+
+ // THEN
+ // internal dependencies
+ QVERIFY(renderer.beginDrawingBarrierJob()->dependencies().contains(renderer.readRenderQueueSizeBarrierJob()));
+ QVERIFY(renderer.updateGLResourcesBarrierJob()->dependencies().contains(renderer.beginDrawingBarrierJob()));
+ QVERIFY(renderer.prepareCommandSubmissionBarrierJob()->dependencies().contains(renderer.updateGLResourcesBarrierJob()));
+ QVERIFY(renderer.endDrawingBarrierJob()->dependencies().contains(renderer.prepareCommandSubmissionBarrierJob()));
+ QVERIFY(renderer.filterCompatibleTechniqueJob()->dependencies().contains(renderer.beginDrawingBarrierJob()));
+ QVERIFY(renderer.loadTextureJob()->dependencies().contains(renderer.updateGLResourcesBarrierJob()));
+ QVERIFY(renderer.prepareCommandSubmissionBarrierJob()->dependencies().contains(renderer.loadTextureJob()));
+ QVERIFY(renderer.updateGLResourcesBarrierJob()->dependencies().contains(renderer.filterCompatibleTechniqueJob()));
}
};
diff --git a/tests/auto/render/renderqueue/renderqueue.pro b/tests/auto/render/renderqueue/renderqueue.pro
index 92e675285..945fe4cf4 100644
--- a/tests/auto/render/renderqueue/renderqueue.pro
+++ b/tests/auto/render/renderqueue/renderqueue.pro
@@ -7,3 +7,5 @@ QT += 3dcore 3dcore-private 3drender 3drender-private testlib
CONFIG += testcase
SOURCES += tst_renderqueue.cpp
+
+include(../../core/common/common.pri)
diff --git a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
index d18b270c5..1bdf20170 100644
--- a/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
+++ b/tests/auto/render/renderviewbuilder/tst_renderviewbuilder.cpp
@@ -49,6 +49,7 @@
#include <Qt3DRender/private/qrenderaspect_p.h>
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/managers_p.h>
+#include <Qt3DRender/private/renderbarrierjob_p.h>
QT_BEGIN_NAMESPACE
@@ -306,21 +307,25 @@ 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()));
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.filterProximityJob()));
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.lightGathererJob()));
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.frustumCullingJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(testAspect.renderer()->updateGLResourcesBarrierJob()));
for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(materialGatherer));
}
// Step 5
for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) {
- QCOMPARE(renderViewBuilderJob->dependencies().size(), 1);
- QCOMPARE(renderViewBuilderJob->dependencies().first().data(), renderViewBuilder.syncRenderCommandBuildingJob().data());
+ QCOMPARE(renderViewBuilderJob->dependencies().size(), 4);
+ QVERIFY(renderViewBuilderJob->dependencies().contains(renderViewBuilder.syncRenderCommandBuildingJob()));
+ QVERIFY(renderViewBuilderJob->dependencies().contains(testAspect.renderer()->updateSkinningPaletteJob()));
+ QVERIFY(renderViewBuilderJob->dependencies().contains(testAspect.renderer()->updateWorldBoundingVolumeJob()));
+ QVERIFY(renderViewBuilderJob->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob()));
}
// Step 6
@@ -378,7 +383,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() + 7);
+ QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 8);
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.renderableEntityFilterJob()));
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.computableEntityFilterJob()));
@@ -386,14 +391,18 @@ private Q_SLOTS:
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.lightGathererJob()));
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.frustumCullingJob()));
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.filterProximityJob()));
+ QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(testAspect.renderer()->updateGLResourcesBarrierJob()));
for (const auto materialGatherer : renderViewBuilder.materialGathererJobs()) {
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(materialGatherer));
}
// Step 5
for (const auto renderViewBuilderJob : renderViewBuilder.renderViewBuilderJobs()) {
- QCOMPARE(renderViewBuilderJob->dependencies().size(), 1);
- QCOMPARE(renderViewBuilderJob->dependencies().first().data(), renderViewBuilder.syncRenderCommandBuildingJob().data());
+ QCOMPARE(renderViewBuilderJob->dependencies().size(), 4);
+ QVERIFY(renderViewBuilderJob->dependencies().contains(renderViewBuilder.syncRenderCommandBuildingJob()));
+ QVERIFY(renderViewBuilderJob->dependencies().contains(testAspect.renderer()->updateSkinningPaletteJob()));
+ QVERIFY(renderViewBuilderJob->dependencies().contains(testAspect.renderer()->updateWorldBoundingVolumeJob()));
+ QVERIFY(renderViewBuilderJob->dependencies().contains(testAspect.renderer()->updateShaderDataTransformJob()));
}
// Step 6
@@ -562,14 +571,14 @@ private Q_SLOTS:
renderViewBuilder.buildJobHierachy();
// THEN
- QCOMPARE(renderViewBuilder.frustumCullingJob()->viewProjection(), QMatrix4x4());
+ QCOMPARE(renderViewBuilder.frustumCullingJob()->viewProjection(), Matrix4x4());
// WHEN
renderViewBuilder.renderViewJob()->run();
renderViewBuilder.syncFrustumCullingJob()->run();
// THEN
- QCOMPARE(renderViewBuilder.frustumCullingJob()->viewProjection(), camera->projectionMatrix() * camera->viewMatrix());
+ QCOMPARE(convertToQMatrix4x4(renderViewBuilder.frustumCullingJob()->viewProjection()), camera->projectionMatrix() * camera->viewMatrix());
}
void checkRemoveEntitiesNotInSubset()
diff --git a/tests/auto/render/renderviews/tst_renderviews.cpp b/tests/auto/render/renderviews/tst_renderviews.cpp
index d941126e2..8ff1a584a 100644
--- a/tests/auto/render/renderviews/tst_renderviews.cpp
+++ b/tests/auto/render/renderviews/tst_renderviews.cpp
@@ -59,23 +59,6 @@ private Q_SLOTS:
}
- void checkRenderViewDoesNotLeak()
- {
- QSKIP("Allocated Disabled");
- // GIVEN
- Qt3DCore::QFrameAllocator allocator(192, 16, 128);
- RenderView *rv = allocator.allocate<RenderView>();
-
- // THEN
- QVERIFY(!allocator.isEmpty());
-
- // WHEN
- delete rv;
-
- // THEN
- QVERIFY(allocator.isEmpty());
- }
-
void checkRenderViewInitialState()
{
// GIVEN
diff --git a/tests/auto/render/renderviewutils/tst_renderviewutils.cpp b/tests/auto/render/renderviewutils/tst_renderviewutils.cpp
index 81d0ee4a2..247c5e0a3 100644
--- a/tests/auto/render/renderviewutils/tst_renderviewutils.cpp
+++ b/tests/auto/render/renderviewutils/tst_renderviewutils.cpp
@@ -711,17 +711,25 @@ void tst_RenderViewUtils::transformedProperties()
QScopedPointer<Qt3DRender::Render::ShaderDataManager> manager(new Qt3DRender::Render::ShaderDataManager());
// WHEN
- const QVector3D position = QVector3D(15.0f, -5.0f, 10.0f);
- QMatrix4x4 worldMatrix;
- QMatrix4x4 viewMatrix;
-
- worldMatrix.translate(-3.0f, 2.0f, 7.5f);
- viewMatrix.translate(9.0f, 6.0f, 12.0f);
+ const Vector3D position = Vector3D(15.0f, -5.0f, 10.0f);
+ const QVector3D positionQt = convertToQVector3D(position);
+ Matrix4x4 worldMatrix;
+ {
+ QMatrix4x4 m;
+ m.translate(-3.0f, 2.0f, 7.5f);
+ worldMatrix = Matrix4x4(m);
+ }
+ Matrix4x4 viewMatrix;
+ {
+ QMatrix4x4 m;
+ m.translate(9.0f, 6.0f, 12.0f);
+ viewMatrix = Matrix4x4(m);
+ }
- shaderData->setProperty("position0", position);
- shaderData->setProperty("position1", position);
- shaderData->setProperty("position2", position);
- shaderData->setProperty("position3", position);
+ shaderData->setProperty("position0", positionQt);
+ shaderData->setProperty("position1", positionQt);
+ shaderData->setProperty("position2", positionQt);
+ shaderData->setProperty("position3", positionQt);
shaderData->setProperty("position1Transformed", Qt3DRender::Render::ShaderData::ModelToEye);
shaderData->setProperty("position2Transformed", Qt3DRender::Render::ShaderData::ModelToWorld);
shaderData->setProperty("position3Transformed", Qt3DRender::Render::ShaderData::ModelToWorldDirection);
@@ -737,16 +745,16 @@ void tst_RenderViewUtils::transformedProperties()
// WHEN
backendShaderData->updateWorldTransform(worldMatrix);
- const QVector3D position1Value = backendShaderData->getTransformedProperty(QStringLiteral("position1"), viewMatrix).value<QVector3D>();
- const QVector3D position2Value = backendShaderData->getTransformedProperty(QStringLiteral("position2"), viewMatrix).value<QVector3D>();
- const QVector3D position3Value = backendShaderData->getTransformedProperty(QStringLiteral("position3"), viewMatrix).value<QVector3D>();
+ const Vector3D position1Value = backendShaderData->getTransformedProperty(QStringLiteral("position1"), viewMatrix).value<Vector3D>();
+ const Vector3D position2Value = backendShaderData->getTransformedProperty(QStringLiteral("position2"), viewMatrix).value<Vector3D>();
+ const Vector3D position3Value = backendShaderData->getTransformedProperty(QStringLiteral("position3"), viewMatrix).value<Vector3D>();
const QVariant position0Value = backendShaderData->getTransformedProperty(QStringLiteral("position0"), viewMatrix);
// THEN
QCOMPARE(position0Value, QVariant());
QCOMPARE(position1Value, viewMatrix * worldMatrix * position);
QCOMPARE(position2Value, worldMatrix * position);
- QCOMPARE(position3Value, (worldMatrix * QVector4D(position, 0.0f)).toVector3D());
+ QCOMPARE(position3Value, Vector3D((worldMatrix * Vector4D(position, 0.0f))));
}
void tst_RenderViewUtils::shouldNotifyDynamicPropertyChanges()
diff --git a/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
index 2c3f3f7c9..da420e1ac 100644
--- a/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
+++ b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
@@ -49,7 +49,7 @@ public:
}
- virtual void visit(uint andx, const QVector3D &a, uint bndx, const QVector3D &b)
+ virtual void visit(uint andx, const Vector3D &a, uint bndx, const Vector3D &b)
{
m_segments.push_back(TestSegment(andx, a, bndx, b));
}
@@ -69,7 +69,7 @@ public:
return m_segments.size();
}
- bool verifySegment(uint segment, uint andx, uint bndx, QVector3D a, QVector3D b) const
+ bool verifySegment(uint segment, uint andx, uint bndx, Vector3D a, Vector3D b) const
{
if (segment >= uint(m_segments.size()))
return false;
@@ -87,13 +87,13 @@ private:
struct TestSegment
{
uint abcndx[2];
- QVector3D abc[2];
+ Vector3D abc[2];
TestSegment()
{
abcndx[0] = abcndx[1] = uint(-1);
}
- TestSegment(uint andx, const QVector3D &a, uint bndx, const QVector3D &b)
+ TestSegment(uint andx, const Vector3D &a, uint bndx, const Vector3D &b)
{
abcndx[0] = andx;
abcndx[1] = bndx;
@@ -218,9 +218,9 @@ private Q_SLOTS:
// 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)));
+ QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,1), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 2,3, Vector3D(0,1,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifySegment(2, 4,5, Vector3D(1,0,0), Vector3D(0,1,0)));
}
void testVisitSegmentsIndexed()
@@ -318,11 +318,11 @@ private Q_SLOTS:
// 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)));
+ QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0)));
+ QVERIFY(visitor.verifySegment(3, 0,2, Vector3D(0,0,0), Vector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(4, 1,3, Vector3D(1,0,0), Vector3D(0,1,0)));
}
void testVisitLineStrip()
@@ -387,9 +387,9 @@ private Q_SLOTS:
// 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)));
+ QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0)));
}
void testVisitListStripIndexed()
@@ -481,9 +481,9 @@ private Q_SLOTS:
// 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)));
+ QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0)));
}
void testVisitLineLoop()
@@ -548,10 +548,10 @@ private Q_SLOTS:
// 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)));
+ QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0)));
+ QVERIFY(visitor.verifySegment(3, 3,0, Vector3D(0,1,0), Vector3D(0,0,0)));
}
void testVisitLineLoopIndexed()
@@ -643,10 +643,10 @@ private Q_SLOTS:
// 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)));
+ QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0)));
+ QVERIFY(visitor.verifySegment(3, 3,0, Vector3D(0,1,0), Vector3D(0,0,0)));
}
void testVisitLineAdjacency()
@@ -712,7 +712,7 @@ private Q_SLOTS:
// THEN
QCOMPARE(visitor.segmentCount(), uint(1));
- QVERIFY(visitor.verifySegment(0, 1, 2, QVector3D(1,0,0), QVector3D(0,1,0)));
+ QVERIFY(visitor.verifySegment(0, 1, 2, Vector3D(1,0,0), Vector3D(0,1,0)));
}
void testVisitLinesAdjacencyIndexed()
@@ -805,7 +805,7 @@ private Q_SLOTS:
// THEN
QCOMPARE(visitor.segmentCount(), uint(1));
- QVERIFY(visitor.verifySegment(0, 1, 2, QVector3D(1,0,0), QVector3D(0,1,0)));
+ QVERIFY(visitor.verifySegment(0, 1, 2, Vector3D(1,0,0), Vector3D(0,1,0)));
}
};
diff --git a/tests/auto/render/shadercache/tst_shadercache.cpp b/tests/auto/render/shadercache/tst_shadercache.cpp
index 1c70d4405..49628ef0f 100644
--- a/tests/auto/render/shadercache/tst_shadercache.cpp
+++ b/tests/auto/render/shadercache/tst_shadercache.cpp
@@ -131,6 +131,19 @@ void tst_ShaderCache::value()
auto dnaC = ProgramDNA(54321);
auto uncachedProgram = cache.getShaderProgramAndAddRef(dnaC, nodeIdB);
QVERIFY(uncachedProgram == nullptr);
+
+ cache.clear();
+ // Test inserting nullptr.
+ cache.insert(dnaA, nodeIdA, nullptr);
+ bool wasPresent = false;
+ cachedProgramA = cache.getShaderProgramAndAddRef(dnaA, nodeIdA, &wasPresent);
+ QCOMPARE(wasPresent, true);
+ QCOMPARE(cachedProgramA, nullptr);
+ cache.clear();
+ // Test wasPresent==false.
+ cachedProgramB = cache.getShaderProgramAndAddRef(dnaB, nodeIdB, &wasPresent);
+ QCOMPARE(wasPresent, false);
+ QCOMPARE(cachedProgramB, nullptr);
}
void tst_ShaderCache::removeRef()
diff --git a/tests/auto/render/transform/tst_transform.cpp b/tests/auto/render/transform/tst_transform.cpp
index ebb27953d..151baff76 100644
--- a/tests/auto/render/transform/tst_transform.cpp
+++ b/tests/auto/render/transform/tst_transform.cpp
@@ -49,7 +49,7 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendTransform.isEnabled(), false);
QVERIFY(backendTransform.peerId().isNull());
- QCOMPARE(backendTransform.transformMatrix(), QMatrix4x4());
+ QCOMPARE(convertToQMatrix4x4(backendTransform.transformMatrix()), QMatrix4x4());
}
void checkCleanupState()
@@ -71,7 +71,7 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendTransform.isEnabled(), false);
- QCOMPARE(backendTransform.transformMatrix(), QMatrix4x4());
+ QCOMPARE(convertToQMatrix4x4(backendTransform.transformMatrix()), QMatrix4x4());
QCOMPARE(backendTransform.rotation(), QQuaternion());
QCOMPARE(backendTransform.scale(), QVector3D());
QCOMPARE(backendTransform.translation(), QVector3D());
@@ -93,7 +93,7 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendTransform.isEnabled(), true);
QCOMPARE(backendTransform.peerId(), transform.id());
- QCOMPARE(backendTransform.transformMatrix(), transform.matrix());
+ QCOMPARE(convertToQMatrix4x4(backendTransform.transformMatrix()), transform.matrix());
QCOMPARE(backendTransform.rotation(), transform.rotation());
QCOMPARE(backendTransform.scale(), transform.scale3D());
QCOMPARE(backendTransform.translation(), transform.translation());
diff --git a/tests/auto/render/triangleboundingvolume/triangleboundingvolume.pro b/tests/auto/render/triangleboundingvolume/triangleboundingvolume.pro
index e88a997e2..dcbb2c17f 100644
--- a/tests/auto/render/triangleboundingvolume/triangleboundingvolume.pro
+++ b/tests/auto/render/triangleboundingvolume/triangleboundingvolume.pro
@@ -7,3 +7,4 @@ QT += 3dcore 3dcore-private 3drender 3drender-private testlib
CONFIG += testcase
SOURCES += tst_triangleboundingvolume.cpp
+
diff --git a/tests/auto/render/triangleboundingvolume/tst_triangleboundingvolume.cpp b/tests/auto/render/triangleboundingvolume/tst_triangleboundingvolume.cpp
index df375e777..b037c461f 100644
--- a/tests/auto/render/triangleboundingvolume/tst_triangleboundingvolume.cpp
+++ b/tests/auto/render/triangleboundingvolume/tst_triangleboundingvolume.cpp
@@ -47,43 +47,43 @@ private Q_SLOTS:
{
// GIVEN
Qt3DRender::Render::TriangleBoundingVolume volume = Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(),
- QVector3D(),
- QVector3D(),
- QVector3D());
+ Vector3D(),
+ Vector3D(),
+ Vector3D());
// THEN
QCOMPARE(volume.id(), Qt3DCore::QNodeId());
- QCOMPARE(volume.a(), QVector3D());
- QCOMPARE(volume.b(), QVector3D());
- QCOMPARE(volume.c(), QVector3D());
+ QCOMPARE(volume.a(), Vector3D());
+ QCOMPARE(volume.b(), Vector3D());
+ QCOMPARE(volume.c(), Vector3D());
QCOMPARE(volume.type(), Qt3DRender::RayCasting::QBoundingVolume::Triangle);
}
void transformed_data()
{
- QTest::addColumn<QVector3D>("a");
- QTest::addColumn<QVector3D>("b");
- QTest::addColumn<QVector3D>("c");
+ QTest::addColumn<Vector3D>("a");
+ QTest::addColumn<Vector3D>("b");
+ QTest::addColumn<Vector3D>("c");
- QTest::addColumn<QVector3D>("transformedA");
- QTest::addColumn<QVector3D>("transformedB");
- QTest::addColumn<QVector3D>("transformedC");
+ QTest::addColumn<Vector3D>("transformedA");
+ QTest::addColumn<Vector3D>("transformedB");
+ QTest::addColumn<Vector3D>("transformedC");
QTest::newRow("onFarPlane")
- << QVector3D(-1.0, 1.0, 0.0)
- << QVector3D(0.0, -1.0, 0.0)
- << QVector3D(1.0, 1.0, 0.0)
- << QVector3D(-1.0, 1.0, -40.0)
- << QVector3D(0.0, -1.0, -40.0)
- << QVector3D(1.0, 1.0, -40.0);
+ << Vector3D(-1.0, 1.0, 0.0)
+ << Vector3D(0.0, -1.0, 0.0)
+ << Vector3D(1.0, 1.0, 0.0)
+ << Vector3D(-1.0, 1.0, -40.0)
+ << Vector3D(0.0, -1.0, -40.0)
+ << Vector3D(1.0, 1.0, -40.0);
QTest::newRow("onNearPlane")
- << QVector3D(-1.0, 1.0, 40.0)
- << QVector3D(0.0, -1.0, 40.0)
- << QVector3D(1.0, 1.0, 40.0)
- << QVector3D(-1.0, 1.0, 0.0)
- << QVector3D(0.0, -1.0, 0.0)
- << QVector3D(1.0, 1.0, 0.0);
+ << Vector3D(-1.0, 1.0, 40.0)
+ << Vector3D(0.0, -1.0, 40.0)
+ << Vector3D(1.0, 1.0, 40.0)
+ << Vector3D(-1.0, 1.0, 0.0)
+ << Vector3D(0.0, -1.0, 0.0)
+ << Vector3D(1.0, 1.0, 0.0);
}
@@ -91,12 +91,12 @@ private Q_SLOTS:
void transformed()
{
// GIVEN
- QFETCH(QVector3D, a);
- QFETCH(QVector3D, b);
- QFETCH(QVector3D, c);
- QFETCH(QVector3D, transformedA);
- QFETCH(QVector3D, transformedB);
- QFETCH(QVector3D, transformedC);
+ QFETCH(Vector3D, a);
+ QFETCH(Vector3D, b);
+ QFETCH(Vector3D, c);
+ QFETCH(Vector3D, transformedA);
+ QFETCH(Vector3D, transformedB);
+ QFETCH(Vector3D, transformedC);
Qt3DRender::Render::TriangleBoundingVolume volume(Qt3DCore::QNodeId(),
a,
b,
@@ -111,7 +111,7 @@ private Q_SLOTS:
camera.setUpVector(QVector3D(0.0f, 1.0f, 0.0f));
camera.setViewCenter(QVector3D(0.0f, 0.0f, 0.0f));
- const QMatrix4x4 viewMatrix = camera.viewMatrix();
+ const Matrix4x4 viewMatrix(camera.viewMatrix());
// WHEN
volume.transform(viewMatrix);
@@ -125,61 +125,61 @@ private Q_SLOTS:
void intersects_data()
{
QTest::addColumn<Qt3DRender::RayCasting::QRay3D>("ray");
- QTest::addColumn<QVector3D>("a");
- QTest::addColumn<QVector3D>("b");
- QTest::addColumn<QVector3D>("c");
- QTest::addColumn<QVector3D>("uvw");
+ QTest::addColumn<Vector3D>("a");
+ QTest::addColumn<Vector3D>("b");
+ QTest::addColumn<Vector3D>("c");
+ QTest::addColumn<Vector3D>("uvw");
QTest::addColumn<float>("t");
QTest::addColumn<bool>("isIntersecting");
const float farPlaneDistance = 40.0;
QTest::newRow("halfway_center")
- << Qt3DRender::RayCasting::QRay3D(QVector3D(), QVector3D(0.0, 0.0, 1.0), farPlaneDistance)
- << QVector3D(3.0, 1.5, 20.0)
- << QVector3D(0.0, -1.5, 20.0)
- << QVector3D(-3, 1.5, 20.0)
- << QVector3D(0.25, 0.5, 0.25)
+ << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), farPlaneDistance)
+ << Vector3D(3.0, 1.5, 20.0)
+ << Vector3D(0.0, -1.5, 20.0)
+ << Vector3D(-3, 1.5, 20.0)
+ << Vector3D(0.25, 0.5, 0.25)
<< 0.5f
<< true;
QTest::newRow("miss_halfway_center_too_short")
- << Qt3DRender::RayCasting::QRay3D(QVector3D(), QVector3D(0.0, 0.0, 1.0), farPlaneDistance * 0.25f)
- << QVector3D(3.0, 1.5, 20.0)
- << QVector3D(0.0, -1.5, 20.0)
- << QVector3D(-3, 1.5, 20.0)
- << QVector3D()
+ << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), farPlaneDistance * 0.25f)
+ << Vector3D(3.0, 1.5, 20.0)
+ << Vector3D(0.0, -1.5, 20.0)
+ << Vector3D(-3, 1.5, 20.0)
+ << Vector3D()
<< 0.0f
<< false;
QTest::newRow("far_center")
- << Qt3DRender::RayCasting::QRay3D(QVector3D(), QVector3D(0.0, 0.0, 1.0), farPlaneDistance)
- << QVector3D(3.0, 1.5, 40.0)
- << QVector3D(0.0, -1.5, 40.0)
- << QVector3D(-3, 1.5, 40.0)
- << QVector3D(0.25, 0.5, 0.25)
+ << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), farPlaneDistance)
+ << Vector3D(3.0, 1.5, 40.0)
+ << Vector3D(0.0, -1.5, 40.0)
+ << Vector3D(-3, 1.5, 40.0)
+ << Vector3D(0.25, 0.5, 0.25)
<< 1.0f
<< true;
QTest::newRow("near_center")
- << Qt3DRender::RayCasting::QRay3D(QVector3D(), QVector3D(0.0, 0.0, 1.0), 1.0f)
- << QVector3D(3.0, 1.5, 0.0)
- << QVector3D(0.0, -1.5, 0.0)
- << QVector3D(-3, 1.5, 0.0)
- << QVector3D(0.25, 0.5, 0.25)
+ << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), 1.0f)
+ << Vector3D(3.0, 1.5, 0.0)
+ << Vector3D(0.0, -1.5, 0.0)
+ << Vector3D(-3, 1.5, 0.0)
+ << Vector3D(0.25, 0.5, 0.25)
<< 0.0f
<< true;
QTest::newRow("above_miss_center")
- << Qt3DRender::RayCasting::QRay3D(QVector3D(0.0, 2.0, 0.0), QVector3D(0.0, 2.0, 1.0), 1.0f)
- << QVector3D(3.0, 1.5, 0.0)
- << QVector3D(0.0, -1.5, 0.0)
- << QVector3D(-3, 1.5, 0.0)
- << QVector3D()
+ << Qt3DRender::RayCasting::QRay3D(Vector3D(0.0, 2.0, 0.0), Vector3D(0.0, 2.0, 1.0), 1.0f)
+ << Vector3D(3.0, 1.5, 0.0)
+ << Vector3D(0.0, -1.5, 0.0)
+ << Vector3D(-3, 1.5, 0.0)
+ << Vector3D()
<< 0.0f
<< false;
QTest::newRow("below_miss_center")
- << Qt3DRender::RayCasting::QRay3D(QVector3D(0.0, -2.0, 0.0), QVector3D(0.0, -2.0, 1.0), 1.0f)
- << QVector3D(3.0, 1.5, 0.0)
- << QVector3D(0.0, -1.5, 0.0)
- << QVector3D(-3, 1.5, 0.0)
- << QVector3D()
+ << Qt3DRender::RayCasting::QRay3D(Vector3D(0.0, -2.0, 0.0), Vector3D(0.0, -2.0, 1.0), 1.0f)
+ << Vector3D(3.0, 1.5, 0.0)
+ << Vector3D(0.0, -1.5, 0.0)
+ << Vector3D(-3, 1.5, 0.0)
+ << Vector3D()
<< 0.0f
<< false;
}
@@ -188,15 +188,15 @@ private Q_SLOTS:
{
// GIVEN
QFETCH(Qt3DRender::RayCasting::QRay3D, ray);
- QFETCH(QVector3D, a);
- QFETCH(QVector3D, b);
- QFETCH(QVector3D, c);
- QFETCH(QVector3D, uvw);
+ QFETCH(Vector3D, a);
+ QFETCH(Vector3D, b);
+ QFETCH(Vector3D, c);
+ QFETCH(Vector3D, uvw);
QFETCH(float, t);
QFETCH(bool, isIntersecting);
// WHEN
- QVector3D tmp_uvw;
+ Vector3D tmp_uvw;
float tmp_t;
const bool shouldBeIntersecting = Qt3DRender::Render::intersectsSegmentTriangle(ray,
a, b, c,
diff --git a/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp b/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp
index c6db3f62d..2f6d283be 100644
--- a/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp
+++ b/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp
@@ -353,10 +353,10 @@ private Q_SLOTS:
QVector<Qt3DRender::Render::TriangleBoundingVolume *> v =
QVector<Qt3DRender::Render::TriangleBoundingVolume *>()
- << new Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(), QVector3D(0, 1, 0), QVector3D(1, 0, -1), QVector3D(-1, 0, -1))
- << new Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(), QVector3D(-1, 0, -1), QVector3D(1, 0, -1), QVector3D(0, 0, 1))
- << new Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(), QVector3D(0, 0, 1), QVector3D(0, 1, 0), QVector3D(-1, 0, -1))
- << new Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(), QVector3D(0, 1, 0), QVector3D(0, 0, 1), QVector3D(1, 0, -1));
+ << new Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(), Vector3D(0, 1, 0), Vector3D(1, 0, -1), Vector3D(-1, 0, -1))
+ << new Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(), Vector3D(-1, 0, -1), Vector3D(1, 0, -1), Vector3D(0, 0, 1))
+ << new Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(), Vector3D(0, 0, 1), Vector3D(0, 1, 0), Vector3D(-1, 0, -1))
+ << new Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(), Vector3D(0, 1, 0), Vector3D(0, 0, 1), Vector3D(1, 0, -1));
QTest::newRow("indexedMesh") << customIndexedGeometryRenderer() << v;
QTest::newRow("nonIndexedMesh") << customNonIndexedGeometryRenderer() << v;
diff --git a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
index 9b6481423..4205d598e 100644
--- a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
+++ b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
@@ -49,7 +49,7 @@ public:
}
- virtual void visit(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c)
+ virtual void visit(uint andx, const Vector3D &a, uint bndx, const Vector3D &b, uint cndx, const Vector3D &c)
{
m_triangles.push_back(TestTriangle(andx, a, bndx, b, cndx, c));
}
@@ -69,7 +69,7 @@ public:
return m_triangles.size();
}
- bool verifyTriangle(uint triangle, uint andx, uint bndx, uint cndx, QVector3D a, QVector3D b, QVector3D c) const
+ bool verifyTriangle(uint triangle, uint andx, uint bndx, uint cndx, Vector3D a, Vector3D b, Vector3D c) const
{
if (triangle >= uint(m_triangles.size()))
return false;
@@ -89,13 +89,13 @@ private:
struct TestTriangle
{
uint abcndx[3];
- QVector3D abc[3];
+ Vector3D abc[3];
TestTriangle()
{
abcndx[0] = abcndx[1] = abcndx[2] = uint(-1);
}
- TestTriangle(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c)
+ TestTriangle(uint andx, const Vector3D &a, uint bndx, const Vector3D &b, uint cndx, const Vector3D &c)
{
abcndx[0] = andx;
abcndx[1] = bndx;
@@ -194,7 +194,7 @@ private Q_SLOTS:
positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
positionAttribute->setVertexSize(3);
positionAttribute->setCount(6);
- positionAttribute->setByteStride(3*4);
+ positionAttribute->setByteStride(0);
positionAttribute->setByteOffset(0);
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
geometry->addAttribute(positionAttribute.data());
@@ -220,8 +220,8 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 2);
- QVERIFY(visitor.verifyTriangle(0, 2,1,0, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(1, 5,4,3, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(1, 5,4,3, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
}
void testVisitTrianglesIndexed()
@@ -331,11 +331,11 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 5);
- QVERIFY(visitor.verifyTriangle(0, 2,1,0, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(1, 5,4,3, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(2, 0,1,5, QVector3D(0,0,1), QVector3D(1,0,0), QVector3D(0,1,0)));
- QVERIFY(visitor.verifyTriangle(3, 2,3,4, QVector3D(0,1,0), QVector3D(0,0,1), QVector3D(1,0,0)));
- QVERIFY(visitor.verifyTriangle(4, 4,2,0, QVector3D(1,0,0), QVector3D(0,1,0), QVector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(1, 5,4,3, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(2, 0,1,5, Vector3D(0,0,1), Vector3D(1,0,0), Vector3D(0,1,0)));
+ QVERIFY(visitor.verifyTriangle(3, 2,3,4, Vector3D(0,1,0), Vector3D(0,0,1), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifyTriangle(4, 4,2,0, Vector3D(1,0,0), Vector3D(0,1,0), Vector3D(0,0,1)));
}
void testVisitTriangleStrip()
@@ -407,10 +407,10 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 4);
- QVERIFY(visitor.verifyTriangle(0, 2,1,0, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(1, 3,2,1, QVector3D(0,0,1), QVector3D(0,1,0), QVector3D(1,0,0)));
- QVERIFY(visitor.verifyTriangle(2, 4,3,2, QVector3D(1,0,0), QVector3D(0,0,1), QVector3D(0,1,0)));
- QVERIFY(visitor.verifyTriangle(3, 5,4,3, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(1, 3,2,1, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifyTriangle(2, 4,3,2, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,1,0)));
+ QVERIFY(visitor.verifyTriangle(3, 5,4,3, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
}
void testVisitTriangleStripIndexed()
@@ -517,14 +517,14 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 8);
- QVERIFY(visitor.verifyTriangle(0, 2,1,0, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(1, 3,2,1, QVector3D(0,0,1), QVector3D(0,1,0), QVector3D(1,0,0)));
- QVERIFY(visitor.verifyTriangle(2, 4,3,2, QVector3D(1,0,0), QVector3D(0,0,1), QVector3D(0,1,0)));
- QVERIFY(visitor.verifyTriangle(3, 5,4,3, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(4, 0,1,5, QVector3D(0,0,1), QVector3D(1,0,0), QVector3D(0,1,0)));
- QVERIFY(visitor.verifyTriangle(5, 4,0,1, QVector3D(1,0,0), QVector3D(0,0,1), QVector3D(1,0,0)));
- QVERIFY(visitor.verifyTriangle(6, 3,4,0, QVector3D(0,0,1), QVector3D(1,0,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(7, 2,3,4, QVector3D(0,1,0), QVector3D(0,0,1), QVector3D(1,0,0)));
+ QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(1, 3,2,1, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifyTriangle(2, 4,3,2, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,1,0)));
+ QVERIFY(visitor.verifyTriangle(3, 5,4,3, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(4, 0,1,5, Vector3D(0,0,1), Vector3D(1,0,0), Vector3D(0,1,0)));
+ QVERIFY(visitor.verifyTriangle(5, 4,0,1, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifyTriangle(6, 3,4,0, Vector3D(0,0,1), Vector3D(1,0,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(7, 2,3,4, Vector3D(0,1,0), Vector3D(0,0,1), Vector3D(1,0,0)));
}
void testVisitTriangleFan()
@@ -596,10 +596,10 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 4);
- QVERIFY(visitor.verifyTriangle(0, 2,1,0, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(1, 3,2,0, QVector3D(0,0,1), QVector3D(0,1,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(2, 4,3,0, QVector3D(1,0,0), QVector3D(0,0,1), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(3, 5,4,0, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(1, 3,2,0, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(2, 4,3,0, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(3, 5,4,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
}
void testVisitTriangleFanIndexed()
@@ -700,10 +700,10 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 4);
- QVERIFY(visitor.verifyTriangle(0, 2,1,0, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(1, 3,2,0, QVector3D(0,0,1), QVector3D(0,1,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(2, 4,3,0, QVector3D(1,0,0), QVector3D(0,0,1), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(3, 5,4,0, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(1, 3,2,0, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(2, 4,3,0, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(3, 5,4,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
}
void testVisitTrianglesAdjacency()
@@ -775,7 +775,7 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 1);
- QVERIFY(visitor.verifyTriangle(0, 4,2,0, QVector3D(1,0,0), QVector3D(0,1,0), QVector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(0, 4,2,0, Vector3D(1,0,0), Vector3D(0,1,0), Vector3D(0,0,1)));
}
void testVisitTrianglesAdjacencyIndexed()
@@ -883,8 +883,8 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 2);
- QVERIFY(visitor.verifyTriangle(0, 4,2,0, QVector3D(1,0,0), QVector3D(0,1,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(1, 3,0,5, QVector3D(0,0,1), QVector3D(0,0,1), QVector3D(0,1,0)));
+ QVERIFY(visitor.verifyTriangle(0, 4,2,0, Vector3D(1,0,0), Vector3D(0,1,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(1, 3,0,5, Vector3D(0,0,1), Vector3D(0,0,1), Vector3D(0,1,0)));
}
void testVisitTriangleStripAdjacency()
@@ -969,8 +969,8 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 2);
- QVERIFY(visitor.verifyTriangle(0, 4,2,0, QVector3D(1,0,0), QVector3D(0,1,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(1, 6,4,2, QVector3D(1,1,1), QVector3D(1,0,0), QVector3D(0,1,0)));
+ QVERIFY(visitor.verifyTriangle(0, 4,2,0, Vector3D(1,0,0), Vector3D(0,1,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(1, 6,4,2, Vector3D(1,1,1), Vector3D(1,0,0), Vector3D(0,1,0)));
}
void testVisitTriangleStripAdjacencyIndexed()
@@ -1074,8 +1074,8 @@ private Q_SLOTS:
// THEN
QVERIFY(visitor.triangleCount() == 2);
- QVERIFY(visitor.verifyTriangle(0, 4,2,0, QVector3D(1,0,0), QVector3D(0,1,0), QVector3D(0,0,1)));
- QVERIFY(visitor.verifyTriangle(1, 5,4,2, QVector3D(0,1,0), QVector3D(1,0,0), QVector3D(0,1,0)));
+ QVERIFY(visitor.verifyTriangle(0, 4,2,0, Vector3D(1,0,0), Vector3D(0,1,0), Vector3D(0,0,1)));
+ QVERIFY(visitor.verifyTriangle(1, 5,4,2, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,1,0)));
}
};
diff --git a/tests/auto/render/uniform/tst_uniform.cpp b/tests/auto/render/uniform/tst_uniform.cpp
index b8578b294..213646369 100644
--- a/tests/auto/render/uniform/tst_uniform.cpp
+++ b/tests/auto/render/uniform/tst_uniform.cpp
@@ -107,7 +107,7 @@ private Q_SLOTS:
}
{
// GIVEN
- UniformValue v(QVector3D(572.0f, 355.0f, 383.0f));
+ UniformValue v(Vector3D(572.0f, 355.0f, 383.0f));
// THEN
QCOMPARE(v.constData<float>()[0], 572.0f);
QCOMPARE(v.constData<float>()[1], 355.0f);
@@ -116,7 +116,7 @@ private Q_SLOTS:
}
{
// GIVEN
- UniformValue v(QVector4D(355.0f, 383.0f, 1340.0f, 1603.0f));
+ UniformValue v(Vector4D(355.0f, 383.0f, 1340.0f, 1603.0f));
// THEN
QCOMPARE(v.constData<float>()[0], 355.0f);
QCOMPARE(v.constData<float>()[1], 383.0f);
@@ -340,7 +340,7 @@ private Q_SLOTS:
void checkComparison()
{
// GIVEN
- const UniformValue v1(QVector3D(454.0f, 883.0f, 572.0f));
+ const UniformValue v1(Vector3D(454.0f, 883.0f, 572.0f));
UniformValue v2(454.0f);
// THEN
@@ -348,13 +348,13 @@ private Q_SLOTS:
QVERIFY(v1 != v2);
// WHEN
- v2 = UniformValue::fromVariant(QVector3D(454.0f, 883.0f, 572.0f));
+ v2 = UniformValue::fromVariant(QVariant::fromValue(Vector3D(454.0f, 883.0f, 572.0f)));
// THEN
QVERIFY(v1 == v2);
QVERIFY(!(v1 != v2));
// WHEN
- v2 = UniformValue::fromVariant(QVector3D(454.0f, 883.0f, 572.0f));
+ v2 = UniformValue::fromVariant(QVariant::fromValue(Vector3D(454.0f, 883.0f, 572.0f)));
// THEN
QVERIFY(v1 == v2);
QVERIFY(!(v1 != v2));
diff --git a/tests/auto/render/updateshaderdatatransformjob/tst_updateshaderdatatransformjob.cpp b/tests/auto/render/updateshaderdatatransformjob/tst_updateshaderdatatransformjob.cpp
index c076aa21e..67ddccd9b 100644
--- a/tests/auto/render/updateshaderdatatransformjob/tst_updateshaderdatatransformjob.cpp
+++ b/tests/auto/render/updateshaderdatatransformjob/tst_updateshaderdatatransformjob.cpp
@@ -179,7 +179,8 @@ private Q_SLOTS:
// THEN
// See scene file to find translation
- QCOMPARE(backendShaderData->getTransformedProperty(QLatin1String("eyePosition"), camera->viewMatrix()).value<QVector3D>(), camera->viewMatrix() * (QVector3D(1.0f, 1.0f, 1.0f) + QVector3D(0.0f, 5.0f, 0.0f)));
+ QCOMPARE(backendShaderData->getTransformedProperty(QLatin1String("eyePosition"), Matrix4x4(camera->viewMatrix())).value<Vector3D>(),
+ Matrix4x4(camera->viewMatrix()) * (Vector3D(1.0f, 1.0f, 1.0f) + Vector3D(0.0f, 5.0f, 0.0f)));
}
void checkRunModelToWorld()
@@ -219,7 +220,8 @@ private Q_SLOTS:
// THEN
// See scene file to find translation
- QCOMPARE(backendShaderData->getTransformedProperty(QLatin1String("position"), camera->viewMatrix()).value<QVector3D>(), QVector3D(1.0f, 1.0f, 1.0f) + QVector3D(5.0f, 5.0f, 5.0f));
+ QCOMPARE(backendShaderData->getTransformedProperty(QLatin1String("position"), Matrix4x4(camera->viewMatrix())).value<Vector3D>(),
+ Vector3D(1.0f, 1.0f, 1.0f) + Vector3D(5.0f, 5.0f, 5.0f));
}
};