diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-12-13 10:46:43 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-12-13 10:47:04 +0100 |
commit | bfb58a7fff934fde6f4c2b4c989f411b43aee8d9 (patch) | |
tree | 432201a0c7fb6c49d7835f728fc0da97d8742b39 /src | |
parent | f660c657092811e77aa0ffb8145d6b060464292c (diff) | |
parent | d69e2c2b42719e6839f32e8ab796cf22d9f29bfa (diff) |
Merge remote-tracking branch 'origin/5.10' into dev
Change-Id: Ib51c8311ce78b2fec62dd0c09cb943a85a7d0b2b
Diffstat (limited to 'src')
64 files changed, 708 insertions, 155 deletions
diff --git a/src/animation/backend/evaluateblendclipanimatorjob.cpp b/src/animation/backend/evaluateblendclipanimatorjob.cpp index 3cde7b32f..abd50f174 100644 --- a/src/animation/backend/evaluateblendclipanimatorjob.cpp +++ b/src/animation/backend/evaluateblendclipanimatorjob.cpp @@ -51,8 +51,6 @@ namespace Animation { EvaluateBlendClipAnimatorJob::EvaluateBlendClipAnimatorJob() : Qt3DCore::QAspectJob() - , m_currentGlobalTime(0.0) - , m_lastGlobalTime(0.0) { SET_JOB_RUN_STAT_TYPE(this, JobTypes::EvaluateBlendClipAnimator, 0); } diff --git a/src/animation/backend/evaluateblendclipanimatorjob_p.h b/src/animation/backend/evaluateblendclipanimatorjob_p.h index 6ef3b93cf..7548168e9 100644 --- a/src/animation/backend/evaluateblendclipanimatorjob_p.h +++ b/src/animation/backend/evaluateblendclipanimatorjob_p.h @@ -78,9 +78,6 @@ protected: private: HBlendedClipAnimator m_blendClipAnimatorHandle; Handler *m_handler; - - qint64 m_currentGlobalTime; - qint64 m_lastGlobalTime; }; typedef QSharedPointer<EvaluateBlendClipAnimatorJob> EvaluateBlendClipAnimatorJobPtr; diff --git a/src/animation/backend/evaluateclipanimatorjob.cpp b/src/animation/backend/evaluateclipanimatorjob.cpp index 972762033..90999fd64 100644 --- a/src/animation/backend/evaluateclipanimatorjob.cpp +++ b/src/animation/backend/evaluateclipanimatorjob.cpp @@ -48,8 +48,6 @@ namespace Animation { EvaluateClipAnimatorJob::EvaluateClipAnimatorJob() : Qt3DCore::QAspectJob() - , m_currentGlobalTime(0.0) - , m_lastGlobalTime(0.0) { SET_JOB_RUN_STAT_TYPE(this, JobTypes::EvaluateClipAnimator, 0); } diff --git a/src/animation/backend/evaluateclipanimatorjob_p.h b/src/animation/backend/evaluateclipanimatorjob_p.h index 389d12456..c9b1a8f96 100644 --- a/src/animation/backend/evaluateclipanimatorjob_p.h +++ b/src/animation/backend/evaluateclipanimatorjob_p.h @@ -82,9 +82,6 @@ protected: private: HClipAnimator m_clipAnimatorHandle; Handler *m_handler; - - qint64 m_currentGlobalTime; - qint64 m_lastGlobalTime; }; } // namespace Animation diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp index 78ad01508..9cdffee92 100644 --- a/src/animation/frontend/qabstractclipanimator.cpp +++ b/src/animation/frontend/qabstractclipanimator.cpp @@ -41,6 +41,7 @@ #include "qabstractclipanimator_p.h" #include <Qt3DAnimation/qchannelmapper.h> #include <Qt3DAnimation/qclock.h> +#include <Qt3DAnimation/private/qanimationcallbacktrigger_p.h> QT_BEGIN_NAMESPACE @@ -116,6 +117,18 @@ QAbstractClipAnimator::QAbstractClipAnimator(QAbstractClipAnimatorPrivate &dd, Q { } +/*! \internal */ +void QAbstractClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) +{ + if (change->type() == Qt3DCore::CallbackTriggered) { + QAnimationCallbackTriggerPtr callbackTrigger = qSharedPointerCast<Qt3DAnimation::QAnimationCallbackTrigger>(change); + if (callbackTrigger->callback()) + callbackTrigger->callback()->valueChanged(callbackTrigger->value()); + } else { + QComponent::sceneChangeEvent(change); + } +} + QAbstractClipAnimator::~QAbstractClipAnimator() { } diff --git a/src/animation/frontend/qabstractclipanimator.h b/src/animation/frontend/qabstractclipanimator.h index 8fdb114f3..9e8d3c457 100644 --- a/src/animation/frontend/qabstractclipanimator.h +++ b/src/animation/frontend/qabstractclipanimator.h @@ -90,6 +90,8 @@ protected: explicit QAbstractClipAnimator(Qt3DCore::QNode *parent = nullptr); QAbstractClipAnimator(QAbstractClipAnimatorPrivate &dd, Qt3DCore::QNode *parent = nullptr); + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; + private: Q_DECLARE_PRIVATE(QAbstractClipAnimator) }; diff --git a/src/animation/frontend/qclipanimator.cpp b/src/animation/frontend/qclipanimator.cpp index 6b503e87f..5383e2c9b 100644 --- a/src/animation/frontend/qclipanimator.cpp +++ b/src/animation/frontend/qclipanimator.cpp @@ -42,7 +42,6 @@ #include <Qt3DAnimation/qabstractanimationclip.h> #include <Qt3DAnimation/qchannelmapper.h> #include <Qt3DAnimation/qclock.h> -#include <Qt3DAnimation/private/qanimationcallbacktrigger_p.h> QT_BEGIN_NAMESPACE @@ -167,18 +166,6 @@ Qt3DCore::QNodeCreatedChangeBasePtr QClipAnimator::createNodeCreationChange() co return creationChange; } -/*! \internal */ -void QClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) -{ - if (change->type() == Qt3DCore::CallbackTriggered) { - QAnimationCallbackTriggerPtr callbackTrigger = qSharedPointerCast<Qt3DAnimation::QAnimationCallbackTrigger>(change); - if (callbackTrigger->callback()) - callbackTrigger->callback()->valueChanged(callbackTrigger->value()); - } else if (change->type() == Qt3DCore::PropertyUpdated) { - QAbstractClipAnimator::sceneChangeEvent(change); - } -} - } // namespace Qt3DAnimation QT_END_NAMESPACE diff --git a/src/animation/frontend/qclipanimator.h b/src/animation/frontend/qclipanimator.h index dee544831..72f1ba95f 100644 --- a/src/animation/frontend/qclipanimator.h +++ b/src/animation/frontend/qclipanimator.h @@ -70,7 +70,6 @@ Q_SIGNALS: protected: QClipAnimator(QClipAnimatorPrivate &dd, Qt3DCore::QNode *parent = nullptr); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; private: Q_DECLARE_PRIVATE(QClipAnimator) diff --git a/src/core/changes/qnodecommand.cpp b/src/core/changes/qnodecommand.cpp index ae5ae46f1..8222ada4d 100644 --- a/src/core/changes/qnodecommand.cpp +++ b/src/core/changes/qnodecommand.cpp @@ -65,7 +65,7 @@ QNodeCommand::CommandId QNodeCommandPrivate::createId() * \inheaderfile Qt3DCore/QNodeCommand * \inherits Qt3DCore::QSceneChange * \inmodule Qt3DCore - * \since 5.9 + * \since 5.10 * \brief The QNodeCommand class is the base class for all CommandRequested QSceneChange events * * The QNodeCommand class is the base class for all QSceneChange events that diff --git a/src/doc/src/qt3dextras-module.qdoc b/src/doc/src/qt3dextras-module.qdoc index 087018139..b9a7cc28a 100644 --- a/src/doc/src/qt3dextras-module.qdoc +++ b/src/doc/src/qt3dextras-module.qdoc @@ -67,41 +67,15 @@ \section2 Materials - \list - \li Qt3DExtras::QDiffuseMapMaterial - \li Qt3DExtras::QDiffuseSpecularMapMaterial - \li Qt3DExtras::QGoochMaterial - \li Qt3DExtras::QNormalDiffuseMapMaterial - \li Qt3DExtras::QNormalDiffuseMapAlphaMaterial - \li Qt3DExtras::QNormalDiffuseSpecularMapMaterial - \li Qt3DExtras::QPerVertexColorMaterial - \li Qt3DExtras::QPhongMaterial - \li Qt3DExtras::QPhongAlphaMaterial - \endlist + \annotatedlist qt3d-extras-materials \section2 Meshes and Geometries - \list - \li Qt3DExtras::QConeGeometry - \li Qt3DExtras::QConeMesh - \li Qt3DExtras::QCuboidGeometry - \li Qt3DExtras::QCuboidMesh - \li Qt3DExtras::QCylinderGeometry - \li Qt3DExtras::QCylinderMesh - \li Qt3DExtras::QPlaneGeometry - \li Qt3DExtras::QPlaneMesh - \li Qt3DExtras::QSphereGeometry - \li Qt3DExtras::QSphereMesh - \li Qt3DExtras::QTorusGeometry - \li Qt3DExtras::QTorusMesh - \endlist + \annotatedlist qt3d-extras-geometries \section2 Camera Controllers - \list - \li Qt3DExtras::QFirstPersonCameraController - \li Qt3DExtras::QOrbitCameraController - \endlist + \annotatedlist qt3d-extras-cameracontrollers \section2 Entities diff --git a/src/extras/defaults/qdiffusemapmaterial.cpp b/src/extras/defaults/qdiffusemapmaterial.cpp index 26fb99c2c..d5e729b8e 100644 --- a/src/extras/defaults/qdiffusemapmaterial.cpp +++ b/src/extras/defaults/qdiffusemapmaterial.cpp @@ -202,7 +202,7 @@ void QDiffuseMapMaterialPrivate::handleTextureScaleChanged(const QVariant &var) \inherits Qt3DRender::QMaterial \deprecated - \see Qt3DExtras::QDiffuseSpecularMaterial + This class is deprecated; use Qt3DExtras::QDiffuseSpecularMaterial instead. The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular. The relative strengths of these components are controlled by means of diff --git a/src/extras/defaults/qdiffusespecularmapmaterial.cpp b/src/extras/defaults/qdiffusespecularmapmaterial.cpp index 727eaed27..0acf610e9 100644 --- a/src/extras/defaults/qdiffusespecularmapmaterial.cpp +++ b/src/extras/defaults/qdiffusespecularmapmaterial.cpp @@ -209,7 +209,7 @@ void QDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged(const QVarian \inherits Qt3DRender::QMaterial \deprecated - \see Qt3DExtras::QDiffuseSpecularMaterial + This class is deprecated; use Qt3DExtras::QDiffuseSpecularMaterial instead. The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular. The relative strengths of these components are controlled by means of diff --git a/src/extras/defaults/qdiffusespecularmaterial.cpp b/src/extras/defaults/qdiffusespecularmaterial.cpp index 83bba9e41..14e1c2766 100644 --- a/src/extras/defaults/qdiffusespecularmaterial.cpp +++ b/src/extras/defaults/qdiffusespecularmaterial.cpp @@ -211,6 +211,7 @@ void QDiffuseSpecularMaterialPrivate::handleTextureScaleChanged(const QVariant & /*! \class Qt3DExtras::QDiffuseSpecularMaterial + \ingroup qt3d-extras-materials \brief The QDiffuseSpecularMaterial class provides a default implementation of the phong lighting effect. \inmodule Qt3DExtras diff --git a/src/extras/defaults/qfirstpersoncameracontroller.cpp b/src/extras/defaults/qfirstpersoncameracontroller.cpp index 2ad997d05..0561bbc37 100644 --- a/src/extras/defaults/qfirstpersoncameracontroller.cpp +++ b/src/extras/defaults/qfirstpersoncameracontroller.cpp @@ -44,6 +44,7 @@ namespace Qt3DExtras { /*! \class Qt3DExtras::QFirstPersonCameraController + \ingroup qt3d-extras-cameracontrollers \brief The QFirstPersonCameraController class allows controlling the scene camera from the first person perspective. \inmodule Qt3DExtras diff --git a/src/extras/defaults/qforwardrenderer.cpp b/src/extras/defaults/qforwardrenderer.cpp index f3137ea2d..b02077298 100644 --- a/src/extras/defaults/qforwardrenderer.cpp +++ b/src/extras/defaults/qforwardrenderer.cpp @@ -48,6 +48,13 @@ #include <Qt3DRender/qfrustumculling.h> #include <Qt3DRender/qrendersurfaceselector.h> +static void initResources() +{ +#ifdef QT_STATIC + Q_INIT_RESOURCE(extras); +#endif +} + QT_BEGIN_NAMESPACE using namespace Qt3DRender; @@ -68,6 +75,8 @@ void QForwardRendererPrivate::init() { Q_Q(QForwardRenderer); + initResources(); + m_frustumCulling->setParent(m_clearBuffer); m_clearBuffer->setParent(m_cameraSelector); m_cameraSelector->setParent(m_viewport); diff --git a/src/extras/defaults/qgoochmaterial.cpp b/src/extras/defaults/qgoochmaterial.cpp index ba7ef8dab..57ec359b3 100644 --- a/src/extras/defaults/qgoochmaterial.cpp +++ b/src/extras/defaults/qgoochmaterial.cpp @@ -188,6 +188,7 @@ void QGoochMaterialPrivate::handleShininessChanged(const QVariant &var) /*! \class Qt3DExtras::QGoochMaterial + \ingroup qt3d-extras-materials \brief The QGoochMaterial provides a material that implements the Gooch shading model, popular in CAD and CAM applications. \inmodule Qt3DExtras diff --git a/src/extras/defaults/qmetalroughmaterial.cpp b/src/extras/defaults/qmetalroughmaterial.cpp index 4d537f20f..1cf114423 100644 --- a/src/extras/defaults/qmetalroughmaterial.cpp +++ b/src/extras/defaults/qmetalroughmaterial.cpp @@ -161,6 +161,7 @@ void QMetalRoughMaterialPrivate::handleTextureScaleChanged(const QVariant &var) /*! \class Qt3DExtras::QMetalRoughMaterial + \ingroup qt3d-extras-materials \brief The QMetalRoughMaterial provides a default implementation of PBR lighting. \inmodule Qt3DExtras diff --git a/src/extras/defaults/qmorphphongmaterial.cpp b/src/extras/defaults/qmorphphongmaterial.cpp index 4b22e8765..ade9f8542 100644 --- a/src/extras/defaults/qmorphphongmaterial.cpp +++ b/src/extras/defaults/qmorphphongmaterial.cpp @@ -169,6 +169,7 @@ void QMorphPhongMaterialPrivate::handleInterpolatorChanged(const QVariant &var) /*! \class Qt3DExtras::QMorphPhongMaterial + \ingroup qt3d-extras-materials \brief The QMorphPhongMaterial class provides a default implementation of the phong lighting effect. \inmodule Qt3DExtras \since 5.7 diff --git a/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp index 9b2a64520..27fda6879 100644 --- a/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp +++ b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp @@ -166,7 +166,7 @@ void QNormalDiffuseMapAlphaMaterialPrivate::init() \inherits Qt3DExtras::QNormalDiffuseMapMaterial \deprecated - \see Qt3DExtras::QDiffuseSpecularMaterial + This class is deprecated; use Qt3DExtras::QDiffuseSpecularMaterial instead. The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular. The relative strengths of these components are controlled by means of diff --git a/src/extras/defaults/qnormaldiffusemapmaterial.cpp b/src/extras/defaults/qnormaldiffusemapmaterial.cpp index beed4085e..7c8260084 100644 --- a/src/extras/defaults/qnormaldiffusemapmaterial.cpp +++ b/src/extras/defaults/qnormaldiffusemapmaterial.cpp @@ -219,7 +219,7 @@ void QNormalDiffuseMapMaterialPrivate::handleTextureScaleChanged(const QVariant \inherits Qt3DRender::QMaterial \deprecated - \see Qt3DExtras::QDiffuseSpecularMaterial + This class is deprecated; use QDiffuseSpecularMaterial instead. The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular. The relative strengths of these components are controlled by means of diff --git a/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp index 028fd14e7..5fb2b7e9e 100644 --- a/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp +++ b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp @@ -227,7 +227,7 @@ void QNormalDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged(const Q \inherits Qt3DRender::QMaterial \deprecated - \see Qt3DExtras::QDiffuseSpecularMaterial + This class is deprecated; use QDiffuseSpecularMaterial instead. The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular. The relative strengths of these components are controlled by means of diff --git a/src/extras/defaults/qorbitcameracontroller.cpp b/src/extras/defaults/qorbitcameracontroller.cpp index c4f976f89..61b930569 100644 --- a/src/extras/defaults/qorbitcameracontroller.cpp +++ b/src/extras/defaults/qorbitcameracontroller.cpp @@ -49,6 +49,7 @@ QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate() /*! \class Qt3DExtras::QOrbitCameraController + \ingroup qt3d-extras-cameracontrollers \brief The QOrbitCameraController class allows controlling the scene camera along orbital path. \inmodule Qt3DExtras \since 5.7 diff --git a/src/extras/defaults/qpervertexcolormaterial.cpp b/src/extras/defaults/qpervertexcolormaterial.cpp index 5619a71e7..f0462039e 100644 --- a/src/extras/defaults/qpervertexcolormaterial.cpp +++ b/src/extras/defaults/qpervertexcolormaterial.cpp @@ -75,6 +75,7 @@ QPerVertexColorMaterialPrivate::QPerVertexColorMaterialPrivate() /*! \class Qt3DExtras::QPerVertexColorMaterial + \ingroup qt3d-extras-materials \brief The QPerVertexColorMaterial class provides a default implementation for rendering the color properties set for each vertex. \inmodule Qt3DExtras diff --git a/src/extras/defaults/qphongalphamaterial.cpp b/src/extras/defaults/qphongalphamaterial.cpp index 24cff94e9..2f705072f 100644 --- a/src/extras/defaults/qphongalphamaterial.cpp +++ b/src/extras/defaults/qphongalphamaterial.cpp @@ -210,7 +210,7 @@ void QPhongAlphaMaterialPrivate::handleShininessChanged(const QVariant &var) \inherits Qt3DRender::QMaterial \deprecated - \see Qt3DExtras::QDiffuseSpecularMaterial + This class is deprecated; use QDiffuseSpecularMaterial instead. The phong lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular. The relative strengths of these components are controlled by means of their diff --git a/src/extras/defaults/qphongmaterial.cpp b/src/extras/defaults/qphongmaterial.cpp index 17d837568..6318ea140 100644 --- a/src/extras/defaults/qphongmaterial.cpp +++ b/src/extras/defaults/qphongmaterial.cpp @@ -185,7 +185,7 @@ void QPhongMaterialPrivate::handleShininessChanged(const QVariant &var) \inherits Qt3DRender::QMaterial \deprecated - \see Qt3DExtras::QDiffuseSpecularMaterial + This class is deprecated; use QDiffuseSpecularMaterial instead. The phong lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular. The relative strengths of these components are controlled by means of their diff --git a/src/extras/defaults/qskyboxentity.cpp b/src/extras/defaults/qskyboxentity.cpp index 202ba4fcb..df6547083 100644 --- a/src/extras/defaults/qskyboxentity.cpp +++ b/src/extras/defaults/qskyboxentity.cpp @@ -40,6 +40,7 @@ #include "qskyboxentity.h" #include "qskyboxentity_p.h" +#include <QtCore/qtimer.h> #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qeffect.h> #include <Qt3DRender/qtexture.h> @@ -86,6 +87,7 @@ QSkyboxEntityPrivate::QSkyboxEntityPrivate() , m_negYImage(new QTextureImage()) , m_negZImage(new QTextureImage()) , m_extension(QStringLiteral(".png")) + , m_hasPendingReloadTextureCall(false) { m_loadedTexture->setGenerateMipMaps(false); } @@ -191,17 +193,23 @@ void QSkyboxEntityPrivate::init() */ void QSkyboxEntityPrivate::reloadTexture() { - if (m_extension == QStringLiteral(".dds")) { - m_loadedTexture->setSource(QUrl(m_baseName + m_extension)); - m_textureParameter->setValue(QVariant::fromValue(m_loadedTexture)); - } else { - m_posXImage->setSource(QUrl(m_baseName + QStringLiteral("_posx") + m_extension)); - m_posYImage->setSource(QUrl(m_baseName + QStringLiteral("_posy") + m_extension)); - m_posZImage->setSource(QUrl(m_baseName + QStringLiteral("_posz") + m_extension)); - m_negXImage->setSource(QUrl(m_baseName + QStringLiteral("_negx") + m_extension)); - m_negYImage->setSource(QUrl(m_baseName + QStringLiteral("_negy") + m_extension)); - m_negZImage->setSource(QUrl(m_baseName + QStringLiteral("_negz") + m_extension)); - m_textureParameter->setValue(QVariant::fromValue(m_skyboxTexture)); + if (!m_hasPendingReloadTextureCall) { + m_hasPendingReloadTextureCall = true; + QTimer::singleShot(0, [this] { + if (m_extension == QStringLiteral(".dds")) { + m_loadedTexture->setSource(QUrl(m_baseName + m_extension)); + m_textureParameter->setValue(QVariant::fromValue(m_loadedTexture)); + } else { + m_posXImage->setSource(QUrl(m_baseName + QStringLiteral("_posx") + m_extension)); + m_posYImage->setSource(QUrl(m_baseName + QStringLiteral("_posy") + m_extension)); + m_posZImage->setSource(QUrl(m_baseName + QStringLiteral("_posz") + m_extension)); + m_negXImage->setSource(QUrl(m_baseName + QStringLiteral("_negx") + m_extension)); + m_negYImage->setSource(QUrl(m_baseName + QStringLiteral("_negy") + m_extension)); + m_negZImage->setSource(QUrl(m_baseName + QStringLiteral("_negz") + m_extension)); + m_textureParameter->setValue(QVariant::fromValue(m_skyboxTexture)); + } + m_hasPendingReloadTextureCall = false; + }); } } diff --git a/src/extras/defaults/qskyboxentity_p.h b/src/extras/defaults/qskyboxentity_p.h index 88a40e2eb..945b42bf1 100644 --- a/src/extras/defaults/qskyboxentity_p.h +++ b/src/extras/defaults/qskyboxentity_p.h @@ -111,6 +111,7 @@ class QSkyboxEntityPrivate : public Qt3DCore::QEntityPrivate QString m_extension; QString m_baseName; QVector3D m_position; + bool m_hasPendingReloadTextureCall; }; } // Qt3DExtras diff --git a/src/extras/defaults/qt3dwindow.cpp b/src/extras/defaults/qt3dwindow.cpp index baa2aeddb..12e210f0d 100644 --- a/src/extras/defaults/qt3dwindow.cpp +++ b/src/extras/defaults/qt3dwindow.cpp @@ -62,6 +62,13 @@ #include <Qt3DRender/qcamera.h> #include <QtGui/qopenglcontext.h> +static void initResources() +{ +#ifdef QT_STATIC + Q_INIT_RESOURCE(extras); +#endif +} + QT_BEGIN_NAMESPACE namespace Qt3DExtras { @@ -86,6 +93,8 @@ Qt3DWindow::Qt3DWindow(QScreen *screen) { Q_D(Qt3DWindow); + initResources(); + if (!d->parentWindow) d->connectToScreen(screen ? screen : d->topLevelScreen.data()); diff --git a/src/extras/defaults/qtexturedmetalroughmaterial.cpp b/src/extras/defaults/qtexturedmetalroughmaterial.cpp index 8e26ddccc..55d061fc3 100644 --- a/src/extras/defaults/qtexturedmetalroughmaterial.cpp +++ b/src/extras/defaults/qtexturedmetalroughmaterial.cpp @@ -45,13 +45,12 @@ namespace Qt3DExtras { /*! \class Qt3DExtras::QTexturedMetalRoughMaterial - \brief This is deprecated, please use QMetalRoughMaterial instead. + \brief This class is deprecated; use QMetalRoughMaterial instead. \inmodule Qt3DExtras \since 5.9 \inherits Qt3DExtras::QMetalRoughMaterial \deprecated - \see Qt3DExtras::QMetalRoughMaterial */ /*! diff --git a/src/extras/defaults/qtexturematerial.cpp b/src/extras/defaults/qtexturematerial.cpp index 32e60360e..6d57f3a49 100644 --- a/src/extras/defaults/qtexturematerial.cpp +++ b/src/extras/defaults/qtexturematerial.cpp @@ -143,6 +143,7 @@ void QTextureMaterialPrivate::handleTextureTransformChanged(const QVariant &var) /*! \class Qt3DExtras::QTextureMaterial + \ingroup qt3d-extras-materials \brief The QTextureMaterial provides a default implementation of a simple unlit texture material. \inmodule Qt3DExtras diff --git a/src/extras/geometries/qconegeometry.cpp b/src/extras/geometries/qconegeometry.cpp index a80e2a78a..2cf526142 100644 --- a/src/extras/geometries/qconegeometry.cpp +++ b/src/extras/geometries/qconegeometry.cpp @@ -39,6 +39,7 @@ /*! * \class Qt3DExtras::QConeGeometry + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QConeGeometry * \inmodule Qt3DExtras * \brief The QConeGeometry class allows creation of a cone in 3D space. diff --git a/src/extras/geometries/qconemesh.cpp b/src/extras/geometries/qconemesh.cpp index 5e327df03..a0d1bd310 100644 --- a/src/extras/geometries/qconemesh.cpp +++ b/src/extras/geometries/qconemesh.cpp @@ -106,6 +106,7 @@ namespace Qt3DExtras { /*! * \class Qt3DExtras::QConeMesh + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QConeMesh * \inmodule Qt3DExtras * diff --git a/src/extras/geometries/qcuboidgeometry.cpp b/src/extras/geometries/qcuboidgeometry.cpp index 9e6747c1e..f9efaaf9d 100644 --- a/src/extras/geometries/qcuboidgeometry.cpp +++ b/src/extras/geometries/qcuboidgeometry.cpp @@ -648,6 +648,7 @@ void QCuboidGeometryPrivate::init() /*! * \class Qt3DExtras::QCuboidGeometry + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QCuboidGeometry * \inmodule Qt3DExtras * \brief The QCuboidGeometry class allows creation of a cuboid in 3D space. diff --git a/src/extras/geometries/qcuboidmesh.cpp b/src/extras/geometries/qcuboidmesh.cpp index 9e10d93a4..bdad566fc 100644 --- a/src/extras/geometries/qcuboidmesh.cpp +++ b/src/extras/geometries/qcuboidmesh.cpp @@ -96,6 +96,7 @@ namespace Qt3DExtras { /*! * \class Qt3DExtras::QCuboidMesh + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QCuboidMesh * \inmodule Qt3DExtras * diff --git a/src/extras/geometries/qcylindergeometry.cpp b/src/extras/geometries/qcylindergeometry.cpp index c86b76d24..9d26068f2 100644 --- a/src/extras/geometries/qcylindergeometry.cpp +++ b/src/extras/geometries/qcylindergeometry.cpp @@ -409,6 +409,7 @@ void QCylinderGeometryPrivate::init() /*! * \class Qt3DExtras::QCylinderGeometry + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QCylinderGeometry * \inmodule Qt3DExtras * \brief The QCylinderGeometry class allows creation of a cylinder in 3D space. diff --git a/src/extras/geometries/qcylindermesh.cpp b/src/extras/geometries/qcylindermesh.cpp index 02df6295f..792944cd5 100644 --- a/src/extras/geometries/qcylindermesh.cpp +++ b/src/extras/geometries/qcylindermesh.cpp @@ -91,6 +91,7 @@ namespace Qt3DExtras { /*! * \class Qt3DExtras::QCylinderMesh + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QCylinderMesh * \inmodule Qt3DExtras * diff --git a/src/extras/geometries/qplanegeometry.cpp b/src/extras/geometries/qplanegeometry.cpp index 225726342..0176accdd 100644 --- a/src/extras/geometries/qplanegeometry.cpp +++ b/src/extras/geometries/qplanegeometry.cpp @@ -278,6 +278,7 @@ public: /*! * \class Qt3DExtras::QPlaneGeometry + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QPlaneGeometry * \inmodule Qt3DExtras * \brief The QPlaneGeometry class allows creation of a plane in 3D space. diff --git a/src/extras/geometries/qplanemesh.cpp b/src/extras/geometries/qplanemesh.cpp index 4804df024..223e5a628 100644 --- a/src/extras/geometries/qplanemesh.cpp +++ b/src/extras/geometries/qplanemesh.cpp @@ -81,6 +81,7 @@ namespace Qt3DExtras { /*! * \class Qt3DExtras::QPlaneMesh + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QPlaneMesh * \inmodule Qt3DExtras * diff --git a/src/extras/geometries/qspheregeometry.cpp b/src/extras/geometries/qspheregeometry.cpp index 1a3b50553..f5ec6bec2 100644 --- a/src/extras/geometries/qspheregeometry.cpp +++ b/src/extras/geometries/qspheregeometry.cpp @@ -382,6 +382,7 @@ void QSphereGeometryPrivate::init() /*! * \class Qt3DExtras::QSphereGeometry + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QSphereGeometry * \inmodule Qt3DExtras * \brief The QSphereGeometry class allows creation of a sphere in 3D space. diff --git a/src/extras/geometries/qspheremesh.cpp b/src/extras/geometries/qspheremesh.cpp index 22089d7ab..28854fe29 100644 --- a/src/extras/geometries/qspheremesh.cpp +++ b/src/extras/geometries/qspheremesh.cpp @@ -80,6 +80,7 @@ namespace Qt3DExtras { /*! * \class Qt3DExtras::QSphereMesh + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QSphereMesh * \inmodule Qt3DExtras * diff --git a/src/extras/geometries/qtorusgeometry.cpp b/src/extras/geometries/qtorusgeometry.cpp index 726b81c62..98707b03c 100644 --- a/src/extras/geometries/qtorusgeometry.cpp +++ b/src/extras/geometries/qtorusgeometry.cpp @@ -362,6 +362,7 @@ void QTorusGeometryPrivate::init() /*! * \class Qt3DExtras::QTorusGeometry + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QTorusGeometry * \inmodule Qt3DExtras * \brief The QTorusGeometry class allows creation of a torus in 3D space. diff --git a/src/extras/geometries/qtorusmesh.cpp b/src/extras/geometries/qtorusmesh.cpp index 8e7c678db..fd10afc1e 100644 --- a/src/extras/geometries/qtorusmesh.cpp +++ b/src/extras/geometries/qtorusmesh.cpp @@ -83,6 +83,7 @@ namespace Qt3DExtras { /*! * \class Qt3DExtras::QTorusMesh + \ingroup qt3d-extras-geometries * \inheaderfile Qt3DExtras/QTorusMesh * \inmodule Qt3DExtras * diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp index 26e966f76..01977f72b 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer.cpp +++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp @@ -131,6 +131,7 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp , m_texture(nullptr) , m_node(nullptr) , m_cleaner(nullptr) + , m_window(nullptr) , m_multisample(false) // this value is not used, will be synced from the Scene3DItem instead , m_lastMultisample(false) , m_needsShutdown(true) @@ -138,9 +139,16 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp Q_CHECK_PTR(m_item); Q_CHECK_PTR(m_item->window()); + m_window = m_item->window(); QObject::connect(m_item->window(), &QQuickWindow::beforeRendering, this, &Scene3DRenderer::render, Qt::DirectConnection); QObject::connect(m_item->window(), &QQuickWindow::sceneGraphInvalidated, this, &Scene3DRenderer::onSceneGraphInvalidated, Qt::DirectConnection); + // So that we can schedule the cleanup QObject::connect(m_item, &QQuickItem::windowChanged, this, &Scene3DRenderer::onWindowChanged, Qt::QueuedConnection); + // Main thread -> updates the rendering window + QObject::connect(m_item, &QQuickItem::windowChanged, [this] (QQuickWindow *w) { + QMutexLocker l(&m_windowMutex); + m_window = w; + }); Q_ASSERT(QOpenGLContext::currentContext()); ContextSaver saver; @@ -245,11 +253,11 @@ void Scene3DRenderer::setSGNode(Scene3DSGNode *node) void Scene3DRenderer::render() { - if (!m_item || !m_item->window()) + QMutexLocker l(&m_windowMutex); + // Lock to ensure the window doesn't change while we are rendering + if (!m_item || !m_window) return; - QQuickWindow *window = m_item->window(); - if (m_aspectEngine->rootEntity() != m_item->entity()) scheduleRootEntityChange(); @@ -257,10 +265,10 @@ void Scene3DRenderer::render() // The OpenGL state may be dirty from the previous QtQuick nodes, so reset // it here to give Qt3D the clean state it expects - window->resetOpenGLState(); + m_window->resetOpenGLState(); const QSize boundingRectSize = m_item->boundingRect().size().toSize(); - const QSize currentSize = boundingRectSize * window->effectiveDevicePixelRatio(); + const QSize currentSize = boundingRectSize * m_window->effectiveDevicePixelRatio(); const bool sizeHasChanged = currentSize != m_lastSize; const bool multisampleHasChanged = m_multisample != m_lastMultisample; const bool forceRecreate = sizeHasChanged || multisampleHasChanged; @@ -282,7 +290,7 @@ void Scene3DRenderer::render() if (m_finalFBO.isNull() || forceRecreate) { m_finalFBO.reset(createFramebufferObject(currentSize)); - m_texture.reset(window->createTextureFromId(m_finalFBO->texture(), m_finalFBO->size(), QQuickWindow::TextureHasAlphaChannel)); + m_texture.reset(m_window->createTextureFromId(m_finalFBO->texture(), m_finalFBO->size(), QQuickWindow::TextureHasAlphaChannel)); m_node->setTexture(m_texture.data()); } @@ -322,13 +330,13 @@ void Scene3DRenderer::render() // Reset the state used by the Qt Quick scenegraph to avoid any // interference when rendering the rest of the UI. - window->resetOpenGLState(); + m_window->resetOpenGLState(); // Mark material as dirty to request a new frame m_node->markDirty(QSGNode::DirtyMaterial); // Request next frame - window->update(); + m_window->update(); } } // namespace Qt3DRender diff --git a/src/quick3d/imports/scene3d/scene3drenderer_p.h b/src/quick3d/imports/scene3d/scene3drenderer_p.h index ab1db1010..7a85bc774 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer_p.h +++ b/src/quick3d/imports/scene3d/scene3drenderer_p.h @@ -53,6 +53,7 @@ #include <QtCore/QObject> #include <QtCore/qsize.h> +#include <QtCore/QMutex> QT_BEGIN_NAMESPACE @@ -102,6 +103,8 @@ private: QScopedPointer<QSGTexture> m_texture; Scene3DSGNode *m_node; // Will be released by the QtQuick SceneGraph Scene3DCleaner *m_cleaner; + QQuickWindow *m_window; + QMutex m_windowMutex; QSize m_lastSize; bool m_multisample; bool m_lastMultisample; diff --git a/src/render/backend/attachmentpack.cpp b/src/render/backend/attachmentpack.cpp index 9a08fdde4..a2ac8c30c 100644 --- a/src/render/backend/attachmentpack.cpp +++ b/src/render/backend/attachmentpack.cpp @@ -50,11 +50,10 @@ AttachmentPack::AttachmentPack() { } -AttachmentPack::AttachmentPack(const RenderTargetSelector *selector, const RenderTarget *target, AttachmentManager *attachmentManager) +AttachmentPack::AttachmentPack(const RenderTarget *target, + AttachmentManager *attachmentManager, + const QVector<QRenderTargetOutput::AttachmentPoint> &drawBuffers) { - // Cache draw buffers list - const QVector<QRenderTargetOutput::AttachmentPoint> selectedAttachmentPoints = selector->outputs(); - // Copy attachments const auto outputIds = target->renderOutputs(); for (Qt3DCore::QNodeId outputId : outputIds) { @@ -66,15 +65,15 @@ AttachmentPack::AttachmentPack(const RenderTargetSelector *selector, const Rende // Create actual DrawBuffers list that is used for glDrawBuffers // If nothing is specified, use all the attachments as draw buffers - if (selectedAttachmentPoints.isEmpty()) { + if (drawBuffers.isEmpty()) { m_drawBuffers.reserve(m_attachments.size()); for (const Attachment &attachment : qAsConst(m_attachments)) // only consider Color Attachments if (attachment.m_point <= QRenderTargetOutput::Color15) m_drawBuffers.push_back((int) attachment.m_point); } else { - m_drawBuffers.reserve(selectedAttachmentPoints.size()); - for (QRenderTargetOutput::AttachmentPoint drawBuffer : selectedAttachmentPoints) + m_drawBuffers.reserve(drawBuffers.size()); + for (QRenderTargetOutput::AttachmentPoint drawBuffer : drawBuffers) if (drawBuffer <= QRenderTargetOutput::Color15) m_drawBuffers.push_back((int) drawBuffer); } diff --git a/src/render/backend/attachmentpack_p.h b/src/render/backend/attachmentpack_p.h index 98362149a..a3a2586dd 100644 --- a/src/render/backend/attachmentpack_p.h +++ b/src/render/backend/attachmentpack_p.h @@ -84,7 +84,9 @@ class AttachmentPack { public: AttachmentPack(); - AttachmentPack(const RenderTargetSelector *selector, const RenderTarget *target, AttachmentManager *attachmentManager); + AttachmentPack(const RenderTarget *target, + AttachmentManager *attachmentManager, + const QVector<QRenderTargetOutput::AttachmentPoint> &drawBuffers = QVector<QRenderTargetOutput::AttachmentPoint>()); QVector<Attachment> attachments() const { return m_attachments; } QVector<int> getGlDrawBuffers() const { return m_drawBuffers; } diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index dbb33fbcf..4bf22cf0e 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -1985,7 +1985,7 @@ const QVector<Qt3DCore::QNodeId> Renderer::takePendingRenderCaptureSendRequests( // 1 dirty buffer == 1 job, all job can be performed in parallel QVector<Qt3DCore::QAspectJobPtr> Renderer::createRenderBufferJobs() const { - const QVector<QNodeId> dirtyBuffers = m_nodesManager->bufferManager()->dirtyBuffers(); + const QVector<QNodeId> dirtyBuffers = m_nodesManager->bufferManager()->takeDirtyBuffers(); QVector<QAspectJobPtr> dirtyBuffersJobs; dirtyBuffersJobs.reserve(dirtyBuffers.size()); diff --git a/src/render/backend/renderviewbuilder.cpp b/src/render/backend/renderviewbuilder.cpp index dca75f517..0682018fc 100644 --- a/src/render/backend/renderviewbuilder.cpp +++ b/src/render/backend/renderviewbuilder.cpp @@ -218,7 +218,7 @@ public: const QVector<Entity *> filteredEntities = m_renderer->cache()->leafNodeCache.value(m_leafNode).filterEntitiesByLayer; lock.unlock(); // Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector - RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, filteredEntities); + renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, filteredEntities); // Set the light sources, with layer filters applied. QVector<LightSource> lightSources = m_lightGathererJob->lights(); @@ -231,9 +231,9 @@ public: if (isDraw) { // Filter out frustum culled entity for drawable entities if (rv->frustumCulling()) - RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, m_frustumCullingJob->visibleEntities()); + renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_frustumCullingJob->visibleEntities()); // Filter out entities which didn't satisfy proximity filtering - RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, m_filterProximityJob->filteredEntities()); + renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_filterProximityJob->filteredEntities()); } // Split among the number of command builders @@ -647,17 +647,15 @@ int RenderViewBuilder::optimalJobCount() return RenderViewBuilder::m_optimalParallelJobCount; } -void RenderViewBuilder::removeEntitiesNotInSubset(QVector<Entity *> &entities, QVector<Entity *> subset) +QVector<Entity *> RenderViewBuilder::entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset) { - // Note: assumes entities was sorted already - std::sort(subset.begin(), subset.end()); + QVector<Entity *> intersection; + intersection.reserve(qMin(entities.size(), subset.size())); + std::set_intersection(entities.begin(), entities.end(), + subset.begin(), subset.end(), + std::back_inserter(intersection)); - for (auto i = entities.size() - 1, j = subset.size() - 1; i >= 0; --i) { - while (j >= 0 && subset.at(j) > entities.at(i)) - --j; - if (j < 0 || entities.at(i) != subset.at(j)) - entities.removeAt(i); - } + return intersection; } } // Render diff --git a/src/render/backend/renderviewbuilder_p.h b/src/render/backend/renderviewbuilder_p.h index 8094fb46a..818313500 100644 --- a/src/render/backend/renderviewbuilder_p.h +++ b/src/render/backend/renderviewbuilder_p.h @@ -110,7 +110,7 @@ public: bool materialGathererCacheNeedsToBeRebuilt() const; static int optimalJobCount(); - static void removeEntitiesNotInSubset(QVector<Entity *> &entities, QVector<Entity *> subset); + static QVector<Entity *> entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset); private: Render::FrameGraphNode *m_leafNode; diff --git a/src/render/framegraph/qblitframebuffer.cpp b/src/render/framegraph/qblitframebuffer.cpp index 505bab96c..d5484b719 100644 --- a/src/render/framegraph/qblitframebuffer.cpp +++ b/src/render/framegraph/qblitframebuffer.cpp @@ -47,6 +47,99 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +/*! + \class Qt3DRender::QBlitFramebuffer + \inmodule Qt3DRender + \since 5.10 + \ingroup framegraph + \brief FrameGraph node to transfer a rectangle of pixel values from one + region of a render target to another. + + This node inserts a \c glBlitFrameBuffer or an equivalent into the command + stream. This provides a more efficient method for copying rectangles + between textures or surface backbuffers wrapped by QRenderTarget than + drawing textured quads. It also supports scaling with the specified + interpolation method. + + \note In practice the QBlitFramebuffer node will often be used in + combination with QNoDraw since a blit should not involve issuing draw calls + for any entities. + */ + +/*! + \qmltype BlitFramebuffer + \inqmlmodule Qt3D.Render + \instantiates Qt3DRender::QBlitFramebuffer + \inherits FrameGraphNode + \since 5.10 + \brief FrameGraph node to transfer a rectangle of pixel values from one + region of a render target to another. + + This node inserts a \c glBlitFrameBuffer or an equivalent into the command + stream. This provides a more efficient method for copying rectangles + between textures or surface backbuffers wrapped by QRenderTarget than + drawing textured quads. It also supports scaling with the specified + interpolation method. + + \note In practice the BlitFramebuffer node will often be used in + combination with NoDraw since a blit should not involve issuing draw calls + for any entities. +*/ + +/*! + \qmlproperty RenderTarget BlitFramebuffer::source + + Specifies the source render target. When not set, the source is assumed to + be the default framebuffer (i.e. the backbuffer of the current surface), if + there is one. + + \note the source and destination must not refer to the same render target. + */ + +/*! + \qmlproperty RenderTarget BlitFramebuffer::destination + + Specifies the destination render target. When not set, the destination is + assumed to be the default framebuffer (i.e. the backbuffer of the current + surface), if there is one. + + \note the source and destination must not refer to the same render target. + */ + +/*! + \qmlproperty Rect BlitFramebuffer::sourceRect + + Specifies the source rectangle. The coordinates are assumed to follow the + normal Qt coordinate system, meaning Y runs from top to bottom. + */ + +/*! + \qmlproperty Rect BlitFramebuffer::destinationRect + + Specifies the destination rectangle. The coordinates are assumed to follow + the normal Qt coordinate system, meaning Y runs from top to bottom. + */ + +/*! + \qmlproperty RenderTargetOutput.AttachmentPoint BlitFramebuffer::sourceAttachmentPoint + + Specifies the source attachment point. Defaults to + RenderTargetOutput.AttachmentPoint.Color0. + */ + +/*! + \qmlproperty RenderTargetOutput.AttachmentPoint BlitFramebuffer::destinationAttachmentPoint + + Specifies the source attachment point. Defaults to + RenderTargetOutput.AttachmentPoint.Color0. + */ + +/*! + \qmlproperty InterpolationMethod BlitFramebuffer::interpolationMethod + + Specifies the interpolation applied if the image is stretched. Defaults to Linear. + */ + QBlitFramebufferPrivate::QBlitFramebufferPrivate() : QFrameGraphNodePrivate() , m_source(nullptr) @@ -59,82 +152,168 @@ QBlitFramebufferPrivate::QBlitFramebufferPrivate() { } +/*! + Constructs a new QBlitFramebuffer with the given \a parent. + */ QBlitFramebuffer::QBlitFramebuffer(QNode *parent) : QFrameGraphNode(*new QBlitFramebufferPrivate, parent) { } +/*! + \internal + */ QBlitFramebuffer::QBlitFramebuffer(QBlitFramebufferPrivate &dd, QNode *parent) : QFrameGraphNode(dd, parent) { } +/*! + Destructor. + */ QBlitFramebuffer::~QBlitFramebuffer() { } +/*! + \return the source render target. + */ QRenderTarget *QBlitFramebuffer::source() const { Q_D(const QBlitFramebuffer); return d->m_source; } +/*! + \return the destination render target. + */ QRenderTarget *QBlitFramebuffer::destination() const { Q_D(const QBlitFramebuffer); return d->m_destination; } +/*! + \return the source rectangle. + */ QRectF QBlitFramebuffer::sourceRect() const { Q_D(const QBlitFramebuffer); return d->m_sourceRect; } +/*! + \return the destination rectangle. + */ QRectF QBlitFramebuffer::destinationRect() const { Q_D(const QBlitFramebuffer); return d->m_destinationRect; } +/*! + \return the source attachment point. + */ Qt3DRender::QRenderTargetOutput::AttachmentPoint QBlitFramebuffer::sourceAttachmentPoint() const { Q_D(const QBlitFramebuffer); return d->m_sourceAttachmentPoint; } +/*! + \return the destination attachment point. + */ QRenderTargetOutput::AttachmentPoint QBlitFramebuffer::destinationAttachmentPoint() const { Q_D(const QBlitFramebuffer); return d->m_destinationAttachmentPoint; } +/*! + \return the interpolation method. + */ QBlitFramebuffer::InterpolationMethod QBlitFramebuffer::interpolationMethod() const { Q_D(const QBlitFramebuffer); return d->m_interpolationMethod; } +/*! + Sets the source render target. The default value is nullptr, in which + case the source is assumed to be be the default framebuffer (i.e. the + backbuffer of the current surface), if there is one. + + \note the source and destination must not refer to the same render target. + + \note As with other nodes, \a source gets automatically parented to the + QBlitFramebuffer instance when no parent has been set. The lifetime is also + tracked, meaning the source reverts to nullptr in case the currently set + \a source is destroyed. + */ void QBlitFramebuffer::setSource(QRenderTarget *source) { Q_D(QBlitFramebuffer); if (d->m_source != source) { + if (d->m_source) { + // Remove bookkeeping connection + d->unregisterDestructionHelper(d->m_source); + } + d->m_source = source; + + if (d->m_source) { + // Ensures proper bookkeeping. Calls us back with nullptr in case the rt gets destroyed. + d->registerDestructionHelper(d->m_source, &QBlitFramebuffer::setSource, d->m_source); + + if (!d->m_source->parent()) + d->m_source->setParent(this); + } + emit sourceChanged(); } } +/*! + Sets the destination render target. The default value is nullptr, in which + case the destination is assumed to be be the default framebuffer (i.e. the + backbuffer of the current surface), if there is one. + + \note the source and destination must not refer to the same render target. + + \note As with other nodes, \a destination gets automatically parented to the + QBlitFramebuffer instance when no parent has been set. The lifetime is also + tracked, meaning the destination reverts to nullptr in case the currently set + \a destination is destroyed. + */ void QBlitFramebuffer::setDestination(QRenderTarget *destination) { Q_D(QBlitFramebuffer); if (d->m_destination != destination) { + if (d->m_destination) { + // Remove bookkeeping connection + d->unregisterDestructionHelper(d->m_destination); + } + d->m_destination = destination; + + if (d->m_destination) { + // Ensures proper bookkeeping. Calls us back with nullptr in case the rt gets destroyed. + d->registerDestructionHelper(d->m_destination, &QBlitFramebuffer::setDestination, d->m_destination); + + if (!d->m_destination->parent()) + d->m_destination->setParent(this); + } + emit destinationChanged(); } } +/*! + Sets the source rectangle to \a inputRect. The coordinates are assumed to + follow the normal Qt coordinate system, meaning Y runs from top to bottom. + */ void QBlitFramebuffer::setSourceRect(const QRectF &inputRect) { Q_D(QBlitFramebuffer); @@ -144,6 +323,11 @@ void QBlitFramebuffer::setSourceRect(const QRectF &inputRect) } } +/*! + Sets the destination rectangle to \a inputRect. The coordinates are assumed + to follow the normal Qt coordinate system, meaning Y runs from top to + bottom. + */ void QBlitFramebuffer::setDestinationRect(const QRectF &outputRect) { Q_D(QBlitFramebuffer); @@ -153,6 +337,10 @@ void QBlitFramebuffer::setDestinationRect(const QRectF &outputRect) } } +/*! + Sets the \a sourceAttachmentPoint. Defaults to + Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0. + */ void QBlitFramebuffer::setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint) { Q_D(QBlitFramebuffer); @@ -162,6 +350,10 @@ void QBlitFramebuffer::setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput: } } +/*! + Sets the \a destinationAttachmentPoint. Defaults to + Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0. + */ void QBlitFramebuffer::setDestinationAttachmentPoint(QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint) { Q_D(QBlitFramebuffer); @@ -171,6 +363,10 @@ void QBlitFramebuffer::setDestinationAttachmentPoint(QRenderTargetOutput::Attach } } +/*! + Sets the \a interpolationMethod that is applied if the image is stretched. + Defaults to Linear. + */ void QBlitFramebuffer::setInterpolationMethod(QBlitFramebuffer::InterpolationMethod interpolationMethod) { Q_D(QBlitFramebuffer); @@ -180,6 +376,9 @@ void QBlitFramebuffer::setInterpolationMethod(QBlitFramebuffer::InterpolationMet } } +/*! + \internal + */ Qt3DCore::QNodeCreatedChangeBasePtr QBlitFramebuffer::createNodeCreationChange() const { auto creationChange = QFrameGraphNodeCreatedChangePtr<QBlitFramebufferData>::create(this); diff --git a/src/render/framegraph/qrendercapture.cpp b/src/render/framegraph/qrendercapture.cpp index 66c518506..28bc41b91 100644 --- a/src/render/framegraph/qrendercapture.cpp +++ b/src/render/framegraph/qrendercapture.cpp @@ -149,6 +149,15 @@ namespace Qt3DRender { */ /*! + * \qmlmethod RenderCaptureReply Qt3D.Render::RenderCapture::requestCapture(Rect rect) + * + * Used to request render capture from a specified \a rect. Only one render capture + * result is produced per requestCapture call even if the frame graph has multiple leaf nodes. + * The function returns a QRenderCaptureReply object, which receives the captured image + * when it is done. The user is responsible for deallocating the returned object. + */ + +/*! * \internal */ QRenderCaptureReplyPrivate::QRenderCaptureReplyPrivate() @@ -311,7 +320,7 @@ QRenderCapture::QRenderCapture(Qt3DCore::QNode *parent) * The function returns a QRenderCaptureReply object, which receives the captured image * when it is done. The user is responsible for deallocating the returned object. */ -QRenderCaptureReply *QRenderCapture::requestCapture(int captureId, const QRect &rect) +QRenderCaptureReply *QRenderCapture::requestCapture(int captureId) { Q_D(QRenderCapture); QRenderCaptureReply *reply = d->createReply(captureId); @@ -322,7 +331,7 @@ QRenderCaptureReply *QRenderCapture::requestCapture(int captureId, const QRect & Qt3DCore::QPropertyUpdatedChangePtr change(new Qt3DCore::QPropertyUpdatedChange(id())); change->setPropertyName(QByteArrayLiteral("renderCaptureRequest")); - const QRenderCaptureRequest request = { captureId, rect }; + const QRenderCaptureRequest request = { captureId, QRect() }; change->setValue(QVariant::fromValue(request)); d->notifyObservers(change); @@ -330,8 +339,8 @@ QRenderCaptureReply *QRenderCapture::requestCapture(int captureId, const QRect & } /*! - * Used to request render capture. Only one render capture result is produced per - * requestCapture call even if the frame graph has multiple leaf nodes. + * Used to request render capture from a specified \a rect. Only one render capture result + * is produced per requestCapture call even if the frame graph has multiple leaf nodes. * The function returns a QRenderCaptureReply object, which receives the captured image * when it is done. The user is responsible for deallocating the returned object. */ @@ -357,6 +366,17 @@ QRenderCaptureReply *QRenderCapture::requestCapture(const QRect &rect) } /*! + * Used to request render capture. Only one render capture result is produced per + * requestCapture call even if the frame graph has multiple leaf nodes. + * The function returns a QRenderCaptureReply object, which receives the captured image + * when it is done. The user is responsible for deallocating the returned object. + */ +Qt3DRender::QRenderCaptureReply *QRenderCapture::requestCapture() +{ + return requestCapture(QRect()); +} + +/*! * \internal */ void QRenderCapture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) diff --git a/src/render/framegraph/qrendercapture.h b/src/render/framegraph/qrendercapture.h index c0a4d4ab4..80eeabe64 100644 --- a/src/render/framegraph/qrendercapture.h +++ b/src/render/framegraph/qrendercapture.h @@ -84,9 +84,10 @@ class QT3DRENDERSHARED_EXPORT QRenderCapture : public QFrameGraphNode public: explicit QRenderCapture(Qt3DCore::QNode *parent = nullptr); - Q_INVOKABLE Q_DECL_DEPRECATED_X("Use the overload with no parameter") - Qt3DRender::QRenderCaptureReply *requestCapture(int captureId, const QRect &rect = QRect()); - Q_REVISION(9) Q_INVOKABLE Qt3DRender::QRenderCaptureReply *requestCapture(const QRect &rect = QRect()); + Q_INVOKABLE Q_DECL_DEPRECATED_X("Use the overload with no id parameter") + Qt3DRender::QRenderCaptureReply *requestCapture(int captureId); + Q_REVISION(9) Q_INVOKABLE Qt3DRender::QRenderCaptureReply *requestCapture(); + Q_REVISION(10) Q_INVOKABLE Qt3DRender::QRenderCaptureReply *requestCapture(const QRect &rect); protected: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; diff --git a/src/render/frontend/qlevelofdetail.h b/src/render/frontend/qlevelofdetail.h index 14ed92628..24d5942ab 100644 --- a/src/render/frontend/qlevelofdetail.h +++ b/src/render/frontend/qlevelofdetail.h @@ -78,7 +78,7 @@ public: QVector<qreal> thresholds() const; QLevelOfDetailBoundingSphere volumeOverride() const; - Q_INVOKABLE QLevelOfDetailBoundingSphere createBoundingSphere(const QVector3D ¢er, float radius); + Q_INVOKABLE Qt3DRender::QLevelOfDetailBoundingSphere createBoundingSphere(const QVector3D ¢er, float radius); public Q_SLOTS: void setCamera(QCamera *camera); diff --git a/src/render/geometry/buffermanager.cpp b/src/render/geometry/buffermanager.cpp index 25f95189e..14b552879 100644 --- a/src/render/geometry/buffermanager.cpp +++ b/src/render/geometry/buffermanager.cpp @@ -58,7 +58,7 @@ void BufferManager::addDirtyBuffer(Qt3DCore::QNodeId bufferId) m_dirtyBuffers.push_back(bufferId); } -QVector<Qt3DCore::QNodeId> BufferManager::dirtyBuffers() +QVector<Qt3DCore::QNodeId> BufferManager::takeDirtyBuffers() { return qMove(m_dirtyBuffers); } diff --git a/src/render/geometry/buffermanager_p.h b/src/render/geometry/buffermanager_p.h index ed3563876..4805955bd 100644 --- a/src/render/geometry/buffermanager_p.h +++ b/src/render/geometry/buffermanager_p.h @@ -72,7 +72,7 @@ public: // Aspect Thread void addDirtyBuffer(Qt3DCore::QNodeId bufferId); - QVector<Qt3DCore::QNodeId> dirtyBuffers(); + QVector<Qt3DCore::QNodeId> takeDirtyBuffers(); // Aspect Thread void addBufferReference(Qt3DCore::QNodeId bufferId); diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index 9a20c77e7..d33aca825 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -366,6 +366,10 @@ QSize GraphicsContext::renderTargetSize(const QSize &surfaceSize) const void GraphicsContext::setViewport(const QRectF &viewport, const QSize &surfaceSize) { + // save for later use; this has nothing to do with the viewport but it is + // here that we get to know the surfaceSize from the RenderView. + m_surfaceSize = surfaceSize; + m_viewport = viewport; QSize size = renderTargetSize(surfaceSize); @@ -579,38 +583,11 @@ void GraphicsContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, // this is the default fbo that some platforms create (iOS), we just register it // Insert FBO into hash m_renderTargets.insert(renderTargetNodeId, fboId); - } else if ((fboId = m_glHelper->createFrameBufferObject()) != 0) { - // The FBO is created and its attachments are set once - // Insert FBO into hash - m_renderTargets.insert(renderTargetNodeId, fboId); - // Bind FBO - m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); - bindFrameBufferAttachmentHelper(fboId, attachments); } else { - qCritical() << "Failed to create FBO"; + fboId = createRenderTarget(renderTargetNodeId, attachments); } } else { - fboId = m_renderTargets.value(renderTargetNodeId); - - // We need to check if one of the attachment was resized - bool needsResize = !m_renderTargetsSize.contains(fboId); // not even initialized yet? - if (!needsResize) { - // render target exists, has attachment been resized? - GLTextureManager *glTextureManager = m_renderer->nodeManagers()->glTextureManager(); - const QSize s = m_renderTargetsSize[fboId]; - const auto attachments_ = attachments.attachments(); - for (const Attachment &attachment : attachments_) { - GLTexture *rTex = glTextureManager->lookupResource(attachment.m_textureUuid); - needsResize |= (rTex != nullptr && rTex->size() != s); - if (attachment.m_point == QRenderTargetOutput::Color0) - m_renderTargetFormat = rTex->properties().format; - } - } - - if (needsResize) { - m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); - bindFrameBufferAttachmentHelper(fboId, attachments); - } + fboId = updateRenderTarget(renderTargetNodeId, attachments, true); } } m_activeFBO = fboId; @@ -619,6 +596,54 @@ void GraphicsContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, activateDrawBuffers(attachments); } +GLuint GraphicsContext::createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments) +{ + const GLuint fboId = m_glHelper->createFrameBufferObject(); + if (fboId) { + // The FBO is created and its attachments are set once + // Insert FBO into hash + m_renderTargets.insert(renderTargetNodeId, fboId); + // Bind FBO + m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); + bindFrameBufferAttachmentHelper(fboId, attachments); + } else { + qCritical("Failed to create FBO"); + } + return fboId; +} + +GLuint GraphicsContext::updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget) +{ + const GLuint fboId = m_renderTargets.value(renderTargetNodeId); + + // We need to check if one of the attachment was resized + bool needsResize = !m_renderTargetsSize.contains(fboId); // not even initialized yet? + if (!needsResize) { + // render target exists, has attachment been resized? + GLTextureManager *glTextureManager = m_renderer->nodeManagers()->glTextureManager(); + const QSize s = m_renderTargetsSize[fboId]; + const auto attachments_ = attachments.attachments(); + for (const Attachment &attachment : attachments_) { + GLTexture *rTex = glTextureManager->lookupResource(attachment.m_textureUuid); + // ### TODO QTBUG-64757 this check is insufficient since the + // texture may have changed to another one with the same size. That + // case is not handled atm. + needsResize |= (rTex != nullptr && rTex->size() != s); + if (isActiveRenderTarget) { + if (attachment.m_point == QRenderTargetOutput::Color0) + m_renderTargetFormat = rTex->properties().format; + } + } + } + + if (needsResize) { + m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); + bindFrameBufferAttachmentHelper(fboId, attachments); + } + + return fboId; +} + void GraphicsContext::bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments) { // Set FBO attachments. These are normally textures, except that on Open GL @@ -1515,30 +1540,53 @@ bool GraphicsContext::hasGLBufferForBuffer(Buffer *buffer) return (it != m_renderBufferHash.end()); } -void GraphicsContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTarget, - Qt3DCore::QNodeId outputRenderTarget, +void GraphicsContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId, + Qt3DCore::QNodeId outputRenderTargetId, QRect inputRect, QRect outputRect, uint defaultFboId, QRenderTargetOutput::AttachmentPoint inputAttachmentPoint, QRenderTargetOutput::AttachmentPoint outputAttachmentPoint, QBlitFramebuffer::InterpolationMethod interpolationMethod) { - //Find the context side name for the render targets - const GLuint inputFboId = m_renderTargets[inputRenderTarget]; + GLuint inputFboId = defaultFboId; + bool inputBufferIsDefault = true; + if (!inputRenderTargetId.isNull()) { + RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(inputRenderTargetId); + if (renderTarget) { + AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager()); + if (m_renderTargets.contains(inputRenderTargetId)) + inputFboId = updateRenderTarget(inputRenderTargetId, attachments, false); + else + inputFboId = createRenderTarget(inputRenderTargetId, attachments); + } + inputBufferIsDefault = false; + } + GLuint outputFboId = defaultFboId; bool outputBufferIsDefault = true; - if (!outputRenderTarget.isNull() && m_renderTargets.contains(outputRenderTarget)) { - outputFboId = m_renderTargets[outputRenderTarget]; + if (!outputRenderTargetId.isNull()) { + RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(outputRenderTargetId); + if (renderTarget) { + AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager()); + if (m_renderTargets.contains(outputRenderTargetId)) + outputFboId = updateRenderTarget(outputRenderTargetId, attachments, false); + else + outputFboId = createRenderTarget(outputRenderTargetId, attachments); + } outputBufferIsDefault = false; } + // Up until this point the input and output rects are normal Qt rectangles. + // Convert them to GL rectangles (Y at bottom). + const int inputFboHeight = inputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[inputFboId].height(); const GLint srcX0 = inputRect.left(); - const GLint srcY0 = inputRect.top(); + const GLint srcY0 = inputFboHeight - (inputRect.top() + inputRect.height()); const GLint srcX1 = srcX0 + inputRect.width(); const GLint srcY1 = srcY0 + inputRect.height(); + const int outputFboHeight = outputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[outputFboId].height(); const GLint dstX0 = outputRect.left(); - const GLint dstY0 = outputRect.top(); + const GLint dstY0 = outputFboHeight - (outputRect.top() + outputRect.height()); const GLint dstX1 = dstX0 + outputRect.width(); const GLint dstY1 = dstY0 + outputRect.height(); @@ -1552,7 +1600,8 @@ void GraphicsContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTarget, bindFramebuffer(outputFboId, GraphicsHelperInterface::FBODraw); //Bind texture - readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint); + if (!inputBufferIsDefault) + readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint); if (!outputBufferIsDefault) drawBuffer(GL_COLOR_ATTACHMENT0 + outputAttachmentPoint); diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h index b07a11c7e..24b08e45e 100644 --- a/src/render/graphicshelpers/graphicscontext_p.h +++ b/src/render/graphicshelpers/graphicscontext_p.h @@ -168,7 +168,7 @@ public: void releaseBuffer(Qt3DCore::QNodeId bufferId); bool hasGLBufferForBuffer(Buffer *buffer); - void blitFramebuffer(Qt3DCore::QNodeId outputRenderTarget, Qt3DCore::QNodeId inputRenderTarget, + void blitFramebuffer(Qt3DCore::QNodeId outputRenderTargetId, Qt3DCore::QNodeId inputRenderTargetId, QRect inputRect, QRect outputRect, uint defaultFboId, QRenderTargetOutput::AttachmentPoint inputAttachmentPoint, @@ -268,6 +268,8 @@ private: GraphicsHelperInterface *resolveHighestOpenGLFunctions(); + GLuint createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments); + GLuint updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget); void bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments); void activateDrawBuffers(const AttachmentPack &attachments); HGLBuffer createGLBufferFor(Buffer *buffer, GLBuffer::Type type); @@ -291,6 +293,7 @@ private: QHash<Qt3DCore::QNodeId, GLuint> m_renderTargets; QHash<GLuint, QSize> m_renderTargetsSize; QAbstractTexture::TextureFormat m_renderTargetFormat; + QSize m_surfaceSize; QHash<QSurface *, GraphicsHelperInterface*> m_glHelpers; diff --git a/src/render/jobs/filterlayerentityjob.cpp b/src/render/jobs/filterlayerentityjob.cpp index 902338be7..f727e0820 100644 --- a/src/render/jobs/filterlayerentityjob.cpp +++ b/src/render/jobs/filterlayerentityjob.cpp @@ -113,6 +113,9 @@ void FilterLayerEntityJob::run() } else { // No LayerFilter set -> retrieve all selectAllEntities(); } + + // sort needed for set_intersection in RenderViewBuilder + std::sort(m_filteredEntities.begin(), m_filteredEntities.end()); } // We accept the entity if it contains any of the layers that are in the layer filter diff --git a/src/render/jobs/filterproximitydistancejob.cpp b/src/render/jobs/filterproximitydistancejob.cpp index b07997336..5067eeba2 100644 --- a/src/render/jobs/filterproximitydistancejob.cpp +++ b/src/render/jobs/filterproximitydistancejob.cpp @@ -82,6 +82,9 @@ void FilterProximityDistanceJob::run() } m_filteredEntities = std::move(entitiesToFilter); } + + // sort needed for set_intersection in RenderViewBuilder + std::sort(m_filteredEntities.begin(), m_filteredEntities.end()); } void FilterProximityDistanceJob::selectAllEntities() diff --git a/src/render/jobs/frustumcullingjob.cpp b/src/render/jobs/frustumcullingjob.cpp index 13ba2b438..85c6b5cad 100644 --- a/src/render/jobs/frustumcullingjob.cpp +++ b/src/render/jobs/frustumcullingjob.cpp @@ -76,6 +76,9 @@ void FrustumCullingJob::run() }; cullScene(m_root, planes); + + // sort needed for set_intersection in RenderViewBuilder + std::sort(m_visibleEntities.begin(), m_visibleEntities.end()); } void FrustumCullingJob::cullScene(Entity *e, const Plane *planes) diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp index 6a6f62916..ffad387c6 100644 --- a/src/render/jobs/renderviewjobutils.cpp +++ b/src/render/jobs/renderviewjobutils.cpp @@ -145,7 +145,7 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN RenderTarget *renderTarget = manager->renderTargetManager()->data(renderTargetHandle); if (renderTarget) - rv->setAttachmentPack(AttachmentPack(targetSelector, renderTarget, manager->attachmentManager())); + rv->setAttachmentPack(AttachmentPack(renderTarget, manager->attachmentManager(), targetSelector->outputs())); } break; } diff --git a/src/render/materialsystem/qshaderprogram.cpp b/src/render/materialsystem/qshaderprogram.cpp index e6f9631d0..0ca8a9947 100644 --- a/src/render/materialsystem/qshaderprogram.cpp +++ b/src/render/materialsystem/qshaderprogram.cpp @@ -54,6 +54,127 @@ \since 5.5 A shader program consists of several different shaders, such as vertex and fragment shaders. + + Qt3D will automatically populate a set of default uniforms if they are + encountered during the shader instrospection phase. + + \table + \header + \li {1, 1} Default Uniform + \li {2, 1} Associated Qt3D Parameter name + \li {3, 1} GLSL declaration + + \row + \li {1, 1} ModelMatrix + \li {2, 1} modelMatrix + \li {3, 1} uniform mat4 modelMatrix; + + \row + \li {1, 1} ViewMatrix + \li {2, 1} viewMatrix + \li {3, 1} uniform mat4 viewMatrix; + + \row + \li {1, 1} ProjectionMatrix + \li {2, 1} projectionMatrix + \li {3, 1} uniform mat4 projectionMatrix; + + \row + \li {1, 1} ModelViewMatrix + \li {2, 1} modelView + \li {3, 1} uniform mat4 modelView; + + \row + \li {1, 1} ViewProjectionMatrix + \li {2, 1} viewProjectionMatrix + \li {3, 1} uniform mat4 viewProjectionMatrix; + + \row + \li {1, 1} ModelViewProjectionMatrix + \li {2, 1} modelViewProjection \br mvp + \li {3, 1} uniform mat4 modelViewProjection; \br uniform mat4 mvp; + + \row + \li {1, 1} InverseModelMatrix + \li {2, 1} inverseModelMatrix + \li {3, 1} uniform mat4 inverseModelMatrix; + + \row + \li {1, 1} InverseViewMatrix + \li {2, 1} inverseViewMatrix + \li {3, 1} uniform mat4 inverseViewMatrix; + + \row + \li {1, 1} InverseProjectionMatrix + \li {2, 1} inverseProjectionMatrix + \li {3, 1} uniform mat4 inverseProjectionMatrix; + + \row + \li {1, 1} InverseModelViewMatrix + \li {2, 1} inverseModelView + \li {3, 1} uniform mat4 inverseModelView; + + \row + \li {1, 1} InverseViewProjectionMatrix + \li {2, 1} inverseViewProjectionMatrix + \li {3, 1} uniform mat4 inverseViewProjectionMatrix; + + \row + \li {1, 1} InverseModelViewProjectionMatrix + \li {2, 1} inverseModelViewProjection + \li {3, 1} uniform mat4 inverseModelViewProjection; + + \row + \li {1, 1} ModelNormalMatrix + \li {2, 1} modelNormalMatrix + \li {3, 1} uniform mat3 modelNormalMatrix; + + \row + \li {1, 1} ModelViewNormalMatrix + \li {2, 1} modelViewNormal + \li {3, 1} uniform mat3 modelViewNormal; + + \row + \li {1, 1} ViewportMatrix + \li {2, 1} viewportMatrix + \li {3, 1} uniform mat4 viewportMatrix; + + \row + \li {1, 1} InverseViewportMatrix + \li {2, 1} inverseViewportMatrix + \li {3, 1} uniform mat4 inverseViewportMatrix; + + \row + \li {1, 1} AspectRatio \br (surface width / surface height) + \li {2, 1} aspectRatio + \li {3, 1} uniform float aspectRatio; + + \row + \li {1, 1} Exposure + \li {2, 1} exposure + \li {3, 1} uniform float exposure; + + \row + \li {1, 1} Gamma + \li {2, 1} gamma + \li {3, 1} uniform float gamma; + + \row + \li {1, 1} Time \br (in nano seconds) + \li {2, 1} time + \li {3, 1} uniform float time; + + \row + \li {1, 1} EyePosition + \li {2, 1} eyePosition + \li {3, 1} uniform vec3 eyePosition; + + \row + \li {1, 1} SkinningPalette + \li {2, 1} skinningPalette[0] + \li {3, 1} const int maxJoints = 100; \br uniform mat4 skinningPalette[maxJoints]; + + \endtable */ /*! @@ -65,6 +186,127 @@ ShaderProgram class encapsulates a shader program. A shader program consists of several different shaders, such as vertex and fragment shaders. + + Qt3D will automatically populate a set of default uniforms if they are + encountered during the shader instrospection phase. + + \table + \header + \li {1, 1} Default Uniform + \li {2, 1} Associated Qt3D Parameter name + \li {3, 1} GLSL declaration + + \row + \li {1, 1} ModelMatrix + \li {2, 1} modelMatrix + \li {3, 1} uniform mat4 modelMatrix; + + \row + \li {1, 1} ViewMatrix + \li {2, 1} viewMatrix + \li {3, 1} uniform mat4 viewMatrix; + + \row + \li {1, 1} ProjectionMatrix + \li {2, 1} projectionMatrix + \li {3, 1} uniform mat4 projectionMatrix; + + \row + \li {1, 1} ModelViewMatrix + \li {2, 1} modelView + \li {3, 1} uniform mat4 modelView; + + \row + \li {1, 1} ViewProjectionMatrix + \li {2, 1} viewProjectionMatrix + \li {3, 1} uniform mat4 viewProjectionMatrix; + + \row + \li {1, 1} ModelViewProjectionMatrix + \li {2, 1} modelViewProjection \br mvp + \li {3, 1} uniform mat4 modelViewProjection; \br uniform mat4 mvp; + + \row + \li {1, 1} InverseModelMatrix + \li {2, 1} inverseModelMatrix + \li {3, 1} uniform mat4 inverseModelMatrix; + + \row + \li {1, 1} InverseViewMatrix + \li {2, 1} inverseViewMatrix + \li {3, 1} uniform mat4 inverseViewMatrix; + + \row + \li {1, 1} InverseProjectionMatrix + \li {2, 1} inverseProjectionMatrix + \li {3, 1} uniform mat4 inverseProjectionMatrix; + + \row + \li {1, 1} InverseModelViewMatrix + \li {2, 1} inverseModelView + \li {3, 1} uniform mat4 inverseModelView; + + \row + \li {1, 1} InverseViewProjectionMatrix + \li {2, 1} inverseViewProjectionMatrix + \li {3, 1} uniform mat4 inverseViewProjectionMatrix; + + \row + \li {1, 1} InverseModelViewProjectionMatrix + \li {2, 1} inverseModelViewProjection + \li {3, 1} uniform mat4 inverseModelViewProjection; + + \row + \li {1, 1} ModelNormalMatrix + \li {2, 1} modelNormalMatrix + \li {3, 1} uniform mat3 modelNormalMatrix; + + \row + \li {1, 1} ModelViewNormalMatrix + \li {2, 1} modelViewNormal + \li {3, 1} uniform mat3 modelViewNormal; + + \row + \li {1, 1} ViewportMatrix + \li {2, 1} viewportMatrix + \li {3, 1} uniform mat4 viewportMatrix; + + \row + \li {1, 1} InverseViewportMatrix + \li {2, 1} inverseViewportMatrix + \li {3, 1} uniform mat4 inverseViewportMatrix; + + \row + \li {1, 1} AspectRatio \br (surface width / surface height) + \li {2, 1} aspectRatio + \li {3, 1} uniform float aspectRatio; + + \row + \li {1, 1} Exposure + \li {2, 1} exposure + \li {3, 1} uniform float exposure; + + \row + \li {1, 1} Gamma + \li {2, 1} gamma + \li {3, 1} uniform float gamma; + + \row + \li {1, 1} Time \br (in nano seconds) + \li {2, 1} time + \li {3, 1} uniform float time; + + \row + \li {1, 1} EyePosition + \li {2, 1} eyePosition + \li {3, 1} uniform vec3 eyePosition; + + \row + \li {1, 1} SkinningPalette + \li {2, 1} skinningPalette[0] + \li {3, 1} const int maxJoints = 100; \br uniform mat4 skinningPalette[maxJoints]; + + \endtable */ /*! diff --git a/src/render/materialsystem/shaderbuilder.cpp b/src/render/materialsystem/shaderbuilder.cpp index c2b32ce86..da1e6a713 100644 --- a/src/render/materialsystem/shaderbuilder.cpp +++ b/src/render/materialsystem/shaderbuilder.cpp @@ -51,6 +51,13 @@ #include <QFileInfo> #include <QUrl> +static void initResources() +{ +#ifdef QT_STATIC + Q_INIT_RESOURCE(materialsystem); +#endif +} + QT_BEGIN_NAMESPACE class GlobalShaderPrototypes @@ -58,6 +65,7 @@ class GlobalShaderPrototypes public: GlobalShaderPrototypes() { + initResources(); setPrototypesFile(QStringLiteral(":/prototypes/default.json")); } diff --git a/src/render/texture/gltexture.cpp b/src/render/texture/gltexture.cpp index 11cc1544f..4665be561 100644 --- a/src/render/texture/gltexture.cpp +++ b/src/render/texture/gltexture.cpp @@ -175,7 +175,8 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture() setDirtyFlag(Properties, true); } } else { - qWarning() << "[Qt3DRender::GLTexture] No QTextureImageData generated from functor yet, texture will be invalid for this frame"; + // No QTextureImageData generated from functor yet, texture will be invalid for this frame + // but will be correctly loaded at frame n+1 texturedDataInvalid = true; } } |