diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2015-01-23 16:22:00 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2015-08-07 00:11:31 +0000 |
commit | c2f6f37699296557c5d79ae750e0ce91647de2ee (patch) | |
tree | 6c140186656c46d5e8584d48772f70e78d04806c | |
parent | ce69c98f6954ef2c8806bc44a457a58e4202d751 (diff) |
New Buffer API Frontend Classes
- Switch QAbstractAttribute and QAbstractBuffer to QNode subclasses
- Get rid of all shared pointer when dealing with these (needed to expose to
QML and use the QObject ownership)
- Introduce QGeometryRender, QGeometry, QAttributeProvider,
QAttributeAggregator.
A QMesh component now is:
a QGeometryRenderer which specifies its QGeometry.
The QGeometry refererences n attributes. Each attribute references a QAbstractBuffer.
Change-Id: I49a10c11a605e5fe7c180af86a404f622e763f48
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
46 files changed, 1659 insertions, 268 deletions
diff --git a/examples/qt3d/tessellation-modes/tessellatedquadmesh.cpp b/examples/qt3d/tessellation-modes/tessellatedquadmesh.cpp index 630fa1061..c582ee2ec 100644 --- a/examples/qt3d/tessellation-modes/tessellatedquadmesh.cpp +++ b/examples/qt3d/tessellation-modes/tessellatedquadmesh.cpp @@ -70,13 +70,13 @@ public: positionBytes.resize(size); memcpy(positionBytes.data(), positionData, size); - Qt3D::BufferPtr vertexBuffer(new Qt3D::Buffer(QOpenGLBuffer::VertexBuffer)); - vertexBuffer->setUsage(QOpenGLBuffer::StaticDraw); + Qt3D::QBuffer *vertexBuffer(new Qt3D::QBuffer(Qt3D::QBuffer::VertexBuffer)); + vertexBuffer->setUsage(Qt3D::QBuffer::StaticDraw); vertexBuffer->setData(positionBytes); Qt3D::QMeshDataPtr mesh(new Qt3D::QMeshData(Qt3D::QMeshData::Patches)); mesh->addAttribute(Qt3D::QMeshData::defaultPositionAttributeName(), - Qt3D::AttributePtr(new Qt3D::Attribute(vertexBuffer, GL_FLOAT_VEC3, nVerts))); + new Qt3D::QAttribute(vertexBuffer, GL_FLOAT_VEC3, nVerts)); mesh->setVerticesPerPatch(4); return mesh; } diff --git a/src/core/io/qabstractattribute.cpp b/src/core/io/qabstractattribute.cpp index 17ed41bf6..d3f28c347 100644 --- a/src/core/io/qabstractattribute.cpp +++ b/src/core/io/qabstractattribute.cpp @@ -36,7 +36,9 @@ #include "qabstractattribute.h" #include "qabstractattribute_p.h" -#include <qabstractbuffer.h> +#include "qabstractbuffer.h" + +#include <Qt3DCore/qscenepropertychange.h> QT_BEGIN_NAMESPACE @@ -47,36 +49,81 @@ namespace Qt3D { \internal */ QAbstractAttributePrivate::QAbstractAttributePrivate() + : QNodePrivate() + , m_buffer(Q_NULLPTR) + , m_name() + , m_type(0) + , m_count(0) + , m_byteStride(0) + , m_byteOffset(0) + , m_divisor(0) + , m_attributeType(QAbstractAttribute::VertexAttribute) { } -/*! \internal */ -QAbstractAttribute::QAbstractAttribute(QAbstractAttributePrivate &dd, QAbstractBufferPtr buf, int type, uint count, uint offset, uint stride) - : d_ptr(&dd) +QAbstractAttribute::QAbstractAttribute(QNode *parent) + : QNode(*new QAbstractAttributePrivate(), parent) +{ +} + +QAbstractAttribute::~QAbstractAttribute() +{ + Q_ASSERT_X(QNodePrivate::get(this)->m_wasCleanedUp, Q_FUNC_INFO, "QNode::cleanup should have been called by now. A Qt3D::QAbstractAttribute subclass didn't call QNode::cleanup in its destructor"); +} + +QAbstractAttribute::QAbstractAttribute(QAbstractBuffer *buf, int type, uint count, uint offset, uint stride, QNode *parent) + : QNode(*new QAbstractAttributePrivate(), parent) { Q_D(QAbstractAttribute); d->m_buffer = buf; d->m_count = count; - d->m_divisor = 0; - d->m_offset = offset; + d->m_byteOffset = offset; d->m_type = type; - d->m_stride = stride; + d->m_byteStride = stride; +} + +QAbstractAttribute::QAbstractAttribute(QAbstractAttributePrivate &dd, QNode *parent) + : QNode(dd, parent) +{ } -QAbstractAttribute::QAbstractAttribute(QAbstractBufferPtr buf, int type, uint count, uint offset, uint stride) - : d_ptr(new QAbstractAttributePrivate) + +QAbstractAttribute::QAbstractAttribute(QAbstractAttributePrivate &dd, QAbstractBuffer *buf, const QString &name, int type, uint count, uint offset, uint stride, QNode *parent) + : QNode(dd, parent) { Q_D(QAbstractAttribute); d->m_buffer = buf; + d->m_name = name; d->m_count = count; - d->m_divisor = 0; - d->m_offset = offset; + d->m_byteOffset = offset; d->m_type = type; - d->m_stride = stride; + d->m_byteStride = stride; } -QAbstractAttribute::~QAbstractAttribute() +void QAbstractAttribute::copy(const QNode *ref) { + QNode::copy(ref); + const QAbstractAttribute *attribute = static_cast<const QAbstractAttribute *>(ref); + d_func()->m_buffer = qobject_cast<QAbstractBuffer *>(QNode::clone(attribute->d_func()->m_buffer)); + d_func()->m_name = attribute->d_func()->m_name; + d_func()->m_count = attribute->d_func()->m_count; + d_func()->m_divisor = attribute->d_func()->m_divisor; + d_func()->m_byteOffset = attribute->d_func()->m_byteOffset; + d_func()->m_type = attribute->d_func()->m_type; + d_func()->m_byteStride = attribute->d_func()->m_byteStride; + d_func()->m_attributeType = attribute->d_func()->m_attributeType; +} + +QAbstractBuffer *QAbstractAttribute::buffer() const +{ + Q_D(const QAbstractAttribute); + return d->m_buffer; +} + +QString QAbstractAttribute::name() const +{ + Q_D(const QAbstractAttribute); + return d->m_name; } int QAbstractAttribute::type() const @@ -94,13 +141,13 @@ uint QAbstractAttribute::count() const uint QAbstractAttribute::byteStride() const { Q_D(const QAbstractAttribute); - return d->m_stride; + return d->m_byteStride; } -uint QAbstractAttribute::byteOffset() +uint QAbstractAttribute::byteOffset() const { Q_D(const QAbstractAttribute); - return d->m_offset; + return d->m_byteOffset; } uint QAbstractAttribute::divisor() const @@ -109,10 +156,115 @@ uint QAbstractAttribute::divisor() const return d->m_divisor; } -QAbstractBufferPtr QAbstractAttribute::buffer() const +QAbstractAttribute::AttributeType QAbstractAttribute::attributeType() const { Q_D(const QAbstractAttribute); - return d->m_buffer; + return d->m_attributeType; +} + +void QAbstractAttribute::setBuffer(QAbstractBuffer *buffer) +{ + Q_D(QAbstractAttribute); + if (d->m_buffer == buffer) + return; + + if (d->m_buffer && d->m_changeArbiter) { + QScenePropertyChangePtr change(new QScenePropertyChange(NodeRemoved, QSceneChange::Node, id())); + change->setPropertyName("buffer"); + change->setValue(QVariant::fromValue(d->m_buffer->id())); + d->notifyObservers(change); + } + + + d->m_buffer = buffer; + const bool blocked = blockNotifications(true); + emit bufferChanged(); + blockNotifications(blocked); + + // We need to add it as a child of the current node if it has been declared inline + // Or not previously added as a child of the current node so that + // 1) The backend gets notified about it's creation + // 2) When the current node is destroyed, it gets destroyed as well + if (buffer && !buffer->parent()) + buffer->setParent(this); + + if (d->m_buffer && d->m_changeArbiter) { + QScenePropertyChangePtr change(new QScenePropertyChange(NodeAdded, QSceneChange::Node, id())); + change->setPropertyName("buffer"); + change->setValue(QVariant::fromValue(buffer->id())); + d->notifyObservers(change); + } +} + +void QAbstractAttribute::setName(const QString &name) +{ + Q_D(QAbstractAttribute); + if (d->m_name == name) + return; + + d->m_name = name; + emit nameChanged(); +} + +void QAbstractAttribute::setType(int type) +{ + Q_D(QAbstractAttribute); + + if (d->m_type == type) + return; + + d->m_type = type; + emit typeChanged(); +} + +void QAbstractAttribute::setCount(uint count) +{ + Q_D(QAbstractAttribute); + if (d->m_count == count) + return; + + d->m_count = count; + emit countChanged(); +} + +void QAbstractAttribute::setByteStride(uint byteStride) +{ + Q_D(QAbstractAttribute); + if (d->m_byteStride == byteStride) + return; + + d->m_byteStride = byteStride; + emit byteStrideChanged(); +} + +void QAbstractAttribute::setByteOffset(uint byteOffset) +{ + Q_D(QAbstractAttribute); + if (d->m_byteOffset == byteOffset) + return; + + d->m_byteOffset = byteOffset; + emit byteOffsetChanged(); +} + +void QAbstractAttribute::setDivisor(uint divisor) +{ + Q_D(QAbstractAttribute); + if (d->m_divisor == divisor) + return; + + d->m_divisor = divisor; + emit divisorChanged(); +} + +void QAbstractAttribute::setAttributeType(AttributeType attributeType) +{ + Q_D(QAbstractAttribute); + if (d->m_attributeType == attributeType) + return; + + d->m_attributeType = attributeType; + emit attributeTypeChanged(); } } // Qt3D diff --git a/src/core/io/qabstractattribute.h b/src/core/io/qabstractattribute.h index 8b24e2f47..cb3b09bb5 100644 --- a/src/core/io/qabstractattribute.h +++ b/src/core/io/qabstractattribute.h @@ -38,7 +38,8 @@ #define QT3D_QABSTRACTATTRIBUTE_H #include <Qt3DCore/qt3dcore_global.h> -#include <QSharedPointer> +#include <Qt3DCore/QNode> +#include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE @@ -49,27 +50,71 @@ class QAbstractAttributePrivate; typedef QSharedPointer<QAbstractBuffer> QAbstractBufferPtr; -class QT3DCORESHARED_EXPORT QAbstractAttribute +class QT3DCORESHARED_EXPORT QAbstractAttribute : public QNode { + Q_OBJECT + Q_PROPERTY(Qt3D::QAbstractBuffer *buffer READ buffer WRITE setBuffer NOTIFY bufferChanged) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(int type READ type WRITE setType NOTIFY typeChanged) // TODO needs a better name. this is the GL type. + Q_PROPERTY(uint count READ count WRITE setCount NOTIFY countChanged) + Q_PROPERTY(uint byteStride READ byteStride WRITE setByteStride NOTIFY byteStrideChanged) + Q_PROPERTY(uint byteOffset READ byteOffset WRITE setByteOffset NOTIFY byteOffsetChanged) + Q_PROPERTY(uint divisor READ divisor WRITE setDivisor NOTIFY divisorChanged) + Q_PROPERTY(AttributeType attributeType READ attributeType WRITE setAttributeType NOTIFY attributeTypeChanged) + public: - explicit QAbstractAttribute(QAbstractBufferPtr buf, int type, uint count, uint offset = 0, uint stride = 0); - virtual ~QAbstractAttribute(); + explicit QAbstractAttribute(QNode *parent = 0); + ~QAbstractAttribute(); + QAbstractAttribute(QAbstractBuffer *buf, int type, uint count, uint offset = 0, uint stride = 0, QNode *parent = 0); + + enum AttributeType { + VertexAttribute, + IndexAttribute + }; + Q_ENUM(AttributeType) + QAbstractBuffer *buffer() const; + QString name() const; int type() const; uint count() const; uint byteStride() const; - uint byteOffset(); + uint byteOffset() const; uint divisor() const; - QAbstractBufferPtr buffer() const; + AttributeType attributeType() const; + virtual QVector<QVector4D> asVector4D() const = 0; virtual QVector<QVector3D> asVector3D() const = 0; virtual QVector<QVector2D> asVector2D() const = 0; virtual void dump(int count) = 0; +public Q_SLOTS: + void setBuffer(QAbstractBuffer *buffer); + void setName(const QString &name); + void setType(int type); + void setCount(uint count); + void setByteStride(uint byteStride); + void setByteOffset(uint byteOffset); + void setDivisor(uint divisor); + void setAttributeType(AttributeType attributeType); + +Q_SIGNALS: + void bufferChanged(); + void nameChanged(); + void typeChanged(); + void countChanged(); + void byteStrideChanged(); + void byteOffsetChanged(); + void divisorChanged(); + void attributeTypeChanged(); + protected: + QAbstractAttribute(QAbstractAttributePrivate &dd, QNode *parent = 0); + QAbstractAttribute(QAbstractAttributePrivate &dd, QAbstractBuffer *buf, const QString &name, int type, uint count, uint offset = 0, uint stride = 0, QNode *parent = 0); + + void copy(const QNode *ref) Q_DECL_OVERRIDE; + +private: Q_DECLARE_PRIVATE(QAbstractAttribute) - QAbstractAttributePrivate *d_ptr; - QAbstractAttribute(QAbstractAttributePrivate &dd, QAbstractBufferPtr buf, int type, uint count, uint offset = 0, uint stride = 0); }; } // Qt3D diff --git a/src/core/io/qabstractattribute_p.h b/src/core/io/qabstractattribute_p.h index 526a8d81d..6d9c5950d 100644 --- a/src/core/io/qabstractattribute_p.h +++ b/src/core/io/qabstractattribute_p.h @@ -38,26 +38,31 @@ #define QT3D_QABSTRACTATTRIBUTE_P_H #include <Qt3DCore/qt3dcore_global.h> +#include <Qt3DCore/QAbstractAttribute> +#include <Qt3DCore/QAbstractBuffer> +#include <private/qnode_p.h> QT_BEGIN_NAMESPACE namespace Qt3D { -class QAbstractBuffer; +class QAbstractAttribute; -typedef QSharedPointer<QAbstractBuffer> QAbstractBufferPtr; - -class QT3DCORESHARED_EXPORT QAbstractAttributePrivate +class QT3DCORESHARED_EXPORT QAbstractAttributePrivate : public QNodePrivate { public: + Q_DECLARE_PUBLIC(QAbstractAttribute) + QAbstractAttributePrivate(); + QAbstractBuffer *m_buffer; + QString m_name; int m_type; uint m_count; - uint m_stride; - uint m_offset; + uint m_byteStride; + uint m_byteOffset; uint m_divisor; - QAbstractBufferPtr m_buffer; + QAbstractAttribute::AttributeType m_attributeType; }; } // Qt3D diff --git a/src/core/io/qabstractbuffer.cpp b/src/core/io/qabstractbuffer.cpp index 9337b923f..7089b5a91 100644 --- a/src/core/io/qabstractbuffer.cpp +++ b/src/core/io/qabstractbuffer.cpp @@ -45,29 +45,42 @@ namespace Qt3D { \class Qt3D::QAbstractBufferPrivate \internal */ + QAbstractBufferPrivate::QAbstractBufferPrivate() + : QNodePrivate() { } -QAbstractBuffer::QAbstractBuffer() - : d_ptr(new QAbstractBufferPrivate) +QAbstractBuffer::QAbstractBuffer(QNode *parent) + : QNode(*new QAbstractBufferPrivate(), parent) { } QAbstractBuffer::~QAbstractBuffer() { + Q_ASSERT_X(QNodePrivate::get(this)->m_wasCleanedUp, Q_FUNC_INFO, "QNode::cleanup should have been called by now. A Qt3D::QAbstractBuffer subclass didn't call QNode::cleanup in its destructor"); } /*! \internal */ -QAbstractBuffer::QAbstractBuffer(QAbstractBufferPrivate &dd) - : d_ptr(&dd) +QAbstractBuffer::QAbstractBuffer(QAbstractBufferPrivate &dd, QNode *parent) + : QNode(dd, parent) +{ +} + +void QAbstractBuffer::copy(const QNode *ref) { + QNode::copy(ref); + const QAbstractBuffer *buffer = static_cast<const QAbstractBuffer *>(ref); + d_func()->m_data = buffer->d_func()->m_data; } void QAbstractBuffer::setData(const QByteArray &bytes) { Q_D(QAbstractBuffer); - d->m_data = bytes; + if (bytes != d->m_data) { + d->m_data = bytes; + emit dataChanged(); + } } QByteArray QAbstractBuffer::data() const diff --git a/src/core/io/qabstractbuffer.h b/src/core/io/qabstractbuffer.h index a1c4dea6e..1b0a8483f 100644 --- a/src/core/io/qabstractbuffer.h +++ b/src/core/io/qabstractbuffer.h @@ -38,6 +38,8 @@ #define QT3D_QABSTRACTBUFFER_H #include <Qt3DCore/qt3dcore_global.h> +#include <Qt3DCore/QNode> +#include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE @@ -45,10 +47,12 @@ namespace Qt3D { class QAbstractBufferPrivate; -class QT3DCORESHARED_EXPORT QAbstractBuffer +class QT3DCORESHARED_EXPORT QAbstractBuffer : public QNode { + Q_OBJECT + Q_PROPERTY(QByteArray data READ data WRITE setData NOTIFY dataChanged) public: - QAbstractBuffer(); + QAbstractBuffer(QNode *parent = 0); virtual ~QAbstractBuffer(); virtual void setData(const QByteArray &bytes); @@ -58,9 +62,14 @@ public: virtual void create() = 0; protected: + QAbstractBuffer(QAbstractBufferPrivate &dd, QNode *parent = 0); + void copy(const QNode *ref) Q_DECL_OVERRIDE; + +Q_SIGNALS: + void dataChanged(); + +private: Q_DECLARE_PRIVATE(QAbstractBuffer) - QAbstractBufferPrivate *d_ptr; - QAbstractBuffer(QAbstractBufferPrivate &dd); }; } // Qt3D diff --git a/src/core/io/qabstractbuffer_p.h b/src/core/io/qabstractbuffer_p.h index a393df4dd..01e293782 100644 --- a/src/core/io/qabstractbuffer_p.h +++ b/src/core/io/qabstractbuffer_p.h @@ -38,17 +38,22 @@ #define QT3D_QABSTRACTBUFFER_P_H #include <Qt3DCore/qt3dcore_global.h> +#include <private/qnode_p.h> + #include <QByteArray> QT_BEGIN_NAMESPACE namespace Qt3D { -class QT3DCORESHARED_EXPORT QAbstractBufferPrivate +class QAbstractBuffer; + +class QT3DCORESHARED_EXPORT QAbstractBufferPrivate : public QNodePrivate { public: - QAbstractBufferPrivate(); + Q_DECLARE_PUBLIC(QAbstractBuffer) + QAbstractBufferPrivate(); QByteArray m_data; }; diff --git a/src/plugins/sceneparsers/assimp/assimpparser.cpp b/src/plugins/sceneparsers/assimp/assimpparser.cpp index 351faa281..c477ea51f 100644 --- a/src/plugins/sceneparsers/assimp/assimpparser.cpp +++ b/src/plugins/sceneparsers/assimp/assimpparser.cpp @@ -599,44 +599,44 @@ void AssimpParser::loadMesh(uint meshIndex) } } // Create a Buffer from the raw array - BufferPtr vbuffer(new Buffer(QOpenGLBuffer::VertexBuffer)); - vbuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *vbuffer(new QBuffer(QBuffer::VertexBuffer)); + vbuffer->setUsage(QBuffer::StaticDraw); vbuffer->setData(bufferArray); // Add vertex attributes to the mesh with the right array meshData->addAttribute(VERTICES_ATTRIBUTE_NAME, - AttributePtr(new Attribute(vbuffer, - GL_FLOAT_VEC3, - mesh->mNumVertices, - 0, - chunkSize * sizeof(float)))); + new QAttribute(vbuffer, + GL_FLOAT_VEC3, + mesh->mNumVertices, + 0, + chunkSize * sizeof(float))); meshData->addAttribute(NORMAL_ATTRIBUTE_NAME, - AttributePtr(new Attribute(vbuffer, - GL_FLOAT_VEC3, - mesh->mNumVertices, - 3 * sizeof(float), - chunkSize * sizeof(float)))); + new QAttribute(vbuffer, + GL_FLOAT_VEC3, + mesh->mNumVertices, + 3 * sizeof(float), + chunkSize * sizeof(float))); if (hasTangent) meshData->addAttribute(TANGENT_ATTRIBUTE_NAME, - AttributePtr(new Attribute(vbuffer, - GL_FLOAT_VEC3, - mesh->mNumVertices, - 6 * sizeof(float), - chunkSize * sizeof(float)))); + new QAttribute(vbuffer, + GL_FLOAT_VEC3, + mesh->mNumVertices, + 6 * sizeof(float), + chunkSize * sizeof(float))); if (hasTexture) meshData->addAttribute(TEXTCOORD_ATTRIBUTE_NAME, - AttributePtr(new Attribute(vbuffer, - GL_FLOAT_VEC2, - mesh->mNumVertices, - (hasTangent ? 9 : 6) * sizeof(float), - chunkSize * sizeof(float)))); + new QAttribute(vbuffer, + GL_FLOAT_VEC2, + mesh->mNumVertices, + (hasTangent ? 9 : 6) * sizeof(float), + chunkSize * sizeof(float))); if (hasColor) meshData->addAttribute(COLOR_ATTRIBUTE_NAME, - AttributePtr(new Attribute(vbuffer, - GL_FLOAT_VEC4, - mesh->mNumVertices, - (6 + (hasTangent ? 3 : 0) + (hasTexture ? 2 : 0)) * sizeof(float), - chunkSize * sizeof(float)))); + new QAttribute(vbuffer, + GL_FLOAT_VEC4, + mesh->mNumVertices, + (6 + (hasTangent ? 3 : 0) + (hasTexture ? 2 : 0)) * sizeof(float), + chunkSize * sizeof(float))); GLuint indiceType; QByteArray ibufferContent; uint indices = mesh->mNumFaces * 3; @@ -663,12 +663,12 @@ void AssimpParser::loadMesh(uint meshIndex) } // Create Indices buffer - BufferPtr ibuffer(new Buffer(QOpenGLBuffer::IndexBuffer)); - ibuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *ibuffer(new QBuffer(QBuffer::IndexBuffer)); + ibuffer->setUsage(QBuffer::StaticDraw); ibuffer->setData(ibufferContent); // Add indices attributes - meshData->setIndexAttribute(AttributePtr(new Attribute(ibuffer, indiceType, indices, 0, 0))); + meshData->setIndexAttribute(new QAttribute(ibuffer, indiceType, indices, 0, 0)); meshData->computeBoundsFromAttribute(VERTICES_ATTRIBUTE_NAME); diff --git a/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp b/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp index 23ef7cb92..9cfcab31c 100644 --- a/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp +++ b/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp @@ -43,6 +43,7 @@ #include <Qt3DCore/qmatrixtransform.h> #include <Qt3DCore/qtranslatetransform.h> #include <Qt3DCore/qrotatetransform.h> +#include <Qt3DCore/qabstractattribute.h> #include <Qt3DQuick/quick3dentity.h> #include <Qt3DQuick/quick3dentityloader.h> #include <Qt3DQuick/quick3dtransform.h> @@ -75,6 +76,8 @@ void Qt3DQuick3DCorePlugin::registerTypes(const char *uri) qmlRegisterType<Qt3D::QRotateTransform>(uri, 2, 0, "Rotate"); qmlRegisterType<Qt3D::QLookAtTransform>(uri, 2, 0, "LookAt"); qmlRegisterType<Qt3D::QScaleTransform>(uri, 2, 0, "Scale"); + + qmlRegisterUncreatableType<Qt3D::QAbstractAttribute>(uri, 2, 0, "AbstractAttribute", QStringLiteral("QAbstractAttribute is abstract")); } QT_END_NAMESPACE diff --git a/src/quick3d/imports/render/qt3dquick3drendererplugin.cpp b/src/quick3d/imports/render/qt3dquick3drendererplugin.cpp index d9c2dff3a..bb3fd8bd2 100644 --- a/src/quick3d/imports/render/qt3dquick3drendererplugin.cpp +++ b/src/quick3d/imports/render/qt3dquick3drendererplugin.cpp @@ -91,6 +91,10 @@ #include <Qt3DRenderer/qstencilop.h> #include <Qt3DRenderer/qstencilopseparate.h> #include <Qt3DRenderer/qstencilmask.h> +#include <Qt3DRenderer/qattribute.h> +#include <Qt3DRenderer/qbuffer.h> +#include <Qt3DRenderer/qgeometry.h> +#include <Qt3DRenderer/qgeometryrenderer.h> #include <Qt3DQuickRenderer/quick3dtechnique.h> #include <Qt3DQuickRenderer/quick3dmaterial.h> #include <Qt3DQuickRenderer/quick3dtechniquefilter.h> @@ -108,6 +112,7 @@ #include <Qt3DQuickRenderer/quick3dshaderdataarray.h> #include <Qt3DQuickRenderer/quick3dstateset.h> #include <Qt3DQuickRenderer/quick3drendertargetselector.h> +#include <Qt3DQuickRenderer/quick3dgeometry.h> static void initResources() { @@ -190,6 +195,14 @@ void Qt3DQuick3DRendererPlugin::registerTypes(const char *uri) qmlRegisterUncreatableType<Qt3D::QAbstractTextureImage>(uri, 2, 0, "QAbstractTextureImage", QStringLiteral("QAbstractTextureImage is abstract")); qmlRegisterType<Qt3D::QTextureImage>(uri, 2, 0, "TextureImage"); + // Geometry + qmlRegisterUncreatableType<Qt3D::QAbstractAttribute>(uri, 2, 0, "QAbstractAttribute", QStringLiteral("QAbstractAttribute is abstract")); + qmlRegisterUncreatableType<Qt3D::QAbstractBuffer>(uri, 2, 0, "QAbstractBuffer", QStringLiteral("QAbstractBuffer is abstract")); + qmlRegisterType<Qt3D::QAttribute>(uri, 2, 0, "Attribute"); + qmlRegisterType<Qt3D::QBuffer>(uri, 2, 0, "Buffer"); + qmlRegisterExtendedType<Qt3D::QGeometry, Qt3D::Render::Quick::Quick3DGeometry>(uri, 2, 0, "Geometry"); + qmlRegisterType<Qt3D::QGeometryRenderer>(uri, 2, 0, "GeometryRenderer"); + // Meshes qmlRegisterUncreatableType<Qt3D::QAbstractMesh>(uri, 2, 0, "QAbstractMesh", QStringLiteral("QAbstractMesh is abstract")); qmlRegisterType<Qt3D::QMesh>(uri, 2, 0, "Mesh"); diff --git a/src/quick3d/quick3drenderer/items/items.pri b/src/quick3d/quick3drenderer/items/items.pri index 35fa140d3..8c31f6f38 100644 --- a/src/quick3d/quick3drenderer/items/items.pri +++ b/src/quick3d/quick3drenderer/items/items.pri @@ -16,7 +16,8 @@ HEADERS += \ $$PWD/quick3dshaderdata.h \ $$PWD/quick3dshaderdataarray.h \ $$PWD/quick3dstateset.h \ - $$PWD/quick3drendertargetselector.h + $$PWD/quick3drendertargetselector.h \ + $$PWD/quick3dgeometry.h SOURCES += \ $$PWD/quick3drenderpassfilter.cpp \ @@ -35,6 +36,7 @@ SOURCES += \ $$PWD/quick3dshaderdata.cpp \ $$PWD/quick3dshaderdataarray.cpp \ $$PWD/quick3dstateset.cpp \ - $$PWD/quick3drendertargetselector.cpp + $$PWD/quick3drendertargetselector.cpp \ + $$PWD/quick3dgeometry.cpp INCLUDEPATH += $$PWD diff --git a/src/quick3d/quick3drenderer/items/quick3dgeometry.cpp b/src/quick3d/quick3drenderer/items/quick3dgeometry.cpp new file mode 100644 index 000000000..125b8d7a9 --- /dev/null +++ b/src/quick3d/quick3drenderer/items/quick3dgeometry.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 "quick3dgeometry.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +namespace Render { + +namespace Quick { + +Quick3DGeometry::Quick3DGeometry(QObject *parent) + : QObject(parent) +{ +} + +QQmlListProperty<QAbstractAttribute> Quick3DGeometry::attributeList() +{ + return QQmlListProperty<QAbstractAttribute>(this, 0, + &Quick3DGeometry::appendAttribute, + &Quick3DGeometry::attributesCount, + &Quick3DGeometry::attributeAt, + &Quick3DGeometry::clearAttributes); +} + +void Quick3DGeometry::appendAttribute(QQmlListProperty<QAbstractAttribute> *list, QAbstractAttribute *attribute) +{ + Quick3DGeometry *geometry = static_cast<Quick3DGeometry *>(list->object); + geometry->parentGeometry()->addAttribute(attribute); +} + +QAbstractAttribute *Quick3DGeometry::attributeAt(QQmlListProperty<QAbstractAttribute> *list, int index) +{ + Quick3DGeometry *geometry = static_cast<Quick3DGeometry *>(list->object); + return geometry->parentGeometry()->attributes().at(index); +} + +int Quick3DGeometry::attributesCount(QQmlListProperty<QAbstractAttribute> *list) +{ + Quick3DGeometry *geometry = static_cast<Quick3DGeometry *>(list->object); + return geometry->parentGeometry()->attributes().count(); +} + +void Quick3DGeometry::clearAttributes(QQmlListProperty<QAbstractAttribute> *list) +{ + Quick3DGeometry *geometry = static_cast<Quick3DGeometry *>(list->object); + Q_FOREACH (QAbstractAttribute *attribute, geometry->parentGeometry()->attributes()) + geometry->parentGeometry()->removeAttribute(attribute); +} + +} // Quick + +} // Render + +} // Qt3D + +QT_END_NAMESPACE diff --git a/src/quick3d/quick3drenderer/items/quick3dgeometry.h b/src/quick3d/quick3drenderer/items/quick3dgeometry.h new file mode 100644 index 000000000..940e89dad --- /dev/null +++ b/src/quick3d/quick3drenderer/items/quick3dgeometry.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 QT3D_QUICK3DGEOMETRY_H +#define QT3D_QUICK3DGEOMETRY_H + +#include <Qt3DQuickRenderer/qt3dquickrenderer_global.h> +#include <QQmlListProperty> +#include <Qt3DRenderer/QGeometry> + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +namespace Render { + +namespace Quick { + +class QT3DQUICKRENDERERSHARED_EXPORT Quick3DGeometry : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty<QAbstractAttribute> attributes READ attributeList) + Q_CLASSINFO("DefaultProperty", "attributeProviders") + +public: + explicit Quick3DGeometry(QObject *parent = 0); + inline QGeometry *parentGeometry() const { return qobject_cast<QGeometry *>(parent()); } + + QQmlListProperty<QAbstractAttribute> attributeList(); + +private: + static void appendAttribute(QQmlListProperty<QAbstractAttribute> *list, QAbstractAttribute *provider); + static QAbstractAttribute *attributeAt(QQmlListProperty<QAbstractAttribute> *list, int index); + static int attributesCount(QQmlListProperty<QAbstractAttribute> *list); + static void clearAttributes(QQmlListProperty<QAbstractAttribute> *list); +}; + +} // Quick + +} // Render + +} // Qt3D + +QT_END_NAMESPACE + +#endif // QT3D_QUICK3DGEOMETRY_H diff --git a/src/render/backend/jobs/loadmeshdatajob.cpp b/src/render/backend/jobs/loadmeshdatajob.cpp index 1e1266b09..5bc54ee48 100644 --- a/src/render/backend/jobs/loadmeshdatajob.cpp +++ b/src/render/backend/jobs/loadmeshdatajob.cpp @@ -82,7 +82,7 @@ void LoadMeshDataJob::run() QMeshData *meshData = m_renderer->meshDataManager()->data(meshDataHandle); *meshData = *(meshDataPtr.data()); m_renderer->meshDataManager()->addMeshDataForFunctor(meshDataHandle, m_functor); - AttributePtr attr = meshData->attributeByName(QMeshData::defaultPositionAttributeName()).staticCast<Attribute>(); + QAttribute *attr = static_cast<QAttribute *>(meshData->attributeByName(QMeshData::defaultPositionAttributeName())); if (!attr) qCWarning(Jobs) << Q_FUNC_INFO << "unknown attribute: position"; } diff --git a/src/render/backend/qgraphicscontext.cpp b/src/render/backend/qgraphicscontext.cpp index f65512628..e3e925ec3 100644 --- a/src/render/backend/qgraphicscontext.cpp +++ b/src/render/backend/qgraphicscontext.cpp @@ -831,9 +831,12 @@ void QGraphicsContext::setUniforms(QUniformPack &uniforms) m_activeShader->updateUniforms(this, uniforms); } -void QGraphicsContext::specifyAttribute(QString nm, AttributePtr attr) +void QGraphicsContext::specifyAttribute(QString nm, QAttribute *attr) { - QOpenGLBuffer buf = glBufferFor(attr->buffer().staticCast<Buffer>()); + if (attr == Q_NULLPTR) + return; + + QOpenGLBuffer buf = glBufferFor(attr->buffer()); buf.bind(); QOpenGLShaderProgram* prog = activeShader(); @@ -857,21 +860,21 @@ void QGraphicsContext::specifyAttribute(QString nm, AttributePtr attr) buf.release(); } -void QGraphicsContext::specifyIndices(AttributePtr attr) +void QGraphicsContext::specifyIndices(QAttribute *attr) { - if (attr->buffer().staticCast<Buffer>()->type() != QOpenGLBuffer::IndexBuffer) { + if (static_cast<QBuffer *>(attr->buffer())->type() != QBuffer::IndexBuffer) { qCWarning(Backend) << Q_FUNC_INFO << "provided buffer is not correct type"; return; } - QOpenGLBuffer buf = glBufferFor(attr->buffer().staticCast<Buffer>()); + QOpenGLBuffer buf = glBufferFor(attr->buffer()); if (!buf.bind()) qCWarning(Backend) << Q_FUNC_INFO << "binding index buffer failed"; // bind within the current VAO } -QOpenGLBuffer QGraphicsContext::glBufferFor(BufferPtr buf) +QOpenGLBuffer QGraphicsContext::glBufferFor(QBuffer *buf) { if (m_bufferHash.contains(buf)) return m_bufferHash.value(buf); diff --git a/src/render/backend/qgraphicscontext_p.h b/src/render/backend/qgraphicscontext_p.h index 5fc3300d3..7585fc951 100644 --- a/src/render/backend/qgraphicscontext_p.h +++ b/src/render/backend/qgraphicscontext_p.h @@ -128,9 +128,9 @@ public: void setRenderer(Renderer *renderer); - void specifyAttribute(QString nm, AttributePtr attr); + void specifyAttribute(QString nm, QAttribute *attr); - void specifyIndices(AttributePtr attr); + void specifyIndices(QAttribute *attr); void setUniforms(QUniformPack &uniforms); @@ -140,7 +140,7 @@ public: * @param buf * @return */ - QOpenGLBuffer glBufferFor(BufferPtr buf); + QOpenGLBuffer glBufferFor(QBuffer *buf); /** * @brief activateTexture - make a texture active on a hardware unit @@ -210,7 +210,7 @@ private: RenderShader *m_activeShader; QHash<ProgramDNA, RenderShader *> m_renderShaderHash; - QHash<BufferPtr, QOpenGLBuffer> m_bufferHash; + QHash<QBuffer *, QOpenGLBuffer> m_bufferHash; QHash<QNodeId, GLuint> m_renderTargets; QHash<GLuint, QSize> m_renderTargetsSize; diff --git a/src/render/backend/renderentity.cpp b/src/render/backend/renderentity.cpp index ffe78efb9..224d35b69 100644 --- a/src/render/backend/renderentity.cpp +++ b/src/render/backend/renderentity.cpp @@ -45,6 +45,7 @@ #include <Qt3DRenderer/private/renderlogging_p.h> #include <Qt3DRenderer/sphere.h> #include <Qt3DRenderer/qshaderdata.h> +#include <Qt3DRenderer/qgeometryrenderer.h> #include <Qt3DCore/qcameralens.h> #include <Qt3DCore/qentity.h> @@ -251,6 +252,8 @@ void RenderEntity::addComponent(QComponent *component) m_materialComponent = component->id(); else if (qobject_cast<QShaderData *>(component) != Q_NULLPTR) m_shaderDataComponents.append(component->id()); + else if (qobject_cast<QGeometryRenderer *>(component) != Q_NULLPTR) + m_geometryRendererComponent = component->id(); } void RenderEntity::removeComponent(const QNodeId &nodeId) @@ -267,6 +270,8 @@ void RenderEntity::removeComponent(const QNodeId &nodeId) m_materialComponent = QNodeId(); else if (m_shaderDataComponents.contains(nodeId)) m_shaderDataComponents.removeAll(nodeId); + else if (m_geometryRendererComponent == nodeId) + m_geometryRendererComponent = QNodeId(); } template<> diff --git a/src/render/backend/renderentity_p.h b/src/render/backend/renderentity_p.h index 5b835468e..f69483a31 100644 --- a/src/render/backend/renderentity_p.h +++ b/src/render/backend/renderentity_p.h @@ -158,6 +158,7 @@ private: QNodeId m_cameraComponent; QList<QNodeId> m_layerComponents; QList<QNodeId> m_shaderDataComponents; + QNodeId m_geometryRendererComponent; QString m_objectName; }; diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index 833ab07e9..08b7f41f4 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -811,7 +811,7 @@ void Renderer::executeCommands(const QVector<RenderCommand *> &commands) // Manager should have a VAO Manager that are indexed by QMeshData and Shader // RenderCommand should have a handle to the corresponding VAO for the Mesh and Shader - bool drawIndexed = !meshData->indexAttribute().isNull(); + bool drawIndexed = (meshData->indexAttribute() != Q_NULLPTR); //// We activate the shader here // This will fill the attributes & uniforms info the first time the shader is loaded @@ -834,14 +834,14 @@ void Renderer::executeCommands(const QVector<RenderCommand *> &commands) // TO DO : Do that in a better / nicer way Q_FOREACH (QString nm, meshData->attributeNames()) { - AttributePtr attr(meshData->attributeByName(nm).staticCast<Attribute>()); + QAttribute *attr(static_cast<QAttribute *>(meshData->attributeByName(nm))); if (command->m_parameterAttributeToShaderNames.contains(nm)) m_graphicsContext->specifyAttribute(command->m_parameterAttributeToShaderNames[nm], attr); else qCDebug(Render::Rendering) << "Couldn't find a Parameter attribute named " << nm; } if (drawIndexed) - m_graphicsContext->specifyIndices(meshData->indexAttribute().staticCast<Attribute>()); + m_graphicsContext->specifyIndices(static_cast<QAttribute *>(meshData->indexAttribute())); if (vao) vao->release(); diff --git a/src/render/frontend/qcuboidmesh.cpp b/src/render/frontend/qcuboidmesh.cpp index d8fb1175e..39cb2615c 100644 --- a/src/render/frontend/qcuboidmesh.cpp +++ b/src/render/frontend/qcuboidmesh.cpp @@ -497,32 +497,32 @@ QMeshDataPtr createCuboidMesh(float xExtent, vertices, indices, baseVertex); // Wrap the raw bytes in buffers and set attributes/indices on the mesh - BufferPtr vertexBuffer(new Buffer(QOpenGLBuffer::VertexBuffer)); - vertexBuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *vertexBuffer(new QBuffer(QBuffer::VertexBuffer)); + vertexBuffer->setUsage(QBuffer::StaticDraw); vertexBuffer->setData(vertexBytes); - BufferPtr indexBuffer(new Buffer(QOpenGLBuffer::IndexBuffer)); - indexBuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer)); + indexBuffer->setUsage(QBuffer::StaticDraw); indexBuffer->setData(indexBytes); QMeshDataPtr mesh(new QMeshData(QMeshData::Triangles)); quint32 offset = 0; mesh->addAttribute(QMeshData::defaultPositionAttributeName(), - AttributePtr(new Attribute(vertexBuffer, GL_FLOAT_VEC3, nVerts, offset, stride))); + new QAttribute(vertexBuffer, GL_FLOAT_VEC3, nVerts, offset, stride)); offset += 3 * sizeof(float); mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), - AttributePtr(new Attribute(vertexBuffer, GL_FLOAT_VEC2, nVerts, offset, stride))); + new QAttribute(vertexBuffer, GL_FLOAT_VEC2, nVerts, offset, stride)); offset += 2 * sizeof(float); mesh->addAttribute(QMeshData::defaultNormalAttributeName(), - AttributePtr(new Attribute(vertexBuffer, GL_FLOAT_VEC3, nVerts, offset, stride))); + new QAttribute(vertexBuffer, GL_FLOAT_VEC3, nVerts, offset, stride)); offset += 3 * sizeof(float); mesh->addAttribute(QMeshData::defaultTangentAttributeName(), - AttributePtr(new Attribute(vertexBuffer, GL_FLOAT_VEC4, nVerts, offset, stride))); + new QAttribute(vertexBuffer, GL_FLOAT_VEC4, nVerts, offset, stride)); - mesh->setIndexAttribute(AttributePtr(new Attribute(indexBuffer, GL_UNSIGNED_SHORT, indexCount, 0, 0))); + mesh->setIndexAttribute(new QAttribute(indexBuffer, GL_UNSIGNED_SHORT, indexCount, 0, 0)); mesh->computeBoundsFromAttribute(QMeshData::defaultPositionAttributeName()); qCDebug(Render::Frontend) << "computed axis-aligned bounding box is:" << mesh->boundingBox(); diff --git a/src/render/frontend/qcylindermesh.cpp b/src/render/frontend/qcylindermesh.cpp index 5f173fbc4..2ddbb3266 100644 --- a/src/render/frontend/qcylindermesh.cpp +++ b/src/render/frontend/qcylindermesh.cpp @@ -173,29 +173,29 @@ QMeshDataPtr assembleMesh(const QByteArray &verticesBytes, quint32 vertexSize, i { QMeshDataPtr mesh(new QMeshData(QMeshData::Triangles)); - BufferPtr verticesBuffer(new Buffer(QOpenGLBuffer::VertexBuffer)); - verticesBuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *verticesBuffer(new QBuffer(QBuffer::VertexBuffer)); + verticesBuffer->setUsage(QBuffer::StaticDraw); verticesBuffer->setData(verticesBytes); mesh->addAttribute(QMeshData::defaultPositionAttributeName(), - QAbstractAttributePtr(new Attribute(verticesBuffer, GL_FLOAT_VEC3, - verticesCount, 0, vertexSize))); + new QAttribute(verticesBuffer, GL_FLOAT_VEC3, + verticesCount, 0, vertexSize)); quint32 offset = sizeof(float) * 3; mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), - QAbstractAttributePtr(new Attribute(verticesBuffer, GL_FLOAT_VEC2, - verticesCount, offset, vertexSize))); + new QAttribute(verticesBuffer, GL_FLOAT_VEC2, + verticesCount, offset, vertexSize)); offset += sizeof(float) * 2; mesh->addAttribute(QMeshData::defaultNormalAttributeName(), - QAbstractAttributePtr(new Attribute(verticesBuffer, GL_FLOAT_VEC3, - verticesCount, offset, vertexSize))); + new QAttribute(verticesBuffer, GL_FLOAT_VEC3, + verticesCount, offset, vertexSize)); offset += sizeof(float) * 3; - BufferPtr indicesBuffer(new Buffer(QOpenGLBuffer::IndexBuffer)); - indicesBuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *indicesBuffer(new QBuffer(QBuffer::IndexBuffer)); + indicesBuffer->setUsage(QBuffer::StaticDraw); indicesBuffer->setData(indicesBytes); - mesh->setIndexAttribute(AttributePtr(new Attribute(indicesBuffer, GL_UNSIGNED_SHORT, indicesCount, 0, 0))); + mesh->setIndexAttribute(new QAttribute(indicesBuffer, GL_UNSIGNED_SHORT, indicesCount, 0, 0)); mesh->computeBoundsFromAttribute(QMeshData::defaultPositionAttributeName()); diff --git a/src/render/frontend/qgeometry.cpp b/src/render/frontend/qgeometry.cpp new file mode 100644 index 000000000..156b0f5f2 --- /dev/null +++ b/src/render/frontend/qgeometry.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 "qgeometry.h" + +#include <private/qnode_p.h> +#include <Qt3DCore/qabstractattribute.h> +#include <Qt3DCore/qscenepropertychange.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +class QGeometryPrivate : public QNodePrivate +{ +public: + Q_DECLARE_PUBLIC(QGeometry) + QGeometryPrivate() + : QNodePrivate() + {} + + QAttributeList m_attributes; +}; + +QGeometry::QGeometry(QNode *parent) + : QNode(*new QGeometryPrivate(), parent) +{ +} + +QGeometry::~QGeometry() +{ + QNode::cleanup(); +} + +void QGeometry::addAttribute(QAbstractAttribute *attribute) +{ + Q_D(QGeometry); + if (!d->m_attributes.contains(attribute)) { + d->m_attributes.append(attribute); + + // We need to add it as a child of the current node if it has been declared inline + // Or not previously added as a child of the current node so that + // 1) The backend gets notified about it's creation + // 2) When the current node is destroyed, it gets destroyed as well + if (!attribute->parent()) + attribute->setParent(this); + + if (d->m_changeArbiter != Q_NULLPTR) { + QScenePropertyChangePtr change(new QScenePropertyChange(NodeAdded, QSceneChange::Node, id())); + change->setPropertyName("attribute"); + change->setValue(QVariant::fromValue(attribute->id())); + d->notifyObservers(change); + } + } +} + +void QGeometry::removeAttribute(QAbstractAttribute *attribute) +{ + Q_D(QGeometry); + if (d->m_changeArbiter != Q_NULLPTR) { + QScenePropertyChangePtr change(new QScenePropertyChange(NodeRemoved, QSceneChange::Node, id())); + change->setPropertyName("attribute"); + change->setValue(QVariant::fromValue(attribute->id())); + d->notifyObservers(change); + } + d->m_attributes.removeOne(attribute); +} + +QAttributeList QGeometry::attributes() const +{ + Q_D(const QGeometry); + return d->m_attributes; +} + +void QGeometry::copy(const QNode *ref) +{ + QNode::copy(ref); + const QGeometry *geometry = static_cast<const QGeometry *>(ref); + Q_FOREACH (QAbstractAttribute *attribute, geometry->d_func()->m_attributes) + d_func()->m_attributes.append(qobject_cast<QAbstractAttribute *>(QNode::clone(attribute))); +} + +} // Qt3D + +QT_END_NAMESPACE diff --git a/src/render/frontend/qgeometry.h b/src/render/frontend/qgeometry.h new file mode 100644 index 000000000..c696a402e --- /dev/null +++ b/src/render/frontend/qgeometry.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 QT3D_QGEOMETRY_H +#define QT3D_QGEOMETRY_H + +#include <Qt3DCore/qnode.h> +#include <Qt3DRenderer/qt3drenderer_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +class QGeometryPrivate; +class QAbstractAttribute; + +typedef QVector<QAbstractAttribute *> QAttributeList; + +class QT3DRENDERERSHARED_EXPORT QGeometry : public QNode +{ + Q_OBJECT + +public: + explicit QGeometry(QNode *parent = 0); + ~QGeometry(); + + QAttributeList attributes() const; + void addAttribute(QAbstractAttribute *attribute); + void removeAttribute(QAbstractAttribute *attribute); + +protected: + void copy(const QNode *ref) Q_DECL_OVERRIDE; + +private: + Q_DECLARE_PRIVATE(QGeometry) + QT3D_CLONEABLE(QGeometry) +}; + +} // Qt3D + +QT_END_NAMESPACE + +#endif // QT3D_QGEOMETRY_H diff --git a/src/render/frontend/qgeometryrenderer.cpp b/src/render/frontend/qgeometryrenderer.cpp new file mode 100644 index 000000000..b5acdd02f --- /dev/null +++ b/src/render/frontend/qgeometryrenderer.cpp @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 "qgeometryrenderer.h" +#include "qgeometryrenderer_p.h" + +#include <private/qcomponent_p.h> +#include <Qt3DCore/qscenepropertychange.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +QGeometryRendererPrivate::QGeometryRendererPrivate() + : QComponentPrivate() + , m_instanceCount(1) + , m_baseVertex(0) + , m_baseInstance(0) + , m_restartIndex(-1) + , m_primitiveRestart(false) + , m_geometry(Q_NULLPTR) + , m_primitiveType(QGeometryRenderer::Triangles) +{ +} + +QGeometryRenderer::QGeometryRenderer(QNode *parent) + : QComponent(*new QGeometryRendererPrivate(), parent) +{ +} + +QGeometryRenderer::~QGeometryRenderer() +{ + QComponent::cleanup(); +} + +QGeometryRenderer::QGeometryRenderer(QGeometryRendererPrivate &dd, QNode *parent) + : QComponent(dd, parent) +{ +} + +int QGeometryRenderer::instanceCount() const +{ + Q_D(const QGeometryRenderer); + return d->m_instanceCount; +} + +int QGeometryRenderer::baseVertex() const +{ + Q_D(const QGeometryRenderer); + return d->m_baseVertex; +} + +int QGeometryRenderer::baseInstance() const +{ + Q_D(const QGeometryRenderer); + return d->m_baseInstance; +} + +int QGeometryRenderer::restartIndex() const +{ + Q_D(const QGeometryRenderer); + return d->m_restartIndex; +} + +bool QGeometryRenderer::primitiveRestart() const +{ + Q_D(const QGeometryRenderer); + return d->m_primitiveRestart; +} + +QGeometry *QGeometryRenderer::geometry() const +{ + Q_D(const QGeometryRenderer); + return d->m_geometry; +} + +QGeometryRenderer::PrimitiveType QGeometryRenderer::primitiveType() const +{ + Q_D(const QGeometryRenderer); + return d->m_primitiveType; +} + +void QGeometryRenderer::setInstanceCount(int instanceCount) +{ + Q_D(QGeometryRenderer); + if (d->m_instanceCount == instanceCount) + return; + + d->m_instanceCount = instanceCount; + emit instanceCountChanged(); +} + +void QGeometryRenderer::setBaseVertex(int baseVertex) +{ + Q_D(QGeometryRenderer); + if (d->m_baseVertex == baseVertex) + return; + + d->m_baseVertex = baseVertex; + emit baseVertexChanged(); +} + +void QGeometryRenderer::setBaseInstance(int baseInstance) +{ + Q_D(QGeometryRenderer); + if (d->m_baseInstance == baseInstance) + return; + + d->m_baseInstance = baseInstance; + emit baseInstanceChanged(); +} + +void QGeometryRenderer::setRestartIndex(int index) +{ + Q_D(QGeometryRenderer); + if (index == d->m_restartIndex) + return; + + d->m_restartIndex = index; + emit restartIndexChanged(); +} + +void QGeometryRenderer::setPrimitiveRestart(bool enabled) +{ + Q_D(QGeometryRenderer); + if (enabled == d->m_primitiveRestart) + return; + + d->m_primitiveRestart = enabled; + emit primitiveRestartChanged(); +} + +void QGeometryRenderer::setGeometry(QGeometry *geometry) +{ + Q_D(QGeometryRenderer); + if (d->m_geometry == geometry) + return; + + if (d->m_geometry && d->m_changeArbiter) { + QScenePropertyChangePtr change(new QScenePropertyChange(NodeRemoved, QSceneChange::Node, id())); + change->setPropertyName("geometry"); + change->setValue(QVariant::fromValue(d->m_geometry->id())); + d->notifyObservers(change); + } + + if (geometry && !geometry->parent()) + geometry->setParent(this); + + d->m_geometry = geometry; + const bool blocked = blockNotifications(true); + emit geometryChanged(); + blockNotifications(blocked); + + if (d->m_geometry && d->m_changeArbiter) { + QScenePropertyChangePtr change(new QScenePropertyChange(NodeAdded, QSceneChange::Node, id())); + change->setPropertyName("geometry"); + change->setValue(QVariant::fromValue(d->m_geometry->id())); + d->notifyObservers(change); + } +} + +void QGeometryRenderer::setPrimitiveType(QGeometryRenderer::PrimitiveType primitiveType) +{ + Q_D(QGeometryRenderer); + if (d->m_primitiveType == primitiveType) + return; + + d->m_primitiveType = primitiveType; + emit primitiveTypeChanged(); +} + +void QGeometryRenderer::copy(const QNode *ref) +{ + QComponent::copy(ref); + const QGeometryRenderer *other = static_cast<const QGeometryRenderer *>(ref); + d_func()->m_instanceCount = other->d_func()->m_instanceCount; + d_func()->m_baseVertex = other->d_func()->m_baseVertex; + d_func()->m_baseInstance = other->d_func()->m_baseInstance; + d_func()->m_restartIndex = other->d_func()->m_restartIndex; + d_func()->m_primitiveRestart = other->d_func()->m_primitiveRestart; + d_func()->m_primitiveType = other->d_func()->m_primitiveType; + d_func()->m_geometry = static_cast<QGeometry *>(QNode::clone(other->d_func()->m_geometry)); +} + +} // Qt3D + +QT_END_NAMESPACE diff --git a/src/render/frontend/qgeometryrenderer.h b/src/render/frontend/qgeometryrenderer.h new file mode 100644 index 000000000..3258b6082 --- /dev/null +++ b/src/render/frontend/qgeometryrenderer.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 QT3D_QGEOMETRYRENDERER_H +#define QT3D_QGEOMETRYRENDERER_H + +#include <Qt3DCore/qcomponent.h> +#include <Qt3DRenderer/qgeometry.h> +#include <Qt3DRenderer/qt3drenderer_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +class QGeometryRendererPrivate; + +class QT3DRENDERERSHARED_EXPORT QGeometryRenderer : public QComponent +{ + Q_OBJECT + Q_PROPERTY(int instanceCount READ instanceCount WRITE setInstanceCount NOTIFY instanceCountChanged) + Q_PROPERTY(int baseVertex READ baseVertex WRITE setBaseVertex NOTIFY baseVertexChanged) + Q_PROPERTY(int baseInstance READ baseInstance WRITE setBaseInstance NOTIFY baseInstanceChanged) + Q_PROPERTY(int restartIndex READ restartIndex WRITE setRestartIndex NOTIFY restartIndexChanged) + Q_PROPERTY(bool primitiveRestart READ primitiveRestart WRITE setPrimitiveRestart NOTIFY primitiveRestartChanged) + Q_PROPERTY(Qt3D::QGeometry* geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) + Q_PROPERTY(PrimitiveType primitiveType READ primitiveType WRITE setPrimitiveType NOTIFY primitiveTypeChanged) + +public: + explicit QGeometryRenderer(QNode *parent = 0); + ~QGeometryRenderer(); + + enum PrimitiveType { + Points = 0x0000, + Lines = 0x0001, + LineLoop = 0x0002, + LineStrip = 0x0003, + Triangles = 0x0004, + TriangleStrip = 0x0005, + TriangleFan = 0x0006, + LinesAdjacency = 0x000A, + TrianglesAdjacency = 0x000C, + LineStripAdjacency = 0x000B, + TriangleStripAdjacency = 0x000D, + Patches = 0x000E + }; + Q_ENUM(PrimitiveType) + + // how to figure out index count, bounding boxes, and all the fancy stuff that QMeshData provides for us? + // also how to figure out which attribute(s?) hold the indices? + + int instanceCount() const; + int baseVertex() const; + int baseInstance() const; + int restartIndex() const; + bool primitiveRestart() const; + QGeometry *geometry() const; + PrimitiveType primitiveType() const; + + void setInstanceCount(int instanceCount); + void setBaseVertex(int baseVertex); + void setBaseInstance(int baseInstance); + void setRestartIndex(int index); + void setPrimitiveRestart(bool enabled); + void setGeometry(QGeometry *geometry); + void setPrimitiveType(PrimitiveType primitiveType); + +Q_SIGNALS: + void instanceCountChanged(); + void baseVertexChanged(); + void baseInstanceChanged(); + void restartIndexChanged(); + void primitiveRestartChanged(); + void geometryChanged(); + void primitiveTypeChanged(); + +protected: + QGeometryRenderer(QGeometryRendererPrivate &dd, QNode *parent = 0); + void copy(const QNode *ref) Q_DECL_OVERRIDE; + +private: + Q_DECLARE_PRIVATE(QGeometryRenderer) + QT3D_CLONEABLE(QGeometryRenderer) +}; + +} // Qt3D + +QT_END_NAMESPACE + +#endif // QT3D_QGEOMETRYRENDERER_H diff --git a/src/render/frontend/qgeometryrenderer_p.h b/src/render/frontend/qgeometryrenderer_p.h new file mode 100644 index 000000000..c32c2df41 --- /dev/null +++ b/src/render/frontend/qgeometryrenderer_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 QT3D_QGEOMETRYRENDERER_P_H +#define QT3D_QGEOMETRYRENDERER_P_H + +#include <Qt3DCore/private/qcomponent_p.h> +#include <Qt3DRenderer/qgeometryrenderer.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +class QGeometryRendererPrivate : public QComponentPrivate +{ +public: + QGeometryRendererPrivate(); + Q_DECLARE_PUBLIC(QGeometryRenderer) + + int m_instanceCount; + int m_baseVertex; + int m_baseInstance; + int m_restartIndex; + bool m_primitiveRestart; + QGeometry *m_geometry; + QGeometryRenderer::PrimitiveType m_primitiveType; +}; + +} // Qt3D + +QT_END_NAMESPACE + + +#endif // QT3D_QGEOMETRYRENDERER_P_H + diff --git a/src/render/frontend/qitemmodelbuffer.cpp b/src/render/frontend/qitemmodelbuffer.cpp index 08cfae34a..f842854e5 100644 --- a/src/render/frontend/qitemmodelbuffer.cpp +++ b/src/render/frontend/qitemmodelbuffer.cpp @@ -108,6 +108,7 @@ void variantToBytes(void* dest, const QVariant& v, GLint type) } QItemModelBuffer::QItemModelBuffer() + : m_buffer(Q_NULLPTR) { } @@ -117,7 +118,8 @@ void QItemModelBuffer::setModel(QAbstractItemModel *model) return; m_model = model; - m_buffer.clear(); + delete m_buffer; + m_buffer = Q_NULLPTR; connect(m_model, SIGNAL(modelReset()), this, SLOT(onModelReset())); connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), @@ -127,7 +129,8 @@ void QItemModelBuffer::setModel(QAbstractItemModel *model) void QItemModelBuffer::setRoot(const QModelIndex &rootIndex) { m_rootIndex = rootIndex; - m_buffer.clear(); + delete m_buffer; + m_buffer = Q_NULLPTR; } void QItemModelBuffer::mapRoleName(QByteArray roleName, int elementType) @@ -144,21 +147,23 @@ void QItemModelBuffer::mapRoleName(QByteArray roleName, QString attributeName, i } m_mappings.append(RoleMapping(roleName, attributeName, elementType)); - m_buffer.clear(); + delete m_buffer; + m_buffer = Q_NULLPTR; } -BufferPtr QItemModelBuffer::buffer() +QBuffer *QItemModelBuffer::buffer() { if (!m_buffer) { if (!validateRoles()) return m_buffer; + qDeleteAll(m_attributes); m_attributes.clear(); m_itemStride = 0; - m_buffer.reset(new Buffer(QOpenGLBuffer::VertexBuffer)); + m_buffer = new QBuffer(QBuffer::VertexBuffer); // assume model will change - m_buffer->setUsage(QOpenGLBuffer::DynamicDraw); + m_buffer->setUsage(QBuffer::DynamicDraw); int rowCount = m_model->rowCount(m_rootIndex); int offset = 0; @@ -168,7 +173,7 @@ BufferPtr QItemModelBuffer::buffer() for (int m=0; m<mappingCount; ++m) { const RoleMapping mapping(m_mappings.at(m)); - AttributePtr attr(new Attribute(m_buffer, mapping.type, + QAttribute *attr(new QAttribute(m_buffer, mapping.type, rowCount, offset, m_itemStride)); m_attributes[mapping.attribute] = attr; @@ -186,7 +191,7 @@ QStringList QItemModelBuffer::attributeNames() const return m_attributes.keys(); } -AttributePtr QItemModelBuffer::attributeByName(QString nm) const +QAttribute *QItemModelBuffer::attributeByName(QString nm) const { return m_attributes.value(nm); } diff --git a/src/render/frontend/qitemmodelbuffer.h b/src/render/frontend/qitemmodelbuffer.h index 311690f7f..6e02a6e53 100644 --- a/src/render/frontend/qitemmodelbuffer.h +++ b/src/render/frontend/qitemmodelbuffer.h @@ -63,10 +63,10 @@ public: void mapRoleName(QByteArray roleName, int type); void mapRoleName(QByteArray roleName, QString attributeName, int type); - BufferPtr buffer(); + QBuffer *buffer(); QStringList attributeNames() const; - AttributePtr attributeByName(QString nm) const; + QAttribute *attributeByName(QString nm) const; private Q_SLOTS: @@ -89,8 +89,8 @@ private: QList<RoleMapping> m_mappings; - BufferPtr m_buffer; - QMap<QString, AttributePtr> m_attributes; + QBuffer *m_buffer; + QMap<QString, QAttribute *> m_attributes; int m_itemStride; QByteArray computeBufferData(); diff --git a/src/render/frontend/qmeshv2.cpp b/src/render/frontend/qmeshv2.cpp new file mode 100644 index 000000000..7fbb75770 --- /dev/null +++ b/src/render/frontend/qmeshv2.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 "qmeshv2.h" + +#include <private/qgeometryrenderer_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +class QMeshV2Private : public QGeometryRendererPrivate +{ +public: + Q_DECLARE_PUBLIC(QMeshV2) + QMeshV2Private(); + QUrl m_source; +}; + +QMeshV2Private::QMeshV2Private() + : QGeometryRendererPrivate() +{ +} + +QMeshV2::QMeshV2(QNode *parent) + : QGeometryRenderer(*new QMeshV2Private(), parent) +{ +} + +QMeshV2::~QMeshV2() +{ + QGeometryRenderer::cleanup(); +} + +QUrl QMeshV2::source() const +{ + Q_D(const QMeshV2); + return d->m_source; +} + +void QMeshV2::setSource(const QUrl &source) +{ + Q_D(QMeshV2); + if (d->m_source == source) + return; + + d->m_source = source; + emit sourceChanged(source); +} + + +void QMeshV2::copy(const QNode *ref) +{ + QGeometryRenderer::copy(ref); + const QMeshV2 *mesh = static_cast<const QMeshV2 *>(ref); + d_func()->m_source = mesh->d_func()->m_source; +} + +} + +QT_END_NAMESPACE diff --git a/src/render/frontend/qmeshv2.h b/src/render/frontend/qmeshv2.h new file mode 100644 index 000000000..8cad897a5 --- /dev/null +++ b/src/render/frontend/qmeshv2.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 QT3D_QMESHV2_H +#define QT3D_QMESHV2_H + +#include <Qt3DRenderer/qt3drenderer_global.h> +#include <Qt3DRenderer/qgeometryrenderer.h> +#include <QUrl> + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +class QMeshV2Private; + +class QT3DRENDERERSHARED_EXPORT QMeshV2 : public QGeometryRenderer +{ + Q_OBJECT + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + +public: + QMeshV2(QNode *parent = 0); + ~QMeshV2(); + + QUrl source() const; + void setSource(const QUrl &arg); + + // FIXME now this is an attribute provider directly. but we still do want + // a functor factory for loading the mesh data to load it in a aspect's job? + // so when THAT happens, how is the loaded mesh data connected to this class? + + // should this class have something like + // * the usual mesh functor to create mesh data + // * a protected/private "setMeshData" that sets back the mesh data + // * and attributes() reading from that mesh data? + +Q_SIGNALS: + void sourceChanged(const QUrl &arg); + +protected: + void copy(const QNode *ref) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QMeshV2) + Q_DECLARE_PRIVATE(QMeshV2) + QT3D_CLONEABLE(QMeshV2) +}; + +} + +QT_END_NAMESPACE + +#endif // QT3D_QMESHV2_H diff --git a/src/render/frontend/qplanemesh.cpp b/src/render/frontend/qplanemesh.cpp index e255a6f59..ce00a34b9 100644 --- a/src/render/frontend/qplanemesh.cpp +++ b/src/render/frontend/qplanemesh.cpp @@ -227,27 +227,27 @@ QMeshDataPtr createPlaneMesh(float w, float h, const QSize &resolution) } // Wrap the raw bytes in a buffer - BufferPtr buf(new Buffer(QOpenGLBuffer::VertexBuffer)); - buf->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *buf(new QBuffer(QBuffer::VertexBuffer)); + buf->setUsage(QBuffer::StaticDraw); buf->setData(bufferBytes); // Create the mesh data, specify the vertex format and data QMeshDataPtr mesh(new QMeshData(QMeshData::Triangles)); quint32 offset = 0; mesh->addAttribute(QMeshData::defaultPositionAttributeName(), - AttributePtr(new Attribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride))); + new QAttribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride)); offset += 3 * sizeof(float); mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), - AttributePtr(new Attribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride))); + new QAttribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride)); offset += 2 * sizeof(float); mesh->addAttribute(QMeshData::defaultNormalAttributeName(), - AttributePtr(new Attribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride))); + new QAttribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride)); offset += 3 * sizeof(float); mesh->addAttribute(QMeshData::defaultTangentAttributeName(), - AttributePtr(new Attribute(buf, GL_FLOAT_VEC4, nVerts, offset, stride))); + new QAttribute(buf, GL_FLOAT_VEC4, nVerts, offset, stride)); // Create the index data. 2 triangles per rectangular face const int faces = 2 * (resolution.width() - 1) * (resolution.height() - 1); @@ -276,12 +276,12 @@ QMeshDataPtr createPlaneMesh(float w, float h, const QSize &resolution) } // Wrap the index bytes in a buffer - BufferPtr indexBuffer(new Buffer(QOpenGLBuffer::IndexBuffer)); - indexBuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer)); + indexBuffer->setUsage(QBuffer::StaticDraw); indexBuffer->setData(indexBytes); // Specify index data on the mesh - mesh->setIndexAttribute(AttributePtr(new Attribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0))); + mesh->setIndexAttribute(new QAttribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0)); mesh->computeBoundsFromAttribute(QMeshData::defaultPositionAttributeName()); qCDebug(Render::Frontend) << "computed axis-aligned bounding box is:" << mesh->boundingBox(); diff --git a/src/render/frontend/qspheremesh.cpp b/src/render/frontend/qspheremesh.cpp index 169317891..0519c1c58 100644 --- a/src/render/frontend/qspheremesh.cpp +++ b/src/render/frontend/qspheremesh.cpp @@ -229,21 +229,21 @@ QMeshDataPtr createSphereMesh(double radius, int rings, int slices, bool hasTang } } - BufferPtr buf(new Buffer(QOpenGLBuffer::VertexBuffer)); - buf->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *buf(new QBuffer(QBuffer::VertexBuffer)); + buf->setUsage(QBuffer::StaticDraw); buf->setData(bufferBytes); - mesh->addAttribute(QMeshData::defaultPositionAttributeName(), AttributePtr(new Attribute(buf, GL_FLOAT_VEC3, nVerts, 0, stride))); + mesh->addAttribute(QMeshData::defaultPositionAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, nVerts, 0, stride)); quint32 offset = sizeof(float) * 3; - mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), AttributePtr(new Attribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride))); + mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), new QAttribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride)); offset += sizeof(float) * 2; - mesh->addAttribute(QMeshData::defaultNormalAttributeName(), AttributePtr(new Attribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride))); + mesh->addAttribute(QMeshData::defaultNormalAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride)); offset += sizeof(float) * 3; if (hasTangents) { - mesh->addAttribute(QMeshData::defaultTangentAttributeName(), AttributePtr(new Attribute(buf, GL_FLOAT_VEC4, nVerts, offset, stride))); + mesh->addAttribute(QMeshData::defaultTangentAttributeName(), new QAttribute(buf, GL_FLOAT_VEC4, nVerts, offset, stride)); offset += sizeof(float) * 4; } @@ -296,10 +296,10 @@ QMeshDataPtr createSphereMesh(double radius, int rings, int slices, bool hasTang } } - BufferPtr indexBuffer(new Buffer(QOpenGLBuffer::IndexBuffer)); - indexBuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer)); + indexBuffer->setUsage(QBuffer::StaticDraw); indexBuffer->setData(indexBytes); - mesh->setIndexAttribute(AttributePtr(new Attribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0))); + mesh->setIndexAttribute(new QAttribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0)); mesh->computeBoundsFromAttribute(QMeshData::defaultPositionAttributeName()); qCDebug(Render::Frontend) << "computed sphere bounds is:" << mesh->boundingBox(); diff --git a/src/render/frontend/qtorusmesh.cpp b/src/render/frontend/qtorusmesh.cpp index af115baab..4fe56e86f 100644 --- a/src/render/frontend/qtorusmesh.cpp +++ b/src/render/frontend/qtorusmesh.cpp @@ -214,17 +214,17 @@ QMeshDataPtr createTorusMesh(double radius, double minorRadius, } } - BufferPtr buf(new Buffer(QOpenGLBuffer::VertexBuffer)); - buf->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *buf(new QBuffer(QBuffer::VertexBuffer)); + buf->setUsage(QBuffer::StaticDraw); buf->setData(bufferBytes); - mesh->addAttribute(QMeshData::defaultPositionAttributeName(), QAbstractAttributePtr(new Attribute(buf, GL_FLOAT_VEC3, nVerts, 0, stride))); + mesh->addAttribute(QMeshData::defaultPositionAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, nVerts, 0, stride)); quint32 offset = sizeof(float) * 3; - mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), QAbstractAttributePtr(new Attribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride))); + mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), new QAttribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride)); offset += sizeof(float) * 2; - mesh->addAttribute(QMeshData::defaultNormalAttributeName(), QAbstractAttributePtr(new Attribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride))); + mesh->addAttribute(QMeshData::defaultNormalAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride)); offset += sizeof(float) * 3; QByteArray indexBytes; @@ -250,10 +250,10 @@ QMeshDataPtr createTorusMesh(double radius, double minorRadius, } } - BufferPtr indexBuffer(new Buffer(QOpenGLBuffer::IndexBuffer)); - indexBuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer)); + indexBuffer->setUsage(QBuffer::StaticDraw); indexBuffer->setData(indexBytes); - mesh->setIndexAttribute(AttributePtr(new Attribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0))); + mesh->setIndexAttribute(new QAttribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0)); mesh->computeBoundsFromAttribute(QMeshData::defaultPositionAttributeName()); diff --git a/src/render/frontend/render-frontend.pri b/src/render/frontend/render-frontend.pri index 2a62ad520..9cfab5104 100644 --- a/src/render/frontend/render-frontend.pri +++ b/src/render/frontend/render-frontend.pri @@ -79,7 +79,11 @@ HEADERS += \ $$PWD/qstencilop.h \ $$PWD/qstencilopseparate.h \ $$PWD/qstenciltestseparate.h \ - $$PWD/qstencilmask.h + $$PWD/qstencilmask.h \ + $$PWD/qgeometryrenderer.h \ + $$PWD/qgeometry.h \ + $$PWD/qmeshv2.h \ + $$PWD/qgeometryrenderer_p.h SOURCES += \ $$PWD/qmaterial.cpp \ @@ -133,4 +137,7 @@ SOURCES += \ $$PWD/qstencilop.cpp \ $$PWD/qstencilopseparate.cpp \ $$PWD/qstenciltestseparate.cpp \ - $$PWD/qstencilmask.cpp + $$PWD/qstencilmask.cpp \ + $$PWD/qgeometryrenderer.cpp \ + $$PWD/qgeometry.cpp \ + $$PWD/qmeshv2.cpp diff --git a/src/render/io/gltfparser.cpp b/src/render/io/gltfparser.cpp index 0cff55016..1baaf1712 100644 --- a/src/render/io/gltfparser.cpp +++ b/src/render/io/gltfparser.cpp @@ -625,11 +625,11 @@ void GLTFParser::processJSONBufferView( QString id, const QJsonObject& json ) } int target = json.value(KEY_TARGET).toInt(); - QOpenGLBuffer::Type ty(QOpenGLBuffer::VertexBuffer); + QBuffer::BufferType ty(QBuffer::VertexBuffer); switch (target) { - case GL_ARRAY_BUFFER: ty = QOpenGLBuffer::VertexBuffer; break; - case GL_ELEMENT_ARRAY_BUFFER: ty = QOpenGLBuffer::IndexBuffer; break; + case GL_ARRAY_BUFFER: ty = QBuffer::VertexBuffer; break; + case GL_ELEMENT_ARRAY_BUFFER: ty = QBuffer::IndexBuffer; break; default: qWarning() << Q_FUNC_INFO << "buffer" << id << "unsupported target:" << target; return; @@ -654,7 +654,7 @@ void GLTFParser::processJSONBufferView( QString id, const QJsonObject& json ) } delete f; - BufferPtr b(new Buffer(ty)); + QBuffer *b(new QBuffer(ty)); b->setData(bytes); m_buffers[id] = b; } @@ -667,7 +667,7 @@ void GLTFParser::processJSONAccessor( QString id, const QJsonObject& json ) return; } - BufferPtr buf = m_buffers.value(bvName); + QBuffer *buf = m_buffers.value(bvName); int offset = 0, stride = 0; int type = json.value(KEY_TYPE).toInt(); int count = json.value(KEY_COUNT).toInt(); @@ -677,7 +677,7 @@ void GLTFParser::processJSONAccessor( QString id, const QJsonObject& json ) if ( json.contains(KEY_BYTE_STRIDE)) stride = json.value(KEY_BYTE_STRIDE).toInt(); - AttributePtr attr( new Attribute( buf, type, count, offset, stride ) ); + QAttribute *attr( new QAttribute( buf, type, count, offset, stride ) ); m_attributeDict[id] = attr; } diff --git a/src/render/io/gltfparser_p.h b/src/render/io/gltfparser_p.h index d18e4483e..0ca5edc28 100644 --- a/src/render/io/gltfparser_p.h +++ b/src/render/io/gltfparser_p.h @@ -114,7 +114,7 @@ private: // so record the association here for when we instantiate meshes QMap<QMeshData*, QString> m_meshMaterialDict; - QMap<QString, AttributePtr> m_attributeDict; + QMap<QString, QAttribute *> m_attributeDict; class BufferData { @@ -131,7 +131,7 @@ private: QMap<QString, QMaterial*> m_materialCache; QMap<QString, BufferData> m_bufferDatas; - QMap<QString, BufferPtr> m_buffers; + QMap<QString, QBuffer*> m_buffers; QMap<QString, QString> m_shaderPaths; QMap<QString, QShaderProgram*> m_programs; diff --git a/src/render/io/objloader.cpp b/src/render/io/objloader.cpp index 5bde449d8..7cd0dce69 100644 --- a/src/render/io/objloader.cpp +++ b/src/render/io/objloader.cpp @@ -244,26 +244,26 @@ QMeshData *ObjLoader::mesh() const } } // of buffer filling loop - BufferPtr buf(new Buffer(QOpenGLBuffer::VertexBuffer)); - buf->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *buf(new QBuffer(QBuffer::VertexBuffer)); + buf->setUsage(QBuffer::StaticDraw); buf->setData(bufferBytes); - mesh->addAttribute(QMeshData::defaultPositionAttributeName(), AttributePtr(new Attribute(buf, GL_FLOAT_VEC3, count, 0, stride))); + mesh->addAttribute(QMeshData::defaultPositionAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, count, 0, stride)); quint32 offset = sizeof(float) * 3; if (hasTextureCoordinates()) { - mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), AttributePtr(new Attribute(buf, GL_FLOAT_VEC2, count, offset, stride))); + mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), new QAttribute(buf, GL_FLOAT_VEC2, count, offset, stride)); offset += sizeof(float) * 2; } if (hasNormals()) { - mesh->addAttribute(QMeshData::defaultNormalAttributeName(), AttributePtr(new Attribute(buf, GL_FLOAT_VEC3, count, offset, stride))); + mesh->addAttribute(QMeshData::defaultNormalAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, count, offset, stride)); offset += sizeof(float) * 3; } if (hasTangents()) { - mesh->addAttribute(QMeshData::defaultTangentAttributeName(), AttributePtr(new Attribute(buf, GL_FLOAT_VEC4, count, offset, stride))); + mesh->addAttribute(QMeshData::defaultTangentAttributeName(), new QAttribute(buf, GL_FLOAT_VEC4, count, offset, stride)); offset += sizeof(float) * 4; } @@ -284,10 +284,10 @@ QMeshData *ObjLoader::mesh() const memcpy(indexBytes.data(), reinterpret_cast<const char*>(m_indices.data()), indexBytes.size()); } - BufferPtr indexBuffer(new Buffer(QOpenGLBuffer::IndexBuffer)); - indexBuffer->setUsage(QOpenGLBuffer::StaticDraw); + QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer)); + indexBuffer->setUsage(QBuffer::StaticDraw); indexBuffer->setData(indexBytes); - mesh->setIndexAttribute(AttributePtr(new Attribute(indexBuffer, ty, m_indices.size(), 0, 0))); + mesh->setIndexAttribute(new QAttribute(indexBuffer, ty, m_indices.size(), 0, 0)); mesh->computeBoundsFromAttribute(QMeshData::defaultPositionAttributeName()); qCDebug(Render::Io) << "computed bounds is:" << mesh->boundingBox(); diff --git a/src/render/io/qattribute.cpp b/src/render/io/qattribute.cpp index 9087c2d64..814ec0aa8 100644 --- a/src/render/io/qattribute.cpp +++ b/src/render/io/qattribute.cpp @@ -36,10 +36,11 @@ #include "qattribute.h" #include "qattribute_p.h" +#include <QVector4D> #include <QVector3D> #include <QVector2D> #include <QVector> -#include <Qt3DCore/qabstractbuffer.h> +#include <Qt3DRenderer/qbuffer.h> #include <Qt3DRenderer/private/renderlogging_p.h> QT_BEGIN_NAMESPACE @@ -50,28 +51,105 @@ namespace Qt3D { class Qt3D::AttributePrivate \internal */ -AttributePrivate::AttributePrivate() +QAttributePrivate::QAttributePrivate() : QAbstractAttributePrivate() { } -Attribute::Attribute(QAbstractBufferPtr buf, int type, int count, int offset, int stride) - : QAbstractAttribute(*new AttributePrivate, buf, type, count, offset, stride) +QAttribute::QAttribute(QNode *parent) + : QAbstractAttribute(*new QAttributePrivate(), parent) { } -/*! \internal */ -Attribute::Attribute(AttributePrivate &dd, QAbstractBufferPtr buf, int type, int count, int offset, int stride) - : QAbstractAttribute(dd, buf, type, count, offset, stride) +QAttribute::QAttribute(QBuffer *buf, int type, int count, int offset, int stride) + : QAbstractAttribute(*new QAttributePrivate(), buf, QString(), type, count, offset, stride) { } -QVector<QVector3D> Attribute::asVector3D() const +QAttribute::QAttribute(QBuffer *buf, const QString &name, int type, int count, int offset, int stride) + : QAbstractAttribute(*new QAttributePrivate(), buf, name, type, count, offset, stride) { - Q_D(const Attribute); +} + +QAttribute::~QAttribute() +{ + QAbstractAttribute::cleanup(); +} + +void QAttribute::copy(const QNode *ref) +{ + QAbstractAttribute::copy(ref); +} + +QVector<QVector4D> QAttribute::asVector4D() const +{ + Q_D(const QAttribute); const QByteArray buffer = d->m_buffer->data(); const char *rawBuffer = buffer.constData(); - rawBuffer += d->m_offset; + rawBuffer += d->m_byteOffset; + const float* fptr; + int stride; + + switch (type()) { + case GL_FLOAT_VEC2: + stride = sizeof(float) * 2; break; + + case GL_FLOAT_VEC3: + stride = sizeof(float) * 3; break; + + case GL_FLOAT_VEC4: + stride = sizeof(float) * 4; break; + + default: + qCDebug(Render::Io) << Q_FUNC_INFO << "can't convert" << QString::number(type(), 16) << "to QVector3D"; + return QVector<QVector4D>(); + } + + if (d->m_byteStride != 0) + stride = d->m_byteStride; + QVector<QVector4D> result; + result.resize(d->m_count); + + for (uint c = 0; c < d->m_count; ++c) { + QVector4D v; + fptr = reinterpret_cast<const float*>(rawBuffer); + + switch (type()) { + case GL_FLOAT_VEC2: + v.setX(fptr[0]); + v.setY(fptr[1]); + break; + + case GL_FLOAT_VEC3: + v.setX(fptr[0]); + v.setY(fptr[1]); + v.setZ(fptr[2]); + break; + + case GL_FLOAT_VEC4: + v.setX(fptr[0]); + v.setY(fptr[1]); + v.setZ(fptr[2]); + v.setW(fptr[3]); + break; + + default: + break; // should never happen, we check types above + } + + result[c] = v; + rawBuffer += stride; + } + + return result; +} + +QVector<QVector3D> QAttribute::asVector3D() const +{ + Q_D(const QAttribute); + const QByteArray buffer = d->m_buffer->data(); + const char *rawBuffer = buffer.constData(); + rawBuffer += d->m_byteOffset; const float* fptr; int stride; @@ -90,12 +168,12 @@ QVector<QVector3D> Attribute::asVector3D() const return QVector<QVector3D>(); } - if (d->m_stride != 0) - stride = d->m_stride; + if (d->m_byteStride != 0) + stride = d->m_byteStride; QVector<QVector3D> result; result.resize(d->m_count); - for (uint c=0; c < d->m_count; ++c) { + for (uint c = 0; c < d->m_count; ++c) { QVector3D v; fptr = reinterpret_cast<const float*>(rawBuffer); @@ -103,7 +181,6 @@ QVector<QVector3D> Attribute::asVector3D() const case GL_FLOAT_VEC2: v.setX(fptr[0]); v.setY(fptr[1]); - v.setZ(0.0f); break; case GL_FLOAT_VEC3: @@ -124,11 +201,11 @@ QVector<QVector3D> Attribute::asVector3D() const return result; } -QVector<QVector2D> Attribute::asVector2D() const +QVector<QVector2D> QAttribute::asVector2D() const { - Q_D(const Attribute); + Q_D(const QAttribute); char* rawBuffer = d->m_buffer->data().data(); - rawBuffer += d->m_offset; + rawBuffer += d->m_byteOffset; float* fptr; int stride; @@ -147,13 +224,13 @@ QVector<QVector2D> Attribute::asVector2D() const return QVector<QVector2D>(); } - if (d->m_stride != 0) - stride = d->m_stride; + if (d->m_byteStride != 0) + stride = d->m_byteStride; QVector<QVector2D> result; result.resize(d->m_count); - for (uint c=0; c < d->m_count; ++c) { + for (uint c = 0; c < d->m_count; ++c) { QVector2D v; fptr = reinterpret_cast<float*>(rawBuffer); v.setX(fptr[0]); @@ -165,16 +242,16 @@ QVector<QVector2D> Attribute::asVector2D() const return result; } -void Attribute::dump(int count) +void QAttribute::dump(int count) { - Q_D(const Attribute); - const char* rawBuffer = d->m_buffer->data().constData(); - rawBuffer += d->m_offset; + Q_D(const QAttribute); + const char* rawBuffer = d->m_buffer->data().data(); + rawBuffer += d->m_byteOffset; const float* fptr; const quint16* usptr; - int stride = d->m_stride; + int stride = d->m_byteStride; for (int c=0; c<count; ++c) { switch (type()) { @@ -208,6 +285,11 @@ void Attribute::dump(int count) } } +QBuffer *QAttribute::buffer() const +{ + return static_cast<QBuffer *>(QAbstractAttribute::buffer()); +} + } // Qt3D QT_END_NAMESPACE diff --git a/src/render/io/qattribute.h b/src/render/io/qattribute.h index 29c8228a2..6d312dd30 100644 --- a/src/render/io/qattribute.h +++ b/src/render/io/qattribute.h @@ -39,33 +39,43 @@ #include <Qt3DCore/qabstractattribute.h> #include <Qt3DRenderer/qt3drenderer_global.h> -#include <QOpenGLBuffer> +#include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE namespace Qt3D { -class AttributePrivate; +class QAttributePrivate; +class QBuffer; -class QT3DRENDERERSHARED_EXPORT Attribute : public QAbstractAttribute +class QT3DRENDERERSHARED_EXPORT QAttribute : public QAbstractAttribute { + Q_OBJECT + public: - Attribute(QAbstractBufferPtr buf, int type, int count, int offset=0, int stride = 0); + explicit QAttribute(QNode *parent = 0); + QAttribute(QBuffer *buf, int type, int count, int offset=0, int stride = 0); + QAttribute(QBuffer *buf, const QString &name, int type, int count, int offset=0, int stride = 0); + ~QAttribute(); + QVector<QVector4D> asVector4D() const Q_DECL_OVERRIDE; QVector<QVector3D> asVector3D() const Q_DECL_OVERRIDE; QVector<QVector2D> asVector2D() const Q_DECL_OVERRIDE; void dump(int count) Q_DECL_OVERRIDE; + QBuffer *buffer() const; + protected: - Q_DECLARE_PRIVATE(Attribute) - Attribute(AttributePrivate &dd, QAbstractBufferPtr buf, int type, int count, int offset=0, int stride = 0); -}; + void copy(const QNode *ref) Q_DECL_OVERRIDE; -typedef QSharedPointer<Attribute> AttributePtr; +private: + QT3D_CLONEABLE(QAttribute) + Q_DECLARE_PRIVATE(QAttribute) +}; } // Qt3D QT_END_NAMESPACE -#endif // QATTRIBUTE_H +#endif // QT3D_QATTRIBUTE_H diff --git a/src/render/io/qattribute_p.h b/src/render/io/qattribute_p.h index 82b2278d6..bd660b1eb 100644 --- a/src/render/io/qattribute_p.h +++ b/src/render/io/qattribute_p.h @@ -44,12 +44,12 @@ QT_BEGIN_NAMESPACE namespace Qt3D { -class Attribute; +class QAttribute; -class QT3DRENDERERSHARED_EXPORT AttributePrivate : public QAbstractAttributePrivate +class QT3DRENDERERSHARED_EXPORT QAttributePrivate : public QAbstractAttributePrivate { public: - AttributePrivate(); + QAttributePrivate(); }; } // Qt3D diff --git a/src/render/io/qbuffer.cpp b/src/render/io/qbuffer.cpp index 54ab6d75d..e9ab21c96 100644 --- a/src/render/io/qbuffer.cpp +++ b/src/render/io/qbuffer.cpp @@ -46,55 +46,86 @@ namespace Qt3D { \class Qt3D::BufferPrivate \internal */ -BufferPrivate::BufferPrivate() +QBufferPrivate::QBufferPrivate() : QAbstractBufferPrivate() + , m_usage(QBuffer::StaticDraw) { } -Buffer::Buffer(QOpenGLBuffer::Type ty) - : QAbstractBuffer(*new BufferPrivate) + +QBuffer::QBuffer(QBuffer::BufferType ty, QNode *parent) + : QAbstractBuffer(*new QBufferPrivate(), parent) { - Q_D(Buffer); + Q_D(QBuffer); d->m_type = ty; - d->m_usage = QOpenGLBuffer::StaticDraw; +} + +QBuffer::~QBuffer() +{ + QAbstractBuffer::cleanup(); } /*! \internal */ -Buffer::Buffer(BufferPrivate &dd, QOpenGLBuffer::Type ty) - : QAbstractBuffer(dd) +QBuffer::QBuffer(QBufferPrivate &dd, QBuffer::BufferType ty, QNode *parent) + : QAbstractBuffer(dd, parent) { - Q_D(Buffer); + Q_D(QBuffer); d->m_type = ty; - d->m_usage = QOpenGLBuffer::StaticDraw; } -void Buffer::setUsage(QOpenGLBuffer::UsagePattern usage) +void QBuffer::copy(const QNode *ref) +{ + QAbstractBuffer::copy(ref); + const QBuffer *buffer = static_cast<const QBuffer *>(ref); + d_func()->m_type = buffer->d_func()->m_type; + d_func()->m_usage = buffer->d_func()->m_usage; +} + +QBuffer::UsageType QBuffer::usage() const { - Q_D(Buffer); - d->m_usage = usage; + Q_D(const QBuffer); + return d->m_usage; } -QOpenGLBuffer::Type Buffer::type() const +void QBuffer::setUsage(QBuffer::UsageType usage) { - Q_D(const Buffer); + Q_D(QBuffer); + if (usage != d->m_usage) { + d->m_usage = usage; + emit usageChanged(); + } +} + +QBuffer::BufferType QBuffer::type() const +{ + Q_D(const QBuffer); return d->m_type; } -void Buffer::bind() +void QBuffer::setType(QBuffer::BufferType type) +{ + Q_D(QBuffer); + if (type != d->m_type) { + d->m_type = type; + emit typeChanged(); + } +} + +void QBuffer::bind() { } -void Buffer::create() +void QBuffer::create() { // TO DO -> Wrap createGL in here } -QOpenGLBuffer Buffer::createGL() const +QOpenGLBuffer QBuffer::createGL() const { - Q_D(const Buffer); - QOpenGLBuffer b(d->m_type); - b.setUsagePattern(d->m_usage); + Q_D(const QBuffer); + QOpenGLBuffer b(static_cast<QOpenGLBuffer::Type>(d->m_type)); + b.setUsagePattern(static_cast<QOpenGLBuffer::UsagePattern>(d->m_usage)); if (!b.create()) qCWarning(Render::Io) << Q_FUNC_INFO << "buffer creation failed"; @@ -106,9 +137,9 @@ QOpenGLBuffer Buffer::createGL() const return b; } -void Buffer::upload(QOpenGLBuffer b) +void QBuffer::upload(QOpenGLBuffer b) { - Q_D(Buffer); + Q_D(QBuffer); if (!b.bind()) qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed"; b.allocate(NULL, d->m_data.count()); // orphan the buffer diff --git a/src/render/io/qbuffer.h b/src/render/io/qbuffer.h index 429f0fb3d..a5e1ceedc 100644 --- a/src/render/io/qbuffer.h +++ b/src/render/io/qbuffer.h @@ -50,15 +50,46 @@ GLint elementType(GLint type); GLint tupleSizeFromType(GLint type); GLuint byteSizeFromType(GLint type); -class BufferPrivate; +class QBufferPrivate; -class QT3DRENDERERSHARED_EXPORT Buffer : public QAbstractBuffer +class QT3DRENDERERSHARED_EXPORT QBuffer : public QAbstractBuffer { + Q_OBJECT + Q_PROPERTY(BufferType type READ type WRITE setType NOTIFY typeChanged) + Q_PROPERTY(UsageType usage READ usage WRITE setUsage NOTIFY usageChanged) + public: - explicit Buffer(QOpenGLBuffer::Type ty); + enum BufferType + { + VertexBuffer = 0x8892, // GL_ARRAY_BUFFER + IndexBuffer = 0x8893, // GL_ELEMENT_ARRAY_BUFFER + PixelPackBuffer = 0x88EB, // GL_PIXEL_PACK_BUFFER + PixelUnpackBuffer = 0x88EC // GL_PIXEL_UNPACK_BUFFER + }; + Q_ENUM(BufferType) + + enum UsageType + { + StreamDraw = 0x88E0, // GL_STREAM_DRAW + StreamRead = 0x88E1, // GL_STREAM_READ + StreamCopy = 0x88E2, // GL_STREAM_COPY + StaticDraw = 0x88E4, // GL_STATIC_DRAW + StaticRead = 0x88E5, // GL_STATIC_READ + StaticCopy = 0x88E6, // GL_STATIC_COPY + DynamicDraw = 0x88E8, // GL_DYNAMIC_DRAW + DynamicRead = 0x88E9, // GL_DYNAMIC_READ + DynamicCopy = 0x88EA // GL_DYNAMIC_COPY + }; + Q_ENUM(UsageType) + + QBuffer(BufferType ty = QBuffer::VertexBuffer, QNode *parent = 0); + ~QBuffer(); + + void setUsage(UsageType usage); + UsageType usage() const; - void setUsage(QOpenGLBuffer::UsagePattern usage); - QOpenGLBuffer::Type type() const; + void setType(BufferType type); + BufferType type() const; void bind() Q_DECL_OVERRIDE; void create() Q_DECL_OVERRIDE; @@ -70,11 +101,17 @@ public: // GraphicsContext could listen, orphan the QOpenGLBuffer and hence // reupload next time it's need protected: - Q_DECLARE_PRIVATE(Buffer) - Buffer(BufferPrivate &dd, QOpenGLBuffer::Type ty); -}; + QBuffer(QBufferPrivate &dd, QBuffer::BufferType ty, QNode *parent = 0); + void copy(const QNode *ref) Q_DECL_OVERRIDE; + +Q_SIGNALS: + void typeChanged(); + void usageChanged(); -typedef QSharedPointer<Buffer> BufferPtr; +private: + Q_DECLARE_PRIVATE(QBuffer) + QT3D_CLONEABLE(QBuffer) +}; } // Qt3D diff --git a/src/render/io/qbuffer_p.h b/src/render/io/qbuffer_p.h index c86bdcd5c..036a9e26d 100644 --- a/src/render/io/qbuffer_p.h +++ b/src/render/io/qbuffer_p.h @@ -38,6 +38,7 @@ #define QT3D_QBUFFER_P_H #include <private/qabstractbuffer_p.h> +#include <Qt3DRenderer/qbuffer.h> #include <Qt3DRenderer/qt3drenderer_global.h> #include <QOpenGLBuffer> @@ -45,15 +46,13 @@ QT_BEGIN_NAMESPACE namespace Qt3D { -class Buffer; - -class QT3DRENDERERSHARED_EXPORT BufferPrivate : public QAbstractBufferPrivate +class QT3DRENDERERSHARED_EXPORT QBufferPrivate : public QAbstractBufferPrivate { public: - BufferPrivate(); + QBufferPrivate(); - QOpenGLBuffer::Type m_type; - QOpenGLBuffer::UsagePattern m_usage; + QBuffer::BufferType m_type; + QBuffer::UsageType m_usage; }; } // Qt3D diff --git a/src/render/io/qmeshdata.cpp b/src/render/io/qmeshdata.cpp index ddb2b00d8..0a689257f 100644 --- a/src/render/io/qmeshdata.cpp +++ b/src/render/io/qmeshdata.cpp @@ -49,11 +49,18 @@ namespace Qt3D { \internal */ QMeshDataPrivate::QMeshDataPrivate() - : m_verticesPerPatch(0) + : m_indexAttr(Q_NULLPTR) + , m_verticesPerPatch(0) , m_primitiveType(0) { } +QMeshDataPrivate::~QMeshDataPrivate() +{ + delete m_indexAttr; + qDeleteAll(m_attributes); +} + QMeshData::QMeshData(PrimitiveType primitiveType) : d_ptr(new QMeshDataPrivate) { @@ -62,15 +69,18 @@ QMeshData::QMeshData(PrimitiveType primitiveType) QMeshData::~QMeshData() { +// delete d_ptr; } +// TO DO: Be careful is QMeshData is copied to not leak memory + /*! \internal */ QMeshData::QMeshData(QMeshDataPrivate &dd) : d_ptr(&dd) { } -void QMeshData::addAttribute(const QString &name, const QAbstractAttributePtr &attr) +void QMeshData::addAttribute(const QString &name, QAbstractAttribute *attr) { Q_D(QMeshData); const int i = d->m_attributesNames.indexOf(name); @@ -82,7 +92,7 @@ void QMeshData::addAttribute(const QString &name, const QAbstractAttributePtr &a } } -void QMeshData::setIndexAttribute(const QAbstractAttributePtr &attr) +void QMeshData::setIndexAttribute(QAbstractAttribute *attr) { Q_D(QMeshData); d->m_indexAttr = attr; @@ -94,17 +104,17 @@ QStringList QMeshData::attributeNames() const return d->m_attributesNames; } -QAbstractAttributePtr QMeshData::attributeByName(const QString &name) const +QAbstractAttribute *QMeshData::attributeByName(const QString &name) const { Q_D(const QMeshData); const int i = d->m_attributesNames.indexOf(name); if (i != -1) return d->m_attributes[i]; else - return QAbstractAttributePtr(); + return Q_NULLPTR; } -QAbstractAttributePtr QMeshData::indexAttribute() const +QAbstractAttribute *QMeshData::indexAttribute() const { Q_D(const QMeshData); return d->m_indexAttr; @@ -161,17 +171,17 @@ int QMeshData::primitiveCount() const } } -QList<QAbstractBufferPtr> QMeshData::buffers() const +QVector<QAbstractBuffer *> QMeshData::buffers() const { Q_D(const QMeshData); - QSet<QAbstractBufferPtr> r; + QVector<QAbstractBuffer*> r; + r.reserve(d->m_attributes.count() + 1); if (d->m_indexAttr) - r.insert(d->m_indexAttr->buffer()); - - Q_FOREACH (const QAbstractAttributePtr &v, d->m_attributes) - r.insert(v->buffer()); + r.push_back(d->m_indexAttr->buffer()); + Q_FOREACH (QAbstractAttribute *attr, d->m_attributes) + r.push_back(attr->buffer()); - return r.toList(); + return r; } void QMeshData::setBoundingBox(const QAxisAlignedBoundingBox &bbox) @@ -183,7 +193,7 @@ void QMeshData::setBoundingBox(const QAxisAlignedBoundingBox &bbox) void QMeshData::computeBoundsFromAttribute(const QString &name) { Q_D(QMeshData); - QAbstractAttributePtr attr = attributeByName(name); + QAbstractAttribute *attr = attributeByName(name); if (!attr) { qWarning() << Q_FUNC_INFO << "unknown attribute:" << name; return; diff --git a/src/render/io/qmeshdata.h b/src/render/io/qmeshdata.h index d60aa819b..23116ec7e 100644 --- a/src/render/io/qmeshdata.h +++ b/src/render/io/qmeshdata.h @@ -49,9 +49,6 @@ class QAbstractAttribute; class QAbstractBuffer; class QMeshDataPrivate; -typedef QSharedPointer<QAbstractAttribute> QAbstractAttributePtr; -typedef QSharedPointer<QAbstractBuffer> QAbstractBufferPtr; - class QT3DRENDERERSHARED_EXPORT QMeshData { public: @@ -73,12 +70,12 @@ public: explicit QMeshData(PrimitiveType primitiveType = Triangles); virtual ~QMeshData(); - void addAttribute(const QString &name, const QAbstractAttributePtr &attr); - void setIndexAttribute(const QAbstractAttributePtr &attr); + void addAttribute(const QString &name, QAbstractAttribute *attr); + void setIndexAttribute(QAbstractAttribute *attr); QStringList attributeNames() const; - QAbstractAttributePtr attributeByName(const QString &name) const; - QAbstractAttributePtr indexAttribute() const; + QAbstractAttribute *attributeByName(const QString &name) const; + QAbstractAttribute *indexAttribute() const; static QString defaultPositionAttributeName(); static QString defaultNormalAttributeName(); @@ -94,7 +91,7 @@ public: int primitiveCount() const; - QList<QAbstractBufferPtr> buffers() const; + QVector<QAbstractBuffer *> buffers() const; void setBoundingBox(const QAxisAlignedBoundingBox &bbox); void computeBoundsFromAttribute(const QString &name); diff --git a/src/render/io/qmeshdata_p.h b/src/render/io/qmeshdata_p.h index 19bb89963..c1722396d 100644 --- a/src/render/io/qmeshdata_p.h +++ b/src/render/io/qmeshdata_p.h @@ -56,10 +56,11 @@ class QMeshDataPrivate { public: QMeshDataPrivate(); + ~QMeshDataPrivate(); QStringList m_attributesNames; - QVector<QAbstractAttributePtr> m_attributes; - QAbstractAttributePtr m_indexAttr; + QVector<QAbstractAttribute *> m_attributes; + QAbstractAttribute *m_indexAttr; QAxisAlignedBoundingBox m_bbox; int m_verticesPerPatch; int m_primitiveType; |