summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2017-08-19 15:53:30 +0100
committerSean Harmer <sean.harmer@kdab.com>2017-08-19 16:28:52 +0100
commit8f863343a9e2e2f3630f22407f4e5e30e72745cf (patch)
tree5574e3c2215d74345e15df5f45ed3211e065541a
parent3edb85002b848033bbeefa33001d19fb514ef489 (diff)
parent9d8c9ada161ad97634992c444196add0abb4f9d1 (diff)
Merge branch '5.9' into dev
Conflicts: src/render/backend/renderer.cpp src/render/backend/renderview.cpp src/render/graphicshelpers/graphicscontext_p.h src/render/graphicshelpers/graphicshelperes2_p.h src/render/graphicshelpers/graphicshelpergl2_p.h src/render/graphicshelpers/graphicshelpergl3_2_p.h src/render/graphicshelpers/graphicshelpergl3_3_p.h src/render/graphicshelpers/graphicshelpergl4_p.h src/render/graphicshelpers/graphicshelperinterface_p.h src/render/jobs/pickboundingvolumejob.cpp tests/auto/animation/clipanimator/tst_clipanimator.cpp tests/auto/auto.pro tests/manual/manual.pro Also disabled the QQmlMetaType codepaths following commit 49a11e882059ee1729f776722e085dd21d378c36 in qtdeclarative. The QQmlMetaType codepaths will be re-enabled once a qt5.git integration has succeeded. Change-Id: Ia654d75425e6d406c472d19864383612208cad2b
-rw-r--r--src/animation/backend/handler.cpp4
-rw-r--r--src/animation/frontend/qadditiveclipblend.cpp4
-rw-r--r--src/animation/frontend/qblendedclipanimator.cpp7
-rw-r--r--src/animation/frontend/qclipanimator.cpp3
-rw-r--r--src/core/jobs/qthreadpooler.cpp1
-rw-r--r--src/doc/src/qt3d-module.qdoc2
-rw-r--r--src/doc/src/qt3danimation-module.qdoc4
-rw-r--r--src/extras/text/qtext2dentity.cpp19
-rw-r--r--src/input/backend/keyeventdispatcherjob.cpp2
-rw-r--r--src/input/backend/mouseeventdispatcherjob.cpp4
-rw-r--r--src/input/frontend/qabstractphysicaldevice.cpp3
-rw-r--r--src/input/frontend/qaxisaccumulator.cpp18
-rw-r--r--src/input/frontend/qmousehandler.cpp74
-rw-r--r--src/plugins/sceneparsers/assimp/assimpimporter.cpp34
-rw-r--r--src/quick3d/quick3d/qt3dquicknodefactory.cpp2
-rw-r--r--src/quick3d/quick3d/qt3dquicknodefactory_p.h2
-rw-r--r--src/quick3d/quick3danimation/qt3dquickanimationnodefactory.cpp3
-rw-r--r--src/quick3d/quick3danimation/qt3dquickanimationnodefactory_p.h1
-rw-r--r--src/quick3d/quick3dextras/qt3dquickextrasnodefactory.cpp2
-rw-r--r--src/quick3d/quick3dinput/qt3dquickinputnodefactory.cpp3
-rw-r--r--src/quick3d/quick3dinput/qt3dquickinputnodefactory_p.h2
-rw-r--r--src/quick3d/quick3drender/qt3dquickrendernodefactory.cpp3
-rw-r--r--src/quick3d/quick3drender/qt3dquickrendernodefactory_p.h2
-rw-r--r--src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory.cpp3
-rw-r--r--src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory_p.h1
-rw-r--r--src/render/backend/entity.cpp6
-rw-r--r--src/render/backend/rendercommand.cpp10
-rw-r--r--src/render/backend/rendercommand_p.h10
-rw-r--r--src/render/backend/renderer.cpp11
-rw-r--r--src/render/backend/renderview.cpp189
-rw-r--r--src/render/backend/renderview_p.h2
-rw-r--r--src/render/frontend/qlevelofdetail.cpp2
-rw-r--r--src/render/frontend/qrenderaspect.cpp1
-rw-r--r--src/render/geometry/qgeometryrenderer.cpp1
-rw-r--r--src/render/geometry/qmesh.cpp28
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp10
-rw-r--r--src/render/graphicshelpers/graphicscontext_p.h3
-rw-r--r--src/render/graphicshelpers/graphicshelperes2.cpp24
-rw-r--r--src/render/graphicshelpers/graphicshelperes2_p.h2
-rw-r--r--src/render/graphicshelpers/graphicshelpergl2.cpp20
-rw-r--r--src/render/graphicshelpers/graphicshelpergl2_p.h2
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_2.cpp15
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_2_p.h2
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_3.cpp15
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_3_p.h2
-rw-r--r--src/render/graphicshelpers/graphicshelpergl4.cpp17
-rw-r--r--src/render/graphicshelpers/graphicshelpergl4_p.h2
-rw-r--r--src/render/graphicshelpers/graphicshelperinterface_p.h8
-rw-r--r--src/render/jobs/pickboundingvolumejob.cpp40
-rw-r--r--src/render/materialsystem/qparameter.cpp4
-rw-r--r--src/render/picking/qobjectpicker.cpp97
-rw-r--r--src/render/picking/qpicklineevent.h3
-rw-r--r--src/render/picking/qpickpointevent.h3
-rw-r--r--src/render/picking/qpicktriangleevent.h3
-rw-r--r--src/render/renderstates/qstencilmask_p.h2
-rw-r--r--src/render/renderstates/qstenciloperation.cpp49
-rw-r--r--src/render/renderstates/qstenciloperation_p.h15
-rw-r--r--src/render/renderstates/qstenciltest.cpp49
-rw-r--r--src/render/renderstates/qstenciltest_p.h15
-rw-r--r--src/render/renderstates/renderstates.cpp59
-rw-r--r--src/render/renderstates/renderstates_p.h3
-rw-r--r--src/render/renderstates/statevariant_p.h2
-rw-r--r--src/render/services/vsyncframeadvanceservice.cpp20
-rw-r--r--src/render/services/vsyncframeadvanceservice_p.h2
-rw-r--r--src/render/texture/qpaintedtextureimage.cpp2
-rw-r--r--src/src.pro2
-rw-r--r--sync.profile1
-rw-r--r--tests/auto/animation/animationclip/tst_animationclip.cpp4
-rw-r--r--tests/auto/animation/channelmapper/tst_channelmapper.cpp2
-rw-r--r--tests/auto/animation/channelmapping/tst_channelmapping.cpp8
-rw-r--r--tests/auto/animation/clipanimator/tst_clipanimator.cpp10
-rw-r--r--tests/auto/auto.pro8
-rw-r--r--tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp2
-rw-r--r--tests/auto/coretest/coretest.pro25
-rw-r--r--tests/auto/coretest/qbackendnodetester.cpp73
-rw-r--r--tests/auto/coretest/qbackendnodetester_p.h78
-rw-r--r--tests/auto/coretest/testpostmanarbiter.cpp90
-rw-r--r--tests/auto/coretest/testpostmanarbiter_p.h92
-rw-r--r--tests/auto/input/abstractaxisinput/tst_abstractaxisinput.cpp2
-rw-r--r--tests/auto/input/action/tst_action.cpp2
-rw-r--r--tests/auto/input/actioninput/tst_actioninput.cpp4
-rw-r--r--tests/auto/input/analogaxisinput/tst_analogaxisinput.cpp4
-rw-r--r--tests/auto/input/axis/tst_axis.cpp2
-rw-r--r--tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp2
-rw-r--r--tests/auto/input/buttonaxisinput/tst_buttonaxisinput.cpp14
-rw-r--r--tests/auto/input/inputchord/tst_inputchord.cpp2
-rw-r--r--tests/auto/input/inputsequence/tst_inputsequence.cpp4
-rw-r--r--tests/auto/input/keyboardhandler/tst_keyboardhandler.cpp6
-rw-r--r--tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp2
-rw-r--r--tests/auto/render/attribute/tst_attribute.cpp18
-rw-r--r--tests/auto/render/buffer/tst_buffer.cpp10
-rw-r--r--tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp16
-rw-r--r--tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp24
-rw-r--r--tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp24
-rw-r--r--tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp24
-rw-r--r--tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp24
-rw-r--r--tests/auto/render/qrenderstate/qrenderstate.pro12
-rw-r--r--tests/auto/render/qrenderstate/tst_qrenderstate.cpp300
-rw-r--r--tests/auto/render/qsceneloader/tst_qsceneloader.cpp2
-rw-r--r--tests/auto/render/render.pro1
-rw-r--r--tests/auto/render/renderviews/tst_renderviews.cpp188
-rw-r--r--tests/auto/render/sceneloader/tst_sceneloader.cpp2
-rw-r--r--tests/auto/render/texture/tst_texture.cpp8
-rw-r--r--tests/auto/render/vsyncframeadvanceservice/tst_vsyncframeadvanceservice.cpp84
-rw-r--r--tests/manual/deferred-renderer-qml/SceneEffect.qml16
-rw-r--r--tests/manual/deferred-renderer-qml/SceneEntity.qml59
-rw-r--r--tests/manual/deferred-renderer-qml/ScreenQuadEntity.qml98
-rw-r--r--tests/manual/deferred-renderer-qml/deferred-renderer-qml.pro2
-rw-r--r--tests/manual/deferred-renderer-qml/main.qml9
-rw-r--r--tests/manual/manual.pro3
-rw-r--r--tests/manual/rendercapture-qml-fbo/CaptureScene.qml210
-rw-r--r--tests/manual/rendercapture-qml-fbo/main.cpp75
-rw-r--r--tests/manual/rendercapture-qml-fbo/main.qml136
-rw-r--r--tests/manual/rendercapture-qml-fbo/qml.qrc6
-rw-r--r--tests/manual/rendercapture-qml-fbo/rendercapture-qml-fbo.pro18
-rw-r--r--tests/manual/rendercapture-qml-fbo/rendercaptureprovider.h85
116 files changed, 2483 insertions, 363 deletions
diff --git a/src/animation/backend/handler.cpp b/src/animation/backend/handler.cpp
index 8ced81cd1..ce7aa3c17 100644
--- a/src/animation/backend/handler.cpp
+++ b/src/animation/backend/handler.cpp
@@ -217,7 +217,7 @@ QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time)
if (oldSize < newSize) {
m_evaluateClipAnimatorJobs.resize(newSize);
for (int i = oldSize; i < newSize; ++i) {
- m_evaluateClipAnimatorJobs[i].reset(new EvaluateClipAnimatorJob());
+ m_evaluateClipAnimatorJobs[i] = QSharedPointer<EvaluateClipAnimatorJob>::create();
m_evaluateClipAnimatorJobs[i]->setHandler(this);
}
}
@@ -243,7 +243,7 @@ QVector<Qt3DCore::QAspectJobPtr> Handler::jobsToExecute(qint64 time)
if (oldSize < newSize) {
m_evaluateBlendClipAnimatorJobs.resize(newSize);
for (int i = oldSize; i < newSize; ++i) {
- m_evaluateBlendClipAnimatorJobs[i].reset(new EvaluateBlendClipAnimatorJob());
+ m_evaluateBlendClipAnimatorJobs[i] = QSharedPointer<EvaluateBlendClipAnimatorJob>::create();
m_evaluateBlendClipAnimatorJobs[i]->setHandler(this);
}
}
diff --git a/src/animation/frontend/qadditiveclipblend.cpp b/src/animation/frontend/qadditiveclipblend.cpp
index 5cbd75af6..dda3265c2 100644
--- a/src/animation/frontend/qadditiveclipblend.cpp
+++ b/src/animation/frontend/qadditiveclipblend.cpp
@@ -165,7 +165,7 @@ float QAdditiveClipBlend::additiveFactor() const
}
/*!
- \qmlproperty AbstractClipBlendNode baseClip
+ \qmlproperty AbstractClipBlendNode Qt3D.Animation::AdditiveClipBlend::baseClip
This property holds the base animation clip. When the additiveFactor is zero the \a baseClip will
also be the resulting clip of this blend node.
@@ -183,7 +183,7 @@ QAbstractClipBlendNode *QAdditiveClipBlend::baseClip() const
}
/*!
- \qmlproperty AbstractClipBlendNode additiveClip
+ \qmlproperty AbstractClipBlendNode Qt3D.Animation::AdditiveClipBlend::additiveClip
This property holds the additive clip to be blended with the baseClip. The amount of blending
is controlled by the additiveFactor property.
diff --git a/src/animation/frontend/qblendedclipanimator.cpp b/src/animation/frontend/qblendedclipanimator.cpp
index 90d82a69f..93cc27f50 100644
--- a/src/animation/frontend/qblendedclipanimator.cpp
+++ b/src/animation/frontend/qblendedclipanimator.cpp
@@ -267,12 +267,11 @@ QBlendedClipAnimator::~QBlendedClipAnimator()
}
/*!
- \qmlproperty AbstractClipBlendNode blendTree
+ \qmlproperty AbstractClipBlendNode Qt3D.Animation::BlendedClipAnimator::blendTree
- This property holds the root of the animation blend tree that will be evaluated before being
- interpolated by the animator.
+ This property holds the root of the animation blend tree that will
+ be evaluated before being interpolated by the animator.
*/
-
/*!
\property QBlendedClipAnimator::blendTree
diff --git a/src/animation/frontend/qclipanimator.cpp b/src/animation/frontend/qclipanimator.cpp
index 4fe21828f..19e6eafed 100644
--- a/src/animation/frontend/qclipanimator.cpp
+++ b/src/animation/frontend/qclipanimator.cpp
@@ -117,12 +117,11 @@ QClipAnimator::~QClipAnimator()
}
/*!
- \qmlproperty AbstractAnimationClip clip
+ \qmlproperty var Qt3D.Animation::ClipAnimator::clip
This property holds the animation clip which contains the key frame data to be played back.
The key frame data can be specified in either an AnimationClip or AnimationClipLoader.
*/
-
/*!
\property QClipAnimator::clip
diff --git a/src/core/jobs/qthreadpooler.cpp b/src/core/jobs/qthreadpooler.cpp
index 2e5788b89..57a1b09a6 100644
--- a/src/core/jobs/qthreadpooler.cpp
+++ b/src/core/jobs/qthreadpooler.cpp
@@ -45,6 +45,7 @@
#include <QtCore/QFile>
#include <QtCore/QThreadStorage>
#include <QtCore/QDateTime>
+#include <QtCore/QCoreApplication>
#endif
#include <Qt3DCore/private/dependencyhandler_p.h>
diff --git a/src/doc/src/qt3d-module.qdoc b/src/doc/src/qt3d-module.qdoc
index 0e26375a9..86a17342e 100644
--- a/src/doc/src/qt3d-module.qdoc
+++ b/src/doc/src/qt3d-module.qdoc
@@ -117,7 +117,7 @@
import Qt3D.Input 2.0
import Qt3D.Logic 2.0
import Qt3D.Extras 2.0
- import Qt3D.Animation 2.0
+ import Qt3D.Animation 2.9
\endcode
\section1 QML Types
diff --git a/src/doc/src/qt3danimation-module.qdoc b/src/doc/src/qt3danimation-module.qdoc
index 0601a8973..ed3406aa4 100644
--- a/src/doc/src/qt3danimation-module.qdoc
+++ b/src/doc/src/qt3danimation-module.qdoc
@@ -213,7 +213,7 @@
*/
/*!
- \qmlmodule Qt3D.Animation 2.0
+ \qmlmodule Qt3D.Animation 2.9
\title Qt 3D Qt3DAnimation QML Types
\ingroup qmlmodules
\ingroup qt3d-qmlmodules
@@ -223,6 +223,6 @@
To import and use the module's QML types, use the following statement:
\badcode
- import Qt3D.Animation 2.0
+ import Qt3D.Animation 2.9
\endcode
*/
diff --git a/src/extras/text/qtext2dentity.cpp b/src/extras/text/qtext2dentity.cpp
index 1dfd171cd..10939a1e2 100644
--- a/src/extras/text/qtext2dentity.cpp
+++ b/src/extras/text/qtext2dentity.cpp
@@ -284,6 +284,10 @@ void QText2DEntityPrivate::update()
setCurrentGlyphRuns(glyphRuns);
}
+/*!
+ Returns the font for the text item that is displayed
+ in the Qt Quick scene.
+*/
QFont QText2DEntity::font() const
{
Q_D(const QText2DEntity);
@@ -308,6 +312,10 @@ void QText2DEntity::setFont(const QFont &font)
}
}
+/*!
+ Returns the color for the text item that is displayed in the Qt
+ Quick scene.
+*/
QColor QText2DEntity::color() const
{
Q_D(const QText2DEntity);
@@ -327,6 +335,9 @@ void QText2DEntity::setColor(const QColor &color)
}
}
+/*!
+ Returns the text that is displayed in the Qt Quick scene.
+*/
QString QText2DEntity::text() const
{
Q_D(const QText2DEntity);
@@ -344,12 +355,20 @@ void QText2DEntity::setText(const QString &text)
}
}
+/*!
+ Returns the width of the text item that is displayed in the
+ Qt Quick scene.
+*/
float QText2DEntity::width() const
{
Q_D(const QText2DEntity);
return d->m_width;
}
+/*!
+ Returns the width of the text item that is displayed in the
+ Qt Quick scene.
+*/
float QText2DEntity::height() const
{
Q_D(const QText2DEntity);
diff --git a/src/input/backend/keyeventdispatcherjob.cpp b/src/input/backend/keyeventdispatcherjob.cpp
index ac90e9e37..6201453fc 100644
--- a/src/input/backend/keyeventdispatcherjob.cpp
+++ b/src/input/backend/keyeventdispatcherjob.cpp
@@ -69,7 +69,7 @@ void KeyEventDispatcherJob::run()
if (input)
for (const QT_PREPEND_NAMESPACE(QKeyEvent) &e : qAsConst(m_events)) {
// Send events to frontend
- input->keyEvent(QKeyEventPtr(new QKeyEvent(e)));
+ input->keyEvent(QKeyEventPtr::create(e));
}
}
diff --git a/src/input/backend/mouseeventdispatcherjob.cpp b/src/input/backend/mouseeventdispatcherjob.cpp
index 11653d8a8..4bd3e93c3 100644
--- a/src/input/backend/mouseeventdispatcherjob.cpp
+++ b/src/input/backend/mouseeventdispatcherjob.cpp
@@ -77,10 +77,10 @@ void MouseEventDispatcherJob::run()
if (input) {
// Send mouse and wheel events to frontend
for (const QT_PREPEND_NAMESPACE(QMouseEvent) &e : m_mouseEvents)
- input->mouseEvent(QMouseEventPtr(new QMouseEvent(e)));
+ input->mouseEvent(QMouseEventPtr::create(e));
#if QT_CONFIG(wheelevent)
for (const QT_PREPEND_NAMESPACE(QWheelEvent) &e : m_wheelEvents)
- input->wheelEvent(QWheelEventPtr(new QWheelEvent(e)));
+ input->wheelEvent(QWheelEventPtr::create(e));
#endif
}
}
diff --git a/src/input/frontend/qabstractphysicaldevice.cpp b/src/input/frontend/qabstractphysicaldevice.cpp
index 8a0e81e0c..dc54228d4 100644
--- a/src/input/frontend/qabstractphysicaldevice.cpp
+++ b/src/input/frontend/qabstractphysicaldevice.cpp
@@ -228,6 +228,9 @@ void QAbstractPhysicalDevicePrivate::postButtonEvent(int button, qreal value)
notifyObservers(change);
}
+/*!
+ \internal
+*/
Qt3DCore::QNodeCreatedChangeBasePtr QAbstractPhysicalDevice::createNodeCreationChange() const
{
auto creationChange = QPhysicalDeviceCreatedChangeBasePtr::create(this);
diff --git a/src/input/frontend/qaxisaccumulator.cpp b/src/input/frontend/qaxisaccumulator.cpp
index 5f10d81a7..d656ad2de 100644
--- a/src/input/frontend/qaxisaccumulator.cpp
+++ b/src/input/frontend/qaxisaccumulator.cpp
@@ -199,6 +199,16 @@ float QAxisAccumulator::value() const
}
/*!
+ \qmlproperty real Qt3D.Input::Axis::velocity
+ \readonly
+
+ Returns the velocity. If the sourceAxisType is set to Velocity this is
+ simply the value of the source axis multiplied by the scale. If the
+ sourceAxisType is set to Acceleration, the velocity is integrated using the
+ source axis' value as an acceleration.
+*/
+
+/*!
Returns the velocity. If the sourceAxisType is set to Velocity this is
simply the value of the source axis multiplied by the scale. If the
sourceAxisType is set to Acceleration, the velocity is integrated using
@@ -211,6 +221,14 @@ float QAxisAccumulator::velocity() const
}
/*!
+ \qmlproperty real Qt3D.Input::Axis::scale
+
+ The amount to scale the axis value by when accumulating. This can be
+ thought of as the maximum velocity or acceleration the axis can
+ control.
+*/
+
+/*!
The amount to scale the axis value by when accumulating. This can be
thought of as the maximum velocity or acceleration the axis can
control.
diff --git a/src/input/frontend/qmousehandler.cpp b/src/input/frontend/qmousehandler.cpp
index 419052d8a..61708425a 100644
--- a/src/input/frontend/qmousehandler.cpp
+++ b/src/input/frontend/qmousehandler.cpp
@@ -107,7 +107,7 @@ void QMouseHandlerPrivate::mouseEvent(const QMouseEventPtr &event)
* \brief Provides mouse event notification
*
* \TODO
- * \sa MouseDevice
+ * \sa MouseDevice, MouseEvent
*/
/*!
@@ -123,28 +123,34 @@ void QMouseHandlerPrivate::mouseEvent(const QMouseEventPtr &event)
* \note QMouseHandler components shouldn't be shared, not respecting that
* condition will most likely result in undefined behaviors.
*
- * \sa QMouseDevice
+ * \sa QMouseDevice, QMouseEvent
*/
/*!
\qmlproperty MouseDevice Qt3D.Input::MouseHandler::sourceDevice
+
Holds the current mouse source device of the MouseHandler instance.
*/
/*!
\qmlproperty bool Qt3D.Input::MouseHandler::containsMouse
\readonly
+
Holds \c true if the QMouseHandler currently contains the mouse.
*/
/*!
- \qmlsignal Qt3D.Input::MouseHandler::clicked()
- This signal is emitted when a mouse button is clicked
+ \qmlsignal Qt3D.Input::MouseHandler::clicked(MouseEvent mouse)
+
+ This signal is emitted when a mouse button is clicked with the event details
+ being contained within \a mouse
*/
/*!
- \qmlsignal Qt3D.Input::MouseHandler::doubleClicked()
- This signal is emitted when a mouse button is double clicked
+ \qmlsignal Qt3D.Input::MouseHandler::doubleClicked(MouseEvent mouse)
+
+ This signal is emitted when a mouse button is double clicked with the event
+ details being contained within \a mouse
*/
/*!
@@ -156,41 +162,52 @@ void QMouseHandlerPrivate::mouseEvent(const QMouseEventPtr &event)
*/
/*!
- \qmlsignal Qt3D.Input::MouseHandler::pressed()
- This signal is emitted when a mouse button is pressed
- */
+ \qmlsignal Qt3D.Input::MouseHandler::pressed(MouseEvent mouse)
-/*!
- \qmlsignal Qt3D.Input::MouseHandler::released()
- This signal is emitted when a mouse button is released
+ This signal is emitted when a mouse button is pressed with the event details
+ being contained within \a mouse
*/
/*!
- \qmlsignal Qt3D.Input::MouseHandler::pressAndHold()
- This signal is emitted when a mouse button is pressed and held down
+ \qmlsignal Qt3D.Input::MouseHandler::released(MouseEvent mouse)
+
+ This signal is emitted when a mouse button is released with the event
+ details being contained within \a mouse
*/
/*!
- \qmlsignal Qt3D.Input::MouseHandler::positionChanged()
- This signal is emitted when the mouse position changes
+ \qmlsignal Qt3D.Input::MouseHandler::pressAndHold(MouseEvent mouse)
+
+ This signal is emitted when a mouse button is pressed and held down with the
+ event details being contained within \a mouse
*/
/*!
- \qmlsignal Qt3D.Input::MouseHandler::wheel()
- This signal is emitted when the mouse wheel is used
+ \qmlsignal Qt3D.Input::MouseHandler::positionChanged(MouseEvent mouse)
+
+ This signal is emitted when the mouse position changes with the event
+ details being contained within \a mouse
*/
+/*!
+ \qmlsignal Qt3D.Input::MouseHandler::wheel(MouseEvent mouse)
+ This signal is emitted when the mouse wheel is used with the event details
+ being contained within \a wheel
+ */
/*!
\fn QMouseHandler::clicked(Qt3DInput::QMouseEvent *mouse)
- This signal is emitted when a mouse button is clicked with the event details being contained within \a mouse
+
+ This signal is emitted when a mouse button is clicked with the event details
+ being contained within \a mouse
*/
/*!
\fn QMouseHandler::doubleClicked(Qt3DInput::QMouseEvent *mouse)
- This signal is emitted when a mouse button is double clicked with the event details being contained within \a mouse
+ This signal is emitted when a mouse button is double clicked with the event
+ details being contained within \a mouse
*/
/*!
@@ -203,30 +220,37 @@ void QMouseHandlerPrivate::mouseEvent(const QMouseEventPtr &event)
/*!
\fn QMouseHandler::pressed(Qt3DInput::QMouseEvent *mouse)
- This signal is emitted when a mouse button is pressed with the event details being contained within \a mouse
+
+ This signal is emitted when a mouse button is pressed with the event details
+ being contained within \a mouse
*/
/*!
\fn QMouseHandler::released(Qt3DInput::QMouseEvent *mouse)
- This signal is emitted when a mouse button is released with the event details being contained within \a mouse
+ This signal is emitted when a mouse button is released with the event
+ details being contained within \a mouse
*/
/*!
\fn QMouseHandler::pressAndHold(Qt3DInput::QMouseEvent *mouse)
- This signal is emitted when a mouse button is pressed and held down with the event details being contained within \a mouse
+
+ This signal is emitted when a mouse button is pressed and held down with the
+ event details being contained within \a mouse
*/
/*!
\fn QMouseHandler::positionChanged(Qt3DInput::QMouseEvent *mouse)
- This signal is emitted when the mouse position changes with the event details being contained within \a mouse
+ This signal is emitted when the mouse position changes with the event
+ details being contained within \a mouse
*/
/*!
\fn QMouseHandler::wheel(Qt3DInput::QWheelEvent *wheel)
- This signal is emitted when the mouse wheel is used with the event details being contained within \a wheel
+ This signal is emitted when the mouse wheel is used with the event details
+ being contained within \a wheel
*/
/*!
diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
index fb0d8b1a9..a2f500a6c 100644
--- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp
+++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
@@ -693,6 +693,13 @@ void AssimpImporter::loadMaterial(uint materialIndex)
copyMaterialTextures(material, assimpMaterial);
m_scene->m_materials.insert(materialIndex, material);
+
+ Qt3DRender::AssimpImporter::SceneImporter *scene = m_scene;
+ QObject::connect(material, &QObject::destroyed, [&, scene, materialIndex](QObject *object) {
+ QMaterial *r = static_cast<QMaterial *>(object);
+ if (scene->m_materials[materialIndex] == r)
+ scene->m_materials.remove(materialIndex);
+ });
}
/*!
@@ -844,6 +851,13 @@ void AssimpImporter::loadMesh(uint meshIndex)
m_scene->m_meshes[meshIndex] = geometryRenderer;
+ Qt3DRender::AssimpImporter::SceneImporter *scene = m_scene;
+ QObject::connect(geometryRenderer, &QObject::destroyed, [&, scene, meshIndex](QObject *object) {
+ QGeometryRenderer *r = static_cast<QGeometryRenderer *>(object);
+ if (scene->m_meshes[meshIndex] == r)
+ scene->m_meshes.remove(meshIndex);
+ });
+
if (mesh->mNumAnimMeshes > 0) {
aiAnimMesh *animesh = mesh->mAnimMeshes[0];
@@ -1004,6 +1018,13 @@ void AssimpImporter::loadEmbeddedTexture(uint textureIndex)
imageData->setData(textureContent);
texture->addTextureImage(imageData);
m_scene->m_embeddedTextures[textureIndex] = texture;
+
+ Qt3DRender::AssimpImporter::SceneImporter *scene = m_scene;
+ QObject::connect(texture, &QObject::destroyed, [&, scene, textureIndex](QObject *object) {
+ QAbstractTexture *r = static_cast<QAbstractTexture *>(object);
+ if (scene->m_embeddedTextures[textureIndex] == r)
+ scene->m_embeddedTextures.remove(textureIndex);
+ });
}
/*!
@@ -1047,6 +1068,13 @@ void AssimpImporter::loadCamera(uint cameraIndex)
camera->addComponent(transform);
m_scene->m_cameras[cameraNode] = camera;
+
+ Qt3DRender::AssimpImporter::SceneImporter *scene = m_scene;
+ QObject::connect(camera, &QObject::destroyed, [&, scene, cameraNode](QObject *object) {
+ QEntity *r = static_cast<QEntity *>(object);
+ if (scene->m_cameras[cameraNode] == r)
+ scene->m_cameras.remove(cameraNode);
+ });
}
int findTimeIndex(const QVector<float> &times, float time) {
@@ -1377,9 +1405,15 @@ AssimpImporter::SceneImporter::SceneImporter()
// The Assimp::Importer manages the lifetime of the aiScene object
}
+
+
AssimpImporter::SceneImporter::~SceneImporter()
{
delete m_importer;
+ qDeleteAll(m_materials.values());
+ qDeleteAll(m_meshes.values());
+ qDeleteAll(m_embeddedTextures.values());
+ qDeleteAll(m_cameras.values());
}
} // namespace Qt3DRender
diff --git a/src/quick3d/quick3d/qt3dquicknodefactory.cpp b/src/quick3d/quick3d/qt3dquicknodefactory.cpp
index a8c021754..4d399d8f4 100644
--- a/src/quick3d/quick3d/qt3dquicknodefactory.cpp
+++ b/src/quick3d/quick3d/qt3dquicknodefactory.cpp
@@ -66,7 +66,9 @@ QNode *QuickNodeFactory::createNode(const char *type)
if (!typeInfo.resolved) {
typeInfo.resolved = true;
+#if 0
typeInfo.t = QQmlMetaType::qmlType(QString::fromLatin1(typeInfo.quickName), typeInfo.version.first, typeInfo.version.second);
+#endif
}
return typeInfo.t ? qobject_cast<QNode *>(typeInfo.t->create()) : nullptr;
diff --git a/src/quick3d/quick3d/qt3dquicknodefactory_p.h b/src/quick3d/quick3d/qt3dquicknodefactory_p.h
index 6c074da04..3cfbb6cc8 100644
--- a/src/quick3d/quick3d/qt3dquicknodefactory_p.h
+++ b/src/quick3d/quick3d/qt3dquicknodefactory_p.h
@@ -52,7 +52,7 @@
//
#include <QtCore/qhash.h>
-
+#include <QtQml/private/qqmlmetatype_p.h>
#include <Qt3DCore/private/qabstractnodefactory_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick3d/quick3danimation/qt3dquickanimationnodefactory.cpp b/src/quick3d/quick3danimation/qt3dquickanimationnodefactory.cpp
index 4fd7d30cc..8dbc501b9 100644
--- a/src/quick3d/quick3danimation/qt3dquickanimationnodefactory.cpp
+++ b/src/quick3d/quick3danimation/qt3dquickanimationnodefactory.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qt3dquickanimationnodefactory_p.h"
-#include <private/qqmlmetatype_p.h>
QT_BEGIN_NAMESPACE
@@ -65,7 +64,9 @@ Qt3DCore::QNode *QuickAnimationNodeFactory::createNode(const char *type)
if (!typeInfo.resolved) {
typeInfo.resolved = true;
+#if 0
typeInfo.t = QQmlMetaType::qmlType(QString::fromLatin1(typeInfo.quickName), typeInfo.version.first, typeInfo.version.second);
+#endif
}
return typeInfo.t ? qobject_cast<Qt3DCore::QNode *>(typeInfo.t->create()) : nullptr;
diff --git a/src/quick3d/quick3danimation/qt3dquickanimationnodefactory_p.h b/src/quick3d/quick3danimation/qt3dquickanimationnodefactory_p.h
index 5c7a828ed..5b1dd831b 100644
--- a/src/quick3d/quick3danimation/qt3dquickanimationnodefactory_p.h
+++ b/src/quick3d/quick3danimation/qt3dquickanimationnodefactory_p.h
@@ -52,6 +52,7 @@
//
#include <private/qabstractnodefactory_p.h>
+#include <QtQml/private/qqmlmetatype_p.h>
#include <QtCore/qhash.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick3d/quick3dextras/qt3dquickextrasnodefactory.cpp b/src/quick3d/quick3dextras/qt3dquickextrasnodefactory.cpp
index 073a3ec44..be7dec52a 100644
--- a/src/quick3d/quick3dextras/qt3dquickextrasnodefactory.cpp
+++ b/src/quick3d/quick3dextras/qt3dquickextrasnodefactory.cpp
@@ -65,7 +65,9 @@ Qt3DCore::QNode *QuickExtrasNodeFactory::createNode(const char *type)
if (!typeInfo.resolved) {
typeInfo.resolved = true;
+#if 0
typeInfo.t = QQmlMetaType::qmlType(QString::fromLatin1(typeInfo.quickName), typeInfo.version.first, typeInfo.version.second);
+#endif
}
return typeInfo.t ? qobject_cast<Qt3DCore::QNode *>(typeInfo.t->create()) : nullptr;
diff --git a/src/quick3d/quick3dinput/qt3dquickinputnodefactory.cpp b/src/quick3d/quick3dinput/qt3dquickinputnodefactory.cpp
index b158e30d5..11bb3b55b 100644
--- a/src/quick3d/quick3dinput/qt3dquickinputnodefactory.cpp
+++ b/src/quick3d/quick3dinput/qt3dquickinputnodefactory.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include <Qt3DQuickInput/private/qt3dquickinputnodefactory_p.h>
-#include <QtQml/private/qqmlmetatype_p.h>
QT_BEGIN_NAMESPACE
@@ -65,7 +64,9 @@ Qt3DCore::QNode *QuickInputNodeFactory::createNode(const char *type)
if (!typeInfo.resolved) {
typeInfo.resolved = true;
+#if 0
typeInfo.t = QQmlMetaType::qmlType(QString::fromLatin1(typeInfo.quickName), typeInfo.version.first, typeInfo.version.second);
+#endif
}
return typeInfo.t ? qobject_cast<Qt3DCore::QNode *>(typeInfo.t->create()) : nullptr;
diff --git a/src/quick3d/quick3dinput/qt3dquickinputnodefactory_p.h b/src/quick3d/quick3dinput/qt3dquickinputnodefactory_p.h
index f4d4aee27..7aa6c85d9 100644
--- a/src/quick3d/quick3dinput/qt3dquickinputnodefactory_p.h
+++ b/src/quick3d/quick3dinput/qt3dquickinputnodefactory_p.h
@@ -52,7 +52,7 @@
//
#include <QtCore/qhash.h>
-
+#include <QtQml/private/qqmlmetatype_p.h>
#include <Qt3DCore/private/qabstractnodefactory_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick3d/quick3drender/qt3dquickrendernodefactory.cpp b/src/quick3d/quick3drender/qt3dquickrendernodefactory.cpp
index f57451379..82025c046 100644
--- a/src/quick3d/quick3drender/qt3dquickrendernodefactory.cpp
+++ b/src/quick3d/quick3drender/qt3dquickrendernodefactory.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include <Qt3DQuickRender/private/qt3dquickrendernodefactory_p.h>
-#include <QtQml/private/qqmlmetatype_p.h>
QT_BEGIN_NAMESPACE
@@ -65,7 +64,9 @@ Qt3DCore::QNode *QuickRenderNodeFactory::createNode(const char *type)
if (!typeInfo.resolved) {
typeInfo.resolved = true;
+#if 0
typeInfo.t = QQmlMetaType::qmlType(QString::fromLatin1(typeInfo.quickName), typeInfo.version.first, typeInfo.version.second);
+#endif
}
return typeInfo.t ? qobject_cast<Qt3DCore::QNode *>(typeInfo.t->create()) : nullptr;
diff --git a/src/quick3d/quick3drender/qt3dquickrendernodefactory_p.h b/src/quick3d/quick3drender/qt3dquickrendernodefactory_p.h
index 6068124e5..cc19eb656 100644
--- a/src/quick3d/quick3drender/qt3dquickrendernodefactory_p.h
+++ b/src/quick3d/quick3drender/qt3dquickrendernodefactory_p.h
@@ -52,7 +52,7 @@
//
#include <QtCore/qhash.h>
-
+#include <QtQml/private/qqmlmetatype_p.h>
#include <Qt3DCore/private/qabstractnodefactory_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory.cpp b/src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory.cpp
index 5d092501e..0724bca5e 100644
--- a/src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory.cpp
+++ b/src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qt3dquickscene2dnodefactory_p.h"
-#include <QtQml/private/qqmlmetatype_p.h>
#include <private/qrenderaspect_p.h>
@@ -77,8 +76,10 @@ Qt3DCore::QNode *QuickScene2DNodeFactory::createNode(const char *type)
if (!typeInfo.resolved) {
typeInfo.resolved = true;
+#if 0
typeInfo.t = QQmlMetaType::qmlType(QString::fromLatin1(typeInfo.quickName),
typeInfo.version.first, typeInfo.version.second);
+#endif
}
return typeInfo.t ? qobject_cast<Qt3DCore::QNode *>(typeInfo.t->create()) : nullptr;
diff --git a/src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory_p.h b/src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory_p.h
index b5eb82aa1..81ee5ee5b 100644
--- a/src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory_p.h
+++ b/src/quick3d/quick3dscene2d/qt3dquickscene2dnodefactory_p.h
@@ -52,6 +52,7 @@
//
#include <Qt3DCore/private/qabstractnodefactory_p.h>
+#include <QtQml/private/qqmlmetatype_p.h>
#include <QtCore/qhash.h>
QT_BEGIN_NAMESPACE
diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp
index 061fc06c4..34568c1a7 100644
--- a/src/render/backend/entity.cpp
+++ b/src/render/backend/entity.cpp
@@ -180,9 +180,9 @@ void Entity::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
m_shaderDataComponents.clear();
m_lightComponents.clear();
m_environmentLightComponents.clear();
- m_localBoundingVolume.reset(new Sphere(peerId()));
- m_worldBoundingVolume.reset(new Sphere(peerId()));
- m_worldBoundingVolumeWithChildren.reset(new Sphere(peerId()));
+ m_localBoundingVolume = QSharedPointer<Sphere>::create(peerId());
+ m_worldBoundingVolume = QSharedPointer<Sphere>::create(peerId());
+ m_worldBoundingVolumeWithChildren = QSharedPointer<Sphere>::create(peerId());
for (const auto &idAndType : qAsConst(data.componentIdsAndTypes))
addComponent(idAndType);
diff --git a/src/render/backend/rendercommand.cpp b/src/render/backend/rendercommand.cpp
index 044ef035c..85c4858cf 100644
--- a/src/render/backend/rendercommand.cpp
+++ b/src/render/backend/rendercommand.cpp
@@ -66,21 +66,11 @@ RenderCommand::RenderCommand()
, m_primitiveRestartEnabled(false)
, m_isValid(false)
{
- m_sortingType.global = 0;
m_workGroups[0] = 0;
m_workGroups[1] = 0;
m_workGroups[2] = 0;
}
-bool compareCommands(RenderCommand *r1, RenderCommand *r2)
-{
- // The smaller m_depth is, the closer it is to the eye.
- if (r1->m_sortBackToFront && r2->m_sortBackToFront)
- return r1->m_depth > r2->m_depth;
-
- return r1->m_sortingType.global < r2->m_sortingType.global;
-}
-
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/backend/rendercommand_p.h b/src/render/backend/rendercommand_p.h
index 4b2966fc6..57fb553b7 100644
--- a/src/render/backend/rendercommand_p.h
+++ b/src/render/backend/rendercommand_p.h
@@ -70,13 +70,14 @@ namespace Render {
class RenderStateSet;
-class RenderCommand
+class Q_AUTOTEST_EXPORT RenderCommand
{
public:
RenderCommand();
HVao m_vao; // VAO used during the submission step to store all states and VBOs
HShader m_shader; // Shader for given pass and mesh
+ HMaterial m_material; // Purely used to ease sorting (minimize stage changes, binding changes ....)
ShaderParameterPack m_parameterPack; // Might need to be reworked so as to be able to destroy the
// Texture while submission is happening.
RenderStateSet *m_stateSet;
@@ -101,11 +102,6 @@ public:
CommandType m_type;
- union sortingType {
- char sorts[4];
- int global;
- } m_sortingType;
-
bool m_sortBackToFront;
int m_workGroups[3];
@@ -127,8 +123,6 @@ public:
bool m_isValid;
};
-bool compareCommands(RenderCommand *r1, RenderCommand *r2);
-
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index 3ca1a1675..b056d4380 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -157,7 +157,7 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_graphicsContext(nullptr)
, m_renderQueue(new RenderQueue())
, m_renderThread(type == QRenderAspect::Threaded ? new RenderThread(this) : nullptr)
- , m_vsyncFrameAdvanceService(new VSyncFrameAdvanceService())
+ , m_vsyncFrameAdvanceService(new VSyncFrameAdvanceService(m_renderThread != nullptr))
, m_waitForInitializationToBeCompleted(0)
, m_pickEventFilter(new PickEventFilter())
, m_exposed(0)
@@ -1364,10 +1364,13 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
if (!request.rect.isEmpty())
rect = rect.intersected(request.rect);
QImage image;
- if (!rect.isEmpty())
+ if (!rect.isEmpty()) {
+ // Bind fbo as read framebuffer
+ m_graphicsContext->bindFramebuffer(m_graphicsContext->activeFBO(), GraphicsHelperInterface::FBORead);
image = m_graphicsContext->readFramebuffer(rect);
- else
+ } else {
qWarning() << "Requested capture rectangle is outside framebuffer";
+ }
Render::RenderCapture *renderCapture =
static_cast<Render::RenderCapture*>(m_nodesManager->frameGraphManager()->lookupNode(renderView->renderCaptureNodeId()));
renderCapture->addRenderCapture(request.captureId, image);
@@ -1386,7 +1389,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
// lastBoundFBOId != m_graphicsContext->activeFBO() when the last FrameGraph leaf node/renderView
// contains RenderTargetSelector/RenderTarget
if (lastBoundFBOId != m_graphicsContext->activeFBO())
- m_graphicsContext->bindFramebuffer(lastBoundFBOId);
+ m_graphicsContext->bindFramebuffer(lastBoundFBOId, GraphicsHelperInterface::FBOReadAndDraw);
// Reset state and call doneCurrent if the surface
// is valid and was actually activated
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 8177f958b..cded6b804 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -267,11 +267,178 @@ RenderView::~RenderView()
}
}
+namespace {
+
+template<int SortType>
+struct AdjacentSubRangeFinder
+{
+ static bool adjacentSubRange(RenderCommand *, RenderCommand *)
+ {
+ Q_UNREACHABLE();
+ return false;
+ }
+};
+
+template<>
+struct AdjacentSubRangeFinder<QSortPolicy::StateChangeCost>
+{
+ static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
+ {
+ return a->m_changeCost == b->m_changeCost;
+ }
+};
+
+template<>
+struct AdjacentSubRangeFinder<QSortPolicy::BackToFront>
+{
+ static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
+ {
+ return a->m_depth == b->m_depth;
+ }
+};
+
+template<>
+struct AdjacentSubRangeFinder<QSortPolicy::Material>
+{
+ static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
+ {
+ return a->m_shaderDna == b->m_shaderDna;
+ }
+};
+
+template<typename Predicate>
+int advanceUntilNonAdjacent(const QVector<RenderCommand *> &commands,
+ const int beg, const int end, Predicate pred)
+{
+ int i = beg + 1;
+ while (i < end) {
+ if (!pred(*(commands.begin() + beg), *(commands.begin() + i)))
+ break;
+ ++i;
+ }
+ return i;
+}
+
+
+using CommandIt = QVector<RenderCommand *>::iterator;
+
+template<int SortType>
+struct SubRangeSorter
+{
+ static void sortSubRange(CommandIt begin, const CommandIt end)
+ {
+ Q_UNREACHABLE();
+ }
+};
+
+template<>
+struct SubRangeSorter<QSortPolicy::StateChangeCost>
+{
+ static void sortSubRange(CommandIt begin, const CommandIt end)
+ {
+ std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
+ return a->m_changeCost > b->m_changeCost;
+ });
+ }
+};
+
+template<>
+struct SubRangeSorter<QSortPolicy::BackToFront>
+{
+ static void sortSubRange(CommandIt begin, const CommandIt end)
+ {
+ std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
+ return a->m_depth > b->m_depth;
+ });
+ }
+};
+
+template<>
+struct SubRangeSorter<QSortPolicy::Material>
+{
+ static void sortSubRange(CommandIt begin, const CommandIt end)
+ {
+ // First we sort by shaderDNA
+ std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
+ return a->m_shaderDna > b->m_shaderDna;
+ });
+ }
+};
+
+
+int findSubRange(const QVector<RenderCommand *> &commands,
+ const int begin, const int end,
+ const QSortPolicy::SortType sortType)
+{
+ switch (sortType) {
+ case QSortPolicy::StateChangeCost:
+ return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::StateChangeCost>::adjacentSubRange);
+ case QSortPolicy::BackToFront:
+ return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::BackToFront>::adjacentSubRange);
+ case QSortPolicy::Material:
+ return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange);
+ default:
+ Q_UNREACHABLE();
+ return end;
+ }
+}
+
+void sortByMaterial(QVector<RenderCommand *> &commands, int begin, const int end)
+{
+ // We try to arrange elements so that their rendering cost is minimized for a given shader
+ int rangeEnd = advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange);
+ while (begin != end) {
+ if (begin + 1 < rangeEnd) {
+ std::stable_sort(commands.begin() + begin + 1, commands.begin() + rangeEnd, [] (RenderCommand *a, RenderCommand *b){
+ return a->m_material < b->m_material;
+ });
+ }
+ begin = rangeEnd;
+ rangeEnd = advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange);
+ }
+}
+
+void sortCommandRange(QVector<RenderCommand *> &commands, int begin, const int end, const int level,
+ const QVector<Qt3DRender::QSortPolicy::SortType> &sortingTypes)
+{
+ if (level >= sortingTypes.size())
+ return;
+
+ switch (sortingTypes.at(level)) {
+ case QSortPolicy::StateChangeCost:
+ SubRangeSorter<QSortPolicy::StateChangeCost>::sortSubRange(commands.begin() + begin, commands.begin() + end);
+ break;
+ case QSortPolicy::BackToFront:
+ SubRangeSorter<QSortPolicy::BackToFront>::sortSubRange(commands.begin() + begin, commands.begin() + end);
+ break;
+ case QSortPolicy::Material:
+ // Groups all same shader DNA together
+ SubRangeSorter<QSortPolicy::Material>::sortSubRange(commands.begin() + begin, commands.begin() + end);
+ // Group all same material together (same parameters most likely)
+ sortByMaterial(commands, begin, end);
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+
+ // For all sub ranges of adjacent item for sortType[i]
+ // Perform filtering with sortType[i + 1]
+ int rangeEnd = findSubRange(commands, begin, end, sortingTypes.at(level));
+ while (begin != end) {
+ sortCommandRange(commands, begin, rangeEnd, level + 1, sortingTypes);
+ begin = rangeEnd;
+ rangeEnd = findSubRange(commands, begin, end, sortingTypes.at(level));
+ }
+}
+
+} // anonymous
+
void RenderView::sort()
{
- // Compares the bitsetKey of the RenderCommands
- // Key[Depth | StateCost | Shader]
- std::sort(m_commands.begin(), m_commands.end(), compareCommands);
+ sortCommandRange(m_commands, 0, m_commands.size(), 0, m_data.m_sortingTypes);
+
+ // For RenderCommand with the same shader
+ // We compute the adjacent change cost
// Minimize uniform changes
int i = 0;
@@ -392,6 +559,7 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
&& !geometryRenderer->geometryId().isNull()) {
const Qt3DCore::QNodeId materialComponentId = entity->componentUuid<Material>();
+ const HMaterial materialHandle = entity->componentHandle<Material, 16>();
const QVector<RenderPassParameterData> renderPassData = m_parameters.value(materialComponentId);
HGeometry geometryHandle = m_manager->lookupHandle<Geometry, GeometryManager, HGeometry>(geometryRenderer->geometryId());
Geometry *geometry = m_manager->data<Geometry, GeometryManager>(geometryHandle);
@@ -403,6 +571,7 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
command->m_depth = m_data.m_eyePos.distanceToPoint(entity->worldBoundingVolume()->center());
command->m_geometry = geometryHandle;
command->m_geometryRenderer = geometryRendererHandle;
+ command->m_material = materialHandle;
// For RenderPass based states we use the globally set RenderState
// if no renderstates are defined as part of the pass. That means:
// RenderPass { renderStates: [] } will use the states defined by
@@ -482,7 +651,7 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
command->m_verticesPerPatch = geometryRenderer->verticesPerPatch();
}
- buildSortingKey(command);
+ prepareForSorting(command);
commands.append(command);
}
}
@@ -703,27 +872,21 @@ void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &unif
}
}
-void RenderView::buildSortingKey(RenderCommand *command) const
+void RenderView::prepareForSorting(RenderCommand *command) const
{
// Build a bitset key depending on the SortingCriterion
- int sortCount = m_data.m_sortingTypes.count();
+ const int sortCount = m_data.m_sortingTypes.count();
// If sortCount == 0, no sorting is applied
// Handle at most 4 filters at once
for (int i = 0; i < sortCount && i < 4; i++) {
switch (m_data.m_sortingTypes.at(i)) {
- case QSortPolicy::StateChangeCost:
- command->m_sortingType.sorts[i] = command->m_changeCost; // State change cost
- break;
case QSortPolicy::BackToFront:
command->m_sortBackToFront = true; // Depth value
break;
- case QSortPolicy::Material:
- command->m_sortingType.sorts[i] = command->m_shaderDna; // Material
- break;
default:
- Q_UNREACHABLE();
+ break;
}
}
}
diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h
index e69cd2a52..5579e8e95 100644
--- a/src/render/backend/renderview_p.h
+++ b/src/render/backend/renderview_p.h
@@ -354,7 +354,7 @@ private:
Shader *shader,
ShaderData *shaderData,
const QString &structName) const;
- void buildSortingKey(RenderCommand *command) const;
+ void prepareForSorting(RenderCommand *command) const;
};
} // namespace Render
diff --git a/src/render/frontend/qlevelofdetail.cpp b/src/render/frontend/qlevelofdetail.cpp
index 03df4e6a8..a3596a518 100644
--- a/src/render/frontend/qlevelofdetail.cpp
+++ b/src/render/frontend/qlevelofdetail.cpp
@@ -277,7 +277,7 @@ QLevelOfDetailPrivate::QLevelOfDetailPrivate()
* If this value to nullptr, the bounding volume of the entity is used. Care must be
* taken that this bounding volume never becomes invalid.
*
- * \sa Qt3dRender::QLevelOfDetailBoundingSphere
+ * \sa Qt3DRender::QLevelOfDetailBoundingSphere
*/
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 1f928f768..532e55d0f 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -393,6 +393,7 @@ QRenderAspect::~QRenderAspect()
{
}
+// Called by Scene3DRenderer only
void QRenderAspectPrivate::renderInitialize(QOpenGLContext *context)
{
if (m_renderer->api() == Render::AbstractRenderer::OpenGL)
diff --git a/src/render/geometry/qgeometryrenderer.cpp b/src/render/geometry/qgeometryrenderer.cpp
index 666c72d83..a497bab97 100644
--- a/src/render/geometry/qgeometryrenderer.cpp
+++ b/src/render/geometry/qgeometryrenderer.cpp
@@ -182,6 +182,7 @@ QGeometryRendererPrivate::~QGeometryRendererPrivate()
\list
\li QGeometryRenderer.Points
+ \li QGeometryRenderer.Lines
\li QGeometryRenderer.LineLoop
\li QGeometryRenderer.LineStrip
\li QGeometryRenderer.Triangles
diff --git a/src/render/geometry/qmesh.cpp b/src/render/geometry/qmesh.cpp
index 109a8a445..9a1f10bc5 100644
--- a/src/render/geometry/qmesh.cpp
+++ b/src/render/geometry/qmesh.cpp
@@ -101,8 +101,18 @@ void QMeshPrivate::updateFunctor()
*
* Loads mesh data from external files in a variety of formats.
*
- * In Qt3D 5.9, Mesh supports the following formats: Wavefront OBJ, Stanford Triangle Format PLY, STL (STereoLithography).
- * QMesh will also support Autodesk FBX files if the SDK is installed and the fbx geometry loader plugin is built and found.
+ * In Qt3D 5.9, Mesh supports the following formats:
+ *
+ * \list
+ * \li Wavefront OBJ
+ * \li Stanford Triangle Format PLY
+ * \li STL (STereoLithography)
+ * \endlist
+ *
+ * QMesh will also support the following format if the SDK is installed and the fbx geometry loader plugin is built and found.
+ * \list
+ * \li Autodesk FBX
+ * \endlist
*/
/*!
@@ -139,8 +149,18 @@ void QMeshPrivate::updateFunctor()
* Loads mesh data from external files in a variety of formats.
* Qt3DRender::QMesh loads data into a single mesh.
*
- * In Qt3D 5.9, QMesh supports the following formats: Wavefront OBJ, Stanford Triangle Format PLY, STL (STereoLithography).
- * QMesh will also support Autodesk FBX files if the SDK is installed and the fbx geometry loader plugin is built and found.
+ * In Qt3D 5.9, QMesh supports the following formats:
+ *
+ * \list
+ * \li Wavefront OBJ
+ * \li Stanford Triangle Format PLY
+ * \li STL (STereoLithography)
+ * \endlist
+ *
+ * QMesh will also support the following format if the SDK is installed and the fbx geometry loader plugin is built and found:
+ * \list
+ * \li Autodesk FBX
+ * \endlist
*
* If you wish to load an entire scene made of several objects, you should rather use the Qt3DRender::QSceneLoader instead.
*
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp
index 7910c828a..f09336243 100644
--- a/src/render/graphicshelpers/graphicscontext.cpp
+++ b/src/render/graphicshelpers/graphicscontext.cpp
@@ -592,7 +592,7 @@ void GraphicsContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId,
// Insert FBO into hash
m_renderTargets.insert(renderTargetNodeId, fboId);
// Bind FBO
- m_glHelper->bindFrameBufferObject(fboId);
+ m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
bindFrameBufferAttachmentHelper(fboId, attachments);
} else {
qCritical() << "Failed to create FBO";
@@ -616,13 +616,13 @@ void GraphicsContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId,
}
if (needsResize) {
- m_glHelper->bindFrameBufferObject(fboId);
+ m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
bindFrameBufferAttachmentHelper(fboId, attachments);
}
}
}
m_activeFBO = fboId;
- m_glHelper->bindFrameBufferObject(m_activeFBO);
+ m_glHelper->bindFrameBufferObject(m_activeFBO, GraphicsHelperInterface::FBODraw);
// Set active drawBuffers
activateDrawBuffers(attachments);
}
@@ -972,9 +972,9 @@ void GraphicsContext::alphaTest(GLenum mode1, GLenum mode2)
m_glHelper->alphaTest(mode1, mode2);
}
-void GraphicsContext::bindFramebuffer(GLuint fbo)
+void GraphicsContext::bindFramebuffer(GLuint fbo, GraphicsHelperInterface::FBOBindMode mode)
{
- m_glHelper->bindFrameBufferObject(fbo);
+ m_glHelper->bindFrameBufferObject(fbo, mode);
}
void GraphicsContext::depthTest(GLenum mode)
diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h
index 9252bb467..fcb17ade7 100644
--- a/src/render/graphicshelpers/graphicscontext_p.h
+++ b/src/render/graphicshelpers/graphicscontext_p.h
@@ -70,6 +70,7 @@
#include <Qt3DRender/private/qgraphicsapifilter_p.h>
#include <Qt3DRender/private/shadercache_p.h>
#include <Qt3DRender/private/uniform_p.h>
+#include <Qt3DRender/private/graphicshelperinterface_p.h>
#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -194,7 +195,7 @@ public:
// Wrapper methods
void alphaTest(GLenum mode1, GLenum mode2);
- void bindFramebuffer(GLuint fbo);
+ void bindFramebuffer(GLuint fbo, GraphicsHelperInterface::FBOBindMode mode);
void bindBufferBase(GLenum target, GLuint bindingIndex, GLuint buffer);
void bindFragOutputs(GLuint shader, const QHash<QString, int> &outputs);
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
diff --git a/src/render/graphicshelpers/graphicshelperes2.cpp b/src/render/graphicshelpers/graphicshelperes2.cpp
index 4954aac9e..a72e6159c 100644
--- a/src/render/graphicshelpers/graphicshelperes2.cpp
+++ b/src/render/graphicshelpers/graphicshelperes2.cpp
@@ -63,6 +63,15 @@ QT_BEGIN_NAMESPACE
#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
#endif
+// ES 2.0 FBO
+#ifndef GL_DRAW_FRAMEBUFFER
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#endif
+
+#ifndef GL_READ_FRAMEBUFFER
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#endif
+
namespace Qt3DRender {
namespace Render {
@@ -344,9 +353,20 @@ void GraphicsHelperES2::releaseFrameBufferObject(GLuint frameBufferId)
m_funcs->glDeleteFramebuffers(1, &frameBufferId);
}
-void GraphicsHelperES2::bindFrameBufferObject(GLuint frameBufferId)
+void GraphicsHelperES2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
{
- m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
+ switch (mode) {
+ case FBODraw:
+ m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBORead:
+ m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBOReadAndDraw:
+ default:
+ m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
+ return;
+ }
}
GLuint GraphicsHelperES2::boundFrameBufferObject()
diff --git a/src/render/graphicshelpers/graphicshelperes2_p.h b/src/render/graphicshelpers/graphicshelperes2_p.h
index d068b5307..b93268188 100644
--- a/src/render/graphicshelpers/graphicshelperes2_p.h
+++ b/src/render/graphicshelpers/graphicshelperes2_p.h
@@ -75,7 +75,7 @@ public:
bool frameBufferNeedsRenderBuffer(const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) Q_DECL_OVERRIDE;
- void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) Q_DECL_OVERRIDE;
void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelpergl2.cpp b/src/render/graphicshelpers/graphicshelpergl2.cpp
index 28d1a91c9..9abc392ee 100644
--- a/src/render/graphicshelpers/graphicshelpergl2.cpp
+++ b/src/render/graphicshelpers/graphicshelpergl2.cpp
@@ -418,12 +418,24 @@ void GraphicsHelperGL2::bindFragDataLocation(GLuint, const QHash<QString, int> &
qCritical() << "bindFragDataLocation is not supported by GL 2.0";
}
-void GraphicsHelperGL2::bindFrameBufferObject(GLuint frameBufferId)
+void GraphicsHelperGL2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
{
- if (m_fboFuncs != nullptr)
- m_fboFuncs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
- else
+ if (m_fboFuncs != nullptr) {
+ switch (mode) {
+ case FBODraw:
+ m_fboFuncs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBORead:
+ m_fboFuncs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBOReadAndDraw:
+ default:
+ m_fboFuncs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
+ return;
+ }
+ } else {
qWarning() << "FBO not supported by your OpenGL hardware";
+ }
}
GLuint GraphicsHelperGL2::boundFrameBufferObject()
diff --git a/src/render/graphicshelpers/graphicshelpergl2_p.h b/src/render/graphicshelpers/graphicshelpergl2_p.h
index 7d617937d..3a15af260 100644
--- a/src/render/graphicshelpers/graphicshelpergl2_p.h
+++ b/src/render/graphicshelpers/graphicshelpergl2_p.h
@@ -75,7 +75,7 @@ public:
bool frameBufferNeedsRenderBuffer(const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) Q_DECL_OVERRIDE;
- void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) Q_DECL_OVERRIDE;
void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelpergl3_2.cpp b/src/render/graphicshelpers/graphicshelpergl3_2.cpp
index 47e850871..54c46babe 100644
--- a/src/render/graphicshelpers/graphicshelpergl3_2.cpp
+++ b/src/render/graphicshelpers/graphicshelpergl3_2.cpp
@@ -392,9 +392,20 @@ void GraphicsHelperGL3_2::releaseFrameBufferObject(GLuint frameBufferId)
m_funcs->glDeleteFramebuffers(1, &frameBufferId);
}
-void GraphicsHelperGL3_2::bindFrameBufferObject(GLuint frameBufferId)
+void GraphicsHelperGL3_2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
{
- m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
+ switch (mode) {
+ case FBODraw:
+ m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBORead:
+ m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBOReadAndDraw:
+ default:
+ m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
+ return;
+ }
}
GLuint GraphicsHelperGL3_2::boundFrameBufferObject()
diff --git a/src/render/graphicshelpers/graphicshelpergl3_2_p.h b/src/render/graphicshelpers/graphicshelpergl3_2_p.h
index 94ff4b4eb..bebe14ade 100644
--- a/src/render/graphicshelpers/graphicshelpergl3_2_p.h
+++ b/src/render/graphicshelpers/graphicshelpergl3_2_p.h
@@ -77,7 +77,7 @@ public:
bool frameBufferNeedsRenderBuffer(const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) Q_DECL_OVERRIDE;
- void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) Q_DECL_OVERRIDE;
void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelpergl3_3.cpp b/src/render/graphicshelpers/graphicshelpergl3_3.cpp
index fbb1455c6..e1ae23e6d 100644
--- a/src/render/graphicshelpers/graphicshelpergl3_3.cpp
+++ b/src/render/graphicshelpers/graphicshelpergl3_3.cpp
@@ -379,9 +379,20 @@ void GraphicsHelperGL3_3::releaseFrameBufferObject(GLuint frameBufferId)
m_funcs->glDeleteFramebuffers(1, &frameBufferId);
}
-void GraphicsHelperGL3_3::bindFrameBufferObject(GLuint frameBufferId)
+void GraphicsHelperGL3_3::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
{
- m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
+ switch (mode) {
+ case FBODraw:
+ m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBORead:
+ m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBOReadAndDraw:
+ default:
+ m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
+ return;
+ }
}
GLuint GraphicsHelperGL3_3::boundFrameBufferObject()
diff --git a/src/render/graphicshelpers/graphicshelpergl3_3_p.h b/src/render/graphicshelpers/graphicshelpergl3_3_p.h
index 3b03cf851..e890fd1a4 100644
--- a/src/render/graphicshelpers/graphicshelpergl3_3_p.h
+++ b/src/render/graphicshelpers/graphicshelpergl3_3_p.h
@@ -77,7 +77,7 @@ public:
bool frameBufferNeedsRenderBuffer(const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) Q_DECL_OVERRIDE;
- void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) Q_DECL_OVERRIDE;
void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelpergl4.cpp b/src/render/graphicshelpers/graphicshelpergl4.cpp
index 9cb1f02ee..badbaf67d 100644
--- a/src/render/graphicshelpers/graphicshelpergl4.cpp
+++ b/src/render/graphicshelpers/graphicshelpergl4.cpp
@@ -652,9 +652,20 @@ void GraphicsHelperGL4::releaseFrameBufferObject(GLuint frameBufferId)
m_funcs->glDeleteFramebuffers(1, &frameBufferId);
}
-void GraphicsHelperGL4::bindFrameBufferObject(GLuint frameBufferId)
-{
- m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
+void GraphicsHelperGL4::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
+{
+ switch (mode) {
+ case FBODraw:
+ m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBORead:
+ m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId);
+ return;
+ case FBOReadAndDraw:
+ default:
+ m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
+ return;
+ }
}
GLuint GraphicsHelperGL4::boundFrameBufferObject()
diff --git a/src/render/graphicshelpers/graphicshelpergl4_p.h b/src/render/graphicshelpers/graphicshelpergl4_p.h
index e636832b3..1effbc9b9 100644
--- a/src/render/graphicshelpers/graphicshelpergl4_p.h
+++ b/src/render/graphicshelpers/graphicshelpergl4_p.h
@@ -75,7 +75,7 @@ public:
bool frameBufferNeedsRenderBuffer(const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) Q_DECL_OVERRIDE;
- void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) Q_DECL_OVERRIDE;
void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelperinterface_p.h b/src/render/graphicshelpers/graphicshelperinterface_p.h
index 45326eb91..9ded1835e 100644
--- a/src/render/graphicshelpers/graphicshelperinterface_p.h
+++ b/src/render/graphicshelpers/graphicshelperinterface_p.h
@@ -85,6 +85,12 @@ public:
MapBuffer
};
+ enum FBOBindMode {
+ FBODraw,
+ FBORead,
+ FBOReadAndDraw
+ };
+
virtual ~GraphicsHelperInterface() {}
virtual void alphaTest(GLenum mode1, GLenum mode2) = 0;
virtual void bindBufferBase(GLenum target, GLuint index, GLuint buffer) = 0;
@@ -92,7 +98,7 @@ public:
virtual bool frameBufferNeedsRenderBuffer(const Attachment &attachment) = 0;
virtual void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) = 0;
virtual void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) = 0;
- virtual void bindFrameBufferObject(GLuint frameBufferId) = 0;
+ virtual void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) = 0;
virtual void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) = 0;
virtual void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0;
virtual void blendEquation(GLenum mode) = 0;
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp
index 2f39c6641..f0426b8fb 100644
--- a/src/render/jobs/pickboundingvolumejob.cpp
+++ b/src/render/jobs/pickboundingvolumejob.cpp
@@ -358,32 +358,32 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event,
QPickEventPtr pickEvent;
switch (hit.m_type) {
case QCollisionQueryResult::Hit::Triangle:
- pickEvent.reset(new QPickTriangleEvent(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 = 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);
break;
case QCollisionQueryResult::Hit::Edge:
- pickEvent.reset(new QPickLineEvent(event.localPos(), hit.m_intersection,
- localIntersection, hit.m_distance,
- hit.m_primitiveIndex,
- hit.m_vertexIndex[0], hit.m_vertexIndex[1],
- eventButton, eventButtons, eventModifiers));
+ 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);
break;
case QCollisionQueryResult::Hit::Point:
- pickEvent.reset(new QPickPointEvent(event.localPos(), hit.m_intersection,
- localIntersection, hit.m_distance,
- hit.m_vertexIndex[0],
- eventButton, eventButtons, eventModifiers));
+ pickEvent = QPickPointEventPtr::create(event.localPos(), hit.m_intersection,
+ localIntersection, hit.m_distance,
+ hit.m_vertexIndex[0],
+ eventButton, eventButtons, eventModifiers);
break;
case QCollisionQueryResult::Hit::Entity:
- pickEvent.reset(new QPickEvent(event.localPos(), hit.m_intersection,
- localIntersection, hit.m_distance,
- eventButton, eventButtons, eventModifiers));
+ pickEvent = QPickEventPtr::create(event.localPos(), hit.m_intersection,
+ localIntersection, hit.m_distance,
+ eventButton, eventButtons, eventModifiers);
break;
default:
Q_UNREACHABLE();
diff --git a/src/render/materialsystem/qparameter.cpp b/src/render/materialsystem/qparameter.cpp
index 64c672737..b9bfa44e7 100644
--- a/src/render/materialsystem/qparameter.cpp
+++ b/src/render/materialsystem/qparameter.cpp
@@ -88,7 +88,7 @@
\endcode
When it comes to texture support, the Parameter value should be set to the
- appropriate \l {Qt3DRender::QAbstractTexture}{Texture} subclass that matches the sampler type of the shader
+ appropriate \l {Qt3DRender::QAbstractTexture}{texture} subclass that matches the sampler type of the shader
uniform.
\code
@@ -101,7 +101,7 @@
// uniform sampler2D diffuseTexture
\endcode
- \sa Texture
+ \sa Qt3DRender::QAbstractTexture
*/
/*!
diff --git a/src/render/picking/qobjectpicker.cpp b/src/render/picking/qobjectpicker.cpp
index 49f608a67..77d319676 100644
--- a/src/render/picking/qobjectpicker.cpp
+++ b/src/render/picking/qobjectpicker.cpp
@@ -82,10 +82,10 @@ namespace Qt3DRender {
*/
/*!
- * \qmltype ObjectPicker
- * \instantiates Qt3DRender::QObjectPicker
- * \inqmlmodule Qt3D.Render
- * \brief The ObjectPicker class instantiates a component that can
+ \qmltype ObjectPicker
+ \instantiates Qt3DRender::QObjectPicker
+ \inqmlmodule Qt3D.Render
+ \brief The ObjectPicker class instantiates a component that can
be used to interact with an Entity by a process known as picking.
For every combination of viewport and camera, picking casts a ray through the scene to
@@ -109,80 +109,107 @@ namespace Qt3DRender {
\note Instances of this component shouldn't be shared, not respecting that
condition will most likely result in undefined behavior.
-
*/
/*!
+ \qmlsignal Qt3D.Render::ObjectPicker::clicked(PickEvent pick)
+
+ This signal is emitted when the bounding volume defined by the pickAttribute
+ property intersects with a ray on a mouse click the PickEvent \a pick contains
+ details of the event.
+*/
+
+/*!
\qmlsignal Qt3D.Render::ObjectPicker::pressed(PickEvent pick)
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on a mouse press.
+
+ This signal is emitted when the bounding volume defined by the
+ pickAttribute property intersects with a ray on a mouse press. Intersection
+ information are accessible through the \a pick parameter.
*/
/*!
\qmlsignal Qt3D.Render::ObjectPicker::released(PickEvent pick)
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on a mouse release.
+
+ This signal is emitted when the bounding volume defined by the
+ pickAttribute property intersects with a ray on a mouse release.
+ Intersection information are accessible through the \a pick parameter.
*/
/*!
\qmlsignal Qt3D.Render::ObjectPicker::clicked(PickEvent pick)
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on a mouse click.
+
+ This signal is emitted when the bounding volume defined by the
+ pickAttribute property intersects with a ray on a mouse click. Intersection
+ information are accessible through the pick \a parameter.
*/
/*!
\qmlsignal Qt3D.Render::ObjectPicker::moved(PickEvent pick)
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on a mouse move with a button pressed.
+
+ This signal is emitted when the bounding volume defined by the
+ pickAttribute property intersects with a ray on a mouse move with a button
+ pressed. Intersection information are accessible through the \a pick
+ parameter.
*/
/*!
\qmlsignal Qt3D.Render::ObjectPicker::entered()
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on the mouse entering the volume.
+
+ This signal is emitted when the bounding volume defined by the pickAttribute
+ property intersects with a ray on the mouse entering the volume.
*/
/*!
\qmlsignal Qt3D.Render::ObjectPicker::exited()
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on the ray exiting the volume.
+
+ This signal is emitted when the bounding volume defined by the pickAttribute
+ property intersects with a ray on the ray exiting the volume.
*/
/*!
- \fn QObjectPicker::clicked(Qt3DRender::QPickEvent *pick)
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on a mouse click the QPickEvent \a pick contains details of the event.
+ \fn QObjectPicker::clicked(Qt3DRender::QPickEvent *pick)
+
+ This signal is emitted when the bounding volume defined by the pickAttribute
+ property intersects with a ray on a mouse click the QPickEvent \a pick contains
+ details of the event.
*/
/*!
- \fn QObjectPicker::entered()
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on the mouse entering the volume.
+ \fn QObjectPicker::entered()
+
+ This signal is emitted when the bounding volume defined by the pickAttribute
+ property intersects with a ray on the mouse entering the volume.
*/
/*!
- \fn QObjectPicker::exited()
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on the ray exiting the volume.
+ \fn QObjectPicker::exited()
+
+ This signal is emitted when the bounding volume defined by the pickAttribute
+ property intersects with a ray on the ray exiting the volume.
*/
/*!
- \fn QObjectPicker::moved(Qt3DRender::QPickEvent *pick)
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on a mouse move with a button pressed the QPickEvent \a pick contains details of the event.
+ \fn QObjectPicker::moved(Qt3DRender::QPickEvent *pick)
+ This signal is emitted when the bounding volume defined by the
+ pickAttribute property intersects with a ray on a mouse move with a button
+ pressed the QPickEvent \a pick contains details of the event.
*/
/*!
- \fn QObjectPicker::pressed(Qt3DRender::QPickEvent *pick)
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on a mouse press the QPickEvent \a pick contains details of the event.
+ \fn QObjectPicker::pressed(Qt3DRender::QPickEvent *pick)
+
+ This signal is emitted when the bounding volume defined by the
+ pickAttribute property intersects with a ray on a mouse press the
+ QPickEvent \a pick contains details of the event.
*/
/*!
- \fn QObjectPicker::released(Qt3DRender::QPickEvent *pick)
- This signal is emitted when the bounding volume defined by the pickAttribute property intersects
- with a ray on a mouse release the QPickEvent \a pick contains details of the event.
+ \fn QObjectPicker::released(Qt3DRender::QPickEvent *pick)
+
+ This signal is emitted when the bounding volume defined by the
+ pickAttribute property intersects with a ray on a mouse release the
+ QPickEvent \a pick contains details of the event.
*/
QObjectPicker::QObjectPicker(Qt3DCore::QNode *parent)
diff --git a/src/render/picking/qpicklineevent.h b/src/render/picking/qpicklineevent.h
index 102989450..09697ad22 100644
--- a/src/render/picking/qpicklineevent.h
+++ b/src/render/picking/qpicklineevent.h
@@ -41,6 +41,7 @@
#define QT3DRENDER_QPICKLINEEVENT_H
#include <Qt3DRender/qpickevent.h>
+#include <QtCore/qsharedpointer.h>
QT_BEGIN_NAMESPACE
@@ -68,6 +69,8 @@ private:
Q_DECLARE_PRIVATE(QPickLineEvent)
};
+typedef QSharedPointer<QPickLineEvent> QPickLineEventPtr;
+
} // Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/picking/qpickpointevent.h b/src/render/picking/qpickpointevent.h
index fbfebcedd..f298f64b9 100644
--- a/src/render/picking/qpickpointevent.h
+++ b/src/render/picking/qpickpointevent.h
@@ -41,6 +41,7 @@
#define QT3DRENDER_QPICKPOINTEVENT_H
#include <Qt3DRender/qpickevent.h>
+#include <QtCore/qsharedpointer.h>
QT_BEGIN_NAMESPACE
@@ -64,6 +65,8 @@ private:
Q_DECLARE_PRIVATE(QPickPointEvent)
};
+typedef QSharedPointer<QPickPointEvent> QPickPointEventPtr;
+
} // Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/picking/qpicktriangleevent.h b/src/render/picking/qpicktriangleevent.h
index 7655a0b94..f116af288 100644
--- a/src/render/picking/qpicktriangleevent.h
+++ b/src/render/picking/qpicktriangleevent.h
@@ -41,6 +41,7 @@
#define QT3DRENDER_QPICKTRIANGLEEVENT_H
#include <Qt3DRender/qpickevent.h>
+#include <QtCore/qsharedpointer.h>
QT_BEGIN_NAMESPACE
@@ -75,6 +76,8 @@ private:
Q_DECLARE_PRIVATE(QPickTriangleEvent)
};
+typedef QSharedPointer<QPickTriangleEvent> QPickTriangleEventPtr;
+
} // Qt3DRender
QT_END_NAMESPACE
diff --git a/src/render/renderstates/qstencilmask_p.h b/src/render/renderstates/qstencilmask_p.h
index a6aad60b9..762b249f8 100644
--- a/src/render/renderstates/qstencilmask_p.h
+++ b/src/render/renderstates/qstencilmask_p.h
@@ -60,7 +60,7 @@ class QT3DRENDERSHARED_PRIVATE_EXPORT QStencilMaskPrivate : public QRenderStateP
{
public:
QStencilMaskPrivate()
- : QRenderStatePrivate(Render::StencilTestStateMask)
+ : QRenderStatePrivate(Render::StencilWriteStateMask)
, m_frontOutputMask(0)
, m_backOutputMask(0)
{}
diff --git a/src/render/renderstates/qstenciloperation.cpp b/src/render/renderstates/qstenciloperation.cpp
index 7a5b113d8..66a326d55 100644
--- a/src/render/renderstates/qstenciloperation.cpp
+++ b/src/render/renderstates/qstenciloperation.cpp
@@ -40,6 +40,7 @@
#include "qstenciloperation.h"
#include "qstenciloperation_p.h"
#include "qstenciloperationarguments.h"
+#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DRender/private/qrenderstatecreatedchange_p.h>
QT_BEGIN_NAMESPACE
@@ -103,6 +104,19 @@ namespace Qt3DRender {
QStencilOperation::QStencilOperation(QNode *parent)
: QRenderState(*new QStencilOperationPrivate(), parent)
{
+ Q_D(QStencilOperation);
+
+ const auto resend = [d]() { d->resendArguments(); };
+
+ (void) connect(d->m_front, &QStencilOperationArguments::allTestsPassOperationChanged, resend);
+ (void) connect(d->m_front, &QStencilOperationArguments::depthTestFailureOperationChanged, resend);
+ (void) connect(d->m_front, &QStencilOperationArguments::stencilTestFailureOperationChanged, resend);
+ (void) connect(d->m_front, &QStencilOperationArguments::faceModeChanged, resend);
+
+ (void) connect(d->m_back, &QStencilOperationArguments::allTestsPassOperationChanged, resend);
+ (void) connect(d->m_back, &QStencilOperationArguments::depthTestFailureOperationChanged, resend);
+ (void) connect(d->m_back, &QStencilOperationArguments::stencilTestFailureOperationChanged, resend);
+ (void) connect(d->m_back, &QStencilOperationArguments::faceModeChanged, resend);
}
/*! \internal */
@@ -110,6 +124,30 @@ QStencilOperation::~QStencilOperation()
{
}
+/*! \internal */
+void QStencilOperationPrivate::resendArguments()
+{
+ auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(m_id);
+ QStencilOperationData data;
+ fillData(data);
+ e->setPropertyName("arguments");
+ e->setValue(QVariant::fromValue(data));
+ notifyObservers(e);
+}
+
+/*! \internal */
+void QStencilOperationPrivate::fillData(QStencilOperationData &data) const
+{
+ data.front.face = m_front->faceMode();
+ data.front.stencilTestFailureOperation = m_front->stencilTestFailureOperation();
+ data.front.depthTestFailureOperation = m_front->depthTestFailureOperation();
+ data.front.allTestsPassOperation = m_front->allTestsPassOperation();
+ data.back.face = m_back->faceMode();
+ data.back.stencilTestFailureOperation = m_back->stencilTestFailureOperation();
+ data.back.depthTestFailureOperation = m_back->depthTestFailureOperation();
+ data.back.allTestsPassOperation = m_back->allTestsPassOperation();
+}
+
QStencilOperationArguments *QStencilOperation::front() const
{
Q_D(const QStencilOperation);
@@ -125,16 +163,7 @@ QStencilOperationArguments *QStencilOperation::back() const
Qt3DCore::QNodeCreatedChangeBasePtr QStencilOperation::createNodeCreationChange() const
{
auto creationChange = QRenderStateCreatedChangePtr<QStencilOperationData>::create(this);
- auto &data = creationChange->data;
- Q_D(const QStencilOperation);
- data.front.face = d->m_front->faceMode();
- data.front.stencilTestFailureOperation = d->m_front->stencilTestFailureOperation();
- data.front.depthTestFailureOperation = d->m_front->depthTestFailureOperation();
- data.front.allTestsPassOperation = d->m_front->allTestsPassOperation();
- data.back.face = d->m_back->faceMode();
- data.back.stencilTestFailureOperation = d->m_back->stencilTestFailureOperation();
- data.back.depthTestFailureOperation = d->m_back->depthTestFailureOperation();
- data.back.allTestsPassOperation = d->m_back->allTestsPassOperation();
+ d_func()->fillData(creationChange->data);
return creationChange;
}
diff --git a/src/render/renderstates/qstenciloperation_p.h b/src/render/renderstates/qstenciloperation_p.h
index 3273ada23..dbce734b1 100644
--- a/src/render/renderstates/qstenciloperation_p.h
+++ b/src/render/renderstates/qstenciloperation_p.h
@@ -58,6 +58,12 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
+struct QStencilOperationData
+{
+ QStencilOperationArgumentsData front;
+ QStencilOperationArgumentsData back;
+};
+
class QT3DRENDERSHARED_PRIVATE_EXPORT QStencilOperationPrivate : public QRenderStatePrivate
{
public:
@@ -69,16 +75,15 @@ public:
QStencilOperationArguments *m_front;
QStencilOperationArguments *m_back;
-};
-struct QStencilOperationData
-{
- QStencilOperationArgumentsData front;
- QStencilOperationArgumentsData back;
+ void resendArguments();
+ void fillData(QStencilOperationData &data) const;
};
} // namespace Qt3DRender
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(Qt3DRender::QStencilOperationData)
+
#endif // QT3DRENDER_QSTENCILOPERATION_P_H
diff --git a/src/render/renderstates/qstenciltest.cpp b/src/render/renderstates/qstenciltest.cpp
index f1e42f1e3..74acfe3bc 100644
--- a/src/render/renderstates/qstenciltest.cpp
+++ b/src/render/renderstates/qstenciltest.cpp
@@ -41,6 +41,7 @@
#include "qstenciltest.h"
#include "qstenciltest_p.h"
#include "qstenciltestarguments.h"
+#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DRender/private/qrenderstatecreatedchange_p.h>
QT_BEGIN_NAMESPACE
@@ -106,6 +107,19 @@ namespace Qt3DRender {
QStencilTest::QStencilTest(QNode *parent)
: QRenderState(*new QStencilTestPrivate, parent)
{
+ Q_D(QStencilTest);
+
+ const auto resend = [d]() { d->resendArguments(); };
+
+ (void) connect(d->m_front, &QStencilTestArguments::comparisonMaskChanged, resend);
+ (void) connect(d->m_front, &QStencilTestArguments::faceModeChanged, resend);
+ (void) connect(d->m_front, &QStencilTestArguments::referenceValueChanged, resend);
+ (void) connect(d->m_front, &QStencilTestArguments::stencilFunctionChanged, resend);
+
+ (void) connect(d->m_back, &QStencilTestArguments::comparisonMaskChanged, resend);
+ (void) connect(d->m_back, &QStencilTestArguments::faceModeChanged, resend);
+ (void) connect(d->m_back, &QStencilTestArguments::referenceValueChanged, resend);
+ (void) connect(d->m_back, &QStencilTestArguments::stencilFunctionChanged, resend);
}
/*! \internal */
@@ -113,6 +127,30 @@ QStencilTest::~QStencilTest()
{
}
+/*! \internal */
+void QStencilTestPrivate::resendArguments()
+{
+ auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(m_id);
+ QStencilTestData data;
+ fillData(data);
+ e->setPropertyName("arguments");
+ e->setValue(QVariant::fromValue(data));
+ notifyObservers(e);
+}
+
+/*! \internal */
+void QStencilTestPrivate::fillData(QStencilTestData &data) const
+{
+ data.front.face = m_front->faceMode();
+ data.front.comparisonMask = m_front->comparisonMask();
+ data.front.referenceValue = m_front->referenceValue();
+ data.front.stencilFunction = m_front->stencilFunction();
+ data.back.face = m_back->faceMode();
+ data.back.comparisonMask = m_back->comparisonMask();
+ data.back.referenceValue = m_back->referenceValue();
+ data.back.stencilFunction = m_back->stencilFunction();
+}
+
QStencilTestArguments *QStencilTest::front() const
{
Q_D(const QStencilTest);
@@ -128,16 +166,7 @@ QStencilTestArguments *QStencilTest::back() const
Qt3DCore::QNodeCreatedChangeBasePtr QStencilTest::createNodeCreationChange() const
{
auto creationChange = QRenderStateCreatedChangePtr<QStencilTestData>::create(this);
- auto &data = creationChange->data;
- Q_D(const QStencilTest);
- data.front.face = d->m_front->faceMode();
- data.front.comparisonMask = d->m_front->comparisonMask();
- data.front.referenceValue = d->m_front->referenceValue();
- data.front.stencilFunction = d->m_front->stencilFunction();
- data.back.face = d->m_back->faceMode();
- data.back.comparisonMask = d->m_back->comparisonMask();
- data.back.referenceValue = d->m_back->referenceValue();
- data.back.stencilFunction = d->m_back->stencilFunction();
+ d_func()->fillData(creationChange->data);
return creationChange;
}
diff --git a/src/render/renderstates/qstenciltest_p.h b/src/render/renderstates/qstenciltest_p.h
index fc17cfde8..838ba5bc0 100644
--- a/src/render/renderstates/qstenciltest_p.h
+++ b/src/render/renderstates/qstenciltest_p.h
@@ -58,6 +58,12 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
+struct QStencilTestData
+{
+ QStencilTestArgumentsData front;
+ QStencilTestArgumentsData back;
+};
+
class QT3DRENDERSHARED_PRIVATE_EXPORT QStencilTestPrivate : public QRenderStatePrivate
{
public:
@@ -71,16 +77,15 @@ public:
Q_DECLARE_PUBLIC(QStencilTest)
QStencilTestArguments *m_front;
QStencilTestArguments *m_back;
-};
-struct QStencilTestData
-{
- QStencilTestArgumentsData front;
- QStencilTestArgumentsData back;
+ void resendArguments();
+ void fillData(QStencilTestData &data) const;
};
} // namespace Qt3DRender
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(Qt3DRender::QStencilTestData)
+
#endif // QT3DRENDER_QSTENCILTEST_P_H
diff --git a/src/render/renderstates/renderstates.cpp b/src/render/renderstates/renderstates.cpp
index d94191a13..d5e12aeab 100644
--- a/src/render/renderstates/renderstates.cpp
+++ b/src/render/renderstates/renderstates.cpp
@@ -43,8 +43,11 @@
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DRender/qrenderstate.h>
#include <Qt3DRender/qcullface.h>
+#include <Qt3DRender/qpointsize.h>
#include <Qt3DRender/private/graphicscontext_p.h>
+#include <Qt3DRender/private/qstenciloperation_p.h>
+#include <Qt3DRender/private/qstenciltest_p.h>
QT_BEGIN_NAMESPACE
@@ -102,7 +105,7 @@ void BlendEquation::apply(GraphicsContext *gc) const
void BlendEquation::updateProperty(const char *name, const QVariant &value)
{
- if (name == QByteArrayLiteral("mode")) std::get<0>(m_values) = value.toInt();
+ if (name == QByteArrayLiteral("blendFunction")) std::get<0>(m_values) = value.toInt();
}
void AlphaFunc::apply(GraphicsContext* gc) const
@@ -110,6 +113,14 @@ void AlphaFunc::apply(GraphicsContext* gc) const
gc->alphaTest(std::get<0>(m_values), std::get<1>(m_values));
}
+void AlphaFunc::updateProperty(const char *name, const QVariant &value)
+{
+ if (name == QByteArrayLiteral("alphaFunction"))
+ std::get<0>(m_values) = value.toInt();
+ if (name == QByteArrayLiteral("referenceValue"))
+ std::get<1>(m_values) = value.toFloat();
+}
+
void MSAAEnabled::apply(GraphicsContext *gc) const
{
gc->setMSAAEnabled(std::get<0>(m_values));
@@ -128,7 +139,7 @@ void DepthTest::apply(GraphicsContext *gc) const
void DepthTest::updateProperty(const char *name, const QVariant &value)
{
- if (name == QByteArrayLiteral("func")) std::get<0>(m_values) = value.toInt();
+ if (name == QByteArrayLiteral("depthFunction")) std::get<0>(m_values) = value.toInt();
}
void CullFace::apply(GraphicsContext *gc) const
@@ -192,6 +203,19 @@ void StencilTest::apply(GraphicsContext *gc) const
gc->openGLContext()->functions()->glStencilFuncSeparate(GL_BACK, std::get<3>(m_values), std::get<4>(m_values), std::get<5>(m_values));
}
+void StencilTest::updateProperty(const char *name, const QVariant &value)
+{
+ if (name == QByteArrayLiteral("arguments")) {
+ const QStencilTestData data = value.value<QStencilTestData>();
+ std::get<0>(m_values) = data.front.stencilFunction;
+ std::get<1>(m_values) = data.front.referenceValue;
+ std::get<2>(m_values) = data.front.comparisonMask;
+ std::get<3>(m_values) = data.back.stencilFunction;
+ std::get<4>(m_values) = data.back.referenceValue;
+ std::get<5>(m_values) = data.back.comparisonMask;
+ }
+}
+
void AlphaCoverage::apply(GraphicsContext *gc) const
{
gc->setAlphaCoverageEnabled(true);
@@ -204,7 +228,7 @@ void PointSize::apply(GraphicsContext *gc) const
void PointSize::updateProperty(const char *name, const QVariant &value)
{
- if (name == QByteArrayLiteral("specification")) std::get<0>(m_values) = value.toBool();
+ if (name == QByteArrayLiteral("sizeMode")) std::get<0>(m_values) = (value.toInt() == QPointSize::Programmable);
else if (name == QByteArrayLiteral("value")) std::get<1>(m_values) = value.toFloat();
}
@@ -216,8 +240,8 @@ void PolygonOffset::apply(GraphicsContext *gc) const
void PolygonOffset::updateProperty(const char *name, const QVariant &value)
{
- if (name == QByteArrayLiteral("factor")) std::get<0>(m_values) = value.toFloat();
- else if (name == QByteArrayLiteral("units")) std::get<1>(m_values) = value.toFloat();
+ if (name == QByteArrayLiteral("scaleFactor")) std::get<0>(m_values) = value.toFloat();
+ else if (name == QByteArrayLiteral("depthSteps")) std::get<1>(m_values) = value.toFloat();
}
void ColorMask::apply(GraphicsContext *gc) const
@@ -227,10 +251,10 @@ void ColorMask::apply(GraphicsContext *gc) const
void ColorMask::updateProperty(const char *name, const QVariant &value)
{
- if (name == QByteArrayLiteral("red")) std::get<0>(m_values) = value.toBool();
- else if (name == QByteArrayLiteral("green")) std::get<1>(m_values) = value.toBool();
- else if (name == QByteArrayLiteral("blue")) std::get<2>(m_values) = value.toBool();
- else if (name == QByteArrayLiteral("alpha")) std::get<3>(m_values) = value.toBool();
+ if (name == QByteArrayLiteral("redMasked")) std::get<0>(m_values) = value.toBool();
+ else if (name == QByteArrayLiteral("greenMasked")) std::get<1>(m_values) = value.toBool();
+ else if (name == QByteArrayLiteral("blueMasked")) std::get<2>(m_values) = value.toBool();
+ else if (name == QByteArrayLiteral("alphaMasked")) std::get<3>(m_values) = value.toBool();
}
void ClipPlane::apply(GraphicsContext *gc) const
@@ -257,6 +281,19 @@ void StencilOp::apply(GraphicsContext *gc) const
gc->openGLContext()->functions()->glStencilOpSeparate(GL_BACK, std::get<3>(m_values), std::get<4>(m_values), std::get<5>(m_values));
}
+void StencilOp::updateProperty(const char *name, const QVariant &value)
+{
+ if (name == QByteArrayLiteral("arguments")) {
+ const QStencilOperationData data = value.value<QStencilOperationData>();
+ std::get<0>(m_values) = data.front.stencilTestFailureOperation;
+ std::get<1>(m_values) = data.front.depthTestFailureOperation;
+ std::get<2>(m_values) = data.front.allTestsPassOperation;
+ std::get<3>(m_values) = data.back.stencilTestFailureOperation;
+ std::get<4>(m_values) = data.back.depthTestFailureOperation;
+ std::get<5>(m_values) = data.back.allTestsPassOperation;
+ }
+}
+
void StencilMask::apply(GraphicsContext *gc) const
{
gc->openGLContext()->functions()->glStencilMaskSeparate(GL_FRONT, std::get<0>(m_values));
@@ -265,8 +302,8 @@ void StencilMask::apply(GraphicsContext *gc) const
void StencilMask::updateProperty(const char *name, const QVariant &value)
{
- if (name == QByteArrayLiteral("frontMask")) std::get<0>(m_values) = value.toInt();
- else if (name == QByteArrayLiteral("backMask")) std::get<1>(m_values) = value.toInt();
+ if (name == QByteArrayLiteral("frontOutputMask")) std::get<0>(m_values) = value.toInt();
+ else if (name == QByteArrayLiteral("backOutputMask")) std::get<1>(m_values) = value.toInt();
}
#ifndef GL_LINE_SMOOTH
diff --git a/src/render/renderstates/renderstates_p.h b/src/render/renderstates/renderstates_p.h
index b503067a9..2b1af1c4c 100644
--- a/src/render/renderstates/renderstates_p.h
+++ b/src/render/renderstates/renderstates_p.h
@@ -78,6 +78,7 @@ class Q_AUTOTEST_EXPORT AlphaFunc : public GenericState<AlphaFunc, AlphaTestMask
{
public:
void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
class Q_AUTOTEST_EXPORT MSAAEnabled : public GenericState<MSAAEnabled, MSAAEnabledStateMask, GLboolean>
@@ -132,6 +133,7 @@ class Q_AUTOTEST_EXPORT StencilTest : public GenericState<StencilTest, StencilTe
{
public:
void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
class Q_AUTOTEST_EXPORT AlphaCoverage : public GenericState<AlphaCoverage, AlphaCoverageStateMask>
@@ -178,6 +180,7 @@ class Q_AUTOTEST_EXPORT StencilOp : public GenericState<StencilOp, StencilOpMask
{
public:
void apply(GraphicsContext *gc) const Q_DECL_FINAL;
+ void updateProperty(const char *name, const QVariant &value) Q_DECL_OVERRIDE;
};
class Q_AUTOTEST_EXPORT StencilMask : public GenericState<StencilMask, StencilWriteStateMask, uint, uint>
diff --git a/src/render/renderstates/statevariant_p.h b/src/render/renderstates/statevariant_p.h
index 55ec23899..393e4156c 100644
--- a/src/render/renderstates/statevariant_p.h
+++ b/src/render/renderstates/statevariant_p.h
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Render {
-struct StateVariant
+struct Q_AUTOTEST_EXPORT StateVariant
{
StateMask type;
diff --git a/src/render/services/vsyncframeadvanceservice.cpp b/src/render/services/vsyncframeadvanceservice.cpp
index 533b0fba1..880985aea 100644
--- a/src/render/services/vsyncframeadvanceservice.cpp
+++ b/src/render/services/vsyncframeadvanceservice.cpp
@@ -52,20 +52,22 @@ namespace Render {
class VSyncFrameAdvanceServicePrivate Q_DECL_FINAL : public Qt3DCore::QAbstractFrameAdvanceServicePrivate
{
public:
- VSyncFrameAdvanceServicePrivate()
+ explicit VSyncFrameAdvanceServicePrivate(bool drivenByRenderThread)
: QAbstractFrameAdvanceServicePrivate(QStringLiteral("Renderer Aspect Frame Advance Service - aligned with vsync"))
, m_semaphore(0)
, m_elapsedTimeSincePreviousFrame(0)
+ , m_drivenByRenderThread(drivenByRenderThread)
{
}
QSemaphore m_semaphore;
QElapsedTimer m_elapsed;
quint64 m_elapsedTimeSincePreviousFrame;
+ bool m_drivenByRenderThread;
};
-VSyncFrameAdvanceService::VSyncFrameAdvanceService()
- : QAbstractFrameAdvanceService(*new VSyncFrameAdvanceServicePrivate())
+VSyncFrameAdvanceService::VSyncFrameAdvanceService(bool drivenByRenderThread)
+ : QAbstractFrameAdvanceService(*new VSyncFrameAdvanceServicePrivate(drivenByRenderThread))
{
}
@@ -77,7 +79,17 @@ VSyncFrameAdvanceService::~VSyncFrameAdvanceService()
qint64 VSyncFrameAdvanceService::waitForNextFrame()
{
Q_D(VSyncFrameAdvanceService);
- d->m_semaphore.acquire(1);
+
+ // When rendering with Scene3D, we always want to acquire the available
+ // amount + 1 to handle the cases where for some reason proceedToNextFrame
+ // is being called more than once between calls to waitForNextFrame This
+ // could be the case when resizing the window
+
+ // When Qt3D is driving rendering however, this shouldn't happen
+ if (d->m_drivenByRenderThread)
+ d->m_semaphore.acquire(1);
+ else
+ d->m_semaphore.acquire(d->m_semaphore.available() + 1);
const quint64 currentTime = d->m_elapsed.nsecsElapsed();
qCDebug(VSyncAdvanceService) << "Elapsed nsecs since last call " << currentTime - d->m_elapsedTimeSincePreviousFrame;
diff --git a/src/render/services/vsyncframeadvanceservice_p.h b/src/render/services/vsyncframeadvanceservice_p.h
index 98daebf81..f33d41b98 100644
--- a/src/render/services/vsyncframeadvanceservice_p.h
+++ b/src/render/services/vsyncframeadvanceservice_p.h
@@ -64,7 +64,7 @@ class VSyncFrameAdvanceServicePrivate;
class Q_AUTOTEST_EXPORT VSyncFrameAdvanceService Q_DECL_FINAL : public Qt3DCore::QAbstractFrameAdvanceService
{
public:
- VSyncFrameAdvanceService();
+ explicit VSyncFrameAdvanceService(bool drivenByRenderThread);
~VSyncFrameAdvanceService();
qint64 waitForNextFrame() Q_DECL_FINAL;
diff --git a/src/render/texture/qpaintedtextureimage.cpp b/src/render/texture/qpaintedtextureimage.cpp
index 4d03eb809..db03b26b9 100644
--- a/src/render/texture/qpaintedtextureimage.cpp
+++ b/src/render/texture/qpaintedtextureimage.cpp
@@ -88,7 +88,7 @@ void QPaintedTextureImagePrivate::repaint()
painter.end();
++m_generation;
- m_currentGenerator.reset(new QPaintedTextureImageDataGenerator(*m_image.data(), m_generation, q_func()->id()));
+ m_currentGenerator = QSharedPointer<QPaintedTextureImageDataGenerator>::create(*m_image.data(), m_generation, q_func()->id());
q_func()->notifyDataGeneratorChanged();
}
diff --git a/src/src.pro b/src/src.pro
index c3ff226fd..cd07486e9 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -86,7 +86,7 @@ qtHaveModule(quick) {
# Qt3D Scene Parser plugins
src_plugins_sceneparsers.file = $$PWD/plugins/sceneparsers/sceneparsers.pro
src_plugins_sceneparsers.target = sub-plugins-sceneparsers
-src_plugins_sceneparsers.depends = src_render src_extras
+src_plugins_sceneparsers.depends = src_render src_extras src_animation
# Qt3D Geometry Loader plugins
src_plugins_geometryloaders.file = $$PWD/plugins/geometryloaders/geometryloaders.pro
diff --git a/sync.profile b/sync.profile
index 5382d7e88..88c777606 100644
--- a/sync.profile
+++ b/sync.profile
@@ -11,6 +11,7 @@
"Qt3DExtras" => "$basedir/src/extras",
"Qt3DQuickExtras" => "$basedir/src/quick3d/quick3dextras",
"Qt3DQuickScene2D" => "$basedir/src/quick3d/quick3dscene2d",
+ "Qt3DCoreTest" => "$basedir/tests/auto/coretest",
);
%moduleheaders = ( # restrict the module headers to those found in relative path
);
diff --git a/tests/auto/animation/animationclip/tst_animationclip.cpp b/tests/auto/animation/animationclip/tst_animationclip.cpp
index 61c55d36e..15ee60581 100644
--- a/tests/auto/animation/animationclip/tst_animationclip.cpp
+++ b/tests/auto/animation/animationclip/tst_animationclip.cpp
@@ -103,7 +103,7 @@ private Q_SLOTS:
Qt3DCore::QPropertyUpdatedChangePtr updateChange;
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendClip.sceneChangeEvent(updateChange);
@@ -113,7 +113,7 @@ private Q_SLOTS:
// WHEN
const QUrl newSource = QUrl::fromLocalFile("fallover.qlip");
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("source");
updateChange->setValue(newSource);
backendClip.sceneChangeEvent(updateChange);
diff --git a/tests/auto/animation/channelmapper/tst_channelmapper.cpp b/tests/auto/animation/channelmapper/tst_channelmapper.cpp
index 8a9b60bf5..4dcb52aef 100644
--- a/tests/auto/animation/channelmapper/tst_channelmapper.cpp
+++ b/tests/auto/animation/channelmapper/tst_channelmapper.cpp
@@ -105,7 +105,7 @@ private Q_SLOTS:
Qt3DCore::QPropertyUpdatedChangePtr updateChange;
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendMapper.sceneChangeEvent(updateChange);
diff --git a/tests/auto/animation/channelmapping/tst_channelmapping.cpp b/tests/auto/animation/channelmapping/tst_channelmapping.cpp
index 17e0418b5..478406336 100644
--- a/tests/auto/animation/channelmapping/tst_channelmapping.cpp
+++ b/tests/auto/animation/channelmapping/tst_channelmapping.cpp
@@ -109,7 +109,7 @@ private Q_SLOTS:
Qt3DCore::QPropertyUpdatedChangePtr updateChange;
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendMapping.sceneChangeEvent(updateChange);
@@ -119,7 +119,7 @@ private Q_SLOTS:
// WHEN
const QString channelName(QLatin1String("Rotation"));
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("channelName");
updateChange->setValue(channelName);
backendMapping.sceneChangeEvent(updateChange);
@@ -129,7 +129,7 @@ private Q_SLOTS:
// WHEN
const auto id = Qt3DCore::QNodeId::createId();
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("target");
updateChange->setValue(QVariant::fromValue(id));
backendMapping.sceneChangeEvent(updateChange);
@@ -139,7 +139,7 @@ private Q_SLOTS:
// WHEN
const QString property(QLatin1String("bar"));
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("property");
updateChange->setValue(property);
backendMapping.sceneChangeEvent(updateChange);
diff --git a/tests/auto/animation/clipanimator/tst_clipanimator.cpp b/tests/auto/animation/clipanimator/tst_clipanimator.cpp
index b15e09869..168cba050 100644
--- a/tests/auto/animation/clipanimator/tst_clipanimator.cpp
+++ b/tests/auto/animation/clipanimator/tst_clipanimator.cpp
@@ -116,7 +116,7 @@ private Q_SLOTS:
Qt3DCore::QPropertyUpdatedChangePtr updateChange;
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendAnimator.sceneChangeEvent(updateChange);
@@ -126,7 +126,7 @@ private Q_SLOTS:
// WHEN
auto newClip = new Qt3DAnimation::QAnimationClipLoader();
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("clip");
updateChange->setValue(QVariant::fromValue(newClip->id()));
backendAnimator.sceneChangeEvent(updateChange);
@@ -136,7 +136,7 @@ private Q_SLOTS:
// WHEN
auto clock = new Qt3DAnimation::QClock();
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("clock");
updateChange->setValue(QVariant::fromValue(clock->id()));
backendAnimator.sceneChangeEvent(updateChange);
@@ -145,7 +145,7 @@ private Q_SLOTS:
QCOMPARE(backendAnimator.clockId(), clock->id());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("running");
updateChange->setValue(true);
backendAnimator.sceneChangeEvent(updateChange);
@@ -154,7 +154,7 @@ private Q_SLOTS:
QCOMPARE(backendAnimator.isRunning(), true);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("loops");
updateChange->setValue(64);
backendAnimator.sceneChangeEvent(updateChange);
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 39631ef99..2d7ec9cb3 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -1,15 +1,21 @@
TEMPLATE = subdirs
SUBDIRS = \
+ coretest \
core \
cmake
installed_cmake.depends = cmake
-QT_FOR_CONFIG += 3dcore
+QT_FOR_CONFIG += 3dcore
qtConfig(qt3d-render): SUBDIRS += render
qtConfig(qt3d-input): SUBDIRS += input
qtConfig(qt3d-animation): SUBDIRS += animation
qtConfig(qt3d-extras): SUBDIRS += extras
qtConfig(qt3d-render):qtConfig(qt3d-input): SUBDIRS += quick3d
+for(subdir, SUBDIRS) {
+ !equals(subdir, coretest) {
+ $${subdir}.depends += coretest
+ }
+}
diff --git a/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp b/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp
index faccb6d34..57f7e7ed4 100644
--- a/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp
+++ b/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp
@@ -229,7 +229,7 @@ public:
void sendReply()
{
Qt3DCore::QPropertyUpdatedChangePtr reply;
- reply.reset(new Qt3DCore::QPropertyUpdatedChange(m_targetId));
+ reply = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(m_targetId);
reply->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
reply->setPropertyName("Reply");
notifyObservers(reply);
diff --git a/tests/auto/coretest/coretest.pro b/tests/auto/coretest/coretest.pro
new file mode 100644
index 000000000..9bcc56c1b
--- /dev/null
+++ b/tests/auto/coretest/coretest.pro
@@ -0,0 +1,25 @@
+TARGET = Qt3DCoreTest
+MODULE = 3dcoretest
+CONFIG += static internal_module
+
+DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_FOREACH
+PRECOMPILED_HEADER =
+INCLUDEPATH += $$PWD
+
+SOURCES += \
+ $$PWD/testpostmanarbiter.cpp
+
+HEADERS += \
+ $$PWD/testpostmanarbiter_p.h
+
+qtConfig(private_tests) {
+ SOURCES += \
+ $$PWD/qbackendnodetester.cpp
+
+ HEADERS += \
+ $$PWD/qbackendnodetester_p.h
+}
+
+QT += core-private 3dcore 3dcore-private
+
+load(qt_module)
diff --git a/tests/auto/coretest/qbackendnodetester.cpp b/tests/auto/coretest/qbackendnodetester.cpp
new file mode 100644
index 000000000..be9767828
--- /dev/null
+++ b/tests/auto/coretest/qbackendnodetester.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbackendnodetester_p.h"
+#include <Qt3DCore/qbackendnode.h>
+#include <Qt3DCore/qnode.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DCore {
+
+QBackendNodeTester::QBackendNodeTester(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void QBackendNodeTester::setPeerId(QBackendNode *backend, QNodeId id)
+{
+ Q_ASSERT(backend);
+ backend->setPeerId(id);
+}
+
+void QBackendNodeTester::simulateInitialization(QNode *frontend, QBackendNode *backend)
+{
+ Q_ASSERT(frontend);
+ Q_ASSERT(backend);
+ const auto change = frontend->createNodeCreationChange();
+ backend->setPeerId(change->subjectId());
+ backend->setEnabled(change->isNodeEnabled());
+ backend->initializeFromPeer(change);
+}
+
+void QBackendNodeTester::sceneChangeEvent(QBackendNode *backend, const Qt3DCore::QSceneChangePtr &e)
+{
+ backend->sceneChangeEvent(e);
+}
+
+} // namespace Qt3DCore
+
+QT_END_NAMESPACE
diff --git a/tests/auto/coretest/qbackendnodetester_p.h b/tests/auto/coretest/qbackendnodetester_p.h
new file mode 100644
index 000000000..020cfcdf1
--- /dev/null
+++ b/tests/auto/coretest/qbackendnodetester_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DCORE_QBACKENDNODETESTER_P_H
+#define QT3DCORE_QBACKENDNODETESTER_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 <QObject>
+#include <Qt3DCore/qnodeid.h>
+#include <Qt3DCore/qscenechange.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DCore {
+
+class QBackendNode;
+class QNode;
+
+class QBackendNodeTester : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QBackendNodeTester(QObject *parent = 0);
+
+ // Proxies to allow test classes to call private methods on QBackendNode
+ void setPeerId(QBackendNode *backend, QNodeId id);
+ void simulateInitialization(QNode *frontend, QBackendNode *backend);
+ void sceneChangeEvent(QBackendNode *backend, const Qt3DCore::QSceneChangePtr &e);
+};
+
+} // namespace Qt3DCore
+
+QT_END_NAMESPACE
+
+#endif // QT3DCORE_QBACKENDNODETESTER_P_H
diff --git a/tests/auto/coretest/testpostmanarbiter.cpp b/tests/auto/coretest/testpostmanarbiter.cpp
new file mode 100644
index 000000000..b4c1b03af
--- /dev/null
+++ b/tests/auto/coretest/testpostmanarbiter.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "testpostmanarbiter_p.h"
+#include <Qt3DCore/private/qnode_p.h>
+
+QT_BEGIN_NAMESPACE
+
+TestPostman::TestPostman(TestArbiter *arbiter)
+ : m_arbiter(arbiter)
+{}
+
+void TestPostman::setScene(Qt3DCore::QScene *)
+{}
+
+void TestPostman::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &)
+{}
+
+void TestPostman::notifyBackend(const Qt3DCore::QSceneChangePtr &e)
+{
+ m_arbiter->sceneChangeEventWithLock(e);
+}
+
+bool TestPostman::shouldNotifyFrontend(const Qt3DCore::QSceneChangePtr &)
+{
+ return false;
+}
+
+TestArbiter::TestArbiter()
+ : m_postman(new TestPostman(this))
+{
+}
+
+TestArbiter::~TestArbiter()
+{
+}
+
+void TestArbiter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
+{
+ events.push_back(e);
+}
+
+void TestArbiter::sceneChangeEventWithLock(const Qt3DCore::QSceneChangePtr &e)
+{
+ events.push_back(e);
+}
+
+void TestArbiter::sceneChangeEventWithLock(const Qt3DCore::QSceneChangeList &e)
+{
+ events += QVector<Qt3DCore::QSceneChangePtr>::fromStdVector(e);
+}
+
+Qt3DCore::QAbstractPostman *TestArbiter::postman() const
+{
+ return m_postman;
+}
+
+void TestArbiter::setArbiterOnNode(Qt3DCore::QNode *node)
+{
+ Qt3DCore::QNodePrivate::get(node)->setArbiter(this);
+ for (Qt3DCore::QNode *n : node->childNodes())
+ setArbiterOnNode(n);
+}
+
+QT_END_NAMESPACE
diff --git a/tests/auto/coretest/testpostmanarbiter_p.h b/tests/auto/coretest/testpostmanarbiter_p.h
new file mode 100644
index 000000000..7785b864a
--- /dev/null
+++ b/tests/auto/coretest/testpostmanarbiter_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DCORE_TESTPOSTMANARBITER_P_H
+#define QT3DCORE_TESTPOSTMANARBITER_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/private/qpostman_p.h>
+#include <Qt3DCore/private/qchangearbiter_p.h>
+#include <Qt3DCore/qpropertyupdatedchange.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DCore {
+ class QNode;
+} // Qt3D
+
+class TestArbiter;
+
+class TestPostman : public Qt3DCore::QAbstractPostman
+{
+public:
+ explicit TestPostman(TestArbiter *arbiter);
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &) Q_DECL_FINAL;
+ void setScene(Qt3DCore::QScene *) Q_DECL_FINAL;
+ void notifyBackend(const Qt3DCore::QSceneChangePtr &e) Q_DECL_FINAL;
+ bool shouldNotifyFrontend(const Qt3DCore::QSceneChangePtr &e) Q_DECL_FINAL;
+
+private:
+ TestArbiter *m_arbiter;
+};
+
+class TestArbiter : public Qt3DCore::QAbstractArbiter
+{
+public:
+ TestArbiter();
+ ~TestArbiter();
+
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_FINAL;
+
+ void sceneChangeEventWithLock(const Qt3DCore::QSceneChangePtr &e) Q_DECL_FINAL;
+
+ void sceneChangeEventWithLock(const Qt3DCore::QSceneChangeList &e) Q_DECL_FINAL;
+
+ Qt3DCore::QAbstractPostman *postman() const Q_DECL_FINAL;
+
+ QVector<Qt3DCore::QSceneChangePtr> events;
+
+ void setArbiterOnNode(Qt3DCore::QNode *node);
+
+private:
+ TestPostman *m_postman;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT3DCORE_TESTPOSTMANARBITER_P_H
diff --git a/tests/auto/input/abstractaxisinput/tst_abstractaxisinput.cpp b/tests/auto/input/abstractaxisinput/tst_abstractaxisinput.cpp
index 0e80b2478..97e9b7c77 100644
--- a/tests/auto/input/abstractaxisinput/tst_abstractaxisinput.cpp
+++ b/tests/auto/input/abstractaxisinput/tst_abstractaxisinput.cpp
@@ -138,7 +138,7 @@ private Q_SLOTS:
// WHEN
TestDevice device;
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("sourceDevice");
updateChange->setValue(QVariant::fromValue(device.id()));
backendAxisInput.sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/action/tst_action.cpp b/tests/auto/input/action/tst_action.cpp
index 91ca2f794..7ef9bca1e 100644
--- a/tests/auto/input/action/tst_action.cpp
+++ b/tests/auto/input/action/tst_action.cpp
@@ -113,7 +113,7 @@ private Q_SLOTS:
Qt3DCore::QPropertyUpdatedChangePtr updateChange;
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendAction.sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/actioninput/tst_actioninput.cpp b/tests/auto/input/actioninput/tst_actioninput.cpp
index fd87606a7..23dfaad64 100644
--- a/tests/auto/input/actioninput/tst_actioninput.cpp
+++ b/tests/auto/input/actioninput/tst_actioninput.cpp
@@ -102,7 +102,7 @@ private Q_SLOTS:
QCOMPARE(backendActionInput.buttons(), QVector<int>() << 64);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendActionInput.sceneChangeEvent(updateChange);
@@ -112,7 +112,7 @@ private Q_SLOTS:
// WHEN
TestDevice device;
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("sourceDevice");
updateChange->setValue(QVariant::fromValue(device.id()));
backendActionInput.sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/analogaxisinput/tst_analogaxisinput.cpp b/tests/auto/input/analogaxisinput/tst_analogaxisinput.cpp
index faa7385bc..a37c37e96 100644
--- a/tests/auto/input/analogaxisinput/tst_analogaxisinput.cpp
+++ b/tests/auto/input/analogaxisinput/tst_analogaxisinput.cpp
@@ -107,7 +107,7 @@ private Q_SLOTS:
QCOMPARE(backendAxisInput.axis(), 32);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendAxisInput.sceneChangeEvent(updateChange);
@@ -117,7 +117,7 @@ private Q_SLOTS:
// WHEN
TestDevice device;
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("sourceDevice");
updateChange->setValue(QVariant::fromValue(device.id()));
backendAxisInput.sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/axis/tst_axis.cpp b/tests/auto/input/axis/tst_axis.cpp
index dc8b225ba..42f7f56fc 100644
--- a/tests/auto/input/axis/tst_axis.cpp
+++ b/tests/auto/input/axis/tst_axis.cpp
@@ -114,7 +114,7 @@ private Q_SLOTS:
Qt3DCore::QPropertyUpdatedChangePtr updateChange;
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendAxis.sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp b/tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp
index 94cb71030..8e0b499fd 100644
--- a/tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp
+++ b/tests/auto/input/axisaccumulator/tst_axisaccumulator.cpp
@@ -114,7 +114,7 @@ private Q_SLOTS:
Qt3DCore::QPropertyUpdatedChangePtr updateChange;
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendAxisAccumulator.sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/buttonaxisinput/tst_buttonaxisinput.cpp b/tests/auto/input/buttonaxisinput/tst_buttonaxisinput.cpp
index 90867a747..18887cfe6 100644
--- a/tests/auto/input/buttonaxisinput/tst_buttonaxisinput.cpp
+++ b/tests/auto/input/buttonaxisinput/tst_buttonaxisinput.cpp
@@ -127,7 +127,7 @@ private Q_SLOTS:
QCOMPARE(backendAxisInput.buttons(), QVector<int>() << 64);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(0.5f);
updateChange->setPropertyName("scale");
backendAxisInput.sceneChangeEvent(updateChange);
@@ -136,7 +136,7 @@ private Q_SLOTS:
QCOMPARE(backendAxisInput.scale(), 0.5f);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendAxisInput.sceneChangeEvent(updateChange);
@@ -146,7 +146,7 @@ private Q_SLOTS:
// WHEN
TestDevice device;
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("sourceDevice");
updateChange->setValue(QVariant::fromValue(device.id()));
backendAxisInput.sceneChangeEvent(updateChange);
@@ -155,7 +155,7 @@ private Q_SLOTS:
QCOMPARE(backendAxisInput.sourceDevice(), device.id());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(0.42f);
updateChange->setPropertyName("acceleration");
backendAxisInput.sceneChangeEvent(updateChange);
@@ -164,7 +164,7 @@ private Q_SLOTS:
QCOMPARE(backendAxisInput.acceleration(), 0.42f);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(-0.42f);
updateChange->setPropertyName("acceleration");
backendAxisInput.sceneChangeEvent(updateChange);
@@ -173,7 +173,7 @@ private Q_SLOTS:
QVERIFY(qIsInf(backendAxisInput.acceleration()));
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(0.43f);
updateChange->setPropertyName("deceleration");
backendAxisInput.sceneChangeEvent(updateChange);
@@ -182,7 +182,7 @@ private Q_SLOTS:
QCOMPARE(backendAxisInput.deceleration(), 0.43f);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(-0.43f);
updateChange->setPropertyName("deceleration");
backendAxisInput.sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/inputchord/tst_inputchord.cpp b/tests/auto/input/inputchord/tst_inputchord.cpp
index d3ad1c84a..093bd29f7 100644
--- a/tests/auto/input/inputchord/tst_inputchord.cpp
+++ b/tests/auto/input/inputchord/tst_inputchord.cpp
@@ -113,7 +113,7 @@ private Q_SLOTS:
QCOMPARE(backendInputChord.timeout(), 250000000);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendInputChord.sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/inputsequence/tst_inputsequence.cpp b/tests/auto/input/inputsequence/tst_inputsequence.cpp
index a73572553..b5630ddb5 100644
--- a/tests/auto/input/inputsequence/tst_inputsequence.cpp
+++ b/tests/auto/input/inputsequence/tst_inputsequence.cpp
@@ -118,7 +118,7 @@ private Q_SLOTS:
QCOMPARE(backendInputSequence.timeout(), 250000000);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(150);
updateChange->setPropertyName("buttonInterval");
backendInputSequence.sceneChangeEvent(updateChange);
@@ -127,7 +127,7 @@ private Q_SLOTS:
QCOMPARE(backendInputSequence.buttonInterval(), 150000000);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendInputSequence.sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/keyboardhandler/tst_keyboardhandler.cpp b/tests/auto/input/keyboardhandler/tst_keyboardhandler.cpp
index 4314660ec..3681f3554 100644
--- a/tests/auto/input/keyboardhandler/tst_keyboardhandler.cpp
+++ b/tests/auto/input/keyboardhandler/tst_keyboardhandler.cpp
@@ -109,7 +109,7 @@ private Q_SLOTS:
QCOMPARE(backendKeyboardHandler->keyboardDevice(), device.id());
// WHEN (still disabled, nothing should happen)
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("focus");
updateChange->setValue(true);
backendKeyboardHandler->sceneChangeEvent(updateChange);
@@ -118,7 +118,7 @@ private Q_SLOTS:
QVERIFY(backendKeyboardDevice->lastKeyboardInputRequester().isNull());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("enabled");
updateChange->setValue(true);
backendKeyboardHandler->sceneChangeEvent(updateChange);
@@ -127,7 +127,7 @@ private Q_SLOTS:
QCOMPARE(backendKeyboardHandler->isEnabled(), true);
// WHEN (now enabled, should request focus)
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("focus");
updateChange->setValue(true);
backendKeyboardHandler->sceneChangeEvent(updateChange);
diff --git a/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp b/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp
index 3df09a67a..2447c564d 100644
--- a/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp
+++ b/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp
@@ -186,7 +186,7 @@ private Q_SLOTS:
QCOMPARE(velocity(), 0.0f);
// WHEN
- valueChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
valueChange->setPropertyName("velocity");
valueChange->setValue(123.0f);
sceneChangeEvent(valueChange);
diff --git a/tests/auto/render/attribute/tst_attribute.cpp b/tests/auto/render/attribute/tst_attribute.cpp
index 2361f2405..a673a327b 100644
--- a/tests/auto/render/attribute/tst_attribute.cpp
+++ b/tests/auto/render/attribute/tst_attribute.cpp
@@ -153,7 +153,7 @@ private Q_SLOTS:
QVERIFY(!renderer.dirtyBits());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(3);
updateChange->setPropertyName("vertexSize");
renderAttribute.sceneChangeEvent(updateChange);
@@ -168,7 +168,7 @@ private Q_SLOTS:
QVERIFY(!renderAttribute.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(static_cast<int>(Qt3DRender::QAttribute::IndexAttribute));
updateChange->setPropertyName("attributeType");
renderAttribute.sceneChangeEvent(updateChange);
@@ -183,7 +183,7 @@ private Q_SLOTS:
QVERIFY(!renderAttribute.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(static_cast<int>(Qt3DRender::QAttribute::DrawIndirectAttribute));
updateChange->setPropertyName("attributeType");
renderAttribute.sceneChangeEvent(updateChange);
@@ -198,7 +198,7 @@ private Q_SLOTS:
QVERIFY(!renderAttribute.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(1340);
updateChange->setPropertyName("count");
renderAttribute.sceneChangeEvent(updateChange);
@@ -213,7 +213,7 @@ private Q_SLOTS:
QVERIFY(!renderAttribute.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(QStringLiteral("L88"));
updateChange->setPropertyName("name");
renderAttribute.sceneChangeEvent(updateChange);
@@ -228,7 +228,7 @@ private Q_SLOTS:
QVERIFY(!renderAttribute.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(555);
updateChange->setPropertyName("byteOffset");
renderAttribute.sceneChangeEvent(updateChange);
@@ -243,7 +243,7 @@ private Q_SLOTS:
QVERIFY(!renderAttribute.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(454);
updateChange->setPropertyName("byteStride");
renderAttribute.sceneChangeEvent(updateChange);
@@ -258,7 +258,7 @@ private Q_SLOTS:
QVERIFY(!renderAttribute.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(1450);
updateChange->setPropertyName("divisor");
renderAttribute.sceneChangeEvent(updateChange);
@@ -273,7 +273,7 @@ private Q_SLOTS:
QVERIFY(!renderAttribute.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
Qt3DCore::QNodeId bufferId = Qt3DCore::QNodeId::createId();
updateChange->setValue(QVariant::fromValue(bufferId));
updateChange->setPropertyName("buffer");
diff --git a/tests/auto/render/buffer/tst_buffer.cpp b/tests/auto/render/buffer/tst_buffer.cpp
index 589c05d7e..7af342264 100644
--- a/tests/auto/render/buffer/tst_buffer.cpp
+++ b/tests/auto/render/buffer/tst_buffer.cpp
@@ -185,7 +185,7 @@ private Q_SLOTS:
QVERIFY(!renderBuffer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(static_cast<int>(Qt3DRender::QBuffer::DynamicRead));
updateChange->setPropertyName("usage");
renderBuffer.sceneChangeEvent(updateChange);
@@ -201,7 +201,7 @@ private Q_SLOTS:
QVERIFY(!renderBuffer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(QByteArrayLiteral("LS9"));
updateChange->setPropertyName("data");
renderBuffer.sceneChangeEvent(updateChange);
@@ -222,7 +222,7 @@ private Q_SLOTS:
// WHEN
Qt3DRender::QBufferDataGeneratorPtr functor(new TestFunctor(355));
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(QVariant::fromValue(functor));
updateChange->setPropertyName("dataGenerator");
renderBuffer.sceneChangeEvent(updateChange);
@@ -238,7 +238,7 @@ private Q_SLOTS:
QVERIFY(!renderBuffer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(true);
updateChange->setPropertyName("syncData");
renderBuffer.sceneChangeEvent(updateChange);
@@ -267,7 +267,7 @@ private Q_SLOTS:
renderBuffer.pendingBufferUpdates().clear();
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
Qt3DRender::QBufferUpdate updateData;
updateData.offset = 2;
updateData.data = QByteArrayLiteral("LS5");
diff --git a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
index 4e14fbbaf..af074def0 100644
--- a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
+++ b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
@@ -206,7 +206,7 @@ private Q_SLOTS:
QVERIFY(!renderGeometryRenderer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("vertexCount");
updateChange->setValue(56);
renderGeometryRenderer.sceneChangeEvent(updateChange);
@@ -222,7 +222,7 @@ private Q_SLOTS:
QVERIFY(!renderGeometryRenderer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("indexOffset");
updateChange->setValue(65);
renderGeometryRenderer.sceneChangeEvent(updateChange);
@@ -238,7 +238,7 @@ private Q_SLOTS:
QVERIFY(!renderGeometryRenderer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("firstInstance");
updateChange->setValue(82);
renderGeometryRenderer.sceneChangeEvent(updateChange);
@@ -270,7 +270,7 @@ private Q_SLOTS:
QVERIFY(!renderGeometryRenderer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("restartIndexValue");
updateChange->setValue(46);
renderGeometryRenderer.sceneChangeEvent(updateChange);
@@ -286,7 +286,7 @@ private Q_SLOTS:
QVERIFY(!renderGeometryRenderer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("primitiveRestartEnabled");
updateChange->setValue(true);
renderGeometryRenderer.sceneChangeEvent(updateChange);
@@ -302,7 +302,7 @@ private Q_SLOTS:
QVERIFY(!renderGeometryRenderer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("primitiveType");
updateChange->setValue(static_cast<int>(Qt3DRender::QGeometryRenderer::LineLoop));
renderGeometryRenderer.sceneChangeEvent(updateChange);
@@ -318,7 +318,7 @@ private Q_SLOTS:
QVERIFY(!renderGeometryRenderer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setPropertyName("geometryFactory");
Qt3DRender::QGeometryFactoryPtr factory(new TestFactory(1450));
updateChange->setValue(QVariant::fromValue(factory));
@@ -380,7 +380,7 @@ private Q_SLOTS:
QVERIFY(!renderGeometryRenderer.isDirty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(QVariant::fromValue(true));
updateChange->setPropertyName("enabled");
renderGeometryRenderer.sceneChangeEvent(updateChange);
diff --git a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
index 4a393c99f..c6719f3bd 100644
--- a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
+++ b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
@@ -257,15 +257,35 @@ private Q_SLOTS:
QVERIFY(fboId != 0);
// WHEN
- m_glHelper.bindFrameBufferObject(fboId);
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
// THEN
- const GLint error = m_func->glGetError();
+ GLint error = m_func->glGetError();
QVERIFY(error == 0);
GLint boundindFBOId = 0;
m_func->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundindFBOId);
QVERIFY(GLuint(boundindFBOId) == fboId);
+ // WHEN
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBORead);
+
+ // THEN
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+ boundindFBOId = 0;
+ m_func->glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundindFBOId);
+ QVERIFY(GLuint(boundindFBOId) == fboId);
+
+ // WHEN
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBOReadAndDraw);
+
+ // THEN
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+ boundindFBOId = 0;
+ m_func->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &boundindFBOId);
+ QVERIFY(GLuint(boundindFBOId) == fboId);
+
// Cleanup
m_fboFuncs->glDeleteFramebuffers(1, &fboId);
}
diff --git a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
index 38b566142..86a26cfdf 100644
--- a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
+++ b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
@@ -341,15 +341,35 @@ private Q_SLOTS:
QVERIFY(fboId != 0);
// WHEN
- m_glHelper.bindFrameBufferObject(fboId);
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
// THEN
- const GLint error = m_func->glGetError();
+ GLint error = m_func->glGetError();
QVERIFY(error == 0);
GLint boundindFBOId = 0;
m_func->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundindFBOId);
QVERIFY(GLuint(boundindFBOId) == fboId);
+ // WHEN
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBORead);
+
+ // THEN
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+ boundindFBOId = 0;
+ m_func->glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundindFBOId);
+ QVERIFY(GLuint(boundindFBOId) == fboId);
+
+ // WHEN
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBOReadAndDraw);
+
+ // THEN
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+ boundindFBOId = 0;
+ m_func->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &boundindFBOId);
+ QVERIFY(GLuint(boundindFBOId) == fboId);
+
// Cleanup
m_func->glDeleteFramebuffers(1, &fboId);
}
diff --git a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
index b76287844..48121ad36 100644
--- a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
+++ b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
@@ -439,15 +439,35 @@ private Q_SLOTS:
QVERIFY(fboId != 0);
// WHEN
- m_glHelper.bindFrameBufferObject(fboId);
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
// THEN
- const GLint error = m_func->glGetError();
+ GLint error = m_func->glGetError();
QVERIFY(error == 0);
GLint boundindFBOId = 0;
m_func->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundindFBOId);
QVERIFY(GLuint(boundindFBOId) == fboId);
+ // WHEN
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBORead);
+
+ // THEN
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+ boundindFBOId = 0;
+ m_func->glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundindFBOId);
+ QVERIFY(GLuint(boundindFBOId) == fboId);
+
+ // WHEN
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBOReadAndDraw);
+
+ // THEN
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+ boundindFBOId = 0;
+ m_func->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &boundindFBOId);
+ QVERIFY(GLuint(boundindFBOId) == fboId);
+
// Cleanup
m_func->glDeleteFramebuffers(1, &fboId);
}
diff --git a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
index 91fe3d3d4..46897ab49 100644
--- a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
+++ b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
@@ -461,15 +461,35 @@ private Q_SLOTS:
QVERIFY(fboId != 0);
// WHEN
- m_glHelper.bindFrameBufferObject(fboId);
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw);
// THEN
- const GLint error = m_func->glGetError();
+ GLint error = m_func->glGetError();
QVERIFY(error == 0);
GLint boundindFBOId = 0;
m_func->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundindFBOId);
QVERIFY(GLuint(boundindFBOId) == fboId);
+ // WHEN
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBORead);
+
+ // THEN
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+ boundindFBOId = 0;
+ m_func->glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundindFBOId);
+ QVERIFY(GLuint(boundindFBOId) == fboId);
+
+ // WHEN
+ m_glHelper.bindFrameBufferObject(fboId, GraphicsHelperInterface::FBOReadAndDraw);
+
+ // THEN
+ error = m_func->glGetError();
+ QVERIFY(error == 0);
+ boundindFBOId = 0;
+ m_func->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &boundindFBOId);
+ QVERIFY(GLuint(boundindFBOId) == fboId);
+
// Cleanup
m_func->glDeleteFramebuffers(1, &fboId);
}
diff --git a/tests/auto/render/qrenderstate/qrenderstate.pro b/tests/auto/render/qrenderstate/qrenderstate.pro
new file mode 100644
index 000000000..60bdfef01
--- /dev/null
+++ b/tests/auto/render/qrenderstate/qrenderstate.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qrenderstate
+
+QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib
+
+CONFIG += testcase
+
+SOURCES += tst_qrenderstate.cpp
+
+include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/render/qrenderstate/tst_qrenderstate.cpp b/tests/auto/render/qrenderstate/tst_qrenderstate.cpp
new file mode 100644
index 000000000..6e90f4ce1
--- /dev/null
+++ b/tests/auto/render/qrenderstate/tst_qrenderstate.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <qbackendnodetester.h>
+#include <testrenderer.h>
+
+#include <Qt3DCore/private/qscene_p.h>
+#include <Qt3DRender/private/renderstatenode_p.h>
+#include <Qt3DRender/private/managers_p.h>
+
+#include <Qt3DRender/QRenderState>
+#include <Qt3DRender/QAlphaCoverage>
+#include <Qt3DRender/QAlphaTest>
+#include <Qt3DRender/QBlendEquation>
+#include <Qt3DRender/QBlendEquationArguments>
+#include <Qt3DRender/QColorMask>
+#include <Qt3DRender/QCullFace>
+#include <Qt3DRender/QDepthTest>
+#include <Qt3DRender/QDithering>
+#include <Qt3DRender/QFrontFace>
+#include <Qt3DRender/QPointSize>
+#include <Qt3DRender/QPolygonOffset>
+#include <Qt3DRender/QScissorTest>
+#include <Qt3DRender/QStencilTest>
+#include <Qt3DRender/QStencilTestArguments>
+#include <Qt3DRender/QStencilMask>
+#include <Qt3DRender/QStencilOperation>
+#include <Qt3DRender/QStencilOperationArguments>
+#include <Qt3DRender/QClipPlane>
+
+#include "testpostmanarbiter.h"
+
+using namespace Qt3DCore;
+using namespace Qt3DRender;
+using namespace Qt3DRender::Render;
+
+class tst_QRenderState : public QBackendNodeTester
+{
+ Q_OBJECT
+public:
+ tst_QRenderState() {}
+ ~tst_QRenderState() {}
+
+private:
+ RenderStateManager m_renderStateManager;
+ TestRenderer m_renderer;
+
+ RenderStateNode* createBackendNode(QRenderState *frontend)
+ {
+ RenderStateNode *backend = m_renderStateManager.getOrCreateResource(frontend->id());
+ simulateInitialization(frontend, backend);
+ backend->setRenderer(&m_renderer);
+ return backend;
+ }
+
+ // Create two frontend objects of class T and set given property to v1 / v2 respectively
+ template <class T, class V, class Setter>
+ void addTestCase(Qt3DRender::Render::StateMask mask, const char *property, Setter setter, V v1, V v2)
+ {
+ T *obj1 = new T();
+ T *obj2 = new T();
+
+ (obj1->*(setter))(v1);
+ (obj2->*(setter))(v2);
+
+ QTest::addRow("%s::%s", obj1->metaObject()->className(), property)
+ << (QRenderState*) obj1
+ << (QRenderState*) obj2
+ << (quint64) mask
+ << QString(property)
+ << QVariant(v2);
+ }
+
+ // Create two frontend objects of class T and set given property to v1 / v2 respectively, for the specified arguments sub-object
+ template <class T, class Args, class V, class Setter>
+ void addStencilTestCase(Qt3DRender::Render::StateMask mask, const char *argsName, const char *property, Setter setter, V v1, V v2)
+ {
+ T *obj1 = new T();
+ T *obj2 = new T();
+
+ const QMetaObject *metaObj = obj1->metaObject();
+ const int pIndex = metaObj->indexOfProperty(argsName);
+ const QMetaProperty prop = metaObj->property(pIndex);
+ Args *args1 = qvariant_cast<Args*>(prop.read(obj1));
+ Args *args2 = qvariant_cast<Args*>(prop.read(obj2));
+
+ (args1->*(setter))(v1);
+ (args2->*(setter))(v2);
+
+ QTest::addRow("%s::%s::%s", metaObj->className(), argsName, property)
+ << (QRenderState*) obj1
+ << (QObject*) args1
+ << (QRenderState*) obj2
+ << (quint64) mask
+ << QString(property)
+ << QVariant(v2);
+ }
+
+private Q_SLOTS:
+
+ void checkPropertyUpdates_data()
+ {
+ QTest::addColumn<QRenderState *>("frontend1");
+ QTest::addColumn<QRenderState *>("frontend2");
+ QTest::addColumn<quint64>("mask");
+ QTest::addColumn<QString>("propertyName");
+ QTest::addColumn<QVariant>("value");
+
+ addTestCase<QAlphaTest>(AlphaTestMask, "alphaFunction", &QAlphaTest::setAlphaFunction, QAlphaTest::Always, QAlphaTest::LessOrEqual);
+ addTestCase<QAlphaTest>(AlphaTestMask, "referenceValue", &QAlphaTest::setReferenceValue, 0.f, 1.f);
+
+ addTestCase<QBlendEquation>(BlendStateMask, "blendFunction", &QBlendEquation::setBlendFunction, QBlendEquation::Add, QBlendEquation::Subtract);
+
+ addTestCase<QBlendEquationArguments>(BlendEquationArgumentsMask, "sourceRgb", &QBlendEquationArguments::setSourceRgb, QBlendEquationArguments::Zero, QBlendEquationArguments::One);
+ addTestCase<QBlendEquationArguments>(BlendEquationArgumentsMask, "sourceAlpha", &QBlendEquationArguments::setSourceAlpha, QBlendEquationArguments::SourceAlpha, QBlendEquationArguments::OneMinusSource1Color);
+ addTestCase<QBlendEquationArguments>(BlendEquationArgumentsMask, "destinationRgb", &QBlendEquationArguments::setDestinationRgb, QBlendEquationArguments::DestinationColor, QBlendEquationArguments::OneMinusSourceAlpha);
+ addTestCase<QBlendEquationArguments>(BlendEquationArgumentsMask, "destinationAlpha", &QBlendEquationArguments::setDestinationAlpha, QBlendEquationArguments::DestinationAlpha, QBlendEquationArguments::DestinationColor);
+ addTestCase<QBlendEquationArguments>(BlendEquationArgumentsMask, "bufferIndex", &QBlendEquationArguments::setBufferIndex, 0, 1);
+
+ addTestCase<QClipPlane>(ClipPlaneMask, "planeIndex", &QClipPlane::setPlaneIndex, 0, 1);
+ addTestCase<QClipPlane>(ClipPlaneMask, "normal", &QClipPlane::setNormal, QVector3D(0, 1, 0), QVector3D(0, 0, 1));
+ addTestCase<QClipPlane>(ClipPlaneMask, "distance", &QClipPlane::setDistance, 1.f, 2.f);
+
+ addTestCase<QColorMask>(ColorStateMask, "redMasked", &QColorMask::setRedMasked, false, true);
+ addTestCase<QColorMask>(ColorStateMask, "blueMasked", &QColorMask::setBlueMasked, false, true);
+ addTestCase<QColorMask>(ColorStateMask, "greenMasked", &QColorMask::setGreenMasked, false, true);
+ addTestCase<QColorMask>(ColorStateMask, "alphaMasked", &QColorMask::setAlphaMasked, false, true);
+
+ addTestCase<QCullFace>(CullFaceStateMask, "mode", &QCullFace::setMode, QCullFace::Back, QCullFace::FrontAndBack);
+
+ addTestCase<QFrontFace>(FrontFaceStateMask, "direction", &QFrontFace::setDirection, QFrontFace::ClockWise, QFrontFace::CounterClockWise);
+
+ addTestCase<QPointSize>(PointSizeMask, "sizeMode", &QPointSize::setSizeMode, QPointSize::Programmable, QPointSize::Fixed);
+ addTestCase<QPointSize>(PointSizeMask, "value", &QPointSize::setValue, 2.f, 4.f);
+
+ addTestCase<QPolygonOffset>(PolygonOffsetStateMask, "scaleFactor", &QPolygonOffset::setScaleFactor, 1.f, 2.f);
+ addTestCase<QPolygonOffset>(PolygonOffsetStateMask, "depthSteps", &QPolygonOffset::setDepthSteps, 1.f, 2.f);
+
+ addTestCase<QScissorTest>(ScissorStateMask, "left", &QScissorTest::setLeft, 10, 20);
+ addTestCase<QScissorTest>(ScissorStateMask, "bottom", &QScissorTest::setBottom, 10, 20);
+ addTestCase<QScissorTest>(ScissorStateMask, "width", &QScissorTest::setWidth, 10, 20);
+ addTestCase<QScissorTest>(ScissorStateMask, "height", &QScissorTest::setHeight, 10, 20);
+
+ addTestCase<QStencilMask>(StencilWriteStateMask, "frontOutputMask", &QStencilMask::setFrontOutputMask, 0x12, 0x34);
+ addTestCase<QStencilMask>(StencilWriteStateMask, "backOutputMask", &QStencilMask::setBackOutputMask, 0x12, 0x34);
+ }
+
+ void checkPropertyUpdates()
+ {
+ // GIVEN
+ QFETCH(QRenderState*, frontend1);
+ QFETCH(QRenderState*, frontend2);
+ QFETCH(quint64, mask);
+ QFETCH(QString, propertyName);
+ QFETCH(QVariant, value);
+
+ // THEN
+ RenderStateNode *backend1 = createBackendNode(frontend1);
+ RenderStateNode *backend2 = createBackendNode(frontend2);
+ QVERIFY(backend1->mask() == mask);
+ QVERIFY(backend2->mask() == mask);
+ QVERIFY(backend1->impl() != backend2->impl());
+
+ // WHEN
+ TestArbiter arbiter;
+ arbiter.setArbiterOnNode(frontend1);
+ const QMetaObject *metaObj = frontend1->metaObject();
+ const int pIndex = metaObj->indexOfProperty(propertyName.toStdString().c_str());
+ metaObj->property(pIndex).write(frontend1, value);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<QPropertyUpdatedChange>();
+ QVERIFY(change->propertyName() == propertyName);
+ QCOMPARE(change->subjectId(), frontend1->id());
+
+ // WHEN
+ backend1->sceneChangeEvent(change.staticCast<QSceneChange>());
+
+ // THEN
+ QVERIFY(backend1->impl() == backend2->impl());
+
+ arbiter.events.clear();
+ }
+
+ void checkStencilUpdates_data()
+ {
+ QTest::addColumn<QRenderState *>("frontend1");
+ QTest::addColumn<QObject *>("args1");
+ QTest::addColumn<QRenderState *>("frontend2");
+ QTest::addColumn<quint64>("mask");
+ QTest::addColumn<QString>("propertyName");
+ QTest::addColumn<QVariant>("value");
+
+ qRegisterMetaType<QStencilOperationArguments*>("QStencilOperationArguments*");
+ qRegisterMetaType<QStencilTestArguments*>("QStencilTestArguments*");
+
+ for (bool front : QVector<bool>{false, true}) {
+ const char *argsProperty = front ? "front" : "back";
+
+ addStencilTestCase<QStencilOperation, QStencilOperationArguments>(
+ StencilOpMask, argsProperty, "allTestsPassOperation",
+ &QStencilOperationArguments::setAllTestsPassOperation,
+ QStencilOperationArguments::Zero, QStencilOperationArguments::Keep);
+
+ addStencilTestCase<QStencilOperation, QStencilOperationArguments>(
+ StencilOpMask, argsProperty, "depthTestFailureOperation",
+ &QStencilOperationArguments::setDepthTestFailureOperation,
+ QStencilOperationArguments::Replace, QStencilOperationArguments::Zero);
+
+ addStencilTestCase<QStencilOperation, QStencilOperationArguments>(
+ StencilOpMask, argsProperty, "stencilTestFailureOperation",
+ &QStencilOperationArguments::setStencilTestFailureOperation,
+ QStencilOperationArguments::Increment, QStencilOperationArguments::Decrement);
+
+ addStencilTestCase<QStencilTest, QStencilTestArguments>(
+ StencilTestStateMask, argsProperty, "comparisonMask",
+ &QStencilTestArguments::setComparisonMask, 0x12, 0x34);
+
+ addStencilTestCase<QStencilTest, QStencilTestArguments>(
+ StencilTestStateMask, argsProperty, "referenceValue",
+ &QStencilTestArguments::setReferenceValue, 1, 2);
+
+ addStencilTestCase<QStencilTest, QStencilTestArguments>(
+ StencilTestStateMask, argsProperty, "stencilFunction",
+ &QStencilTestArguments::setStencilFunction,
+ QStencilTestArguments::Always, QStencilTestArguments::Equal);
+ }
+ }
+
+ void checkStencilUpdates()
+ {
+ // GIVEN
+ QFETCH(QRenderState*, frontend1);
+ QFETCH(QObject*, args1);
+ QFETCH(QRenderState*, frontend2);
+ QFETCH(quint64, mask);
+ QFETCH(QString, propertyName);
+ QFETCH(QVariant, value);
+
+ // THEN
+ RenderStateNode *backend1 = createBackendNode(frontend1);
+ RenderStateNode *backend2 = createBackendNode(frontend2);
+ QVERIFY(backend1->mask() == mask);
+ QVERIFY(backend2->mask() == mask);
+ QVERIFY(backend1->impl() != backend2->impl());
+
+ // WHEN
+ TestArbiter arbiter;
+ arbiter.setArbiterOnNode(frontend1);
+ const QMetaObject *metaObj = args1->metaObject();
+ const int pIndex = metaObj->indexOfProperty(propertyName.toStdString().c_str());
+ metaObj->property(pIndex).write(args1, value);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<QPropertyUpdatedChange>();
+ QCOMPARE(change->subjectId(), frontend1->id());
+
+ // WHEN
+ backend1->sceneChangeEvent(change.staticCast<QSceneChange>());
+
+ // THEN
+ QVERIFY(backend1->impl() == backend2->impl());
+
+ arbiter.events.clear();
+ }
+};
+
+QTEST_MAIN(tst_QRenderState)
+
+#include "tst_qrenderstate.moc"
diff --git a/tests/auto/render/qsceneloader/tst_qsceneloader.cpp b/tests/auto/render/qsceneloader/tst_qsceneloader.cpp
index 0f425b517..d5d3feec8 100644
--- a/tests/auto/render/qsceneloader/tst_qsceneloader.cpp
+++ b/tests/auto/render/qsceneloader/tst_qsceneloader.cpp
@@ -181,7 +181,7 @@ private Q_SLOTS:
// WHEN
const Qt3DRender::QSceneLoader::Status newStatus = Qt3DRender::QSceneLoader::Ready;
- valueChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ valueChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
valueChange->setPropertyName("status");
valueChange->setValue(QVariant::fromValue(newStatus));
sceneLoader->sceneChangeEvent(valueChange);
diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro
index 0af4a7b3a..7cd5317c7 100644
--- a/tests/auto/render/render.pro
+++ b/tests/auto/render/render.pro
@@ -33,6 +33,7 @@ qtConfig(private_tests) {
qenvironmentlight \
qray3d \
qrenderpassfilter \
+ qrenderstate \
qrendertargetselector \
qsortpolicy \
qrenderstateset \
diff --git a/tests/auto/render/renderviews/tst_renderviews.cpp b/tests/auto/render/renderviews/tst_renderviews.cpp
index d469298f4..2c8486ed0 100644
--- a/tests/auto/render/renderviews/tst_renderviews.cpp
+++ b/tests/auto/render/renderviews/tst_renderviews.cpp
@@ -33,6 +33,7 @@
#include <private/qframeallocator_p_p.h>
#include <private/memorybarrier_p.h>
#include <private/renderviewjobutils_p.h>
+#include <private/rendercommand_p.h>
#include <testpostmanarbiter.h>
QT_BEGIN_NAMESPACE
@@ -129,6 +130,189 @@ private Q_SLOTS:
// TO DO: Complete tests for other framegraph node types
}
+ void checkRenderCommandBackToFrontSorting()
+ {
+ // GIVEN
+ RenderView renderView;
+ QVector<RenderCommand *> rawCommands;
+ QVector<QSortPolicy::SortType> sortTypes;
+
+ sortTypes.push_back(QSortPolicy::BackToFront);
+
+ for (int i = 0; i < 200; ++i) {
+ RenderCommand *c = new RenderCommand();
+ c->m_depth = float(i);
+ rawCommands.push_back(c);
+ }
+
+ // WHEN
+ renderView.addSortType(sortTypes);
+ renderView.setCommands(rawCommands);
+ renderView.sort();
+
+ // THEN
+ const QVector<RenderCommand *> sortedCommands = renderView.commands();
+ QCOMPARE(rawCommands.size(), sortedCommands.size());
+ for (int j = 1; j < sortedCommands.size(); ++j)
+ QVERIFY(sortedCommands.at(j - 1)->m_depth > sortedCommands.at(j)->m_depth);
+
+ // RenderCommands are deleted by RenderView dtor
+ }
+
+ void checkRenderCommandMaterialSorting()
+ {
+ // GIVEN
+ RenderView renderView;
+ QVector<RenderCommand *> rawCommands;
+ QVector<QSortPolicy::SortType> sortTypes;
+
+ sortTypes.push_back(QSortPolicy::Material);
+
+ ProgramDNA dnas[5] = {
+ ProgramDNA(250),
+ ProgramDNA(500),
+ ProgramDNA(1000),
+ ProgramDNA(1500),
+ ProgramDNA(2000),
+ };
+
+ for (int i = 0; i < 20; ++i) {
+ RenderCommand *c = new RenderCommand();
+ c->m_shaderDna = dnas[i % 5];
+ rawCommands.push_back(c);
+ }
+
+ // WHEN
+ renderView.addSortType(sortTypes);
+ renderView.setCommands(rawCommands);
+ renderView.sort();
+
+ // THEN
+ const QVector<RenderCommand *> sortedCommands = renderView.commands();
+ QCOMPARE(rawCommands.size(), sortedCommands.size());
+ ProgramDNA targetDNA;
+
+ for (int j = 0; j < sortedCommands.size(); ++j) {
+
+ if (j % 4 == 0) {
+ targetDNA = sortedCommands.at(j)->m_shaderDna;
+ if (j > 0)
+ QVERIFY(targetDNA != sortedCommands.at(j - 1)->m_shaderDna);
+ }
+ QCOMPARE(targetDNA, sortedCommands.at(j)->m_shaderDna);
+ }
+
+ // RenderCommands are deleted by RenderView dtor
+ }
+
+ void checkRenderCommandStateCostSorting()
+ {
+ // GIVEN
+ RenderView renderView;
+ QVector<RenderCommand *> rawCommands;
+ QVector<QSortPolicy::SortType> sortTypes;
+
+ sortTypes.push_back(QSortPolicy::StateChangeCost);
+
+ for (int i = 0; i < 200; ++i) {
+ RenderCommand *c = new RenderCommand();
+ c->m_changeCost = i;
+ rawCommands.push_back(c);
+ }
+
+ // WHEN
+ renderView.addSortType(sortTypes);
+ renderView.setCommands(rawCommands);
+ renderView.sort();
+
+ // THEN
+ const QVector<RenderCommand *> sortedCommands = renderView.commands();
+ QCOMPARE(rawCommands.size(), sortedCommands.size());
+ for (int j = 1; j < sortedCommands.size(); ++j)
+ QVERIFY(sortedCommands.at(j - 1)->m_changeCost > sortedCommands.at(j)->m_changeCost);
+
+ // RenderCommands are deleted by RenderView dtor
+ }
+
+ void checkRenderCommandCombinedStateMaterialDepthSorting()
+ {
+ // GIVEN
+ RenderView renderView;
+ QVector<RenderCommand *> rawCommands;
+ QVector<QSortPolicy::SortType> sortTypes;
+
+ sortTypes.push_back(QSortPolicy::StateChangeCost);
+ sortTypes.push_back(QSortPolicy::Material);
+ sortTypes.push_back(QSortPolicy::BackToFront);
+
+ ProgramDNA dna[4] = {
+ ProgramDNA(250),
+ ProgramDNA(500),
+ ProgramDNA(1000),
+ ProgramDNA(1500)
+ };
+
+ float depth[3] = {
+ 10.0f,
+ 25.0f,
+ 30.0f
+ };
+
+ int stateChangeCost[2] = {
+ 100,
+ 200
+ };
+
+ auto buildRC = [] (ProgramDNA dna, float depth, int changeCost) {
+ RenderCommand *c = new RenderCommand();
+ c->m_shaderDna = dna;
+ c->m_depth = depth;
+ c->m_changeCost = changeCost;
+ return c;
+ };
+
+ RenderCommand *c5 = buildRC(dna[3], depth[1], stateChangeCost[1]);
+ RenderCommand *c3 = buildRC(dna[3], depth[0], stateChangeCost[1]);
+ RenderCommand *c4 = buildRC(dna[2], depth[1], stateChangeCost[1]);
+ RenderCommand *c8 = buildRC(dna[1], depth[1], stateChangeCost[1]);
+ RenderCommand *c0 = buildRC(dna[0], depth[2], stateChangeCost[1]);
+
+ RenderCommand *c2 = buildRC(dna[2], depth[2], stateChangeCost[0]);
+ RenderCommand *c9 = buildRC(dna[2], depth[0], stateChangeCost[0]);
+ RenderCommand *c1 = buildRC(dna[1], depth[0], stateChangeCost[0]);
+ RenderCommand *c7 = buildRC(dna[0], depth[2], stateChangeCost[0]);
+ RenderCommand *c6 = buildRC(dna[0], depth[1], stateChangeCost[0]);
+
+ rawCommands << c0 << c1 << c2 << c3 << c4 << c5 << c6 << c7 << c8 << c9;
+
+ // WHEN
+ renderView.addSortType(sortTypes);
+ renderView.setCommands(rawCommands);
+ renderView.sort();
+
+ // THEN
+ const QVector<RenderCommand *> sortedCommands = renderView.commands();
+ QCOMPARE(rawCommands.size(), sortedCommands.size());
+
+ for (RenderCommand *rc : sortedCommands)
+ qDebug() << rc->m_changeCost << rc->m_shaderDna << rc->m_depth;
+
+ // Ordered by higher state, higher shaderDNA and higher depth
+ QCOMPARE(c0, sortedCommands.at(4));
+ QCOMPARE(c3, sortedCommands.at(1));
+ QCOMPARE(c4, sortedCommands.at(2));
+ QCOMPARE(c5, sortedCommands.at(0));
+ QCOMPARE(c8, sortedCommands.at(3));
+
+ QCOMPARE(c1, sortedCommands.at(7));
+ QCOMPARE(c2, sortedCommands.at(5));
+ QCOMPARE(c6, sortedCommands.at(9));
+ QCOMPARE(c7, sortedCommands.at(8));
+ QCOMPARE(c9, sortedCommands.at(6));
+
+ // RenderCommands are deleted by RenderView dtor
+ }
+
private:
};
@@ -138,7 +322,7 @@ private:
QT_END_NAMESPACE
-
-QTEST_APPLESS_MAIN(Qt3DRender::Render::tst_RenderViews)
+//APPLESS_
+QTEST_MAIN(Qt3DRender::Render::tst_RenderViews)
#include "tst_renderviews.moc"
diff --git a/tests/auto/render/sceneloader/tst_sceneloader.cpp b/tests/auto/render/sceneloader/tst_sceneloader.cpp
index 975c2c892..9aac50c73 100644
--- a/tests/auto/render/sceneloader/tst_sceneloader.cpp
+++ b/tests/auto/render/sceneloader/tst_sceneloader.cpp
@@ -119,7 +119,7 @@ private Q_SLOTS:
QVERIFY(!sceneManager.pendingSceneLoaderJobs().isEmpty());
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(false);
updateChange->setPropertyName("enabled");
sceneLoader.sceneChangeEvent(updateChange);
diff --git a/tests/auto/render/texture/tst_texture.cpp b/tests/auto/render/texture/tst_texture.cpp
index 6019b129c..784186690 100644
--- a/tests/auto/render/texture/tst_texture.cpp
+++ b/tests/auto/render/texture/tst_texture.cpp
@@ -227,7 +227,7 @@ void tst_RenderTexture::checkPropertyChanges()
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(128);
updateChange->setPropertyName("height");
backend.sceneChangeEvent(updateChange);
@@ -238,7 +238,7 @@ void tst_RenderTexture::checkPropertyChanges()
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(16);
updateChange->setPropertyName("depth");
backend.sceneChangeEvent(updateChange);
@@ -249,7 +249,7 @@ void tst_RenderTexture::checkPropertyChanges()
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(32);
updateChange->setPropertyName("layers");
backend.sceneChangeEvent(updateChange);
@@ -260,7 +260,7 @@ void tst_RenderTexture::checkPropertyChanges()
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
- updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId()));
+ updateChange = QSharedPointer<Qt3DCore::QPropertyUpdatedChange>::create(Qt3DCore::QNodeId());
updateChange->setValue(64);
updateChange->setPropertyName("samples");
backend.sceneChangeEvent(updateChange);
diff --git a/tests/auto/render/vsyncframeadvanceservice/tst_vsyncframeadvanceservice.cpp b/tests/auto/render/vsyncframeadvanceservice/tst_vsyncframeadvanceservice.cpp
index 3d873258f..6f455ea56 100644
--- a/tests/auto/render/vsyncframeadvanceservice/tst_vsyncframeadvanceservice.cpp
+++ b/tests/auto/render/vsyncframeadvanceservice/tst_vsyncframeadvanceservice.cpp
@@ -50,6 +50,63 @@ private:
Qt3DRender::Render::VSyncFrameAdvanceService *m_tickService;
};
+class FakeAspectThread Q_DECL_FINAL : public QThread
+{
+public:
+ FakeAspectThread(Qt3DRender::Render::VSyncFrameAdvanceService *tickService)
+ : m_tickService(tickService)
+ , m_count(0)
+ , m_running(true)
+ , m_waitForStarted(0)
+ {
+ }
+
+ int count() const { return m_count; }
+
+ void stopRunning()
+ {
+ QMutexLocker lock(&m_mutex);
+ m_running = false;
+ }
+
+ void waitForStarted()
+ {
+ m_waitForStarted.acquire(1);
+ }
+
+protected:
+ // QThread interface
+ void run() Q_DECL_FINAL
+ {
+ m_waitForStarted.release(1);
+ while (true) {
+
+ bool running = true;
+ {
+ QMutexLocker lock(&m_mutex);
+ running = m_running;
+ }
+
+ if (!running) {
+ qDebug() << "exiting";
+ return;
+ }
+
+ m_tickService->waitForNextFrame();
+ ++m_count;
+
+ QThread::msleep(100);
+ }
+ }
+
+private:
+ Qt3DRender::Render::VSyncFrameAdvanceService *m_tickService;
+ int m_count;
+ bool m_running;
+ QMutex m_mutex;
+ QSemaphore m_waitForStarted;
+};
+
class tst_VSyncFrameAdvanceService : public QObject
{
Q_OBJECT
@@ -59,7 +116,7 @@ private Q_SLOTS:
void checkSynchronisation()
{
// GIVEN
- Qt3DRender::Render::VSyncFrameAdvanceService tickService;
+ Qt3DRender::Render::VSyncFrameAdvanceService tickService(true);
FakeRenderThread renderThread(&tickService);
QElapsedTimer t;
@@ -74,6 +131,31 @@ private Q_SLOTS:
QVERIFY(t.elapsed() >= 950);
}
+ void checkWaitForNextFrame()
+ {
+ // GIVEN
+ Qt3DRender::Render::VSyncFrameAdvanceService tickService(false);
+ FakeAspectThread aspectThread(&tickService);
+
+ // WHEN
+ aspectThread.start();
+ aspectThread.waitForStarted();
+
+ QElapsedTimer t;
+ t.start();
+
+ while (t.elapsed() < 1000)
+ tickService.proceedToNextFrame();
+
+ aspectThread.stopRunning();
+
+ // To make sure the aspectThread can finish
+ tickService.proceedToNextFrame();
+ aspectThread.wait();
+
+ // THEN
+ QCOMPARE(aspectThread.count(), 10);
+ }
};
QTEST_MAIN(tst_VSyncFrameAdvanceService)
diff --git a/tests/manual/deferred-renderer-qml/SceneEffect.qml b/tests/manual/deferred-renderer-qml/SceneEffect.qml
index 3ec1983fe..0ca081355 100644
--- a/tests/manual/deferred-renderer-qml/SceneEffect.qml
+++ b/tests/manual/deferred-renderer-qml/SceneEffect.qml
@@ -72,15 +72,15 @@ Effect {
out vec3 normal0;
uniform mat4 mvp;
- uniform mat4 modelView;
- uniform mat3 modelViewNormal;
+ uniform mat4 modelMatrix;
+ uniform mat3 modelNormalMatrix;
uniform vec4 meshColor;
void main()
{
color0 = meshColor;
- position0 = vec3(modelView * vertexPosition);
- normal0 = normalize(modelViewNormal * vertexNormal);
+ position0 = vec3(modelMatrix * vertexPosition);
+ normal0 = normalize(modelNormalMatrix * vertexNormal);
gl_Position = mvp * vertexPosition;
}
"
@@ -123,15 +123,15 @@ Effect {
varying vec3 normal0;
uniform mat4 mvp;
- uniform mat4 modelView;
- uniform mat3 modelViewNormal;
+ uniform mat4 modelMatrix;
+ uniform mat3 modelNormalMatrix;
uniform vec4 meshColor;
void main()
{
color0 = meshColor;
- position0 = vec3(modelView * vertexPosition);
- normal0 = normalize(modelViewNormal * vertexNormal);
+ position0 = vec3(modelMatrix * vertexPosition);
+ normal0 = normalize(modelNormalMatrix * vertexNormal);
gl_Position = mvp * vertexPosition;
}
"
diff --git a/tests/manual/deferred-renderer-qml/SceneEntity.qml b/tests/manual/deferred-renderer-qml/SceneEntity.qml
index 001a24854..6a34be7fb 100644
--- a/tests/manual/deferred-renderer-qml/SceneEntity.qml
+++ b/tests/manual/deferred-renderer-qml/SceneEntity.qml
@@ -48,15 +48,26 @@ Entity {
readonly property Camera camera: camera
readonly property Layer layer: sceneLayer
+ readonly property vector3d light1Pos : sphere1.transform.translation
+ readonly property vector3d light2Pos : sphere2.transform.translation
+ readonly property vector3d light3Pos : light3Transform.translation
+ readonly property vector3d light4Pos : Qt.vector3d(5, 2, 7)
+
property PointLight light: PointLight {
color : "white"
- intensity : 4.0
+ intensity : 0.0
QQ2.ColorAnimation on color { from: "white"; to: "blue"; duration: 4000; loops: 2 }
- QQ2.NumberAnimation on intensity { from: 0; to: 5.0; duration: 1000; loops: QQ2.Animation.Infinite }
+ QQ2.SequentialAnimation on intensity {
+ QQ2.NumberAnimation {
+ from: 0; to: 3.0; duration: 500
+ }
+ QQ2.NumberAnimation {
+ from: 3.0; to: 0.0; duration: 500
+ }
+ loops: QQ2.Animation.Infinite
+ }
}
- components: [ root.light ]
-
// Global elements
Camera {
id: camera
@@ -97,21 +108,15 @@ Entity {
QQ2.SequentialAnimation {
loops: QQ2.Animation.Infinite
- running: false
- QQ2.NumberAnimation { target: sphere1Transform; property: "x"; to: 6; duration: 2000 }
- QQ2.NumberAnimation { target: sphere1Transform; property: "x"; to: -10; duration: 2000 }
- }
-
- property PointLight light : PointLight {
- color : "green"
- intensity : 0.3
+ running: true
+ QQ2.NumberAnimation { target: sphere1Transform; property: "x"; to: 3; duration: 2000 }
+ QQ2.NumberAnimation { target: sphere1Transform; property: "x"; to: -5; duration: 2000 }
}
components : [
sphereMesh,
sphere1.material,
sphere1.transform,
- sphere1.light,
sceneLayer
]
}
@@ -124,11 +129,6 @@ Entity {
parameters : Parameter { name : "meshColor"; value : "green" }
}
- property PointLight light : PointLight {
- color : "orange"
- intensity : 0.7
- }
-
property Transform transform: Transform {
translation: Qt.vector3d(5, 0, 5)
}
@@ -137,17 +137,12 @@ Entity {
sphereMesh,
sphere2.transform,
sphere2.material,
- sphere2.light,
sceneLayer
]
}
Entity {
id: light3
- property PointLight light : PointLight {
- color : "white"
- intensity : 0.5
- }
property Material material : Material {
effect : sceneMaterialEffect
@@ -170,26 +165,8 @@ Entity {
components: [
sphereMesh,
light3.material,
- light3.light,
light3.transform,
sceneLayer
]
}
-
- Entity {
- id: light4
- property PointLight light : PointLight {
- color : "white"
- intensity : 0.2
- }
- property Transform transform: Transform {
- translation: Qt.vector3d(5, 2, 7)
- }
-
- components: [
- light4.light,
- light4.transform,
- sceneLayer
- ]
- }
}
diff --git a/tests/manual/deferred-renderer-qml/ScreenQuadEntity.qml b/tests/manual/deferred-renderer-qml/ScreenQuadEntity.qml
index 6c5284d5e..3dae2b79a 100644
--- a/tests/manual/deferred-renderer-qml/ScreenQuadEntity.qml
+++ b/tests/manual/deferred-renderer-qml/ScreenQuadEntity.qml
@@ -42,23 +42,95 @@ import Qt3D.Render 2.0
import Qt3D.Extras 2.0
Entity {
+ id: root
+
readonly property Layer layer: screenQuadLayer
+ property PointLight baseLight
+ property vector3d light1Pos
+ property vector3d light2Pos
+ property vector3d light3Pos
+ property vector3d light4Pos
- components : [
- Layer { id: screenQuadLayer },
+ Entity {
+ components: [
+ baseLight,
+ layer
+ ]
+ }
- PlaneMesh {
- width: 2.0
- height: 2.0
- meshResolution: Qt.size(2, 2)
- },
+ Entity {
+ readonly property Transform transform1 : Transform { translation: root.light1Pos }
+ readonly property PointLight light1 : PointLight {
+ color : "dodgerblue"
+ intensity : 0.9
+ }
+ components: [
+ transform1,
+ light1,
+ layer
+ ]
+ }
- Transform { // We rotate the plane so that it faces us
- rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 90)
- },
+ Entity {
+ readonly property Transform transform2 : Transform { translation: root.light2Pos }
+ readonly property PointLight light2 : PointLight {
+ color : "green"
+ intensity : 0.5
+ }
+ components: [
+ transform2,
+ light2,
+ layer
+ ]
+ }
+
+ Entity {
+ readonly property Transform transform3 : Transform { translation: root.light3Pos }
+ readonly property PointLight light3 : PointLight {
+ color : "white"
+ intensity : 2.0
+ }
+ components: [
+ transform3,
+ light3,
+ layer
+ ]
+ }
- Material {
- effect : FinalEffect {}
+ Entity {
+ readonly property Transform transform4 : Transform { translation: root.light4Pos }
+ readonly property PointLight light4 : PointLight {
+ color : "white"
+ intensity : 0.5
}
- ]
+ components: [
+ transform4,
+ light4,
+ layer
+ ]
+ }
+
+ // We need to have the actual screen quad entity separate from the lights.
+ // If the lights were sub-entities of this screen quad entity, they would
+ // be affected by the rotation matrix, and their world positions would thus
+ // be changed.
+ Entity {
+ components : [
+ Layer { id: screenQuadLayer },
+
+ PlaneMesh {
+ width: 2.0
+ height: 2.0
+ meshResolution: Qt.size(2, 2)
+ },
+
+ Transform { // We rotate the plane so that it faces us
+ rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 90)
+ },
+
+ Material {
+ effect : FinalEffect {}
+ }
+ ]
+ }
}
diff --git a/tests/manual/deferred-renderer-qml/deferred-renderer-qml.pro b/tests/manual/deferred-renderer-qml/deferred-renderer-qml.pro
index 8f7dc12d5..8db1d6dcf 100644
--- a/tests/manual/deferred-renderer-qml/deferred-renderer-qml.pro
+++ b/tests/manual/deferred-renderer-qml/deferred-renderer-qml.pro
@@ -12,6 +12,8 @@ OTHER_FILES += \
DeferredRenderer.qml \
FinalEffect.qml \
SceneEffect.qml \
+ SceneEntity.qml \
+ ScreenQuadEntity.qml \
GBuffer.qml
RESOURCES += \
diff --git a/tests/manual/deferred-renderer-qml/main.qml b/tests/manual/deferred-renderer-qml/main.qml
index 790911723..8b97bb671 100644
--- a/tests/manual/deferred-renderer-qml/main.qml
+++ b/tests/manual/deferred-renderer-qml/main.qml
@@ -74,7 +74,14 @@ Entity {
FirstPersonCameraController { camera: sceneEntity.camera }
- ScreenQuadEntity { id: screenQuadEntity }
+ ScreenQuadEntity {
+ id: screenQuadEntity
+ baseLight: sceneEntity.light
+ light1Pos: sceneEntity.light1Pos
+ light2Pos: sceneEntity.light2Pos
+ light3Pos: sceneEntity.light3Pos
+ light4Pos: sceneEntity.light4Pos
+ }
SceneEntity { id: sceneEntity }
GBufferDebugger { id: debugEntity }
}
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index 7c6d2390b..8501a41af 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -53,7 +53,8 @@ SUBDIRS += \
animation-keyframe-programmatic \
layerfilter-qml \
skinned-mesh \
- proximityfilter
+ proximityfilter \
+ rendercapture-qml-fbo
qtHaveModule(widgets): {
SUBDIRS += \
diff --git a/tests/manual/rendercapture-qml-fbo/CaptureScene.qml b/tests/manual/rendercapture-qml-fbo/CaptureScene.qml
new file mode 100644
index 000000000..9c6cb1431
--- /dev/null
+++ b/tests/manual/rendercapture-qml-fbo/CaptureScene.qml
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2 as QQ2
+import Qt3D.Core 2.0
+import Qt3D.Render 2.1
+import Qt3D.Input 2.0
+import Qt3D.Extras 2.0
+
+Entity {
+ id: sceneRoot
+
+ function requestRenderCapture()
+ {
+ return renderCapture.requestCapture()
+ }
+
+ Camera {
+ id: camera
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 45
+ aspectRatio: 1
+ nearPlane : 0.1
+ farPlane : 1000.0
+ position: Qt.vector3d(100.0, 100.0, 20.0)
+ upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
+ viewCenter: Qt.vector3d(0.0, 0.0, -8.0)
+ }
+
+ Camera {
+ id: camera2
+ projectionType: CameraLens.PerspectiveProjection
+ fieldOfView: 15
+ aspectRatio: 1
+ nearPlane : 0.1
+ farPlane : 1000.0
+ position: Qt.vector3d( 0.0, 0.0, -40.0 )
+ upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
+ viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
+ }
+
+ OrbitCameraController {
+ camera: camera
+ }
+
+ components: [
+ RenderSettings {
+ activeFrameGraph: RenderSurfaceSelector {
+ Viewport {
+ normalizedRect: Qt.rect(0, 0, 1, 1)
+
+ // Clear Back Buffer
+ ClearBuffers {
+ buffers: ClearBuffers.ColorDepthBuffer
+ clearColor: Qt.rgba(0, 0.5, 1, 1)
+ NoDraw { }
+ }
+
+ // Render to back buffer
+ CameraSelector {
+ camera: camera
+ }
+
+ // FBO
+ RenderTargetSelector {
+ target: RenderTarget {
+ attachments: [
+ RenderTargetOutput {
+ attachmentPoint: RenderTargetOutput.Color0
+ texture: Texture2D {
+ id: colorTexture
+ width: 400
+ height: 400
+ format: Texture.RGBAFormat
+ generateMipMaps: false
+ magnificationFilter: Texture.Linear
+ minificationFilter: Texture.Linear
+ wrapMode {
+ x: WrapMode.ClampToEdge
+ y: WrapMode.ClampToEdge
+ }
+ }
+ }
+ ]
+ }
+ // Clear FBO
+ ClearBuffers {
+ buffers: ClearBuffers.ColorDepthBuffer
+ clearColor: Qt.rgba(0, 0.5, 0.5, 1)
+ NoDraw { }
+ }
+
+ // Render into FBO
+ CameraSelector {
+ camera: camera
+ // Render Capture
+ RenderCapture {
+ id: renderCapture
+ }
+ }
+ }
+ }
+ }
+ },
+ // Event Source will be set by the Qt3DQuickWindow
+ InputSettings { }
+ ]
+
+ PhongMaterial {
+ id: material
+ }
+
+ TorusMesh {
+ id: torusMesh
+ radius: 5
+ minorRadius: 1
+ rings: 100
+ slices: 20
+ }
+
+ Transform {
+ id: torusTransform
+ scale3D: Qt.vector3d(1.5, 1, 0.5)
+ rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45)
+ }
+
+ Entity {
+ id: torusEntity
+ components: [ torusMesh, material, torusTransform ]
+ }
+
+ SphereMesh {
+ id: sphereMesh
+ radius: 3
+ }
+
+ Transform {
+ id: sphereTransform
+ property real userAngle: 0.0
+ matrix: {
+ var m = Qt.matrix4x4();
+ m.rotate(userAngle, Qt.vector3d(0, 1, 0));
+ m.translate(Qt.vector3d(20, 0, 0));
+ return m;
+ }
+ }
+
+ QQ2.NumberAnimation {
+ target: sphereTransform
+ property: "userAngle"
+ duration: 10000
+ from: 0
+ to: 360
+
+ loops: QQ2.Animation.Infinite
+ running: true
+ }
+
+ Entity {
+ id: sphereEntity
+ components: [ sphereMesh, material, sphereTransform ]
+ }
+}
diff --git a/tests/manual/rendercapture-qml-fbo/main.cpp b/tests/manual/rendercapture-qml-fbo/main.cpp
new file mode 100644
index 000000000..5c581c88e
--- /dev/null
+++ b/tests/manual/rendercapture-qml-fbo/main.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QQuickItem>
+#include <QQuickView>
+#include <Qt3DQuick/QQmlAspectEngine>
+#include <QGuiApplication>
+#include <QQmlEngine>
+#include <QQmlContext>
+#include "rendercaptureprovider.h"
+
+
+int main(int argc, char* argv[])
+{
+ QGuiApplication app(argc, argv);
+ QQuickView view;
+ RenderCaptureProvider *provider = new RenderCaptureProvider;
+ qmlRegisterType<RenderCaptureProvider>("Extras", 1, 0, "RenderCaptureProvider");
+
+ view.engine()->rootContext()->setContextProperty("_renderCaptureProvider", provider);
+ view.engine()->addImageProvider("rendercapture", provider);
+
+ view.setSource(QUrl("qrc:/main.qml"));
+ view.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/rendercapture-qml-fbo/main.qml b/tests/manual/rendercapture-qml-fbo/main.qml
new file mode 100644
index 000000000..49ccbf7ea
--- /dev/null
+++ b/tests/manual/rendercapture-qml-fbo/main.qml
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.0
+import Qt3D.Render 2.1
+import QtQuick.Scene3D 2.0
+
+Item {
+
+ width: 1250
+ height: 700
+
+ RowLayout {
+ anchors.fill: parent
+ anchors.margins: 10
+
+ Rectangle {
+ id: background
+ width: 600
+ height: 600
+
+ color: "blue"
+
+ Scene3D {
+ id: scene3d
+ anchors.fill: parent
+ multisample: msacheckbox.checked
+
+ aspects: ["input", "logic"]
+
+ CaptureScene {
+ id: scene
+ }
+ }
+ }
+
+ ColumnLayout {
+
+ Button {
+ id: button
+ anchors.top: parent.top
+ text: "Render Capture"
+
+ property var reply
+ property bool continuous : checkbox.checked
+ property int cid: 1
+
+ function doRenderCapture()
+ {
+ reply = scene.requestRenderCapture()
+ reply.completeChanged.connect(onRenderCaptureComplete)
+ }
+
+ function onRenderCaptureComplete()
+ {
+ _renderCaptureProvider.updateImage(reply)
+ image.source = "image://rendercapture/" + cid
+ reply.saveImage("capture.png")
+ cid++
+ if (continuous === true)
+ doRenderCapture()
+ }
+
+ onClicked: doRenderCapture()
+ }
+ RowLayout {
+ CheckBox {
+ id: checkbox
+ text: "continuous"
+ }
+ CheckBox {
+ id: msacheckbox
+ text: "multisample"
+ }
+ }
+ Image {
+ id: image
+ cache: false
+ source: "image://rendercapture/0"
+ Layout.maximumWidth: 600
+ Layout.minimumWidth: 600
+ Layout.maximumHeight: 600
+ Layout.minimumHeight: 600
+ }
+ }
+ }
+}
diff --git a/tests/manual/rendercapture-qml-fbo/qml.qrc b/tests/manual/rendercapture-qml-fbo/qml.qrc
new file mode 100644
index 000000000..310d6dfe3
--- /dev/null
+++ b/tests/manual/rendercapture-qml-fbo/qml.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>CaptureScene.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/rendercapture-qml-fbo/rendercapture-qml-fbo.pro b/tests/manual/rendercapture-qml-fbo/rendercapture-qml-fbo.pro
new file mode 100644
index 000000000..bea0fc867
--- /dev/null
+++ b/tests/manual/rendercapture-qml-fbo/rendercapture-qml-fbo.pro
@@ -0,0 +1,18 @@
+!include( ../manual.pri ) {
+ error( "Couldn't find the manual.pri file!" )
+}
+
+QT += 3dcore 3drender 3dinput 3dextras 3dquick 3dlogic qml quick 3dquickextras
+
+SOURCES += \
+ main.cpp
+
+DISTFILES += \
+ main.qml
+
+RESOURCES += \
+ qml.qrc
+
+HEADERS += \
+ rendercaptureprovider.h
+
diff --git a/tests/manual/rendercapture-qml-fbo/rendercaptureprovider.h b/tests/manual/rendercapture-qml-fbo/rendercaptureprovider.h
new file mode 100644
index 000000000..d04dbd276
--- /dev/null
+++ b/tests/manual/rendercapture-qml-fbo/rendercaptureprovider.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
+** 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$
+**
+****************************************************************************/
+
+#ifndef RENDERCAPTUREPROVIDER_H
+#define RENDERCAPTUREPROVIDER_H
+
+#include <QtQuick/QQuickImageProvider>
+#include <Qt3DRender/QRenderCapture>
+
+class RenderCaptureProvider : public QObject, public QQuickImageProvider
+{
+ Q_OBJECT
+public:
+ RenderCaptureProvider()
+ : QObject(), QQuickImageProvider(Image)
+ {
+ m_image = QImage(10,10, QImage::Format_ARGB32);
+ m_image.fill(QColor("blue").rgba());
+ }
+
+ Q_INVOKABLE void updateImage(Qt3DRender::QRenderCaptureReply *reply)
+ {
+ m_image = reply->image();
+ }
+
+ virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
+ {
+ Q_UNUSED(id)
+ Q_UNUSED(requestedSize)
+ *size = m_image.size();
+ return m_image;
+ }
+
+private:
+ QImage m_image;
+};
+
+#endif