diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-08-04 12:40:59 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2015-08-07 14:31:54 +0000 |
commit | 975624820bbb086f0d7957236128ddb043e792d0 (patch) | |
tree | 542c17edee5cb5238704e7aa6c083f15045a6149 /src | |
parent | 4bbe0ad81a06fb42f3aab592e5645e546bfb90db (diff) |
QAbstractAttribute: Type abstracted with an enum
Also added a dataSize property to know the number of components per vertice (1 - 4)
Change-Id: Iaa7cee2a53958ed2ec2f603f3ffc7971c027991d
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/io/qabstractattribute.cpp | 45 | ||||
-rw-r--r-- | src/core/io/qabstractattribute.h | 37 | ||||
-rw-r--r-- | src/core/io/qabstractattribute_p.h | 3 | ||||
-rw-r--r-- | src/plugins/sceneparsers/assimp/assimpparser.cpp | 18 | ||||
-rw-r--r-- | src/render/backend/qgraphicscontext.cpp | 35 | ||||
-rw-r--r-- | src/render/backend/qgraphicscontext_p.h | 3 | ||||
-rw-r--r-- | src/render/backend/renderattribute.cpp | 16 | ||||
-rw-r--r-- | src/render/backend/renderattribute_p.h | 6 | ||||
-rw-r--r-- | src/render/backend/renderer.cpp | 2 | ||||
-rw-r--r-- | src/render/frontend/qcuboidmesh.cpp | 10 | ||||
-rw-r--r-- | src/render/frontend/qcylindermesh.cpp | 8 | ||||
-rw-r--r-- | src/render/frontend/qitemmodelbuffer.cpp | 63 | ||||
-rw-r--r-- | src/render/frontend/qplanemesh.cpp | 10 | ||||
-rw-r--r-- | src/render/frontend/qspheremesh.cpp | 10 | ||||
-rw-r--r-- | src/render/frontend/qtorusmesh.cpp | 8 | ||||
-rw-r--r-- | src/render/io/gltfparser.cpp | 58 | ||||
-rw-r--r-- | src/render/io/objloader.cpp | 16 | ||||
-rw-r--r-- | src/render/io/qattribute.cpp | 120 | ||||
-rw-r--r-- | src/render/io/qattribute.h | 4 |
19 files changed, 305 insertions, 167 deletions
diff --git a/src/core/io/qabstractattribute.cpp b/src/core/io/qabstractattribute.cpp index d3f28c347..f33bc0183 100644 --- a/src/core/io/qabstractattribute.cpp +++ b/src/core/io/qabstractattribute.cpp @@ -52,7 +52,8 @@ QAbstractAttributePrivate::QAbstractAttributePrivate() : QNodePrivate() , m_buffer(Q_NULLPTR) , m_name() - , m_type(0) + , m_dataType(QAbstractAttribute::Float) + , m_dataSize(1) , m_count(0) , m_byteStride(0) , m_byteOffset(0) @@ -71,14 +72,15 @@ 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) +QAbstractAttribute::QAbstractAttribute(QAbstractBuffer *buf, DataType type, uint dataSize, 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_byteOffset = offset; - d->m_type = type; + d->m_dataType = type; + d->m_dataSize = dataSize; d->m_byteStride = stride; } @@ -87,8 +89,7 @@ QAbstractAttribute::QAbstractAttribute(QAbstractAttributePrivate &dd, QNode *par { } - -QAbstractAttribute::QAbstractAttribute(QAbstractAttributePrivate &dd, QAbstractBuffer *buf, const QString &name, int type, uint count, uint offset, uint stride, QNode *parent) +QAbstractAttribute::QAbstractAttribute(QAbstractAttributePrivate &dd, QAbstractBuffer *buf, const QString &name, DataType dataType, uint dataSize, uint count, uint offset, uint stride, QNode *parent) : QNode(dd, parent) { Q_D(QAbstractAttribute); @@ -96,7 +97,8 @@ QAbstractAttribute::QAbstractAttribute(QAbstractAttributePrivate &dd, QAbstractB d->m_name = name; d->m_count = count; d->m_byteOffset = offset; - d->m_type = type; + d->m_dataType = dataType; + d->m_dataSize = dataSize; d->m_byteStride = stride; } @@ -109,7 +111,8 @@ void QAbstractAttribute::copy(const QNode *ref) 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_dataType = attribute->d_func()->m_dataType; + d_func()->m_dataSize = attribute->d_func()->m_dataSize; d_func()->m_byteStride = attribute->d_func()->m_byteStride; d_func()->m_attributeType = attribute->d_func()->m_attributeType; } @@ -126,10 +129,16 @@ QString QAbstractAttribute::name() const return d->m_name; } -int QAbstractAttribute::type() const +uint QAbstractAttribute::dataSize() const +{ + Q_D(const QAbstractAttribute); + return d->m_dataSize; +} + +QAbstractAttribute::DataType QAbstractAttribute::dataType() const { Q_D(const QAbstractAttribute); - return d->m_type; + return d->m_dataType; } uint QAbstractAttribute::count() const @@ -206,15 +215,25 @@ void QAbstractAttribute::setName(const QString &name) emit nameChanged(); } -void QAbstractAttribute::setType(int type) +void QAbstractAttribute::setDataType(DataType type) { Q_D(QAbstractAttribute); - if (d->m_type == type) + if (d->m_dataType == type) return; - d->m_type = type; - emit typeChanged(); + d->m_dataType = type; + emit dataTypeChanged(); +} + +void QAbstractAttribute::setDataSize(uint size) +{ + Q_D(QAbstractAttribute); + if (d->m_dataSize == size) + return; + Q_ASSERT(size >= 1 && size <= 4); + d->m_dataSize = size; + emit dataSizeChanged(); } void QAbstractAttribute::setCount(uint count) diff --git a/src/core/io/qabstractattribute.h b/src/core/io/qabstractattribute.h index cb3b09bb5..f1f157b57 100644 --- a/src/core/io/qabstractattribute.h +++ b/src/core/io/qabstractattribute.h @@ -55,7 +55,8 @@ 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(DataType dataType READ dataType WRITE setDataType NOTIFY dataTypeChanged) + Q_PROPERTY(uint dataSize READ dataSize WRITE setDataSize NOTIFY dataSizeChanged) 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) @@ -63,19 +64,34 @@ class QT3DCORESHARED_EXPORT QAbstractAttribute : public QNode Q_PROPERTY(AttributeType attributeType READ attributeType WRITE setAttributeType NOTIFY attributeTypeChanged) public: - 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) + enum DataType { + Byte = 0, + UnsignedByte, + Short, + UnsignedShort, + Int, + UnsignedInt, + HalfFloat, + Float, + Double + }; + Q_ENUM(DataType) + + explicit QAbstractAttribute(QNode *parent = 0); + ~QAbstractAttribute(); + QAbstractAttribute(QAbstractBuffer *buf, DataType dataType, uint dataSize, uint count, uint offset = 0, uint stride = 0, QNode *parent = 0); + QAbstractBuffer *buffer() const; QString name() const; - int type() const; + DataType dataType() const; + uint dataSize() const; uint count() const; uint byteStride() const; uint byteOffset() const; @@ -87,10 +103,10 @@ public: 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 setDataType(DataType type); + void setDataSize(uint size); void setCount(uint count); void setByteStride(uint byteStride); void setByteOffset(uint byteOffset); @@ -100,7 +116,8 @@ public Q_SLOTS: Q_SIGNALS: void bufferChanged(); void nameChanged(); - void typeChanged(); + void dataTypeChanged(); + void dataSizeChanged(); void countChanged(); void byteStrideChanged(); void byteOffsetChanged(); @@ -109,7 +126,7 @@ Q_SIGNALS: 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); + QAbstractAttribute(QAbstractAttributePrivate &dd, QAbstractBuffer *buf, const QString &name, DataType dataType, uint dataSize, uint count, uint offset = 0, uint stride = 0, QNode *parent = 0); void copy(const QNode *ref) Q_DECL_OVERRIDE; diff --git a/src/core/io/qabstractattribute_p.h b/src/core/io/qabstractattribute_p.h index 6d9c5950d..66cb5f888 100644 --- a/src/core/io/qabstractattribute_p.h +++ b/src/core/io/qabstractattribute_p.h @@ -57,7 +57,8 @@ public: QAbstractBuffer *m_buffer; QString m_name; - int m_type; + QAbstractAttribute::DataType m_dataType; + uint m_dataSize; uint m_count; uint m_byteStride; uint m_byteOffset; diff --git a/src/plugins/sceneparsers/assimp/assimpparser.cpp b/src/plugins/sceneparsers/assimp/assimpparser.cpp index c477ea51f..c01f507a1 100644 --- a/src/plugins/sceneparsers/assimp/assimpparser.cpp +++ b/src/plugins/sceneparsers/assimp/assimpparser.cpp @@ -606,44 +606,44 @@ void AssimpParser::loadMesh(uint meshIndex) // Add vertex attributes to the mesh with the right array meshData->addAttribute(VERTICES_ATTRIBUTE_NAME, new QAttribute(vbuffer, - GL_FLOAT_VEC3, + QAttribute::Float, 3, mesh->mNumVertices, 0, chunkSize * sizeof(float))); meshData->addAttribute(NORMAL_ATTRIBUTE_NAME, new QAttribute(vbuffer, - GL_FLOAT_VEC3, + QAttribute::Float, 3, mesh->mNumVertices, 3 * sizeof(float), chunkSize * sizeof(float))); if (hasTangent) meshData->addAttribute(TANGENT_ATTRIBUTE_NAME, new QAttribute(vbuffer, - GL_FLOAT_VEC3, + QAttribute::Float, 3, mesh->mNumVertices, 6 * sizeof(float), chunkSize * sizeof(float))); if (hasTexture) meshData->addAttribute(TEXTCOORD_ATTRIBUTE_NAME, new QAttribute(vbuffer, - GL_FLOAT_VEC2, + QAttribute::Float, 2, mesh->mNumVertices, (hasTangent ? 9 : 6) * sizeof(float), chunkSize * sizeof(float))); if (hasColor) meshData->addAttribute(COLOR_ATTRIBUTE_NAME, new QAttribute(vbuffer, - GL_FLOAT_VEC4, + QAttribute::Float, 4, mesh->mNumVertices, (6 + (hasTangent ? 3 : 0) + (hasTexture ? 2 : 0)) * sizeof(float), chunkSize * sizeof(float))); - GLuint indiceType; + QAttribute::DataType indiceType; QByteArray ibufferContent; uint indices = mesh->mNumFaces * 3; // If there are less than 65535 indices, indices can then fit in ushort // which saves video memory if (indices >= USHRT_MAX) { - indiceType = GL_UNSIGNED_INT; + indiceType = QAttribute::UnsignedInt; ibufferContent.resize(indices * sizeof(quint32)); for (uint i = 0; i < mesh->mNumFaces; i++) { aiFace face = mesh->mFaces[i]; @@ -652,7 +652,7 @@ void AssimpParser::loadMesh(uint meshIndex) } } else { - indiceType = GL_UNSIGNED_SHORT; + indiceType = QAttribute::UnsignedShort; ibufferContent.resize(indices * sizeof(quint16)); for (uint i = 0; i < mesh->mNumFaces; i++) { aiFace face = mesh->mFaces[i]; @@ -668,7 +668,7 @@ void AssimpParser::loadMesh(uint meshIndex) ibuffer->setData(ibufferContent); // Add indices attributes - meshData->setIndexAttribute(new QAttribute(ibuffer, indiceType, indices, 0, 0)); + meshData->setIndexAttribute(new QAttribute(ibuffer, indiceType, 1, indices, 0, 0)); meshData->computeBoundsFromAttribute(VERTICES_ATTRIBUTE_NAME); diff --git a/src/render/backend/qgraphicscontext.cpp b/src/render/backend/qgraphicscontext.cpp index affa7dd56..141761fa1 100644 --- a/src/render/backend/qgraphicscontext.cpp +++ b/src/render/backend/qgraphicscontext.cpp @@ -885,9 +885,9 @@ void QGraphicsContext::specifyAttribute(const RenderAttribute *attribute, Render } prog->enableAttributeArray(location); prog->setAttributeBuffer(location, - QGraphicsContext::elementType(attribute->type()), + glDataTypeFromAttributeDataType(attribute->dataType()), attribute->byteOffset(), - QGraphicsContext::tupleSizeFromType(attribute->type()), + attribute->dataSize(), attribute->byteStride()); if (attribute->divisor() != 0) { @@ -1012,6 +1012,37 @@ GLuint QGraphicsContext::byteSizeFromType(GLint type) return 0; } +GLint QGraphicsContext::glDataTypeFromAttributeDataType(QAttribute::DataType dataType) +{ + switch (dataType) { + case QAttribute::DataType::Byte: + return GL_BYTE; + case QAttribute::DataType::UnsignedByte: + return GL_UNSIGNED_BYTE; + case QAttribute::DataType::Short: + return GL_SHORT; + case QAttribute::DataType::UnsignedShort: + return GL_UNSIGNED_SHORT; + case QAttribute::DataType::Int: + return GL_INT; + case QAttribute::UnsignedInt: + return GL_UNSIGNED_INT; + case QAttribute::HalfFloat: +#ifdef GL_HALF_FLOAT + return GL_HALF_FLOAT; +#endif +#ifndef QT_OPENGL_ES_2 // Otherwise compile error as Qt defines GL_DOUBLE as GL_FLOAT when using ES2 + case QAttribute::Double: + return GL_DOUBLE; +#endif + case QAttribute::Float: + break; + default: + qWarning() << Q_FUNC_INFO << "unsupported dataType:" << dataType; + } + return GL_FLOAT; +} + } // Render } // Qt3D of namespace diff --git a/src/render/backend/qgraphicscontext_p.h b/src/render/backend/qgraphicscontext_p.h index bd516e145..f53d2c650 100644 --- a/src/render/backend/qgraphicscontext_p.h +++ b/src/render/backend/qgraphicscontext_p.h @@ -49,6 +49,7 @@ #include <Qt3DRenderer/private/quniformvalue_p.h> #include <Qt3DRenderer/qclearbuffer.h> #include <Qt3DRenderer/private/rendershader_p.h> +#include <Qt3DRenderer/qattribute.h> QT_BEGIN_NAMESPACE @@ -185,6 +186,8 @@ public: static GLint elementType(GLint type); static GLint tupleSizeFromType(GLint type); static GLuint byteSizeFromType(GLint type); + static GLint glDataTypeFromAttributeDataType(QAttribute::DataType dataType); + bool supportsVAO() const { return m_supportsVAO; } diff --git a/src/render/backend/renderattribute.cpp b/src/render/backend/renderattribute.cpp index a8435c5bc..4a717849d 100644 --- a/src/render/backend/renderattribute.cpp +++ b/src/render/backend/renderattribute.cpp @@ -46,7 +46,8 @@ namespace Render { RenderAttribute::RenderAttribute() : QBackendNode(ReadOnly) - , m_type(0) + , m_dataType(QAbstractAttribute::Float) + , m_dataSize(1) , m_count(0) , m_byteStride(0) , m_byteOffset(0) @@ -62,7 +63,8 @@ RenderAttribute::~RenderAttribute() void RenderAttribute::cleanup() { - m_type = 0; + m_dataType = QAbstractAttribute::Float; + m_dataSize = 1; m_count = 0; m_byteStride = 0; m_byteOffset = 0; @@ -77,7 +79,8 @@ void RenderAttribute::updateFromPeer(QNode *peer) { QAttribute *attribute = static_cast<QAttribute *>(peer); if (attribute) { - m_type = attribute->type(); + m_dataType = attribute->dataType(); + m_dataSize = attribute->dataSize(); m_count = attribute->count(); m_byteOffset = attribute->byteOffset(); m_byteStride = attribute->byteStride(); @@ -101,8 +104,11 @@ void RenderAttribute::sceneChangeEvent(const QSceneChangePtr &e) if (propertyName == QByteArrayLiteral("name")) { m_name = propertyChange->value().value<QString>(); m_attributeDirty = true; - } else if (propertyName == QByteArrayLiteral("type")) { - m_type = propertyChange->value().value<int>(); + } else if (propertyName == QByteArrayLiteral("dataType")) { + m_dataType = static_cast<QAbstractAttribute::DataType>(propertyChange->value().value<int>()); + m_attributeDirty = true; + } else if (propertyName == QByteArrayLiteral("dataSize")) { + m_dataSize = propertyChange->value().value<uint>(); m_attributeDirty = true; } else if (propertyName == QByteArrayLiteral("count")) { m_count = propertyChange->value().value<uint>(); diff --git a/src/render/backend/renderattribute_p.h b/src/render/backend/renderattribute_p.h index 0cf19d593..92eefe67c 100644 --- a/src/render/backend/renderattribute_p.h +++ b/src/render/backend/renderattribute_p.h @@ -59,7 +59,8 @@ public: inline QNodeId bufferId() const { return m_bufferId; } inline QString name() const { return m_name; } - inline int type() const { return m_type; } + inline QAbstractAttribute::DataType dataType() const { return m_dataType; } + inline uint dataSize() const { return m_dataSize; } inline uint count() const { return m_count; } inline uint byteStride() const { return m_byteStride; } inline uint byteOffset() const { return m_byteOffset; } @@ -71,7 +72,8 @@ public: private: QNodeId m_bufferId; QString m_name; - int m_type; + QAbstractAttribute::DataType m_dataType; + uint m_dataSize; uint m_count; uint m_byteStride; uint m_byteOffset; diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index b2a1bd85e..255284efe 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -908,7 +908,7 @@ void Renderer::executeCommands(const QVector<RenderCommand *> &commands) const GLint primType = rGeometryRenderer->primitiveType(); const bool drawInstanced = rGeometryRenderer->instanceCount() > 1; const bool drawIndexed = indexAttribute != Q_NULLPTR; - const GLint indexType = drawIndexed ? indexAttribute->type() : 0; + const GLint indexType = drawIndexed ? QGraphicsContext::glDataTypeFromAttributeDataType(indexAttribute->dataType()) : 0; // TO DO: Add glMulti Draw variants if (!drawInstanced) { // Non instanced Rendering diff --git a/src/render/frontend/qcuboidmesh.cpp b/src/render/frontend/qcuboidmesh.cpp index 39cb2615c..ed5018371 100644 --- a/src/render/frontend/qcuboidmesh.cpp +++ b/src/render/frontend/qcuboidmesh.cpp @@ -508,21 +508,21 @@ QMeshDataPtr createCuboidMesh(float xExtent, QMeshDataPtr mesh(new QMeshData(QMeshData::Triangles)); quint32 offset = 0; mesh->addAttribute(QMeshData::defaultPositionAttributeName(), - new QAttribute(vertexBuffer, GL_FLOAT_VEC3, nVerts, offset, stride)); + new QAttribute(vertexBuffer, QAttribute::Float, 3, nVerts, offset, stride)); offset += 3 * sizeof(float); mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), - new QAttribute(vertexBuffer, GL_FLOAT_VEC2, nVerts, offset, stride)); + new QAttribute(vertexBuffer, QAttribute::Float, 2, nVerts, offset, stride)); offset += 2 * sizeof(float); mesh->addAttribute(QMeshData::defaultNormalAttributeName(), - new QAttribute(vertexBuffer, GL_FLOAT_VEC3, nVerts, offset, stride)); + new QAttribute(vertexBuffer, QAttribute::Float, 3, nVerts, offset, stride)); offset += 3 * sizeof(float); mesh->addAttribute(QMeshData::defaultTangentAttributeName(), - new QAttribute(vertexBuffer, GL_FLOAT_VEC4, nVerts, offset, stride)); + new QAttribute(vertexBuffer, QAttribute::Float, 4, nVerts, offset, stride)); - mesh->setIndexAttribute(new QAttribute(indexBuffer, GL_UNSIGNED_SHORT, indexCount, 0, 0)); + mesh->setIndexAttribute(new QAttribute(indexBuffer, QAttribute::UnsignedShort, 1, 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 2ddbb3266..3f97b7e4a 100644 --- a/src/render/frontend/qcylindermesh.cpp +++ b/src/render/frontend/qcylindermesh.cpp @@ -178,24 +178,24 @@ QMeshDataPtr assembleMesh(const QByteArray &verticesBytes, quint32 vertexSize, i verticesBuffer->setData(verticesBytes); mesh->addAttribute(QMeshData::defaultPositionAttributeName(), - new QAttribute(verticesBuffer, GL_FLOAT_VEC3, + new QAttribute(verticesBuffer, QAttribute::Float, 3, verticesCount, 0, vertexSize)); quint32 offset = sizeof(float) * 3; mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), - new QAttribute(verticesBuffer, GL_FLOAT_VEC2, + new QAttribute(verticesBuffer, QAttribute::Float, 2, verticesCount, offset, vertexSize)); offset += sizeof(float) * 2; mesh->addAttribute(QMeshData::defaultNormalAttributeName(), - new QAttribute(verticesBuffer, GL_FLOAT_VEC3, + new QAttribute(verticesBuffer, QAttribute::Float, 3, verticesCount, offset, vertexSize)); offset += sizeof(float) * 3; QBuffer *indicesBuffer(new QBuffer(QBuffer::IndexBuffer)); indicesBuffer->setUsage(QBuffer::StaticDraw); indicesBuffer->setData(indicesBytes); - mesh->setIndexAttribute(new QAttribute(indicesBuffer, GL_UNSIGNED_SHORT, indicesCount, 0, 0)); + mesh->setIndexAttribute(new QAttribute(indicesBuffer, QAttribute::UnsignedShort, 1, indicesCount, 0, 0)); mesh->computeBoundsFromAttribute(QMeshData::defaultPositionAttributeName()); diff --git a/src/render/frontend/qitemmodelbuffer.cpp b/src/render/frontend/qitemmodelbuffer.cpp index f842854e5..540d341e0 100644 --- a/src/render/frontend/qitemmodelbuffer.cpp +++ b/src/render/frontend/qitemmodelbuffer.cpp @@ -107,6 +107,63 @@ void variantToBytes(void* dest, const QVariant& v, GLint type) QString::number(type, 16); } +namespace { + +QAbstractAttribute::DataType typeFromGLType(GLint dataType, uint &dataCount) +{ + switch (dataType) { + + case GL_UNSIGNED_SHORT: + dataCount = 1; + return QAbstractAttribute::UnsignedShort; + + case GL_UNSIGNED_BYTE: + dataCount = 1; + return QAbstractAttribute::UnsignedByte; + + case GL_UNSIGNED_INT: + dataCount = 1; + return QAbstractAttribute::UnsignedInt; + + case GL_SHORT: + dataCount = 1; + return QAbstractAttribute::Short; + + case GL_BYTE: + dataCount = 1; + return QAbstractAttribute::Byte; + + case GL_INT: + dataCount = 1; + return QAbstractAttribute::Int; + + case GL_FLOAT: + dataCount = 1; + break; + + case GL_FLOAT_VEC2: + dataCount = 2; + break; + + case GL_FLOAT_VEC3: + dataCount = 3; + break; + + case GL_FLOAT_VEC4: + dataCount = 4; + break; + +// TO DO: Handle doubles + + default: + Q_UNREACHABLE(); + } + + return QAbstractAttribute::Float; +} + +} // anonymous + QItemModelBuffer::QItemModelBuffer() : m_buffer(Q_NULLPTR) { @@ -173,8 +230,10 @@ QBuffer *QItemModelBuffer::buffer() for (int m=0; m<mappingCount; ++m) { const RoleMapping mapping(m_mappings.at(m)); - QAttribute *attr(new QAttribute(m_buffer, mapping.type, - rowCount, + uint dataSize = 0; + QAttribute::DataType dataType = typeFromGLType(mapping.type, dataSize); + QAttribute *attr(new QAttribute(m_buffer, dataType, + dataSize, rowCount, offset, m_itemStride)); m_attributes[mapping.attribute] = attr; offset += Render::QGraphicsContext::byteSizeFromType(mapping.type); diff --git a/src/render/frontend/qplanemesh.cpp b/src/render/frontend/qplanemesh.cpp index ce00a34b9..f8b9f570c 100644 --- a/src/render/frontend/qplanemesh.cpp +++ b/src/render/frontend/qplanemesh.cpp @@ -235,19 +235,19 @@ QMeshDataPtr createPlaneMesh(float w, float h, const QSize &resolution) QMeshDataPtr mesh(new QMeshData(QMeshData::Triangles)); quint32 offset = 0; mesh->addAttribute(QMeshData::defaultPositionAttributeName(), - new QAttribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride)); + new QAttribute(buf, QAttribute::Float, 3, nVerts, offset, stride)); offset += 3 * sizeof(float); mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), - new QAttribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride)); + new QAttribute(buf, QAttribute::Float, 2, nVerts, offset, stride)); offset += 2 * sizeof(float); mesh->addAttribute(QMeshData::defaultNormalAttributeName(), - new QAttribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride)); + new QAttribute(buf, QAttribute::Float, 3, nVerts, offset, stride)); offset += 3 * sizeof(float); mesh->addAttribute(QMeshData::defaultTangentAttributeName(), - new QAttribute(buf, GL_FLOAT_VEC4, nVerts, offset, stride)); + new QAttribute(buf, QAttribute::Float, 4, nVerts, offset, stride)); // Create the index data. 2 triangles per rectangular face const int faces = 2 * (resolution.width() - 1) * (resolution.height() - 1); @@ -281,7 +281,7 @@ QMeshDataPtr createPlaneMesh(float w, float h, const QSize &resolution) indexBuffer->setData(indexBytes); // Specify index data on the mesh - mesh->setIndexAttribute(new QAttribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0)); + mesh->setIndexAttribute(new QAttribute(indexBuffer, QAttribute::UnsignedShort, 1, 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 0519c1c58..87e885a0c 100644 --- a/src/render/frontend/qspheremesh.cpp +++ b/src/render/frontend/qspheremesh.cpp @@ -233,17 +233,17 @@ QMeshDataPtr createSphereMesh(double radius, int rings, int slices, bool hasTang buf->setUsage(QBuffer::StaticDraw); buf->setData(bufferBytes); - mesh->addAttribute(QMeshData::defaultPositionAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, nVerts, 0, stride)); + mesh->addAttribute(QMeshData::defaultPositionAttributeName(), new QAttribute(buf, QAttribute::Float, 3, nVerts, 0, stride)); quint32 offset = sizeof(float) * 3; - mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), new QAttribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride)); + mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), new QAttribute(buf, QAttribute::Float, 2, nVerts, offset, stride)); offset += sizeof(float) * 2; - mesh->addAttribute(QMeshData::defaultNormalAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride)); + mesh->addAttribute(QMeshData::defaultNormalAttributeName(), new QAttribute(buf, QAttribute::Float, 3, nVerts, offset, stride)); offset += sizeof(float) * 3; if (hasTangents) { - mesh->addAttribute(QMeshData::defaultTangentAttributeName(), new QAttribute(buf, GL_FLOAT_VEC4, nVerts, offset, stride)); + mesh->addAttribute(QMeshData::defaultTangentAttributeName(), new QAttribute(buf, QAttribute::Float, 4, nVerts, offset, stride)); offset += sizeof(float) * 4; } @@ -299,7 +299,7 @@ QMeshDataPtr createSphereMesh(double radius, int rings, int slices, bool hasTang QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer)); indexBuffer->setUsage(QBuffer::StaticDraw); indexBuffer->setData(indexBytes); - mesh->setIndexAttribute(new QAttribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0)); + mesh->setIndexAttribute(new QAttribute(indexBuffer, QAttribute::UnsignedShort, 1, 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 4fe56e86f..241553f8d 100644 --- a/src/render/frontend/qtorusmesh.cpp +++ b/src/render/frontend/qtorusmesh.cpp @@ -218,13 +218,13 @@ QMeshDataPtr createTorusMesh(double radius, double minorRadius, buf->setUsage(QBuffer::StaticDraw); buf->setData(bufferBytes); - mesh->addAttribute(QMeshData::defaultPositionAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, nVerts, 0, stride)); + mesh->addAttribute(QMeshData::defaultPositionAttributeName(), new QAttribute(buf, QAttribute::Float, 3, nVerts, 0, stride)); quint32 offset = sizeof(float) * 3; - mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), new QAttribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride)); + mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), new QAttribute(buf, QAttribute::Float, 2, nVerts, offset, stride)); offset += sizeof(float) * 2; - mesh->addAttribute(QMeshData::defaultNormalAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride)); + mesh->addAttribute(QMeshData::defaultNormalAttributeName(), new QAttribute(buf, QAttribute::Float, 3, nVerts, offset, stride)); offset += sizeof(float) * 3; QByteArray indexBytes; @@ -253,7 +253,7 @@ QMeshDataPtr createTorusMesh(double radius, double minorRadius, QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer)); indexBuffer->setUsage(QBuffer::StaticDraw); indexBuffer->setData(indexBytes); - mesh->setIndexAttribute(new QAttribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0)); + mesh->setIndexAttribute(new QAttribute(indexBuffer, QAttribute::UnsignedShort, 1, indices, 0, 0)); mesh->computeBoundsFromAttribute(QMeshData::defaultPositionAttributeName()); diff --git a/src/render/io/gltfparser.cpp b/src/render/io/gltfparser.cpp index 1baaf1712..65c800fb0 100644 --- a/src/render/io/gltfparser.cpp +++ b/src/render/io/gltfparser.cpp @@ -199,6 +199,59 @@ const QString KEY_INTERNAL_FORMAT = QStringLiteral("internalFormat"); // return QParameter::Undefined; //} +QAbstractAttribute::DataType typeFromGLType(GLint dataType, uint &dataCount) +{ + switch (dataType) { + + case GL_UNSIGNED_SHORT: + dataCount = 1; + return QAbstractAttribute::UnsignedShort; + + case GL_UNSIGNED_BYTE: + dataCount = 1; + return QAbstractAttribute::UnsignedByte; + + case GL_UNSIGNED_INT: + dataCount = 1; + return QAbstractAttribute::UnsignedInt; + + case GL_SHORT: + dataCount = 1; + return QAbstractAttribute::Short; + + case GL_BYTE: + dataCount = 1; + return QAbstractAttribute::Byte; + + case GL_INT: + dataCount = 1; + return QAbstractAttribute::Int; + + case GL_FLOAT: + dataCount = 1; + break; + + case GL_FLOAT_VEC2: + dataCount = 2; + break; + + case GL_FLOAT_VEC3: + dataCount = 3; + break; + + case GL_FLOAT_VEC4: + dataCount = 4; + break; + +// TO DO: Handle doubles + + default: + Q_UNREACHABLE(); + } + + return QAbstractAttribute::Float; +} + } // of anonymous namespace class GLTFParserMeshPrivate; @@ -677,7 +730,10 @@ void GLTFParser::processJSONAccessor( QString id, const QJsonObject& json ) if ( json.contains(KEY_BYTE_STRIDE)) stride = json.value(KEY_BYTE_STRIDE).toInt(); - QAttribute *attr( new QAttribute( buf, type, count, offset, stride ) ); + uint dataSize = 0; + QAttribute::DataType dataType = typeFromGLType(type, dataSize); + + QAttribute *attr( new QAttribute( buf, dataType, dataSize, count, offset, stride ) ); m_attributeDict[id] = attr; } diff --git a/src/render/io/objloader.cpp b/src/render/io/objloader.cpp index 7cd0dce69..e727f3210 100644 --- a/src/render/io/objloader.cpp +++ b/src/render/io/objloader.cpp @@ -249,36 +249,36 @@ QMeshData *ObjLoader::mesh() const buf->setData(bufferBytes); - mesh->addAttribute(QMeshData::defaultPositionAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, count, 0, stride)); + mesh->addAttribute(QMeshData::defaultPositionAttributeName(), new QAttribute(buf, QAttribute::Float, 3, count, 0, stride)); quint32 offset = sizeof(float) * 3; if (hasTextureCoordinates()) { - mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), new QAttribute(buf, GL_FLOAT_VEC2, count, offset, stride)); + mesh->addAttribute(QMeshData::defaultTextureCoordinateAttributeName(), new QAttribute(buf, QAttribute::Float, 2, count, offset, stride)); offset += sizeof(float) * 2; } if (hasNormals()) { - mesh->addAttribute(QMeshData::defaultNormalAttributeName(), new QAttribute(buf, GL_FLOAT_VEC3, count, offset, stride)); + mesh->addAttribute(QMeshData::defaultNormalAttributeName(), new QAttribute(buf, QAttribute::Float, 3, count, offset, stride)); offset += sizeof(float) * 3; } if (hasTangents()) { - mesh->addAttribute(QMeshData::defaultTangentAttributeName(), new QAttribute(buf, GL_FLOAT_VEC4, count, offset, stride)); + mesh->addAttribute(QMeshData::defaultTangentAttributeName(), new QAttribute(buf, QAttribute::Float, 4, count, offset, stride)); offset += sizeof(float) * 4; } QByteArray indexBytes; - GLuint ty; + QAttribute::DataType ty; if (m_indices.size() < 65536) { // we can use USHORT - ty = GL_UNSIGNED_SHORT; + ty = QAttribute::UnsignedShort; indexBytes.resize(m_indices.size() * sizeof(quint16)); quint16* usptr = reinterpret_cast<quint16*>(indexBytes.data()); for (int i=0; i<m_indices.size(); ++i) *usptr++ = static_cast<quint16>(m_indices.at(i)); } else { // use UINT - no conversion needed, but let's ensure int is 32-bit! - ty = GL_UNSIGNED_INT; + ty = QAttribute::UnsignedInt; Q_ASSERT(sizeof(int) == sizeof(quint32)); indexBytes.resize(m_indices.size() * sizeof(quint32)); memcpy(indexBytes.data(), reinterpret_cast<const char*>(m_indices.data()), indexBytes.size()); @@ -287,7 +287,7 @@ QMeshData *ObjLoader::mesh() const QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer)); indexBuffer->setUsage(QBuffer::StaticDraw); indexBuffer->setData(indexBytes); - mesh->setIndexAttribute(new QAttribute(indexBuffer, ty, m_indices.size(), 0, 0)); + mesh->setIndexAttribute(new QAttribute(indexBuffer, ty, 1, 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 07612ef71..80fa9dd49 100644 --- a/src/render/io/qattribute.cpp +++ b/src/render/io/qattribute.cpp @@ -61,13 +61,13 @@ QAttribute::QAttribute(QNode *parent) { } -QAttribute::QAttribute(QBuffer *buf, int type, int count, int offset, int stride) - : QAbstractAttribute(*new QAttributePrivate(), buf, QString(), type, count, offset, stride) +QAttribute::QAttribute(QBuffer *buf, DataType type, uint dataSize, int count, int offset, int stride) + : QAbstractAttribute(*new QAttributePrivate(), buf, QString(), type, dataSize, count, offset, stride) { } -QAttribute::QAttribute(QBuffer *buf, const QString &name, int type, int count, int offset, int stride) - : QAbstractAttribute(*new QAttributePrivate(), buf, name, type, count, offset, stride) +QAttribute::QAttribute(QBuffer *buf, const QString &name, DataType type, uint dataSize, int count, int offset, int stride) + : QAbstractAttribute(*new QAttributePrivate(), buf, name, type, dataSize, count, offset, stride) { } @@ -90,18 +90,13 @@ QVector<QVector4D> QAttribute::asVector4D() const 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; + switch (dataType()) { + case QAttribute::Float: + stride = sizeof(float) * dataSize(); + break; default: - qCDebug(Render::Io) << Q_FUNC_INFO << "can't convert" << QString::number(type(), 16) << "to QVector3D"; + qCDebug(Render::Io) << Q_FUNC_INFO << "can't convert" << dataType() << "x" << dataSize() << "to QVector3D"; return QVector<QVector4D>(); } @@ -114,28 +109,8 @@ QVector<QVector4D> QAttribute::asVector4D() const 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 - } + for (uint i = 0, m = dataSize(); i < m; ++i) + v[i] = fptr[i]; result[c] = v; rawBuffer += stride; @@ -153,18 +128,13 @@ QVector<QVector3D> QAttribute::asVector3D() const 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; + switch (dataType()) { + case QAttribute::Float: + stride = sizeof(float) * dataSize(); + break; default: - qCDebug(Render::Io) << Q_FUNC_INFO << "can't convert" << QString::number(type(), 16) << "to QVector3D"; + qCDebug(Render::Io) << Q_FUNC_INFO << "can't convert" << dataType() << "x" << dataSize() << "to QVector3D"; return QVector<QVector3D>(); } @@ -177,22 +147,8 @@ QVector<QVector3D> QAttribute::asVector3D() const QVector3D 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: - case GL_FLOAT_VEC4: - v.setX(fptr[0]); - v.setY(fptr[1]); - v.setZ(fptr[2]); - break; - - default: - break; // should never happen, we check types above - } + for (uint i = 0, m = qMin(dataSize(), 3U); i < m; ++i) + v[i] = fptr[i]; result[c] = v; rawBuffer += stride; @@ -209,18 +165,13 @@ QVector<QVector2D> QAttribute::asVector2D() 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; + switch (dataType()) { + case QAttribute::Float: + stride = sizeof(float) * dataSize(); + break; default: - qCDebug(Render::Io) << Q_FUNC_INFO << "can't convert" << QString::number(type(), 16) << "to QVector2D"; + qCDebug(Render::Io) << Q_FUNC_INFO << "can't convert" << dataType() << "x" << dataSize() << "to QVector3D"; return QVector<QVector2D>(); } @@ -233,8 +184,8 @@ QVector<QVector2D> QAttribute::asVector2D() const for (uint c = 0; c < d->m_count; ++c) { QVector2D v; fptr = reinterpret_cast<float*>(rawBuffer); - v.setX(fptr[0]); - v.setY(fptr[1]); + for (uint i = 0, m = qMin(dataSize(), 2U); i < m; ++i) + v[i] = fptr[i]; result[c] = v; rawBuffer += stride; } @@ -254,33 +205,26 @@ void QAttribute::dump(int count) int stride = d->m_byteStride; for (int c=0; c<count; ++c) { - switch (type()) { - case GL_UNSIGNED_SHORT: + switch (dataType()) { + case QAttribute::UnsignedShort: if (stride == 0) stride = sizeof(quint16); usptr = reinterpret_cast<const quint16*>(rawBuffer + stride * c); qCDebug(Render::Io) << c << ":u16:" << usptr[0]; break; - case GL_UNSIGNED_INT: + case QAttribute::UnsignedInt: if (stride == 0) stride = sizeof(quint32); qCDebug(Render::Io) << c << ":u32:" << reinterpret_cast<const quint32*>(rawBuffer + stride * c)[0]; break; - case GL_FLOAT_VEC2: - if (stride == 0) - stride = sizeof(float) * 2; - fptr = reinterpret_cast<const float*>(rawBuffer + stride * c); - qCDebug(Render::Io) << c << ":vec2:"<< fptr[0] << fptr[1]; - break; - - case GL_FLOAT_VEC3: + case QAttribute::Float: if (stride == 0) - stride = sizeof(float) * 3; + stride = sizeof(float) * dataSize(); fptr = reinterpret_cast<const float*>(rawBuffer + stride * c); - qCDebug(Render::Io) << c << ":vec3:" << fptr[0] << fptr[1] << fptr[2]; + qCDebug(Render::Io) << c << QString::fromLatin1(":vec") + QString::number(dataSize()) << fptr[0] << fptr[1]; break; - default: qCDebug(Render::Io) << Q_FUNC_INFO << "unspported type:" << QString::number(type(), 16); + default: qCDebug(Render::Io) << Q_FUNC_INFO << "unspported type:" << dataType(); } } } diff --git a/src/render/io/qattribute.h b/src/render/io/qattribute.h index 39948101c..ec281973f 100644 --- a/src/render/io/qattribute.h +++ b/src/render/io/qattribute.h @@ -54,8 +54,8 @@ class QT3DRENDERERSHARED_EXPORT QAttribute : public QAbstractAttribute public: 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(QBuffer *buf, DataType type, uint dataSize, int count, int offset=0, int stride = 0); + QAttribute(QBuffer *buf, const QString &name, DataType type, uint dataSize, int count, int offset=0, int stride = 0); ~QAttribute(); QVector<QVector4D> asVector4D() const Q_DECL_OVERRIDE; |