summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-12-11 15:08:00 +0100
committerLiang Qi <liang.qi@qt.io>2018-12-11 15:08:00 +0100
commitc9ce0deeb8f2bb79c446e41584f753f1b1bfe17f (patch)
tree5e9a06346ea22e6e9a2fafd6a2ac7394c73648c6
parentf1b333c36a19cf85eab798fc1b1952ed063fedfe (diff)
parent0a0a7e4ca4f05c7d6da55ec64c8a9734d82853fe (diff)
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts: src/render/renderers/opengl/textures/gltexture.cpp Change-Id: I57e9a296dc15f0b5dc3af3664f698bdc799c4bb5
-rw-r--r--dist/changes-5.11.320
-rw-r--r--dist/changes-5.12.022
-rw-r--r--examples/qt3d/exampleresources/assets/cubemaps/miramar/qt_attribution.json2
-rw-r--r--src/core/aspects/qabstractaspect.cpp20
-rw-r--r--src/core/aspects/qaspectengine.cpp4
-rw-r--r--src/core/nodes/qcomponent.cpp2
-rw-r--r--src/doc/doc.pro10
-rw-r--r--src/doc/qt3d.qdocconf9
-rw-r--r--src/doc/src/qt3d-module.qdoc26
-rw-r--r--src/doc/src/qt3d-overview.qdoc2
-rw-r--r--src/extras/defaults/qmetalroughmaterial.cpp29
-rw-r--r--src/extras/defaults/qmetalroughmaterial_p.h4
-rw-r--r--src/extras/defaults/qt3dwindow.cpp17
-rw-r--r--src/extras/defaults/qt3dwindow.h1
-rw-r--r--src/extras/extras.qrc1
-rw-r--r--src/extras/shaders/es3/coordinatesystems.inc73
-rw-r--r--src/extras/shaders/es3/light.inc.frag16
-rw-r--r--src/extras/shaders/es3/metalrough.inc.frag190
-rw-r--r--src/extras/shaders/gl3/distancefieldtext.frag2
-rw-r--r--src/extras/shaders/gl3/distancefieldtext.vert2
-rw-r--r--src/extras/text/qtext2dentity.cpp95
-rw-r--r--src/logic/qframeaction.cpp1
-rw-r--r--src/render/backend/rendersettings.cpp5
-rw-r--r--src/render/frontend/qrenderaspect.cpp1
-rw-r--r--src/render/geometry/qgeometryrenderer.cpp4
-rw-r--r--src/render/jobs/pickboundingvolumejob.cpp8
-rw-r--r--src/render/materialsystem/prototypes/default.json9
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp17
-rw-r--r--src/render/renderers/opengl/textures/gltexture.cpp1
-rw-r--r--src/src.pro13
-rw-r--r--tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp88
-rw-r--r--tests/benchmarks/core/core.pro2
-rw-r--r--tools/tools.pro2
33 files changed, 541 insertions, 157 deletions
diff --git a/dist/changes-5.11.3 b/dist/changes-5.11.3
new file mode 100644
index 000000000..f71fa3412
--- /dev/null
+++ b/dist/changes-5.11.3
@@ -0,0 +1,20 @@
+Qt 5.11.3 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.11.0 through 5.11.2.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.11 series is binary compatible with the 5.10.x series.
+Applications compiled for 5.10 will continue to run with 5.11.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+ - This release contains only minor code improvements.
diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0
new file mode 100644
index 000000000..a877c37cc
--- /dev/null
+++ b/dist/changes-5.12.0
@@ -0,0 +1,22 @@
+Qt 5.12 introduces many new features and improvements as well as bugfixes
+over the 5.11.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+https://doc.qt.io/qt-5/index.html
+
+The Qt version 5.12 series is binary compatible with the 5.11.x series.
+Applications compiled for 5.11 will continue to run with 5.12.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Qt 5.12.0 changes *
+****************************************************************************
+
+ - EntityLoader now also supports loading an Entity from a Component
diff --git a/examples/qt3d/exampleresources/assets/cubemaps/miramar/qt_attribution.json b/examples/qt3d/exampleresources/assets/cubemaps/miramar/qt_attribution.json
index 6eccf001c..d8b65eec0 100644
--- a/examples/qt3d/exampleresources/assets/cubemaps/miramar/qt_attribution.json
+++ b/examples/qt3d/exampleresources/assets/cubemaps/miramar/qt_attribution.json
@@ -9,6 +9,6 @@
"Homepage": "http://www.zfight.com/misc/files/textures/envmap_miramar.rar",
"DownloadLocation": "https://opengameart.org/sites/default/files/envmap_miramar.zip",
"License": "Modify however you like, just cred me for my work, maybe link to my page.",
- "LicenseFile": "README.txt",
+ "LicenseFile": "README.TXT",
"Copyright": "Copyright (c) Jockum Skoglund aka hipshot"
}
diff --git a/src/core/aspects/qabstractaspect.cpp b/src/core/aspects/qabstractaspect.cpp
index e793eebca..7b08dec81 100644
--- a/src/core/aspects/qabstractaspect.cpp
+++ b/src/core/aspects/qabstractaspect.cpp
@@ -101,6 +101,26 @@ void QAbstractAspectPrivate::unregisterBackendType(const QMetaObject &mo)
*/
/*!
+ * \macro QT3D_REGISTER_ASPECT(name, AspectType)
+ * \relates Qt3DCore::QAbstractAspect
+ *
+ * Convenience macro for registering \a AspectType for instantiation by the
+ * currently set Qt3DCore::QAspectFactory. This makes it possible to create an
+ * instance of \a AspectType in the aspect thread by later passing \a name to
+ * Qt3DCore::QAspectEngine::registerAspect(const QString &name).
+ *
+ * \note It is also possible to register a new aspect without using this macro
+ * by instead using Qt3DCore::QAspectEngine::registerAspect(QAbstractAspect *aspect)
+ * which will handle moving a previously created aspect instance to the aspect
+ * thread context.
+ *
+ * KDAB has published a few articles about writing custom Qt3D aspects
+ * \l {https://www.kdab.com/writing-custom-qt-3d-aspect/}{on their blog}. These
+ * provide an excellent starting point if you wish to learn more about it.
+ */
+
+
+/*!
* Constructs a new QAbstractAspect with \a parent
*/
QAbstractAspect::QAbstractAspect(QObject *parent)
diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp
index b7a8c84b1..3f219597e 100644
--- a/src/core/aspects/qaspectengine.cpp
+++ b/src/core/aspects/qaspectengine.cpp
@@ -274,8 +274,8 @@ void QAspectEnginePrivate::exitSimulationLoop()
}
/*!
- * Registers a new \a aspect to the AspectManager. The QAspectEngine takes
- * ownership of the aspect and will delete it when the aspect is unregistered.
+ Registers a new \a aspect to the AspectManager. The QAspectEngine takes
+ ownership of the aspect and will delete it when the aspect is unregistered.
//! Called in the main thread
*/
void QAspectEngine::registerAspect(QAbstractAspect *aspect)
diff --git a/src/core/nodes/qcomponent.cpp b/src/core/nodes/qcomponent.cpp
index e678880e8..5ca49ff30 100644
--- a/src/core/nodes/qcomponent.cpp
+++ b/src/core/nodes/qcomponent.cpp
@@ -112,7 +112,7 @@ void QComponentPrivate::removeEntity(QEntity *entity)
*/
/*!
- \fn Qt3DCore::QComponent::addedToEntity(Qt3DCore::QEntity *entity)'
+ \fn Qt3DCore::QComponent::addedToEntity(Qt3DCore::QEntity *entity)
Indicates that a reference has been added to \a entity.
*/
diff --git a/src/doc/doc.pro b/src/doc/doc.pro
index 34ef2f2b4..ab6d8e9a6 100644
--- a/src/doc/doc.pro
+++ b/src/doc/doc.pro
@@ -1,5 +1,15 @@
TEMPLATE = aux
+CONFIG += force_qt
+
+# Add Qt 3D modules for which QDoc needs include paths passed
+QT += \
+ core-private \
+ 3dcore-private \
+ 3drender-private \
+ 3dinput-private \
+ 3danimation-private
+
QMAKE_DOCS = $$PWD/qt3d.qdocconf
OTHER_FILES += $$PWD/src/*.qdoc
diff --git a/src/doc/qt3d.qdocconf b/src/doc/qt3d.qdocconf
index 5ea4cd6f8..798dcbfd7 100644
--- a/src/doc/qt3d.qdocconf
+++ b/src/doc/qt3d.qdocconf
@@ -5,14 +5,7 @@ description = Qt 3D Reference Documentation
version = $QT_VERSION
moduleheader = Qt3DDoc
-includepaths = -I . \
- -I $QT_INSTALL_HEADERS \
- -I $QT_INSTALL_HEADERS/Qt3DCore \
- -I $QT_INSTALL_HEADERS/Qt3DCore/$QT_VERSION \
- -I $QT_INSTALL_HEADERS/Qt3DAnimation \
- -I $QT_INSTALL_HEADERS/Qt3DAnimation/$QT_VERSION \
- -I $QT_INSTALL_HEADERS/Qt3DInput \
- -I $QT_INSTALL_HEADERS/Qt3DInput/$QT_VERSION
+includepaths = -I .
examplesinstallpath = qt3d
diff --git a/src/doc/src/qt3d-module.qdoc b/src/doc/src/qt3d-module.qdoc
index 12a2e8761..e6dcf359e 100644
--- a/src/doc/src/qt3d-module.qdoc
+++ b/src/doc/src/qt3d-module.qdoc
@@ -69,23 +69,23 @@
The Qt 3D core QML types are imported with
- \badcode
- import Qt3D.Core 2.0
- \endcode
+ \qml \QtMinorVersion
+ import Qt3D.Core 2.\1
+ \endqml
Other modules import functionality for collision detection, rendering, input,
and animation. The complete list of Qt 3D import statements:
- \badcode
- import Qt3D.Core 2.0
- import Qt3D.Render 2.0
- import Qt3D.Input 2.0
- import Qt3D.Logic 2.0
- import Qt3D.Extras 2.0
- import Qt3D.Animation 2.9
- import QtQuick.Scene2D 2.9
- import QtQuick.Scene3D 2.0
- \endcode
+ \qml \QtMinorVersion
+ import Qt3D.Core 2.\1
+ import Qt3D.Render 2.\1
+ import Qt3D.Input 2.\1
+ import Qt3D.Logic 2.\1
+ import Qt3D.Extras 2.\1
+ import Qt3D.Animation 2.\1
+ import QtQuick.Scene2D 2.\1
+ import QtQuick.Scene3D 2.\1
+ \endqml
\section1 QML Types
diff --git a/src/doc/src/qt3d-overview.qdoc b/src/doc/src/qt3d-overview.qdoc
index ec78791d6..aaf246203 100644
--- a/src/doc/src/qt3d-overview.qdoc
+++ b/src/doc/src/qt3d-overview.qdoc
@@ -60,7 +60,7 @@
\li Multitexturing
\li \l {Instanced Rendering}{Instanced rendering}
\li \l {Uniform Buffer Objects}
- \li \l {Pro Tips}
+ \li \l {Qt 3D Render Pro Tips}{Pro Tips}
\endlist
\section2 Materials
diff --git a/src/extras/defaults/qmetalroughmaterial.cpp b/src/extras/defaults/qmetalroughmaterial.cpp
index 1cf114423..de21268f1 100644
--- a/src/extras/defaults/qmetalroughmaterial.cpp
+++ b/src/extras/defaults/qmetalroughmaterial.cpp
@@ -79,6 +79,10 @@ QMetalRoughMaterialPrivate::QMetalRoughMaterialPrivate()
, m_metalRoughGL3RenderPass(new QRenderPass())
, m_metalRoughGL3Shader(new QShaderProgram())
, m_metalRoughGL3ShaderBuilder(new QShaderProgramBuilder())
+ , m_metalRoughES3Technique(new QTechnique())
+ , m_metalRoughES3RenderPass(new QRenderPass())
+ , m_metalRoughES3Shader(new QShaderProgram())
+ , m_metalRoughES3ShaderBuilder(new QShaderProgramBuilder())
, m_filterKey(new QFilterKey)
{
m_environmentIrradianceTexture->setMagnificationFilter(QAbstractTexture::Linear);
@@ -112,7 +116,6 @@ void QMetalRoughMaterialPrivate::init()
this, &QMetalRoughMaterialPrivate::handleTextureScaleChanged);
m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/default.vert"))));
-
m_metalRoughGL3ShaderBuilder->setParent(q);
m_metalRoughGL3ShaderBuilder->setShaderProgram(m_metalRoughGL3Shader);
m_metalRoughGL3ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/metalrough.frag.json")));
@@ -122,11 +125,25 @@ void QMetalRoughMaterialPrivate::init()
QStringLiteral("ambientOcclusion"),
QStringLiteral("normal")});
+ m_metalRoughES3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es3/default.vert"))));
+ m_metalRoughES3ShaderBuilder->setParent(q);
+ m_metalRoughES3ShaderBuilder->setShaderProgram(m_metalRoughES3Shader);
+ m_metalRoughES3ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/metalrough.frag.json")));
+ m_metalRoughES3ShaderBuilder->setEnabledLayers({QStringLiteral("baseColor"),
+ QStringLiteral("metalness"),
+ QStringLiteral("roughness"),
+ QStringLiteral("ambientOcclusion"),
+ QStringLiteral("normal")});
+
m_metalRoughGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
m_metalRoughGL3Technique->graphicsApiFilter()->setMajorVersion(3);
m_metalRoughGL3Technique->graphicsApiFilter()->setMinorVersion(1);
m_metalRoughGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+ m_metalRoughES3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_metalRoughES3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_metalRoughES3Technique->graphicsApiFilter()->setMinorVersion(0);
+
m_filterKey->setParent(q);
m_filterKey->setName(QStringLiteral("renderingStyle"));
m_filterKey->setValue(QStringLiteral("forward"));
@@ -136,6 +153,11 @@ void QMetalRoughMaterialPrivate::init()
m_metalRoughGL3Technique->addRenderPass(m_metalRoughGL3RenderPass);
m_metalRoughEffect->addTechnique(m_metalRoughGL3Technique);
+ m_metalRoughES3Technique->addFilterKey(m_filterKey);
+ m_metalRoughES3RenderPass->setShaderProgram(m_metalRoughES3Shader);
+ m_metalRoughES3Technique->addRenderPass(m_metalRoughES3RenderPass);
+ m_metalRoughEffect->addTechnique(m_metalRoughES3Technique);
+
m_metalRoughEffect->addParameter(m_baseColorParameter);
m_metalRoughEffect->addParameter(m_metalnessParameter);
m_metalRoughEffect->addParameter(m_roughnessParameter);
@@ -291,6 +313,7 @@ void QMetalRoughMaterial::setBaseColor(const QVariant &baseColor)
d->m_metalRoughEffect->addParameter(d->m_baseColorParameter);
}
d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers);
+ d->m_metalRoughES3ShaderBuilder->setEnabledLayers(layers);
}
void QMetalRoughMaterial::setMetalness(const QVariant &metalness)
@@ -312,6 +335,7 @@ void QMetalRoughMaterial::setMetalness(const QVariant &metalness)
d->m_metalRoughEffect->addParameter(d->m_metalnessParameter);
}
d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers);
+ d->m_metalRoughES3ShaderBuilder->setEnabledLayers(layers);
}
void QMetalRoughMaterial::setRoughness(const QVariant &roughness)
@@ -333,6 +357,7 @@ void QMetalRoughMaterial::setRoughness(const QVariant &roughness)
d->m_metalRoughEffect->addParameter(d->m_roughnessParameter);
}
d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers);
+ d->m_metalRoughES3ShaderBuilder->setEnabledLayers(layers);
}
void QMetalRoughMaterial::setAmbientOcclusion(const QVariant &ambientOcclusion)
@@ -351,6 +376,7 @@ void QMetalRoughMaterial::setAmbientOcclusion(const QVariant &ambientOcclusion)
d->m_metalRoughEffect->removeParameter(d->m_ambientOcclusionMapParameter);
}
d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers);
+ d->m_metalRoughES3ShaderBuilder->setEnabledLayers(layers);
}
void QMetalRoughMaterial::setNormal(const QVariant &normal)
@@ -369,6 +395,7 @@ void QMetalRoughMaterial::setNormal(const QVariant &normal)
d->m_metalRoughEffect->removeParameter(d->m_normalMapParameter);
}
d->m_metalRoughGL3ShaderBuilder->setEnabledLayers(layers);
+ d->m_metalRoughES3ShaderBuilder->setEnabledLayers(layers);
}
void QMetalRoughMaterial::setTextureScale(float textureScale)
diff --git a/src/extras/defaults/qmetalroughmaterial_p.h b/src/extras/defaults/qmetalroughmaterial_p.h
index 838474490..e12df1a8b 100644
--- a/src/extras/defaults/qmetalroughmaterial_p.h
+++ b/src/extras/defaults/qmetalroughmaterial_p.h
@@ -99,6 +99,10 @@ public:
Qt3DRender::QRenderPass *m_metalRoughGL3RenderPass;
Qt3DRender::QShaderProgram *m_metalRoughGL3Shader;
Qt3DRender::QShaderProgramBuilder *m_metalRoughGL3ShaderBuilder;
+ Qt3DRender::QTechnique *m_metalRoughES3Technique;
+ Qt3DRender::QRenderPass *m_metalRoughES3RenderPass;
+ Qt3DRender::QShaderProgram *m_metalRoughES3Shader;
+ Qt3DRender::QShaderProgramBuilder *m_metalRoughES3ShaderBuilder;
Qt3DRender::QFilterKey *m_filterKey;
Q_DECLARE_PUBLIC(QMetalRoughMaterial)
diff --git a/src/extras/defaults/qt3dwindow.cpp b/src/extras/defaults/qt3dwindow.cpp
index 7091628ba..2df4716dd 100644
--- a/src/extras/defaults/qt3dwindow.cpp
+++ b/src/extras/defaults/qt3dwindow.cpp
@@ -62,6 +62,8 @@
#include <Qt3DRender/qcamera.h>
#include <QtGui/qopenglcontext.h>
+#include <QEvent>
+
static void initResources()
{
#ifdef QT_STATIC
@@ -227,6 +229,7 @@ void Qt3DWindow::showEvent(QShowEvent *e)
QWindow::showEvent(e);
}
+
/*!
Resets the aspect ratio of the 3D window.
*/
@@ -236,6 +239,20 @@ void Qt3DWindow::resizeEvent(QResizeEvent *)
d->m_defaultCamera->setAspectRatio(float(width()) / float(height()));
}
+/*!
+ \reimp
+
+ Requests renderer to redraw if we are using OnDemand render policy.
+*/
+bool Qt3DWindow::event(QEvent *e)
+{
+ Q_D(Qt3DWindow);
+ const bool needsRedraw = (e->type() == QEvent::Expose || e->type() == QEvent::UpdateRequest);
+ if (needsRedraw && d->m_renderSettings->renderPolicy() == Qt3DRender::QRenderSettings::OnDemand)
+ d->m_renderSettings->sendCommand(QLatin1Literal("InvalidateFrame"));
+ return QWindow::event(e);
+}
+
} // Qt3DExtras
QT_END_NAMESPACE
diff --git a/src/extras/defaults/qt3dwindow.h b/src/extras/defaults/qt3dwindow.h
index 73a6af278..7020a2bd5 100644
--- a/src/extras/defaults/qt3dwindow.h
+++ b/src/extras/defaults/qt3dwindow.h
@@ -112,6 +112,7 @@ Q_SIGNALS:
protected:
void showEvent(QShowEvent *e) override;
void resizeEvent(QResizeEvent *) override;
+ bool event(QEvent *e) override;
private:
Q_DECLARE_PRIVATE(Qt3DWindow)
diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc
index 8bbffd272..2aedc6622 100644
--- a/src/extras/extras.qrc
+++ b/src/extras/extras.qrc
@@ -13,6 +13,7 @@
<file>shaders/es3/metalrough.inc.frag</file>
<file>shaders/gl3/coordinatesystems.inc</file>
<file>shaders/es2/coordinatesystems.inc</file>
+ <file>shaders/es3/coordinatesystems.inc</file>
<file>shaders/gl3/default.vert</file>
<file>shaders/es2/default.vert</file>
<file>shaders/es3/default.vert</file>
diff --git a/src/extras/shaders/es3/coordinatesystems.inc b/src/extras/shaders/es3/coordinatesystems.inc
new file mode 100644
index 000000000..9c0f99ddd
--- /dev/null
+++ b/src/extras/shaders/es3/coordinatesystems.inc
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FP
+#define FP highp
+#endif
+
+FP mat3 calcWorldSpaceToTangentSpaceMatrix(const in FP vec3 wNormal, const in FP vec4 wTangent)
+{
+ // Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
+ // This allows to build the tangentMatrix below by simply transposing the
+ // tangent -> eyespace matrix (which would now be orthogonal)
+ FP vec3 wFixedTangent = normalize(wTangent.xyz - dot(wTangent.xyz, wNormal) * wNormal);
+
+ // Calculate binormal vector. No "real" need to renormalize it,
+ // as built by crossing two normal vectors.
+ // To orient the binormal correctly, use the fourth coordinate of the tangent,
+ // which is +1 for a right hand system, and -1 for a left hand system.
+ FP vec3 wBinormal = cross(wNormal, wFixedTangent.xyz) * wTangent.w;
+
+ // Construct matrix to transform from world space to tangent space
+ // This is the transpose of the tangentToWorld transformation matrix
+ FP mat3 tangentToWorldMatrix = mat3(wFixedTangent, wBinormal, wNormal);
+ FP mat3 worldToTangentMatrix = transpose(tangentToWorldMatrix);
+ return worldToTangentMatrix;
+}
diff --git a/src/extras/shaders/es3/light.inc.frag b/src/extras/shaders/es3/light.inc.frag
index 9d03fca54..18012ccc1 100644
--- a/src/extras/shaders/es3/light.inc.frag
+++ b/src/extras/shaders/es3/light.inc.frag
@@ -4,14 +4,14 @@ const int TYPE_DIRECTIONAL = 1;
const int TYPE_SPOT = 2;
struct Light {
int type;
- vec3 position;
- vec3 color;
- float intensity;
- vec3 direction;
- float constantAttenuation;
- float linearAttenuation;
- float quadraticAttenuation;
- float cutOffAngle;
+ FP vec3 position;
+ FP vec3 color;
+ FP float intensity;
+ FP vec3 direction;
+ FP float constantAttenuation;
+ FP float linearAttenuation;
+ FP float quadraticAttenuation;
+ FP float cutOffAngle;
};
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
diff --git a/src/extras/shaders/es3/metalrough.inc.frag b/src/extras/shaders/es3/metalrough.inc.frag
index 85f392f4c..188a367f5 100644
--- a/src/extras/shaders/es3/metalrough.inc.frag
+++ b/src/extras/shaders/es3/metalrough.inc.frag
@@ -48,46 +48,48 @@
**
****************************************************************************/
-precision highp float;
+#ifndef FP
+#define FP highp
+#endif
// Exposure correction
-uniform float exposure;
+uniform FP float exposure;
// Gamma correction
-const float gamma = 2.2;
+const FP float gamma = 2.2;
#pragma include light.inc.frag
-int mipLevelCount(const in samplerCube cube)
+int mipLevelCount(const in FP samplerCube cube)
{
int baseSize = textureSize(cube, 0).x;
int nMips = int(log2(float(baseSize > 0 ? baseSize : 1))) + 1;
return nMips;
}
-float remapRoughness(const in float roughness)
+FP float remapRoughness(const in FP float roughness)
{
// As per page 14 of
// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
// we remap the roughness to give a more perceptually linear response
// of "bluriness" as a function of the roughness specified by the user.
// r = roughness^2
- const float maxSpecPower = 999999.0;
- const float minRoughness = sqrt(2.0 / (maxSpecPower + 2.0));
+ const FP float maxSpecPower = 999999.0;
+ const FP float minRoughness = sqrt(2.0 / (maxSpecPower + 2.0));
return max(roughness * roughness, minRoughness);
}
-float alphaToMipLevel(float alpha)
+FP float alphaToMipLevel(FP float alpha)
{
- float specPower = 2.0 / (alpha * alpha) - 2.0;
+ FP float specPower = 2.0 / (alpha * alpha) - 2.0;
// We use the mip level calculation from Lys' default power drop, which in
// turn is a slight modification of that used in Marmoset Toolbag. See
// https://docs.knaldtech.com/doku.php?id=specular_lys for details.
// For now we assume a max specular power of 999999 which gives
// maxGlossiness = 1.
- const float k0 = 0.00098;
- const float k1 = 0.9921;
- float glossiness = (pow(2.0, -10.0 / sqrt(specPower)) - k0) / k1;
+ const FP float k0 = 0.00098;
+ const FP float k1 = 0.9921;
+ FP float glossiness = (pow(2.0, -10.0 / sqrt(specPower)) - k0) / k1;
// TODO: Optimize by doing this on CPU and set as
// uniform int envLight.specularMipLevels say (if present in shader).
@@ -96,35 +98,35 @@ float alphaToMipLevel(float alpha)
// Offset of smallest miplevel we should use (corresponds to specular
// power of 1). I.e. in the 32x32 sized mip.
- const float mipOffset = 5.0;
+ const FP float mipOffset = 5.0;
// The final factor is really 1 - g / g_max but as mentioned above g_max
// is 1 by definition here so we can avoid the division. If we make the
// max specular power for the spec map configurable, this will need to
// be handled properly.
- float mipLevel = (float(mipLevels) - 1.0 - mipOffset) * (1.0 - glossiness);
+ FP float mipLevel = (float(mipLevels) - 1.0 - mipOffset) * (1.0 - glossiness);
return mipLevel;
}
-float normalDistribution(const in vec3 n, const in vec3 h, const in float alpha)
+FP float normalDistribution(const in FP vec3 n, const in FP vec3 h, const in FP float alpha)
{
// Blinn-Phong approximation - see
// http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html
- float specPower = 2.0 / (alpha * alpha) - 2.0;
+ FP float specPower = 2.0 / (alpha * alpha) - 2.0;
return (specPower + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), specPower);
}
-vec3 fresnelFactor(const in vec3 color, const in float cosineFactor)
+FP vec3 fresnelFactor(const in FP vec3 color, const in FP float cosineFactor)
{
// Calculate the Fresnel effect value
- vec3 f = color;
- vec3 F = f + (1.0 - f) * pow(1.0 - cosineFactor, 5.0);
+ FP vec3 f = color;
+ FP vec3 F = f + (1.0 - f) * pow(1.0 - cosineFactor, 5.0);
return clamp(F, f, vec3(1.0));
}
-float geometricModel(const in float lDotN,
- const in float vDotN,
- const in vec3 h)
+FP float geometricModel(const in FP float lDotN,
+ const in FP float vDotN,
+ const in FP vec3 h)
{
// Implicit geometric model (equal to denominator in specular model).
// This currently assumes that there is no attenuation by geometric shadowing or
@@ -132,50 +134,50 @@ float geometricModel(const in float lDotN,
return lDotN * vDotN;
}
-vec3 specularModel(const in vec3 F0,
- const in float sDotH,
- const in float sDotN,
- const in float vDotN,
- const in vec3 n,
- const in vec3 h)
+FP vec3 specularModel(const in FP vec3 F0,
+ const in FP float sDotH,
+ const in FP float sDotN,
+ const in FP float vDotN,
+ const in FP vec3 n,
+ const in FP vec3 h)
{
// Clamp sDotN and vDotN to small positive value to prevent the
// denominator in the reflection equation going to infinity. Balance this
// by using the clamped values in the geometric factor function to
// avoid ugly seams in the specular lighting.
- float sDotNPrime = max(sDotN, 0.001);
- float vDotNPrime = max(vDotN, 0.001);
+ FP float sDotNPrime = max(sDotN, 0.001);
+ FP float vDotNPrime = max(vDotN, 0.001);
- vec3 F = fresnelFactor(F0, sDotH);
- float G = geometricModel(sDotNPrime, vDotNPrime, h);
+ FP vec3 F = fresnelFactor(F0, sDotH);
+ FP float G = geometricModel(sDotNPrime, vDotNPrime, h);
- vec3 cSpec = F * G / (4.0 * sDotNPrime * vDotNPrime);
+ FP vec3 cSpec = F * G / (4.0 * sDotNPrime * vDotNPrime);
return clamp(cSpec, vec3(0.0), vec3(1.0));
}
-vec3 pbrModel(const in int lightIndex,
- const in vec3 wPosition,
- const in vec3 wNormal,
- const in vec3 wView,
- const in vec3 baseColor,
- const in float metalness,
- const in float alpha,
- const in float ambientOcclusion)
+FP vec3 pbrModel(const in int lightIndex,
+ const in FP vec3 wPosition,
+ const in FP vec3 wNormal,
+ const in FP vec3 wView,
+ const in FP vec3 baseColor,
+ const in FP float metalness,
+ const in FP float alpha,
+ const in FP float ambientOcclusion)
{
// Calculate some useful quantities
- vec3 n = wNormal;
- vec3 s = vec3(0.0);
- vec3 v = wView;
- vec3 h = vec3(0.0);
+ FP vec3 n = wNormal;
+ FP vec3 s = vec3(0.0);
+ FP vec3 v = wView;
+ FP vec3 h = vec3(0.0);
- float vDotN = dot(v, n);
- float sDotN = 0.0;
- float sDotH = 0.0;
- float att = 1.0;
+ FP float vDotN = dot(v, n);
+ FP float sDotN = 0.0;
+ FP float sDotH = 0.0;
+ FP float att = 1.0;
if (lights[lightIndex].type != TYPE_DIRECTIONAL) {
// Point and Spot lights
- vec3 sUnnormalized = vec3(lights[lightIndex].position) - wPosition;
+ FP vec3 sUnnormalized = vec3(lights[lightIndex].position) - wPosition;
s = normalize(sUnnormalized);
// Calculate the attenuation factor
@@ -184,7 +186,7 @@ vec3 pbrModel(const in int lightIndex,
if (lights[lightIndex].constantAttenuation != 0.0
|| lights[lightIndex].linearAttenuation != 0.0
|| lights[lightIndex].quadraticAttenuation != 0.0) {
- float dist = length(sUnnormalized);
+ FP float dist = length(sUnnormalized);
att = 1.0 / (lights[lightIndex].constantAttenuation +
lights[lightIndex].linearAttenuation * dist +
lights[lightIndex].quadraticAttenuation * dist * dist);
@@ -208,22 +210,22 @@ vec3 pbrModel(const in int lightIndex,
sDotH = dot(s, h);
// Calculate diffuse component
- vec3 diffuseColor = (1.0 - metalness) * baseColor * lights[lightIndex].color;
- vec3 diffuse = diffuseColor * max(sDotN, 0.0) / 3.14159;
+ FP vec3 diffuseColor = (1.0 - metalness) * baseColor * lights[lightIndex].color;
+ FP vec3 diffuse = diffuseColor * max(sDotN, 0.0) / 3.14159;
// Calculate specular component
- vec3 dielectricColor = vec3(0.04);
- vec3 F0 = mix(dielectricColor, baseColor, metalness);
- vec3 specularFactor = vec3(0.0);
+ FP vec3 dielectricColor = vec3(0.04);
+ FP vec3 F0 = mix(dielectricColor, baseColor, metalness);
+ FP vec3 specularFactor = vec3(0.0);
if (sDotN > 0.0) {
specularFactor = specularModel(F0, sDotH, sDotN, vDotN, n, h);
specularFactor *= normalDistribution(n, h, alpha);
}
- vec3 specularColor = lights[lightIndex].color;
- vec3 specular = specularColor * specularFactor;
+ FP vec3 specularColor = lights[lightIndex].color;
+ FP vec3 specular = specularColor * specularFactor;
// Blend between diffuse and specular to conserver energy
- vec3 color = att * lights[lightIndex].intensity * (specular + diffuse * (vec3(1.0) - specular));
+ FP vec3 color = att * lights[lightIndex].intensity * (specular + diffuse * (vec3(1.0) - specular));
// Reduce by ambient occlusion amount
color *= ambientOcclusion;
@@ -231,36 +233,36 @@ vec3 pbrModel(const in int lightIndex,
return color;
}
-vec3 pbrIblModel(const in vec3 wNormal,
- const in vec3 wView,
- const in vec3 baseColor,
- const in float metalness,
- const in float alpha,
- const in float ambientOcclusion)
+FP vec3 pbrIblModel(const in FP vec3 wNormal,
+ const in FP vec3 wView,
+ const in FP vec3 baseColor,
+ const in FP float metalness,
+ const in FP float alpha,
+ const in FP float ambientOcclusion)
{
// Calculate reflection direction of view vector about surface normal
// vector in world space. This is used in the fragment shader to sample
// from the environment textures for a light source. This is equivalent
// to the l vector for punctual light sources. Armed with this, calculate
// the usual factors needed
- vec3 n = wNormal;
- vec3 l = reflect(-wView, n);
- vec3 v = wView;
- vec3 h = normalize(l + v);
- float vDotN = dot(v, n);
- float lDotN = dot(l, n);
- float lDotH = dot(l, h);
+ FP vec3 n = wNormal;
+ FP vec3 l = reflect(-wView, n);
+ FP vec3 v = wView;
+ FP vec3 h = normalize(l + v);
+ FP float vDotN = dot(v, n);
+ FP float lDotN = dot(l, n);
+ FP float lDotH = dot(l, h);
// Calculate diffuse component
- vec3 diffuseColor = (1.0 - metalness) * baseColor;
- vec3 diffuse = diffuseColor * texture(envLight.irradiance, l).rgb;
+ FP vec3 diffuseColor = (1.0 - metalness) * baseColor;
+ FP vec3 diffuse = diffuseColor * texture(envLight.irradiance, l).rgb;
// Calculate specular component
- vec3 dielectricColor = vec3(0.04);
- vec3 F0 = mix(dielectricColor, baseColor, metalness);
- vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h);
+ FP vec3 dielectricColor = vec3(0.04);
+ FP vec3 F0 = mix(dielectricColor, baseColor, metalness);
+ FP vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h);
- float lod = alphaToMipLevel(alpha);
+ FP float lod = alphaToMipLevel(alpha);
//#define DEBUG_SPECULAR_LODS
#ifdef DEBUG_SPECULAR_LODS
if (lod > 7.0)
@@ -280,11 +282,11 @@ vec3 pbrIblModel(const in vec3 wNormal,
else if (lod > 0.0)
return vec3(1.0, 0.0, 1.0);
#endif
- vec3 specularSkyColor = textureLod(envLight.specular, l, lod).rgb;
- vec3 specular = specularSkyColor * specularFactor;
+ FP vec3 specularSkyColor = textureLod(envLight.specular, l, lod).rgb;
+ FP vec3 specular = specularSkyColor * specularFactor;
// Blend between diffuse and specular to conserve energy
- vec3 color = specular + diffuse * (vec3(1.0) - specularFactor);
+ FP vec3 color = specular + diffuse * (vec3(1.0) - specularFactor);
// Reduce by ambient occlusion amount
color *= ambientOcclusion;
@@ -292,28 +294,28 @@ vec3 pbrIblModel(const in vec3 wNormal,
return color;
}
-vec3 toneMap(const in vec3 c)
+FP vec3 toneMap(const in FP vec3 c)
{
return c / (c + vec3(1.0));
}
-vec3 gammaCorrect(const in vec3 color)
+FP vec3 gammaCorrect(const in FP vec3 color)
{
return pow(color, vec3(1.0 / gamma));
}
-vec4 metalRoughFunction(const in vec4 baseColor,
- const in float metalness,
- const in float roughness,
- const in float ambientOcclusion,
- const in vec3 worldPosition,
- const in vec3 worldView,
- const in vec3 worldNormal)
+FP vec4 metalRoughFunction(const in FP vec4 baseColor,
+ const in FP float metalness,
+ const in FP float roughness,
+ const in FP float ambientOcclusion,
+ const in FP vec3 worldPosition,
+ const in FP vec3 worldView,
+ const in FP vec3 worldNormal)
{
- vec3 cLinear = vec3(0.0);
+ FP vec3 cLinear = vec3(0.0);
// Remap roughness for a perceptually more linear correspondence
- float alpha = remapRoughness(roughness);
+ FP float alpha = remapRoughness(roughness);
for (int i = 0; i < envLightCount; ++i) {
cLinear += pbrIblModel(worldNormal,
@@ -339,10 +341,10 @@ vec4 metalRoughFunction(const in vec4 baseColor,
cLinear *= pow(2.0, exposure);
// Apply simple (Reinhard) tonemap transform to get into LDR range [0, 1]
- vec3 cToneMapped = toneMap(cLinear);
+ FP vec3 cToneMapped = toneMap(cLinear);
// Apply gamma correction prior to display
- vec3 cGamma = gammaCorrect(cToneMapped);
+ FP vec3 cGamma = gammaCorrect(cToneMapped);
return vec4(cGamma, 1.0);
}
diff --git a/src/extras/shaders/gl3/distancefieldtext.frag b/src/extras/shaders/gl3/distancefieldtext.frag
index c53f3df55..23dff8e0f 100644
--- a/src/extras/shaders/gl3/distancefieldtext.frag
+++ b/src/extras/shaders/gl3/distancefieldtext.frag
@@ -1,4 +1,4 @@
-#version 130
+#version 150 core
uniform sampler2D distanceFieldTexture;
uniform float minAlpha;
diff --git a/src/extras/shaders/gl3/distancefieldtext.vert b/src/extras/shaders/gl3/distancefieldtext.vert
index 74a48f426..f6743001c 100644
--- a/src/extras/shaders/gl3/distancefieldtext.vert
+++ b/src/extras/shaders/gl3/distancefieldtext.vert
@@ -1,4 +1,4 @@
-#version 130
+#version 150 core
in vec3 vertexPosition;
in vec2 vertexTexCoord;
diff --git a/src/extras/text/qtext2dentity.cpp b/src/extras/text/qtext2dentity.cpp
index ae25e8ecc..aa4785fe7 100644
--- a/src/extras/text/qtext2dentity.cpp
+++ b/src/extras/text/qtext2dentity.cpp
@@ -69,6 +69,72 @@ inline Q_DECL_CONSTEXPR QRectF scaleRectF(const QRectF &rect, float scale)
namespace Qt3DExtras {
+/*!
+ * \qmltype Text2DEntity
+ * \instantiates Qt3DExtras::QText2DEntity
+ * \inqmlmodule Qt3D.Extras
+ * \brief Text2DEntity allows creation of a 2D text in 3D space.
+ *
+ * The Text2DEntity renders text as triangles in the XY plane. The geometry will be fitted
+ * in the rectangle of specified width and height. If the resulting geometry is wider than
+ * the specified width, the remainder will be rendered on the new line.
+ *
+ * The entity can be positionned in the scene by adding a transform component.
+ *
+ * Text2DEntity will create geometry based on the shape of the glyphs and a solid
+ * material using the specified color.
+ *
+ */
+
+/*!
+ * \qmlproperty QString Text2DEntity::text
+ *
+ * Holds the text used for the mesh.
+ */
+
+/*!
+ * \qmlproperty QFont Text2DEntity::font
+ *
+ * Holds the font of the text.
+ */
+
+/*!
+ * \qmlproperty QColor Text2DEntity::color
+ *
+ * Holds the color of the text.
+ */
+
+/*!
+ * \qmlproperty float Text2DEntity::width
+ *
+ * Holds the width of the text's bounding rectangle.
+ */
+
+/*!
+ * \qmlproperty float Text2DEntity::height
+ *
+ * Holds the height of the text's bounding rectangle.
+ */
+
+
+/*!
+ * \class Qt3DExtras::QText2DEntity
+ * \inheaderfile Qt3DExtras/QText2DEntity
+ * \inmodule Qt3DExtras
+ *
+ * \brief QText2DEntity allows creation of a 2D text in 3D space.
+ *
+ * The QText2DEntity renders text as triangles in the XY plane. The geometry will be fitted
+ * in the rectangle of specified width and height. If the resulting geometry is wider than
+ * the specified width, the remainder will be rendered on the new line.
+ *
+ * The entity can be positionned in the scene by adding a transform component.
+ *
+ * QText2DEntity will create geometry based on the shape of the glyphs and a solid
+ * material using the specified color.
+ *
+ */
+
QHash<Qt3DCore::QScene *, QText2DEntityPrivate::CacheEntry> QText2DEntityPrivate::m_glyphCacheInstances;
QText2DEntityPrivate::QText2DEntityPrivate()
@@ -129,6 +195,7 @@ QText2DEntity::QText2DEntity(QNode *parent)
{
}
+/*! \internal */
QText2DEntity::~QText2DEntity()
{
}
@@ -298,8 +365,10 @@ void QText2DEntityPrivate::update()
}
/*!
- Returns the font for the text item that is displayed
- in the Qt Quick scene.
+ \property QText2DEntity::font
+
+ Holds the font for the text item that is displayed
+ in the Qt Quick scene.
*/
QFont QText2DEntity::font() const
{
@@ -326,8 +395,10 @@ void QText2DEntity::setFont(const QFont &font)
}
/*!
- Returns the color for the text item that is displayed in the Qt
- Quick scene.
+ \property QText2DEntity::color
+
+ Holds the color for the text item that is displayed in the Qt
+ Quick scene.
*/
QColor QText2DEntity::color() const
{
@@ -349,7 +420,9 @@ void QText2DEntity::setColor(const QColor &color)
}
/*!
- Returns the text that is displayed in the Qt Quick scene.
+ \property QText2DEntity::text
+
+ Holds the text that is displayed in the Qt Quick scene.
*/
QString QText2DEntity::text() const
{
@@ -369,8 +442,10 @@ void QText2DEntity::setText(const QString &text)
}
/*!
- Returns the width of the text item that is displayed in the
- Qt Quick scene.
+ \property QText2DEntity::width
+
+ Returns the width of the text item that is displayed in the
+ Qt Quick scene.
*/
float QText2DEntity::width() const
{
@@ -379,8 +454,10 @@ float QText2DEntity::width() const
}
/*!
- Returns the width of the text item that is displayed in the
- Qt Quick scene.
+ \property QText2DEntity::height
+
+ Returns the height of the text item that is displayed in the
+ Qt Quick scene.
*/
float QText2DEntity::height() const
{
diff --git a/src/logic/qframeaction.cpp b/src/logic/qframeaction.cpp
index 915fb015a..77cdae943 100644
--- a/src/logic/qframeaction.cpp
+++ b/src/logic/qframeaction.cpp
@@ -52,6 +52,7 @@ QFrameActionPrivate::QFrameActionPrivate()
/*!
\namespace Qt3DLogic::Logic
+ \inmodule Qt3DLogic
\brief Used to import and use the module's QML types.
*/
diff --git a/src/render/backend/rendersettings.cpp b/src/render/backend/rendersettings.cpp
index 397d297e9..5734f96a6 100644
--- a/src/render/backend/rendersettings.cpp
+++ b/src/render/backend/rendersettings.cpp
@@ -42,6 +42,7 @@
#include <Qt3DRender/QFrameGraphNode>
#include <Qt3DRender/private/abstractrenderer_p.h>
#include <Qt3DRender/private/qrendersettings_p.h>
+#include <Qt3DCore/qnodecommand.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -91,6 +92,10 @@ void RenderSettings::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
else if (propertyChange->propertyName() == QByteArrayLiteral("renderPolicy"))
m_renderPolicy = propertyChange->value().value<QRenderSettings::RenderPolicy>();
markDirty(AbstractRenderer::AllDirty);
+ } else if (e->type() == CommandRequested) {
+ QNodeCommandPtr command = qSharedPointerCast<QNodeCommand>(e);
+ if (command->name() == QLatin1Literal("InvalidateFrame"))
+ markDirty(AbstractRenderer::AllDirty);
}
BackendNode::sceneChangeEvent(e);
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 42ada0baa..14fbe1754 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -186,6 +186,7 @@ namespace Qt3DRender {
/*!
\namespace Qt3DRender::Render
+ \inmodule Qt3DRender
\brief Namespace used for accessing the classes
Renderer and QRenderPlugin.
diff --git a/src/render/geometry/qgeometryrenderer.cpp b/src/render/geometry/qgeometryrenderer.cpp
index b8572cded..6bff3462f 100644
--- a/src/render/geometry/qgeometryrenderer.cpp
+++ b/src/render/geometry/qgeometryrenderer.cpp
@@ -136,13 +136,13 @@ QGeometryRendererPrivate::~QGeometryRendererPrivate()
/*!
\qmlproperty int GeometryRenderer::firstInstance
- Holds the first vertex.
+ Holds the base instance.
*/
/*!
\qmlproperty int GeometryRenderer::firstVertex
- Holds the base instance.
+ Holds the first vertex.
*/
/*!
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp
index 2f1eb4cd8..2050b8772 100644
--- a/src/render/jobs/pickboundingvolumejob.cpp
+++ b/src/render/jobs/pickboundingvolumejob.cpp
@@ -232,8 +232,14 @@ bool PickBoundingVolumeJob::runHelper()
for (const PickingUtils::ViewportCameraAreaDetails &vca : vcaDetails) {
PickingUtils::HitList sphereHits;
QRay3D ray = rayForViewportAndCamera(vca, event.first, event.second.pos());
- if (!ray.isValid())
+ if (!ray.isValid()) {
+ // An invalid rays is when we've lost our surface or the mouse
+ // has moved out of the viewport In case of a button released
+ // outside of the viewport, we still want to notify the
+ // lastCurrent entity about this.
+ dispatchPickEvents(event.second, PickingUtils::HitList(), eventButton, eventButtons, eventModifiers, allHitsRequested);
continue;
+ }
PickingUtils::HierarchicalEntityPicker entityPicker(ray);
if (entityPicker.collectHits(m_manager, m_node)) {
diff --git a/src/render/materialsystem/prototypes/default.json b/src/render/materialsystem/prototypes/default.json
index 63c39164c..597de41c3 100644
--- a/src/render/materialsystem/prototypes/default.json
+++ b/src/render/materialsystem/prototypes/default.json
@@ -404,6 +404,15 @@
},
{
"format": {
+ "api": "OpenGLES",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "highp mat3 $matrix = calcWorldSpaceToTangentSpaceMatrix($worldNormal, $worldTangent);",
+ "headerSnippets": [ "#pragma include :/shaders/es3/coordinatesystems.inc" ]
+ },
+ {
+ "format": {
"api": "OpenGLCoreProfile",
"major": 3,
"minor": 0
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index d270dc583..9aed183b0 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -632,18 +632,21 @@ void Renderer::doRender(bool scene3dBlocking)
// Lock the mutex to protect access to the renderQueue while we look for its state
QMutexLocker locker(m_renderQueue->mutex());
bool queueIsComplete = m_renderQueue->isFrameQueueComplete();
- const bool queueIsEmpty = m_renderQueue->targetRenderViewCount() == 0;
+ bool queueIsEmpty = m_renderQueue->targetRenderViewCount() == 0;
// Scene3D Blocking Mode
if (scene3dBlocking && !queueIsComplete && !queueIsEmpty) {
int i = 0;
// We wait at most 10ms to avoid a case we could never recover from
- while (!queueIsComplete && i++ < 10) {
- QThread::msleep(1);
+ while (!queueIsComplete && !queueIsEmpty && i++ < 10) {
qCDebug(Backend) << Q_FUNC_INFO << "Waiting for ready queue (try:" << i << "/ 10)";
locker.unlock();
- queueIsComplete = m_renderQueue->isFrameQueueComplete();
+ // Give worker threads a chance to complete the queue
+ QThread::msleep(1);
locker.relock();
+ queueIsComplete = m_renderQueue->isFrameQueueComplete();
+ // This could become true if we've tried to shutdown
+ queueIsEmpty = m_renderQueue->targetRenderViewCount() == 0;
}
}
@@ -1979,14 +1982,14 @@ void Renderer::performDraw(RenderCommand *command)
reinterpret_cast<void*>(quintptr(command->m_indexAttributeByteOffset)),
command->m_instanceCount,
command->m_indexOffset,
- command->m_firstVertex);
+ command->m_firstInstance);
} else {
Profiling::GLTimeRecorder recorder(Profiling::DrawArray);
m_submissionContext->drawArraysInstancedBaseInstance(command->m_primitiveType,
- command->m_firstInstance,
+ command->m_firstVertex,
command->m_primitiveCount,
command->m_instanceCount,
- command->m_firstVertex);
+ command->m_firstInstance);
}
}
diff --git a/src/render/renderers/opengl/textures/gltexture.cpp b/src/render/renderers/opengl/textures/gltexture.cpp
index 1d2d19c66..8efc34f23 100644
--- a/src/render/renderers/opengl/textures/gltexture.cpp
+++ b/src/render/renderers/opengl/textures/gltexture.cpp
@@ -435,7 +435,6 @@ QOpenGLTexture *GLTexture::buildGLTexture()
// Set layers count if texture array
if (m_actualTarget == QAbstractTexture::Target1DArray ||
m_actualTarget == QAbstractTexture::Target2DArray ||
- m_actualTarget == QAbstractTexture::Target3D ||
m_actualTarget == QAbstractTexture::Target2DMultisampleArray ||
m_actualTarget == QAbstractTexture::TargetCubeMapArray) {
glTex->setLayers(m_properties.layers);
diff --git a/src/src.pro b/src/src.pro
index cd07486e9..c3c8d6291 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -23,6 +23,10 @@ src_extras.subdir = $$PWD/extras
src_extras.target = src_extras
src_extras.depends = src_render src_input src_logic
+src_doc.subdir = $$PWD/doc
+src_doc.target = sub-doc
+src_doc.depends = src_animation src_input
+
qtHaveModule(quick) {
# Quick3D libs
src_quick3d_core.subdir = $$PWD/quick3d/quick3d
@@ -100,9 +104,7 @@ qtHaveModule(quick) {
src_plugins_render.depends = src_render src_extras src_quick3d_render src_quick3d_scene2d
}
-SUBDIRS += \
- src_core \
- doc
+SUBDIRS += src_core
QT_FOR_CONFIG += 3dcore
include($$OUT_PWD/core/qt3dcore-config.pri)
@@ -110,7 +112,10 @@ include($$OUT_PWD/core/qt3dcore-config.pri)
qtConfig(qt3d-input): SUBDIRS += src_input
qtConfig(qt3d-logic): SUBDIRS += src_logic
qtConfig(qt3d-render): SUBDIRS += src_render
-qtConfig(qt3d-animation): SUBDIRS += src_animation
+qtConfig(qt3d-animation) {
+ SUBDIRS += src_animation
+ qtConfig(qt3d-input): SUBDIRS += src_doc
+}
qtConfig(qt3d-extras) {
SUBDIRS += \
src_extras \
diff --git a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
index b86df05a4..60b60eb6e 100644
--- a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
+++ b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp
@@ -861,6 +861,94 @@ private Q_SLOTS:
arbiter.events.clear();
}
+ void checkDispatchReleaseEventOnLastPickerWhenMovingOutOfViewport()
+ {
+ // GIVEN
+ QmlSceneReader sceneReader(QUrl("qrc:/testscene_dragenabled.qml"));
+ QScopedPointer<Qt3DCore::QNode> root(qobject_cast<Qt3DCore::QNode *>(sceneReader.root()));
+ QVERIFY(root);
+
+ QList<Qt3DRender::QRenderSettings *> renderSettings = root->findChildren<Qt3DRender::QRenderSettings *>();
+ QCOMPARE(renderSettings.size(), 1);
+ Qt3DRender::QPickingSettings *settings = renderSettings.first()->pickingSettings();
+
+ settings->setPickMethod(Qt3DRender::QPickingSettings::TrianglePicking);
+ settings->setPickResultMode(Qt3DRender::QPickingSettings::NearestPick);
+ settings->setFaceOrientationPickingMode(Qt3DRender::QPickingSettings::FrontAndBackFace);
+
+ QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(root.data()));
+ TestArbiter arbiter;
+
+ // Runs Required jobs
+ runRequiredJobs(test.data());
+
+ // THEN
+ QList<Qt3DRender::QObjectPicker *> pickers = root->findChildren<Qt3DRender::QObjectPicker *>();
+ QCOMPARE(pickers.size(), 2);
+
+ Qt3DRender::QObjectPicker *picker1 = nullptr;
+ if (pickers.first()->objectName() == QLatin1String("Picker1"))
+ picker1 = pickers.first();
+ else
+ picker1 = pickers.last();
+
+ Qt3DRender::Render::ObjectPicker *backendPicker1 = test->nodeManagers()->objectPickerManager()->lookupResource(picker1->id());
+ QVERIFY(backendPicker1);
+ Qt3DCore::QBackendNodePrivate::get(backendPicker1)->setArbiter(&arbiter);
+
+ // WHEN -> Pressed on object
+ Qt3DRender::Render::PickBoundingVolumeJob pickBVJob;
+ initializePickBoundingVolumeJob(&pickBVJob, test.data());
+
+ QList<QPair<QObject *, QMouseEvent>> events;
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ bool earlyReturn = !pickBVJob.runHelper();
+
+ // THEN -> Pressed
+ QVERIFY(!earlyReturn);
+ QVERIFY(backendPicker1->isPressed());
+ QCOMPARE(arbiter.events.count(), 1);
+ Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "pressed");
+ Qt3DRender::QPickEventPtr pickEvent = change->value().value<Qt3DRender::QPickEventPtr>();
+ QVERIFY(pickEvent);
+ QVERIFY(!Qt3DRender::QPickEventPrivate::get(pickEvent.data())->m_entity.isNull());
+ QVERIFY(pickEvent.dynamicCast<Qt3DRender::QPickTriangleEvent>());
+
+ arbiter.events.clear();
+
+ // WHEN -> Releasing out of the viewport
+ events.clear();
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(10000.0f, 10000.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ earlyReturn = !pickBVJob.runHelper();
+
+ // THEN -> Should have received released event
+ QVERIFY(!earlyReturn);
+ QVERIFY(!backendPicker1->isPressed());
+ QCOMPARE(arbiter.events.count(), 1);
+ change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "released");
+ pickEvent = change->value().value<Qt3DRender::QPickEventPtr>();
+ QVERIFY(pickEvent);
+ QVERIFY(Qt3DRender::QPickEventPrivate::get(pickEvent.data())->m_entity.isNull());
+
+ arbiter.events.clear();
+
+ // WHEN -> Releasing out of the viewport
+ events.clear();
+ events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(10000.0f, 10000.0f),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)});
+ pickBVJob.setMouseEvents(events);
+ earlyReturn = !pickBVJob.runHelper();
+
+ // THEN -> Should have received nothing
+ QCOMPARE(arbiter.events.count(), 0);
+ }
+
void checkDispatchHoverEvent_data()
{
generateAllPickingSettingsCombinations();
diff --git a/tests/benchmarks/core/core.pro b/tests/benchmarks/core/core.pro
index d5c6b98b3..67710db78 100644
--- a/tests/benchmarks/core/core.pro
+++ b/tests/benchmarks/core/core.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
-!wince*: SUBDIRS += \
+SUBDIRS += \
qcircularbuffer \
qresourcesmanager \
qframeallocator
diff --git a/tools/tools.pro b/tools/tools.pro
index c2f692034..121507613 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -1,5 +1,5 @@
TEMPLATE = subdirs
QT_FOR_CONFIG += 3dcore-private
-qtConfig(assimp):qtConfig(commandlineparser):!cross_compile: {
+qtConfig(assimp):qtConfig(commandlineparser): {
SUBDIRS += qgltf
}