diff options
author | Liang Qi <liang.qi@qt.io> | 2018-12-11 15:08:00 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-12-11 15:08:00 +0100 |
commit | c9ce0deeb8f2bb79c446e41584f753f1b1bfe17f (patch) | |
tree | 5e9a06346ea22e6e9a2fafd6a2ac7394c73648c6 | |
parent | f1b333c36a19cf85eab798fc1b1952ed063fedfe (diff) | |
parent | 0a0a7e4ca4f05c7d6da55ec64c8a9734d82853fe (diff) |
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts:
src/render/renderers/opengl/textures/gltexture.cpp
Change-Id: I57e9a296dc15f0b5dc3af3664f698bdc799c4bb5
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 } |