summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-10-05 13:58:50 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-10-05 13:58:50 +0200
commit6c77dea4711b6a88e80e30db21d622808e5ef9b6 (patch)
tree7f03934b19f5782447da135aeceb4269298e3f2a
parentedc88e97721c0a223a2b77cec217f550f08a4135 (diff)
parentd8789d8fd17fd58f06003e9846b3d107ffc8ec52 (diff)
Merge remote-tracking branch 'origin/5.11' into 5.12
-rw-r--r--examples/qt3d/exampleresources/assets/cubemaps/miramar/qt_attribution.json14
-rw-r--r--examples/qt3d/simple-qml/CameraController.qml297
-rw-r--r--examples/qt3d/simple-qml/doc/src/simple-qml.qdoc16
-rw-r--r--examples/qt3d/simple-qml/simple-qml.qrc1
-rw-r--r--src/core/jobs/qthreadpooler.cpp5
-rw-r--r--src/core/qchangearbiter.cpp7
-rw-r--r--src/doc/src/qmlextramaterials.qdoc14
-rw-r--r--src/extras/defaults/qmorphphongmaterial.cpp26
-rw-r--r--src/extras/defaults/qmorphphongmaterial_p.h3
-rw-r--r--src/extras/defaults/qorbitcameracontroller.cpp2
-rw-r--r--src/extras/extras.qrc3
-rw-r--r--src/extras/shaders/es2/morphphong.vert2
-rw-r--r--src/extras/shaders/es3/default.vert82
-rw-r--r--src/extras/shaders/es3/light.inc.frag25
-rw-r--r--src/extras/shaders/es3/metalrough.inc.frag348
-rw-r--r--src/extras/shaders/gl3/morphphong.vert2
-rw-r--r--src/extras/text/qtext2dentity.cpp15
-rw-r--r--src/extras/text/qtext2dentity_p.h1
-rw-r--r--src/quick3d/imports/scene3d/scene3ditem.cpp3
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer.cpp58
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer_p.h1
-rw-r--r--src/render/materialsystem/prototypes/default.json27
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp8
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp13
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h1
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h1
-rw-r--r--src/render/renderers/opengl/renderer/openglvertexarrayobject.cpp5
-rw-r--r--src/render/renderers/opengl/renderer/openglvertexarrayobject_p.h1
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp3
-rw-r--r--src/render/renderers/opengl/textures/gltexture.cpp4
30 files changed, 631 insertions, 357 deletions
diff --git a/examples/qt3d/exampleresources/assets/cubemaps/miramar/qt_attribution.json b/examples/qt3d/exampleresources/assets/cubemaps/miramar/qt_attribution.json
new file mode 100644
index 000000000..6eccf001c
--- /dev/null
+++ b/examples/qt3d/exampleresources/assets/cubemaps/miramar/qt_attribution.json
@@ -0,0 +1,14 @@
+{
+ "Id": "miramar-sky",
+ "Name": "Miramar Skybox Textures",
+ "QDocModule": "qt3d",
+ "QtUsage": "Used in the anaglyph-rendering example and autotests of Qt 3D.",
+
+ "QtParts": [ "examples", "tests" ] ,
+ "Description": "High res environment map (converted to webgl).",
+ "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",
+ "Copyright": "Copyright (c) Jockum Skoglund aka hipshot"
+}
diff --git a/examples/qt3d/simple-qml/CameraController.qml b/examples/qt3d/simple-qml/CameraController.qml
deleted file mode 100644
index 69eff70ed..000000000
--- a/examples/qt3d/simple-qml/CameraController.qml
+++ /dev/null
@@ -1,297 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 Paul Lemire <paul.lemire350@gmail.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import Qt3D.Core 2.0
-import Qt3D.Render 2.0
-import Qt3D.Input 2.0
-import Qt3D.Logic 2.0
-import QtQml 2.2
-
-Entity {
- id: root
- property Camera camera
- property real linearSpeed: 10.0
- property real orbitSpeed: -180.0
- property real lookSpeed: 180.0
- property bool firstPersonMode: true
-
- QtObject {
- id: d
- readonly property vector3d firstPersonUp: Qt.vector3d(0, 1, 0)
- property bool leftMouseButtonPressed: false
- property bool rightMouseButtonPressed: false
- property real vx: 0;
- property real vy: 0;
- property real vz: 0;
- property real dx: 0
- property real dy: 0
- property bool fineMotion: false
- }
-
- KeyboardDevice {
- id: keyboardSourceDevice
- }
-
- MouseDevice {
- id: mouseSourceDevice
- sensitivity: d.fineMotion ? 0.01 : 0.1
- }
-
- LogicalDevice {
- id: cameraControlDevice
-
- actions: [
- Action {
- name: "LMB"
- inputs: [
- ActionInput {
- sourceDevice: mouseSourceDevice
- buttons: [MouseEvent.LeftButton]
- }
- ]
- },
- Action {
- name: "RMB"
- inputs: [
- ActionInput {
- sourceDevice: mouseSourceDevice
- buttons: [MouseEvent.RightButton]
- }
- ]
- },
- Action {
- name: "fineMotion"
- inputs: [
- ActionInput {
- sourceDevice: keyboardSourceDevice
- buttons: [Qt.Key_Shift]
- }
- ]
- }
-
- ] // actions
-
- axes: [
- // Rotation
- Axis {
- name: "RX"
- inputs: [
- AnalogAxisInput {
- sourceDevice: mouseSourceDevice
- axis: MouseDevice.X
- }
- ]
- },
- Axis {
- name: "RY"
- inputs: [
- AnalogAxisInput {
- sourceDevice: mouseSourceDevice
- axis: MouseDevice.Y
- }
- ]
- },
- // Translation
- Axis {
- name: "TX"
- inputs: [
- ButtonAxisInput {
- sourceDevice: keyboardSourceDevice
- buttons: [Qt.Key_Left]
- scale: -1.0
- },
- ButtonAxisInput {
- sourceDevice: keyboardSourceDevice
- buttons: [Qt.Key_Right]
- scale: 1.0
- }
- ]
- },
- Axis {
- name: "TZ"
- inputs: [
- ButtonAxisInput {
- sourceDevice: keyboardSourceDevice
- buttons: [Qt.Key_Up]
- scale: 1.0
- },
- ButtonAxisInput {
- sourceDevice: keyboardSourceDevice
- buttons: [Qt.Key_Down]
- scale: -1.0
- }
- ]
- },
- Axis {
- name: "TY"
- inputs: [
- ButtonAxisInput {
- sourceDevice: keyboardSourceDevice
- buttons: [Qt.Key_PageUp]
- scale: 1.0
- },
- ButtonAxisInput {
- sourceDevice: keyboardSourceDevice
- buttons: [Qt.Key_PageDown]
- scale: -1.0
- }
- ]
- }
- ] // axes
- }
-
- components: [
- AxisActionHandler {
- id: handler
- logicalDevice: cameraControlDevice
-
- onAxisValueChanged: {
-
- switch (name) {
-
- case "TX": {
- d.vx = axisValue * linearSpeed
- break;
- }
-
- case "TY": {
- d.vy = axisValue * linearSpeed
- break;
- }
-
- case "TZ": {
- d.vz = axisValue * linearSpeed
- break;
- }
-
- case "RX": {
- d.dx = axisValue;
- break;
- }
-
- case "RY": {
- d.dy = axisValue;
- break;
- }
-
- }
- }
-
- onActionStarted: {
-
- switch (name) {
-
- case "LMB": {
- d.leftMouseButtonPressed = true;
- break;
- }
-
- case "RMB": {
- d.rightMouseButtonPressed = true;
- break;
- }
-
- case "fineMotion": {
- console.log("fineMotion started")
- d.fineMotion = true;
- break;
- }
-
- }
-
- }
-
- onActionFinished: {
-
- switch (name) {
-
- case "LMB": {
- d.leftMouseButtonPressed = false;
- break;
- }
-
- case "RMB": {
- d.rightMouseButtonPressed = false;
- break;
- }
-
- case "fineMotion": {
- console.log("fineMotion finished")
- d.fineMotion = false;
- break;
- }
-
- }
- }
- },
-
- FrameAction {
- onTriggered: {
- // The time difference since the last frame is passed in as the
- // argument dt. It is a floating point value in units of seconds.
- root.camera.translate(Qt.vector3d(d.vx, d.vy, d.vz).times(dt))
-
- if (d.leftMouseButtonPressed) {
- if (root.firstPersonMode)
- root.camera.pan(root.lookSpeed * d.dx * dt, d.firstPersonUp)
- else
- root.camera.pan(root.lookSpeed * d.dx * dt)
- root.camera.tilt(root.lookSpeed * d.dy * dt)
- } else if (d.rightMouseButtonPressed) {
- if (root.firstPersonMode)
- root.camera.panAboutViewCenter(root.lookSpeed * d.dx * dt, d.firstPersonUp)
- else
- root.camera.panAboutViewCenter(root.lookSpeed * d.dx * dt)
- root.camera.tiltAboutViewCenter(root.orbitSpeed * d.dy * dt)
- }
- }
- }
- ] // components
-}
diff --git a/examples/qt3d/simple-qml/doc/src/simple-qml.qdoc b/examples/qt3d/simple-qml/doc/src/simple-qml.qdoc
index 13ca8ff1f..9d4f55c52 100644
--- a/examples/qt3d/simple-qml/doc/src/simple-qml.qdoc
+++ b/examples/qt3d/simple-qml/doc/src/simple-qml.qdoc
@@ -65,20 +65,4 @@
\skipto InputSettings
\printuntil }
-
- \section1
-
- \section1 Specifying Settings and Axes
-
- In the \e CameraController.qml file, we use the LogicalDevice type to define
- a set of actions and axes to use within the application:
-
- \quotefromfile simple-qml/CameraController.qml
- \skipto LogicalDevice {
- \printuntil ]
- \dots
- \skipto axes
- \printuntil ]
- \dots
- \skipto /^\}/
*/
diff --git a/examples/qt3d/simple-qml/simple-qml.qrc b/examples/qt3d/simple-qml/simple-qml.qrc
index 9d95d9835..5f6483ac3 100644
--- a/examples/qt3d/simple-qml/simple-qml.qrc
+++ b/examples/qt3d/simple-qml/simple-qml.qrc
@@ -1,6 +1,5 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
- <file>CameraController.qml</file>
</qresource>
</RCC>
diff --git a/src/core/jobs/qthreadpooler.cpp b/src/core/jobs/qthreadpooler.cpp
index 6819faca7..ca123ddad 100644
--- a/src/core/jobs/qthreadpooler.cpp
+++ b/src/core/jobs/qthreadpooler.cpp
@@ -41,6 +41,11 @@
#include <QtCore/QDebug>
#if QT_CONFIG(qt3d_profile_jobs)
+
+#ifdef Q_OS_ANDROID
+#include <QtCore/QStandardPaths>
+#endif
+
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
#include <QtCore/QThreadStorage>
diff --git a/src/core/qchangearbiter.cpp b/src/core/qchangearbiter.cpp
index d6c7e05df..2e32d6722 100644
--- a/src/core/qchangearbiter.cpp
+++ b/src/core/qchangearbiter.cpp
@@ -217,12 +217,15 @@ void QChangeArbiter::registerSceneObserver(QSceneObserverInterface *observer)
void QChangeArbiter::unregisterObserver(QObserverInterface *observer, QNodeId nodeId)
{
QMutexLocker locker(&m_mutex);
- if (m_nodeObservations.contains(nodeId)) {
- QObserverList &observers = m_nodeObservations[nodeId];
+ const auto it = m_nodeObservations.find(nodeId);
+ if (it != m_nodeObservations.end()) {
+ QObserverList &observers = it.value();
for (int i = observers.count() - 1; i >= 0; i--) {
if (observers[i].second == observer)
observers.removeAt(i);
}
+ if (observers.isEmpty())
+ m_nodeObservations.erase(it);
}
}
diff --git a/src/doc/src/qmlextramaterials.qdoc b/src/doc/src/qmlextramaterials.qdoc
index 10198845f..c54cc948b 100644
--- a/src/doc/src/qmlextramaterials.qdoc
+++ b/src/doc/src/qmlextramaterials.qdoc
@@ -28,6 +28,8 @@
/*!
\qmltype DiffuseMapMaterial
\inqmlmodule Qt3D.Extras
+ \obsolete
+
\brief The DiffuseMapMaterial provides a default implementation of the phong lighting effect
where the diffuse light component is read from a texture map.
\since 5.7
@@ -86,6 +88,8 @@
/*!
\qmltype DiffuseSpecularMapMaterial
\inqmlmodule Qt3D.Extras
+ \obsolete
+
\brief The DiffuseSpecularMapMaterial provides a default implementation of the phong lighting
effect where the diffuse and specular light components are read from texture maps.
\since 5.7
@@ -220,6 +224,8 @@
/*!
\qmltype NormalDiffuseMapAlphaMaterial
\inqmlmodule Qt3D.Extras
+ \obsolete
+
\brief The NormalDiffuseMapAlphaMaterial provides a specialization of NormalDiffuseMapMaterial
with alpha coverage and a depth test performed in the rendering pass.
\since 5.7
@@ -291,6 +297,8 @@
/*!
\qmltype NormalDiffuseMapMaterial
\inqmlmodule Qt3D.Extras
+ \obsolete
+
\brief The NormalDiffuseMapMaterial provides a default implementation of the phong lighting
and bump effect where the diffuse light component is read from a texture map and the normals of
the mesh being rendered from a normal texture map.
@@ -363,6 +371,8 @@
/*!
\qmltype NormalDiffuseSpecularMapMaterial
\inqmlmodule Qt3D.Extras
+ \obsolete
+
\brief The NormalDiffuseSpecularMapMaterial provides a default implementation of the phong
lighting and bump effect where the diffuse and specular light components are read from texture
maps and the normals of the mesh being rendered from a normal texture map.
@@ -465,6 +475,8 @@
/*!
\qmltype PhongAlphaMaterial
\inqmlmodule Qt3D.Extras
+ \obsolete
+
\brief The PhongAlphaMaterial class provides a default implementation of
the phong lighting effect with alpha.
\since 5.7
@@ -516,6 +528,8 @@
/*!
\qmltype PhongMaterial
\inqmlmodule Qt3D.Extras
+ \obsolete
+
\brief The PhongMaterial class provides a default implementation of the phong lighting effect.
\since 5.7
\inherits Qt3D.Render::Material
diff --git a/src/extras/defaults/qmorphphongmaterial.cpp b/src/extras/defaults/qmorphphongmaterial.cpp
index ade9f8542..1711a21dd 100644
--- a/src/extras/defaults/qmorphphongmaterial.cpp
+++ b/src/extras/defaults/qmorphphongmaterial.cpp
@@ -44,6 +44,7 @@
#include <Qt3DRender/qparameter.h>
#include <Qt3DRender/qrenderpass.h>
#include <Qt3DRender/qgraphicsapifilter.h>
+#include <Qt3DRender/qshaderprogrambuilder.h>
#include <QUrl>
#include <QVector3D>
#include <QVector4D>
@@ -57,9 +58,9 @@ namespace Qt3DExtras {
QMorphPhongMaterialPrivate::QMorphPhongMaterialPrivate()
: QMaterialPrivate()
, m_phongEffect(new QEffect())
- , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f)))
- , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7f, 0.7f, 0.7f, 1.0f)))
- , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01f, 0.01f, 0.01f, 1.0f)))
+ , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05, 0.05, 0.05, 1.0)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7, 0.7, 0.7, 1.0)))
+ , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01, 0.01, 0.01, 1.0)))
, m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
, m_interpolatorParameter(new QParameter(QStringLiteral("interpolator"), 0.0f))
, m_phongGL3Technique(new QTechnique())
@@ -70,12 +71,16 @@ QMorphPhongMaterialPrivate::QMorphPhongMaterialPrivate()
, m_phongES2RenderPass(new QRenderPass())
, m_phongGL3Shader(new QShaderProgram())
, m_phongGL2ES2Shader(new QShaderProgram())
+ , m_phongGL3ShaderBuilder(new QShaderProgramBuilder())
+ , m_phongGL2ES2ShaderBuilder(new QShaderProgramBuilder())
, m_filterKey(new QFilterKey)
{
}
void QMorphPhongMaterialPrivate::init()
{
+ Q_Q(QMorphPhongMaterial);
+
connect(m_ambientParameter, &Qt3DRender::QParameter::valueChanged,
this, &QMorphPhongMaterialPrivate::handleAmbientChanged);
connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged,
@@ -88,9 +93,19 @@ void QMorphPhongMaterialPrivate::init()
this, &QMorphPhongMaterialPrivate::handleInterpolatorChanged);
m_phongGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/morphphong.vert"))));
- m_phongGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.frag"))));
+ m_phongGL3ShaderBuilder->setParent(q);
+ m_phongGL3ShaderBuilder->setShaderProgram(m_phongGL3Shader);
+ m_phongGL3ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
+ m_phongGL3ShaderBuilder->setEnabledLayers({QStringLiteral("diffuse"),
+ QStringLiteral("specular"),
+ QStringLiteral("normal")});
m_phongGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/morphphong.vert"))));
- m_phongGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.frag"))));
+ m_phongGL2ES2ShaderBuilder->setParent(q);
+ m_phongGL2ES2ShaderBuilder->setShaderProgram(m_phongGL2ES2Shader);
+ m_phongGL2ES2ShaderBuilder->setFragmentShaderGraph(QUrl(QStringLiteral("qrc:/shaders/graphs/phong.frag.json")));
+ m_phongGL2ES2ShaderBuilder->setEnabledLayers({QStringLiteral("diffuse"),
+ QStringLiteral("specular"),
+ QStringLiteral("normal")});
m_phongGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
m_phongGL3Technique->graphicsApiFilter()->setMajorVersion(3);
@@ -115,7 +130,6 @@ void QMorphPhongMaterialPrivate::init()
m_phongGL2Technique->addRenderPass(m_phongGL2RenderPass);
m_phongES2Technique->addRenderPass(m_phongES2RenderPass);
- Q_Q(QMorphPhongMaterial);
m_filterKey->setParent(q);
m_filterKey->setName(QStringLiteral("renderingStyle"));
m_filterKey->setValue(QStringLiteral("forward"));
diff --git a/src/extras/defaults/qmorphphongmaterial_p.h b/src/extras/defaults/qmorphphongmaterial_p.h
index 25bff9042..28b7750d9 100644
--- a/src/extras/defaults/qmorphphongmaterial_p.h
+++ b/src/extras/defaults/qmorphphongmaterial_p.h
@@ -60,6 +60,7 @@ class QTechnique;
class QParameter;
class QShaderProgram;
class QRenderPass;
+class QShaderProgramBuilder;
} // namespace Qt3DRender
@@ -94,6 +95,8 @@ public:
Qt3DRender::QRenderPass *m_phongES2RenderPass;
Qt3DRender::QShaderProgram *m_phongGL3Shader;
Qt3DRender::QShaderProgram *m_phongGL2ES2Shader;
+ Qt3DRender::QShaderProgramBuilder *m_phongGL3ShaderBuilder;
+ Qt3DRender::QShaderProgramBuilder *m_phongGL2ES2ShaderBuilder;
Qt3DRender::QFilterKey *m_filterKey;
Q_DECLARE_PUBLIC(QMorphPhongMaterial)
diff --git a/src/extras/defaults/qorbitcameracontroller.cpp b/src/extras/defaults/qorbitcameracontroller.cpp
index 6d3e83bcb..aff91f6cf 100644
--- a/src/extras/defaults/qorbitcameracontroller.cpp
+++ b/src/extras/defaults/qorbitcameracontroller.cpp
@@ -186,7 +186,7 @@ void QOrbitCameraController::moveCamera(const QAbstractCameraController::InputSt
} else if (state.shiftKeyActive) {
if (zoomDistance(camera()->position(), theCamera->viewCenter()) > d->m_zoomInLimit * d->m_zoomInLimit) {
// Dolly
- theCamera->translate(QVector3D(0, 0, state.tyAxisValue * linearSpeed() * dt), theCamera->DontTranslateViewCenter);
+ theCamera->translate(QVector3D(0, 0, state.tzAxisValue * linearSpeed() * dt), theCamera->DontTranslateViewCenter);
} else {
theCamera->translate(QVector3D(0, 0, -0.5), theCamera->DontTranslateViewCenter);
}
diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc
index bfb14f3f9..8bbffd272 100644
--- a/src/extras/extras.qrc
+++ b/src/extras/extras.qrc
@@ -5,14 +5,17 @@
<file>shaders/gl3/light.inc.frag</file>
<file>shaders/es2/light.inc.frag</file>
<file>shaders/es2/light.inc.frag100</file>
+ <file>shaders/es3/light.inc.frag</file>
<file>shaders/gl3/phong.inc.frag</file>
<file>shaders/es2/phong.inc.frag</file>
<file>shaders/es2/phong.inc.frag100</file>
<file>shaders/gl3/metalrough.inc.frag</file>
+ <file>shaders/es3/metalrough.inc.frag</file>
<file>shaders/gl3/coordinatesystems.inc</file>
<file>shaders/es2/coordinatesystems.inc</file>
<file>shaders/gl3/default.vert</file>
<file>shaders/es2/default.vert</file>
+ <file>shaders/es3/default.vert</file>
<file>shaders/gl3/pervertexcolor.frag</file>
<file>shaders/gl3/pervertexcolor.vert</file>
<file>shaders/es2/pervertexcolor.frag</file>
diff --git a/src/extras/shaders/es2/morphphong.vert b/src/extras/shaders/es2/morphphong.vert
index d091e87c0..89877dca8 100644
--- a/src/extras/shaders/es2/morphphong.vert
+++ b/src/extras/shaders/es2/morphphong.vert
@@ -25,7 +25,7 @@ void main()
morphNormal = normalize(vertexNormal + vertexNormalTarget * abs(interpolator));
}
- worldNormal = normalize( modelNormalMatrix * morphPos );
+ worldNormal = normalize( modelNormalMatrix * morphNormal );
worldPosition = vec3( modelMatrix * vec4( morphPos, 1.0 ) );
gl_Position = modelViewProjection * vec4( morphPos, 1.0 );
diff --git a/src/extras/shaders/es3/default.vert b/src/extras/shaders/es3/default.vert
new file mode 100644
index 000000000..7641882f2
--- /dev/null
+++ b/src/extras/shaders/es3/default.vert
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#version 300 es
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+in vec4 vertexTangent;
+in vec2 vertexTexCoord;
+
+out vec3 worldPosition;
+out vec3 worldNormal;
+out vec4 worldTangent;
+out vec2 texCoord;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 modelViewProjection;
+
+uniform float texCoordScale;
+
+void main()
+{
+ // Pass through scaled texture coordinates
+ texCoord = vertexTexCoord * texCoordScale;
+
+ // Transform position, normal, and tangent to world space
+ worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));
+ worldNormal = normalize(modelNormalMatrix * vertexNormal);
+ worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));
+ worldTangent.w = vertexTangent.w;
+
+ // Calculate vertex position in clip coordinates
+ gl_Position = modelViewProjection * vec4(vertexPosition, 1.0);
+}
diff --git a/src/extras/shaders/es3/light.inc.frag b/src/extras/shaders/es3/light.inc.frag
new file mode 100644
index 000000000..9d03fca54
--- /dev/null
+++ b/src/extras/shaders/es3/light.inc.frag
@@ -0,0 +1,25 @@
+const int MAX_LIGHTS = 8;
+const int TYPE_POINT = 0;
+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;
+};
+uniform Light lights[MAX_LIGHTS];
+uniform int lightCount;
+
+// Pre-convolved environment maps
+struct EnvironmentLight {
+ highp samplerCube irradiance; // For diffuse contribution
+ highp samplerCube specular; // For specular contribution
+};
+uniform EnvironmentLight envLight;
+uniform int envLightCount;
diff --git a/src/extras/shaders/es3/metalrough.inc.frag b/src/extras/shaders/es3/metalrough.inc.frag
new file mode 100644
index 000000000..85f392f4c
--- /dev/null
+++ b/src/extras/shaders/es3/metalrough.inc.frag
@@ -0,0 +1,348 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+precision highp float;
+
+// Exposure correction
+uniform float exposure;
+// Gamma correction
+const float gamma = 2.2;
+
+#pragma include light.inc.frag
+
+int mipLevelCount(const in 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)
+{
+ // 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));
+ return max(roughness * roughness, minRoughness);
+}
+
+float alphaToMipLevel(float alpha)
+{
+ 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;
+
+ // TODO: Optimize by doing this on CPU and set as
+ // uniform int envLight.specularMipLevels say (if present in shader).
+ // Lookup the number of mips in the specular envmap
+ int mipLevels = mipLevelCount(envLight.specular);
+
+ // 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;
+
+ // 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);
+ return mipLevel;
+}
+
+float normalDistribution(const in vec3 n, const in vec3 h, const in 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;
+ 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)
+{
+ // Calculate the Fresnel effect value
+ vec3 f = color;
+ 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)
+{
+ // Implicit geometric model (equal to denominator in specular model).
+ // This currently assumes that there is no attenuation by geometric shadowing or
+ // masking according to the microfacet theory.
+ 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)
+{
+ // 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);
+
+ vec3 F = fresnelFactor(F0, sDotH);
+ float G = geometricModel(sDotNPrime, vDotNPrime, h);
+
+ 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)
+{
+ // Calculate some useful quantities
+ vec3 n = wNormal;
+ vec3 s = vec3(0.0);
+ vec3 v = wView;
+ vec3 h = vec3(0.0);
+
+ float vDotN = dot(v, n);
+ float sDotN = 0.0;
+ float sDotH = 0.0;
+ float att = 1.0;
+
+ if (lights[lightIndex].type != TYPE_DIRECTIONAL) {
+ // Point and Spot lights
+ vec3 sUnnormalized = vec3(lights[lightIndex].position) - wPosition;
+ s = normalize(sUnnormalized);
+
+ // Calculate the attenuation factor
+ sDotN = dot(s, n);
+ if (sDotN > 0.0) {
+ if (lights[lightIndex].constantAttenuation != 0.0
+ || lights[lightIndex].linearAttenuation != 0.0
+ || lights[lightIndex].quadraticAttenuation != 0.0) {
+ float dist = length(sUnnormalized);
+ att = 1.0 / (lights[lightIndex].constantAttenuation +
+ lights[lightIndex].linearAttenuation * dist +
+ lights[lightIndex].quadraticAttenuation * dist * dist);
+ }
+
+ // The light direction is in world space already
+ if (lights[lightIndex].type == TYPE_SPOT) {
+ // Check if fragment is inside or outside of the spot light cone
+ if (degrees(acos(dot(-s, lights[lightIndex].direction))) > lights[lightIndex].cutOffAngle)
+ sDotN = 0.0;
+ }
+ }
+ } else {
+ // Directional lights
+ // The light direction is in world space already
+ s = normalize(-lights[lightIndex].direction);
+ sDotN = dot(s, n);
+ }
+
+ h = normalize(s + v);
+ 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;
+
+ // Calculate specular component
+ vec3 dielectricColor = vec3(0.04);
+ vec3 F0 = mix(dielectricColor, baseColor, metalness);
+ 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;
+
+ // Blend between diffuse and specular to conserver energy
+ vec3 color = att * lights[lightIndex].intensity * (specular + diffuse * (vec3(1.0) - specular));
+
+ // Reduce by ambient occlusion amount
+ color *= ambientOcclusion;
+
+ 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)
+{
+ // 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);
+
+ // Calculate diffuse component
+ vec3 diffuseColor = (1.0 - metalness) * baseColor;
+ 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);
+
+ float lod = alphaToMipLevel(alpha);
+//#define DEBUG_SPECULAR_LODS
+#ifdef DEBUG_SPECULAR_LODS
+ if (lod > 7.0)
+ return vec3(1.0, 0.0, 0.0);
+ else if (lod > 6.0)
+ return vec3(1.0, 0.333, 0.0);
+ else if (lod > 5.0)
+ return vec3(1.0, 1.0, 0.0);
+ else if (lod > 4.0)
+ return vec3(0.666, 1.0, 0.0);
+ else if (lod > 3.0)
+ return vec3(0.0, 1.0, 0.666);
+ else if (lod > 2.0)
+ return vec3(0.0, 0.666, 1.0);
+ else if (lod > 1.0)
+ return vec3(0.0, 0.0, 1.0);
+ 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;
+
+ // Blend between diffuse and specular to conserve energy
+ vec3 color = specular + diffuse * (vec3(1.0) - specularFactor);
+
+ // Reduce by ambient occlusion amount
+ color *= ambientOcclusion;
+
+ return color;
+}
+
+vec3 toneMap(const in vec3 c)
+{
+ return c / (c + vec3(1.0));
+}
+
+vec3 gammaCorrect(const in 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)
+{
+ vec3 cLinear = vec3(0.0);
+
+ // Remap roughness for a perceptually more linear correspondence
+ float alpha = remapRoughness(roughness);
+
+ for (int i = 0; i < envLightCount; ++i) {
+ cLinear += pbrIblModel(worldNormal,
+ worldView,
+ baseColor.rgb,
+ metalness,
+ alpha,
+ ambientOcclusion);
+ }
+
+ for (int i = 0; i < lightCount; ++i) {
+ cLinear += pbrModel(i,
+ worldPosition,
+ worldNormal,
+ worldView,
+ baseColor.rgb,
+ metalness,
+ alpha,
+ ambientOcclusion);
+ }
+
+ // Apply exposure correction
+ cLinear *= pow(2.0, exposure);
+
+ // Apply simple (Reinhard) tonemap transform to get into LDR range [0, 1]
+ vec3 cToneMapped = toneMap(cLinear);
+
+ // Apply gamma correction prior to display
+ vec3 cGamma = gammaCorrect(cToneMapped);
+
+ return vec4(cGamma, 1.0);
+}
diff --git a/src/extras/shaders/gl3/morphphong.vert b/src/extras/shaders/gl3/morphphong.vert
index c74fbdcff..7a8bdd097 100644
--- a/src/extras/shaders/gl3/morphphong.vert
+++ b/src/extras/shaders/gl3/morphphong.vert
@@ -27,7 +27,7 @@ void main()
morphNormal = normalize(vertexNormal + vertexNormalTarget * abs(interpolator));
}
- worldNormal = normalize( modelNormalMatrix * morphPos );
+ worldNormal = normalize( modelNormalMatrix * morphNormal );
worldPosition = vec3( modelMatrix * vec4( morphPos, 1.0 ) );
gl_Position = modelViewProjection * vec4( morphPos, 1.0 );
diff --git a/src/extras/text/qtext2dentity.cpp b/src/extras/text/qtext2dentity.cpp
index 10939a1e2..ae25e8ecc 100644
--- a/src/extras/text/qtext2dentity.cpp
+++ b/src/extras/text/qtext2dentity.cpp
@@ -92,10 +92,17 @@ void QText2DEntityPrivate::setScene(Qt3DCore::QScene *scene)
// Unref old glyph cache if it exists
if (m_scene != nullptr) {
+ // Ensure we don't keep reference to glyphs
+ // if we are changing the cache
+ if (m_glyphCache != nullptr)
+ clearCurrentGlyphRuns();
+
m_glyphCache = nullptr;
+
QText2DEntityPrivate::CacheEntry &entry = QText2DEntityPrivate::m_glyphCacheInstances[m_scene];
--entry.count;
if (entry.count == 0 && entry.glyphCache != nullptr) {
+
delete entry.glyphCache;
entry.glyphCache = nullptr;
}
@@ -149,7 +156,6 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
// For each distinct texture, we need a separate DistanceFieldTextRenderer,
// for which we need vertex and index data
QHash<Qt3DRender::QAbstractTexture*, RenderData> renderData;
-
const float scale = computeActualScale();
// process glyph runs
@@ -248,6 +254,13 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
m_currentGlyphRuns = runs;
}
+void QText2DEntityPrivate::clearCurrentGlyphRuns()
+{
+ for (int i = 0; i < m_currentGlyphRuns.size(); i++)
+ m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]);
+ m_currentGlyphRuns.clear();
+}
+
void QText2DEntityPrivate::update()
{
if (m_glyphCache == nullptr)
diff --git a/src/extras/text/qtext2dentity_p.h b/src/extras/text/qtext2dentity_p.h
index 934e2087f..b98c62ce3 100644
--- a/src/extras/text/qtext2dentity_p.h
+++ b/src/extras/text/qtext2dentity_p.h
@@ -104,6 +104,7 @@ public:
float computeActualScale() const;
void setCurrentGlyphRuns(const QVector<QGlyphRun> &runs);
+ void clearCurrentGlyphRuns();
void update();
struct CacheEntry
diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp
index 2f791b202..ddb25777c 100644
--- a/src/quick3d/imports/scene3d/scene3ditem.cpp
+++ b/src/quick3d/imports/scene3d/scene3ditem.cpp
@@ -372,9 +372,6 @@ QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNode
m_renderer->setCleanerHelper(m_rendererCleaner);
}
- // The main thread is blocked, it is now time to sync data between the renderer and the item.
- m_renderer->synchronize();
-
Scene3DSGNode *fboNode = static_cast<Scene3DSGNode *>(node);
if (fboNode == nullptr) {
fboNode = new Scene3DSGNode();
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp
index b3cac0dcd..b96fc516d 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer.cpp
+++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp
@@ -138,11 +138,13 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
, m_lastMultisample(false)
, m_needsShutdown(true)
, m_blocking(false)
+ , m_forceRecreate(false)
{
Q_CHECK_PTR(m_item);
Q_CHECK_PTR(m_item->window());
m_window = m_item->window();
+ QObject::connect(m_item->window(), &QQuickWindow::afterSynchronizing, this, &Scene3DRenderer::synchronize, Qt::DirectConnection);
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
@@ -247,7 +249,30 @@ void Scene3DRenderer::onWindowChanged(QQuickWindow *w)
void Scene3DRenderer::synchronize()
{
- m_multisample = m_item->multisample();
+ if (m_item && m_window) {
+ m_multisample = m_item->multisample();
+
+ if (m_aspectEngine->rootEntity() != m_item->entity()) {
+ scheduleRootEntityChange();
+ }
+
+ const QSize boundingRectSize = m_item->boundingRect().size().toSize();
+ const QSize currentSize = boundingRectSize * m_window->effectiveDevicePixelRatio();
+ const bool sizeHasChanged = currentSize != m_lastSize;
+ const bool multisampleHasChanged = m_multisample != m_lastMultisample;
+ m_forceRecreate = sizeHasChanged || multisampleHasChanged;
+
+ if (sizeHasChanged) {
+ static const QMetaMethod setItemAreaAndDevicePixelRatio = setItemAreaAndDevicePixelRatioMethod();
+ setItemAreaAndDevicePixelRatio.invoke(m_item, Qt::QueuedConnection, Q_ARG(QSize, boundingRectSize),
+ Q_ARG(qreal, m_window->effectiveDevicePixelRatio()));
+ }
+
+ // Store the current size as a comparison
+ // point for the next frame
+ m_lastSize = currentSize;
+ m_lastMultisample = m_multisample;
+ }
}
void Scene3DRenderer::setSGNode(Scene3DSGNode *node)
@@ -261,51 +286,30 @@ void Scene3DRenderer::render()
{
QMutexLocker l(&m_windowMutex);
// Lock to ensure the window doesn't change while we are rendering
- if (!m_item || !m_window)
+ if (!m_window)
return;
- if (m_aspectEngine->rootEntity() != m_item->entity())
- scheduleRootEntityChange();
-
ContextSaver saver;
// The OpenGL state may be dirty from the previous QtQuick nodes, so reset
// it here to give Qt3D the clean state it expects
m_window->resetOpenGLState();
- const QSize boundingRectSize = m_item->boundingRect().size().toSize();
- 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;
-
- if (sizeHasChanged) {
- // We are in the QSGRenderThread (doing a direct call would result in a race)
- static const QMetaMethod setItemAreaAndDevicePixelRatio = setItemAreaAndDevicePixelRatioMethod();
- setItemAreaAndDevicePixelRatio.invoke(m_item, Qt::QueuedConnection, Q_ARG(QSize, boundingRectSize),
- Q_ARG(qreal, m_window->effectiveDevicePixelRatio()));
- }
-
// Rebuild FBO and textures if never created or a resize has occurred
- if ((m_multisampledFBO.isNull() || forceRecreate) && m_multisample) {
- m_multisampledFBO.reset(createMultisampledFramebufferObject(currentSize));
+ if ((m_multisampledFBO.isNull() || m_forceRecreate) && m_multisample) {
+ m_multisampledFBO.reset(createMultisampledFramebufferObject(m_lastSize));
if (m_multisampledFBO->format().samples() == 0 || !QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
m_multisample = false;
m_multisampledFBO.reset(nullptr);
}
}
- if (m_finalFBO.isNull() || forceRecreate) {
- m_finalFBO.reset(createFramebufferObject(currentSize));
+ if (m_finalFBO.isNull() || m_forceRecreate) {
+ m_finalFBO.reset(createFramebufferObject(m_lastSize));
m_texture.reset(m_window->createTextureFromId(m_finalFBO->texture(), m_finalFBO->size(), QQuickWindow::TextureHasAlphaChannel));
m_node->setTexture(m_texture.data());
}
- // Store the current size as a comparison
- // point for the next frame
- m_lastSize = currentSize;
- m_lastMultisample = m_multisample;
-
// Bind FBO
if (m_multisample) //Only try to use MSAA when available
m_multisampledFBO->bind();
diff --git a/src/quick3d/imports/scene3d/scene3drenderer_p.h b/src/quick3d/imports/scene3d/scene3drenderer_p.h
index eb2b930ef..e28ecbe6e 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer_p.h
+++ b/src/quick3d/imports/scene3d/scene3drenderer_p.h
@@ -110,6 +110,7 @@ private:
bool m_lastMultisample;
bool m_needsShutdown;
bool m_blocking;
+ bool m_forceRecreate;
friend class Scene3DCleaner;
};
diff --git a/src/render/materialsystem/prototypes/default.json b/src/render/materialsystem/prototypes/default.json
index 535f144d7..63c39164c 100644
--- a/src/render/materialsystem/prototypes/default.json
+++ b/src/render/materialsystem/prototypes/default.json
@@ -87,6 +87,15 @@
},
{
"format": {
+ "api": "OpenGLES",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $color = texture($name, $coord);",
+ "headerSnippets": [ "uniform sampler2D $name;" ]
+ },
+ {
+ "format": {
"api": "OpenGLCoreProfile",
"major": 3,
"minor": 0
@@ -111,6 +120,15 @@
},
{
"format": {
+ "api": "OpenGLES",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "fragColor = $fragColor;",
+ "headerSnippets": [ "out highp vec4 fragColor;" ]
+ },
+ {
+ "format": {
"api": "OpenGLCoreProfile",
"major": 3,
"minor": 0
@@ -445,6 +463,15 @@
"rules": [
{
"format": {
+ "api": "OpenGLES",
+ "major": 3,
+ "minor": 0
+ },
+ "substitution": "highp vec4 $outputColor = metalRoughFunction($baseColor, $metalness, $roughness, $ambientOcclusion, $worldPosition, $worldView, $worldNormal);",
+ "headerSnippets": [ "#pragma include :/shaders/es3/metalrough.inc.frag" ]
+ },
+ {
+ "format": {
"api": "OpenGLCoreProfile",
"major": 3,
"minor": 1
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp
index 29ecf9308..34c1e7448 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp
@@ -234,6 +234,14 @@ void GraphicsHelperES3::vertexAttributePointer(GLenum shaderDataType,
}
}
+void GraphicsHelperES3::drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances)
+{
+ m_extraFuncs->glDrawArraysInstanced(primitiveType,
+ first,
+ count,
+ instances);
+}
+
void GraphicsHelperES3::readBuffer(GLenum mode)
{
m_extraFuncs->glReadBuffer(mode);
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp
index 9dce08e4f..56da249f2 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp
@@ -117,6 +117,19 @@ void GraphicsHelperES3_2::setVerticesPerPatch(GLint verticesPerPatch)
m_extraFuncs->glPatchParameteri(GL_PATCH_VERTICES, verticesPerPatch);
}
+void GraphicsHelperES3_2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex, GLint baseInstance)
+{
+ if (baseInstance != 0)
+ qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2";
+
+ m_extraFuncs->glDrawElementsInstancedBaseVertex(primitiveType,
+ primitiveCount,
+ indexType,
+ indices,
+ instances,
+ baseVertex);
+}
+
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h
index ed71b1e3e..259864379 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h
@@ -70,6 +70,7 @@ public:
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override;
bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override;
void setVerticesPerPatch(GLint verticesPerPatch) override;
+ void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override;
};
} // namespace Render
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h
index 142b7cadd..d4467cf7f 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h
@@ -74,6 +74,7 @@ public:
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) override;
void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) override;
void drawBuffers(GLsizei n, const int *bufs) override;
+ void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) override;
void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override;
void readBuffer(GLenum mode) override;
void drawBuffer(GLenum mode) override;
diff --git a/src/render/renderers/opengl/renderer/openglvertexarrayobject.cpp b/src/render/renderers/opengl/renderer/openglvertexarrayobject.cpp
index 0c4fd8c9d..f5d0a64f5 100644
--- a/src/render/renderers/opengl/renderer/openglvertexarrayobject.cpp
+++ b/src/render/renderers/opengl/renderer/openglvertexarrayobject.cpp
@@ -108,6 +108,11 @@ void OpenGLVertexArrayObject::create(SubmissionContext *ctx, const VAOIdentifier
m_owners = key;
}
+VAOIdentifier OpenGLVertexArrayObject::key() const
+{
+ return m_owners;
+}
+
// called from Render thread
void OpenGLVertexArrayObject::destroy()
{
diff --git a/src/render/renderers/opengl/renderer/openglvertexarrayobject_p.h b/src/render/renderers/opengl/renderer/openglvertexarrayobject_p.h
index eee837221..4896df9bf 100644
--- a/src/render/renderers/opengl/renderer/openglvertexarrayobject_p.h
+++ b/src/render/renderers/opengl/renderer/openglvertexarrayobject_p.h
@@ -73,6 +73,7 @@ public:
void release();
void create(SubmissionContext *ctx, const VAOIdentifier &key);
+ VAOIdentifier key() const;
void destroy();
void cleanup();
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index c9ba6409d..5d12729f2 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -2140,7 +2140,8 @@ void Renderer::cleanGraphicsResources()
OpenGLVertexArrayObject *vao = m_nodesManager->vaoManager()->data(vaoHandle);
if (vao) {
vao->destroy();
- m_nodesManager->vaoManager()->release(vaoHandle);
+ // We remove VAO from manager using its VAOIdentifier
+ m_nodesManager->vaoManager()->releaseResource(vao->key());
}
}
}
diff --git a/src/render/renderers/opengl/textures/gltexture.cpp b/src/render/renderers/opengl/textures/gltexture.cpp
index b61d06a80..e98f3965d 100644
--- a/src/render/renderers/opengl/textures/gltexture.cpp
+++ b/src/render/renderers/opengl/textures/gltexture.cpp
@@ -212,6 +212,10 @@ GLTexture::TextureUpdateInfo GLTexture::createOrUpdateGLTexture()
delete m_gl;
m_gl = nullptr;
textureInfo.wasUpdated = true;
+ // If we are destroyed because of some property change but still our content data
+ // make sure we are marked for upload
+ if (m_textureData || !m_imageData.empty())
+ needUpload = true;
}