From 851b2189a8d31b9306f696c38988bbc554fa9e0c Mon Sep 17 00:00:00 2001 From: Volker Enderlein Date: Mon, 30 Sep 2019 13:48:44 +0200 Subject: [PATCH 01/12] Fix for bounding volume handling and calculation - Fixed Ritter algorithm implementation - Added notation of invalid bounding sphere (radius == -1.0) - Handle merging of invalid bounding sphere with valid ones - Added test cases and adjusted tests boundingsphere and proximityfilter - This is necessary to ensure the correct working for viewAll and viewEntity Task-number: QTBUG-78313 Change-Id: I1dc6d227cf9009f6fbd3230093c7a7a94fb05ae3 Reviewed-by: Paul Lemire --- src/render/frontend/sphere.cpp | 48 ++++- src/render/frontend/sphere_p.h | 13 +- src/render/jobs/calcboundingvolumejob.cpp | 78 +++++--- .../boundingsphere/tst_boundingsphere.cpp | 172 ++++++++++++++++-- .../tst_proximityfiltering.cpp | 38 ++++ 5 files changed, 298 insertions(+), 51 deletions(-) diff --git a/src/render/frontend/sphere.cpp b/src/render/frontend/sphere.cpp index 4909acaef..470dbfe59 100644 --- a/src/render/frontend/sphere.cpp +++ b/src/render/frontend/sphere.cpp @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -55,6 +56,9 @@ namespace { // returns true and intersection point q; false otherwise bool intersectRaySphere(const Qt3DRender::RayCasting::QRay3D &ray, const Qt3DRender::Render::Sphere &s, Vector3D *q = nullptr) { + if (s.isNull()) + return false; + const Vector3D p = ray.origin(); const Vector3D d = ray.direction(); const Vector3D m = p - s.center(); @@ -139,11 +143,31 @@ inline void sphereFromExtremePoints(Qt3DRender::Render::Sphere &s, const QVector inline void constructRitterSphere(Qt3DRender::Render::Sphere &s, const QVector &points) { - // Calculate the sphere encompassing two axially extreme points - sphereFromExtremePoints(s, points); + //def bounding_sphere(points): + // dist = lambda a,b: ((a[0] - b[0])**2 + (a[1] - b[1])**2 + (a[2] - b[2])**2)**0.5 + // x = points[0] + // y = max(points,key= lambda p: dist(p,x) ) + // z = max(points,key= lambda p: dist(p,y) ) + // bounding_sphere = (((y[0]+z[0])/2,(y[1]+z[1])/2,(y[2]+z[2])/2), dist(y,z)/2) + // + // exterior_points = [p for p in points if dist(p,bounding_sphere[0]) > bounding_sphere[1] ] + // while ( len(exterior_points) > 0 ): + // pt = exterior_points.pop() + // if (dist(pt, bounding_sphere[0]) > bounding_sphere[1]): + // bounding_sphere = (bounding_sphere[0],dist(pt,bounding_sphere[0])) + // + // return bounding_sphere - // Now make sure the sphere bounds all points by growing if needed - s.expandToContain(points); + const Vector3D x = points[0]; + const Vector3D y = *std::max_element(points.begin(), points.end(), [&x](const Vector3D& lhs, const Vector3D& rhs){ return (lhs - x).lengthSquared() < (rhs - x).lengthSquared(); }); + const Vector3D z = *std::max_element(points.begin(), points.end(), [&y](const Vector3D& lhs, const Vector3D& rhs){ return (lhs - y).lengthSquared() < (rhs - y).lengthSquared(); }); + + const Vector3D center = (y + z) * 0.5f; + const Vector3D maxDistPt = *std::max_element(points.begin(), points.end(), [¢er](const Vector3D& lhs, const Vector3D& rhs){ return (lhs - center).lengthSquared() < (rhs - center).lengthSquared(); }); + const float radius = (maxDistPt - center).length(); + + s.setCenter(center); + s.setRadius(radius); } } // anonymous namespace @@ -169,6 +193,12 @@ void Sphere::initializeFromPoints(const QVector &points) void Sphere::expandToContain(const Vector3D &p) { + if (isNull()) { + m_center = p; + m_radius = 0.0f; + return; + } + const Vector3D d = p - m_center; const float dist2 = d.lengthSquared(); @@ -184,6 +214,13 @@ void Sphere::expandToContain(const Vector3D &p) void Sphere::expandToContain(const Sphere &sphere) { + if (isNull()) { + *this = sphere; + return; + } else if (sphere.isNull()) { + return; + } + const Vector3D d(sphere.m_center - m_center); const float dist2 = d.lengthSquared(); @@ -206,6 +243,9 @@ void Sphere::expandToContain(const Sphere &sphere) Sphere Sphere::transformed(const Matrix4x4 &mat) const { + if (isNull()) + return *this; + // Transform extremities in x, y, and z directions to find extremities // of the resulting ellipsoid Vector3D x = mat.map(m_center + Vector3D(m_radius, 0.0f, 0.0f)); diff --git a/src/render/frontend/sphere_p.h b/src/render/frontend/sphere_p.h index 10cf92091..b7585f85a 100644 --- a/src/render/frontend/sphere_p.h +++ b/src/render/frontend/sphere_p.h @@ -69,7 +69,7 @@ class Q_3DRENDERSHARED_PRIVATE_EXPORT Sphere : public RayCasting::BoundingSphere public: inline Sphere(Qt3DCore::QNodeId i = Qt3DCore::QNodeId()) : m_center() - , m_radius(0.0f) + , m_radius(-1.0f) , m_id(i) {} @@ -82,7 +82,7 @@ public: void setCenter(const Vector3D &c); Vector3D center() const override; - inline bool isNull() { return m_center == Vector3D() && m_radius == 0.0f; } + bool isNull() const { return m_center == Vector3D() && m_radius == -1.0f; } void setRadius(float r); float radius() const override; @@ -131,7 +131,9 @@ inline Vector3D Sphere::center() const inline void Sphere::setRadius(float r) { - m_radius = r; + Q_ASSERT(r >= 0.0f); + if (r >= 0.0f) + m_radius = r; } inline float Sphere::radius() const @@ -142,11 +144,14 @@ inline float Sphere::radius() const inline void Sphere::clear() { m_center = Vector3D(); - m_radius = 0.0f; + m_radius = -1.0f; } inline bool intersects(const Sphere &a, const Sphere &b) { + if (a.isNull() || b.isNull()) + return false; + // Calculate squared distance between sphere centers const Vector3D d = a.center() - b.center(); const float distSq = Vector3D::dotProduct(d, d); diff --git a/src/render/jobs/calcboundingvolumejob.cpp b/src/render/jobs/calcboundingvolumejob.cpp index 113dc34ce..9af2f4f38 100644 --- a/src/render/jobs/calcboundingvolumejob.cpp +++ b/src/render/jobs/calcboundingvolumejob.cpp @@ -90,30 +90,42 @@ public: m_min = QVector3D(findExtremePoints.xMin, findExtremePoints.yMin, findExtremePoints.zMin); m_max = QVector3D(findExtremePoints.xMax, findExtremePoints.yMax, findExtremePoints.zMax); - // Calculate squared distance for the pairs of points - const float xDist2 = (findExtremePoints.xMaxPt - findExtremePoints.xMinPt).lengthSquared(); - const float yDist2 = (findExtremePoints.yMaxPt - findExtremePoints.yMinPt).lengthSquared(); - const float zDist2 = (findExtremePoints.zMaxPt - findExtremePoints.zMinPt).lengthSquared(); - - // Select most distant pair - Vector3D p = findExtremePoints.xMinPt; - Vector3D q = findExtremePoints.xMaxPt; - if (yDist2 > xDist2 && yDist2 > zDist2) { - p = findExtremePoints.yMinPt; - q = findExtremePoints.yMaxPt; + FindMaxDistantPoint maxDistantPointY(m_manager); + maxDistantPointY.setReferencePoint = true; + if (!maxDistantPointY.apply(positionAttribute, indexAttribute, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex)) { + return false; } - if (zDist2 > xDist2 && zDist2 > yDist2) { - p = findExtremePoints.zMinPt; - q = findExtremePoints.zMaxPt; + if (maxDistantPointY.hasNoPoints) + return false; + + //const Vector3D x = maxDistantPointY.referencePt; + const Vector3D y = maxDistantPointY.maxDistPt; + + FindMaxDistantPoint maxDistantPointZ(m_manager); + maxDistantPointZ.setReferencePoint = false; + maxDistantPointZ.referencePt = y; + if (!maxDistantPointZ.apply(positionAttribute, indexAttribute, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex)) { + return false; + } + const Vector3D z = maxDistantPointZ.maxDistPt; + + const Vector3D center = (y + z) * 0.5f; + + FindMaxDistantPoint maxDistantPointCenter(m_manager); + maxDistantPointCenter.setReferencePoint = false; + maxDistantPointCenter.referencePt = center; + if (!maxDistantPointCenter.apply(positionAttribute, indexAttribute, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex)) { + return false; } - const Vector3D c = 0.5f * (p + q); - m_volume.setCenter(c); - m_volume.setRadius((q - c).length()); + const float radius = (center - maxDistantPointCenter.maxDistPt).length(); - ExpandSphere expandSphere(m_manager, m_volume); - if (!expandSphere.apply(positionAttribute, indexAttribute, drawVertexCount, - primitiveRestartEnabled, primitiveRestartIndex)) + m_volume = Qt3DRender::Render::Sphere(center, radius); + + if (m_volume.isNull()) return false; return true; @@ -172,18 +184,34 @@ private: } }; - class ExpandSphere : public Buffer3fVisitor + class FindMaxDistantPoint : public Buffer3fVisitor { public: - ExpandSphere(NodeManagers *manager, Sphere& volume) - : Buffer3fVisitor(manager), m_volume(volume) + FindMaxDistantPoint(NodeManagers *manager) + : Buffer3fVisitor(manager) { } - Sphere& m_volume; + float maxLengthSquared = 0.0f; + Vector3D maxDistPt; + Vector3D referencePt; + bool setReferencePoint = false; + bool hasNoPoints = true; + void visit(uint ndx, float x, float y, float z) override { Q_UNUSED(ndx); - m_volume.expandToContain(Vector3D(x, y, z)); + const Vector3D p = Vector3D(x, y, z); + + if (hasNoPoints && setReferencePoint) { + maxLengthSquared = 0.0f; + referencePt = p; + } + const float lengthSquared = (p - referencePt).lengthSquared(); + if ( lengthSquared >= maxLengthSquared ) { + maxDistPt = p; + maxLengthSquared = lengthSquared; + } + hasNoPoints = false; } }; }; diff --git a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp index 40d992347..0379c883e 100644 --- a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp +++ b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp @@ -169,13 +169,150 @@ class tst_BoundingSphere : public Qt3DCore::QBackendNodeTester private: private Q_SLOTS: + void checkIsNull() { + auto defaultSphere = Qt3DRender::Render::Sphere(); + QVERIFY(defaultSphere.isNull()); + } + + void remainsNotNullAfterTransform() { + QMatrix4x4 mat; + mat.translate(-5,-5,-5); + auto mMat = Matrix4x4(mat); + auto pointSphere = Qt3DRender::Render::Sphere(Vector3D(5.f,5.f,5.f),0.f); + pointSphere.transform(mMat); + QVERIFY(!pointSphere.isNull()); + QVERIFY(pointSphere.center() == Vector3D(0.,0.,0)); + QVERIFY(pointSphere.radius() == 0.f); + } + + void remainsNullAfterTransform() { + QMatrix4x4 mat; + mat.translate(-5,-5,-5); + auto mMat = Matrix4x4(mat); + auto defaultSphere = Qt3DRender::Render::Sphere(); + defaultSphere.transform(mMat); + QVERIFY(defaultSphere.isNull()); + } + + void expandToContainSphere() { + auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f); + auto secondValidSphere = Qt3DRender::Render::Sphere(Vector3D(10.f,10.f,10.f),1.f); + firstValidSphere.expandToContain(secondValidSphere); + QVERIFY(firstValidSphere.center()==Vector3D(0.f,0.f,0.f)); + float dist = static_cast((2 + sqrt(3.*(20)*(20)))/2.); + QVERIFY(qFuzzyCompare(firstValidSphere.radius(), dist)); + } + + void expandToContainSphereOneInvalid() { + auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f); + auto defaultSphere = Qt3DRender::Render::Sphere(); + auto copiedSphere = firstValidSphere; + firstValidSphere.expandToContain(defaultSphere); + QVERIFY(firstValidSphere.center() == copiedSphere.center()); + QVERIFY(firstValidSphere.radius() == copiedSphere.radius()); + QVERIFY(!firstValidSphere.isNull()); + } + + void expandToContainOtherSphereInvalid() { + auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f); + auto defaultSphere = Qt3DRender::Render::Sphere(); + defaultSphere.expandToContain(firstValidSphere); + QVERIFY(defaultSphere.center() == firstValidSphere.center()); + QVERIFY(defaultSphere.radius() == firstValidSphere.radius()); + QVERIFY(!defaultSphere.isNull()); + } + + void expandNullSphereWithNullSphere() { + auto defaultSphere = Qt3DRender::Render::Sphere(); + auto otherDefaultSphere = Qt3DRender::Render::Sphere(); + defaultSphere.expandToContain(otherDefaultSphere); + QVERIFY(defaultSphere.isNull()); + } + + void expandToContainPoint() { + auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f); + firstValidSphere.expandToContain(Vector3D(0,0,0)); + QVERIFY(!firstValidSphere.isNull()); + float expectedRadius = static_cast((1 + qSqrt(3.*(10)*(10)))/2.); + QVERIFY(qFuzzyCompare(firstValidSphere.radius(), expectedRadius)); + } + + void nullSphereExpandToContainPoint() { + auto defaultSphere = Qt3DRender::Render::Sphere(); + defaultSphere.expandToContain(Vector3D(5,5,5)); + QVERIFY(!defaultSphere.isNull()); + QVERIFY(defaultSphere.center() == Vector3D(5,5,5)); + QVERIFY(qFuzzyIsNull(defaultSphere.radius())); + } + + void nullSphereExpandToOrigin() { + auto defaultSphere = Qt3DRender::Render::Sphere(); + defaultSphere.expandToContain(Vector3D(0,0,0)); + QVERIFY(!defaultSphere.isNull()); + QVERIFY(defaultSphere.center() == Vector3D(0,0,0)); + QVERIFY(qFuzzyIsNull(defaultSphere.radius())); + } + + void ritterSphereCubePoints() { + QVector cubePts={ + Vector3D(-0.5, -0.5, 0.5), + Vector3D( 0.5, -0.5, -0.5), + Vector3D(-0.5, 0.5, -0.5), + Vector3D( 0.5, 0.5, -0.5), + Vector3D(-0.5, -0.5, -0.5), + Vector3D( 0.5, -0.5, 0.5), + Vector3D(-0.5, 0.5, 0.5), + Vector3D( 0.5, 0.5, 0.5) + }; + auto ritterSphere=Qt3DRender::Render::Sphere::fromPoints(cubePts); + QVERIFY(!ritterSphere.isNull()); + QVERIFY(qFuzzyIsNull(ritterSphere.center().x())); + QVERIFY(qFuzzyIsNull(ritterSphere.center().y())); + QVERIFY(qFuzzyIsNull(ritterSphere.center().z())); + QVERIFY(qFuzzyCompare(ritterSphere.radius(), static_cast(qSqrt(3)/2))); + } + + void ritterSphereRandomPoints() { + QVector randomPts={ + Vector3D(-81, 55, 46), + Vector3D(-91, -73, -42), + Vector3D(-50, -76, -77), + Vector3D(-40, 63, 58), + Vector3D(-28, -2, -57), + Vector3D(84, 17, 33), + Vector3D(53, 11, -49), + Vector3D(-7, -24, -86), + Vector3D(-89, 6, 76), + Vector3D(46, -18, -27) + }; + + auto ritterSphere = Qt3DRender::Render::Sphere::fromPoints(randomPts); + QVERIFY(!ritterSphere.isNull()); + QVERIFY(qFuzzyCompare(ritterSphere.center().x(), 17.f)); + QVERIFY(qFuzzyCompare(ritterSphere.center().y(), -29.5f)); + QVERIFY(qFuzzyCompare(ritterSphere.center().z(), -22.0f)); + QVERIFY(qFuzzyCompare(ritterSphere.radius(), 148.66152831179963f)); + } + + void ritterSphereOnePoint() { + QVector singlePt={ + Vector3D(-0.5, -0.5, -0.5), + }; + auto ritterSphere = Qt3DRender::Render::Sphere::fromPoints(singlePt); + QVERIFY(!ritterSphere.isNull()); + QVERIFY(qFuzzyCompare(ritterSphere.center().x(), -0.5f)); + QVERIFY(qFuzzyCompare(ritterSphere.center().y(), -0.5f)); + QVERIFY(qFuzzyCompare(ritterSphere.center().z(), -0.5f)); + QVERIFY(qFuzzyIsNull(ritterSphere.radius())); + } + void checkExtraGeometries_data() { QTest::addColumn("qmlFile"); QTest::addColumn("sphereCenter"); QTest::addColumn("sphereRadius"); QTest::newRow("SphereMesh") << "qrc:/sphere.qml" << QVector3D(0.f, 0.f, 0.f) << 1.f; - QTest::newRow("CubeMesh") << "qrc:/cube.qml" << QVector3D(0.0928356f, -0.212021f, -0.0467958f) << 1.07583f; // weird! + QTest::newRow("CubeMesh") << "qrc:/cube.qml" << QVector3D(0.f, 0.f, 0.f) << static_cast(qSqrt(3.)/2.); // not weird at all } void checkExtraGeometries() @@ -200,9 +337,10 @@ private Q_SLOTS: const auto boundingSphere = test->sceneRoot()->worldBoundingVolumeWithChildren(); qDebug() << qmlFile << boundingSphere->radius() << boundingSphere->center(); QCOMPARE(boundingSphere->radius(), sphereRadius); - QVERIFY(qAbs(boundingSphere->center().x() - sphereCenter.x()) < 0.000001f); // qFuzzyCompare hates 0s - QVERIFY(qAbs(boundingSphere->center().y() - sphereCenter.y()) < 0.000001f); - QVERIFY(qAbs(boundingSphere->center().z() - sphereCenter.z()) < 0.000001f); + + QVERIFY(qFuzzyIsNull(boundingSphere->center().x() - sphereCenter.x())); + QVERIFY(qFuzzyIsNull(boundingSphere->center().y() - sphereCenter.y())); + QVERIFY(qFuzzyIsNull(boundingSphere->center().z() - sphereCenter.z())); } void checkCustomGeometry_data() @@ -212,10 +350,10 @@ private Q_SLOTS: QTest::addColumn("expectedCenter"); QTest::addColumn("expectedRadius"); QTest::addColumn("withPrimitiveRestart"); - QTest::newRow("all") << 0 << 0 << QVector3D(-0.488892f, 0.0192147f, -75.4804f) << 25.5442f << false; + QTest::newRow("all") << 0 << 0 << QVector3D(0.0f, 0.0f, -75.0f) << 25.03997f << false; QTest::newRow("first only") << 3 << 0 << QVector3D(0, 1, -100) << 1.0f << false; QTest::newRow("second only") << 3 << int(3 * sizeof(ushort)) << QVector3D(0, -1, -50) << 1.0f << false; - QTest::newRow("all with primitive restart") << 0 << 0 << QVector3D(-0.488892f, 0.0192147f, -75.4804f) << 25.5442f << true; + QTest::newRow("all with primitive restart") << 0 << 0 << QVector3D(0.0f, 0.0f, -75.0f) << 25.03997f << true; QTest::newRow("first only with primitive restart") << 4 << 0 << QVector3D(0, 1, -100) << 1.0f << true; QTest::newRow("second only with primitive restart") << 4 << int(3 * sizeof(ushort)) << QVector3D(0, -1, -50) << 1.0f << true; } @@ -341,18 +479,17 @@ private Q_SLOTS: float radius = entityBackend->localBoundingVolume()->radius(); qDebug() << radius << center; - // truncate and compare integers only - QVERIFY(int(radius) == int(expectedRadius)); - QVERIFY(int(center.x()) == int(expectedCenter.x())); - QVERIFY(int(center.y()) == int(expectedCenter.y())); - QVERIFY(int(center.z()) == int(expectedCenter.z())); + QCOMPARE(radius, expectedRadius); + QCOMPARE(center.x(), expectedCenter.x()); + QCOMPARE(center.y(), expectedCenter.y()); + QCOMPARE(center.z(), expectedCenter.z()); } void checkCustomPackedGeometry() { int drawVertexCount = 6; - QVector3D expectedCenter(-0.488892f, 0.0192147f, -75.4804f); - float expectedRadius = 25.5442f; + QVector3D expectedCenter(0.0f, 0.0f, -75.0f); + float expectedRadius = 25.03997f; // two triangles with different Z QByteArray vdata; @@ -432,11 +569,10 @@ private Q_SLOTS: float radius = entityBackend->localBoundingVolume()->radius(); qDebug() << radius << center; - // truncate and compare integers only - QVERIFY(int(radius) == int(expectedRadius)); - QVERIFY(int(center.x()) == int(expectedCenter.x())); - QVERIFY(int(center.y()) == int(expectedCenter.y())); - QVERIFY(int(center.z()) == int(expectedCenter.z())); + QCOMPARE(radius, expectedRadius); + QCOMPARE(center.x(), expectedCenter.x()); + QCOMPARE(center.y(), expectedCenter.y()); + QCOMPARE(center.z(), expectedCenter.z()); } }; diff --git a/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp b/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp index c8d862b2e..dcd39c785 100644 --- a/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp +++ b/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp @@ -29,6 +29,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -43,6 +47,40 @@ namespace { Qt3DCore::QEntity *buildEntityAtDistance(float distance, Qt3DCore::QEntity *parent) { Qt3DCore::QEntity *entity = new Qt3DCore::QEntity(parent); + + // create geometry with a valid bounding volume - a single point is sufficient + auto geometry = new Qt3DRender::QGeometry; + auto vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, geometry); + + auto positionAttribute = new Qt3DRender::QAttribute; + positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + positionAttribute->setVertexSize(3); + positionAttribute->setByteStride(3 * sizeof(float)); + positionAttribute->setBuffer(vertexBuffer); + + QByteArray vertexBufferData; + vertexBufferData.resize(static_cast(3 * sizeof(float))); + + auto vertexArray = reinterpret_cast(vertexBufferData.data()); + + int i = 0; + vertexArray[i++] = 0.0f; + vertexArray[i++] = 0.0f; + vertexArray[i++] = 0.0f; + + vertexBuffer->setData(vertexBufferData); + positionAttribute->setCount(1); + + geometry->addAttribute(positionAttribute); + + auto geometryRenderer = new Qt3DRender::QGeometryRenderer; + geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points); + geometryRenderer->setGeometry(geometry); + + entity->addComponent(geometryRenderer); + Qt3DCore::QTransform *transform = new Qt3DCore::QTransform(parent); const QVector3D t = QVector3D(1.0f, 0.0f, 0.0f) * distance; From 21c87018a093a361d92f573bc1b4cb96ed1e1160 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Fri, 4 Oct 2019 11:29:07 +0300 Subject: [PATCH 02/12] Doc: Add inherits tags to ClipAnimator and BlendedClipAnimator Task-number: QTBUG-78485 Change-Id: Ic80a17b40c9ee81fd7bac2e669e729358c19c340 Reviewed-by: Mike Krus --- src/animation/frontend/qblendedclipanimator.cpp | 1 + src/animation/frontend/qclipanimator.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/animation/frontend/qblendedclipanimator.cpp b/src/animation/frontend/qblendedclipanimator.cpp index 388144c81..c48706606 100644 --- a/src/animation/frontend/qblendedclipanimator.cpp +++ b/src/animation/frontend/qblendedclipanimator.cpp @@ -56,6 +56,7 @@ QBlendedClipAnimatorPrivate::QBlendedClipAnimatorPrivate() \qmltype BlendedClipAnimator \instantiates Qt3DAnimation::QBlendedClipAnimator \inqmlmodule Qt3D.Animation + \inherits AbstractClipAnimator \since 5.9 \brief BlendedClipAnimator is a component providing animation playback capabilities of a tree diff --git a/src/animation/frontend/qclipanimator.cpp b/src/animation/frontend/qclipanimator.cpp index 398758820..03510aa93 100644 --- a/src/animation/frontend/qclipanimator.cpp +++ b/src/animation/frontend/qclipanimator.cpp @@ -66,6 +66,7 @@ bool QClipAnimatorPrivate::canPlay() const \qmltype ClipAnimator \instantiates Qt3DAnimation::QClipAnimator \inqmlmodule Qt3D.Animation + \inherits AbstractClipAnimator \since 5.9 \brief ClipAnimator is a component providing simple animation playback capabilities. From b18845b0451cf0ff9c7611483b589ce51b3c9e1b Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 17 Sep 2019 17:43:45 +0200 Subject: [PATCH 03/12] Ensure we can build assimp on Windows and macOS with non gcc compilers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-75145 Change-Id: Ibee7d877bf78c2d2ed74ac8a89b7af5bf22f14f1 Reviewed-by: Antti Määttä --- src/plugins/sceneparsers/sceneparsers.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro index 9bb0ada36..e57bcac22 100644 --- a/src/plugins/sceneparsers/sceneparsers.pro +++ b/src/plugins/sceneparsers/sceneparsers.pro @@ -2,7 +2,7 @@ TEMPLATE = subdirs # QNX is not supported, and Linux GCC 4.9 on ARM chokes on the assimp # sources (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66964). QT_FOR_CONFIG += 3dcore-private -qtConfig(assimp):if(qtConfig(system-assimp)|android-clang|gcc:greaterThan(QT_GCC_MAJOR_VERSION, 4)): { +!ios:!tvos:!qcc:qtConfig(assimp):if(qtConfig(system-assimp)|android-clang|clang|win32-msvc)|if(gcc:greaterThan(QT_GCC_MAJOR_VERSION, 4)) { SUBDIRS += assimp } SUBDIRS += gltf From 905444291f3da2dd10769683c75508732d983ac9 Mon Sep 17 00:00:00 2001 From: Tomi Korpipaa Date: Mon, 7 Oct 2019 11:18:04 +0300 Subject: [PATCH 04/12] Clarify Scene2D input event support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-63900 Change-Id: I4a0331cd364480f6cdbf89e53ae486f13e6c3fe7 Reviewed-by: Antti Määttä Reviewed-by: Paul Lemire --- src/quick3d/quick3dscene2d/items/qscene2d.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.cpp b/src/quick3d/quick3dscene2d/items/qscene2d.cpp index ef06f39f1..8908894c8 100644 --- a/src/quick3d/quick3dscene2d/items/qscene2d.cpp +++ b/src/quick3d/quick3dscene2d/items/qscene2d.cpp @@ -70,6 +70,8 @@ namespace Quick { with the item; if an entity has a QObjectPicker component, the pick events from that picker are sent to the QScene2D and converted to mouse events and finally sent to the item. + \note Only mouse events are supported. The item does not support keyboard input. + \since 5.9 */ @@ -91,6 +93,8 @@ namespace Quick { with the item; if an entity has an ObjectPicker component, the pick events from that picker are sent to the Scene2D and converted to mouse events and finally sent to the item. + \note Only mouse events are supported. The item does not support keyboard input. + Usage: \qml Entity { From b367a04314ad0624c9ddb9d56ae50dac10c966b3 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Mon, 7 Oct 2019 15:38:49 +0300 Subject: [PATCH 05/12] Add documentation for AbstractClipAnimator QML type properties Add documentation for the following QML properties: channelMapper, clock, normalizedTime, running. Task-number: QTBUG-78482 Change-Id: I1c24b5f9cbf647eda6f7bb329c58e496dcb22f4a Reviewed-by: Paul Lemire --- .../frontend/qabstractclipanimator.cpp | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp index 238dbea8c..2d4de676c 100644 --- a/src/animation/frontend/qabstractclipanimator.cpp +++ b/src/animation/frontend/qabstractclipanimator.cpp @@ -138,6 +138,11 @@ void QAbstractClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &ch QAbstractClipAnimator::~QAbstractClipAnimator() { } +/*! + \qmlproperty bool Qt3DAnimation::AbstractClipAnimator::running + + This property holds a boolean indicating whether the animation is currently running. +*/ /*! \property Qt3DAnimation::QAbstractClipAnimator::running @@ -154,6 +159,13 @@ bool QAbstractClipAnimator::isRunning() const return d->m_running; } +/*! + \qmlproperty ChannelMapper Qt3DAnimation::AbstractClipAnimator::channelMapper + + This property holds the ChannelMapper that controls how the channels in + the animation clip map onto the properties of the target objects. +*/ + /*! \property Qt3DAnimation::QAbstractClipAnimator::channelMapper @@ -211,6 +223,12 @@ int QAbstractClipAnimator::loopCount() const Q_D(const QAbstractClipAnimator); return d->m_loops; } +/*! + \qmlproperty Clock Qt3DAnimation::AbstractClipAnimator::clock + + The clock controls the speed with which an animation is played. +*/ + /*! \property Qt3DAnimation::QAbstractClipAnimator::clock @@ -221,7 +239,11 @@ QClock *QAbstractClipAnimator::clock() const Q_D(const QAbstractClipAnimator); return d->m_clock; } +/*! + \qmlproperty real Qt3DAnimation::AbstractClipAnimator::normalizedTime + This property holds the clips normalized time. +*/ /*! \property Qt3DAnimation::QAbstractClipAnimator::normalizedTime From 714c81d95e9a0bd91637a25fb20c54135c306442 Mon Sep 17 00:00:00 2001 From: Tomi Korpipaa Date: Tue, 8 Oct 2019 13:51:23 +0300 Subject: [PATCH 06/12] Fix rendering when closing and re-opening a window Scene3D stops rendering if a window is closed and then opened again. That happens because eventfilter was removed at SurfaceAboutToBeDestroyed. There is no need to remove the event filter, as a destroyed window will not receive any events in any case. Task-number: QTBUG-77263 Change-Id: I1bcf3c572da6c06c09d1d9590bd8481b1fed6953 Reviewed-by: Miikka Heikkinen Reviewed-by: Paul Lemire --- src/render/backend/platformsurfacefilter.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/render/backend/platformsurfacefilter.cpp b/src/render/backend/platformsurfacefilter.cpp index 7458f607d..891e30c44 100644 --- a/src/render/backend/platformsurfacefilter.cpp +++ b/src/render/backend/platformsurfacefilter.cpp @@ -107,10 +107,6 @@ bool PlatformSurfaceFilter::eventFilter(QObject *obj, QEvent *e) // If we remove it, the call to isSurfaceValid will // implicitely return false PlatformSurfaceFilter::m_surfacesValidity.remove(m_surface); - if (m_obj) { - m_obj->removeEventFilter(this); - m_obj = nullptr; - } break; } From 744d5bbdb462bb731bc6422c12645e24a57e6bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4=C3=A4tt=C3=A4?= Date: Tue, 8 Oct 2019 13:29:49 +0300 Subject: [PATCH 07/12] Add comment about far plane value affecting picking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-70589 Change-Id: I397d24f3d7fed25fe3612e481a3ee16d4e0fe1ab Reviewed-by: Miikka Heikkinen Reviewed-by: Tomi Korpipää Reviewed-by: Paul Lemire --- src/render/picking/qobjectpicker.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/render/picking/qobjectpicker.cpp b/src/render/picking/qobjectpicker.cpp index f41ea06a6..d1a246c27 100644 --- a/src/render/picking/qobjectpicker.cpp +++ b/src/render/picking/qobjectpicker.cpp @@ -80,6 +80,9 @@ namespace Qt3DRender { \note Instances of this component shouldn't be shared, not respecting that condition will most likely result in undefined behavior. + \note The camera far plane value affects picking and produces incorrect results due to + floating-point precision if it is greater than ~100 000. + \since 5.6 */ @@ -113,6 +116,9 @@ namespace Qt3DRender { \note Instances of this component shouldn't be shared, not respecting that condition will most likely result in undefined behavior. + + \note The camera far plane value affects picking and produces incorrect results due to + floating-point precision if it is greater than ~100 000. */ /*! From 2e74095b645d3ecbbb8850e24dc823ed4378f650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4=C3=A4tt=C3=A4?= Date: Wed, 9 Oct 2019 08:57:54 +0300 Subject: [PATCH 08/12] Prevent picking from losing events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use append instead of assingment in PickBoundingVolumeJobs setxxxEvents. The setters gets called more times than the job gets to run so appending will not overwrite the events we have not processed yet. Task-number: QTBUG-69397 Change-Id: I4823ac5f622f636ee18af64d729ef196f76bc886 Reviewed-by: Tomi Korpipää Reviewed-by: Paul Lemire --- src/render/jobs/pickboundingvolumejob.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index 96ec11b4e..1a6cd7ba4 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -122,12 +122,12 @@ void PickBoundingVolumeJob::setRoot(Entity *root) void PickBoundingVolumeJob::setMouseEvents(const QList> &pendingEvents) { - m_pendingMouseEvents = pendingEvents; + m_pendingMouseEvents.append(pendingEvents); } void PickBoundingVolumeJob::setKeyEvents(const QList &pendingEvents) { - m_pendingKeyEvents = pendingEvents; + m_pendingKeyEvents.append(pendingEvents); } void PickBoundingVolumeJob::markPickersDirty() From e628cf90be9eef43d7a80a35067a5f4a6ef80809 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 9 Oct 2019 07:58:39 +0200 Subject: [PATCH 09/12] Fix blitting to also blit depth and stencil buffers Change-Id: Ib7b491c638508cfcdfbd523fd4e6a3d757c2c832 Reviewed-by: Sean Harmer --- .../renderers/opengl/graphicshelpers/submissioncontext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp index 1a2971a3f..73393d78b 100644 --- a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp +++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp @@ -1509,7 +1509,8 @@ void SubmissionContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId, const GLenum mode = interpolationMethod ? GL_NEAREST : GL_LINEAR; m_glHelper->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - GL_COLOR_BUFFER_BIT, mode); + GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, + mode); // Reset draw buffer bindFramebuffer(lastDrawFboId, GraphicsHelperInterface::FBOReadAndDraw); From 93aa379ae5cf624f024aa9173ce42e90b5c58002 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 9 Oct 2019 11:14:36 +0200 Subject: [PATCH 10/12] Make sure right screen is set on QOpenGLContext and QOffscreenSurface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the Qt3D window is on a specific screen, then it needs to ensure that any supporting QOpenGLContexts and QOffscreenSurfaces are set to be using that same screen or it will fail to render the content. Change-Id: Ief4f3e88bf6f71862bc5dace0cb0bddcdf3a98b5 Reviewed-by: Tomi Korpipää Reviewed-by: Paul Lemire --- src/quick3d/imports/scene3d/scene3ditem.cpp | 5 +++++ src/quick3d/quick3dextras/qt3dquickwindow.cpp | 3 +++ src/render/backend/abstractrenderer_p.h | 3 +++ src/render/backend/offscreensurfacehelper.cpp | 1 + src/render/frontend/qrenderaspect.cpp | 1 + src/render/frontend/qrenderaspect_p.h | 2 ++ .../renderers/opengl/renderer/commandthread.cpp | 1 + src/render/renderers/opengl/renderer/renderer.cpp | 14 ++++++++++++++ src/render/renderers/opengl/renderer/renderer_p.h | 4 ++++ 9 files changed, 34 insertions(+) diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp index f5173497b..eb8c6ffd9 100644 --- a/src/quick3d/imports/scene3d/scene3ditem.cpp +++ b/src/quick3d/imports/scene3d/scene3ditem.cpp @@ -66,6 +66,7 @@ #include #include +#include #include #include #include @@ -301,6 +302,7 @@ void Scene3DItem::setWindowSurface(QObject *rootObject) m_dummySurface = new QOffscreenSurface; m_dummySurface->setParent(qGuiApp); // parent to something suitably long-living m_dummySurface->setFormat(rw->format()); + m_dummySurface->setScreen(rw->screen()); m_dummySurface->create(); surfaceSelector->setSurface(m_dummySurface); } else { @@ -388,6 +390,9 @@ QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNode // If the render aspect wasn't created yet, do so now if (m_renderAspect == nullptr) { m_renderAspect = new QRenderAspect(QRenderAspect::Synchronous); + auto *rw = QQuickRenderControl::renderWindowFor(window()); + static_cast(Qt3DRender::QRenderAspectPrivate::get(m_renderAspect))->m_screen = + (rw ? rw->screen() : window()->screen()); m_aspectEngine->registerAspect(m_renderAspect); } diff --git a/src/quick3d/quick3dextras/qt3dquickwindow.cpp b/src/quick3d/quick3dextras/qt3dquickwindow.cpp index bc4bb25ee..d67dfdc71 100644 --- a/src/quick3d/quick3dextras/qt3dquickwindow.cpp +++ b/src/quick3d/quick3dextras/qt3dquickwindow.cpp @@ -66,6 +66,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -132,6 +133,8 @@ Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent) QSurfaceFormat::setDefaultFormat(format); d->m_renderAspect = new Qt3DRender::QRenderAspect; + if (parent && parent->screen()) + static_cast(Qt3DRender::QRenderAspectPrivate::get(d->m_renderAspect))->m_screen = parent->screen(); d->m_inputAspect = new Qt3DInput::QInputAspect; d->m_logicAspect = new Qt3DLogic::QLogicAspect; d->m_engine = new Qt3DCore::Quick::QQmlAspectEngine; diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h index 69e71dece..273ab359a 100644 --- a/src/render/backend/abstractrenderer_p.h +++ b/src/render/backend/abstractrenderer_p.h @@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE class QSurface; class QSize; +class QScreen; namespace Qt3DCore { class QAbstractFrameAdvanceService; @@ -177,6 +178,8 @@ public: // For QtQuick rendering virtual void setOpenGLContext(QOpenGLContext *ctx) = 0; + virtual void setScreen(QScreen *) {} + virtual QScreen *screen() const { return nullptr; } virtual void setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) = 0; virtual QSurfaceFormat format() = 0; diff --git a/src/render/backend/offscreensurfacehelper.cpp b/src/render/backend/offscreensurfacehelper.cpp index 89dc6211f..38558d484 100644 --- a/src/render/backend/offscreensurfacehelper.cpp +++ b/src/render/backend/offscreensurfacehelper.cpp @@ -72,6 +72,7 @@ void OffscreenSurfaceHelper::createOffscreenSurface() m_offscreenSurface = new QOffscreenSurface; m_offscreenSurface->setParent(this); m_offscreenSurface->setFormat(m_renderer->format()); + m_offscreenSurface->setScreen(m_renderer->screen()); m_offscreenSurface->create(); } diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 14fbe1754..c60488e16 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -564,6 +564,7 @@ void QRenderAspect::onRegistered() // TO DO: Load proper Renderer class based on Qt configuration preferences d->m_renderer = new Render::Renderer(d->m_renderType); + d->m_renderer->setScreen(d->m_screen); d->m_renderer->setNodeManagers(d->m_nodeManagers); // Create a helper for deferring creation of an offscreen surface used during cleanup diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h index 4a091e164..28a9b2453 100644 --- a/src/render/frontend/qrenderaspect_p.h +++ b/src/render/frontend/qrenderaspect_p.h @@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE class QSurface; +class QScreen; namespace Qt3DRender { @@ -104,6 +105,7 @@ public: QVector m_renderPlugins; QRenderAspect::RenderType m_renderType; Render::OffscreenSurfaceHelper *m_offscreenHelper; + QScreen *m_screen = nullptr; static QMutex m_pluginLock; static QVector m_pluginConfig; diff --git a/src/render/renderers/opengl/renderer/commandthread.cpp b/src/render/renderers/opengl/renderer/commandthread.cpp index dcaacadcc..70ab964d6 100644 --- a/src/render/renderers/opengl/renderer/commandthread.cpp +++ b/src/render/renderers/opengl/renderer/commandthread.cpp @@ -97,6 +97,7 @@ void CommandThread::initialize(QOpenGLContext *mainContext, OffscreenSurfaceHelp // thread the wglShareLists call is made on) m_localContext.reset(new QOpenGLContext()); m_localContext->setFormat(m_mainContext->format()); + m_localContext->setScreen(m_mainContext->screen()); m_localContext->setShareContext(m_mainContext); if (!m_localContext->create()) qWarning("CommandThread: Failed to create local context"); diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index b4a19c641..d0b1f2a5d 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -357,6 +357,16 @@ void Renderer::setOpenGLContext(QOpenGLContext *context) m_glContext = context; } +void Renderer::setScreen(QScreen *scr) +{ + m_screen = scr; +} + +QScreen *Renderer::screen() const +{ + return m_screen; +} + // Called in RenderThread context by the run method of RenderThread // RenderThread has locked the mutex already and unlocks it when this // method termintates @@ -374,6 +384,8 @@ void Renderer::initialize() // we need to create it if (!m_glContext) { ctx = new QOpenGLContext; + if (m_screen) + ctx->setScreen(m_screen); ctx->setShareContext(qt_gl_global_share_context()); // TO DO: Shouldn't we use the highest context available and trust @@ -403,6 +415,8 @@ void Renderer::initialize() if (!ctx->shareContext()) { m_shareContext = new QOpenGLContext; + if (ctx->screen()) + m_shareContext->setScreen(ctx->screen()); m_shareContext->setFormat(ctx->format()); m_shareContext->setShareContext(ctx); m_shareContext->create(); diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index 5b5f5c4f4..9376e9eda 100644 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ b/src/render/renderers/opengl/renderer/renderer_p.h @@ -106,6 +106,7 @@ QT_BEGIN_NAMESPACE class QSurface; class QMouseEvent; +class QScreen; namespace Qt3DCore { class QEntity; @@ -294,6 +295,8 @@ public: ViewSubmissionResultData submitRenderViews(const QVector &renderViews); RendererCache *cache() { return &m_cache; } + void setScreen(QScreen *scr) override; + QScreen *screen() const override; #ifdef QT3D_RENDER_UNIT_TESTS public: @@ -421,6 +424,7 @@ private: QMetaObject::Connection m_contextConnection; RendererCache m_cache; + QScreen *m_screen = nullptr; }; } // namespace Render From 4e0f5efb815f6be45a3aa83217618479d8d25c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4=C3=A4tt=C3=A4?= Date: Thu, 10 Oct 2019 15:21:43 +0300 Subject: [PATCH 11/12] Add note to material system nodes that can't be disabled Task-number: QTBUG-67017 Change-Id: I20acb3aa5e778be7752e1568b08001838f094eb3 Reviewed-by: Paul Lemire --- src/render/materialsystem/qeffect.cpp | 4 ++++ src/render/materialsystem/qfilterkey.cpp | 4 ++++ src/render/materialsystem/qparameter.cpp | 4 ++++ src/render/materialsystem/qtechnique.cpp | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/src/render/materialsystem/qeffect.cpp b/src/render/materialsystem/qeffect.cpp index b611657c4..ba19154fd 100644 --- a/src/render/materialsystem/qeffect.cpp +++ b/src/render/materialsystem/qeffect.cpp @@ -69,6 +69,8 @@ QEffectPrivate::QEffectPrivate() An QEffect instance should be shared among several QMaterial instances when possible. + \note QEffect node can not be disabled. + \code QEffect *effect = new QEffect(); @@ -115,6 +117,8 @@ QEffectPrivate::QEffectPrivate() A Parameter defined on an Effect is overridden by a QParameter (of the same name) defined in a Material, TechniqueFilter, RenderPassFilter. + \note Effect node can not be disabled. + \code Effect { id: effect diff --git a/src/render/materialsystem/qfilterkey.cpp b/src/render/materialsystem/qfilterkey.cpp index 547c56d26..0cffde7c1 100644 --- a/src/render/materialsystem/qfilterkey.cpp +++ b/src/render/materialsystem/qfilterkey.cpp @@ -61,6 +61,8 @@ QFilterKeyPrivate::QFilterKeyPrivate() Filter keys are used by QTechnique and QRenderPass to specify at which stage of rendering the technique or the render pass is used. + + \note QFilterKey node can not be disabled. */ /*! @@ -74,6 +76,8 @@ QFilterKeyPrivate::QFilterKeyPrivate() A FilterKey is a storage type for filter key and value pair. Filter keys are used by Technique and RenderPass to specify at which stage of rendering the technique or the render pass is used. + + \note FilterKey node can not be disabled. */ QFilterKey::QFilterKey(QNode *parent) diff --git a/src/render/materialsystem/qparameter.cpp b/src/render/materialsystem/qparameter.cpp index afaf42158..92f3cf0c2 100644 --- a/src/render/materialsystem/qparameter.cpp +++ b/src/render/materialsystem/qparameter.cpp @@ -77,6 +77,8 @@ \note when the targeted uniform is an array, the name should be the name of the uniform with [0] appended to it. + \note Parameter node can not be disabled. + \code Parameter { name: "diffuseValues[0]" @@ -139,6 +141,8 @@ \note when the targeted uniform is an array, the name should be the name of the uniform with [0] appended to it. + \note QParameter node can not be disabled. + \code QParameter *param = new QParameter(); QVariantList values = QVariantList() << 0.0f << 1.0f << 2.0f << 3.0f << 4.0f << 883.0f << 1340.0f << 1584.0f; diff --git a/src/render/materialsystem/qtechnique.cpp b/src/render/materialsystem/qtechnique.cpp index b668eb25f..e5f109d46 100644 --- a/src/render/materialsystem/qtechnique.cpp +++ b/src/render/materialsystem/qtechnique.cpp @@ -90,6 +90,8 @@ QTechniquePrivate::~QTechniquePrivate() QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view will likely have no effect on Qt3D related rendering. + \note Technique node can not be disabled. + \qml Technique { id: gl3Technique @@ -155,6 +157,8 @@ QTechniquePrivate::~QTechniquePrivate() QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view will likely have no effect on Qt3D related rendering. + \note QTechnique node can not be disabled. + \code QTechnique *gl3Technique = new QTechnique(); From 7628760f8f16aba7769c04f2251633faa9fbcad1 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Mon, 14 Oct 2019 12:00:28 +0200 Subject: [PATCH 12/12] Doc: Use correct qml module names for qml types Change-Id: I19c9f2a3d31af77366316e78194a15789d1b67f9 Reviewed-by: Martin Smith --- src/render/frontend/qcomputecommand.cpp | 2 +- src/render/renderstates/qrenderstate.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/render/frontend/qcomputecommand.cpp b/src/render/frontend/qcomputecommand.cpp index 8b176cd4f..e7acdd94a 100644 --- a/src/render/frontend/qcomputecommand.cpp +++ b/src/render/frontend/qcomputecommand.cpp @@ -67,7 +67,7 @@ namespace Qt3DRender { /*! \qmltype ComputeCommand \since 5.7 - \inmodule Qt3DRender + \inqmlmodule Qt3D.Render \inherits Component3D \instantiates Qt3DRender::QComputeCommand \brief Component to issue work for the compute shader on GPU. diff --git a/src/render/renderstates/qrenderstate.cpp b/src/render/renderstates/qrenderstate.cpp index 8a7d897be..cd5346710 100644 --- a/src/render/renderstates/qrenderstate.cpp +++ b/src/render/renderstates/qrenderstate.cpp @@ -59,6 +59,7 @@ namespace Qt3DRender { /*! \qmltype RenderState + \inqmlmodule Qt3D.Render \brief An abstract base type for all render states. \since 5.7 \inherits Node