diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-05-24 12:09:44 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-05-24 12:10:02 +0100 |
commit | 77d294db076dac19e8b549b445ffede9f7260c84 (patch) | |
tree | 828ee7a6862ec5c0bd24f97cb540625a2c647376 /src/extras | |
parent | 59f8fec8a41606b3185fe3a4e276978e3e1ed5ef (diff) | |
parent | 939b9b4b7591e8a421cf048a0a84ed3e75d81d21 (diff) |
Merge branch 'dev' into wip/animationwip/animation
Change-Id: I6e770609c90a7745d08fa4e2f424e865678c5d6f
Diffstat (limited to 'src/extras')
117 files changed, 5931 insertions, 3058 deletions
diff --git a/src/extras/3dtext/3dtext.pri b/src/extras/3dtext/3dtext.pri index bcf2ce948..d7855f1b0 100644 --- a/src/extras/3dtext/3dtext.pri +++ b/src/extras/3dtext/3dtext.pri @@ -1,11 +1,11 @@ SOURCES += \ - $$PWD/qtext3dgeometry.cpp \ - $$PWD/qtext3dmesh.cpp + $$PWD/qextrudedtextgeometry.cpp \ + $$PWD/qextrudedtextmesh.cpp HEADERS += \ - $$PWD/qtext3dgeometry.h \ - $$PWD/qtext3dgeometry_p.h \ - $$PWD/qtext3dmesh.h + $$PWD/qextrudedtextgeometry.h \ + $$PWD/qextrudedtextgeometry_p.h \ + $$PWD/qextrudedtextmesh.h INCLUDEPATH += $$PWD diff --git a/src/extras/3dtext/qtext3dgeometry.cpp b/src/extras/3dtext/qextrudedtextgeometry.cpp index 529c93b79..4a460bfc7 100644 --- a/src/extras/3dtext/qtext3dgeometry.cpp +++ b/src/extras/3dtext/qextrudedtextgeometry.cpp @@ -48,8 +48,8 @@ ** ****************************************************************************/ -#include "qtext3dgeometry.h" -#include "qtext3dgeometry_p.h" +#include "qextrudedtextgeometry.h" +#include "qextrudedtextgeometry_p.h" #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qbufferdatagenerator.h> #include <Qt3DRender/qattribute.h> @@ -65,7 +65,9 @@ namespace Qt3DExtras { namespace { -using IndexType = unsigned short; +static float edgeSplitAngle = 90.f * 0.1f; + +using IndexType = unsigned int; struct TriangulationData { struct Outline { @@ -103,7 +105,7 @@ TriangulationData triangulate(const QString &text, const QFont &font) for (QPolygonF &p : polygons) path.addPolygon(p); - // Extract polylines out of the path, this allows us to retrive indicies for each glyph outline + // Extract polylines out of the path, this allows us to retrieve indices for each glyph outline QPolylineSet polylines = qPolyline(path); QVector<IndexType> tmpIndices; tmpIndices.resize(polylines.indices.size()); @@ -145,11 +147,10 @@ inline QVector3D mix(const QVector3D &a, const QVector3D &b, float ratio) } // anonymous namespace -QText3DGeometryPrivate::QText3DGeometryPrivate() +QExtrudedTextGeometryPrivate::QExtrudedTextGeometryPrivate() : QGeometryPrivate() , m_font(QFont(QStringLiteral("Arial"))) , m_depth(1.f) - , m_edgeSplitAngle(90.f * 0.1f) , m_positionAttribute(nullptr) , m_normalAttribute(nullptr) , m_indexAttribute(nullptr) @@ -159,9 +160,9 @@ QText3DGeometryPrivate::QText3DGeometryPrivate() m_font.setPointSize(4); } -void QText3DGeometryPrivate::init() +void QExtrudedTextGeometryPrivate::init() { - Q_Q(QText3DGeometry); + Q_Q(QExtrudedTextGeometry); m_positionAttribute = new Qt3DRender::QAttribute(q); m_normalAttribute = new Qt3DRender::QAttribute(q); m_indexAttribute = new Qt3DRender::QAttribute(q); @@ -190,7 +191,7 @@ void QText3DGeometryPrivate::init() m_normalAttribute->setCount(0); m_indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); - m_indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort); + m_indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); m_indexAttribute->setBuffer(m_indexBuffer); m_indexAttribute->setCount(0); @@ -202,101 +203,96 @@ void QText3DGeometryPrivate::init() } /*! - * \qmltype Text3DGeometry - * \instantiates Qt3DExtras::QText3DGeometry + * \qmltype ExtrudedTextGeometry + * \instantiates Qt3DExtras::QExtrudedTextGeometry * \inqmlmodule Qt3D.Extras - * \brief Text3DGeometry allows creation of a 3D text in 3D space. + * \brief ExtrudedTextGeometry allows creation of a 3D text in 3D space. * - * The Text3DGeometry type is most commonly used internally by the Text3DMesh type - * but can also be used in custom GeometryRenderer types. + * The ExtrudedTextGeometry type is most commonly used internally by the + * ExtrudedTextMesh type but can also be used in custom GeometryRenderer types. */ /*! - * \qmlproperty QString Text3DGeometry::text + * \qmlproperty QString ExtrudedTextGeometry::text * * Holds the text used for the mesh. */ /*! - * \qmlproperty QFont Text3DGeometry::font + * \qmlproperty QFont ExtrudedTextGeometry::font * * Holds the font of the text. */ /*! - * \qmlproperty float Text3DGeometry::depth + * \qmlproperty float ExtrudedTextGeometry::depth * * Holds the extrusion depth of the text. */ /*! - * \qmlproperty float Text3DGeometry::edgeSplitAngle - * - * Holds the threshold angle for smooth normals. - */ - -/*! - * \qmlproperty Attribute Text3DGeometry::positionAttribute + * \qmlproperty Attribute ExtrudedTextGeometry::positionAttribute * * Holds the geometry position attribute. */ /*! - * \qmlproperty Attribute Text3DGeometry::normalAttribute + * \qmlproperty Attribute ExtrudedTextGeometry::normalAttribute * * Holds the geometry normal attribute. */ /*! - * \qmlproperty Attribute Text3DGeometry::indexAttribute + * \qmlproperty Attribute ExtrudedTextGeometry::indexAttribute * * Holds the geometry index attribute. */ /*! - * \class Qt3DExtras::QText3DGeometry - * \inheaderfile Qt3DExtras/QText3DGeometry + * \class Qt3DExtras::QExtrudedTextGeometry + * \inheaderfile Qt3DExtras/QExtrudedTextGeometry * \inmodule Qt3DExtras - * \brief The QText3DGeometry class allows creation of a 3D text in 3D space. - * \since 5.8 + * \brief The QExtrudedTextGeometry class allows creation of a 3D extruded text + * in 3D space. + * \since 5.9 * \ingroup geometries * \inherits Qt3DRender::QGeometry * - * The QText3DGeometry class is most commonly used internally by the QText3DMesh + * The QExtrudedTextGeometry class is most commonly used internally by the QText3DMesh * but can also be used in custom Qt3DRender::QGeometryRenderer subclasses. */ /*! - * Constructs a new QText3DGeometry with \a parent. + * Constructs a new QExtrudedTextGeometry with \a parent. */ -QText3DGeometry::QText3DGeometry(Qt3DCore::QNode *parent) - : QGeometry(*new QText3DGeometryPrivate(), parent) +QExtrudedTextGeometry::QExtrudedTextGeometry(Qt3DCore::QNode *parent) + : QGeometry(*new QExtrudedTextGeometryPrivate(), parent) { - Q_D(QText3DGeometry); + Q_D(QExtrudedTextGeometry); d->init(); } /*! * \internal */ -QText3DGeometry::QText3DGeometry(QText3DGeometryPrivate &dd, Qt3DCore::QNode *parent) +QExtrudedTextGeometry::QExtrudedTextGeometry(QExtrudedTextGeometryPrivate &dd, Qt3DCore::QNode *parent) : QGeometry(dd, parent) { - Q_D(QText3DGeometry); + Q_D(QExtrudedTextGeometry); d->init(); } /*! * \internal */ -QText3DGeometry::~QText3DGeometry() +QExtrudedTextGeometry::~QExtrudedTextGeometry() {} /*! * \internal - * Updates vertices based on text, font, depth and smoothAngle properties. + * Updates vertices based on text, font, extrusionLength and smoothAngle properties. */ -void QText3DGeometryPrivate::update() +void QExtrudedTextGeometryPrivate::update() { if (m_text.trimmed().isEmpty()) // save enough? return; @@ -328,6 +324,9 @@ void QText3DGeometryPrivate::update() const int end = data.outlines[i].end; const int verticesIndexBegin = verticesIndex; + if (begin == end) + continue; + QVector3D prevNormal = QVector3D::crossProduct( vertices[data.outlineIndices[end - 1] + numVertices].position - vertices[data.outlineIndices[end - 1]].position, vertices[data.outlineIndices[begin]].position - vertices[data.outlineIndices[end - 1]].position).normalized(); @@ -339,7 +338,7 @@ void QText3DGeometryPrivate::update() const QVector3D normal = QVector3D::crossProduct(vertices[cur + numVertices].position - vertices[cur].position, vertices[next].position - vertices[cur].position).normalized(); // use smooth normals in case of a short angle - const bool smooth = QVector3D::dotProduct(prevNormal, normal) > (90.0f - m_edgeSplitAngle) / 90.0f; + const bool smooth = QVector3D::dotProduct(prevNormal, normal) > (90.0f - edgeSplitAngle) / 90.0f; const QVector3D resultNormal = smooth ? mix(prevNormal, normal, 0.5f) : normal; if (!smooth) { vertices.push_back({vertices[cur].position, prevNormal}); @@ -403,9 +402,9 @@ void QText3DGeometryPrivate::update() } } -void QText3DGeometry::setText(QString text) +void QExtrudedTextGeometry::setText(const QString &text) { - Q_D(QText3DGeometry); + Q_D(QExtrudedTextGeometry); if (d->m_text != text) { d->m_text = text; d->update(); @@ -413,9 +412,9 @@ void QText3DGeometry::setText(QString text) } } -void QText3DGeometry::setFont(QFont font) +void QExtrudedTextGeometry::setFont(const QFont &font) { - Q_D(QText3DGeometry); + Q_D(QExtrudedTextGeometry); if (d->m_font != font) { d->m_font = font; d->update(); @@ -423,9 +422,9 @@ void QText3DGeometry::setFont(QFont font) } } -void QText3DGeometry::setDepth(float depth) +void QExtrudedTextGeometry::setDepth(float depth) { - Q_D(QText3DGeometry); + Q_D(QExtrudedTextGeometry); if (d->m_depth != depth) { d->m_depth = depth; d->update(); @@ -433,90 +432,69 @@ void QText3DGeometry::setDepth(float depth) } } -void QText3DGeometry::setEdgeSplitAngle(float smoothAngle) -{ - Q_D(QText3DGeometry); - if (d->m_edgeSplitAngle != smoothAngle) { - d->m_edgeSplitAngle = smoothAngle; - d->update(); - emit edgeSplitAngleChanged(smoothAngle); - } -} - /*! - * \property QString Text3DGeometry::text + * \property QString QExtrudedTextGeometry::text * * Holds the text used for the mesh. */ -QString QText3DGeometry::text() const +QString QExtrudedTextGeometry::text() const { - Q_D(const QText3DGeometry); + Q_D(const QExtrudedTextGeometry); return d->m_text; } /*! - * \property QFont Text3DGeometry::font + * \property QFont QExtrudedTextGeometry::font * * Holds the font of the text. */ -QFont QText3DGeometry::font() const +QFont QExtrudedTextGeometry::font() const { - Q_D(const QText3DGeometry); + Q_D(const QExtrudedTextGeometry); return d->m_font; } /*! - * \property float Text3DGeometry::depth + * \property float QExtrudedTextGeometry::extrusionLength * - * Holds the extrusion depth of the text. + * Holds the extrusion length of the text. */ -float QText3DGeometry::depth() const +float QExtrudedTextGeometry::extrusionLength() const { - Q_D(const QText3DGeometry); + Q_D(const QExtrudedTextGeometry); return d->m_depth; } /*! - * \property float Text3DGeometry::edgeSplitAngle - * - * Holds the threshold angle for smooth normals. - */ -float QText3DGeometry::edgeSplitAngle() const -{ - Q_D(const QText3DGeometry); - return d->m_edgeSplitAngle; -} - -/*! - * \property Text3DGeometry::positionAttribute + * \property QExtrudedTextGeometry::positionAttribute * * Holds the geometry position attribute. */ -Qt3DRender::QAttribute *QText3DGeometry::positionAttribute() const +Qt3DRender::QAttribute *QExtrudedTextGeometry::positionAttribute() const { - Q_D(const QText3DGeometry); + Q_D(const QExtrudedTextGeometry); return d->m_positionAttribute; } /*! - * \property Text3DGeometry::normalAttribute + * \property QExtrudedTextMesh::normalAttribute * * Holds the geometry normal attribute. */ -Qt3DRender::QAttribute *QText3DGeometry::normalAttribute() const +Qt3DRender::QAttribute *QExtrudedTextGeometry::normalAttribute() const { - Q_D(const QText3DGeometry); + Q_D(const QExtrudedTextGeometry); return d->m_normalAttribute; } /*! - * \property Text3DGeometry::indexAttribute + * \property QExtrudedTextMesh::indexAttribute * * Holds the geometry index attribute. */ -Qt3DRender::QAttribute *QText3DGeometry::indexAttribute() const +Qt3DRender::QAttribute *QExtrudedTextGeometry::indexAttribute() const { - Q_D(const QText3DGeometry); + Q_D(const QExtrudedTextGeometry); return d->m_indexAttribute; } diff --git a/src/extras/3dtext/qtext3dgeometry.h b/src/extras/3dtext/qextrudedtextgeometry.h index 4cd89b112..9ee8b23f0 100644 --- a/src/extras/3dtext/qtext3dgeometry.h +++ b/src/extras/3dtext/qextrudedtextgeometry.h @@ -48,8 +48,8 @@ ** ****************************************************************************/ -#ifndef QT3DEXTRAS_QTEXT3DGEOMETRY_H -#define QT3DEXTRAS_QTEXT3DGEOMETRY_H +#ifndef QT3DEXTRAS_QEXTRUDEDTEXTGEOMETRY_H +#define QT3DEXTRAS_QEXTRUDEDTEXTGEOMETRY_H #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qgeometry.h> @@ -66,52 +66,48 @@ class QAttribute; namespace Qt3DExtras { -class QText3DGeometryPrivate; +class QExtrudedTextGeometryPrivate; -class QT3DEXTRASSHARED_EXPORT QText3DGeometry : public Qt3DRender::QGeometry +class QT3DEXTRASSHARED_EXPORT QExtrudedTextGeometry : public Qt3DRender::QGeometry { Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) - Q_PROPERTY(float depth READ depth WRITE setDepth NOTIFY depthChanged) - Q_PROPERTY(float edgeSplitAngle READ edgeSplitAngle WRITE setEdgeSplitAngle NOTIFY edgeSplitAngleChanged) + Q_PROPERTY(float extrusionLength READ extrusionLength WRITE setDepth NOTIFY depthChanged) Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT) Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT) Q_PROPERTY(Qt3DRender::QAttribute *indexAttribute READ indexAttribute CONSTANT) public: - explicit QText3DGeometry(Qt3DCore::QNode *parent = nullptr); - ~QText3DGeometry(); + explicit QExtrudedTextGeometry(Qt3DCore::QNode *parent = nullptr); + ~QExtrudedTextGeometry(); Qt3DRender::QAttribute *positionAttribute() const; Qt3DRender::QAttribute *normalAttribute() const; Qt3DRender::QAttribute *indexAttribute() const; QString text() const; QFont font() const; - float depth() const; - float edgeSplitAngle() const; + float extrusionLength() const; public Q_SLOTS: - void setText(QString text); - void setFont(QFont font); - void setDepth(float depth); - void setEdgeSplitAngle(float edgeSplitAngle); + void setText(const QString &text); + void setFont(const QFont &font); + void setDepth(float extrusionLength); Q_SIGNALS: - void textChanged(QString text); - void fontChanged(QFont font); - void depthChanged(float depth); - void edgeSplitAngleChanged(float edgeSplitAngle); + void textChanged(const QString &text); + void fontChanged(const QFont &font); + void depthChanged(float extrusionLength); protected: - QText3DGeometry(QText3DGeometryPrivate &dd, QNode *parent = nullptr); + explicit QExtrudedTextGeometry(QExtrudedTextGeometryPrivate &dd, QNode *parent = nullptr); private: - Q_DECLARE_PRIVATE(QText3DGeometry) + Q_DECLARE_PRIVATE(QExtrudedTextGeometry) }; } // namespace Qt3DExtras QT_END_NAMESPACE -#endif // QT3DEXTRAS_QTEXT3DGEOMETRY_H +#endif // QT3DEXTRAS_QEXTRUDEDTEXTGEOMETRY_H diff --git a/src/extras/3dtext/qtext3dgeometry_p.h b/src/extras/3dtext/qextrudedtextgeometry_p.h index dc5e2f6a7..0bfa45e17 100644 --- a/src/extras/3dtext/qtext3dgeometry_p.h +++ b/src/extras/3dtext/qextrudedtextgeometry_p.h @@ -48,8 +48,8 @@ ** ****************************************************************************/ -#ifndef QT3DEXTRAS_QTEXT3DGEOMETRY_P_H -#define QT3DEXTRAS_QTEXT3DGEOMETRY_P_H +#ifndef QT3DEXTRAS_QEXTRUDEDTEXTGEOMETRY_P_H +#define QT3DEXTRAS_QEXTRUDEDTEXTGEOMETRY_P_H // // W A R N I N G @@ -76,12 +76,12 @@ class QBuffer; namespace Qt3DExtras { -class QText3DGeometry; +class QExtrudedTextGeometry; -class QText3DGeometryPrivate : public Qt3DRender::QGeometryPrivate +class QExtrudedTextGeometryPrivate : public Qt3DRender::QGeometryPrivate { public: - QText3DGeometryPrivate(); + QExtrudedTextGeometryPrivate(); void init(); void update(); @@ -96,11 +96,11 @@ public: Qt3DRender::QBuffer *m_vertexBuffer; Qt3DRender::QBuffer *m_indexBuffer; - Q_DECLARE_PUBLIC(QText3DGeometry) + Q_DECLARE_PUBLIC(QExtrudedTextGeometry) }; } // namespace Qt3DExtras QT_END_NAMESPACE -#endif // QT3DEXTRAS_QTEXT3DGEOMETRY_P_H +#endif // QT3DEXTRAS_QEXTRUDEDTEXTGEOMETRY_P_H diff --git a/src/extras/3dtext/qtext3dmesh.cpp b/src/extras/3dtext/qextrudedtextmesh.cpp index a89c01a4d..9d1dc7359 100644 --- a/src/extras/3dtext/qtext3dmesh.cpp +++ b/src/extras/3dtext/qextrudedtextmesh.cpp @@ -48,130 +48,108 @@ ** ****************************************************************************/ -#include "qtext3dmesh.h" -#include "qtext3dgeometry.h" +#include "qextrudedtextmesh.h" +#include "qextrudedtextgeometry.h" QT_BEGIN_NAMESPACE namespace Qt3DExtras { /*! - * \qmltype Text3DMesh - * \instantiates Qt3DExtras::QText3DMesh + * \qmltype ExtrudedTextMesh + * \instantiates Qt3DExtras::QExtrudedTextMesh * \inqmlmodule Qt3D.Extras - * \brief A 3D Text mesh. + * \brief A 3D extruded Text mesh. */ /*! - * \qmlproperty QString Text3DMesh::text + * \qmlproperty QString ExtrudedTextMesh::text * * Holds the text used for the mesh. */ /*! - * \qmlproperty QFont Text3DMesh::font + * \qmlproperty QFont ExtrudedTextMesh::font * * Holds the font of the text. */ /*! - * \qmlproperty float Text3DMesh::depth + * \qmlproperty float ExtrudedTextMesh::depth * * Holds the extrusion depth of the text. */ /*! - * \qmlproperty float Text3DMesh::edgeSplitAngle - * - * Holds the threshold angle for smooth normals. - */ - -/*! - * \class Qt3DExtras::QText3DMesh - * \inheaderfile Qt3DExtras/QText3DMesh + * \class Qt3DExtras::QExtrudedTextMesh + * \inheaderfile Qt3DExtras/QExtrudedTextMesh * \inmodule Qt3DExtras * * \inherits Qt3DRender::QGeometryRenderer * - * \brief A 3D Text mesh. + * \brief A 3D extruded Text mesh. */ /*! * Constructs a new QText3DMesh with \a parent. */ -QText3DMesh::QText3DMesh(Qt3DCore::QNode *parent) +QExtrudedTextMesh::QExtrudedTextMesh(Qt3DCore::QNode *parent) : QGeometryRenderer(parent) { - QText3DGeometry *geometry = new QText3DGeometry(); - QObject::connect(geometry, &QText3DGeometry::depthChanged, this, &QText3DMesh::depthChanged); - QObject::connect(geometry, &QText3DGeometry::textChanged, this, &QText3DMesh::textChanged); - QObject::connect(geometry, &QText3DGeometry::fontChanged, this, &QText3DMesh::fontChanged); - QObject::connect(geometry, &QText3DGeometry::edgeSplitAngleChanged, this, &QText3DMesh::edgeSplitAngleChanged); + QExtrudedTextGeometry *geometry = new QExtrudedTextGeometry(); + QObject::connect(geometry, &QExtrudedTextGeometry::depthChanged, this, &QExtrudedTextMesh::depthChanged); + QObject::connect(geometry, &QExtrudedTextGeometry::textChanged, this, &QExtrudedTextMesh::textChanged); + QObject::connect(geometry, &QExtrudedTextGeometry::fontChanged, this, &QExtrudedTextMesh::fontChanged); QGeometryRenderer::setGeometry(geometry); } /*! \internal */ -QText3DMesh::~QText3DMesh() +QExtrudedTextMesh::~QExtrudedTextMesh() {} -void QText3DMesh::setText(QString text) -{ - static_cast<QText3DGeometry*>(geometry())->setText(text); -} - -void QText3DMesh::setFont(QFont font) +void QExtrudedTextMesh::setText(const QString &text) { - static_cast<QText3DGeometry*>(geometry())->setFont(font); + static_cast<QExtrudedTextGeometry*>(geometry())->setText(text); } -void QText3DMesh::setDepth(float depth) +void QExtrudedTextMesh::setFont(const QFont &font) { - static_cast<QText3DGeometry*>(geometry())->setDepth(depth); + static_cast<QExtrudedTextGeometry*>(geometry())->setFont(font); } -void QText3DMesh::setEdgeSplitAngle(float smoothAngle) +void QExtrudedTextMesh::setDepth(float depth) { - static_cast<QText3DGeometry*>(geometry())->setEdgeSplitAngle(smoothAngle); + static_cast<QExtrudedTextGeometry*>(geometry())->setDepth(depth); } /*! - * \property QString QText3DMesh::text + * \property QString QExtrudedTextMesh::text * * Holds the text used for the mesh. */ -QString QText3DMesh::text() +QString QExtrudedTextMesh::text() const { - return static_cast<QText3DGeometry*>(geometry())->text(); + return static_cast<QExtrudedTextGeometry*>(geometry())->text(); } /*! - * \property QFont QText3DMesh::font + * \property QFont QExtrudedTextMesh::font * * Holds the font of the text. */ -QFont QText3DMesh::font() +QFont QExtrudedTextMesh::font() const { - return static_cast<QText3DGeometry*>(geometry())->font(); + return static_cast<QExtrudedTextGeometry*>(geometry())->font(); } /*! - * \property float QText3DMesh::depth + * \property float QExtrudedTextMesh::depth * * Holds the extrusion depth of the text. */ -float QText3DMesh::depth() -{ - return static_cast<QText3DGeometry*>(geometry())->depth(); -} - -/*! - * \property float QText3DMesh::edgeSplitAngle - * - * Holds the threshold angle for smooth normals. - */ -float QText3DMesh::edgeSplitAngle() +float QExtrudedTextMesh::depth() const { - return static_cast<QText3DGeometry*>(geometry())->edgeSplitAngle(); + return static_cast<QExtrudedTextGeometry*>(geometry())->extrusionLength(); } } // namespace Qt3DExtras diff --git a/src/extras/3dtext/qtext3dmesh.h b/src/extras/3dtext/qextrudedtextmesh.h index 6bb546675..3f2f41a37 100644 --- a/src/extras/3dtext/qtext3dmesh.h +++ b/src/extras/3dtext/qextrudedtextmesh.h @@ -48,8 +48,8 @@ ** ****************************************************************************/ -#ifndef QT3DEXTRAS_QTEXT3DMESH_H -#define QT3DEXTRAS_QTEXT3DMESH_H +#ifndef QT3DEXTRAS_QEXTRUDEDTEXTMESH_H +#define QT3DEXTRAS_QEXTRUDEDTEXTMESH_H #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qgeometryrenderer.h> @@ -60,38 +60,34 @@ QT_BEGIN_NAMESPACE namespace Qt3DExtras { -class QT3DEXTRASSHARED_EXPORT QText3DMesh : public Qt3DRender::QGeometryRenderer +class QT3DEXTRASSHARED_EXPORT QExtrudedTextMesh : public Qt3DRender::QGeometryRenderer { Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) Q_PROPERTY(float depth READ depth WRITE setDepth NOTIFY depthChanged) - Q_PROPERTY(float edgeSplitAngle READ edgeSplitAngle WRITE setEdgeSplitAngle NOTIFY edgeSplitAngleChanged) public: - QText3DMesh(Qt3DCore::QNode *parent = nullptr); - ~QText3DMesh(); + explicit QExtrudedTextMesh(Qt3DCore::QNode *parent = nullptr); + ~QExtrudedTextMesh(); - QString text(); - QFont font(); - float depth(); - float edgeSplitAngle(); + QString text() const; + QFont font() const; + float depth() const; public Q_SLOTS: - void setText(QString text); - void setFont(QFont font); + void setText(const QString &text); + void setFont(const QFont &font); void setDepth(float depth); - void setEdgeSplitAngle(float edgeSplitAngle); Q_SIGNALS: - void textChanged(QString text); - void fontChanged(QFont font); + void textChanged(const QString &text); + void fontChanged(const QFont &font); void depthChanged(float depth); - void edgeSplitAngleChanged(float edgeSplitAngle); }; } // namespace Qt3DExtras QT_END_NAMESPACE -#endif // QT3DEXTRAS_QTEXT3DMESH_H +#endif // QT3DEXTRAS_QEXTRUDEDTEXTMESH_H diff --git a/src/extras/animations/animations.pri b/src/extras/animations/animations.pri deleted file mode 100644 index 71d6099fc..000000000 --- a/src/extras/animations/animations.pri +++ /dev/null @@ -1,26 +0,0 @@ -HEADERS += \ - $$PWD/qanimationcontroller.h \ - $$PWD/qanimationcontroller_p.h \ - $$PWD/qanimationgroup.h \ - $$PWD/qanimationgroup_p.h \ - $$PWD/qkeyframeanimation.h \ - $$PWD/qkeyframeanimation_p.h \ - $$PWD/qmorphinganimation.h \ - $$PWD/qmorphinganimation_p.h \ - $$PWD/qabstractanimation.h \ - $$PWD/qabstractanimation_p.h \ - $$PWD/qmorphtarget.h \ - $$PWD/qmorphtarget_p.h \ - $$PWD/qvertexblendanimation.h \ - $$PWD/qvertexblendanimation_p.h - -SOURCES += \ - $$PWD/qanimationcontroller.cpp \ - $$PWD/qanimationgroup.cpp \ - $$PWD/qkeyframeanimation.cpp \ - $$PWD/qmorphinganimation.cpp \ - $$PWD/qabstractanimation.cpp \ - $$PWD/qmorphtarget.cpp \ - $$PWD/qvertexblendanimation.cpp - -INCLUDEPATH += $$PWD diff --git a/src/extras/animations/qabstractanimation.cpp b/src/extras/animations/qabstractanimation.cpp deleted file mode 100644 index f87455c18..000000000 --- a/src/extras/animations/qabstractanimation.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qabstractanimation.h" -#include "Qt3DExtras/private/qabstractanimation_p.h" - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -QAbstractAnimationPrivate::QAbstractAnimationPrivate(QAbstractAnimation::AnimationType type) - : QObjectPrivate() - , m_animationType(type) - , m_position(0.0f) - , m_duration(0.0f) -{ - -} - -QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent) - : QObject(dd, parent) -{ - -} - -QString QAbstractAnimation::animationName() const -{ - Q_D(const QAbstractAnimation); - return d->m_animationName; -} - -QAbstractAnimation::AnimationType QAbstractAnimation::animationType() const -{ - Q_D(const QAbstractAnimation); - return d->m_animationType; -} - -float QAbstractAnimation::position() const -{ - Q_D(const QAbstractAnimation); - return d->m_position; -} - -float QAbstractAnimation::duration() const -{ - Q_D(const QAbstractAnimation); - return d->m_duration; -} - -void QAbstractAnimation::setAnimationName(const QString &name) -{ - Q_D(QAbstractAnimation); - if (name != d->m_animationName) { - d->m_animationName = name; - emit animationNameChanged(name); - } -} - -void QAbstractAnimation::setPosition(float position) -{ - Q_D(QAbstractAnimation); - if (!qFuzzyCompare(position, d->m_position)) { - d->m_position = position; - emit positionChanged(position); - } -} - -void QAbstractAnimation::setDuration(float duration) -{ - Q_D(QAbstractAnimation); - if (!qFuzzyCompare(duration, d->m_duration)) { - d->m_duration = duration; - emit durationChanged(duration); - } -} - -} // Qt3DExtras - -QT_END_NAMESPACE diff --git a/src/extras/animations/qabstractanimation.h b/src/extras/animations/qabstractanimation.h deleted file mode 100644 index 242fe293a..000000000 --- a/src/extras/animations/qabstractanimation.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QABSTRACTANIMATION_H -#define QT3DEXTRAS_QABSTRACTANIMATION_H - -#include <QtCore/qobject.h> -#include <QtCore/qvector.h> - -#include <Qt3DExtras/qt3dextras_global.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QAbstractAnimationPrivate; - -class QT3DEXTRASSHARED_EXPORT QAbstractAnimation : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString animationName READ animationName WRITE setAnimationName NOTIFY animationNameChanged) - Q_PROPERTY(QAbstractAnimation::AnimationType animationType READ animationType CONSTANT) - Q_PROPERTY(float position READ position WRITE setPosition NOTIFY positionChanged) - Q_PROPERTY(float duration READ duration NOTIFY durationChanged) - -public: - enum AnimationType { - KeyframeAnimation = 1, - MorphingAnimation = 2, - VertexBlendAnimation = 3, - }; - - QString animationName() const; - QAbstractAnimation::AnimationType animationType() const; - float position() const; - float duration() const; - -public Q_SLOTS: - void setAnimationName(const QString &name); - void setPosition(float position); - -protected: - explicit QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = nullptr); - - void setDuration(float duration); - -Q_SIGNALS: - void animationNameChanged(const QString &name); - void positionChanged(float position); - void durationChanged(float duration); - -private: - Q_DECLARE_PRIVATE(QAbstractAnimation) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QABSTRACTANIMATION_H diff --git a/src/extras/animations/qabstractanimation_p.h b/src/extras/animations/qabstractanimation_p.h deleted file mode 100644 index 1370ef2c7..000000000 --- a/src/extras/animations/qabstractanimation_p.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QABSTRACTANIMATION_P_H -#define QT3DEXTRAS_QABSTRACTANIMATION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qobject_p.h> -#include <Qt3DExtras/QAbstractAnimation> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QAbstractAnimationPrivate : public QObjectPrivate -{ -public: - QAbstractAnimationPrivate(QAbstractAnimation::AnimationType type); - - QString m_animationName; - QAbstractAnimation::AnimationType m_animationType; - float m_position; - float m_duration; - - Q_DECLARE_PUBLIC(QAbstractAnimation) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QANIMATIONCONTROLLER_P_H diff --git a/src/extras/animations/qanimationcontroller.cpp b/src/extras/animations/qanimationcontroller.cpp deleted file mode 100644 index adef3d45c..000000000 --- a/src/extras/animations/qanimationcontroller.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qanimationcontroller.h" -#include "qanimationgroup.h" - -#include <private/qanimationcontroller_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -QAnimationControllerPrivate::QAnimationControllerPrivate() - : QObjectPrivate() - , m_activeAnimationGroup(0) - , m_position(0.0f) - , m_positionScale(1.0f) - , m_positionOffset(0.0f) - , m_entity(nullptr) - , m_recursive(true) -{ - -} - -void QAnimationControllerPrivate::updatePosition(float position) -{ - m_position = position; - if (m_activeAnimationGroup >= 0 && m_activeAnimationGroup < m_animationGroups.size()) { - const float pos = m_positionScale * position + m_positionOffset; - m_animationGroups[m_activeAnimationGroup]->setPosition(pos); - } -} - -QAnimationGroup *QAnimationControllerPrivate::findGroup(const QString &name) -{ - for (QAnimationGroup *g : m_animationGroups) { - if (g->name() == name) - return g; - } - return nullptr; -} - -void QAnimationControllerPrivate::extractAnimations() -{ - Q_Q(QAnimationController); - if (!m_entity) - return; - QList<Qt3DExtras::QAbstractAnimation *> animations - = m_entity->findChildren<Qt3DExtras::QAbstractAnimation *>(QString(), - m_recursive ? Qt::FindChildrenRecursively : Qt::FindDirectChildrenOnly); - if (animations.size() > 0) { - for (Qt3DExtras::QAbstractAnimation *a : animations) { - QAnimationGroup *group = findGroup(a->animationName()); - if (!group) { - group = new QAnimationGroup(q); - group->setName(a->animationName()); - m_animationGroups.push_back(group); - } - group->addAnimation(a); - } - } -} -void QAnimationControllerPrivate::clearAnimations() -{ - for (Qt3DExtras::QAnimationGroup *a : m_animationGroups) - a->deleteLater(); - m_animationGroups.clear(); - m_activeAnimationGroup = 0; -} - -QAnimationController::QAnimationController(QObject *parent) - : QObject(*new QAnimationControllerPrivate, parent) -{ - -} - -QVector<QAnimationGroup *> QAnimationController::animationGroupList() -{ - Q_D(QAnimationController); - return d->m_animationGroups; -} - -int QAnimationController::activeAnimationGroup() const -{ - Q_D(const QAnimationController); - return d->m_activeAnimationGroup; -} - -float QAnimationController::position() const -{ - Q_D(const QAnimationController); - return d->m_position; -} - -float QAnimationController::positionScale() const -{ - Q_D(const QAnimationController); - return d->m_positionScale; -} - -float QAnimationController::positionOffset() const -{ - Q_D(const QAnimationController); - return d->m_positionOffset; -} - -Qt3DCore::QEntity *QAnimationController::entity() const -{ - Q_D(const QAnimationController); - return d->m_entity; -} - -bool QAnimationController::recursive() const -{ - Q_D(const QAnimationController); - return d->m_recursive; -} - -void QAnimationController::setAnimationGroups(const QVector<QAnimationGroup *> &animationGroups) -{ - Q_D(QAnimationController); - d->m_animationGroups = animationGroups; - if (d->m_activeAnimationGroup >= d->m_animationGroups.size()) - d->m_activeAnimationGroup = 0; - d->updatePosition(d->m_position); -} - -void QAnimationController::addAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroup) -{ - Q_D(QAnimationController); - if (!d->m_animationGroups.contains(animationGroup)) - d->m_animationGroups.push_back(animationGroup); -} - -void QAnimationController::removeAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroup) -{ - Q_D(QAnimationController); - if (d->m_animationGroups.contains(animationGroup)) - d->m_animationGroups.removeAll(animationGroup); - if (d->m_activeAnimationGroup >= d->m_animationGroups.size()) - d->m_activeAnimationGroup = 0; -} - -void QAnimationController::setActiveAnimationGroup(int index) -{ - Q_D(QAnimationController); - if (d->m_activeAnimationGroup != index) { - d->m_activeAnimationGroup = index; - d->updatePosition(d->m_position); - emit activeAnimationGroupChanged(index); - } -} -void QAnimationController::setPosition(float position) -{ - Q_D(QAnimationController); - if (!qFuzzyCompare(d->m_position, position)) { - d->updatePosition(position); - emit positionChanged(position); - } -} - -void QAnimationController::setPositionScale(float scale) -{ - Q_D(QAnimationController); - if (!qFuzzyCompare(d->m_positionScale, scale)) { - d->m_positionScale = scale; - emit positionScaleChanged(scale); - } -} - -void QAnimationController::setPositionOffset(float offset) -{ - Q_D(QAnimationController); - if (!qFuzzyCompare(d->m_positionOffset, offset)) { - d->m_positionOffset = offset; - emit positionOffsetChanged(offset); - } -} - -void QAnimationController::setEntity(Qt3DCore::QEntity *entity) -{ - Q_D(QAnimationController); - if (d->m_entity != entity) { - d->clearAnimations(); - d->m_entity = entity; - d->extractAnimations(); - d->updatePosition(d->m_position); - emit entityChanged(entity); - } -} - -void QAnimationController::setRecursive(bool recursive) -{ - Q_D(QAnimationController); - if (d->m_recursive != recursive) { - d->m_recursive = recursive; - emit recursiveChanged(recursive); - } -} - -int QAnimationController::getAnimationIndex(const QString &name) const -{ - Q_D(const QAnimationController); - for (int i = 0; i < d->m_animationGroups.size(); ++i) { - if (d->m_animationGroups[i]->name() == name) - return i; - } - return -1; -} - -QAnimationGroup *QAnimationController::getGroup(int index) const -{ - Q_D(const QAnimationController); - return d->m_animationGroups.at(index); -} - -} // Qt3DExtras - -QT_END_NAMESPACE diff --git a/src/extras/animations/qanimationcontroller.h b/src/extras/animations/qanimationcontroller.h deleted file mode 100644 index 4ee32dd8b..000000000 --- a/src/extras/animations/qanimationcontroller.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QANIMATIONCONTROLLER_H -#define QT3DEXTRAS_QANIMATIONCONTROLLER_H - -#include <Qt3DExtras/qkeyframeanimation.h> -#include <Qt3DExtras/qanimationgroup.h> -#include <Qt3DCore/qentity.h> - -#include <Qt3DExtras/qt3dextras_global.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QAnimationControllerPrivate; - -class QT3DEXTRASSHARED_EXPORT QAnimationController : public QObject -{ - Q_OBJECT - Q_PROPERTY(int activeAnimationGroup READ activeAnimationGroup WRITE setActiveAnimationGroup NOTIFY activeAnimationGroupChanged) - Q_PROPERTY(float position READ position WRITE setPosition NOTIFY positionChanged) - Q_PROPERTY(float positionScale READ positionScale WRITE setPositionScale NOTIFY positionScaleChanged) - Q_PROPERTY(float positionOffset READ positionOffset WRITE setPositionOffset NOTIFY positionOffsetChanged) - Q_PROPERTY(Qt3DCore::QEntity *entity READ entity WRITE setEntity NOTIFY entityChanged) - Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged) - -public: - QAnimationController(QObject *parent = nullptr); - - QVector<Qt3DExtras::QAnimationGroup *> animationGroupList(); - - int activeAnimationGroup() const; - float position() const; - float positionScale() const; - float positionOffset() const; - Qt3DCore::QEntity *entity() const; - bool recursive() const; - - void setAnimationGroups(const QVector<Qt3DExtras::QAnimationGroup *> &animationGroups); - void addAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroups); - void removeAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroups); - - Q_INVOKABLE int getAnimationIndex(const QString &name) const; - Q_INVOKABLE Qt3DExtras::QAnimationGroup *getGroup(int index) const; - -public Q_SLOTS: - void setActiveAnimationGroup(int index); - void setPosition(float position); - void setPositionScale(float scale); - void setPositionOffset(float offset); - void setEntity(Qt3DCore::QEntity *entity); - void setRecursive(bool recursive); - -Q_SIGNALS: - void activeAnimationGroupChanged(int index); - void positionChanged(float position); - void positionScaleChanged(float scale); - void positionOffsetChanged(float offset); - void entityChanged(Qt3DCore::QEntity *entity); - void recursiveChanged(bool recursive); - -private: - Q_DECLARE_PRIVATE(QAnimationController) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QANIMATIONCONTROLLER_H diff --git a/src/extras/animations/qanimationcontroller_p.h b/src/extras/animations/qanimationcontroller_p.h deleted file mode 100644 index dd5079ef5..000000000 --- a/src/extras/animations/qanimationcontroller_p.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QANIMATIONCONTROLLER_P_H -#define QT3DEXTRAS_QANIMATIONCONTROLLER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qobject_p.h> -#include <Qt3DExtras/QAnimationGroup> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QAnimationControllerPrivate : public QObjectPrivate -{ -public: - QAnimationControllerPrivate(); - - QString m_name; - int m_activeAnimationGroup; - QVector<QAnimationGroup *> m_animationGroups; - float m_position; - float m_positionScale; - float m_positionOffset; - Qt3DCore::QEntity *m_entity; - bool m_recursive; - - void updatePosition(float position); - void extractAnimations(); - void clearAnimations(); - QAnimationGroup *findGroup(const QString &name); - - Q_DECLARE_PUBLIC(QAnimationController) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QANIMATIONCONTROLLER_P_H diff --git a/src/extras/animations/qanimationgroup.cpp b/src/extras/animations/qanimationgroup.cpp deleted file mode 100644 index e9febe811..000000000 --- a/src/extras/animations/qanimationgroup.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qanimationgroup.h" -#include "Qt3DExtras/private/qanimationgroup_p.h" - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -QAnimationGroupPrivate::QAnimationGroupPrivate() - : QObjectPrivate() - , m_position(0.0f) - , m_duration(0.0f) -{ - -} - -void QAnimationGroupPrivate::updatePosition(float position) -{ - m_position = position; - for (QAbstractAnimation *aa : m_animations) - aa->setPosition(position); -} - -QAnimationGroup::QAnimationGroup(QObject *parent) - : QObject(*new QAnimationGroupPrivate, parent) -{ - -} - -QString QAnimationGroup::name() const -{ - Q_D(const QAnimationGroup); - return d->m_name; -} - -QVector<Qt3DExtras::QAbstractAnimation *> QAnimationGroup::animationList() -{ - Q_D(QAnimationGroup); - return d->m_animations; -} - -float QAnimationGroup::position() const -{ - Q_D(const QAnimationGroup); - return d->m_position; -} - -float QAnimationGroup::duration() const -{ - Q_D(const QAnimationGroup); - return d->m_duration; -} - -void QAnimationGroup::setName(const QString &name) -{ - Q_D(QAnimationGroup); - if (d->m_name != name) { - d->m_name = name; - emit nameChanged(name); - } -} - -void QAnimationGroup::setAnimations(const QVector<Qt3DExtras::QAbstractAnimation *> &animations) -{ - Q_D(QAnimationGroup); - d->m_animations = animations; - d->m_duration = 0.0f; - for (const Qt3DExtras::QAbstractAnimation *a : animations) - d->m_duration = qMax(d->m_duration, a->duration()); -} - -void QAnimationGroup::addAnimation(QAbstractAnimation *animation) -{ - Q_D(QAnimationGroup); - d->m_animations.push_back(animation); - d->m_duration = qMax(d->m_duration, animation->duration()); -} - -void QAnimationGroup::setPosition(float position) -{ - Q_D(QAnimationGroup); - if (!qFuzzyCompare(d->m_position, position)) { - d->updatePosition(position); - emit positionChanged(position); - } -} - -} // Qt3DExtras - -QT_END_NAMESPACE diff --git a/src/extras/animations/qanimationgroup.h b/src/extras/animations/qanimationgroup.h deleted file mode 100644 index 4595a2082..000000000 --- a/src/extras/animations/qanimationgroup.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QANIMATIONGROUP_H -#define QT3DEXTRAS_QANIMATIONGROUP_H - -#include <qobject.h> - -#include <Qt3DExtras/qabstractanimation.h> - -#include <Qt3DExtras/qt3dextras_global.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QAnimationGroupPrivate; - -class QT3DEXTRASSHARED_EXPORT QAnimationGroup : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) - Q_PROPERTY(float position READ position WRITE setPosition NOTIFY positionChanged) - Q_PROPERTY(float duration READ duration NOTIFY durationChanged) - -public: - explicit QAnimationGroup(QObject *parent = nullptr); - - QString name() const; - QVector<Qt3DExtras::QAbstractAnimation *> animationList(); - float position() const; - float duration() const; - - void setAnimations(const QVector<Qt3DExtras::QAbstractAnimation *> &animations); - void addAnimation(Qt3DExtras::QAbstractAnimation *animation); - void removeAnimation(Qt3DExtras::QAbstractAnimation *animation); - -public Q_SLOTS: - void setName(const QString &name); - void setPosition(float position); - -Q_SIGNALS: - void nameChanged(const QString &name); - void positionChanged(float position); - void durationChanged(float duration); - -private: - - Q_DECLARE_PRIVATE(QAnimationGroup) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QANIMATIONGROUP_H diff --git a/src/extras/animations/qanimationgroup_p.h b/src/extras/animations/qanimationgroup_p.h deleted file mode 100644 index cffe44636..000000000 --- a/src/extras/animations/qanimationgroup_p.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QANIMATIONGROUP_P_H -#define QT3DEXTRAS_QANIMATIONGROUP_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qobject_p.h> -#include <Qt3DExtras/QAnimationGroup> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QAnimationGroupPrivate : public QObjectPrivate -{ -public: - QAnimationGroupPrivate(); - - QString m_name; - QVector<Qt3DExtras::QAbstractAnimation *> m_animations; - float m_position; - float m_duration; - - void updatePosition(float position); - - Q_DECLARE_PUBLIC(QAnimationGroup) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QANIMATIONGROUP_P_H diff --git a/src/extras/animations/qkeyframeanimation.cpp b/src/extras/animations/qkeyframeanimation.cpp deleted file mode 100644 index 425cbe0df..000000000 --- a/src/extras/animations/qkeyframeanimation.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qkeyframeanimation.h" -#include "Qt3DExtras/private/qkeyframeanimation_p.h" - -#include <cmath> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -QKeyframeAnimationPrivate::QKeyframeAnimationPrivate() - : QAbstractAnimationPrivate(QAbstractAnimation::KeyframeAnimation) - , m_minposition(0.0f) - , m_maxposition(0.0f) - , m_prevPosition(-1.0f) - , m_target(nullptr) - , m_startMode(QKeyframeAnimation::Constant) - , m_endMode(QKeyframeAnimation::Constant) -{ - -} - -QKeyframeAnimation::QKeyframeAnimation(QObject *parent) - : QAbstractAnimation(*new QKeyframeAnimationPrivate(), parent) -{ - Q_D(QKeyframeAnimation); - d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged, - this, &QKeyframeAnimation::updateAnimation); -} - - -void QKeyframeAnimation::setFramePositions(const QVector<float> &positions) -{ - Q_D(QKeyframeAnimation); - d->m_framePositions = positions; - d->m_prevPosition = -1.0f; - if (d->m_framePositions.size() == 0) { - d->m_minposition = d->m_maxposition = 0.0f; - return; - } - d->m_minposition = d->m_framePositions.first(); - d->m_maxposition = d->m_framePositions.last(); - float lastPos = d->m_minposition; - for (float p : d->m_framePositions) { - if (p < lastPos || p > d->m_maxposition) - qWarning() << "positions not ordered correctly"; - lastPos = p; - } - setDuration(d->m_maxposition); -} - -void QKeyframeAnimation::setKeyframes(const QVector<Qt3DCore::QTransform *> &keyframes) -{ - Q_D(QKeyframeAnimation); - d->m_keyframes = keyframes; -} - -// slerp which allows long path -QQuaternion lslerp(QQuaternion q1, QQuaternion q2, float t) -{ - QQuaternion ret; - // Handle the easy cases first. - if (t <= 0.0f) - return q1; - else if (t >= 1.0f) - return q2; - - float cos = qBound(-1.0f, QQuaternion::dotProduct(q1, q2), 1.0f); - float angle = std::acos(cos); - float sin = std::sin(angle); - if (!qFuzzyIsNull(sin)) { - float a = std::sin((1.0 - t) * angle) / sin; - float b = std::sin(t * angle) / sin; - ret = (q1 * a + q2 * b).normalized(); - } else { - ret = q1 * (1.0f-t) + q2 * t; - } - return ret; -} - -void QKeyframeAnimationPrivate::calculateFrame(float position) -{ - if (m_target && m_framePositions.size() > 0 - && m_keyframes.size() == m_framePositions.size() - && m_prevPosition != m_position) { - if (m_position >= m_minposition && m_position < m_maxposition) { - for (int i = 0; i < m_framePositions.size() - 1; i++) { - if (position >= m_framePositions.at(i) - && position < m_framePositions.at(i+1)) { - float ip = (position - m_framePositions.at(i)) - / (m_framePositions.at(i+1) - m_framePositions.at(i)); - float eIp = m_easing.valueForProgress(ip); - float eIip = 1.0f - eIp; - - Qt3DCore::QTransform *a = m_keyframes.at(i); - Qt3DCore::QTransform *b = m_keyframes.at(i+1); - - QVector3D s = a->scale3D() * eIip + b->scale3D() * eIp; - QVector3D t = a->translation() * eIip + b->translation() * eIp; - QQuaternion r = QQuaternion::slerp(a->rotation(), b->rotation(), eIp); - - m_target->setRotation(r); - m_target->setScale3D(s); - m_target->setTranslation(t); - return; - } - } - } else if (position < m_minposition) { - m_target->setRotation(m_keyframes.first()->rotation()); - m_target->setScale3D(m_keyframes.first()->scale3D()); - m_target->setTranslation(m_keyframes.first()->translation()); - } else { - m_target->setRotation(m_keyframes.last()->rotation()); - m_target->setScale3D(m_keyframes.last()->scale3D()); - m_target->setTranslation(m_keyframes.last()->translation()); - } - m_prevPosition = m_position; - } -} - -void QKeyframeAnimation::updateAnimation(float position) -{ - Q_D(QKeyframeAnimation); - d->calculateFrame(position); -} - -QVector<float> QKeyframeAnimation::framePositions() const -{ - Q_D(const QKeyframeAnimation); - return d->m_framePositions; -} - -QVector<Qt3DCore::QTransform *> QKeyframeAnimation::keyframeList() const -{ - Q_D(const QKeyframeAnimation); - return d->m_keyframes; -} - -void QKeyframeAnimation::setTarget(Qt3DCore::QTransform *target) -{ - Q_D(QKeyframeAnimation); - if (d->m_target != target) { - d->m_target = target; - emit targetChanged(d->m_target); - d->m_prevPosition = -1.0f; - - if (target) { - d->m_baseScale = target->scale3D(); - d->m_baseTranslation = target->translation(); - d->m_baseRotation = target->rotation(); - } - } -} - -QKeyframeAnimation::RepeatMode QKeyframeAnimation::startMode() const -{ - Q_D(const QKeyframeAnimation); - return d->m_startMode; -} - -QKeyframeAnimation::RepeatMode QKeyframeAnimation::endMode() const -{ - Q_D(const QKeyframeAnimation); - return d->m_endMode; -} - -void QKeyframeAnimation::setEasing(QEasingCurve::Type easing) -{ - Q_D(QKeyframeAnimation); - if (d->m_easing.type() != easing) { - d->m_easing.setType(easing); - emit easingChanged(easing); - } -} - -void QKeyframeAnimation::setTargetName(const QString &name) -{ - Q_D(QKeyframeAnimation); - d->m_targetName = name; - emit targetNameChanged(name); -} - -void QKeyframeAnimation::setStartMode(QKeyframeAnimation::RepeatMode mode) -{ - Q_D(QKeyframeAnimation); - if (d->m_startMode != mode) { - d->m_startMode = mode; - emit startModeChanged(mode); - } -} - -void QKeyframeAnimation::setEndMode(QKeyframeAnimation::RepeatMode mode) -{ - Q_D(QKeyframeAnimation); - if (mode != d->m_endMode) { - d->m_endMode = mode; - emit endModeChanged(mode); - } -} - -void QKeyframeAnimation::addKeyframe(Qt3DCore::QTransform *keyframe) -{ - Q_D(QKeyframeAnimation); - d->m_keyframes.push_back(keyframe); -} - -QString QKeyframeAnimation::targetName() const -{ - Q_D(const QKeyframeAnimation); - return d->m_targetName; -} - -QEasingCurve::Type QKeyframeAnimation::easing() const -{ - Q_D(const QKeyframeAnimation); - return d->m_easing.type(); -} - -Qt3DCore::QTransform *QKeyframeAnimation::target() const -{ - Q_D(const QKeyframeAnimation); - return d->m_target; -} - -} // Qt3DExtras - -QT_END_NAMESPACE diff --git a/src/extras/animations/qkeyframeanimation.h b/src/extras/animations/qkeyframeanimation.h deleted file mode 100644 index 178c9dbf1..000000000 --- a/src/extras/animations/qkeyframeanimation.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QKEYFRAMEANIMATION_H -#define QT3DEXTRAS_QKEYFRAMEANIMATION_H - -#include <Qt3DCore/qtransform.h> - -#include <Qt3DExtras/qabstractanimation.h> -#include <Qt3DExtras/qt3dextras_global.h> - -#include <QtCore/qeasingcurve.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QKeyframeAnimationPrivate; - -class QT3DEXTRASSHARED_EXPORT QKeyframeAnimation : public QAbstractAnimation -{ - Q_OBJECT - Q_PROPERTY(QVector<float> framePositions READ framePositions WRITE setFramePositions NOTIFY framePositionsChanged) - Q_PROPERTY(Qt3DCore::QTransform *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(QEasingCurve::Type easing READ easing WRITE setEasing NOTIFY easingChanged) - Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged) - Q_PROPERTY(QKeyframeAnimation::RepeatMode startMode READ startMode WRITE setStartMode NOTIFY startModeChanged) - Q_PROPERTY(QKeyframeAnimation::RepeatMode endMode READ endMode WRITE setEndMode NOTIFY endModeChanged) - -public: - explicit QKeyframeAnimation(QObject *parent = nullptr); - - enum RepeatMode - { - None, - Constant, - Repeat, - }; - Q_ENUM(RepeatMode) - - QVector<float> framePositions() const; - QVector<Qt3DCore::QTransform *> keyframeList() const; - Qt3DCore::QTransform *target() const; - QEasingCurve::Type easing() const; - QString targetName() const; - RepeatMode startMode() const; - RepeatMode endMode() const; - - void setKeyframes(const QVector<Qt3DCore::QTransform *> &keyframes); - void addKeyframe(Qt3DCore::QTransform *keyframe); - void removeKeyframe(Qt3DCore::QTransform *keyframe); - -public Q_SLOTS: - void setFramePositions(const QVector<float> &positions); - void setTarget(Qt3DCore::QTransform *target); - void setEasing(QEasingCurve::Type easing); - void setTargetName(const QString &name); - void setStartMode(RepeatMode mode); - void setEndMode(RepeatMode mode); - -Q_SIGNALS: - void framePositionsChanged(const QVector<float> &positions); - void targetChanged(Qt3DCore::QTransform *target); - void easingChanged(QEasingCurve::Type easing); - void targetNameChanged(const QString &name); - void startModeChanged(RepeatMode startMode); - void endModeChanged(RepeatMode endMode); - -private: - void updateAnimation(float position); - - Q_DECLARE_PRIVATE(QKeyframeAnimation) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QKEYFRAMEANIMATION_H diff --git a/src/extras/animations/qkeyframeanimation_p.h b/src/extras/animations/qkeyframeanimation_p.h deleted file mode 100644 index 0095b9432..000000000 --- a/src/extras/animations/qkeyframeanimation_p.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QKEYFRAMEANIMATION_P_H -#define QT3DEXTRAS_QKEYFRAMEANIMATION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qobject_p.h> -#include <Qt3DExtras/qkeyframeanimation.h> -#include <private/qabstractanimation_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QKeyframeAnimationPrivate : public QAbstractAnimationPrivate -{ -public: - QKeyframeAnimationPrivate(); - - void calculateFrame(float position); - - float m_prevPosition; - QVector<float> m_framePositions; - QVector<Qt3DCore::QTransform *> m_keyframes; - Qt3DCore::QTransform *m_target; - QEasingCurve m_easing; - QString m_animationName; - QString m_targetName; - float m_minposition; - float m_maxposition; - QKeyframeAnimation::RepeatMode m_startMode; - QKeyframeAnimation::RepeatMode m_endMode; - QVector3D m_baseScale; - QVector3D m_baseTranslation; - QQuaternion m_baseRotation; - QMetaObject::Connection m_positionConnection; - - Q_DECLARE_PUBLIC(QKeyframeAnimation) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QKEYFRAMEANIMATION_P_H diff --git a/src/extras/animations/qmorphinganimation.cpp b/src/extras/animations/qmorphinganimation.cpp deleted file mode 100644 index e7fe05147..000000000 --- a/src/extras/animations/qmorphinganimation.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmorphinganimation.h" -#include <private/qmorphinganimation_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -QMorphingAnimationPrivate::QMorphingAnimationPrivate() - : QAbstractAnimationPrivate(QAbstractAnimation::MorphingAnimation) - , m_flattened(nullptr) - , m_method(QMorphingAnimation::Relative) - , m_interpolator(0.0f) - , m_target(nullptr) - , m_currentTarget(nullptr) -{ - m_easing.setType(QEasingCurve::InOutCubic); -} - -QMorphingAnimationPrivate::~QMorphingAnimationPrivate() -{ - for (QVector<float> *weights : m_weights) - delete weights; -} - -void QMorphingAnimationPrivate::updateAnimation(float position) -{ - Q_Q(QMorphingAnimation); - if (!m_target || !m_target->geometry()) - return; - - m_morphKey.resize(m_morphTargets.size()); - - for (int i = 0; i < m_targetPositions.size() - 1; ++i) { - if (position > m_targetPositions.at(i) && position <= m_targetPositions.at(i + 1)) { - float interpolator = (position - m_targetPositions.at(i)) - / (m_targetPositions.at(i + 1) - m_targetPositions.at(i)); - interpolator = m_easing.valueForProgress(interpolator); - float iip = 1.0f - interpolator; - float sum = 0.0f; - QVector<int> relevantValues; - for (int j = 0; j < m_morphTargets.size(); ++j) { - m_morphKey[j] = interpolator * m_weights.at(i + 1)->at(j) - + iip * m_weights.at(i)->at(j); - sum += m_morphKey[j]; - if (!qFuzzyIsNull(m_morphKey[j])) - relevantValues.push_back(j); - } - - if (relevantValues.size() == 0 || qFuzzyIsNull(sum)) { - // only base is used - interpolator = 0.0f; - } else if (relevantValues.size() == 1) { - // one morph target has non-zero weight - setTargetInterpolated(relevantValues[0]); - interpolator = sum; - } else { - // more than one morph target has non-zero weight - // flatten morph targets to one - qWarning() << Q_FUNC_INFO << "Flattening required"; - } - if (!qFuzzyCompare(interpolator, m_interpolator)) { - if (m_method == QMorphingAnimation::Normalized) - m_interpolator = interpolator; - else - m_interpolator = -interpolator; - emit q->interpolatorChanged(m_interpolator); - } - return; - } - } -} - -void QMorphingAnimationPrivate::setTargetInterpolated(int morphTarget) -{ - QMorphTarget *target = m_morphTargets[morphTarget]; - Qt3DRender::QGeometry *geometry = m_target->geometry(); - - // remove attributes from previous frame - if (m_currentTarget && (target != m_currentTarget)) { - const QVector<Qt3DRender::QAttribute *> targetAttributes = m_currentTarget->attributeList(); - for (int i = 0; i < targetAttributes.size(); ++i) - geometry->removeAttribute(targetAttributes.at(i)); - } - - const QVector<Qt3DRender::QAttribute *> targetAttributes = target->attributeList(); - - // add attributes from current frame to the geometry - if (target != m_currentTarget) { - for (int i = 0; i < m_attributeNames.size(); ++i) { - QString targetName = m_attributeNames.at(i); - targetName.append("Target"); - targetAttributes[i]->setName(targetName); - geometry->addAttribute(targetAttributes.at(i)); - } - } - m_currentTarget = target; -} - -QMorphingAnimation::QMorphingAnimation(QObject *parent) - : QAbstractAnimation(*new QMorphingAnimationPrivate, parent) -{ - Q_D(QMorphingAnimation); - d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged, - this, &QMorphingAnimation::updateAnimation); -} - -QVector<float> QMorphingAnimation::targetPositions() const -{ - Q_D(const QMorphingAnimation); - return d->m_targetPositions; -} - -float QMorphingAnimation::interpolator() const -{ - Q_D(const QMorphingAnimation); - return d->m_interpolator; -} - -Qt3DRender::QGeometryRenderer *QMorphingAnimation::target() const -{ - Q_D(const QMorphingAnimation); - return d->m_target; -} - -QString QMorphingAnimation::targetName() const -{ - Q_D(const QMorphingAnimation); - return d->m_targetName; -} - -QMorphingAnimation::Method QMorphingAnimation::method() const -{ - Q_D(const QMorphingAnimation); - return d->m_method; -} - -QEasingCurve::Type QMorphingAnimation::easing() const -{ - Q_D(const QMorphingAnimation); - return d->m_easing.type(); -} - -void QMorphingAnimation::setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets) -{ - Q_D(QMorphingAnimation); - d->m_morphTargets = targets; - d->m_attributeNames = targets[0]->attributeNames(); -} - -void QMorphingAnimation::addMorphTarget(Qt3DExtras::QMorphTarget *target) -{ - Q_D(QMorphingAnimation); - if (!d->m_morphTargets.contains(target)) - d->m_morphTargets.push_back(target); -} - -void QMorphingAnimation::removeMorphTarget(Qt3DExtras::QMorphTarget *target) -{ - Q_D(QMorphingAnimation); - d->m_morphTargets.removeAll(target); -} - -void QMorphingAnimation::setTargetPositions(const QVector<float> &targetPositions) -{ - Q_D(QMorphingAnimation); - d->m_targetPositions = targetPositions; - emit targetPositionsChanged(targetPositions); - setDuration(d->m_targetPositions.last()); - if (d->m_weights.size() < targetPositions.size()) { - d->m_weights.resize(targetPositions.size()); - for (int i = 0; i < d->m_weights.size(); ++i) { - if (d->m_weights[i] == nullptr) - d->m_weights[i] = new QVector<float>(); - } - } -} - -void QMorphingAnimation::setTarget(Qt3DRender::QGeometryRenderer *target) -{ - Q_D(QMorphingAnimation); - if (d->m_target != target) { - d->m_target = target; - emit targetChanged(target); - } -} - -void QMorphingAnimation::setWeights(int positionIndex, const QVector<float> &weights) -{ - Q_D(QMorphingAnimation); - if (d->m_weights.size() < positionIndex) - d->m_weights.resize(positionIndex + 1); - if (d->m_weights[positionIndex] == nullptr) - d->m_weights[positionIndex] = new QVector<float>(); - *d->m_weights[positionIndex] = weights; -} - -QVector<float> QMorphingAnimation::getWeights(int positionIndex) -{ - Q_D(QMorphingAnimation); - return *d->m_weights[positionIndex]; -} - -QVector<Qt3DExtras::QMorphTarget *> QMorphingAnimation::morphTargetList() -{ - Q_D(QMorphingAnimation); - return d->m_morphTargets; -} - -void QMorphingAnimation::setTargetName(const QString name) -{ - Q_D(QMorphingAnimation); - if (d->m_targetName != name) { - d->m_targetName = name; - emit targetNameChanged(name); - } -} - -void QMorphingAnimation::setMethod(QMorphingAnimation::Method method) -{ - Q_D(QMorphingAnimation); - if (d->m_method != method) { - d->m_method = method; - emit methodChanged(method); - } -} - -void QMorphingAnimation::setEasing(QEasingCurve::Type easing) -{ - Q_D(QMorphingAnimation); - if (d->m_easing.type() != easing) { - d->m_easing.setType(easing); - emit easingChanged(easing); - } -} - -void QMorphingAnimation::updateAnimation(float position) -{ - Q_D(QMorphingAnimation); - d->updateAnimation(position); -} - -} // Qt3DExtras - -QT_END_NAMESPACE diff --git a/src/extras/animations/qmorphinganimation.h b/src/extras/animations/qmorphinganimation.h deleted file mode 100644 index f8ca71ec9..000000000 --- a/src/extras/animations/qmorphinganimation.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QMORPHINGANIMATION_H -#define QT3DEXTRAS_QMORPHINGANIMATION_H - -#include <Qt3DRender/qgeometryrenderer.h> - -#include <Qt3DExtras/qabstractanimation.h> -#include <Qt3DExtras/qmorphtarget.h> -#include <Qt3DExtras/qt3dextras_global.h> - -#include <QtCore/qeasingcurve.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QMorphingAnimationPrivate; - -class QT3DEXTRASSHARED_EXPORT QMorphingAnimation : public QAbstractAnimation -{ - Q_OBJECT - Q_PROPERTY(QVector<float> targetPositions READ targetPositions WRITE setTargetPositions NOTIFY targetPositionsChanged) - Q_PROPERTY(float interpolator READ interpolator NOTIFY interpolatorChanged) - Q_PROPERTY(Qt3DRender::QGeometryRenderer *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged) - Q_PROPERTY(QMorphingAnimation::Method method READ method WRITE setMethod NOTIFY methodChanged) - Q_PROPERTY(QEasingCurve::Type easing READ easing WRITE setEasing NOTIFY easingChanged) - -public: - enum Method - { - Normalized, - Relative - }; - Q_ENUM(Method) - - explicit QMorphingAnimation(QObject *parent = nullptr); - - QVector<float> targetPositions() const; - float interpolator() const; - Qt3DRender::QGeometryRenderer *target() const; - QString targetName() const; - QMorphingAnimation::Method method() const; - QEasingCurve::Type easing() const; - - void setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets); - void addMorphTarget(Qt3DExtras::QMorphTarget *target); - void removeMorphTarget(Qt3DExtras::QMorphTarget *target); - - void setWeights(int positionIndex, const QVector<float> &weights); - QVector<float> getWeights(int positionIndex); - - QVector<Qt3DExtras::QMorphTarget *> morphTargetList(); - -public Q_SLOTS: - void setTargetPositions(const QVector<float> &targetPositions); - void setTarget(Qt3DRender::QGeometryRenderer *target); - void setTargetName(const QString name); - void setMethod(QMorphingAnimation::Method method); - void setEasing(QEasingCurve::Type easing); - -Q_SIGNALS: - void targetPositionsChanged(const QVector<float> &targetPositions); - void interpolatorChanged(float interpolator); - void targetChanged(Qt3DRender::QGeometryRenderer *target); - void targetNameChanged(const QString &name); - void methodChanged(QMorphingAnimation::Method method); - void easingChanged(QEasingCurve::Type easing); - -private: - - void updateAnimation(float position); - - Q_DECLARE_PRIVATE(QMorphingAnimation) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QMORPHINGANIMATION_H diff --git a/src/extras/animations/qmorphinganimation_p.h b/src/extras/animations/qmorphinganimation_p.h deleted file mode 100644 index e4a18f199..000000000 --- a/src/extras/animations/qmorphinganimation_p.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QMORPHINGANIMATION_P_H -#define QT3DEXTRAS_QMORPHINGANIMATION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qeasingcurve.h> -#include <Qt3DExtras/qmorphinganimation.h> - -#include <private/qobject_p.h> -#include <private/qabstractanimation_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QMorphingAnimationPrivate : public QAbstractAnimationPrivate -{ -public: - QMorphingAnimationPrivate(); - ~QMorphingAnimationPrivate(); - - void updateAnimation(float position); - void setTargetInterpolated(int morphTarget); - - QVector<float> m_targetPositions; - QVector<QVector<float>*> m_weights; - QVector<float> m_morphKey; - QStringList m_attributeNames; - QVector<Qt3DExtras::QMorphTarget *> m_morphTargets; - QMorphTarget *m_flattened; - QMorphingAnimation::Method m_method; - QEasingCurve m_easing; - float m_interpolator; - Qt3DRender::QGeometryRenderer *m_target; - QString m_targetName; - - QMorphTarget *m_currentTarget; - - QMetaObject::Connection m_positionConnection; - - Q_DECLARE_PUBLIC(QMorphingAnimation) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QMORPHINGANIMATION_P_H diff --git a/src/extras/animations/qmorphtarget.cpp b/src/extras/animations/qmorphtarget.cpp deleted file mode 100644 index 0c327a490..000000000 --- a/src/extras/animations/qmorphtarget.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmorphtarget.h" -#include "Qt3DExtras/private/qmorphtarget_p.h" - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -QMorphTargetPrivate::QMorphTargetPrivate() - : QObjectPrivate() -{ - -} - -void QMorphTargetPrivate::updateAttributeNames() -{ - m_attributeNames.clear(); - for (const Qt3DRender::QAttribute *attr : m_targetAttributes) - m_attributeNames.push_back(attr->name()); -} - -QMorphTarget::QMorphTarget(QObject *parent) - : QObject(*new QMorphTargetPrivate, parent) -{ - -} - -QVector<Qt3DRender::QAttribute *> QMorphTarget::attributeList() const -{ - Q_D(const QMorphTarget); - return d->m_targetAttributes; -} - -QStringList QMorphTarget::attributeNames() const -{ - Q_D(const QMorphTarget); - return d->m_attributeNames; -} - -void QMorphTarget::setAttributes(const QVector<Qt3DRender::QAttribute *> &attributes) -{ - Q_D(QMorphTarget); - d->m_targetAttributes = attributes; - d->m_attributeNames.clear(); - for (const Qt3DRender::QAttribute *attr : attributes) - d->m_attributeNames.push_back(attr->name()); - - emit attributeNamesChanged(d->m_attributeNames); -} - -void QMorphTarget::addAttribute(Qt3DRender::QAttribute *attribute) -{ - Q_D(QMorphTarget); - for (const Qt3DRender::QAttribute *attr : d->m_targetAttributes) { - if (attr->name() == attribute->name()) - return; - } - d->m_targetAttributes.push_back(attribute); - d->m_attributeNames.push_back(attribute->name()); - emit attributeNamesChanged(d->m_attributeNames); -} - -void QMorphTarget::removeAttribute(Qt3DRender::QAttribute *attribute) -{ - Q_D(QMorphTarget); - if (d->m_targetAttributes.contains(attribute)) { - d->m_targetAttributes.removeAll(attribute); - d->updateAttributeNames(); - emit attributeNamesChanged(d->m_attributeNames); - } -} - -QMorphTarget *QMorphTarget::fromGeometry(Qt3DRender::QGeometry *geometry, const QStringList &attributes) -{ - QMorphTarget *target = new QMorphTarget(); - for (Qt3DRender::QAttribute *attr : geometry->attributes()) { - if (attributes.contains(attr->name())) - target->addAttribute(attr); - } - return target; -} - -} // Qt3DExtras - -QT_END_NAMESPACE diff --git a/src/extras/animations/qmorphtarget.h b/src/extras/animations/qmorphtarget.h deleted file mode 100644 index 64c3037cb..000000000 --- a/src/extras/animations/qmorphtarget.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QMORPHTARGET_H -#define QT3DEXTRAS_QMORPHTARGET_H - -#include <Qt3DRender/qattribute.h> -#include <Qt3DRender/qgeometry.h> - -#include <QtCore/qstringlist.h> - -#include <Qt3DExtras/qt3dextras_global.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QMorphTargetPrivate; - -class QT3DEXTRASSHARED_EXPORT QMorphTarget : public QObject -{ - Q_OBJECT - Q_PROPERTY(QStringList attributeNames READ attributeNames NOTIFY attributeNamesChanged) - -public: - explicit QMorphTarget(QObject *parent = nullptr); - - QVector<Qt3DRender::QAttribute *> attributeList() const; - QStringList attributeNames() const; - - void setAttributes(const QVector<Qt3DRender::QAttribute *> &attributes); - void addAttribute(Qt3DRender::QAttribute *attribute); - void removeAttribute(Qt3DRender::QAttribute *attribute); - - Q_INVOKABLE static QMorphTarget *fromGeometry(Qt3DRender::QGeometry *geometry, - const QStringList &attributes); - -Q_SIGNALS: - void attributeNamesChanged(const QStringList &attributeNames); - -private: - - Q_DECLARE_PRIVATE(QMorphTarget) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QMORPHTARGET_H diff --git a/src/extras/animations/qvertexblendanimation.cpp b/src/extras/animations/qvertexblendanimation.cpp deleted file mode 100644 index 1b45992fe..000000000 --- a/src/extras/animations/qvertexblendanimation.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qvertexblendanimation.h" - -#include <private/qvertexblendanimation_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -QVertexBlendAnimationPrivate::QVertexBlendAnimationPrivate() - : QAbstractAnimationPrivate(QAbstractAnimation::VertexBlendAnimation) - , m_currentBase(nullptr) - , m_currentTarget(nullptr) -{ - -} - -void QVertexBlendAnimationPrivate::getAttributesInPosition(float position, int *target0, - int *target1, float *interpolator) -{ - if (position < m_targetPositions.first()) { - *target0 = 0; - *target1 = qMin(1, m_targetPositions.size()); - *interpolator = 0.0f; - } else if (position > m_targetPositions.last()) { - *target0 = qMax(m_targetPositions.size() - 2, 0); - *target1 = qMax(m_targetPositions.size() - 1, 0); - *interpolator = 1.0f; - } else { - for (int i = 0; i < m_targetPositions.size() - 1; i++) { - if (position >= m_targetPositions[i] && position < m_targetPositions[i + 1]) { - *target0 = i; - *target1 = i + 1; - float a = (position - m_targetPositions[i]) - / (m_targetPositions[i + 1] - m_targetPositions[i]); - *interpolator = a; - } - } - } -} - -static Qt3DRender::QAttribute *findAttribute(QVector<Qt3DRender::QAttribute *> &attributes, - QString name) -{ - for (Qt3DRender::QAttribute *gattr : attributes) { - if (gattr->name() == name) - return gattr; - } - return nullptr; -} - -void QVertexBlendAnimationPrivate::updateAnimation(float position) -{ - Q_Q(QVertexBlendAnimation); - if (!m_target || !m_target->geometry()) - return; - - Qt3DExtras::QMorphTarget *base; - Qt3DExtras::QMorphTarget *target; - int target0, target1; - float interpolator; - getAttributesInPosition(position, &target0, &target1, &interpolator); - - base = m_morphTargets.at(target0); - target = m_morphTargets.at(target1); - - Qt3DRender::QGeometry *geometry = m_target->geometry(); - - // remove attributes from previous frame - if ((m_currentBase && (base != m_currentBase)) - || (m_currentTarget && (target != m_currentTarget))) { - const QVector<Qt3DRender::QAttribute *> baseAttributes = m_currentBase->attributeList(); - const QVector<Qt3DRender::QAttribute *> targetAttributes = m_currentTarget->attributeList(); - for (int i = 0; i < baseAttributes.size(); ++i) { - geometry->removeAttribute(baseAttributes.at(i)); - geometry->removeAttribute(targetAttributes.at(i)); - } - } - - const QVector<Qt3DRender::QAttribute *> baseAttributes = base->attributeList(); - const QVector<Qt3DRender::QAttribute *> targetAttributes = target->attributeList(); - const QStringList attributeNames = base->attributeNames(); - - // add attributes from current frame to the geometry - if (base != m_currentBase || target != m_currentTarget) { - for (int i = 0; i < baseAttributes.size(); ++i) { - const QString baseName = attributeNames.at(i); - QString targetName = baseName; - targetName.append("Target"); - - baseAttributes[i]->setName(baseName); - geometry->addAttribute(baseAttributes.at(i)); - targetAttributes[i]->setName(targetName); - geometry->addAttribute(targetAttributes.at(i)); - } - } - m_currentBase = base; - m_currentTarget = target; - - if (!qFuzzyCompare(interpolator, m_interpolator)) { - m_interpolator = interpolator; - emit q->interpolatorChanged(interpolator); - } -} - -QVertexBlendAnimation::QVertexBlendAnimation(QObject *parent) - : QAbstractAnimation(*new QVertexBlendAnimationPrivate, parent) -{ - Q_D(QVertexBlendAnimation); - d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged, - this, &QVertexBlendAnimation::updateAnimation); -} - -QVector<float> QVertexBlendAnimation::targetPositions() const -{ - Q_D(const QVertexBlendAnimation); - return d->m_targetPositions; -} - -float QVertexBlendAnimation::interpolator() const -{ - Q_D(const QVertexBlendAnimation); - return d->m_interpolator; -} - -Qt3DRender::QGeometryRenderer *QVertexBlendAnimation::target() const -{ - Q_D(const QVertexBlendAnimation); - return d->m_target; -} - -QString QVertexBlendAnimation::targetName() const -{ - Q_D(const QVertexBlendAnimation); - return d->m_targetName; -} - -void QVertexBlendAnimation::setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets) -{ - Q_D(QVertexBlendAnimation); - d->m_morphTargets = targets; -} - -void QVertexBlendAnimation::addMorphTarget(Qt3DExtras::QMorphTarget *target) -{ - Q_D(QVertexBlendAnimation); - if (!d->m_morphTargets.contains(target)) - d->m_morphTargets.push_back(target); -} - -void QVertexBlendAnimation::removeMorphTarget(Qt3DExtras::QMorphTarget *target) -{ - Q_D(QVertexBlendAnimation); - d->m_morphTargets.removeAll(target); -} - -void QVertexBlendAnimation::setTargetPositions(const QVector<float> &targetPositions) -{ - Q_D(QVertexBlendAnimation); - if (d->m_targetPositions == targetPositions) - return; - d->m_targetPositions = targetPositions; - emit targetPositionsChanged(targetPositions); - setDuration(d->m_targetPositions.last()); -} - -void QVertexBlendAnimation::setTarget(Qt3DRender::QGeometryRenderer *target) -{ - Q_D(QVertexBlendAnimation); - if (d->m_target != target) { - d->m_target = target; - emit targetChanged(target); - } -} - -QVector<Qt3DExtras::QMorphTarget *> QVertexBlendAnimation::morphTargetList() -{ - Q_D(QVertexBlendAnimation); - return d->m_morphTargets; -} - -void QVertexBlendAnimation::setTargetName(const QString name) -{ - Q_D(QVertexBlendAnimation); - if (d->m_targetName != name) { - d->m_targetName = name; - emit targetNameChanged(name); - } -} - -void QVertexBlendAnimation::updateAnimation(float position) -{ - Q_D(QVertexBlendAnimation); - d->updateAnimation(position); -} - -} // Qt3DExtras - -QT_END_NAMESPACE diff --git a/src/extras/animations/qvertexblendanimation.h b/src/extras/animations/qvertexblendanimation.h deleted file mode 100644 index ebd313e83..000000000 --- a/src/extras/animations/qvertexblendanimation.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QVERTEXBLENDANIMATION_H -#define QT3DEXTRAS_QVERTEXBLENDANIMATION_H - -#include <Qt3DRender/qgeometryrenderer.h> -#include <Qt3DExtras/qabstractanimation.h> -#include <Qt3DExtras/qmorphtarget.h> - -#include <Qt3DExtras/qt3dextras_global.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QVertexBlendAnimationPrivate; - -class QT3DEXTRASSHARED_EXPORT QVertexBlendAnimation : public QAbstractAnimation -{ - Q_OBJECT - Q_PROPERTY(QVector<float> targetPositions READ targetPositions WRITE setTargetPositions NOTIFY targetPositionsChanged) - Q_PROPERTY(float interpolator READ interpolator NOTIFY interpolatorChanged) - Q_PROPERTY(Qt3DRender::QGeometryRenderer *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged) - -public: - explicit QVertexBlendAnimation(QObject *parent = nullptr); - - QVector<float> targetPositions() const; - float interpolator() const; - Qt3DRender::QGeometryRenderer *target() const; - QString targetName() const; - - void setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets); - void addMorphTarget(Qt3DExtras::QMorphTarget *target); - void removeMorphTarget(Qt3DExtras::QMorphTarget *target); - - QVector<Qt3DExtras::QMorphTarget *> morphTargetList(); - -public Q_SLOTS: - void setTargetPositions(const QVector<float> &targetPositions); - void setTarget(Qt3DRender::QGeometryRenderer *target); - void setTargetName(const QString name); - -Q_SIGNALS: - void targetPositionsChanged(const QVector<float> &targetPositions); - void interpolatorChanged(float interpolator); - void targetChanged(Qt3DRender::QGeometryRenderer *target); - void targetNameChanged(const QString &name); - -private: - - void updateAnimation(float position); - - Q_DECLARE_PRIVATE(QVertexBlendAnimation) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QVERTEXBLENDANIMATION_H diff --git a/src/extras/animations/qvertexblendanimation_p.h b/src/extras/animations/qvertexblendanimation_p.h deleted file mode 100644 index 812953e04..000000000 --- a/src/extras/animations/qvertexblendanimation_p.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DEXTRAS_QVERTEXBLENDANIMATION_P_H -#define QT3DEXTRAS_QVERTEXBLENDANIMATION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - - -#include <Qt3DExtras/qvertexblendanimation.h> - -#include <private/qobject_p.h> -#include <private/qabstractanimation_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DExtras { - -class QVertexBlendAnimationPrivate : public QAbstractAnimationPrivate -{ -public: - QVertexBlendAnimationPrivate(); - - void getAttributesInPosition(float position, int *target0, int *target1, float *interpolator); - void updateAnimation(float position); - - QVector<float> m_targetPositions; - QVector<Qt3DExtras::QMorphTarget *> m_morphTargets; - float m_interpolator; - Qt3DRender::QGeometryRenderer *m_target; - QString m_targetName; - QMorphTarget *m_currentBase; - QMorphTarget *m_currentTarget; - - QMetaObject::Connection m_positionConnection; - - Q_DECLARE_PUBLIC(QVertexBlendAnimation) -}; - -} // Qt3DExtras - -QT_END_NAMESPACE - -#endif // QT3DEXTRAS_QVertexBlendANIMATION_P_H diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri index 21ef6fef6..8a18fb6e9 100644 --- a/src/extras/defaults/defaults.pri +++ b/src/extras/defaults/defaults.pri @@ -4,6 +4,7 @@ HEADERS += \ $$PWD/qphongmaterial.h \ $$PWD/qphongmaterial_p.h \ $$PWD/qdiffusemapmaterial_p.h \ + $$PWD/qdiffusemapmaterial.h \ $$PWD/qnormaldiffusespecularmapmaterial.h \ $$PWD/qnormaldiffusespecularmapmaterial_p.h \ $$PWD/qnormaldiffusemapmaterial.h \ @@ -23,13 +24,19 @@ HEADERS += \ $$PWD/qphongalphamaterial.h \ $$PWD/qphongalphamaterial_p.h \ $$PWD/qt3dwindow.h \ + $$PWD/qt3dwindow_p.h \ $$PWD/qfirstpersoncameracontroller.h \ $$PWD/qfirstpersoncameracontroller_p.h \ $$PWD/qorbitcameracontroller.h \ $$PWD/qorbitcameracontroller_p.h \ + $$PWD/qtexturematerial.h \ + $$PWD/qtexturematerial_p.h \ + $$PWD/qmetalroughmaterial.h \ + $$PWD/qmetalroughmaterial_p.h \ + $$PWD/qtexturedmetalroughmaterial.h \ + $$PWD/qtexturedmetalroughmaterial_p.h \ $$PWD/qmorphphongmaterial.h \ - $$PWD/qmorphphongmaterial_p.h \ - $$PWD/qdiffusemapmaterial.h + $$PWD/qmorphphongmaterial_p.h SOURCES += \ $$PWD/qphongmaterial.cpp \ @@ -46,5 +53,8 @@ SOURCES += \ $$PWD/qt3dwindow.cpp \ $$PWD/qfirstpersoncameracontroller.cpp \ $$PWD/qorbitcameracontroller.cpp \ + $$PWD/qtexturematerial.cpp \ + $$PWD/qmetalroughmaterial.cpp \ + $$PWD/qtexturedmetalroughmaterial.cpp \ $$PWD/qmorphphongmaterial.cpp diff --git a/src/extras/defaults/qdiffusemapmaterial.cpp b/src/extras/defaults/qdiffusemapmaterial.cpp index b3aa3bf00..a6da98a2e 100644 --- a/src/extras/defaults/qdiffusemapmaterial.cpp +++ b/src/extras/defaults/qdiffusemapmaterial.cpp @@ -39,6 +39,7 @@ #include "qdiffusemapmaterial.h" #include "qdiffusemapmaterial_p.h" + #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qmaterial.h> #include <Qt3DRender/qeffect.h> @@ -48,9 +49,9 @@ #include <Qt3DRender/qparameter.h> #include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qgraphicsapifilter.h> -#include <QUrl> -#include <QVector3D> -#include <QVector4D> +#include <QtCore/QUrl> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qdiffusemapmaterial.h b/src/extras/defaults/qdiffusemapmaterial.h index b6bba9b36..e6c632ed2 100644 --- a/src/extras/defaults/qdiffusemapmaterial.h +++ b/src/extras/defaults/qdiffusemapmaterial.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qmaterial.h> -#include <QColor> +#include <QtGui/QColor> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qdiffusespecularmapmaterial.cpp b/src/extras/defaults/qdiffusespecularmapmaterial.cpp index 4b79eea2b..615ee6305 100644 --- a/src/extras/defaults/qdiffusespecularmapmaterial.cpp +++ b/src/extras/defaults/qdiffusespecularmapmaterial.cpp @@ -39,6 +39,7 @@ #include "qdiffusespecularmapmaterial.h" #include "qdiffusespecularmapmaterial_p.h" + #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qmaterial.h> #include <Qt3DRender/qeffect.h> @@ -48,9 +49,9 @@ #include <Qt3DRender/qparameter.h> #include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qgraphicsapifilter.h> -#include <QUrl> -#include <QVector3D> -#include <QVector4D> +#include <QtCore/QUrl> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qdiffusespecularmapmaterial.h b/src/extras/defaults/qdiffusespecularmapmaterial.h index d5dd053bd..d86948673 100644 --- a/src/extras/defaults/qdiffusespecularmapmaterial.h +++ b/src/extras/defaults/qdiffusespecularmapmaterial.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qmaterial.h> -#include <QColor> +#include <QtGui/QColor> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qfirstpersoncameracontroller.cpp b/src/extras/defaults/qfirstpersoncameracontroller.cpp index e31448eb8..5321bfcf2 100644 --- a/src/extras/defaults/qfirstpersoncameracontroller.cpp +++ b/src/extras/defaults/qfirstpersoncameracontroller.cpp @@ -1,66 +1,53 @@ /**************************************************************************** ** ** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ +** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt3D module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ +** $QT_BEGIN_LICENSE:LGPL3$ ** 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. +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** "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." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "qfirstpersoncameracontroller_p.h" #include "qfirstpersoncameracontroller.h" -#include <Qt3DRender/QCamera> -#include <Qt3DInput/QAxis> -#include <Qt3DInput/QAnalogAxisInput> -#include <Qt3DInput/QButtonAxisInput> +#include "qfirstpersoncameracontroller_p.h" + #include <Qt3DInput/QAction> #include <Qt3DInput/QActionInput> -#include <Qt3DInput/QLogicalDevice> +#include <Qt3DInput/QAnalogAxisInput> +#include <Qt3DInput/QAxis> +#include <Qt3DInput/QButtonAxisInput> +#include <Qt3DLogic/QFrameAction> #include <Qt3DInput/QKeyboardDevice> +#include <Qt3DInput/QLogicalDevice> #include <Qt3DInput/QMouseDevice> #include <Qt3DInput/QMouseEvent> -#include <Qt3DLogic/QFrameAction> +#include <Qt3DRender/QCamera> QT_BEGIN_NAMESPACE @@ -80,6 +67,8 @@ QFirstPersonCameraControllerPrivate::QFirstPersonCameraControllerPrivate() , m_fineMotionKeyInput(new Qt3DInput::QActionInput()) , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput()) , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput()) + , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput()) + , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput()) , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput()) , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput()) , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput()) @@ -92,6 +81,8 @@ QFirstPersonCameraControllerPrivate::QFirstPersonCameraControllerPrivate() , m_frameAction(new Qt3DLogic::QFrameAction()) , m_linearSpeed(10.0f) , m_lookSpeed(180.0f) + , m_acceleration(-1.0f) + , m_deceleration(-1.0f) , m_firstPersonUp(QVector3D(0.0f, 1.0f, 0.0f)) {} @@ -121,6 +112,16 @@ void QFirstPersonCameraControllerPrivate::init() m_mouseRyInput->setSourceDevice(m_mouseDevice); m_ryAxis->addInput(m_mouseRyInput); + // Mouse Wheel X + m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX); + m_mouseTzXInput->setSourceDevice(m_mouseDevice); + m_tzAxis->addInput(m_mouseTzXInput); + + // Mouse Wheel Y + m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY); + m_mouseTzYInput->setSourceDevice(m_mouseDevice); + m_tzAxis->addInput(m_mouseTzYInput); + // Keyboard Pos Tx m_keyboardTxPosInput->setButtons(QVector<int>() << Qt::Key_Right); m_keyboardTxPosInput->setScale(1.0f); @@ -167,6 +168,8 @@ void QFirstPersonCameraControllerPrivate::init() m_logicalDevice->addAxis(m_tyAxis); m_logicalDevice->addAxis(m_tzAxis); + applyAccelerations(); + Q_Q(QFirstPersonCameraController); //// FrameAction @@ -181,6 +184,23 @@ void QFirstPersonCameraControllerPrivate::init() q->addComponent(m_logicalDevice); } +void QFirstPersonCameraControllerPrivate::applyAccelerations() +{ + const auto inputs = { + m_keyboardTxPosInput, + m_keyboardTyPosInput, + m_keyboardTzPosInput, + m_keyboardTxNegInput, + m_keyboardTyNegInput, + m_keyboardTzNegInput + }; + + for (auto input : inputs) { + input->setAcceleration(m_acceleration); + input->setDeceleration(m_deceleration); + } +} + void QFirstPersonCameraControllerPrivate::_q_onTriggered(float dt) { if (m_camera != nullptr) { @@ -215,6 +235,9 @@ void QFirstPersonCameraControllerPrivate::_q_onTriggered(float dt) \li While the left mouse button is pressed, mouse movement along x-axis pans the camera and movement along y-axis tilts it. \row + \li Mouse scroll wheel + \li Zooms the camera in and out without changing the view center. + \row \li Shift key \li Turns the fine motion control active while pressed. Makes mouse pan and tilt less sensitive. @@ -273,6 +296,28 @@ float QFirstPersonCameraController::lookSpeed() const return d->m_lookSpeed; } +/*! + \property QFirstPersonCameraController::acceleration + + Holds the current acceleration of the camera controller. +*/ +float QFirstPersonCameraController::acceleration() const +{ + Q_D(const QFirstPersonCameraController); + return d->m_acceleration; +} + +/*! + \property QFirstPersonCameraController::deceleration + + Holds the current deceleration of the camera controller. +*/ +float QFirstPersonCameraController::deceleration() const +{ + Q_D(const QFirstPersonCameraController); + return d->m_deceleration; +} + void QFirstPersonCameraController::setCamera(Qt3DRender::QCamera *camera) { Q_D(QFirstPersonCameraController); @@ -312,6 +357,26 @@ void QFirstPersonCameraController::setLookSpeed(float lookSpeed) } } +void QFirstPersonCameraController::setAcceleration(float acceleration) +{ + Q_D(QFirstPersonCameraController); + if (d->m_acceleration != acceleration) { + d->m_acceleration = acceleration; + d->applyAccelerations(); + emit accelerationChanged(acceleration); + } +} + +void QFirstPersonCameraController::setDeceleration(float deceleration) +{ + Q_D(QFirstPersonCameraController); + if (d->m_deceleration != deceleration) { + d->m_deceleration = deceleration; + d->applyAccelerations(); + emit decelerationChanged(deceleration); + } +} + } // Qt3DExtras QT_END_NAMESPACE diff --git a/src/extras/defaults/qfirstpersoncameracontroller.h b/src/extras/defaults/qfirstpersoncameracontroller.h index e50d4db5a..3f7a6acc4 100644 --- a/src/extras/defaults/qfirstpersoncameracontroller.h +++ b/src/extras/defaults/qfirstpersoncameracontroller.h @@ -1,48 +1,34 @@ /**************************************************************************** ** ** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ +** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt3D module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ +** $QT_BEGIN_LICENSE:LGPL3$ ** 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. +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** "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." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -70,7 +56,8 @@ class QT3DEXTRASSHARED_EXPORT QFirstPersonCameraController : public Qt3DCore::QE Q_PROPERTY(Qt3DRender::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged) Q_PROPERTY(float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged) Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged) - + Q_PROPERTY(float acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) + Q_PROPERTY(float deceleration READ deceleration WRITE setDeceleration NOTIFY decelerationChanged) public: explicit QFirstPersonCameraController(Qt3DCore::QNode *parent = nullptr); ~QFirstPersonCameraController(); @@ -78,15 +65,21 @@ public: Qt3DRender::QCamera *camera() const; float linearSpeed() const; float lookSpeed() const; + float acceleration() const; + float deceleration() const; void setCamera(Qt3DRender::QCamera *camera); void setLinearSpeed(float linearSpeed); void setLookSpeed(float lookSpeed); + void setAcceleration(float acceleration); + void setDeceleration(float deceleration); Q_SIGNALS: void cameraChanged(); void linearSpeedChanged(); void lookSpeedChanged(); + void accelerationChanged(float acceleration); + void decelerationChanged(float deceleration); private: Q_DECLARE_PRIVATE(QFirstPersonCameraController) diff --git a/src/extras/defaults/qfirstpersoncameracontroller_p.h b/src/extras/defaults/qfirstpersoncameracontroller_p.h index 9ea830f85..48a7c7998 100644 --- a/src/extras/defaults/qfirstpersoncameracontroller_p.h +++ b/src/extras/defaults/qfirstpersoncameracontroller_p.h @@ -51,9 +51,11 @@ #ifndef QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_P_H #define QT3DEXTRAS_QFIRSTPERSONCAMERACONTROLLER_P_H +#include <Qt3DExtras/qfirstpersoncameracontroller.h> +#include <QtGui/QVector3D> + #include <Qt3DCore/private/qentity_p.h> -#include <QVector3D> -#include "qfirstpersoncameracontroller.h" + // // W A R N I N G @@ -98,6 +100,7 @@ public: QFirstPersonCameraControllerPrivate(); void init(); + void applyAccelerations(); Qt3DRender::QCamera *m_camera; @@ -115,6 +118,8 @@ public: Qt3DInput::QAnalogAxisInput *m_mouseRxInput; Qt3DInput::QAnalogAxisInput *m_mouseRyInput; + Qt3DInput::QAnalogAxisInput *m_mouseTzXInput; + Qt3DInput::QAnalogAxisInput *m_mouseTzYInput; Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput; Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput; Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput; @@ -131,6 +136,8 @@ public: float m_linearSpeed; float m_lookSpeed; + float m_acceleration; + float m_deceleration; QVector3D m_firstPersonUp; void _q_onTriggered(float); diff --git a/src/extras/defaults/qforwardrenderer.cpp b/src/extras/defaults/qforwardrenderer.cpp index d556b58d3..3a5c6803b 100644 --- a/src/extras/defaults/qforwardrenderer.cpp +++ b/src/extras/defaults/qforwardrenderer.cpp @@ -134,6 +134,8 @@ QForwardRenderer::QForwardRenderer(QNode *parent) QObject::connect(d->m_cameraSelector, &QCameraSelector::cameraChanged, this, &QForwardRenderer::cameraChanged); QObject::connect(d->m_surfaceSelector, &QRenderSurfaceSelector::surfaceChanged, this, &QForwardRenderer::surfaceChanged); QObject::connect(d->m_surfaceSelector, &QRenderSurfaceSelector::externalRenderTargetSizeChanged, this, &QForwardRenderer::externalRenderTargetSizeChanged); + QObject::connect(d->m_frustumCulling, &QFrustumCulling::enabledChanged, this, &QForwardRenderer::frustumCullingEnabledChanged); + QObject::connect(d->m_viewport, &QViewport::gammaChanged, this, &QForwardRenderer::gammaChanged); d->init(); } @@ -171,6 +173,18 @@ void QForwardRenderer::setExternalRenderTargetSize(const QSize &size) d->m_surfaceSelector->setExternalRenderTargetSize(size); } +void QForwardRenderer::setFrustumCullingEnabled(bool enabled) +{ + Q_D(QForwardRenderer); + d->m_frustumCulling->setEnabled(enabled); +} + +void QForwardRenderer::setGamma(float gamma) +{ + Q_D(QForwardRenderer); + d->m_viewport->setGamma(gamma); +} + /*! \qmlproperty rect ForwardRenderer::viewportRect @@ -226,6 +240,21 @@ Qt3DCore::QEntity *QForwardRenderer::camera() const } /*! + \qmlproperty Object ForwardRenderer::window + + Holds the current render surface. + + \deprecated +*/ +/*! + \property QForwardRenderer::window + + Holds the current render surface. + + \deprecated +*/ + +/*! \qmlproperty Object ForwardRenderer::surface Holds the current render surface. @@ -247,6 +276,38 @@ QSize QForwardRenderer::externalRenderTargetSize() const return d->m_surfaceSelector->externalRenderTargetSize(); } +/*! + \qmlproperty color ForwardRenderer::frustumCulling + + Indicates if the renderer applies frustum culling to the scene. +*/ +/*! + \property QForwardRenderer::frustumCulling + + Indicates if the renderer applies frustum culling to the scene. +*/ +bool QForwardRenderer::isFrustumCullingEnabled() const +{ + Q_D(const QForwardRenderer); + return d->m_frustumCulling->isEnabled(); +} + +/*! + \qmlproperty color ForwardRenderer::gamma + + Holds the gamma value the renderer applies to the scene. +*/ +/*! + \property QForwardRenderer::gamma + + Holds the gamma value the renderer applies to the scene. +*/ +float QForwardRenderer::gamma() const +{ + Q_D(const QForwardRenderer); + return d->m_viewport->gamma(); +} + } // namespace Qt3DExtras QT_END_NAMESPACE diff --git a/src/extras/defaults/qforwardrenderer.h b/src/extras/defaults/qforwardrenderer.h index 01f50f452..7b6078169 100644 --- a/src/extras/defaults/qforwardrenderer.h +++ b/src/extras/defaults/qforwardrenderer.h @@ -42,8 +42,9 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qtechniquefilter.h> -#include <QRectF> -#include <QColor> +#include <QtCore/QRectF> +#include <QtGui/QColor> + QT_BEGIN_NAMESPACE @@ -57,10 +58,13 @@ class QT3DEXTRASSHARED_EXPORT QForwardRenderer : public Qt3DRender::QTechniqueFi { Q_OBJECT Q_PROPERTY(QObject *surface READ surface WRITE setSurface NOTIFY surfaceChanged) + Q_PROPERTY(QObject *window READ surface WRITE setSurface NOTIFY surfaceChanged) Q_PROPERTY(QRectF viewportRect READ viewportRect WRITE setViewportRect NOTIFY viewportRectChanged) Q_PROPERTY(QColor clearColor READ clearColor WRITE setClearColor NOTIFY clearColorChanged) Q_PROPERTY(Qt3DCore::QEntity *camera READ camera WRITE setCamera NOTIFY cameraChanged) Q_PROPERTY(QSize externalRenderTargetSize READ externalRenderTargetSize WRITE setExternalRenderTargetSize NOTIFY externalRenderTargetSizeChanged) + Q_PROPERTY(bool frustumCulling READ isFrustumCullingEnabled WRITE setFrustumCullingEnabled NOTIFY frustumCullingEnabledChanged) + Q_PROPERTY(float gamma READ gamma WRITE setGamma NOTIFY gammaChanged REVISION 9) public: explicit QForwardRenderer(Qt3DCore::QNode *parent = nullptr); ~QForwardRenderer(); @@ -70,6 +74,8 @@ public: Qt3DCore::QEntity *camera() const; QObject *surface() const; QSize externalRenderTargetSize() const; + bool isFrustumCullingEnabled() const; + float gamma() const; public Q_SLOTS: void setViewportRect(const QRectF &viewportRect); @@ -77,6 +83,8 @@ public Q_SLOTS: void setCamera(Qt3DCore::QEntity *camera); void setSurface(QObject * surface); void setExternalRenderTargetSize(const QSize &size); + void setFrustumCullingEnabled(bool enabled); + void setGamma(float gamma); Q_SIGNALS: void viewportRectChanged(const QRectF &viewportRect); @@ -84,6 +92,8 @@ Q_SIGNALS: void cameraChanged(Qt3DCore::QEntity *camera); void surfaceChanged(QObject *surface); void externalRenderTargetSizeChanged(const QSize &size); + void frustumCullingEnabledChanged(bool enabled); + void gammaChanged(float gamma); private: Q_DECLARE_PRIVATE(QForwardRenderer) diff --git a/src/extras/defaults/qgoochmaterial.cpp b/src/extras/defaults/qgoochmaterial.cpp index f2f34fc84..ba7ef8dab 100644 --- a/src/extras/defaults/qgoochmaterial.cpp +++ b/src/extras/defaults/qgoochmaterial.cpp @@ -39,13 +39,13 @@ #include "qgoochmaterial.h" #include "qgoochmaterial_p.h" + #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qeffect.h> #include <Qt3DRender/qgraphicsapifilter.h> #include <Qt3DRender/qparameter.h> #include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qtechnique.h> - #include <QtCore/qurl.h> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qgoochmaterial.h b/src/extras/defaults/qgoochmaterial.h index 232257513..6afddfe8b 100644 --- a/src/extras/defaults/qgoochmaterial.h +++ b/src/extras/defaults/qgoochmaterial.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qmaterial.h> -#include <QColor> +#include <QtGui/QColor> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qmetalroughmaterial.cpp b/src/extras/defaults/qmetalroughmaterial.cpp new file mode 100644 index 000000000..ea213ab82 --- /dev/null +++ b/src/extras/defaults/qmetalroughmaterial.cpp @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmetalroughmaterial.h" +#include "qmetalroughmaterial_p.h" +#include <Qt3DRender/qfilterkey.h> +#include <Qt3DRender/qmaterial.h> +#include <Qt3DRender/qeffect.h> +#include <Qt3DRender/qtexture.h> +#include <Qt3DRender/qtechnique.h> +#include <Qt3DRender/qshaderprogram.h> +#include <Qt3DRender/qparameter.h> +#include <Qt3DRender/qrenderpass.h> +#include <Qt3DRender/qgraphicsapifilter.h> +#include <QUrl> +#include <QVector3D> +#include <QVector4D> + +QT_BEGIN_NAMESPACE + +using namespace Qt3DRender; + +namespace Qt3DExtras { + +QMetalRoughMaterialPrivate::QMetalRoughMaterialPrivate() + : QMaterialPrivate() + , m_environmentIrradianceTexture(new QTexture2D()) + , m_environmentSpecularTexture(new QTexture2D()) + , m_baseColorParameter(new QParameter(QStringLiteral("baseColor"), QColor("grey"))) + , m_metalnessParameter(new QParameter(QStringLiteral("metalness"), 0.0f)) + , m_roughnessParameter(new QParameter(QStringLiteral("roughness"), 0.0f)) + , m_environmentIrradianceParameter(new QParameter(QStringLiteral("envLight.irradiance"), m_environmentIrradianceTexture)) + , m_environmentSpecularParameter(new QParameter(QStringLiteral("envLight.specular"), m_environmentSpecularTexture)) + , m_metalRoughEffect(new QEffect()) + , m_metalRoughGL3Technique(new QTechnique()) + , m_metalRoughGL3RenderPass(new QRenderPass()) + , m_metalRoughGL3Shader(new QShaderProgram()) + , m_filterKey(new QFilterKey) +{ + m_environmentIrradianceTexture->setMagnificationFilter(QAbstractTexture::Linear); + m_environmentIrradianceTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear); + m_environmentIrradianceTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat)); + m_environmentIrradianceTexture->setGenerateMipMaps(true); + m_environmentIrradianceTexture->setMaximumAnisotropy(16.0f); + + m_environmentSpecularTexture->setMagnificationFilter(QAbstractTexture::Linear); + m_environmentSpecularTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear); + m_environmentSpecularTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat)); + m_environmentSpecularTexture->setGenerateMipMaps(true); + m_environmentSpecularTexture->setMaximumAnisotropy(16.0f); +} + +void QMetalRoughMaterialPrivate::init() +{ + connect(m_baseColorParameter, &Qt3DRender::QParameter::valueChanged, + this, &QMetalRoughMaterialPrivate::handleBaseColorChanged); + connect(m_metalnessParameter, &Qt3DRender::QParameter::valueChanged, + this, &QMetalRoughMaterialPrivate::handleMetallicChanged); + connect(m_roughnessParameter, &Qt3DRender::QParameter::valueChanged, + this, &QMetalRoughMaterialPrivate::handleRoughnessChanged); + + m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalrough.vert")))); + m_metalRoughGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalroughuniform.frag")))); + + m_metalRoughGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + m_metalRoughGL3Technique->graphicsApiFilter()->setMajorVersion(3); + m_metalRoughGL3Technique->graphicsApiFilter()->setMinorVersion(1); + m_metalRoughGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); + + Q_Q(QMetalRoughMaterial); + m_filterKey->setParent(q); + m_filterKey->setName(QStringLiteral("renderingStyle")); + m_filterKey->setValue(QStringLiteral("forward")); + + m_metalRoughGL3Technique->addFilterKey(m_filterKey); + m_metalRoughGL3RenderPass->setShaderProgram(m_metalRoughGL3Shader); + m_metalRoughGL3Technique->addRenderPass(m_metalRoughGL3RenderPass); + m_metalRoughEffect->addTechnique(m_metalRoughGL3Technique); + + m_metalRoughEffect->addParameter(m_baseColorParameter); + m_metalRoughEffect->addParameter(m_metalnessParameter); + m_metalRoughEffect->addParameter(m_roughnessParameter); + + // Note that even though those parameters are not exposed in the API, + // they need to be kept around for now due to a bug in some drivers/GPUs + // (at least Intel) which cause issues with unbound textures even if you + // don't try to sample from them. + // Can probably go away once we generate the shaders and deal in this + // case in a better way. + m_metalRoughEffect->addParameter(m_environmentIrradianceParameter); + m_metalRoughEffect->addParameter(m_environmentSpecularParameter); + + q->setEffect(m_metalRoughEffect); +} + +void QMetalRoughMaterialPrivate::handleBaseColorChanged(const QVariant &var) +{ + Q_Q(QMetalRoughMaterial); + emit q->baseColorChanged(var.value<QColor>()); +} + +void QMetalRoughMaterialPrivate::handleMetallicChanged(const QVariant &var) +{ + Q_Q(QMetalRoughMaterial); + emit q->metalnessChanged(var.toFloat()); +} +void QMetalRoughMaterialPrivate::handleRoughnessChanged(const QVariant &var) +{ + Q_Q(QMetalRoughMaterial); + emit q->roughnessChanged(var.toFloat()); +} + +/*! + \class Qt3DExtras::QMetalRoughMaterial + \brief The QMetalRoughMaterial provides a default implementation of PBR + lighting. + \inmodule Qt3DExtras + \since 5.9 + \inherits Qt3DRender::QMaterial + + This material uses an effect with a single render pass approach and performs per fragment + lighting. Techniques are provided for OpenGL 3 only. +*/ + +/*! + Constructs a new QMetalRoughMaterial instance with parent object \a parent. +*/ +QMetalRoughMaterial::QMetalRoughMaterial(QNode *parent) + : QMaterial(*new QMetalRoughMaterialPrivate, parent) +{ + Q_D(QMetalRoughMaterial); + d->init(); +} + +/*! \internal */ +QMetalRoughMaterial::QMetalRoughMaterial(QMetalRoughMaterialPrivate &dd, QNode *parent) + : QMaterial(dd, parent) +{ + Q_D(QMetalRoughMaterial); + d->init(); +} + +/*! + Destroys the QMetalRoughMaterial instance. +*/ +QMetalRoughMaterial::~QMetalRoughMaterial() +{ +} + +/*! + \property QMetalRoughMaterial::baseColor + + Holds the current base color of the material. +*/ +QColor QMetalRoughMaterial::baseColor() const +{ + Q_D(const QMetalRoughMaterial); + return d->m_baseColorParameter->value().value<QColor>(); +} + +/*! + \property QMetalRoughMaterial::metalness + + Holds the current metalness level of the material, since is a value between 0 (purely dielectric, the default) + and 1 (purely metallic). +*/ +float QMetalRoughMaterial::metalness() const +{ + Q_D(const QMetalRoughMaterial); + return d->m_metalnessParameter->value().toFloat(); +} + +/*! + \property QMetalRoughMaterial::roughness + + Holds the current roughness level of the material. +*/ +float QMetalRoughMaterial::roughness() const +{ + Q_D(const QMetalRoughMaterial); + return d->m_roughnessParameter->value().toFloat(); +} + +void QMetalRoughMaterial::setBaseColor(const QColor &baseColor) +{ + Q_D(QMetalRoughMaterial); + d->m_baseColorParameter->setValue(QVariant::fromValue(baseColor)); +} + +void QMetalRoughMaterial::setMetalness(float metalness) +{ + Q_D(QMetalRoughMaterial); + d->m_metalnessParameter->setValue(QVariant::fromValue(metalness)); +} + +void QMetalRoughMaterial::setRoughness(float roughness) +{ + Q_D(QMetalRoughMaterial); + d->m_roughnessParameter->setValue(QVariant::fromValue(roughness)); +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/defaults/qmetalroughmaterial.h b/src/extras/defaults/qmetalroughmaterial.h new file mode 100644 index 000000000..28c9438a7 --- /dev/null +++ b/src/extras/defaults/qmetalroughmaterial.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QMETALROUGHMATERIAL_H +#define QT3DEXTRAS_QMETALROUGHMATERIAL_H + +#include <Qt3DExtras/qt3dextras_global.h> +#include <Qt3DRender/qmaterial.h> +#include <QtGui/qcolor.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { +class QAbstractTexture; +} + +namespace Qt3DExtras { + +class QMetalRoughMaterialPrivate; + +class QT3DEXTRASSHARED_EXPORT QMetalRoughMaterial : public Qt3DRender::QMaterial +{ + Q_OBJECT + Q_PROPERTY(QColor baseColor READ baseColor WRITE setBaseColor NOTIFY baseColorChanged) + Q_PROPERTY(float metalness READ metalness WRITE setMetalness NOTIFY metalnessChanged) + Q_PROPERTY(float roughness READ roughness WRITE setRoughness NOTIFY roughnessChanged) + +public: + explicit QMetalRoughMaterial(Qt3DCore::QNode *parent = nullptr); + ~QMetalRoughMaterial(); + + QColor baseColor() const; + float metalness() const; + float roughness() const; + +public Q_SLOTS: + void setBaseColor(const QColor &baseColor); + void setMetalness(float metalness); + void setRoughness(float roughness); + +Q_SIGNALS: + void baseColorChanged(const QColor &baseColor); + void metalnessChanged(float metalness); + void roughnessChanged(float roughness); + +protected: + explicit QMetalRoughMaterial(QMetalRoughMaterialPrivate &dd, Qt3DCore::QNode *parent = nullptr); + +private: + Q_DECLARE_PRIVATE(QMetalRoughMaterial) +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QMETALROUGHMATERIAL_H diff --git a/src/extras/defaults/qmetalroughmaterial_p.h b/src/extras/defaults/qmetalroughmaterial_p.h new file mode 100644 index 000000000..3090b9757 --- /dev/null +++ b/src/extras/defaults/qmetalroughmaterial_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QMETALROUGHMATERIAL_P_H +#define QT3DEXTRAS_QMETALROUGHMATERIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/private/qmaterial_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QFilterKey; +class QEffect; +class QAbstractTexture; +class QTechnique; +class QParameter; +class QShaderProgram; +class QRenderPass; + +} // namespace Qt3DRender + +namespace Qt3DExtras { + +class QMetalRoughMaterial; + +class QMetalRoughMaterialPrivate : public Qt3DRender::QMaterialPrivate +{ +public: + QMetalRoughMaterialPrivate(); + + void init(); + + void handleBaseColorChanged(const QVariant &var); + void handleMetallicChanged(const QVariant &var); + void handleRoughnessChanged(const QVariant &var); + + Qt3DRender::QAbstractTexture *m_environmentIrradianceTexture; + Qt3DRender::QAbstractTexture *m_environmentSpecularTexture; + Qt3DRender::QParameter *m_baseColorParameter; + Qt3DRender::QParameter *m_metalnessParameter; + Qt3DRender::QParameter *m_roughnessParameter; + Qt3DRender::QParameter *m_environmentIrradianceParameter; + Qt3DRender::QParameter *m_environmentSpecularParameter; + Qt3DRender::QEffect *m_metalRoughEffect; + Qt3DRender::QTechnique *m_metalRoughGL3Technique; + Qt3DRender::QRenderPass *m_metalRoughGL3RenderPass; + Qt3DRender::QShaderProgram *m_metalRoughGL3Shader; + Qt3DRender::QFilterKey *m_filterKey; + + Q_DECLARE_PUBLIC(QMetalRoughMaterial) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QMETALROUGHMATERIAL_P_H + diff --git a/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp index 92564ee3f..eb6398341 100644 --- a/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp +++ b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp @@ -49,10 +49,9 @@ #include <Qt3DRender/qgraphicsapifilter.h> #include <Qt3DRender/qalphacoverage.h> #include <Qt3DRender/qdepthtest.h> - -#include <QUrl> -#include <QVector3D> -#include <QVector4D> +#include <QtCore/QUrl> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qnormaldiffusemapalphamaterial_p.h b/src/extras/defaults/qnormaldiffusemapalphamaterial_p.h index 91b0961f1..5994d87eb 100644 --- a/src/extras/defaults/qnormaldiffusemapalphamaterial_p.h +++ b/src/extras/defaults/qnormaldiffusemapalphamaterial_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include <qnormaldiffusemapmaterial_p.h> +#include <Qt3DExtras/private/qnormaldiffusemapmaterial_p.h> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qnormaldiffusemapmaterial.cpp b/src/extras/defaults/qnormaldiffusemapmaterial.cpp index 8373c4d5d..35cea095a 100644 --- a/src/extras/defaults/qnormaldiffusemapmaterial.cpp +++ b/src/extras/defaults/qnormaldiffusemapmaterial.cpp @@ -39,6 +39,7 @@ #include "qnormaldiffusemapmaterial.h" #include "qnormaldiffusemapmaterial_p.h" + #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qeffect.h> #include <Qt3DRender/qtexture.h> @@ -47,10 +48,9 @@ #include <Qt3DRender/qshaderprogram.h> #include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qgraphicsapifilter.h> - -#include <QUrl> -#include <QVector3D> -#include <QVector4D> +#include <QtCore/QUrl> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qnormaldiffusemapmaterial.h b/src/extras/defaults/qnormaldiffusemapmaterial.h index f60a27b86..c38d53352 100644 --- a/src/extras/defaults/qnormaldiffusemapmaterial.h +++ b/src/extras/defaults/qnormaldiffusemapmaterial.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qmaterial.h> -#include <QColor> +#include <QtGui/QColor> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qnormaldiffusemapmaterial_p.h b/src/extras/defaults/qnormaldiffusemapmaterial_p.h index 8dff59218..d88b01f1f 100644 --- a/src/extras/defaults/qnormaldiffusemapmaterial_p.h +++ b/src/extras/defaults/qnormaldiffusemapmaterial_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include <Qt3DRender/private/qmaterial_p.h> +#include <private/qmaterial_p.h> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp index e4a83c50c..c6f8ced9c 100644 --- a/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp +++ b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp @@ -39,6 +39,7 @@ #include "qnormaldiffusespecularmapmaterial.h" #include "qnormaldiffusespecularmapmaterial_p.h" + #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qmaterial.h> #include <Qt3DRender/qeffect.h> @@ -48,9 +49,9 @@ #include <Qt3DRender/qparameter.h> #include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qgraphicsapifilter.h> -#include <QUrl> -#include <QVector3D> -#include <QVector4D> +#include <QtCore/QUrl> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qnormaldiffusespecularmapmaterial.h b/src/extras/defaults/qnormaldiffusespecularmapmaterial.h index 586715971..164b07710 100644 --- a/src/extras/defaults/qnormaldiffusespecularmapmaterial.h +++ b/src/extras/defaults/qnormaldiffusespecularmapmaterial.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qmaterial.h> -#include <QColor> +#include <QtGui/QColor> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qorbitcameracontroller.cpp b/src/extras/defaults/qorbitcameracontroller.cpp index 95b0e19dc..565a75ea1 100644 --- a/src/extras/defaults/qorbitcameracontroller.cpp +++ b/src/extras/defaults/qorbitcameracontroller.cpp @@ -34,9 +34,9 @@ ** ****************************************************************************/ -#include "qorbitcameracontroller_p.h" #include "qorbitcameracontroller.h" -#include <QtGlobal> +#include "qorbitcameracontroller_p.h" + #include <Qt3DRender/QCamera> #include <Qt3DInput/QAxis> #include <Qt3DInput/QAnalogAxisInput> @@ -48,6 +48,7 @@ #include <Qt3DInput/QMouseDevice> #include <Qt3DInput/QMouseEvent> #include <Qt3DLogic/QFrameAction> +#include <QtCore/QtGlobal> QT_BEGIN_NAMESPACE @@ -79,6 +80,9 @@ namespace Qt3DExtras { \li While both the left and the right mouse button are pressed, mouse movement along y-axis zooms the camera in and out without changing the view center. \row + \li Mouse scroll wheel + \li Zooms the camera in and out without changing the view center. + \row \li Arrow keys \li Move the camera vertically and horizontally relative to camera viewport. \row @@ -113,6 +117,8 @@ QOrbitCameraControllerPrivate::QOrbitCameraControllerPrivate() , m_shiftButtonInput(new Qt3DInput::QActionInput()) , m_mouseRxInput(new Qt3DInput::QAnalogAxisInput()) , m_mouseRyInput(new Qt3DInput::QAnalogAxisInput()) + , m_mouseTzXInput(new Qt3DInput::QAnalogAxisInput()) + , m_mouseTzYInput(new Qt3DInput::QAnalogAxisInput()) , m_keyboardTxPosInput(new Qt3DInput::QButtonAxisInput()) , m_keyboardTyPosInput(new Qt3DInput::QButtonAxisInput()) , m_keyboardTzPosInput(new Qt3DInput::QButtonAxisInput()) @@ -165,6 +171,16 @@ void QOrbitCameraControllerPrivate::init() m_mouseRyInput->setSourceDevice(m_mouseDevice); m_ryAxis->addInput(m_mouseRyInput); + // Mouse Wheel X + m_mouseTzXInput->setAxis(Qt3DInput::QMouseDevice::WheelX); + m_mouseTzXInput->setSourceDevice(m_mouseDevice); + m_tzAxis->addInput(m_mouseTzXInput); + + // Mouse Wheel Y + m_mouseTzYInput->setAxis(Qt3DInput::QMouseDevice::WheelY); + m_mouseTzYInput->setSourceDevice(m_mouseDevice); + m_tzAxis->addInput(m_mouseTzYInput); + // Keyboard Pos Tx m_keyboardTxPosInput->setButtons(QVector<int>() << Qt::Key_Right); m_keyboardTxPosInput->setScale(1.0f); diff --git a/src/extras/defaults/qorbitcameracontroller.h b/src/extras/defaults/qorbitcameracontroller.h index e48e39142..7cb8b3eb7 100644 --- a/src/extras/defaults/qorbitcameracontroller.h +++ b/src/extras/defaults/qorbitcameracontroller.h @@ -37,8 +37,8 @@ #ifndef QT3DEXTRAS_QORBITCAMERACONTROLLER_H #define QT3DEXTRAS_QORBITCAMERACONTROLLER_H -#include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DCore/QEntity> +#include <Qt3DExtras/qt3dextras_global.h> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qorbitcameracontroller_p.h b/src/extras/defaults/qorbitcameracontroller_p.h index d207df712..8105d4375 100644 --- a/src/extras/defaults/qorbitcameracontroller_p.h +++ b/src/extras/defaults/qorbitcameracontroller_p.h @@ -48,9 +48,10 @@ // We mean it. // +#include <Qt3DExtras/qorbitcameracontroller.h> +#include <QtGui/QVector3D> + #include <Qt3DCore/private/qentity_p.h> -#include <QVector3D> -#include "qorbitcameracontroller.h" QT_BEGIN_NAMESPACE @@ -105,6 +106,8 @@ public: Qt3DInput::QAnalogAxisInput *m_mouseRxInput; Qt3DInput::QAnalogAxisInput *m_mouseRyInput; + Qt3DInput::QAnalogAxisInput *m_mouseTzXInput; + Qt3DInput::QAnalogAxisInput *m_mouseTzYInput; Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput; Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput; Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput; diff --git a/src/extras/defaults/qpervertexcolormaterial.cpp b/src/extras/defaults/qpervertexcolormaterial.cpp index 514f994c1..5619a71e7 100644 --- a/src/extras/defaults/qpervertexcolormaterial.cpp +++ b/src/extras/defaults/qpervertexcolormaterial.cpp @@ -39,6 +39,7 @@ #include "qpervertexcolormaterial.h" #include "qpervertexcolormaterial_p.h" + #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qmaterial.h> #include <Qt3DRender/qeffect.h> @@ -47,9 +48,9 @@ #include <Qt3DRender/qparameter.h> #include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qgraphicsapifilter.h> -#include <QUrl> -#include <QVector3D> -#include <QVector4D> +#include <QtCore/QUrl> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qpervertexcolormaterial.h b/src/extras/defaults/qpervertexcolormaterial.h index 485e2fe0e..8b64eb2d3 100644 --- a/src/extras/defaults/qpervertexcolormaterial.h +++ b/src/extras/defaults/qpervertexcolormaterial.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qmaterial.h> -#include <QColor> +#include <QtGui/QColor> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qphongalphamaterial.cpp b/src/extras/defaults/qphongalphamaterial.cpp index 7a05610c2..d7f054d71 100644 --- a/src/extras/defaults/qphongalphamaterial.cpp +++ b/src/extras/defaults/qphongalphamaterial.cpp @@ -39,6 +39,7 @@ #include "qphongalphamaterial.h" #include "qphongalphamaterial_p.h" + #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qmaterial.h> #include <Qt3DRender/qeffect.h> @@ -50,9 +51,9 @@ #include <Qt3DRender/qblendequation.h> #include <Qt3DRender/qblendequationarguments.h> #include <Qt3DRender/qnodepthmask.h> -#include <QUrl> -#include <QVector3D> -#include <QVector4D> +#include <QtCore/QUrl> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qphongalphamaterial.h b/src/extras/defaults/qphongalphamaterial.h index b67524ef7..667c5b283 100644 --- a/src/extras/defaults/qphongalphamaterial.h +++ b/src/extras/defaults/qphongalphamaterial.h @@ -41,10 +41,10 @@ #define QT3DEXTRAS_QPHONGALPHAMATERIAL_H #include <Qt3DExtras/qt3dextras_global.h> -#include <Qt3DRender/qmaterial.h> -#include <Qt3DRender/qblendequationarguments.h> #include <Qt3DRender/qblendequation.h> -#include <QColor> +#include <Qt3DRender/qblendequationarguments.h> +#include <Qt3DRender/qmaterial.h> +#include <QtGui/QColor> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qphongmaterial.cpp b/src/extras/defaults/qphongmaterial.cpp index c294984b6..449eb7351 100644 --- a/src/extras/defaults/qphongmaterial.cpp +++ b/src/extras/defaults/qphongmaterial.cpp @@ -39,6 +39,7 @@ #include "qphongmaterial.h" #include "qphongmaterial_p.h" + #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qmaterial.h> #include <Qt3DRender/qeffect.h> @@ -47,9 +48,10 @@ #include <Qt3DRender/qparameter.h> #include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qgraphicsapifilter.h> -#include <QUrl> -#include <QVector3D> -#include <QVector4D> +#include <QtCore/QUrl> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> + QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qphongmaterial.h b/src/extras/defaults/qphongmaterial.h index d4b8a0f0e..d78c8c2ff 100644 --- a/src/extras/defaults/qphongmaterial.h +++ b/src/extras/defaults/qphongmaterial.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qmaterial.h> -#include <QColor> +#include <QtGui/QColor> QT_BEGIN_NAMESPACE diff --git a/src/extras/defaults/qskyboxentity.cpp b/src/extras/defaults/qskyboxentity.cpp index 32e68e6fc..3c7b0dd4e 100644 --- a/src/extras/defaults/qskyboxentity.cpp +++ b/src/extras/defaults/qskyboxentity.cpp @@ -51,6 +51,7 @@ #include <Qt3DExtras/qcuboidmesh.h> #include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qgraphicsapifilter.h> +#include <Qt3DRender/qseamlesscubemap.h> #include <Qt3DRender/qshaderprogram.h> QT_BEGIN_NAMESPACE @@ -65,6 +66,7 @@ QSkyboxEntityPrivate::QSkyboxEntityPrivate() , m_effect(new QEffect()) , m_material(new QMaterial()) , m_skyboxTexture(new QTextureCubeMap()) + , m_loadedTexture(new QTextureLoader()) , m_gl3Shader(new QShaderProgram()) , m_gl2es2Shader(new QShaderProgram()) , m_gl2Technique(new QTechnique()) @@ -75,6 +77,7 @@ QSkyboxEntityPrivate::QSkyboxEntityPrivate() , m_es2RenderPass(new QRenderPass()) , m_gl3RenderPass(new QRenderPass()) , m_mesh(new QCuboidMesh()) + , m_gammaStrengthParameter(new QParameter(QStringLiteral("gammaStrength"), 0.0f)) , m_textureParameter(new QParameter(QStringLiteral("skyboxTexture"), m_skyboxTexture)) , m_posXImage(new QTextureImage()) , m_posYImage(new QTextureImage()) @@ -84,6 +87,7 @@ QSkyboxEntityPrivate::QSkyboxEntityPrivate() , m_negZImage(new QTextureImage()) , m_extension(QStringLiteral(".png")) { + m_loadedTexture->setGenerateMipMaps(false); } /*! @@ -127,9 +131,11 @@ void QSkyboxEntityPrivate::init() cullFront->setMode(QCullFace::Front); QDepthTest *depthTest = new QDepthTest(); depthTest->setDepthFunction(QDepthTest::LessOrEqual); + QSeamlessCubemap *seamlessCubemap = new QSeamlessCubemap(); m_gl3RenderPass->addRenderState(cullFront); m_gl3RenderPass->addRenderState(depthTest); + m_gl3RenderPass->addRenderState(seamlessCubemap); m_gl2RenderPass->addRenderState(cullFront); m_gl2RenderPass->addRenderState(depthTest); m_es2RenderPass->addRenderState(cullFront); @@ -144,6 +150,7 @@ void QSkyboxEntityPrivate::init() m_effect->addTechnique(m_es2Technique); m_material->setEffect(m_effect); + m_material->addParameter(m_gammaStrengthParameter); m_material->addParameter(m_textureParameter); m_mesh->setXYMeshResolution(QSize(2, 2)); @@ -151,11 +158,17 @@ void QSkyboxEntityPrivate::init() m_mesh->setYZMeshResolution(QSize(2, 2)); m_posXImage->setFace(QTextureCubeMap::CubeMapPositiveX); + m_posXImage->setMirrored(false); m_posYImage->setFace(QTextureCubeMap::CubeMapPositiveY); + m_posYImage->setMirrored(false); m_posZImage->setFace(QTextureCubeMap::CubeMapPositiveZ); + m_posZImage->setMirrored(false); m_negXImage->setFace(QTextureCubeMap::CubeMapNegativeX); + m_negXImage->setMirrored(false); m_negYImage->setFace(QTextureCubeMap::CubeMapNegativeY); + m_negYImage->setMirrored(false); m_negZImage->setFace(QTextureCubeMap::CubeMapNegativeZ); + m_negZImage->setMirrored(false); m_skyboxTexture->setMagnificationFilter(QTextureCubeMap::Linear); m_skyboxTexture->setMinificationFilter(QTextureCubeMap::Linear); @@ -178,12 +191,18 @@ void QSkyboxEntityPrivate::init() */ void QSkyboxEntityPrivate::reloadTexture() { - m_posXImage->setSource(QUrl(m_baseName + QStringLiteral("_posx") + m_extension)); - m_posYImage->setSource(QUrl(m_baseName + QStringLiteral("_posy") + m_extension)); - m_posZImage->setSource(QUrl(m_baseName + QStringLiteral("_posz") + m_extension)); - m_negXImage->setSource(QUrl(m_baseName + QStringLiteral("_negx") + m_extension)); - m_negYImage->setSource(QUrl(m_baseName + QStringLiteral("_negy") + m_extension)); - m_negZImage->setSource(QUrl(m_baseName + QStringLiteral("_negz") + m_extension)); + if (m_extension == QStringLiteral(".dds")) { + m_loadedTexture->setSource(QUrl(m_baseName + m_extension)); + m_textureParameter->setValue(QVariant::fromValue(m_loadedTexture)); + } else { + m_posXImage->setSource(QUrl(m_baseName + QStringLiteral("_posx") + m_extension)); + m_posYImage->setSource(QUrl(m_baseName + QStringLiteral("_posy") + m_extension)); + m_posZImage->setSource(QUrl(m_baseName + QStringLiteral("_posz") + m_extension)); + m_negXImage->setSource(QUrl(m_baseName + QStringLiteral("_negx") + m_extension)); + m_negYImage->setSource(QUrl(m_baseName + QStringLiteral("_negy") + m_extension)); + m_negZImage->setSource(QUrl(m_baseName + QStringLiteral("_negz") + m_extension)); + m_textureParameter->setValue(QVariant::fromValue(m_skyboxTexture)); + } } /*! @@ -232,7 +251,7 @@ void QSkyboxEntity::setBaseName(const QString &baseName) Q_D(QSkyboxEntity); if (baseName != d->m_baseName) { d->m_baseName = baseName; - emit sourceDirectoryChanged(baseName); + emit baseNameChanged(baseName); d->reloadTexture(); } } @@ -267,6 +286,29 @@ QString QSkyboxEntity::extension() const return d->m_extension; } +/*! + * Sets the gamma correction enable state to \a enabled. + * \since 5.9 + */ +void QSkyboxEntity::setGammaCorrectEnabled(bool enabled) +{ + Q_D(QSkyboxEntity); + if (enabled != isGammaCorrectEnabled()) { + d->m_gammaStrengthParameter->setValue(enabled ? 1.0f : 0.0f); + emit gammaCorrectEnabledChanged(enabled); + } +} + +/*! + * Returns true if gamma correction is enabled for this skybox. + * \since 5.9 + */ +bool QSkyboxEntity::isGammaCorrectEnabled() const +{ + Q_D(const QSkyboxEntity); + return !qFuzzyIsNull(d->m_gammaStrengthParameter->value().toFloat()); +} + } // namespace Qt3DExtras QT_END_NAMESPACE diff --git a/src/extras/defaults/qskyboxentity.h b/src/extras/defaults/qskyboxentity.h index a11d2f0a0..e49782dc2 100644 --- a/src/extras/defaults/qskyboxentity.h +++ b/src/extras/defaults/qskyboxentity.h @@ -52,19 +52,26 @@ class QSkyboxEntityPrivate; class QT3DEXTRASSHARED_EXPORT QSkyboxEntity : public Qt3DCore::QEntity { Q_OBJECT + Q_PROPERTY(QString baseName READ baseName WRITE setBaseName NOTIFY baseNameChanged) + Q_PROPERTY(QString extension READ extension WRITE setExtension NOTIFY extensionChanged) + Q_PROPERTY(bool gammaCorrect READ isGammaCorrectEnabled WRITE setGammaCorrectEnabled NOTIFY gammaCorrectEnabledChanged REVISION 9) public: explicit QSkyboxEntity(Qt3DCore::QNode *parent = nullptr); ~QSkyboxEntity(); - void setBaseName(const QString &path); QString baseName() const; + QString extension() const; + bool isGammaCorrectEnabled() const; +public Q_SLOTS: + void setBaseName(const QString &path); void setExtension(const QString &extension); - QString extension() const; + void setGammaCorrectEnabled(bool enabled); Q_SIGNALS: - void sourceDirectoryChanged(const QString &path); + void baseNameChanged(const QString &path); void extensionChanged(const QString &extension); + void gammaCorrectEnabledChanged(bool enabled); private: Q_DECLARE_PRIVATE(QSkyboxEntity) diff --git a/src/extras/defaults/qskyboxentity_p.h b/src/extras/defaults/qskyboxentity_p.h index effe97fce..88a40e2eb 100644 --- a/src/extras/defaults/qskyboxentity_p.h +++ b/src/extras/defaults/qskyboxentity_p.h @@ -51,8 +51,9 @@ // We mean it. // +#include <QtGui/QVector3D> + #include <Qt3DCore/private/qentity_p.h> -#include <QVector3D> QT_BEGIN_NAMESPACE @@ -60,6 +61,7 @@ namespace Qt3DRender { class QFilterKey; class QTextureCubeMap; +class QTextureLoader; class QShaderProgram; class QSkyboxEntity; class QTextureImage; @@ -87,6 +89,7 @@ class QSkyboxEntityPrivate : public Qt3DCore::QEntityPrivate Qt3DRender::QEffect *m_effect; Qt3DRender::QMaterial *m_material; Qt3DRender::QTextureCubeMap *m_skyboxTexture; + Qt3DRender::QTextureLoader *m_loadedTexture; Qt3DRender::QShaderProgram *m_gl3Shader; Qt3DRender::QShaderProgram *m_gl2es2Shader; Qt3DRender::QTechnique *m_gl2Technique; @@ -97,6 +100,7 @@ class QSkyboxEntityPrivate : public Qt3DCore::QEntityPrivate Qt3DRender::QRenderPass *m_es2RenderPass; Qt3DRender::QRenderPass *m_gl3RenderPass; QCuboidMesh *m_mesh; + Qt3DRender::QParameter *m_gammaStrengthParameter; Qt3DRender::QParameter *m_textureParameter; Qt3DRender::QTextureImage *m_posXImage; Qt3DRender:: QTextureImage *m_posYImage; diff --git a/src/extras/defaults/qt3dwindow.cpp b/src/extras/defaults/qt3dwindow.cpp index 06ff14212..635d81956 100644 --- a/src/extras/defaults/qt3dwindow.cpp +++ b/src/extras/defaults/qt3dwindow.cpp @@ -49,27 +49,25 @@ ****************************************************************************/ #include "qt3dwindow.h" +#include "qt3dwindow_p.h" +#include <Qt3DCore/qaspectengine.h> +#include <Qt3DCore/qentity.h> #include <Qt3DExtras/qforwardrenderer.h> #include <Qt3DRender/qrendersettings.h> #include <Qt3DRender/qrenderaspect.h> #include <Qt3DInput/qinputaspect.h> #include <Qt3DInput/qinputsettings.h> #include <Qt3DLogic/qlogicaspect.h> - -#include <Qt3DCore/qaspectengine.h> #include <Qt3DRender/qcamera.h> -#include <Qt3DCore/qentity.h> - #include <QtGui/qopenglcontext.h> QT_BEGIN_NAMESPACE namespace Qt3DExtras { -Qt3DWindow::Qt3DWindow(QScreen *screen) - : QWindow(screen) - , m_aspectEngine(new Qt3DCore::QAspectEngine) +Qt3DWindowPrivate::Qt3DWindowPrivate() + : m_aspectEngine(new Qt3DCore::QAspectEngine) , m_renderAspect(new Qt3DRender::QRenderAspect) , m_inputAspect(new Qt3DInput::QInputAspect) , m_logicAspect(new Qt3DLogic::QLogicAspect) @@ -81,6 +79,16 @@ Qt3DWindow::Qt3DWindow(QScreen *screen) , m_userRoot(nullptr) , m_initialized(false) { +} + +Qt3DWindow::Qt3DWindow(QScreen *screen) + : QWindow(*new Qt3DWindowPrivate(), nullptr) +{ + Q_D(Qt3DWindow); + + if (!d->parentWindow) + d->connectToScreen(screen ? screen : d->topLevelScreen.data()); + setSurfaceType(QSurface::OpenGLSurface); resize(1024, 768); @@ -99,74 +107,89 @@ Qt3DWindow::Qt3DWindow(QScreen *screen) format.setStencilBufferSize(8); setFormat(format); QSurfaceFormat::setDefaultFormat(format); - create(); - m_aspectEngine->registerAspect(m_renderAspect); - m_aspectEngine->registerAspect(m_inputAspect); - m_aspectEngine->registerAspect(m_logicAspect); + d->m_aspectEngine->registerAspect(d->m_renderAspect); + d->m_aspectEngine->registerAspect(d->m_inputAspect); + d->m_aspectEngine->registerAspect(d->m_logicAspect); - m_defaultCamera->setParent(m_root); - m_forwardRenderer->setCamera(m_defaultCamera); - m_forwardRenderer->setSurface(this); - m_renderSettings->setActiveFrameGraph(m_forwardRenderer); - m_inputSettings->setEventSource(this); + d->m_defaultCamera->setParent(d->m_root); + d->m_forwardRenderer->setCamera(d->m_defaultCamera); + d->m_forwardRenderer->setSurface(this); + d->m_renderSettings->setActiveFrameGraph(d->m_forwardRenderer); + d->m_inputSettings->setEventSource(this); } Qt3DWindow::~Qt3DWindow() { + Q_D(Qt3DWindow); + delete d->m_aspectEngine; } void Qt3DWindow::registerAspect(Qt3DCore::QAbstractAspect *aspect) { Q_ASSERT(!isVisible()); - m_aspectEngine->registerAspect(aspect); + Q_D(Qt3DWindow); + d->m_aspectEngine->registerAspect(aspect); } void Qt3DWindow::registerAspect(const QString &name) { Q_ASSERT(!isVisible()); - m_aspectEngine->registerAspect(name); + Q_D(Qt3DWindow); + d->m_aspectEngine->registerAspect(name); } void Qt3DWindow::setRootEntity(Qt3DCore::QEntity *root) { - if (m_userRoot != root) { - if (m_userRoot != nullptr) - m_userRoot->setParent(static_cast<Qt3DCore::QNode*>(nullptr)); + Q_D(Qt3DWindow); + if (d->m_userRoot != root) { + if (d->m_userRoot != nullptr) + d->m_userRoot->setParent(static_cast<Qt3DCore::QNode*>(nullptr)); if (root != nullptr) - root->setParent(m_root); - m_userRoot = root; + root->setParent(d->m_root); + d->m_userRoot = root; } } void Qt3DWindow::setActiveFrameGraph(Qt3DRender::QFrameGraphNode *activeFrameGraph) { - m_renderSettings->setActiveFrameGraph(activeFrameGraph); + Q_D(Qt3DWindow); + d->m_renderSettings->setActiveFrameGraph(activeFrameGraph); } Qt3DRender::QFrameGraphNode *Qt3DWindow::activeFrameGraph() const { - return m_renderSettings->activeFrameGraph(); + Q_D(const Qt3DWindow); + return d->m_renderSettings->activeFrameGraph(); } Qt3DExtras::QForwardRenderer *Qt3DWindow::defaultFrameGraph() const { - return m_forwardRenderer; + Q_D(const Qt3DWindow); + return d->m_forwardRenderer; } Qt3DRender::QCamera *Qt3DWindow::camera() const { - return m_defaultCamera; + Q_D(const Qt3DWindow); + return d->m_defaultCamera; +} + +Qt3DRender::QRenderSettings *Qt3DWindow::renderSettings() const +{ + Q_D(const Qt3DWindow); + return d->m_renderSettings; } void Qt3DWindow::showEvent(QShowEvent *e) { - if (!m_initialized) { - m_root->addComponent(m_renderSettings); - m_root->addComponent(m_inputSettings); - m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr(m_root)); + Q_D(Qt3DWindow); + if (!d->m_initialized) { + d->m_root->addComponent(d->m_renderSettings); + d->m_root->addComponent(d->m_inputSettings); + d->m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr(d->m_root)); - m_initialized = true; + d->m_initialized = true; } QWindow::showEvent(e); @@ -174,7 +197,8 @@ void Qt3DWindow::showEvent(QShowEvent *e) void Qt3DWindow::resizeEvent(QResizeEvent *) { - m_defaultCamera->setAspectRatio(float(width()) / float(height())); + Q_D(Qt3DWindow); + d->m_defaultCamera->setAspectRatio(float(width()) / float(height())); } } // Qt3DExtras diff --git a/src/extras/defaults/qt3dwindow.h b/src/extras/defaults/qt3dwindow.h index 109e1be75..6ec1bbf8b 100644 --- a/src/extras/defaults/qt3dwindow.h +++ b/src/extras/defaults/qt3dwindow.h @@ -51,8 +51,8 @@ #ifndef QT3DWINDOW_H #define QT3DWINDOW_H -#include <QWindow> #include <Qt3DExtras/qt3dextras_global.h> +#include <QtGui/QWindow> QT_BEGIN_NAMESPACE @@ -84,6 +84,8 @@ class QLogicAspect; namespace Qt3DExtras { +class Qt3DWindowPrivate; + class QT3DEXTRASSHARED_EXPORT Qt3DWindow : public QWindow { Q_OBJECT @@ -101,6 +103,7 @@ public: Qt3DExtras::QForwardRenderer *defaultFrameGraph() const; Qt3DRender::QCamera *camera() const; + Qt3DRender::QRenderSettings *renderSettings() const; public Q_SLOTS: @@ -111,28 +114,7 @@ protected: void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; private: - QScopedPointer<Qt3DCore::QAspectEngine> m_aspectEngine; - - // Aspects - Qt3DRender::QRenderAspect *m_renderAspect; - Qt3DInput::QInputAspect *m_inputAspect; - Qt3DLogic::QLogicAspect *m_logicAspect; - - // Renderer configuration - Qt3DRender::QRenderSettings *m_renderSettings; - Qt3DExtras::QForwardRenderer *m_forwardRenderer; - Qt3DRender::QCamera *m_defaultCamera; - - // Input configuration - Qt3DInput::QInputSettings *m_inputSettings; - - // Logic configuration - - // Scene - Qt3DCore::QEntity *m_root; - Qt3DCore::QEntity *m_userRoot; - - bool m_initialized; + Q_DECLARE_PRIVATE(Qt3DWindow) }; } // Qt3DExtras diff --git a/src/extras/animations/qmorphtarget_p.h b/src/extras/defaults/qt3dwindow_p.h index 7d42f8eb4..731d5298e 100644 --- a/src/extras/animations/qmorphtarget_p.h +++ b/src/extras/defaults/qt3dwindow_p.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. ** @@ -34,8 +34,8 @@ ** ****************************************************************************/ -#ifndef QT3DEXTRAS_QMORPHTARGET_P_H -#define QT3DEXTRAS_QMORPHTARGET_P_H +#ifndef QT3DWINDOW_P_H +#define QT3DWINDOW_P_H // // W A R N I N G @@ -48,29 +48,45 @@ // We mean it. // -#include <Qt3DExtras/qmorphtarget.h> - -#include <private/qobject_p.h> +#include <QtGui/private/qwindow_p.h> QT_BEGIN_NAMESPACE namespace Qt3DExtras { -class QMorphTargetPrivate : public QObjectPrivate +class Qt3DWindowPrivate : public QWindowPrivate { public: - QMorphTargetPrivate(); + Qt3DWindowPrivate(); + + Qt3DCore::QAspectEngine *m_aspectEngine; + + // Aspects + Qt3DRender::QRenderAspect *m_renderAspect; + Qt3DInput::QInputAspect *m_inputAspect; + Qt3DLogic::QLogicAspect *m_logicAspect; + + // Renderer configuration + Qt3DRender::QRenderSettings *m_renderSettings; + Qt3DExtras::QForwardRenderer *m_forwardRenderer; + Qt3DRender::QCamera *m_defaultCamera; + + // Input configuration + Qt3DInput::QInputSettings *m_inputSettings; + + // Logic configuration - void updateAttributeNames(); + // Scene + Qt3DCore::QEntity *m_root; + Qt3DCore::QEntity *m_userRoot; - QStringList m_attributeNames; - QVector<Qt3DRender::QAttribute *> m_targetAttributes; + bool m_initialized; - Q_DECLARE_PUBLIC(QMorphTarget) + Q_DECLARE_PUBLIC(Qt3DWindow) }; } // Qt3DExtras QT_END_NAMESPACE -#endif // QT3DEXTRAS_QMORPHTARGET_P_H +#endif // QT3DWINDOW_P_H diff --git a/src/extras/defaults/qtexturedmetalroughmaterial.cpp b/src/extras/defaults/qtexturedmetalroughmaterial.cpp new file mode 100644 index 000000000..e09517866 --- /dev/null +++ b/src/extras/defaults/qtexturedmetalroughmaterial.cpp @@ -0,0 +1,373 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtexturedmetalroughmaterial.h" +#include "qtexturedmetalroughmaterial_p.h" +#include <Qt3DRender/qfilterkey.h> +#include <Qt3DRender/qmaterial.h> +#include <Qt3DRender/qeffect.h> +#include <Qt3DRender/qtexture.h> +#include <Qt3DRender/qtechnique.h> +#include <Qt3DRender/qshaderprogram.h> +#include <Qt3DRender/qparameter.h> +#include <Qt3DRender/qrenderpass.h> +#include <Qt3DRender/qgraphicsapifilter.h> +#include <QUrl> +#include <QVector3D> +#include <QVector4D> + +QT_BEGIN_NAMESPACE + +using namespace Qt3DRender; + +namespace Qt3DExtras { + +QTexturedMetalRoughMaterialPrivate::QTexturedMetalRoughMaterialPrivate() + : QMaterialPrivate() + , m_baseColorTexture(new QTexture2D()) + , m_metalnessTexture(new QTexture2D()) + , m_roughnessTexture(new QTexture2D()) + , m_ambientOcclusionTexture(new QTexture2D()) + , m_normalTexture(new QTexture2D()) + , m_environmentIrradianceTexture(new QTexture2D()) + , m_environmentSpecularTexture(new QTexture2D()) + , m_baseColorParameter(new QParameter(QStringLiteral("baseColorMap"), m_baseColorTexture)) + , m_metalnessParameter(new QParameter(QStringLiteral("metalnessMap"), m_metalnessTexture)) + , m_roughnessParameter(new QParameter(QStringLiteral("roughnessMap"), m_roughnessTexture)) + , m_ambientOcclusionParameter(new QParameter(QStringLiteral("ambientOcclusionMap"), m_ambientOcclusionTexture)) + , m_normalParameter(new QParameter(QStringLiteral("normalMap"), m_normalTexture)) + , m_environmentIrradianceParameter(new QParameter(QStringLiteral("envLight.irradiance"), m_environmentIrradianceTexture)) + , m_environmentSpecularParameter(new QParameter(QStringLiteral("envLight.specular"), m_environmentSpecularTexture)) + , m_metalRoughEffect(new QEffect()) + , m_metalRoughGL3Technique(new QTechnique()) + , m_metalRoughGL3RenderPass(new QRenderPass()) + , m_metalRoughGL3Shader(new QShaderProgram()) + , m_filterKey(new QFilterKey) +{ + m_baseColorTexture->setMagnificationFilter(QAbstractTexture::Linear); + m_baseColorTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear); + m_baseColorTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat)); + m_baseColorTexture->setGenerateMipMaps(true); + m_baseColorTexture->setMaximumAnisotropy(16.0f); + + m_metalnessTexture->setMagnificationFilter(QAbstractTexture::Linear); + m_metalnessTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear); + m_metalnessTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat)); + m_metalnessTexture->setGenerateMipMaps(true); + m_metalnessTexture->setMaximumAnisotropy(16.0f); + + m_roughnessTexture->setMagnificationFilter(QAbstractTexture::Linear); + m_roughnessTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear); + m_roughnessTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat)); + m_roughnessTexture->setGenerateMipMaps(true); + m_roughnessTexture->setMaximumAnisotropy(16.0f); + + m_ambientOcclusionTexture->setMagnificationFilter(QAbstractTexture::Linear); + m_ambientOcclusionTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear); + m_ambientOcclusionTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat)); + m_ambientOcclusionTexture->setGenerateMipMaps(true); + m_ambientOcclusionTexture->setMaximumAnisotropy(16.0f); + + m_normalTexture->setMagnificationFilter(QAbstractTexture::Linear); + m_normalTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear); + m_normalTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat)); + m_normalTexture->setGenerateMipMaps(true); + m_normalTexture->setMaximumAnisotropy(16.0f); + + m_environmentIrradianceTexture->setMagnificationFilter(QAbstractTexture::Linear); + m_environmentIrradianceTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear); + m_environmentIrradianceTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat)); + m_environmentIrradianceTexture->setGenerateMipMaps(true); + m_environmentIrradianceTexture->setMaximumAnisotropy(16.0f); + + m_environmentSpecularTexture->setMagnificationFilter(QAbstractTexture::Linear); + m_environmentSpecularTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear); + m_environmentSpecularTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat)); + m_environmentSpecularTexture->setGenerateMipMaps(true); + m_environmentSpecularTexture->setMaximumAnisotropy(16.0f); +} + +void QTexturedMetalRoughMaterialPrivate::init() +{ + connect(m_baseColorParameter, &Qt3DRender::QParameter::valueChanged, + this, &QTexturedMetalRoughMaterialPrivate::handleBaseColorChanged); + connect(m_metalnessParameter, &Qt3DRender::QParameter::valueChanged, + this, &QTexturedMetalRoughMaterialPrivate::handleMetallicChanged); + connect(m_roughnessParameter, &Qt3DRender::QParameter::valueChanged, + this, &QTexturedMetalRoughMaterialPrivate::handleRoughnessChanged); + connect(m_ambientOcclusionParameter, &Qt3DRender::QParameter::valueChanged, + this, &QTexturedMetalRoughMaterialPrivate::handleAmbientOcclusionChanged); + connect(m_normalParameter, &Qt3DRender::QParameter::valueChanged, + this, &QTexturedMetalRoughMaterialPrivate::handleNormalChanged); + + m_metalRoughGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalrough.vert")))); + m_metalRoughGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/metalrough.frag")))); + + m_metalRoughGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + m_metalRoughGL3Technique->graphicsApiFilter()->setMajorVersion(3); + m_metalRoughGL3Technique->graphicsApiFilter()->setMinorVersion(1); + m_metalRoughGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); + + Q_Q(QTexturedMetalRoughMaterial); + m_filterKey->setParent(q); + m_filterKey->setName(QStringLiteral("renderingStyle")); + m_filterKey->setValue(QStringLiteral("forward")); + + m_metalRoughGL3Technique->addFilterKey(m_filterKey); + m_metalRoughGL3RenderPass->setShaderProgram(m_metalRoughGL3Shader); + m_metalRoughGL3Technique->addRenderPass(m_metalRoughGL3RenderPass); + m_metalRoughEffect->addTechnique(m_metalRoughGL3Technique); + + m_metalRoughEffect->addParameter(m_baseColorParameter); + m_metalRoughEffect->addParameter(m_metalnessParameter); + m_metalRoughEffect->addParameter(m_roughnessParameter); + m_metalRoughEffect->addParameter(m_ambientOcclusionParameter); + m_metalRoughEffect->addParameter(m_normalParameter); + + // Note that even though those parameters are not exposed in the API, + // they need to be kept around for now due to a bug in some drivers/GPUs + // (at least Intel) which cause issues with unbound textures even if you + // don't try to sample from them. + // Can probably go away once we generate the shaders and deal in this + // case in a better way. + m_metalRoughEffect->addParameter(m_environmentIrradianceParameter); + m_metalRoughEffect->addParameter(m_environmentSpecularParameter); + + q->setEffect(m_metalRoughEffect); +} + +void QTexturedMetalRoughMaterialPrivate::handleBaseColorChanged(const QVariant &var) +{ + Q_Q(QTexturedMetalRoughMaterial); + emit q->baseColorChanged(var.value<QAbstractTexture *>()); +} + +void QTexturedMetalRoughMaterialPrivate::handleMetallicChanged(const QVariant &var) +{ + Q_Q(QTexturedMetalRoughMaterial); + emit q->metalnessChanged(var.value<QAbstractTexture *>()); +} +void QTexturedMetalRoughMaterialPrivate::handleRoughnessChanged(const QVariant &var) +{ + Q_Q(QTexturedMetalRoughMaterial); + emit q->roughnessChanged(var.value<QAbstractTexture *>()); +} +void QTexturedMetalRoughMaterialPrivate::handleAmbientOcclusionChanged(const QVariant &var) +{ + Q_Q(QTexturedMetalRoughMaterial); + emit q->ambientOcclusionChanged(var.value<QAbstractTexture *>()); +} + +void QTexturedMetalRoughMaterialPrivate::handleNormalChanged(const QVariant &var) +{ + Q_Q(QTexturedMetalRoughMaterial); + emit q->normalChanged(var.value<QAbstractTexture *>()); +} + +/*! + \class Qt3DExtras::QTexturedMetalRoughMaterial + \brief The QTexturedMetalRoughMaterial provides a default implementation of PBR + lighting, environment maps and bump effect where the components are read from texture + maps (including normal maps). + \inmodule Qt3DExtras + \since 5.9 + \inherits Qt3DRender::QMaterial + + This material uses an effect with a single render pass approach and performs per fragment + lighting. Techniques are provided for OpenGL 3 only. +*/ + +/*! + Constructs a new QTexturedMetalRoughMaterial instance with parent object \a parent. +*/ +QTexturedMetalRoughMaterial::QTexturedMetalRoughMaterial(QNode *parent) + : QMaterial(*new QTexturedMetalRoughMaterialPrivate, parent) +{ + Q_D(QTexturedMetalRoughMaterial); + d->init(); +} + +/*! \internal */ +QTexturedMetalRoughMaterial::QTexturedMetalRoughMaterial(QTexturedMetalRoughMaterialPrivate &dd, QNode *parent) + : QMaterial(dd, parent) +{ + Q_D(QTexturedMetalRoughMaterial); + d->init(); +} + +/*! + Destroys the QTexturedMetalRoughMaterial instance. +*/ +QTexturedMetalRoughMaterial::~QTexturedMetalRoughMaterial() +{ +} + +/*! + \property QTexturedMetalRoughMaterial::baseColor + + Holds the current base color map texture. + + By default, the base color texture has the following properties: + + \list + \li Linear minification and magnification filters + \li Linear mipmap with mipmapping enabled + \li Repeat wrap mode + \li Maximum anisotropy of 16.0 + \endlist +*/ +QAbstractTexture *QTexturedMetalRoughMaterial::baseColor() const +{ + Q_D(const QTexturedMetalRoughMaterial); + return d->m_baseColorParameter->value().value<QAbstractTexture *>(); +} + +/*! + \property QTexturedMetalRoughMaterial::metalness + + Holds the current metalness map texture. + + By default, the metalness texture has the following properties: + + \list + \li Linear minification and magnification filters + \li Linear mipmap with mipmapping enabled + \li Repeat wrap mode + \li Maximum anisotropy of 16.0 + \endlist +*/ +QAbstractTexture *QTexturedMetalRoughMaterial::metalness() const +{ + Q_D(const QTexturedMetalRoughMaterial); + return d->m_metalnessParameter->value().value<QAbstractTexture *>(); +} + +/*! + \property QTexturedMetalRoughMaterial::roughness + + Holds the current roughness map texture. + + By default, the roughness texture has the following properties: + + \list + \li Linear minification and magnification filters + \li Linear mipmap with mipmapping enabled + \li Repeat wrap mode + \li Maximum anisotropy of 16.0 + \endlist +*/ +QAbstractTexture *QTexturedMetalRoughMaterial::roughness() const +{ + Q_D(const QTexturedMetalRoughMaterial); + return d->m_roughnessParameter->value().value<QAbstractTexture *>(); +} + +/*! + \property QTexturedMetalRoughMaterial::ambientOcclusion + + Holds the current ambient occlusion map texture. + + By default, the ambient occlusion texture has the following properties: + + \list + \li Linear minification and magnification filters + \li Linear mipmap with mipmapping enabled + \li Repeat wrap mode + \li Maximum anisotropy of 16.0 + \endlist +*/ +QAbstractTexture *QTexturedMetalRoughMaterial::ambientOcclusion() const +{ + Q_D(const QTexturedMetalRoughMaterial); + return d->m_ambientOcclusionParameter->value().value<QAbstractTexture *>(); +} + +/*! + \property QTexturedMetalRoughMaterial::normal + + Holds the current normal map texture. + + By default, the normal texture has the following properties: + + \list + \li Linear minification and magnification filters + \li Repeat wrap mode + \li Maximum anisotropy of 16.0 + \endlist +*/ +QAbstractTexture *QTexturedMetalRoughMaterial::normal() const +{ + Q_D(const QTexturedMetalRoughMaterial); + return d->m_normalParameter->value().value<QAbstractTexture *>(); +} + + +void QTexturedMetalRoughMaterial::setBaseColor(QAbstractTexture *baseColor) +{ + Q_D(QTexturedMetalRoughMaterial); + d->m_baseColorParameter->setValue(QVariant::fromValue(baseColor)); +} + +void QTexturedMetalRoughMaterial::setMetalness(QAbstractTexture *metalness) +{ + Q_D(QTexturedMetalRoughMaterial); + d->m_metalnessParameter->setValue(QVariant::fromValue(metalness)); +} + +void QTexturedMetalRoughMaterial::setRoughness(QAbstractTexture *roughness) +{ + Q_D(QTexturedMetalRoughMaterial); + d->m_roughnessParameter->setValue(QVariant::fromValue(roughness)); +} + +void QTexturedMetalRoughMaterial::setAmbientOcclusion(QAbstractTexture *ambientOcclusion) +{ + Q_D(QTexturedMetalRoughMaterial); + d->m_ambientOcclusionParameter->setValue(QVariant::fromValue(ambientOcclusion)); +} + +void QTexturedMetalRoughMaterial::setNormal(QAbstractTexture *normal) +{ + Q_D(QTexturedMetalRoughMaterial); + d->m_normalParameter->setValue(QVariant::fromValue(normal)); +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/defaults/qtexturedmetalroughmaterial.h b/src/extras/defaults/qtexturedmetalroughmaterial.h new file mode 100644 index 000000000..62755a781 --- /dev/null +++ b/src/extras/defaults/qtexturedmetalroughmaterial.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXTUREDMETALROUGHMATERIAL_H +#define QT3DEXTRAS_QTEXTUREDMETALROUGHMATERIAL_H + +#include <Qt3DExtras/qt3dextras_global.h> +#include <Qt3DRender/qmaterial.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QTexturedMetalRoughMaterialPrivate; + +class QT3DEXTRASSHARED_EXPORT QTexturedMetalRoughMaterial : public Qt3DRender::QMaterial +{ + Q_OBJECT + Q_PROPERTY(Qt3DRender::QAbstractTexture *baseColor READ baseColor WRITE setBaseColor NOTIFY baseColorChanged) + Q_PROPERTY(Qt3DRender::QAbstractTexture *metalness READ metalness WRITE setMetalness NOTIFY metalnessChanged) + Q_PROPERTY(Qt3DRender::QAbstractTexture *roughness READ roughness WRITE setRoughness NOTIFY roughnessChanged) + Q_PROPERTY(Qt3DRender::QAbstractTexture *ambientOcclusion READ ambientOcclusion WRITE setAmbientOcclusion NOTIFY ambientOcclusionChanged) + Q_PROPERTY(Qt3DRender::QAbstractTexture *normal READ normal WRITE setNormal NOTIFY normalChanged) + +public: + explicit QTexturedMetalRoughMaterial(Qt3DCore::QNode *parent = nullptr); + ~QTexturedMetalRoughMaterial(); + + Qt3DRender::QAbstractTexture *baseColor() const; + Qt3DRender::QAbstractTexture *metalness() const; + Qt3DRender::QAbstractTexture *roughness() const; + Qt3DRender::QAbstractTexture *ambientOcclusion() const; + Qt3DRender::QAbstractTexture *normal() const; + +public Q_SLOTS: + void setBaseColor(Qt3DRender::QAbstractTexture *baseColor); + void setMetalness(Qt3DRender::QAbstractTexture *metalness); + void setRoughness(Qt3DRender::QAbstractTexture *roughness); + void setAmbientOcclusion(Qt3DRender::QAbstractTexture *ambientOcclusion); + void setNormal(Qt3DRender::QAbstractTexture *normal); + +Q_SIGNALS: + void baseColorChanged(Qt3DRender::QAbstractTexture *baseColor); + void metalnessChanged(Qt3DRender::QAbstractTexture *metalness); + void roughnessChanged(Qt3DRender::QAbstractTexture *roughness); + void ambientOcclusionChanged(Qt3DRender::QAbstractTexture *ambientOcclusion); + void normalChanged(Qt3DRender::QAbstractTexture *normal); + +protected: + explicit QTexturedMetalRoughMaterial(QTexturedMetalRoughMaterialPrivate &dd, Qt3DCore::QNode *parent = nullptr); + +private: + Q_DECLARE_PRIVATE(QTexturedMetalRoughMaterial) +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXTUREDMETALROUGHMATERIAL_H diff --git a/src/extras/defaults/qtexturedmetalroughmaterial_p.h b/src/extras/defaults/qtexturedmetalroughmaterial_p.h new file mode 100644 index 000000000..8972726e5 --- /dev/null +++ b/src/extras/defaults/qtexturedmetalroughmaterial_p.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXTUREDMETALROUGHMATERIAL_P_H +#define QT3DEXTRAS_QTEXTUREDMETALROUGHMATERIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/private/qmaterial_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QFilterKey; +class QEffect; +class QAbstractTexture; +class QTechnique; +class QParameter; +class QShaderProgram; +class QRenderPass; + +} // namespace Qt3DRender + +namespace Qt3DExtras { + +class QTexturedMetalRoughMaterial; + +class QTexturedMetalRoughMaterialPrivate : public Qt3DRender::QMaterialPrivate +{ +public: + QTexturedMetalRoughMaterialPrivate(); + + void init(); + + void handleBaseColorChanged(const QVariant &var); + void handleMetallicChanged(const QVariant &var); + void handleRoughnessChanged(const QVariant &var); + void handleAmbientOcclusionChanged(const QVariant &var); + void handleNormalChanged(const QVariant &var); + + Qt3DRender::QAbstractTexture *m_baseColorTexture; + Qt3DRender::QAbstractTexture *m_metalnessTexture; + Qt3DRender::QAbstractTexture *m_roughnessTexture; + Qt3DRender::QAbstractTexture *m_ambientOcclusionTexture; + Qt3DRender::QAbstractTexture *m_normalTexture; + Qt3DRender::QAbstractTexture *m_environmentIrradianceTexture; + Qt3DRender::QAbstractTexture *m_environmentSpecularTexture; + Qt3DRender::QParameter *m_baseColorParameter; + Qt3DRender::QParameter *m_metalnessParameter; + Qt3DRender::QParameter *m_roughnessParameter; + Qt3DRender::QParameter *m_ambientOcclusionParameter; + Qt3DRender::QParameter *m_normalParameter; + Qt3DRender::QParameter *m_environmentIrradianceParameter; + Qt3DRender::QParameter *m_environmentSpecularParameter; + Qt3DRender::QEffect *m_metalRoughEffect; + Qt3DRender::QTechnique *m_metalRoughGL3Technique; + Qt3DRender::QRenderPass *m_metalRoughGL3RenderPass; + Qt3DRender::QShaderProgram *m_metalRoughGL3Shader; + Qt3DRender::QFilterKey *m_filterKey; + + Q_DECLARE_PUBLIC(QTexturedMetalRoughMaterial) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXTUREDMETALROUGHMATERIAL_P_H + diff --git a/src/extras/defaults/qtexturematerial.cpp b/src/extras/defaults/qtexturematerial.cpp new file mode 100644 index 000000000..0038dd44a --- /dev/null +++ b/src/extras/defaults/qtexturematerial.cpp @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtexturematerial.h" +#include "qtexturematerial_p.h" +#include <Qt3DRender/qfilterkey.h> +#include <Qt3DRender/qmaterial.h> +#include <Qt3DRender/qeffect.h> +#include <Qt3DRender/qtexture.h> +#include <Qt3DRender/qtechnique.h> +#include <Qt3DRender/qshaderprogram.h> +#include <Qt3DRender/qparameter.h> +#include <Qt3DRender/qrenderpass.h> +#include <Qt3DRender/qgraphicsapifilter.h> +#include <QUrl> + +QT_BEGIN_NAMESPACE + +using namespace Qt3DRender; + +namespace Qt3DExtras { + +QTextureMaterialPrivate::QTextureMaterialPrivate() + : QMaterialPrivate() + , m_textureEffect(new QEffect) + , m_textureParameter(new QParameter(QStringLiteral("diffuseTexture"), new QTexture2D)) + , m_textureOffsetParameter(new QParameter(QStringLiteral("texCoordOffset"), QVector2D(0.0f, 0.0f))) + , m_textureGL3Technique(new QTechnique) + , m_textureGL2Technique(new QTechnique) + , m_textureES2Technique(new QTechnique) + , m_textureGL3RenderPass(new QRenderPass) + , m_textureGL2RenderPass(new QRenderPass) + , m_textureES2RenderPass(new QRenderPass) + , m_textureGL3Shader(new QShaderProgram) + , m_textureGL2ES2Shader(new QShaderProgram) + , m_filterKey(new QFilterKey) +{ +} + +void QTextureMaterialPrivate::init() +{ + connect(m_textureParameter, &Qt3DRender::QParameter::valueChanged, + this, &QTextureMaterialPrivate::handleTextureChanged); + connect(m_textureOffsetParameter, &Qt3DRender::QParameter::valueChanged, + this, &QTextureMaterialPrivate::handleTextureOffsetChanged); + + m_textureGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/unlittexture.vert")))); + m_textureGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/unlittexture.frag")))); + m_textureGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/unlittexture.vert")))); + m_textureGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/unlittexture.frag")))); + + m_textureGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + m_textureGL3Technique->graphicsApiFilter()->setMajorVersion(3); + m_textureGL3Technique->graphicsApiFilter()->setMinorVersion(1); + m_textureGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); + + m_textureGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + m_textureGL2Technique->graphicsApiFilter()->setMajorVersion(2); + m_textureGL2Technique->graphicsApiFilter()->setMinorVersion(0); + m_textureGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile); + + m_textureES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES); + m_textureES2Technique->graphicsApiFilter()->setMajorVersion(2); + m_textureES2Technique->graphicsApiFilter()->setMinorVersion(0); + m_textureES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile); + + Q_Q(QTextureMaterial); + m_filterKey->setParent(q); + m_filterKey->setName(QStringLiteral("renderingStyle")); + m_filterKey->setValue(QStringLiteral("forward")); + + m_textureGL3Technique->addFilterKey(m_filterKey); + m_textureGL2Technique->addFilterKey(m_filterKey); + m_textureES2Technique->addFilterKey(m_filterKey); + + m_textureGL3RenderPass->setShaderProgram(m_textureGL3Shader); + m_textureGL2RenderPass->setShaderProgram(m_textureGL2ES2Shader); + m_textureES2RenderPass->setShaderProgram(m_textureGL2ES2Shader); + + m_textureGL3Technique->addRenderPass(m_textureGL3RenderPass); + m_textureGL2Technique->addRenderPass(m_textureGL2RenderPass); + m_textureES2Technique->addRenderPass(m_textureES2RenderPass); + + m_textureEffect->addTechnique(m_textureGL3Technique); + m_textureEffect->addTechnique(m_textureGL2Technique); + m_textureEffect->addTechnique(m_textureES2Technique); + + m_textureEffect->addParameter(m_textureParameter); + m_textureEffect->addParameter(m_textureOffsetParameter); + + q->setEffect(m_textureEffect); +} + +void QTextureMaterialPrivate::handleTextureChanged(const QVariant &var) +{ + Q_Q(QTextureMaterial); + emit q->textureChanged(var.value<QAbstractTexture *>()); +} + +void QTextureMaterialPrivate::handleTextureOffsetChanged(const QVariant &var) +{ + Q_Q(QTextureMaterial); + emit q->textureOffsetChanged(var.value<QVector2D>()); +} + +/*! + \class Qt3DExtras::QTextureMaterial + \brief The QTextureMaterial provides a default implementation of a simple unlit + texture material. + \inmodule Qt3DExtras + \since 5.9 + \inherits Qt3DRender::QMaterial + + This material uses an effect with a single render pass approach. Techniques are provided + for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2. +*/ + +/*! + Constructs a new QTextureMaterial instance with parent object \a parent. + */ +QTextureMaterial::QTextureMaterial(QNode *parent) + : QMaterial(*new QTextureMaterialPrivate, parent) +{ + Q_D(QTextureMaterial); + d->init(); +} + +/*! + Destroys the QTextureMaterial instance. +*/ +QTextureMaterial::~QTextureMaterial() +{ +} + +/*! + \property QTextureMaterial::texture + + Holds the current texture used by the material. +*/ +QAbstractTexture *QTextureMaterial::texture() const +{ + Q_D(const QTextureMaterial); + return d->m_textureParameter->value().value<QAbstractTexture *>(); +} + +/*! + \property QTextureMaterial::textureOffset + + Holds the current texture offset. It is applied to texture + coordinates at render time. Defaults to (0.0, 0.0). + +*/ +QVector2D QTextureMaterial::textureOffset() const +{ + Q_D(const QTextureMaterial); + return d->m_textureOffsetParameter->value().value<QVector2D>(); +} + +void QTextureMaterial::setTexture(QAbstractTexture *texture) +{ + Q_D(QTextureMaterial); + d->m_textureParameter->setValue(QVariant::fromValue(texture)); +} + +void QTextureMaterial::setTextureOffset(QVector2D textureOffset) +{ + Q_D(QTextureMaterial); + d->m_textureOffsetParameter->setValue(QVariant::fromValue(textureOffset)); +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/defaults/qtexturematerial.h b/src/extras/defaults/qtexturematerial.h new file mode 100644 index 000000000..3101b9a1b --- /dev/null +++ b/src/extras/defaults/qtexturematerial.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXTUREMATERIAL_H +#define QT3DEXTRAS_QTEXTUREMATERIAL_H + +#include <Qt3DExtras/qt3dextras_global.h> +#include <Qt3DRender/qmaterial.h> +#include <QVector2D> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QAbstractTexture; + +} // namespace Qt3DRender + +namespace Qt3DExtras { + +class QTextureMaterialPrivate; + +class QT3DEXTRASSHARED_EXPORT QTextureMaterial : public Qt3DRender::QMaterial +{ + Q_OBJECT + Q_PROPERTY(Qt3DRender::QAbstractTexture *texture READ texture WRITE setTexture NOTIFY textureChanged) + Q_PROPERTY(QVector2D textureOffset READ textureOffset WRITE setTextureOffset NOTIFY textureOffsetChanged) +public: + explicit QTextureMaterial(Qt3DCore::QNode *parent = nullptr); + ~QTextureMaterial(); + + Qt3DRender::QAbstractTexture *texture() const; + QVector2D textureOffset() const; + +public Q_SLOTS: + void setTexture(Qt3DRender::QAbstractTexture *texture); + void setTextureOffset(QVector2D textureOffset); + +Q_SIGNALS: + void textureChanged(Qt3DRender::QAbstractTexture *texture); + void textureOffsetChanged(QVector2D textureOffset); + +private: + Q_DECLARE_PRIVATE(QTextureMaterial) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXTUREMATERIAL_H diff --git a/src/extras/defaults/qtexturematerial_p.h b/src/extras/defaults/qtexturematerial_p.h new file mode 100644 index 000000000..5a8e78154 --- /dev/null +++ b/src/extras/defaults/qtexturematerial_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXTUREMATERIAL_P_H +#define QT3DEXTRAS_QTEXTUREMATERIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/private/qmaterial_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QFilterKey; +class QEffect; +class QAbstractTexture; +class QTechnique; +class QParameter; +class QShaderProgram; +class QRenderPass; + +} // namespace Qt3DRender + +namespace Qt3DExtras { + +class QTextureMaterial; + +class QTextureMaterialPrivate : public Qt3DRender::QMaterialPrivate +{ + QTextureMaterialPrivate(); + + void init(); + + void handleTextureChanged(const QVariant &var); + void handleTextureOffsetChanged(const QVariant &var); + + Qt3DRender::QEffect *m_textureEffect; + Qt3DRender::QParameter *m_textureParameter; + Qt3DRender::QParameter *m_textureOffsetParameter; + Qt3DRender::QTechnique *m_textureGL3Technique; + Qt3DRender::QTechnique *m_textureGL2Technique; + Qt3DRender::QTechnique *m_textureES2Technique; + Qt3DRender::QRenderPass *m_textureGL3RenderPass; + Qt3DRender::QRenderPass *m_textureGL2RenderPass; + Qt3DRender::QRenderPass *m_textureES2RenderPass; + Qt3DRender::QShaderProgram *m_textureGL3Shader; + Qt3DRender::QShaderProgram *m_textureGL2ES2Shader; + Qt3DRender::QFilterKey *m_filterKey; + + Q_DECLARE_PUBLIC(QTextureMaterial) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXTUREMATERIAL_P_H + diff --git a/src/extras/extras.pro b/src/extras/extras.pro index d11172005..22c9fcb93 100644 --- a/src/extras/extras.pro +++ b/src/extras/extras.pro @@ -9,10 +9,10 @@ DEFINES += QT_NO_FOREACH load(qt_module) -include (animations/animations.pri) include (geometries/geometries.pri) include (3dtext/3dtext.pri) include (defaults/defaults.pri) +include (text/text.pri) HEADERS += \ qt3dextras_global.h diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc index 121bfd029..9fce08a9f 100644 --- a/src/extras/extras.qrc +++ b/src/extras/extras.qrc @@ -39,6 +39,13 @@ <file>shaders/gl3/unlittexture.frag</file> <file>shaders/es2/unlittexture.frag</file> <file>shaders/es2/unlittexture.vert</file> + <file>shaders/gl3/metalrough.vert</file> + <file>shaders/gl3/metalrough.frag</file> + <file>shaders/gl3/metalroughuniform.frag</file> + <file>shaders/gl3/distancefieldtext.vert</file> + <file>shaders/gl3/distancefieldtext.frag</file> + <file>shaders/es2/distancefieldtext.frag</file> + <file>shaders/es2/distancefieldtext.vert</file> <file>shaders/gl3/morphphong.vert</file> <file>shaders/es2/morphphong.vert</file> </qresource> diff --git a/src/extras/geometries/qconegeometry.cpp b/src/extras/geometries/qconegeometry.cpp index a86d10f6b..12bbf7ce3 100644 --- a/src/extras/geometries/qconegeometry.cpp +++ b/src/extras/geometries/qconegeometry.cpp @@ -57,10 +57,12 @@ #include "qconegeometry.h" #include "qconegeometry_p.h" + #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qbufferdatagenerator.h> #include <Qt3DRender/qattribute.h> -#include <QVector3D> +#include <QtGui/QVector3D> + #include <cmath> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qconemesh.cpp b/src/extras/geometries/qconemesh.cpp index 8baa19217..5e327df03 100644 --- a/src/extras/geometries/qconemesh.cpp +++ b/src/extras/geometries/qconemesh.cpp @@ -41,13 +41,15 @@ # define _USE_MATH_DEFINES // For MSVC #endif -#include "qconemesh.h" #include "qconegeometry.h" + +#include <Qt3DExtras/qconemesh.h> #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qbufferdatagenerator.h> #include <Qt3DRender/qattribute.h> +#include <QtGui/QVector3D> + #include <qmath.h> -#include <QVector3D> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qcuboidgeometry.cpp b/src/extras/geometries/qcuboidgeometry.cpp index 28743858a..3bb68a500 100644 --- a/src/extras/geometries/qcuboidgeometry.cpp +++ b/src/extras/geometries/qcuboidgeometry.cpp @@ -39,12 +39,15 @@ #include "qcuboidgeometry.h" #include "qcuboidgeometry_p.h" + #include <Qt3DRender/qattribute.h> #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qbufferdatagenerator.h> #include <Qt3DRender/private/renderlogging_p.h> + #include <limits> + QT_BEGIN_NAMESPACE using namespace Qt3DRender; diff --git a/src/extras/geometries/qcuboidgeometry.h b/src/extras/geometries/qcuboidgeometry.h index fad5dcf9f..2c295d6c4 100644 --- a/src/extras/geometries/qcuboidgeometry.h +++ b/src/extras/geometries/qcuboidgeometry.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qgeometry.h> -#include <QSize> +#include <QtCore/QSize> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qcuboidgeometry_p.h b/src/extras/geometries/qcuboidgeometry_p.h index 212be19b4..cfabc0388 100644 --- a/src/extras/geometries/qcuboidgeometry_p.h +++ b/src/extras/geometries/qcuboidgeometry_p.h @@ -51,8 +51,9 @@ // We mean it. // +#include <QtCore/QSize> + #include <Qt3DRender/private/qgeometry_p.h> -#include <QSize> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qcuboidmesh.cpp b/src/extras/geometries/qcuboidmesh.cpp index 88c735746..9e10d93a4 100644 --- a/src/extras/geometries/qcuboidmesh.cpp +++ b/src/extras/geometries/qcuboidmesh.cpp @@ -38,7 +38,8 @@ ****************************************************************************/ #include "qcuboidmesh.h" -#include "qcuboidgeometry.h" + +#include <Qt3DExtras/qcuboidgeometry.h> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qcuboidmesh.h b/src/extras/geometries/qcuboidmesh.h index f709703c5..ca33c5f2d 100644 --- a/src/extras/geometries/qcuboidmesh.h +++ b/src/extras/geometries/qcuboidmesh.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qgeometryrenderer.h> -#include <QSize> +#include <QtCore/QSize> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qcylindergeometry.cpp b/src/extras/geometries/qcylindergeometry.cpp index 29f7ea7e0..4051477a6 100644 --- a/src/extras/geometries/qcylindergeometry.cpp +++ b/src/extras/geometries/qcylindergeometry.cpp @@ -43,11 +43,14 @@ #include "qcylindergeometry.h" #include "qcylindergeometry_p.h" + #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qbufferdatagenerator.h> #include <Qt3DRender/qattribute.h> +#include <QtGui/QVector3D> + #include <qmath.h> -#include <QVector3D> + QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qcylindermesh.cpp b/src/extras/geometries/qcylindermesh.cpp index 9b0ded28b..02df6295f 100644 --- a/src/extras/geometries/qcylindermesh.cpp +++ b/src/extras/geometries/qcylindermesh.cpp @@ -43,12 +43,14 @@ #endif #include "qcylindermesh.h" -#include "qcylindergeometry.h" + +#include <Qt3DExtras/qcylindergeometry.h> #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qbufferdatagenerator.h> #include <Qt3DRender/qattribute.h> +#include <QtGui/QVector3D> + #include <qmath.h> -#include <QVector3D> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qplanegeometry.cpp b/src/extras/geometries/qplanegeometry.cpp index 16b401d3d..14ddb25e6 100644 --- a/src/extras/geometries/qplanegeometry.cpp +++ b/src/extras/geometries/qplanegeometry.cpp @@ -39,9 +39,11 @@ #include "qplanegeometry.h" #include "qplanegeometry_p.h" + #include <Qt3DRender/qattribute.h> #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qbufferdatagenerator.h> + #include <limits> QT_BEGIN_NAMESPACE @@ -52,7 +54,7 @@ namespace Qt3DExtras { namespace { -QByteArray createPlaneVertexData(float w, float h, const QSize &resolution) +QByteArray createPlaneVertexData(float w, float h, const QSize &resolution, bool mirrored) { Q_ASSERT(w > 0.0f); Q_ASSERT(h > 0.0f); @@ -93,7 +95,7 @@ QByteArray createPlaneVertexData(float w, float h, const QSize &resolution) // texture coordinates *fptr++ = u; - *fptr++ = v; + *fptr++ = mirrored ? 1.0f - v : v; // normal *fptr++ = 0.0f; @@ -147,17 +149,18 @@ QByteArray createPlaneIndexData(const QSize &resolution) class PlaneVertexBufferFunctor : public QBufferDataGenerator { public: - explicit PlaneVertexBufferFunctor(float w, float h, const QSize &resolution) + explicit PlaneVertexBufferFunctor(float w, float h, const QSize &resolution, bool mirrored) : m_width(w) , m_height(h) , m_resolution(resolution) + , m_mirrored(mirrored) {} ~PlaneVertexBufferFunctor() {} QByteArray operator()() Q_DECL_FINAL { - return createPlaneVertexData(m_width, m_height, m_resolution); + return createPlaneVertexData(m_width, m_height, m_resolution, m_mirrored); } bool operator ==(const QBufferDataGenerator &other) const Q_DECL_FINAL @@ -166,7 +169,8 @@ public: if (otherFunctor != nullptr) return (otherFunctor->m_width == m_width && otherFunctor->m_height == m_height && - otherFunctor->m_resolution == m_resolution); + otherFunctor->m_resolution == m_resolution && + otherFunctor->m_mirrored == m_mirrored); return false; } @@ -176,6 +180,7 @@ public: float m_width; float m_height; QSize m_resolution; + bool m_mirrored; }; class PlaneIndexBufferFunctor : public QBufferDataGenerator @@ -235,6 +240,13 @@ public: */ /*! + * \qmlproperty bool PlaneGeometry::mirrored + * \since 5.9 + * + * Controls if the UV coordinates of the plane should be flipped vertically. + */ + +/*! * \qmlproperty Attribute PlaneGeometry::positionAttribute * * Holds the geometry position attribute. @@ -316,7 +328,7 @@ void QPlaneGeometry::updateVertices() d->m_normalAttribute->setCount(nVerts); d->m_texCoordAttribute->setCount(nVerts); d->m_tangentAttribute->setCount(nVerts); - d->m_vertexBuffer->setDataGenerator(QSharedPointer<PlaneVertexBufferFunctor>::create(d->m_width, d->m_height, d->m_meshResolution)); + d->m_vertexBuffer->setDataGenerator(QSharedPointer<PlaneVertexBufferFunctor>::create(d->m_width, d->m_height, d->m_meshResolution, d->m_mirrored)); } /*! @@ -363,6 +375,16 @@ void QPlaneGeometry::setHeight(float height) emit heightChanged(height); } +void QPlaneGeometry::setMirrored(bool mirrored) +{ + Q_D(QPlaneGeometry); + if (mirrored == d->m_mirrored) + return; + d->m_mirrored = mirrored; + updateVertices(); + emit mirroredChanged(mirrored); +} + /*! * \property QPlaneGeometry::resolution * @@ -397,6 +419,18 @@ float QPlaneGeometry::height() const } /*! + * \property QPlaneGeometry::mirrored + * \since 5.9 + * + * Controls if the UV coordinates of the plane should be flipped vertically. + */ +bool QPlaneGeometry::mirrored() const +{ + Q_D(const QPlaneGeometry); + return d->m_mirrored; +} + +/*! * \property QPlaneGeometry::positionAttribute * * Holds the geometry position attribute. @@ -456,6 +490,7 @@ QPlaneGeometryPrivate::QPlaneGeometryPrivate() , m_width(1.0f) , m_height(1.0f) , m_meshResolution(QSize(2, 2)) + , m_mirrored(false) , m_positionAttribute(nullptr) , m_normalAttribute(nullptr) , m_texCoordAttribute(nullptr) @@ -523,7 +558,7 @@ void QPlaneGeometryPrivate::init() // Each primitive has 3 vertives m_indexAttribute->setCount(faces * 3); - m_vertexBuffer->setDataGenerator(QSharedPointer<PlaneVertexBufferFunctor>::create(m_width, m_height, m_meshResolution)); + m_vertexBuffer->setDataGenerator(QSharedPointer<PlaneVertexBufferFunctor>::create(m_width, m_height, m_meshResolution, m_mirrored)); m_indexBuffer->setDataGenerator(QSharedPointer<PlaneIndexBufferFunctor>::create(m_meshResolution)); q->addAttribute(m_positionAttribute); diff --git a/src/extras/geometries/qplanegeometry.h b/src/extras/geometries/qplanegeometry.h index 7ec5cba43..4a4efe6eb 100644 --- a/src/extras/geometries/qplanegeometry.h +++ b/src/extras/geometries/qplanegeometry.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qgeometry.h> -#include <QSize> +#include <QtCore/QSize> QT_BEGIN_NAMESPACE @@ -62,6 +62,7 @@ class QT3DEXTRASSHARED_EXPORT QPlaneGeometry : public Qt3DRender::QGeometry Q_PROPERTY(float width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged) Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged) + Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged REVISION 9) Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT) Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT) Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT) @@ -78,6 +79,7 @@ public: QSize resolution() const; float width() const; float height() const; + bool mirrored() const; Qt3DRender::QAttribute *positionAttribute() const; Qt3DRender::QAttribute *normalAttribute() const; @@ -89,11 +91,13 @@ public Q_SLOTS: void setResolution(const QSize &resolution); void setWidth(float width); void setHeight(float height); + void setMirrored(bool mirrored); Q_SIGNALS: void resolutionChanged(const QSize &resolution); void widthChanged(float width); void heightChanged(float height); + void mirroredChanged(bool mirrored); protected: QPlaneGeometry(QPlaneGeometryPrivate &dd, QNode *parent = nullptr); diff --git a/src/extras/geometries/qplanegeometry_p.h b/src/extras/geometries/qplanegeometry_p.h index d0a4e88e4..68d979895 100644 --- a/src/extras/geometries/qplanegeometry_p.h +++ b/src/extras/geometries/qplanegeometry_p.h @@ -51,8 +51,9 @@ // We mean it. // +#include <QtCore/QSize> + #include <Qt3DRender/private/qgeometry_p.h> -#include <QSize> QT_BEGIN_NAMESPACE @@ -74,6 +75,7 @@ public: float m_width; float m_height; QSize m_meshResolution; + bool m_mirrored; Qt3DRender::QAttribute *m_positionAttribute; Qt3DRender::QAttribute *m_normalAttribute; Qt3DRender::QAttribute *m_texCoordAttribute; diff --git a/src/extras/geometries/qplanemesh.cpp b/src/extras/geometries/qplanemesh.cpp index 120aed6df..4804df024 100644 --- a/src/extras/geometries/qplanemesh.cpp +++ b/src/extras/geometries/qplanemesh.cpp @@ -38,7 +38,8 @@ ****************************************************************************/ #include "qplanemesh.h" -#include "qplanegeometry.h" + +#include <Qt3DExtras/qplanegeometry.h> QT_BEGIN_NAMESPACE @@ -72,6 +73,13 @@ namespace Qt3DExtras { */ /*! + * \qmlproperty bool PlaneMesh::mirrored + * \since 5.9 + * + * Controls if the UV coordinates of the plane should be flipped vertically. + */ + +/*! * \class Qt3DExtras::QPlaneMesh * \inheaderfile Qt3DExtras/QPlaneMesh * \inmodule Qt3DExtras @@ -91,6 +99,7 @@ QPlaneMesh::QPlaneMesh(QNode *parent) QObject::connect(geometry, &QPlaneGeometry::widthChanged, this, &QPlaneMesh::widthChanged); QObject::connect(geometry, &QPlaneGeometry::heightChanged, this, &QPlaneMesh::heightChanged); QObject::connect(geometry, &QPlaneGeometry::resolutionChanged, this, &QPlaneMesh::meshResolutionChanged); + QObject::connect(geometry, &QPlaneGeometry::mirroredChanged, this, &QPlaneMesh::mirroredChanged); QGeometryRenderer::setGeometry(geometry); } @@ -146,6 +155,22 @@ QSize QPlaneMesh::meshResolution() const return static_cast<QPlaneGeometry *>(geometry())->resolution(); } +void QPlaneMesh::setMirrored(bool mirrored) +{ + static_cast<QPlaneGeometry *>(geometry())->setMirrored(mirrored); +} + +/*! + * \property QPlaneMesh::mirrored + * \since 5.9 + * + * Controls if the UV coordinates of the plane should be flipped vertically. + */ +bool QPlaneMesh::mirrored() const +{ + return static_cast<QPlaneGeometry *>(geometry())->mirrored(); +} + } // namespace Qt3DExtras QT_END_NAMESPACE diff --git a/src/extras/geometries/qplanemesh.h b/src/extras/geometries/qplanemesh.h index b1505db17..1cf2ae79e 100644 --- a/src/extras/geometries/qplanemesh.h +++ b/src/extras/geometries/qplanemesh.h @@ -42,7 +42,7 @@ #include <Qt3DExtras/qt3dextras_global.h> #include <Qt3DRender/qgeometryrenderer.h> -#include <QSize> +#include <QtCore/QSize> QT_BEGIN_NAMESPACE @@ -54,6 +54,7 @@ class QT3DEXTRASSHARED_EXPORT QPlaneMesh : public Qt3DRender::QGeometryRenderer Q_PROPERTY(float width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged) Q_PROPERTY(QSize meshResolution READ meshResolution WRITE setMeshResolution NOTIFY meshResolutionChanged) + Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged REVISION 9) public: explicit QPlaneMesh(Qt3DCore::QNode *parent = nullptr); @@ -62,16 +63,19 @@ public: float width() const; float height() const; QSize meshResolution() const; + bool mirrored() const; public Q_SLOTS: void setWidth(float width); void setHeight(float height); void setMeshResolution(const QSize &resolution); + void setMirrored(bool mirrored); Q_SIGNALS: void meshResolutionChanged(const QSize &meshResolution); void widthChanged(float width); void heightChanged(float height); + void mirroredChanged(bool mirrored); private: // As this is a default provided geometry renderer, no one should be able diff --git a/src/extras/geometries/qspheregeometry.cpp b/src/extras/geometries/qspheregeometry.cpp index a79eb8074..eae12ef39 100644 --- a/src/extras/geometries/qspheregeometry.cpp +++ b/src/extras/geometries/qspheregeometry.cpp @@ -39,15 +39,17 @@ #include "qspheregeometry.h" #include "qspheregeometry_p.h" + #include <Qt3DRender/qbufferdatagenerator.h> #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qattribute.h> +#include <qmath.h> + #ifndef _USE_MATH_DEFINES # define _USE_MATH_DEFINES // For MSVC #endif -#include <qmath.h> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qspheremesh.cpp b/src/extras/geometries/qspheremesh.cpp index 988a95990..22089d7ab 100644 --- a/src/extras/geometries/qspheremesh.cpp +++ b/src/extras/geometries/qspheremesh.cpp @@ -39,7 +39,8 @@ ****************************************************************************/ #include "qspheremesh.h" -#include "qspheregeometry.h" + +#include <Qt3DExtras/qspheregeometry.h> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qtorusgeometry.cpp b/src/extras/geometries/qtorusgeometry.cpp index 08afce1b0..57c94ec95 100644 --- a/src/extras/geometries/qtorusgeometry.cpp +++ b/src/extras/geometries/qtorusgeometry.cpp @@ -39,12 +39,14 @@ #include "qtorusgeometry.h" #include "qtorusgeometry_p.h" + #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qbufferdatagenerator.h> #include <Qt3DRender/qattribute.h> +#include <QtGui/QVector3D> +#include <QtGui/QVector4D> + #include <qmath.h> -#include <QVector3D> -#include <QVector4D> QT_BEGIN_NAMESPACE diff --git a/src/extras/geometries/qtorusmesh.cpp b/src/extras/geometries/qtorusmesh.cpp index 96fce9ec0..8e7c678db 100644 --- a/src/extras/geometries/qtorusmesh.cpp +++ b/src/extras/geometries/qtorusmesh.cpp @@ -43,7 +43,8 @@ #endif #include "qtorusmesh.h" -#include "qtorusgeometry.h" + +#include <Qt3DExtras/qtorusgeometry.h> QT_BEGIN_NAMESPACE diff --git a/src/extras/shaders/es2/distancefieldtext.frag b/src/extras/shaders/es2/distancefieldtext.frag new file mode 100644 index 000000000..88ead1f68 --- /dev/null +++ b/src/extras/shaders/es2/distancefieldtext.frag @@ -0,0 +1,36 @@ +#define FP highp + +uniform FP sampler2D distanceFieldTexture; +uniform FP float minAlpha; +uniform FP float maxAlpha; +uniform FP float textureSize; +uniform FP vec4 color; + +varying FP vec3 position; +varying FP vec2 texCoord; + +void main() +{ + // determine the scale of the glyph texture within pixel-space coordinates + // (that is, how many pixels are drawn for each texel) + FP vec2 texelDeltaX = abs(dFdx(texCoord)); + FP vec2 texelDeltaY = abs(dFdy(texCoord)); + FP float avgTexelDelta = textureSize * 0.5 * (texelDeltaX.x + texelDeltaX.y + texelDeltaY.x + texelDeltaY.y); + FP float texScale = 1.0 / avgTexelDelta; + + // scaled to interval [0.0, 0.15] + FP float devScaleMin = 0.00; + FP float devScaleMax = 0.15; + FP float scaled = (clamp(texScale, devScaleMin, devScaleMax) - devScaleMin) / (devScaleMax - devScaleMin); + + // thickness of glyphs should increase a lot for very small glyphs to make them readable + FP float base = 0.5; + FP float threshold = base * scaled; + FP float range = 0.06 / texScale; + + FP float minAlpha = threshold - range; + FP float maxAlpha = threshold + range; + + FP float distVal = texture2D(distanceFieldTexture, texCoord).r; + gl_FragColor = color * smoothstep(minAlpha, maxAlpha, distVal); +} diff --git a/src/extras/shaders/es2/distancefieldtext.vert b/src/extras/shaders/es2/distancefieldtext.vert new file mode 100644 index 000000000..f7fc5327b --- /dev/null +++ b/src/extras/shaders/es2/distancefieldtext.vert @@ -0,0 +1,17 @@ +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; + +varying vec3 position; +varying vec2 texCoord; + +uniform mat4 modelView; +uniform mat4 mvp; + +void main() +{ + texCoord = vertexTexCoord; + position = vec3(modelView * vec4(vertexPosition, 1.0)); + + gl_Position = mvp * vec4(vertexPosition, 1.0); +} + diff --git a/src/extras/shaders/es2/light.inc.frag b/src/extras/shaders/es2/light.inc.frag index 02660f008..074af5799 100644 --- a/src/extras/shaders/es2/light.inc.frag +++ b/src/extras/shaders/es2/light.inc.frag @@ -26,27 +26,45 @@ void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const FP vec3 n = normalize( vnormal ); FP vec3 s, ts; + Light light; for (int i = 0; i < lightCount; ++i) { + if (i == 0) + light = lights[0]; + else if (i == 1) + light = lights[1]; + else if (i == 2) + light = lights[2]; + else if (i == 3) + light = lights[3]; + else if (i == 4) + light = lights[4]; + else if (i == 5) + light = lights[5]; + else if (i == 6) + light = lights[6]; + else if (i == 7) + light = lights[7]; + FP float att = 1.0; - if ( lights[i].type != TYPE_DIRECTIONAL ) { - s = lights[i].position - vpos; + if ( light.type != TYPE_DIRECTIONAL ) { + s = light.position - vpos; if ( dot(snormal, s) < 0.0 ) att = 0.0; else { ts = normalize( tangentMatrix * s ); - if (length( lights[i].attenuation ) != 0.0) { + if (length( light.attenuation ) != 0.0) { FP float dist = length(s); - att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist); + att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); } s = normalize( s ); - if ( lights[i].type == TYPE_SPOT ) { - if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) + if ( light.type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) att = 0.0; } } } else { - if ( dot(snormal, -lights[i].direction) > 0.0 ) - s = normalize( tangentMatrix * -lights[i].direction ); + if ( dot(snormal, -light.direction) > 0.0 ) + s = normalize( tangentMatrix * -light.direction ); else att = 0.0; } @@ -61,8 +79,8 @@ void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); } - diffuseColor += att * lights[i].intensity * diffuse * lights[i].color; - specularColor += att * lights[i].intensity * specular * lights[i].color; + diffuseColor += att * light.intensity * diffuse * light.color; + specularColor += att * light.intensity * specular * light.color; } } @@ -75,21 +93,39 @@ void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 FP vec3 n = normalize( vnormal ); FP vec3 s; + Light light; for (int i = 0; i < lightCount; ++i) { + if (i == 0) + light = lights[0]; + else if (i == 1) + light = lights[1]; + else if (i == 2) + light = lights[2]; + else if (i == 3) + light = lights[3]; + else if (i == 4) + light = lights[4]; + else if (i == 5) + light = lights[5]; + else if (i == 6) + light = lights[6]; + else if (i == 7) + light = lights[7]; + FP float att = 1.0; - if ( lights[i].type != TYPE_DIRECTIONAL ) { - s = lights[i].position - vpos; - if (length( lights[i].attenuation ) != 0.0) { + if ( light.type != TYPE_DIRECTIONAL ) { + s = light.position - vpos; + if (length( light.attenuation ) != 0.0) { FP float dist = length(s); - att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist); + att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); } s = normalize( s ); - if ( lights[i].type == TYPE_SPOT ) { - if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) + if ( light.type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) att = 0.0; } } else { - s = normalize( -lights[i].direction ); + s = normalize( -light.direction ); } FP float diffuse = max( dot( s, n ), 0.0 ); @@ -102,8 +138,8 @@ void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); } - diffuseColor += att * lights[i].intensity * diffuse * lights[i].color; - specularColor += att * lights[i].intensity * specular * lights[i].color; + diffuseColor += att * light.intensity * diffuse * light.color; + specularColor += att * light.intensity * specular * light.color; } } @@ -114,25 +150,43 @@ void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffus FP vec3 n = normalize( vnormal ); FP vec3 s; + Light light; for (int i = 0; i < lightCount; ++i) { + if (i == 0) + light = lights[0]; + else if (i == 1) + light = lights[1]; + else if (i == 2) + light = lights[2]; + else if (i == 3) + light = lights[3]; + else if (i == 4) + light = lights[4]; + else if (i == 5) + light = lights[5]; + else if (i == 6) + light = lights[6]; + else if (i == 7) + light = lights[7]; + FP float att = 1.0; - if ( lights[i].type != TYPE_DIRECTIONAL ) { - s = lights[i].position - vpos; - if (length( lights[i].attenuation ) != 0.0) { + if ( light.type != TYPE_DIRECTIONAL ) { + s = light.position - vpos; + if (length( light.attenuation ) != 0.0) { FP float dist = length(s); - att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist); + att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); } s = normalize( s ); - if ( lights[i].type == TYPE_SPOT ) { - if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle) + if ( light.type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) att = 0.0; } } else { - s = normalize( -lights[i].direction ); + s = normalize( -light.direction ); } FP float diffuse = max( dot( s, n ), 0.0 ); - diffuseColor += att * lights[i].intensity * diffuse * lights[i].color; + diffuseColor += att * light.intensity * diffuse * light.color; } } diff --git a/src/extras/shaders/gl3/distancefieldtext.frag b/src/extras/shaders/gl3/distancefieldtext.frag new file mode 100644 index 000000000..4f0c9cac0 --- /dev/null +++ b/src/extras/shaders/gl3/distancefieldtext.frag @@ -0,0 +1,38 @@ +#version 150 core + +uniform sampler2D distanceFieldTexture; +uniform float minAlpha; +uniform float maxAlpha; +uniform float textureSize; +uniform vec4 color; + +in vec3 position; +in vec2 texCoord; + +out vec4 fragColor; + +void main() +{ + // determine the scale of the glyph texture within pixel-space coordinates + // (that is, how many pixels are drawn for each texel) + vec2 texelDeltaX = abs(dFdx(texCoord)); + vec2 texelDeltaY = abs(dFdy(texCoord)); + float avgTexelDelta = textureSize * 0.5 * (texelDeltaX.x + texelDeltaX.y + texelDeltaY.x + texelDeltaY.y); + float texScale = 1.0 / avgTexelDelta; + + // scaled to interval [0.0, 0.15] + float devScaleMin = 0.00; + float devScaleMax = 0.15; + float scaled = (clamp(texScale, devScaleMin, devScaleMax) - devScaleMin) / (devScaleMax - devScaleMin); + + // thickness of glyphs should increase a lot for very small glyphs to make them readable + float base = 0.5; + float threshold = base * scaled; + float range = 0.06 / texScale; + + float minAlpha = threshold - range; + float maxAlpha = threshold + range; + + float distVal = texture(distanceFieldTexture, texCoord).r; + fragColor = color * smoothstep(minAlpha, maxAlpha, distVal); +} diff --git a/src/extras/shaders/gl3/distancefieldtext.vert b/src/extras/shaders/gl3/distancefieldtext.vert new file mode 100644 index 000000000..9bd2a0a90 --- /dev/null +++ b/src/extras/shaders/gl3/distancefieldtext.vert @@ -0,0 +1,19 @@ +#version 150 core + +in vec3 vertexPosition; +in vec2 vertexTexCoord; + +out vec3 position; +out vec2 texCoord; + +uniform mat4 modelView; +uniform mat4 mvp; + +void main() +{ + texCoord = vertexTexCoord; + position = vec3(modelView * vec4(vertexPosition, 1.0)); + + gl_Position = mvp * vec4(vertexPosition, 1.0); +} + diff --git a/src/extras/shaders/gl3/light.inc.frag b/src/extras/shaders/gl3/light.inc.frag index 3047bdb3c..ce5c581cf 100644 --- a/src/extras/shaders/gl3/light.inc.frag +++ b/src/extras/shaders/gl3/light.inc.frag @@ -16,6 +16,14 @@ struct Light { uniform Light lights[MAX_LIGHTS]; uniform int lightCount; +// Pre-convolved environment maps +struct EnvironmentLight { + samplerCube irradiance; // For diffuse contribution + samplerCube specular; // For specular contribution +}; +uniform EnvironmentLight envLight; +uniform int envLightCount = 0; + void adsModelNormalMapped(const in vec3 worldPos, const in vec3 tsNormal, const in vec3 worldEye, diff --git a/src/extras/shaders/gl3/metalrough.frag b/src/extras/shaders/gl3/metalrough.frag new file mode 100644 index 000000000..7f2f3d20e --- /dev/null +++ b/src/extras/shaders/gl3/metalrough.frag @@ -0,0 +1,395 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#version 150 + +in vec2 texCoord; +in vec3 worldPosition; +in vec3 worldNormal; +in vec4 worldTangent; + +out vec4 fragColor; + +// Qt 3D built in uniforms +uniform vec3 eyePosition; // World space eye position +uniform float time; // Time in seconds + +// PBR Material maps +uniform sampler2D baseColorMap; +uniform sampler2D metalnessMap; +uniform sampler2D roughnessMap; +uniform sampler2D normalMap; +uniform sampler2D ambientOcclusionMap; + +// User control parameters +uniform float metalFactor = 1.0; + +// Exposure correction +uniform float exposure = 0.0; +// Gamma correction +uniform float gamma = 2.2; + +#pragma include light.inc.frag + +int mipLevelCount(const in samplerCube cube) +{ + int baseSize = textureSize(cube, 0).x; + int nMips = int(log2(float(baseSize>0 ? baseSize : 1))) + 1; + return nMips; +} + +float remapRoughness(const in float roughness) +{ + // As per page 14 of + // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + // we remap the roughness to give a more perceptually linear response + // of "bluriness" as a function of the roughness specified by the user. + // r = roughness^2 + const float maxSpecPower = 999999.0; + const float minRoughness = sqrt(2.0 / (maxSpecPower + 2)); + return max(roughness * roughness, minRoughness); +} + +mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in 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) + 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. + 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 + mat3 tangentToWorldMatrix = mat3(wFixedTangent, wBinormal, wNormal); + mat3 worldToTangentMatrix = transpose(tangentToWorldMatrix); + return worldToTangentMatrix; +} + +float alphaToMipLevel(float alpha) +{ + float specPower = 2.0 / (alpha * alpha) - 2.0; + + // We use the mip level calculation from Lys' default power drop, which in + // turn is a slight modification of that used in Marmoset Toolbag. See + // https://docs.knaldtech.com/doku.php?id=specular_lys for details. + // For now we assume a max specular power of 999999 which gives + // maxGlossiness = 1. + const float k0 = 0.00098; + const float k1 = 0.9921; + float glossiness = (pow(2.0, -10.0 / sqrt(specPower)) - k0) / k1; + + // TODO: Optimize by doing this on CPU and set as + // uniform int envLight.specularMipLevels say (if present in shader). + // Lookup the number of mips in the specular envmap + int mipLevels = mipLevelCount(envLight.specular); + + // Offset of smallest miplevel we should use (corresponds to specular + // power of 1). I.e. in the 32x32 sized mip. + const float mipOffset = 5.0; + + // The final factor is really 1 - g / g_max but as mentioned above g_max + // is 1 by definition here so we can avoid the division. If we make the + // max specular power for the spec map configurable, this will need to + // be handled properly. + float mipLevel = (mipLevels - 1.0 - mipOffset) * (1.0 - glossiness); + return mipLevel; +} + +float normalDistribution(const in vec3 n, const in vec3 h, const in float alpha) +{ + // Blinn-Phong approximation - see + // http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html + float specPower = 2.0 / (alpha * alpha) - 2.0; + return (specPower + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), specPower); +} + +vec3 fresnelFactor(const in vec3 color, const in float cosineFactor) +{ + // Calculate the Fresnel effect value + vec3 f = color; + vec3 F = f + (1.0 - f) * pow(1.0 - cosineFactor, 5.0); + return clamp(F, f, vec3(1.0)); +} + +float geometricModel(const in float lDotN, + const in float vDotN, + const in vec3 h) +{ + // Implicit geometric model (equal to denominator in specular model). + // This currently assumes that there is no attenuation by geometric shadowing or + // masking according to the microfacet theory. + return lDotN * vDotN; +} + +vec3 specularModel(const in vec3 F0, + const in float sDotH, + const in float sDotN, + const in float vDotN, + const in vec3 n, + const in vec3 h) +{ + // Clamp sDotN and vDotN to small positive value to prevent the + // denominator in the reflection equation going to infinity. Balance this + // by using the clamped values in the geometric factor function to + // avoid ugly seams in the specular lighting. + float sDotNPrime = max(sDotN, 0.001); + float vDotNPrime = max(vDotN, 0.001); + + vec3 F = fresnelFactor(F0, sDotH); + float G = geometricModel(sDotNPrime, vDotNPrime, h); + + vec3 cSpec = F * G / (4.0 * sDotNPrime * vDotNPrime); + return clamp(cSpec, vec3(0.0), vec3(1.0)); +} + +vec3 pbrModel(const in int lightIndex, + const in vec3 wPosition, + const in vec3 wNormal, + const in vec3 wView, + const in vec3 baseColor, + const in float metalness, + const in float alpha, + const in float ambientOcclusion) +{ + // Calculate some useful quantities + vec3 n = wNormal; + vec3 s = vec3(0.0); + vec3 v = wView; + vec3 h = vec3(0.0); + + float vDotN = dot(v, n); + float sDotN = 0.0; + float sDotH = 0.0; + float att = 1.0; + + if (lights[lightIndex].type != TYPE_DIRECTIONAL) { + // Point and Spot lights + vec3 sUnnormalized = vec3(lights[lightIndex].position) - wPosition; + s = normalize(sUnnormalized); + + // Calculate the attenuation factor + sDotN = dot(s, n); + if (sDotN > 0.0) { + if (lights[lightIndex].constantAttenuation != 0.0 + || lights[lightIndex].linearAttenuation != 0.0 + || lights[lightIndex].quadraticAttenuation != 0.0) { + float dist = length(sUnnormalized); + att = 1.0 / (lights[lightIndex].constantAttenuation + + lights[lightIndex].linearAttenuation * dist + + lights[lightIndex].quadraticAttenuation * dist * dist); + } + + // The light direction is in world space already + if (lights[lightIndex].type == TYPE_SPOT) { + // Check if fragment is inside or outside of the spot light cone + if (degrees(acos(dot(-s, lights[lightIndex].direction))) > lights[lightIndex].cutOffAngle) + sDotN = 0.0; + } + } + } else { + // Directional lights + // The light direction is in world space already + s = normalize(-lights[lightIndex].direction); + sDotN = dot(s, n); + } + + h = normalize(s + v); + sDotH = dot(s, h); + + // Calculate diffuse component + vec3 diffuseColor = (1.0 - metalness) * baseColor; + vec3 diffuse = diffuseColor * max(sDotN, 0.0) / 3.14159; + + // Calculate specular component + vec3 dielectricColor = vec3(0.04); + vec3 F0 = mix(dielectricColor, baseColor, metalness); + vec3 specularFactor = vec3(0.0); + if (sDotN > 0.0) { + specularFactor = specularModel(F0, sDotH, sDotN, vDotN, n, h); + specularFactor *= normalDistribution(n, h, alpha); + } + vec3 specularColor = lights[lightIndex].color; + vec3 specular = specularColor * specularFactor; + + // Blend between diffuse and specular to conserver energy + vec3 color = lights[lightIndex].intensity * (specular + diffuse * (vec3(1.0) - specular)); + + // Reduce by ambient occlusion amount + color *= ambientOcclusion; + + return color; +} + +vec3 pbrIblModel(const in vec3 wNormal, + const in vec3 wView, + const in vec3 baseColor, + const in float metalness, + const in float alpha, + const in float ambientOcclusion) +{ + // Calculate reflection direction of view vector about surface normal + // vector in world space. This is used in the fragment shader to sample + // from the environment textures for a light source. This is equivalent + // to the l vector for punctual light sources. Armed with this, calculate + // the usual factors needed + vec3 n = wNormal; + vec3 l = reflect(-wView, n); + vec3 v = wView; + vec3 h = normalize(l + v); + float vDotN = dot(v, n); + float lDotN = dot(l, n); + float lDotH = dot(l, h); + + // Calculate diffuse component + vec3 diffuseColor = (1.0 - metalness) * baseColor; + vec3 diffuse = diffuseColor * texture(envLight.irradiance, l).rgb; + + // Calculate specular component + vec3 dielectricColor = vec3(0.04); + vec3 F0 = mix(dielectricColor, baseColor, metalness); + vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h); + + float lod = alphaToMipLevel(alpha); +//#define DEBUG_SPECULAR_LODS +#ifdef DEBUG_SPECULAR_LODS + if (lod > 7.0) + return vec3(1.0, 0.0, 0.0); + else if (lod > 6.0) + return vec3(1.0, 0.333, 0.0); + else if (lod > 5.0) + return vec3(1.0, 1.0, 0.0); + else if (lod > 4.0) + return vec3(0.666, 1.0, 0.0); + else if (lod > 3.0) + return vec3(0.0, 1.0, 0.666); + else if (lod > 2.0) + return vec3(0.0, 0.666, 1.0); + else if (lod > 1.0) + return vec3(0.0, 0.0, 1.0); + else if (lod > 0.0) + return vec3(1.0, 0.0, 1.0); +#endif + vec3 specularSkyColor = textureLod(envLight.specular, l, lod).rgb; + vec3 specular = specularSkyColor * specularFactor; + + // Blend between diffuse and specular to conserve energy + vec3 iblColor = specular + diffuse * (vec3(1.0) - specularFactor); + + // Reduce by ambient occlusion amount + iblColor *= ambientOcclusion; + + return iblColor; +} + +vec3 toneMap(const in vec3 c) +{ + return c / (c + vec3(1.0)); +} + +vec3 gammaCorrect(const in vec3 color) +{ + return pow(color, vec3(1.0 / gamma)); +} + +void main() +{ + vec3 cLinear = vec3(0.0); + + // Calculate the perturbed texture coordinates from parallax occlusion mapping + mat3 worldToTangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent); + vec3 wView = normalize(eyePosition - worldPosition); + vec3 tView = worldToTangentMatrix * wView; + + // Sample the inputs needed for the metal-roughness PBR BRDF + vec3 baseColor = texture(baseColorMap, texCoord).rgb; + float metalness = texture(metalnessMap, texCoord).r * metalFactor; + float roughness = texture(roughnessMap, texCoord).r; + float ambientOcclusion = texture(ambientOcclusionMap, texCoord).r; + vec3 tNormal = 2.0 * texture(normalMap, texCoord).rgb - vec3(1.0); + vec3 wNormal = normalize(transpose(worldToTangentMatrix) * tNormal); + + // Remap roughness for a perceptually more linear correspondence + float alpha = remapRoughness(roughness); + + for (int i = 0; i < envLightCount; ++i) { + cLinear += pbrIblModel(wNormal, + wView, + baseColor, + metalness, + alpha, + ambientOcclusion); + } + + for (int i = 0; i < lightCount; ++i) { + cLinear += pbrModel(i, + worldPosition, + wNormal, + wView, + baseColor.rgb, + metalness, + alpha, + ambientOcclusion); + } + + // Apply exposure correction + cLinear *= pow(2.0, exposure); + + // Apply simple (Reinhard) tonemap transform to get into LDR range [0, 1] + vec3 cToneMapped = toneMap(cLinear); + + // Apply gamma correction prior to display + vec3 cGamma = gammaCorrect(cToneMapped); + fragColor = vec4(cGamma, 1.0); +} diff --git a/src/extras/shaders/gl3/metalrough.vert b/src/extras/shaders/gl3/metalrough.vert new file mode 100644 index 000000000..6d3a60ef6 --- /dev/null +++ b/src/extras/shaders/gl3/metalrough.vert @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#version 150 + +in vec3 vertexPosition; +in vec3 vertexNormal; +in vec4 vertexTangent; +in vec2 vertexTexCoord; + +out vec3 worldPosition; +out vec3 worldNormal; +out vec4 worldTangent; +out vec2 texCoord; + +uniform mat4 modelMatrix; +uniform mat3 modelNormalMatrix; +uniform mat4 mvp; + +void main() +{ + // Pass the texture coordinates through + texCoord = vertexTexCoord; + + // Transform position, normal, and tangent to world space + worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0)); + worldNormal = normalize(modelNormalMatrix * vertexNormal); + worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0))); + worldTangent.w = vertexTangent.w; + + gl_Position = mvp * vec4(vertexPosition, 1.0); +} diff --git a/src/extras/shaders/gl3/metalroughuniform.frag b/src/extras/shaders/gl3/metalroughuniform.frag new file mode 100644 index 000000000..f4bad0a00 --- /dev/null +++ b/src/extras/shaders/gl3/metalroughuniform.frag @@ -0,0 +1,371 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#version 150 + +in vec2 texCoord; +in vec3 worldPosition; +in vec3 worldNormal; +in vec4 worldTangent; + +out vec4 fragColor; + +// Qt 3D built in uniforms +uniform vec3 eyePosition; // World space eye position +uniform float time; // Time in seconds + +// PBR Material maps +uniform vec4 baseColor; +uniform float metalness; +uniform float roughness; + +// Exposure correction +uniform float exposure = 0.0; +// Gamma correction +uniform float gamma = 2.2; + +#pragma include light.inc.frag + +int mipLevelCount(const in samplerCube cube) +{ + int baseSize = textureSize(cube, 0).x; + int nMips = int(log2(float(baseSize>0 ? baseSize : 1))) + 1; + return nMips; +} + +float remapRoughness(const in float roughness) +{ + // As per page 14 of + // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + // we remap the roughness to give a more perceptually linear response + // of "bluriness" as a function of the roughness specified by the user. + // r = roughness^2 + const float maxSpecPower = 999999.0; + const float minRoughness = sqrt(2.0 / (maxSpecPower + 2)); + return max(roughness * roughness, minRoughness); +} + +mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in 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) + 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. + 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 + mat3 tangentToWorldMatrix = mat3(wFixedTangent, wBinormal, wNormal); + mat3 worldToTangentMatrix = transpose(tangentToWorldMatrix); + return worldToTangentMatrix; +} + +float alphaToMipLevel(float alpha) +{ + float specPower = 2.0 / (alpha * alpha) - 2.0; + + // We use the mip level calculation from Lys' default power drop, which in + // turn is a slight modification of that used in Marmoset Toolbag. See + // https://docs.knaldtech.com/doku.php?id=specular_lys for details. + // For now we assume a max specular power of 999999 which gives + // maxGlossiness = 1. + const float k0 = 0.00098; + const float k1 = 0.9921; + float glossiness = (pow(2.0, -10.0 / sqrt(specPower)) - k0) / k1; + + // TODO: Optimize by doing this on CPU and set as + // uniform int envLight.specularMipLevels say (if present in shader). + // Lookup the number of mips in the specular envmap + int mipLevels = mipLevelCount(envLight.specular); + + // Offset of smallest miplevel we should use (corresponds to specular + // power of 1). I.e. in the 32x32 sized mip. + const float mipOffset = 5.0; + + // The final factor is really 1 - g / g_max but as mentioned above g_max + // is 1 by definition here so we can avoid the division. If we make the + // max specular power for the spec map configurable, this will need to + // be handled properly. + float mipLevel = (mipLevels - 1.0 - mipOffset) * (1.0 - glossiness); + return mipLevel; +} + +float normalDistribution(const in vec3 n, const in vec3 h, const in float alpha) +{ + // Blinn-Phong approximation - see + // http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html + float specPower = 2.0 / (alpha * alpha) - 2.0; + return (specPower + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), specPower); +} + +vec3 fresnelFactor(const in vec3 color, const in float cosineFactor) +{ + // Calculate the Fresnel effect value + vec3 f = color; + vec3 F = f + (1.0 - f) * pow(1.0 - cosineFactor, 5.0); + return clamp(F, f, vec3(1.0)); +} + +float geometricModel(const in float lDotN, + const in float vDotN, + const in vec3 h) +{ + // Implicit geometric model (equal to denominator in specular model). + // This currently assumes that there is no attenuation by geometric shadowing or + // masking according to the microfacet theory. + return lDotN * vDotN; +} + +vec3 specularModel(const in vec3 F0, + const in float sDotH, + const in float sDotN, + const in float vDotN, + const in vec3 n, + const in vec3 h) +{ + // Clamp sDotN and vDotN to small positive value to prevent the + // denominator in the reflection equation going to infinity. Balance this + // by using the clamped values in the geometric factor function to + // avoid ugly seams in the specular lighting. + float sDotNPrime = max(sDotN, 0.001); + float vDotNPrime = max(vDotN, 0.001); + + vec3 F = fresnelFactor(F0, sDotH); + float G = geometricModel(sDotNPrime, vDotNPrime, h); + + vec3 cSpec = F * G / (4.0 * sDotNPrime * vDotNPrime); + return clamp(cSpec, vec3(0.0), vec3(1.0)); +} + +vec3 pbrModel(const in int lightIndex, + const in vec3 wPosition, + const in vec3 wNormal, + const in vec3 wView, + const in vec3 baseColor, + const in float metalness, + const in float alpha) +{ + // Calculate some useful quantities + vec3 n = wNormal; + vec3 s = vec3(0.0); + vec3 v = wView; + vec3 h = vec3(0.0); + + float vDotN = dot(v, n); + float sDotN = 0.0; + float sDotH = 0.0; + float att = 1.0; + + if (lights[lightIndex].type != TYPE_DIRECTIONAL) { + // Point and Spot lights + vec3 sUnnormalized = vec3(lights[lightIndex].position) - wPosition; + s = normalize(sUnnormalized); + + // Calculate the attenuation factor + sDotN = dot(s, n); + if (sDotN > 0.0) { + if (lights[lightIndex].constantAttenuation != 0.0 + || lights[lightIndex].linearAttenuation != 0.0 + || lights[lightIndex].quadraticAttenuation != 0.0) { + float dist = length(sUnnormalized); + att = 1.0 / (lights[lightIndex].constantAttenuation + + lights[lightIndex].linearAttenuation * dist + + lights[lightIndex].quadraticAttenuation * dist * dist); + } + + // The light direction is in world space already + if (lights[lightIndex].type == TYPE_SPOT) { + // Check if fragment is inside or outside of the spot light cone + if (degrees(acos(dot(-s, lights[lightIndex].direction))) > lights[lightIndex].cutOffAngle) + sDotN = 0.0; + } + } + } else { + // Directional lights + // The light direction is in world space already + s = normalize(-lights[lightIndex].direction); + sDotN = dot(s, n); + } + + h = normalize(s + v); + sDotH = dot(s, h); + + // Calculate diffuse component + vec3 diffuseColor = (1.0 - metalness) * baseColor * lights[lightIndex].color; + vec3 diffuse = diffuseColor * max(sDotN, 0.0) / 3.14159; + + // Calculate specular component + vec3 dielectricColor = vec3(0.04); + vec3 F0 = mix(dielectricColor, baseColor, metalness); + vec3 specularFactor = vec3(0.0); + if (sDotN > 0.0) { + specularFactor = specularModel(F0, sDotH, sDotN, vDotN, n, h); + specularFactor *= normalDistribution(n, h, alpha); + } + vec3 specularColor = lights[lightIndex].color; + vec3 specular = specularColor * specularFactor; + + // Blend between diffuse and specular to conserver energy + return att * lights[lightIndex].intensity * (specular + diffuse * (vec3(1.0) - specular)); +} + +vec3 pbrIblModel(const in vec3 wNormal, + const in vec3 wView, + const in vec3 baseColor, + const in float metalness, + const in float alpha) +{ + // Calculate reflection direction of view vector about surface normal + // vector in world space. This is used in the fragment shader to sample + // from the environment textures for a light source. This is equivalent + // to the l vector for punctual light sources. Armed with this, calculate + // the usual factors needed + vec3 n = wNormal; + vec3 l = reflect(-wView, n); + vec3 v = wView; + vec3 h = normalize(l + v); + float vDotN = dot(v, n); + float lDotN = dot(l, n); + float lDotH = dot(l, h); + + // Calculate diffuse component + vec3 diffuseColor = (1.0 - metalness) * baseColor; + vec3 diffuse = diffuseColor * texture(envLight.irradiance, l).rgb; + + // Calculate specular component + vec3 dielectricColor = vec3(0.04); + vec3 F0 = mix(dielectricColor, baseColor, metalness); + vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h); + + // 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 + float lod = alphaToMipLevel(alpha); +//#define DEBUG_SPECULAR_LODS +#ifdef DEBUG_SPECULAR_LODS + if (lod > 7.0) + return vec3(1.0, 0.0, 0.0); + else if (lod > 6.0) + return vec3(1.0, 0.333, 0.0); + else if (lod > 5.0) + return vec3(1.0, 1.0, 0.0); + else if (lod > 4.0) + return vec3(0.666, 1.0, 0.0); + else if (lod > 3.0) + return vec3(0.0, 1.0, 0.666); + else if (lod > 2.0) + return vec3(0.0, 0.666, 1.0); + else if (lod > 1.0) + return vec3(0.0, 0.0, 1.0); + else if (lod > 0.0) + return vec3(1.0, 0.0, 1.0); +#endif + vec3 specularSkyColor = textureLod(envLight.specular, l, lod).rgb; + vec3 specular = specularSkyColor * specularFactor; + + // Blend between diffuse and specular to conserve energy + return specular + diffuse * (vec3(1.0) - specularFactor); +} + +vec3 toneMap(const in vec3 c) +{ + return c / (c + vec3(1.0)); +} + +vec3 gammaCorrect(const in vec3 color) +{ + return pow(color, vec3(1.0 / gamma)); +} + +void main() +{ + vec3 cLinear = vec3(0.0); + + // Remap roughness for a perceptually more linear correspondence + float alpha = remapRoughness(roughness); + + + vec3 wNormal = normalize(worldNormal); + vec3 worldView = normalize(eyePosition - worldPosition); + for (int i = 0; i < envLightCount; ++i) { + cLinear += pbrIblModel(wNormal, + worldView, + baseColor.rgb, + metalness, + alpha); + } + + for (int i = 0; i < lightCount; ++i) { + cLinear += pbrModel(i, + worldPosition, + wNormal, + worldView, + baseColor.rgb, + metalness, + alpha); + } + + // Apply exposure correction + cLinear *= pow(2.0, exposure); + + // Apply simple (Reinhard) tonemap transform to get into LDR range [0, 1] + vec3 cToneMapped = toneMap(cLinear); + + // Apply gamma correction prior to display + vec3 cGamma = gammaCorrect(cToneMapped); + fragColor = vec4(cGamma, 1.0); +} diff --git a/src/extras/shaders/gl3/skybox.frag b/src/extras/shaders/gl3/skybox.frag index 99c8f111b..931e20343 100644 --- a/src/extras/shaders/gl3/skybox.frag +++ b/src/extras/shaders/gl3/skybox.frag @@ -4,7 +4,21 @@ in vec3 texCoord0; out vec4 fragColor; uniform samplerCube skyboxTexture; +// Gamma correction +uniform float gamma = 2.2; + +uniform float gammaStrength; + +vec3 gammaCorrect(const in vec3 color) +{ + return pow(color, vec3(1.0 / gamma)); +} + void main() { - fragColor = texture(skyboxTexture, texCoord0); + vec4 baseColor = texture(skyboxTexture, texCoord0); + vec4 gammaColor = vec4(gammaCorrect(baseColor.rgb), 1.0); + // This is an odd way to enable or not gamma correction, + // but this is a way to avoid branching until we can generate shaders + fragColor = mix(baseColor, gammaColor, gammaStrength); } diff --git a/src/extras/text/areaallocator.cpp b/src/extras/text/areaallocator.cpp new file mode 100644 index 000000000..61f1d5bc6 --- /dev/null +++ b/src/extras/text/areaallocator.cpp @@ -0,0 +1,296 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "areaallocator_p.h" + +#include <QtCore/qglobal.h> +#include <QtCore/qrect.h> +#include <QtCore/qpoint.h> + +// +// This file is copied from qtdeclarative/src/quick/scenegraph/util/qsgareaallocator.cpp +// + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +namespace +{ + enum SplitType + { + VerticalSplit, + HorizontalSplit + }; + + static const int maxMargin = 2; +} + +struct AreaAllocatorNode +{ + AreaAllocatorNode(AreaAllocatorNode *parent); + ~AreaAllocatorNode(); + inline bool isLeaf(); + + AreaAllocatorNode *parent; + AreaAllocatorNode *left; + AreaAllocatorNode *right; + int split; // only valid for inner nodes. + SplitType splitType; + bool isOccupied; // only valid for leaf nodes. +}; + +AreaAllocatorNode::AreaAllocatorNode(AreaAllocatorNode *parent) + : parent(parent) + , left(0) + , right(0) + , isOccupied(false) +{ +} + +AreaAllocatorNode::~AreaAllocatorNode() +{ + delete left; + delete right; +} + +bool AreaAllocatorNode::isLeaf() +{ + Q_ASSERT((left != 0) == (right != 0)); + return !left; +} + + +AreaAllocator::AreaAllocator(const QSize &size) : m_size(size) +{ + m_root = new AreaAllocatorNode(0); +} + +AreaAllocator::~AreaAllocator() +{ + delete m_root; +} + +QRect AreaAllocator::allocate(const QSize &size) +{ + QPoint point; + bool result = allocateInNode(size, point, QRect(QPoint(0, 0), m_size), m_root); + return result ? QRect(point, size) : QRect(); +} + +bool AreaAllocator::deallocate(const QRect &rect) +{ + return deallocateInNode(rect.topLeft(), m_root); +} + +bool AreaAllocator::allocateInNode(const QSize &size, QPoint &result, const QRect ¤tRect, AreaAllocatorNode *node) +{ + if (size.width() > currentRect.width() || size.height() > currentRect.height()) + return false; + + if (node->isLeaf()) { + if (node->isOccupied) + return false; + if (size.width() + maxMargin >= currentRect.width() && size.height() + maxMargin >= currentRect.height()) { + //Snug fit, occupy entire rectangle. + node->isOccupied = true; + result = currentRect.topLeft(); + return true; + } + // TODO: Reuse nodes. + // Split node. + node->left = new AreaAllocatorNode(node); + node->right = new AreaAllocatorNode(node); + QRect splitRect = currentRect; + if ((currentRect.width() - size.width()) * currentRect.height() < (currentRect.height() - size.height()) * currentRect.width()) { + node->splitType = HorizontalSplit; + node->split = currentRect.top() + size.height(); + splitRect.setHeight(size.height()); + } else { + node->splitType = VerticalSplit; + node->split = currentRect.left() + size.width(); + splitRect.setWidth(size.width()); + } + return allocateInNode(size, result, splitRect, node->left); + } else { + // TODO: avoid unnecessary recursion. + // has been split. + QRect leftRect = currentRect; + QRect rightRect = currentRect; + if (node->splitType == HorizontalSplit) { + leftRect.setHeight(node->split - leftRect.top()); + rightRect.setTop(node->split); + } else { + leftRect.setWidth(node->split - leftRect.left()); + rightRect.setLeft(node->split); + } + if (allocateInNode(size, result, leftRect, node->left)) + return true; + if (allocateInNode(size, result, rightRect, node->right)) + return true; + return false; + } +} + +bool AreaAllocator::deallocateInNode(const QPoint &pos, AreaAllocatorNode *node) +{ + while (!node->isLeaf()) { + // has been split. + int cmp = node->splitType == HorizontalSplit ? pos.y() : pos.x(); + node = cmp < node->split ? node->left : node->right; + } + if (!node->isOccupied) + return false; + node->isOccupied = false; + mergeNodeWithNeighbors(node); + return true; +} + +void AreaAllocator::mergeNodeWithNeighbors(AreaAllocatorNode *node) +{ + bool done = false; + AreaAllocatorNode *parent = 0; + AreaAllocatorNode *current = 0; + AreaAllocatorNode *sibling; + while (!done) { + Q_ASSERT(node->isLeaf()); + Q_ASSERT(!node->isOccupied); + if (node->parent == 0) + return; // No neighbors. + + SplitType splitType = SplitType(node->parent->splitType); + done = true; + + /* Special case. Might be faster than going through the general code path. + // Merge with sibling. + parent = node->parent; + sibling = (node == parent->left ? parent->right : parent->left); + if (sibling->isLeaf() && !sibling->isOccupied) { + Q_ASSERT(!sibling->right); + node = parent; + parent->isOccupied = false; + delete parent->left; + delete parent->right; + parent->left = parent->right = 0; + done = false; + continue; + } + */ + + // Merge with left neighbor. + current = node; + parent = current->parent; + while (parent && current == parent->left && parent->splitType == splitType) { + current = parent; + parent = parent->parent; + } + + if (parent && parent->splitType == splitType) { + Q_ASSERT(current == parent->right); + Q_ASSERT(parent->left); + + AreaAllocatorNode *neighbor = parent->left; + while (neighbor->right && neighbor->splitType == splitType) + neighbor = neighbor->right; + + if (neighbor->isLeaf() && neighbor->parent->splitType == splitType && !neighbor->isOccupied) { + // Left neighbor can be merged. + parent->split = neighbor->parent->split; + + parent = neighbor->parent; + sibling = neighbor == parent->left ? parent->right : parent->left; + AreaAllocatorNode **nodeRef = &m_root; + if (parent->parent) { + if (parent == parent->parent->left) + nodeRef = &parent->parent->left; + else + nodeRef = &parent->parent->right; + } + sibling->parent = parent->parent; + *nodeRef = sibling; + parent->left = parent->right = 0; + delete parent; + delete neighbor; + done = false; + } + } + + // Merge with right neighbor. + current = node; + parent = current->parent; + while (parent && current == parent->right && parent->splitType == splitType) { + current = parent; + parent = parent->parent; + } + + if (parent && parent->splitType == splitType) { + Q_ASSERT(current == parent->left); + Q_ASSERT(parent->right); + + AreaAllocatorNode *neighbor = parent->right; + while (neighbor->left && neighbor->splitType == splitType) + neighbor = neighbor->left; + + if (neighbor->isLeaf() && neighbor->parent->splitType == splitType && !neighbor->isOccupied) { + // Right neighbor can be merged. + parent->split = neighbor->parent->split; + + parent = neighbor->parent; + sibling = neighbor == parent->left ? parent->right : parent->left; + AreaAllocatorNode **nodeRef = &m_root; + if (parent->parent) { + if (parent == parent->parent->left) + nodeRef = &parent->parent->left; + else + nodeRef = &parent->parent->right; + } + sibling->parent = parent->parent; + *nodeRef = sibling; + parent->left = parent->right = 0; + delete parent; + delete neighbor; + done = false; + } + } + } // end while (!done) +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/text/areaallocator_p.h b/src/extras/text/areaallocator_p.h new file mode 100644 index 000000000..809c5c698 --- /dev/null +++ b/src/extras/text/areaallocator_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_AREAALLOCATOR_P_H +#define QT3DEXTRAS_AREAALLOCATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +// +// This file is copied from qtdeclarative/src/quick/scenegraph/util/qsgareaallocator_p.h +// + +#include <QtCore/qsize.h> + +QT_BEGIN_NAMESPACE + +class QRect; +class QPoint; + +namespace Qt3DExtras { + +struct AreaAllocatorNode; + +class AreaAllocator +{ +public: + AreaAllocator(const QSize &size); + ~AreaAllocator(); + + QRect allocate(const QSize &size); + bool deallocate(const QRect &rect); + bool isEmpty() const { return m_root == 0; } + QSize size() const { return m_size; } +private: + bool allocateInNode(const QSize &size, QPoint &result, const QRect ¤tRect, AreaAllocatorNode *node); + bool deallocateInNode(const QPoint &pos, AreaAllocatorNode *node); + void mergeNodeWithNeighbors(AreaAllocatorNode *node); + + AreaAllocatorNode *m_root; + QSize m_size; +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_AREAALLOCATOR_P_H diff --git a/src/extras/text/distancefieldtextrenderer.cpp b/src/extras/text/distancefieldtextrenderer.cpp new file mode 100644 index 000000000..9f390e8da --- /dev/null +++ b/src/extras/text/distancefieldtextrenderer.cpp @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <Qt3DRender/qmaterial.h> +#include <Qt3DRender/qbuffer.h> +#include <Qt3DRender/qattribute.h> +#include <Qt3DRender/qgeometry.h> +#include <Qt3DRender/qgeometryrenderer.h> + +#include <Qt3DExtras/private/qtext2dmaterial_p.h> + +#include "distancefieldtextrenderer_p.h" +#include "distancefieldtextrenderer_p_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +using namespace Qt3DCore; + +DistanceFieldTextRendererPrivate::DistanceFieldTextRendererPrivate() + : m_renderer(nullptr) + , m_geometry(nullptr) + , m_positionAttr(nullptr) + , m_texCoordAttr(nullptr) + , m_indexAttr(nullptr) + , m_vertexBuffer(nullptr) + , m_indexBuffer(nullptr) + , m_material(nullptr) +{ +} + +DistanceFieldTextRendererPrivate::~DistanceFieldTextRendererPrivate() +{ +} + +void DistanceFieldTextRendererPrivate::init() +{ + Q_Q(DistanceFieldTextRenderer); + + m_renderer = new Qt3DRender::QGeometryRenderer(q); + m_renderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); + + m_geometry = new Qt3DRender::QGeometry(m_renderer); + m_renderer->setGeometry(m_geometry); + + m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, m_geometry); + m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, m_geometry); + + m_positionAttr = new Qt3DRender::QAttribute(m_geometry); + m_positionAttr->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + m_positionAttr->setVertexBaseType(Qt3DRender::QAttribute::Float); + m_positionAttr->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + m_positionAttr->setVertexSize(3); + m_positionAttr->setByteStride(5 * sizeof(float)); + m_positionAttr->setByteOffset(0); + m_positionAttr->setBuffer(m_vertexBuffer); + + m_texCoordAttr = new Qt3DRender::QAttribute(m_geometry); + m_texCoordAttr->setName(Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName()); + m_texCoordAttr->setVertexBaseType(Qt3DRender::QAttribute::Float); + m_texCoordAttr->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + m_texCoordAttr->setVertexSize(2); + m_texCoordAttr->setByteStride(5 * sizeof(float)); + m_texCoordAttr->setByteOffset(3 * sizeof(float)); + m_texCoordAttr->setBuffer(m_vertexBuffer); + + m_indexAttr = new Qt3DRender::QAttribute(m_geometry); + m_indexAttr->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); + m_indexAttr->setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort); + m_indexAttr->setBuffer(m_indexBuffer); + + m_geometry->addAttribute(m_positionAttr); + m_geometry->setBoundingVolumePositionAttribute(m_positionAttr); + m_geometry->addAttribute(m_texCoordAttr); + m_geometry->addAttribute(m_indexAttr); + + m_material = new QText2DMaterial(q); + + q->addComponent(m_renderer); + q->addComponent(m_material); +} + +DistanceFieldTextRenderer::DistanceFieldTextRenderer(QNode *parent) + : QEntity(*new DistanceFieldTextRendererPrivate(), parent) +{ + Q_D(DistanceFieldTextRenderer); + d->init(); +} + +DistanceFieldTextRenderer::~DistanceFieldTextRenderer() +{ +} + +void DistanceFieldTextRenderer::setGlyphData(Qt3DRender::QAbstractTexture *glyphTexture, + const QVector<float> &vertexData, + const QVector<quint16> &indexData) +{ + Q_D(DistanceFieldTextRenderer); + + const int vertexCount = vertexData.size() / 5; + + d->m_vertexBuffer->setData(QByteArray((char*) vertexData.data(), vertexData.size() * sizeof(float))); + d->m_indexBuffer->setData(QByteArray((char*) indexData.data(), indexData.size() * sizeof(quint16))); + d->m_positionAttr->setCount(vertexCount); + d->m_texCoordAttr->setCount(vertexCount); + d->m_indexAttr->setCount(indexData.size()); + + d->m_material->setDistanceFieldTexture(glyphTexture); +} + +void DistanceFieldTextRenderer::setColor(const QColor &color) +{ + Q_D(DistanceFieldTextRenderer); + d->m_material->setColor(color); +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/text/distancefieldtextrenderer_p.h b/src/extras/text/distancefieldtextrenderer_p.h new file mode 100644 index 000000000..fdb9a836f --- /dev/null +++ b/src/extras/text/distancefieldtextrenderer_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_DISTANCEFIELDTEXTRENDERER_P_H +#define QT3DEXTRAS_DISTANCEFIELDTEXTRENDERER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QRectF> +#include <Qt3DCore/qnode.h> +#include <Qt3DCore/qentity.h> +#include <Qt3DExtras/qt3dextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { +class QAbstractTexture; +} + +namespace Qt3DExtras { + +class DistanceFieldTextRendererPrivate; + +class DistanceFieldTextRenderer : public Qt3DCore::QEntity +{ + Q_OBJECT + +public: + DistanceFieldTextRenderer(Qt3DCore::QNode *parent = nullptr); + ~DistanceFieldTextRenderer(); + + void setGlyphData(Qt3DRender::QAbstractTexture *glyphTexture, + const QVector<float> &vertexData, + const QVector<quint16> &indexData); + + void setColor(const QColor &color); + + Q_DECLARE_PRIVATE(DistanceFieldTextRenderer) +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_DISTANCEFIELDTEXTRENDERER_P_H diff --git a/src/extras/text/distancefieldtextrenderer_p_p.h b/src/extras/text/distancefieldtextrenderer_p_p.h new file mode 100644 index 000000000..af4bc4723 --- /dev/null +++ b/src/extras/text/distancefieldtextrenderer_p_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_DISTANCEFIELDTEXTRENDERER_P_P_H +#define QT3DEXTRAS_DISTANCEFIELDTEXTRENDERER_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/private/qentity_p.h> +#include <Qt3DExtras/private/distancefieldtextrenderer_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { +class QGeometryRenderer; +class QGeometry; +class QMaterial; +class QAttribute; +class QBuffer; +} + +namespace Qt3DExtras { + +class QText2DMaterial; + +class DistanceFieldTextRendererPrivate : public Qt3DCore::QEntityPrivate +{ +public: + DistanceFieldTextRendererPrivate(); + ~DistanceFieldTextRendererPrivate(); + + Q_DECLARE_PUBLIC(DistanceFieldTextRenderer) + + void init(); + + Qt3DRender::QGeometryRenderer *m_renderer; + Qt3DRender::QGeometry *m_geometry; + Qt3DRender::QAttribute *m_positionAttr; + Qt3DRender::QAttribute *m_texCoordAttr; + Qt3DRender::QAttribute *m_indexAttr; + Qt3DRender::QBuffer *m_vertexBuffer; + Qt3DRender::QBuffer *m_indexBuffer; + QText2DMaterial *m_material; +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_DISTANCEFIELDTEXTRENDERER_P_P_H diff --git a/src/extras/text/qdistancefieldglyphcache.cpp b/src/extras/text/qdistancefieldglyphcache.cpp new file mode 100644 index 000000000..99085f378 --- /dev/null +++ b/src/extras/text/qdistancefieldglyphcache.cpp @@ -0,0 +1,370 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/qrawfont.h> +#include <QtGui/qglyphrun.h> +#include <QtGui/private/qrawfont_p.h> + +#include "qdistancefieldglyphcache_p.h" +#include "qtextureatlas_p.h" + +#include <QtGui/qfont.h> +#include <QtGui/private/qdistancefield_p.h> +#include <Qt3DCore/private/qnode_p.h> +#include <Qt3DExtras/private/qtextureatlas_p.h> + +QT_BEGIN_NAMESPACE + +#define DEFAULT_IMAGE_PADDING 1 + +using namespace Qt3DCore; + +namespace Qt3DExtras { + +// ref-count glyphs and keep track of where they are stored +class StoredGlyph { +public: + StoredGlyph() = default; + StoredGlyph(const StoredGlyph &) = default; + StoredGlyph(const QRawFont &font, quint32 glyph, bool doubleResolution); + + int refCount() const { return m_ref; } + void ref() { ++m_ref; } + int deref() { return m_ref = std::max(m_ref - 1, (quint32) 0); } + + bool addToTextureAtlas(QTextureAtlas *atlas); + void removeFromTextureAtlas(); + + QTextureAtlas *atlas() const { return m_atlas; } + QRectF glyphPathBoundingRect() const { return m_glyphPathBoundingRect; } + QRectF texCoords() const; + +private: + quint32 m_glyph = (quint32) -1; + quint32 m_ref = 0; + QTextureAtlas *m_atlas = nullptr; + QTextureAtlas::TextureId m_atlasEntry = QTextureAtlas::InvalidTexture; + QRectF m_glyphPathBoundingRect; + QImage m_distanceFieldImage; // only used until added to texture atlas +}; + +// A DistanceFieldFont stores all glyphs for a given QRawFont. +// it will use multiple QTextureAtlasess to store the distance +// fields and uses ref-counting for each glyph to ensure that +// unused glyphs are removed from the texture atlasses. +class DistanceFieldFont +{ +public: + DistanceFieldFont(const QRawFont &font, bool doubleRes, Qt3DCore::QNode *parent); + ~DistanceFieldFont(); + + StoredGlyph findGlyph(quint32 glyph) const; + StoredGlyph refGlyph(quint32 glyph); + void derefGlyph(quint32 glyph); + + bool doubleGlyphResolution() const { return m_doubleGlyphResolution; } + +private: + QRawFont m_font; + bool m_doubleGlyphResolution; + Qt3DCore::QNode *m_parentNode; // parent node for the QTextureAtlasses + + QHash<quint32, StoredGlyph> m_glyphs; + + QVector<QTextureAtlas*> m_atlasses; +}; + +StoredGlyph::StoredGlyph(const QRawFont &font, quint32 glyph, bool doubleResolution) + : m_glyph(glyph) + , m_ref(1) + , m_atlas(nullptr) + , m_atlasEntry(QTextureAtlas::InvalidTexture) +{ + // create new single-channel distance field image for given glyph + const QPainterPath path = font.pathForGlyph(glyph); + const QDistanceField dfield(font, glyph, doubleResolution); + m_distanceFieldImage = dfield.toImage(QImage::Format_Alpha8); + + // scale bounding rect down (as in QSGDistanceFieldGlyphCache::glyphData()) + const QRectF pathBound = path.boundingRect(); + float f = 1.0f / QT_DISTANCEFIELD_SCALE(doubleResolution); + m_glyphPathBoundingRect = QRectF(pathBound.left() * f, -pathBound.top() * f, pathBound.width() * f, pathBound.height() * f); +} + +bool StoredGlyph::addToTextureAtlas(QTextureAtlas *atlas) +{ + if (m_atlas || m_distanceFieldImage.isNull()) + return false; + + const auto texId = atlas->addImage(m_distanceFieldImage, DEFAULT_IMAGE_PADDING); + if (texId != QTextureAtlas::InvalidTexture) { + m_atlas = atlas; + m_atlasEntry = texId; + m_distanceFieldImage = QImage(); // free glyph image data + return true; + } + + return false; +} + +void StoredGlyph::removeFromTextureAtlas() +{ + if (m_atlas) { + m_atlas->removeImage(m_atlasEntry); + m_atlas = nullptr; + m_atlasEntry = QTextureAtlas::InvalidTexture; + } +} + +QRectF StoredGlyph::texCoords() const +{ + return m_atlas ? m_atlas->imageTexCoords(m_atlasEntry) : QRectF(); +} + +DistanceFieldFont::DistanceFieldFont(const QRawFont &font, bool doubleRes, Qt3DCore::QNode *parent) + : m_font(font) + , m_doubleGlyphResolution(doubleRes) + , m_parentNode(parent) +{ +} + +DistanceFieldFont::~DistanceFieldFont() +{ + qDeleteAll(m_atlasses); +} + +StoredGlyph DistanceFieldFont::findGlyph(quint32 glyph) const +{ + const auto it = m_glyphs.find(glyph); + return (it != m_glyphs.cend()) ? it.value() : StoredGlyph(); +} + +StoredGlyph DistanceFieldFont::refGlyph(quint32 glyph) +{ + // if glyph already exists, just increase ref-count + auto it = m_glyphs.find(glyph); + if (it != m_glyphs.end()) { + it.value().ref(); + return it.value(); + } + + // need to create new glyph + StoredGlyph storedGlyph(m_font, glyph, m_doubleGlyphResolution); + + // see if one of the existing atlasses can hold the distance field image + for (int i = 0; i < m_atlasses.size(); i++) + if (storedGlyph.addToTextureAtlas(m_atlasses[i])) + break; + + // if no texture atlas is big enough (or no exists yet), allocate a new one + if (!storedGlyph.atlas()) { + // this should be enough to store 40-60 glyphs, which should be sufficient for most + // scenarios + const int size = m_doubleGlyphResolution ? 512 : 256; + + QTextureAtlas *atlas = new QTextureAtlas(m_parentNode); + atlas->setWidth(size); + atlas->setHeight(size); + atlas->setFormat(Qt3DRender::QAbstractTexture::R8_UNorm); + atlas->setPixelFormat(QOpenGLTexture::Red); + atlas->setMinificationFilter(Qt3DRender::QAbstractTexture::Linear); + atlas->setMagnificationFilter(Qt3DRender::QAbstractTexture::Linear); + m_atlasses << atlas; + + if (!storedGlyph.addToTextureAtlas(atlas)) + qWarning() << Q_FUNC_INFO << "Couldn't add glyph to newly allocated atlas. Glyph could be huge?"; + } + + m_glyphs.insert(glyph, storedGlyph); + return storedGlyph; +} + +void DistanceFieldFont::derefGlyph(quint32 glyph) +{ + auto it = m_glyphs.find(glyph); + if (it == m_glyphs.end()) + return; + + // TODO + // possible optimization: keep unreferenced glyphs as the texture atlas + // still has space. only if a new glyph needs to be allocated, and there + // is no more space within the atlas, then we can actually remove the glyphs + // from the atlasses. + + // remove glyph if no refs anymore + if (it.value().deref() <= 0) { + QTextureAtlas *atlas = it.value().atlas(); + it.value().removeFromTextureAtlas(); + + // remove atlas, if it contains no glyphs anymore + if (atlas && atlas->imageCount() == 0) { + Q_ASSERT(m_atlasses.contains(atlas)); + + m_atlasses.removeAll(atlas); + delete atlas; + } + + m_glyphs.erase(it); + } +} + +// copied from QSGDistanceFieldGlyphCacheManager::fontKey +// we use this function to compare QRawFonts, as QRawFont doesn't +// implement a stable comparison function +QString QDistanceFieldGlyphCache::fontKey(const QRawFont &font) +{ + QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine; + if (!fe->faceId().filename.isEmpty()) { + QByteArray keyName = fe->faceId().filename; + if (font.style() != QFont::StyleNormal) + keyName += QByteArray(" I"); + if (font.weight() != QFont::Normal) + keyName += ' ' + QByteArray::number(font.weight()); + keyName += QByteArray(" DF"); + return QString::fromUtf8(keyName); + } else { + return QString::fromLatin1("%1_%2_%3_%4") + .arg(font.familyName()) + .arg(font.styleName()) + .arg(font.weight()) + .arg(font.style()); + } +} + +DistanceFieldFont* QDistanceFieldGlyphCache::getOrCreateDistanceFieldFont(const QRawFont &font) +{ + // return, if font already exists (make sure to only create one DistanceFieldFont for + // each unique QRawFont, by building a hash on the QRawFont that ignores the font size) + const QString key = fontKey(font); + const auto it = m_fonts.constFind(key); + if (it != m_fonts.cend()) + return it.value(); + + // logic taken from QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache + QRawFontPrivate *fontD = QRawFontPrivate::get(font); + const int glyphCount = fontD->fontEngine->glyphCount(); + const bool useDoubleRes = qt_fontHasNarrowOutlines(font) && glyphCount < QT_DISTANCEFIELD_HIGHGLYPHCOUNT(); + + // only keep one FontCache with a fixed pixel size for each distinct font type + QRawFont actualFont = font; + actualFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(useDoubleRes) * QT_DISTANCEFIELD_SCALE(useDoubleRes)); + + // create new font cache + DistanceFieldFont *dff = new DistanceFieldFont(actualFont, useDoubleRes, m_rootNode); + m_fonts.insert(key, dff); + return dff; +} + +QDistanceFieldGlyphCache::QDistanceFieldGlyphCache() + : m_rootNode(nullptr) +{ +} + +QDistanceFieldGlyphCache::~QDistanceFieldGlyphCache() +{ +} + +void QDistanceFieldGlyphCache::setRootNode(QNode *rootNode) +{ + m_rootNode = rootNode; +} + +QNode *QDistanceFieldGlyphCache::rootNode() const +{ + return m_rootNode; +} + +bool QDistanceFieldGlyphCache::doubleGlyphResolution(const QRawFont &font) +{ + return getOrCreateDistanceFieldFont(font)->doubleGlyphResolution(); +} + +namespace { +QDistanceFieldGlyphCache::Glyph refAndGetGlyph(DistanceFieldFont *dff, quint32 glyph) +{ + QDistanceFieldGlyphCache::Glyph ret; + + if (dff) { + const auto entry = dff->refGlyph(glyph); + + if (entry.atlas()) { + ret.glyphPathBoundingRect = entry.glyphPathBoundingRect(); + ret.texCoords = entry.texCoords(); + ret.texture = entry.atlas(); + } + } + + return ret; +} +} // anonymous + +QVector<QDistanceFieldGlyphCache::Glyph> QDistanceFieldGlyphCache::refGlyphs(const QGlyphRun &run) +{ + DistanceFieldFont *dff = getOrCreateDistanceFieldFont(run.rawFont()); + QVector<QDistanceFieldGlyphCache::Glyph> ret; + + const QVector<quint32> glyphs = run.glyphIndexes(); + for (quint32 glyph : glyphs) + ret << refAndGetGlyph(dff, glyph); + + return ret; +} + +QDistanceFieldGlyphCache::Glyph QDistanceFieldGlyphCache::refGlyph(const QRawFont &font, quint32 glyph) +{ + return refAndGetGlyph(getOrCreateDistanceFieldFont(font), glyph); +} + +void QDistanceFieldGlyphCache::derefGlyphs(const QGlyphRun &run) +{ + DistanceFieldFont *dff = getOrCreateDistanceFieldFont(run.rawFont()); + + const QVector<quint32> glyphs = run.glyphIndexes(); + for (quint32 glyph : glyphs) + dff->derefGlyph(glyph); +} + +void QDistanceFieldGlyphCache::derefGlyph(const QRawFont &font, quint32 glyph) +{ + getOrCreateDistanceFieldFont(font)->derefGlyph(glyph); +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/text/qdistancefieldglyphcache_p.h b/src/extras/text/qdistancefieldglyphcache_p.h new file mode 100644 index 000000000..6ca011c76 --- /dev/null +++ b/src/extras/text/qdistancefieldglyphcache_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QDISTANCEFIELDGLYPHCACHE_P_H +#define QT3DEXTRAS_QDISTANCEFIELDGLYPHCACHE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QRectF> +#include <Qt3DCore/qnode.h> +#include <Qt3DExtras/qt3dextras_global.h> + +QT_BEGIN_NAMESPACE + +class QRawFont; +class QGlyphRun; + +namespace Qt3DCore { +class QNode; +} + +namespace Qt3DRender { +class QAbstractTexture; +} + +namespace Qt3DExtras { + +class DistanceFieldFont; +class QDistanceFieldGlyphCachePrivate; + +class QDistanceFieldGlyphCache +{ +public: + QDistanceFieldGlyphCache(); + ~QDistanceFieldGlyphCache(); + + void setRootNode(Qt3DCore::QNode *rootNode); + Qt3DCore::QNode *rootNode() const; + + struct Glyph { + Qt3DRender::QAbstractTexture *texture = nullptr; + QRectF glyphPathBoundingRect; // bounding rect of the QPainterPath used to draw the glyph + QRectF texCoords; // texture coordinates within texture + }; + + bool doubleGlyphResolution(const QRawFont &font); + + QVector<Glyph> refGlyphs(const QGlyphRun &run); + Glyph refGlyph(const QRawFont &font, quint32 glyph); + + void derefGlyphs(const QGlyphRun &run); + void derefGlyph(const QRawFont &font, quint32 glyph); + +private: + DistanceFieldFont* getOrCreateDistanceFieldFont(const QRawFont &font); + static QString fontKey(const QRawFont &font); + + QHash<QString, DistanceFieldFont*> m_fonts; + Qt3DCore::QNode *m_rootNode; +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QDISTANCEFIELDGLYPHCACHE_P_H diff --git a/src/extras/text/qtext2dentity.cpp b/src/extras/text/qtext2dentity.cpp new file mode 100644 index 000000000..dbd4368bc --- /dev/null +++ b/src/extras/text/qtext2dentity.cpp @@ -0,0 +1,381 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtext2dentity.h" +#include "qtext2dentity_p.h" +#include "qtext2dmaterial_p.h" + +#include <QtGui/qtextlayout.h> +#include <QtGui/qglyphrun.h> +#include <QtGui/private/qdistancefield_p.h> +#include <QtGui/private/qtextureglyphcache_p.h> +#include <QtGui/private/qfont_p.h> +#include <QtGui/private/qdistancefield_p.h> + +#include <Qt3DRender/qmaterial.h> +#include <Qt3DRender/qbuffer.h> +#include <Qt3DRender/qattribute.h> +#include <Qt3DRender/qgeometry.h> +#include <Qt3DRender/qgeometryrenderer.h> + +#include <Qt3DCore/private/qscene_p.h> + +QT_BEGIN_NAMESPACE + +namespace { + +inline Q_DECL_CONSTEXPR QRectF scaleRectF(const QRectF &rect, float scale) +{ + return QRectF(rect.left() * scale, rect.top() * scale, rect.width() * scale, rect.height() * scale); +} + +} // anonymous + +namespace Qt3DExtras { + +QHash<Qt3DCore::QScene *, QText2DEntityPrivate::CacheEntry> QText2DEntityPrivate::m_glyphCacheInstances; + +QText2DEntityPrivate::QText2DEntityPrivate() + : m_glyphCache(nullptr) + , m_font(QLatin1String("Times"), 10) + , m_scaledFont(QLatin1String("Times"), 10) + , m_color(QColor(255, 255, 255, 255)) + , m_width(0.0f) + , m_height(0.0f) +{ +} + +QText2DEntityPrivate::~QText2DEntityPrivate() +{ +} + +void QText2DEntityPrivate::setScene(Qt3DCore::QScene *scene) +{ + if (scene == m_scene) + return; + + // Unref old glyph cache if it exists + if (m_scene != nullptr) { + m_glyphCache = nullptr; + QText2DEntityPrivate::CacheEntry &entry = QText2DEntityPrivate::m_glyphCacheInstances[m_scene]; + --entry.count; + if (entry.count == 0 && entry.glyphCache != nullptr) { + delete entry.glyphCache; + entry.glyphCache = nullptr; + } + } + + QEntityPrivate::setScene(scene); + + // Ref new glyph cache is scene is valid + if (scene != nullptr) { + QText2DEntityPrivate::CacheEntry &entry = QText2DEntityPrivate::m_glyphCacheInstances[scene]; + if (entry.glyphCache == nullptr) { + entry.glyphCache = new QDistanceFieldGlyphCache(); + entry.glyphCache->setRootNode(scene->rootNode()); + } + m_glyphCache = entry.glyphCache; + ++entry.count; + // Update to populate glyphCache if needed + update(); + } +} + +QText2DEntity::QText2DEntity(QNode *parent) + : Qt3DCore::QEntity(*new QText2DEntityPrivate(), parent) +{ +} + +QText2DEntity::~QText2DEntity() +{ +} + +float QText2DEntityPrivate::computeActualScale() const +{ + // scale font based on fontScale property and given QFont + float scale = 1.0f; + if (m_font.pointSizeF() > 0) + scale *= m_font.pointSizeF() / m_scaledFont.pointSizeF(); + return scale; +} + +struct RenderData { + int vertexCount = 0; + QVector<float> vertex; + QVector<quint16> index; +}; + +void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs) +{ + if (runs.isEmpty()) + return; + + // For each distinct texture, we need a separate DistanceFieldTextRenderer, + // for which we need vertex and index data + QHash<Qt3DRender::QAbstractTexture*, RenderData> renderData; + + const float scale = computeActualScale(); + + // process glyph runs + for (const QGlyphRun &run : runs) { + const QVector<quint32> glyphs = run.glyphIndexes(); + const QVector<QPointF> pos = run.positions(); + + Q_ASSERT(glyphs.size() == pos.size()); + + const bool doubleGlyphResolution = m_glyphCache->doubleGlyphResolution(run.rawFont()); + + // faithfully copied from QSGDistanceFieldGlyphNode::updateGeometry() + const float pixelSize = run.rawFont().pixelSize(); + const float fontScale = pixelSize / QT_DISTANCEFIELD_BASEFONTSIZE(doubleGlyphResolution); + const float margin = QT_DISTANCEFIELD_RADIUS(doubleGlyphResolution) / QT_DISTANCEFIELD_SCALE(doubleGlyphResolution) * fontScale; + + for (int i = 0; i < glyphs.size(); i++) { + const QDistanceFieldGlyphCache::Glyph &dfield = m_glyphCache->refGlyph(run.rawFont(), glyphs[i]); + + if (!dfield.texture) + continue; + + RenderData &data = renderData[dfield.texture]; + + // faithfully copied from QSGDistanceFieldGlyphNode::updateGeometry() + QRectF metrics = scaleRectF(dfield.glyphPathBoundingRect, fontScale); + metrics.adjust(-margin, margin, margin, 3*margin); + + const float top = 0.0f; + const float left = 0.0f; + const float right = m_width; + const float bottom = m_height; + + float x1 = left + scale * (pos[i].x() + metrics.left()); + float y2 = bottom - scale * (pos[i].y() - metrics.top()); + float x2 = x1 + scale * metrics.width(); + float y1 = y2 - scale * metrics.height(); + + // only draw glyphs that are at least partly visible + if (y2 < top || x1 > right) + continue; + + QRectF texCoords = dfield.texCoords; + + // if a glyph is only partly visible within the given rectangle, + // cut it in half and adjust tex coords + if (y1 < top) { + const float insideRatio = (top - y2) / (y1 - y2); + y1 = top; + texCoords.setHeight(texCoords.height() * insideRatio); + } + + // do the same thing horizontally + if (x2 > right) { + const float insideRatio = (right - x1) / (x2 - x1); + x2 = right; + texCoords.setWidth(texCoords.width() * insideRatio); + } + + data.vertex << x1 << y1 << 0.f << texCoords.left() << texCoords.bottom(); + data.vertex << x1 << y2 << 0.f << texCoords.left() << texCoords.top(); + data.vertex << x2 << y1 << 0.f << texCoords.right() << texCoords.bottom(); + data.vertex << x2 << y2 << 0.f << texCoords.right() << texCoords.top(); + + data.index << data.vertexCount << data.vertexCount+3 << data.vertexCount+1; + data.index << data.vertexCount << data.vertexCount+2 << data.vertexCount+3; + + data.vertexCount += 4; + } + } + + // make sure we have the correct number of DistanceFieldTextRenderers + // TODO: we might keep one renderer at all times, so we won't delete and + // re-allocate one every time the text changes from an empty to a non-empty string + // and vice-versa + while (m_renderers.size() > renderData.size()) + delete m_renderers.takeLast(); + + while (m_renderers.size() < renderData.size()) { + DistanceFieldTextRenderer *renderer = new DistanceFieldTextRenderer(q_func()); + renderer->setColor(m_color); + m_renderers << renderer; + } + + Q_ASSERT(m_renderers.size() == renderData.size()); + + // assign vertex data for all textures to the renderers + int rendererIdx = 0; + for (auto it = renderData.begin(); it != renderData.end(); ++it) { + m_renderers[rendererIdx++]->setGlyphData(it.key(), it.value().vertex, it.value().index); + } + + // de-ref all glyphs for previous QGlyphRuns + for (int i = 0; i < m_currentGlyphRuns.size(); i++) + m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]); + m_currentGlyphRuns = runs; +} + +void QText2DEntityPrivate::update() +{ + if (m_glyphCache == nullptr) + return; + + QVector<QGlyphRun> glyphRuns; + + // collect all GlyphRuns generated by the QTextLayout + if ((m_width > 0.0f || m_height > 0.0f) && !m_text.isEmpty()) { + QTextLayout layout(m_text, m_scaledFont); + const float lineWidth = m_width / computeActualScale(); + float height = 0; + layout.beginLayout(); + + while (true) { + QTextLine line = layout.createLine(); + if (!line.isValid()) + break; + + // position current line + line.setLineWidth(lineWidth); + line.setPosition(QPointF(0, height)); + height += line.height(); + + // add glyph runs created by line + const QList<QGlyphRun> runs = line.glyphRuns(); + for (const QGlyphRun &run : runs) + glyphRuns << run; + } + + layout.endLayout(); + } + + setCurrentGlyphRuns(glyphRuns); +} + +QFont QText2DEntity::font() const +{ + Q_D(const QText2DEntity); + return d->m_font; +} + +void QText2DEntity::setFont(const QFont &font) +{ + Q_D(QText2DEntity); + if (d->m_font != font) { + // ignore the point size of the font, just make it a default value. + // still we want to make sure that font() returns the same value + // that was passed to setFont(), so we store it nevertheless + d->m_font = font; + d->m_scaledFont = font; + d->m_scaledFont.setPointSize(10); + + emit fontChanged(font); + + if (!d->m_text.isEmpty()) + d->update(); + } +} + +QColor QText2DEntity::color() const +{ + Q_D(const QText2DEntity); + return d->m_color; +} + +void QText2DEntity::setColor(const QColor &color) +{ + Q_D(QText2DEntity); + if (d->m_color != color) { + d->m_color = color; + + emit colorChanged(color); + + for (DistanceFieldTextRenderer *renderer : qAsConst(d->m_renderers)) + renderer->setColor(color); + } +} + +QString QText2DEntity::text() const +{ + Q_D(const QText2DEntity); + return d->m_text; +} + +void QText2DEntity::setText(const QString &text) +{ + Q_D(QText2DEntity); + if (d->m_text != text) { + d->m_text = text; + emit textChanged(text); + + d->update(); + } +} + +float QText2DEntity::width() const +{ + Q_D(const QText2DEntity); + return d->m_width; +} + +float QText2DEntity::height() const +{ + Q_D(const QText2DEntity); + return d->m_height; +} + +void QText2DEntity::setWidth(float width) +{ + Q_D(QText2DEntity); + if (width != d->m_width) { + d->m_width = width; + emit widthChanged(width); + d->update(); + } +} + +void QText2DEntity::setHeight(float height) +{ + Q_D(QText2DEntity); + if (height != d->m_height) { + d->m_height = height; + emit heightChanged(height); + d->update(); + } +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/text/qtext2dentity.h b/src/extras/text/qtext2dentity.h new file mode 100644 index 000000000..39be91a0f --- /dev/null +++ b/src/extras/text/qtext2dentity.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXT2DENTITY_H +#define QT3DEXTRAS_QTEXT2DENTITY_H + +#include <QtCore/qrect.h> +#include <QtGui/qcolor.h> +#include <QtGui/qfont.h> +#include <Qt3DCore/qentity.h> +#include <Qt3DExtras/qt3dextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QText2DEntityPrivate; + +class QT3DEXTRASSHARED_EXPORT QText2DEntity : public Qt3DCore::QEntity +{ + Q_OBJECT + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + Q_PROPERTY(float width READ width WRITE setWidth NOTIFY widthChanged) + Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged) + +public: + explicit QText2DEntity(Qt3DCore::QNode *parent = nullptr); + ~QText2DEntity(); + + QFont font() const; + void setFont(const QFont &font); + + QColor color() const; + void setColor(const QColor &color); + + QString text() const; + void setText(const QString &text); + + float width() const; + float height() const; + + void setWidth(float width); + void setHeight(float height); + +Q_SIGNALS: + void fontChanged(const QFont &font); + void colorChanged(const QColor &color); + void textChanged(const QString &text); + void widthChanged(float width); + void heightChanged(float height); + +private: + Q_DECLARE_PRIVATE(QText2DEntity) +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXT2DENTITY_H diff --git a/src/extras/text/qtext2dentity_p.h b/src/extras/text/qtext2dentity_p.h new file mode 100644 index 000000000..863431091 --- /dev/null +++ b/src/extras/text/qtext2dentity_p.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXT2DENTITY_P_H +#define QT3DEXTRAS_QTEXT2DENTITY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/private/qentity_p.h> +#include <Qt3DExtras/private/distancefieldtextrenderer_p.h> +#include <Qt3DExtras/private/qdistancefieldglyphcache_p.h> +#include <QFont> + +QT_BEGIN_NAMESPACE + +namespace Qt3DCore { +class QScene; +} + +namespace Qt3DRender { +class QGeometryRenderer; +class QGeometry; +class QMaterial; +class QAttribute; +class QBuffer; +} + +namespace Qt3DExtras { + +class QText2DMaterial; +class QText2DEntity; + +class QText2DEntityPrivate : public Qt3DCore::QEntityPrivate +{ +public: + QText2DEntityPrivate(); + ~QText2DEntityPrivate(); + + Q_DECLARE_PUBLIC(QText2DEntity) + + // keep track of the glyphs currently being displayed, + // to guarantee proper glyph ref-counting in the + // QDistanceFieldGlyphCache + QVector<QGlyphRun> m_currentGlyphRuns; + QDistanceFieldGlyphCache *m_glyphCache; + + void setScene(Qt3DCore::QScene *scene) Q_DECL_OVERRIDE; + + QFont m_font; + QFont m_scaledFont; // ignore point or pixel size, set to default value + + QColor m_color; + QString m_text; + float m_width; + float m_height; + + QVector<DistanceFieldTextRenderer*> m_renderers; + + float computeActualScale() const; + + void setCurrentGlyphRuns(const QVector<QGlyphRun> &runs); + void update(); + + struct CacheEntry + { + QDistanceFieldGlyphCache *glyphCache = nullptr; + int count = 0; + }; + + static QHash<Qt3DCore::QScene *, CacheEntry> m_glyphCacheInstances; +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXT2DENTITY_P_H diff --git a/src/extras/text/qtext2dmaterial.cpp b/src/extras/text/qtext2dmaterial.cpp new file mode 100644 index 000000000..d8bf312c4 --- /dev/null +++ b/src/extras/text/qtext2dmaterial.cpp @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2014 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtext2dmaterial_p.h" +#include "qtext2dmaterial_p_p.h" +#include <Qt3DRender/qfilterkey.h> +#include <Qt3DRender/qmaterial.h> +#include <Qt3DRender/qeffect.h> +#include <Qt3DRender/qtechnique.h> +#include <Qt3DRender/qshaderprogram.h> +#include <Qt3DRender/qparameter.h> +#include <Qt3DRender/qrenderpass.h> +#include <Qt3DRender/qgraphicsapifilter.h> +#include <Qt3DRender/qblendequation.h> +#include <Qt3DRender/qblendequationarguments.h> +#include <Qt3DRender/qdepthtest.h> +#include <Qt3DRender/qabstracttexture.h> +#include <QUrl> +#include <QVector3D> +#include <QVector4D> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +QText2DMaterialPrivate::QText2DMaterialPrivate() + : QMaterialPrivate() + , m_effect(new Qt3DRender::QEffect()) + , m_distanceFieldTexture(nullptr) + , m_textureParameter(new Qt3DRender::QParameter(QStringLiteral("distanceFieldTexture"), QVariant(0))) + , m_textureSizeParameter(new Qt3DRender::QParameter(QStringLiteral("textureSize"), QVariant(256.f))) + , m_colorParameter(new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(255, 255, 255, 255)))) + , m_gl3Technique(new Qt3DRender::QTechnique()) + , m_gl2Technique(new Qt3DRender::QTechnique()) + , m_es2Technique(new Qt3DRender::QTechnique()) + , m_gl3RenderPass(new Qt3DRender::QRenderPass()) + , m_gl2RenderPass(new Qt3DRender::QRenderPass()) + , m_es2RenderPass(new Qt3DRender::QRenderPass()) + , m_gl3ShaderProgram(new Qt3DRender::QShaderProgram()) + , m_gl2es2ShaderProgram(new Qt3DRender::QShaderProgram()) + , m_blend(new Qt3DRender::QBlendEquation()) + , m_blendArgs(new Qt3DRender::QBlendEquationArguments()) + , m_depthTest(new Qt3DRender::QDepthTest()) +{ +} + +void QText2DMaterialPrivate::init() +{ + m_gl3ShaderProgram->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/distancefieldtext.vert")))); + m_gl3ShaderProgram->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/distancefieldtext.frag")))); + + m_gl2es2ShaderProgram->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/distancefieldtext.vert")))); + m_gl2es2ShaderProgram->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/distancefieldtext.frag")))); + + m_blend->setBlendFunction(Qt3DRender::QBlendEquation::Add); + m_blendArgs->setSourceRgba(Qt3DRender::QBlendEquationArguments::SourceAlpha); + m_blendArgs->setDestinationRgba(Qt3DRender::QBlendEquationArguments::OneMinusSourceAlpha); + m_depthTest->setDepthFunction(Qt3DRender::QDepthTest::LessOrEqual); + + m_gl3RenderPass->setShaderProgram(m_gl3ShaderProgram); + m_gl3RenderPass->addRenderState(m_blend); + m_gl3RenderPass->addRenderState(m_blendArgs); + m_gl3RenderPass->addRenderState(m_depthTest); + + m_gl2RenderPass->setShaderProgram(m_gl2es2ShaderProgram); + m_gl2RenderPass->addRenderState(m_blend); + m_gl2RenderPass->addRenderState(m_blendArgs); + m_gl2RenderPass->addRenderState(m_depthTest); + + m_es2RenderPass->setShaderProgram(m_gl2es2ShaderProgram); + m_es2RenderPass->addRenderState(m_blend); + m_es2RenderPass->addRenderState(m_blendArgs); + m_es2RenderPass->addRenderState(m_depthTest); + + m_gl3Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL); + m_gl3Technique->graphicsApiFilter()->setMajorVersion(3); + m_gl3Technique->graphicsApiFilter()->setMinorVersion(1); + m_gl3Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile); + m_gl3Technique->addRenderPass(m_gl3RenderPass); + + m_gl2Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL); + m_gl2Technique->graphicsApiFilter()->setMajorVersion(2); + m_gl2Technique->graphicsApiFilter()->setMinorVersion(0); + m_gl2Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile); + m_gl2Technique->addRenderPass(m_gl2RenderPass); + + m_es2Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGLES); + m_es2Technique->graphicsApiFilter()->setMajorVersion(2); + m_es2Technique->graphicsApiFilter()->setMinorVersion(0); + m_es2Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile); + m_es2Technique->addRenderPass(m_es2RenderPass); + + Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey(q_func()); + filterKey->setName(QStringLiteral("renderingStyle")); + filterKey->setValue(QStringLiteral("forward")); + m_gl3Technique->addFilterKey(filterKey); + m_gl2Technique->addFilterKey(filterKey); + m_es2Technique->addFilterKey(filterKey); + + m_effect->addTechnique(m_gl3Technique); + m_effect->addTechnique(m_gl2Technique); + m_effect->addTechnique(m_es2Technique); + m_effect->addParameter(m_textureParameter); + m_effect->addParameter(m_textureSizeParameter); + m_effect->addParameter(m_colorParameter); + + q_func()->setEffect(m_effect); +} + +QText2DMaterial::QText2DMaterial(Qt3DCore::QNode *parent) + : QMaterial(*new QText2DMaterialPrivate(), parent) +{ + Q_D(QText2DMaterial); + d->init(); +} + +QText2DMaterial::~QText2DMaterial() +{ +} + +void QText2DMaterial::setColor(const QColor &color) +{ + Q_D(QText2DMaterial); + d->m_colorParameter->setValue(QVariant::fromValue(color)); +} + +void QText2DMaterial::setDistanceFieldTexture(Qt3DRender::QAbstractTexture *tex) +{ + Q_D(QText2DMaterial); + d->m_distanceFieldTexture = tex; + + if (tex) { + d->m_textureParameter->setValue(QVariant::fromValue(tex)); + d->m_textureSizeParameter->setValue(QVariant::fromValue(static_cast<float>(tex->width()))); + } else { + d->m_textureParameter->setValue(0); + d->m_textureSizeParameter->setValue(QVariant::fromValue(1.f)); + } +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/text/qtext2dmaterial_p.h b/src/extras/text/qtext2dmaterial_p.h new file mode 100644 index 000000000..cf967b02b --- /dev/null +++ b/src/extras/text/qtext2dmaterial_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXT2DMATERIAL_P_H +#define QT3DEXTRAS_QTEXT2DMATERIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DExtras/qt3dextras_global.h> +#include <Qt3DRender/qmaterial.h> +#include <QColor> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QText2DMaterialPrivate; + +class QText2DMaterial : public Qt3DRender::QMaterial +{ + Q_OBJECT + +public: + explicit QText2DMaterial(Qt3DCore::QNode *parent = nullptr); + ~QText2DMaterial(); + + void setColor(const QColor &color); + void setDistanceFieldTexture(Qt3DRender::QAbstractTexture *tex); + +private: + Q_DECLARE_PRIVATE(QText2DMaterial) +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXT2DMATERIAL_P_H diff --git a/src/extras/text/qtext2dmaterial_p_p.h b/src/extras/text/qtext2dmaterial_p_p.h new file mode 100644 index 000000000..90f0a71f1 --- /dev/null +++ b/src/extras/text/qtext2dmaterial_p_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2014 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXT2DMATERIAL_P_P_H +#define QT3DEXTRAS_QTEXT2DMATERIAL_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/private/qmaterial_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { +class QAbstractTexture; +class QEffect; +class QTechnique; +class QParameter; +class QRenderPass; +class QShaderProgram; +class QBlendEquation; +class QBlendEquationArguments; +class QDepthTest; + +} // namespace Qt3DRender + +namespace Qt3DExtras { + +class QText2DMaterial; + +class QText2DMaterialPrivate : public Qt3DRender::QMaterialPrivate +{ +public: + QText2DMaterialPrivate(); + + Qt3DRender::QEffect *m_effect; + Qt3DRender::QAbstractTexture *m_distanceFieldTexture; + Qt3DRender::QParameter *m_textureParameter; + Qt3DRender::QParameter *m_textureSizeParameter; + Qt3DRender::QParameter *m_colorParameter; + Qt3DRender::QTechnique *m_gl3Technique; + Qt3DRender::QTechnique *m_gl2Technique; + Qt3DRender::QTechnique *m_es2Technique; + Qt3DRender::QRenderPass *m_gl3RenderPass; + Qt3DRender::QRenderPass *m_gl2RenderPass; + Qt3DRender::QRenderPass *m_es2RenderPass; + Qt3DRender::QShaderProgram *m_gl3ShaderProgram; + Qt3DRender::QShaderProgram *m_gl2es2ShaderProgram; + Qt3DRender::QBlendEquation *m_blend; + Qt3DRender::QBlendEquationArguments *m_blendArgs; + Qt3DRender::QDepthTest *m_depthTest; + + void init(); + + Q_DECLARE_PUBLIC(QText2DMaterial) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXT2DMATERIAL_P_P_H diff --git a/src/extras/text/qtextureatlas.cpp b/src/extras/text/qtextureatlas.cpp new file mode 100644 index 000000000..2b82010a6 --- /dev/null +++ b/src/extras/text/qtextureatlas.cpp @@ -0,0 +1,303 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtextureatlas_p.h" +#include "qtextureatlas_p_p.h" +#include <Qt3DRender/qtexturedata.h> +#include <Qt3DRender/qabstracttextureimage.h> +#include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DCore/qpropertynodeaddedchange.h> +#include <Qt3DCore/qpropertynoderemovedchange.h> + +QT_BEGIN_NAMESPACE + +using namespace Qt3DCore; + +namespace Qt3DExtras { + +QTextureAtlasData::QTextureAtlasData(int w, int h, QImage::Format fmt) + : m_image(w, h, fmt) +{ +} + +QTextureAtlasData::~QTextureAtlasData() +{ +} + +void QTextureAtlasData::addImage(const AtlasTexture &texture, const QImage &image) +{ + QMutexLocker lock(&m_mutex); + + Update update; + update.textureInfo = texture; + update.image = image; + m_updates << update; +} + +QByteArray QTextureAtlasData::createUpdatedImageData() +{ + m_mutex.lock(); + const QVector<Update> updates = std::move(m_updates); + m_mutex.unlock(); + + // copy sub-images into the actual texture image + for (const Update &update : updates) { + const QImage &image = update.image; + + const int padding = update.textureInfo.padding; + const QRect imgRect = update.textureInfo.position; + const QRect alloc = imgRect.adjusted(-padding, -padding, padding, padding); + + // bytes per pixel + if (image.depth() != m_image.depth()) { + qWarning() << "[QTextureAtlas] Image depth does not match. Original =" << m_image.depth() << ", Sub-Image =" << image.depth(); + continue; + } + int bpp = image.depth() / 8; + + // copy image contents into texture image + // use image border pixels to fill the padding region + for (int y = alloc.top(); y <= alloc.bottom(); y++) { + const int ySrc = qBound(0, y - imgRect.top(), image.height()-1); + + const uchar *srcLine = image.scanLine(ySrc); + const uchar *srcLastPx = &srcLine[bpp * (image.width()-1)]; + + uchar *dstLine = m_image.scanLine(y); + + uchar *dstPadL = &dstLine[bpp * alloc.left()]; + uchar *dstPadR = &dstLine[bpp * imgRect.right()]; + uchar *dstImg = &dstLine[bpp * imgRect.left()]; + + // copy left and right padding pixels + for (int pad = 0; pad < padding; pad++) { + for (int px = 0; px < bpp; px++) { + dstPadL[bpp * pad + px] = srcLine[px]; + dstPadR[bpp * pad + px] = srcLastPx[px]; + } + } + + // copy image scanline + memcpy(dstImg, srcLine, bpp * imgRect.width()); + } + } + + return QByteArray(reinterpret_cast<const char*>(m_image.constBits()), m_image.byteCount()); +} + +QTextureAtlasPrivate::QTextureAtlasPrivate() + : Qt3DRender::QAbstractTexturePrivate() +{ + m_target = Qt3DRender::QAbstractTexture::TargetAutomatic; + m_format = Qt3DRender::QAbstractTexture::RGBA8_UNorm; + m_width = 256; + m_height = 256; + m_depth = 1; +} + +QTextureAtlasPrivate::~QTextureAtlasPrivate() +{ +} + +QTextureAtlasGenerator::QTextureAtlasGenerator(const QTextureAtlasPrivate *texAtlas) + : m_data(texAtlas->m_data) + , m_format(texAtlas->m_format) + , m_pixelFormat(texAtlas->m_pixelFormat) + , m_generation(texAtlas->m_currGen) + , m_atlasId(texAtlas->m_id) +{ +} + +QTextureAtlasGenerator::~QTextureAtlasGenerator() +{ +} + +Qt3DRender::QTextureDataPtr QTextureAtlasGenerator::operator()() +{ + Qt3DRender::QTextureImageDataPtr texImage = Qt3DRender::QTextureImageDataPtr::create(); + texImage->setTarget(QOpenGLTexture::Target2D); + texImage->setWidth(m_data->width()); + texImage->setHeight(m_data->height()); + texImage->setDepth(1); + texImage->setFaces(1); + texImage->setLayers(1); + texImage->setMipLevels(1); + texImage->setFormat(static_cast<QOpenGLTexture::TextureFormat>(m_format)); + texImage->setPixelFormat(m_pixelFormat); + texImage->setPixelType(QOpenGLTexture::UInt8); + + const QByteArray bytes = m_data->createUpdatedImageData(); + texImage->setData(bytes, 1); + + Qt3DRender::QTextureDataPtr generatedData = Qt3DRender::QTextureDataPtr::create(); + generatedData->setTarget(Qt3DRender::QAbstractTexture::Target2D); + generatedData->setFormat(m_format); + generatedData->setWidth(m_data->width()); + generatedData->setHeight(m_data->height()); + generatedData->setDepth(1); + generatedData->setLayers(1); + generatedData->addImageData(texImage); + + return generatedData; +} + +bool QTextureAtlasGenerator::operator==(const QTextureGenerator &other) const +{ + const QTextureAtlasGenerator *otherFunctor = Qt3DRender::functor_cast<QTextureAtlasGenerator>(&other); + return (otherFunctor != nullptr + && otherFunctor->m_data == m_data + && otherFunctor->m_atlasId == m_atlasId + && otherFunctor->m_generation == m_generation); +} + +QTextureAtlas::QTextureAtlas(Qt3DCore::QNode *parent) + : QAbstractTexture(*new QTextureAtlasPrivate(), parent) +{ +} + +QOpenGLTexture::PixelFormat QTextureAtlas::pixelFormat() const +{ + Q_D(const QTextureAtlas); + return d->m_pixelFormat; +} + +void QTextureAtlas::setPixelFormat(QOpenGLTexture::PixelFormat fmt) +{ + Q_D(QTextureAtlas); + d->m_pixelFormat = fmt; +} + +QTextureAtlas::~QTextureAtlas() +{ +} + +QTextureAtlas::TextureId QTextureAtlas::addImage(const QImage &image, int padding) +{ + Q_D(QTextureAtlas); + + // lazily create image and allocator to allow setWidth/setHeight after object construction + if (!d->m_allocator) { + Q_ASSERT(d->m_data.isNull()); + + d->m_allocator.reset(new AreaAllocator(QSize(width(), height()))); + d->m_data = QTextureAtlasDataPtr::create(width(), height(), image.format()); + } + + const QSize allocSz = image.size() + QSize(2 * padding, 2 * padding); + + // try to allocate space within image space + const QRect alloc = d->m_allocator->allocate(allocSz); + if (alloc.isEmpty()) + return InvalidTexture; + + const QRect imgRect = alloc.adjusted(padding, padding, -padding, -padding); + AtlasTexture tex; + tex.position = imgRect; + tex.padding = padding; + + // store texture + TextureId id = d->m_currId++; + d->m_textures[id] = tex; + d->m_data->addImage(tex, image); + + // update data functor + d->m_currGen++; + d->setDataFunctor(QTextureAtlasGeneratorPtr::create(d)); + + return id; +} + +void QTextureAtlas::removeImage(TextureId id) +{ + Q_D(QTextureAtlas); + auto it = d->m_textures.find(id); + if (it != d->m_textures.end()) { + QRect imgRect = it->position; + imgRect.adjust(-it->padding, -it->padding, 2*it->padding, 2*it->padding); + + if (d->m_allocator) + d->m_allocator->deallocate(imgRect); + d->m_textures.erase(it); + } +} + +bool QTextureAtlas::hasImage(TextureId id) const +{ + Q_D(const QTextureAtlas); + return d->m_textures.contains(id); +} + +int QTextureAtlas::imageCount() const +{ + Q_D(const QTextureAtlas); + return d->m_textures.size(); +} + +QRect QTextureAtlas::imagePosition(TextureId id) const +{ + Q_D(const QTextureAtlas); + const auto it = d->m_textures.find(id); + return (it != d->m_textures.cend()) ? it->position : QRect(); +} + +QRectF QTextureAtlas::imageTexCoords(TextureId id) const +{ + Q_D(const QTextureAtlas); + const auto it = d->m_textures.find(id); + if (it != d->m_textures.cend()) { + const float w = d->m_data->width(); + const float h = d->m_data->height(); + return QRectF(static_cast<float>(it->position.x()) / w, + static_cast<float>(it->position.y()) / h, + static_cast<float>(it->position.width()) / w, + static_cast<float>(it->position.height()) / h); + } + return QRectF(); +} + +int QTextureAtlas::imagePadding(TextureId id) const +{ + Q_D(const QTextureAtlas); + const auto it = d->m_textures.find(id); + return (it != d->m_textures.cend()) ? it->padding : -1; +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/text/qtextureatlas_p.h b/src/extras/text/qtextureatlas_p.h new file mode 100644 index 000000000..8dc9e19b3 --- /dev/null +++ b/src/extras/text/qtextureatlas_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXTUREATLAS_P_H +#define QT3DEXTRAS_QTEXTUREATLAS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DExtras/qt3dextras_global.h> +#include <Qt3DRender/qabstracttexture.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QTextureAtlasPrivate; + +class QTextureAtlas : public Qt3DRender::QAbstractTexture +{ + Q_OBJECT + +public: + typedef int TextureId; + static Q_CONSTEXPR TextureId InvalidTexture = -1; + + QTextureAtlas(Qt3DCore::QNode *parent = nullptr); + ~QTextureAtlas(); + + QOpenGLTexture::PixelFormat pixelFormat() const; + void setPixelFormat(QOpenGLTexture::PixelFormat fmt); + + TextureId addImage(const QImage &image, int padding); + void removeImage(TextureId id); + + int imageCount() const; + + bool hasImage(TextureId id) const; + QRect imagePosition(TextureId id) const; + QRectF imageTexCoords(TextureId id) const; + int imagePadding(TextureId id) const; + +private: + Q_DECLARE_PRIVATE(QTextureAtlas) +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXTUREATLAS_P_H diff --git a/src/extras/text/qtextureatlas_p_p.h b/src/extras/text/qtextureatlas_p_p.h new file mode 100644 index 000000000..ca18a263a --- /dev/null +++ b/src/extras/text/qtextureatlas_p_p.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QTEXTUREATLAS_P_P_H +#define QT3DEXTRAS_QTEXTUREATLAS_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qscopedpointer.h> +#include <Qt3DRender/private/qabstracttexture_p.h> +#include <Qt3DRender/qtexturegenerator.h> +#include <Qt3DExtras/private/areaallocator_p.h> +#include <Qt3DExtras/private/qtextureatlas_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +// Used to store texture info within atlas +struct AtlasTexture +{ + QRect position; + int padding = 0; +}; + +// data shared between QTextureAtlasPrivate and the QTextureGenerators +// we use this extra indirection so we can lazily copy the sub-images +// into the actual texture image in the backend texture loader thread. +class QTextureAtlasData +{ +public: + QTextureAtlasData(int w, int h, QImage::Format fmt); + ~QTextureAtlasData(); + + int width() const { return m_image.width(); } + int height() const { return m_image.height(); } + + void addImage(const AtlasTexture &texture, const QImage &image); + QByteArray createUpdatedImageData(); + +private: + struct Update { + AtlasTexture textureInfo; + QImage image; + }; + + QMutex m_mutex; + QImage m_image; + QVector<Update> m_updates; +}; + +typedef QSharedPointer<QTextureAtlasData> QTextureAtlasDataPtr; + +class QTextureAtlasPrivate : public Qt3DRender::QAbstractTexturePrivate +{ +public: + QTextureAtlasPrivate(); + ~QTextureAtlasPrivate(); + + Q_DECLARE_PUBLIC(QTextureAtlas) + + QTextureAtlas::TextureId m_currId = 1; // IDs for new sub-textures + int m_currGen = 0; + + QTextureAtlasDataPtr m_data; + QScopedPointer<AreaAllocator> m_allocator; + QOpenGLTexture::PixelFormat m_pixelFormat; + QHash<QTextureAtlas::TextureId, AtlasTexture> m_textures; +}; + +class QTextureAtlasGenerator : public Qt3DRender::QTextureGenerator +{ +public: + QTextureAtlasGenerator(const QTextureAtlasPrivate *texAtlas); + ~QTextureAtlasGenerator(); + Qt3DRender::QTextureDataPtr operator()() Q_DECL_OVERRIDE; + bool operator==(const QTextureGenerator &other) const Q_DECL_OVERRIDE; + + QT3D_FUNCTOR(QTextureAtlasGenerator) + +private: + QTextureAtlasDataPtr m_data; + Qt3DRender::QAbstractTexture::TextureFormat m_format; + QOpenGLTexture::PixelFormat m_pixelFormat; + int m_generation; + Qt3DCore::QNodeId m_atlasId; +}; +typedef QSharedPointer<QTextureAtlasGenerator> QTextureAtlasGeneratorPtr; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QTEXTUREATLAS_P_P_H diff --git a/src/extras/text/text.pri b/src/extras/text/text.pri new file mode 100644 index 000000000..1d2cb793c --- /dev/null +++ b/src/extras/text/text.pri @@ -0,0 +1,21 @@ +HEADERS += \ + $$PWD/distancefieldtextrenderer_p.h \ + $$PWD/distancefieldtextrenderer_p_p.h \ + $$PWD/areaallocator_p.h \ + $$PWD/qdistancefieldglyphcache_p.h \ + $$PWD/qtextureatlas_p_p.h \ + $$PWD/qtextureatlas_p.h \ + $$PWD/qtext2dentity_p.h \ + $$PWD/qtext2dentity.h \ + $$PWD/qtext2dmaterial_p_p.h \ + $$PWD/qtext2dmaterial_p.h + +SOURCES += \ + $$PWD/qtextureatlas.cpp \ + $$PWD/qdistancefieldglyphcache.cpp \ + $$PWD/distancefieldtextrenderer.cpp \ + $$PWD/areaallocator.cpp \ + $$PWD/qtext2dentity.cpp \ + $$PWD/qtext2dmaterial.cpp + +INCLUDEPATH += $$PWD |