diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2016-11-14 17:16:49 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2016-11-23 20:57:02 +0000 |
commit | 5cc6743ad082b1484f6785724f56bd862d54e473 (patch) | |
tree | 07de2b1e5575986a67149b613b586a380edf0623 /src | |
parent | d457074ed24fd0af49dd6ab1aefc25044a1e3a1d (diff) |
Uniform: allow to build UniformValue form QVariantList
This is required when specifying a property var [] to be used as a
QParameter's value. This is used for cases like specify an array of ints or
floats as a uniform.
This fixes a regression since the Uniform handling changes.
Change-Id: I7240d30ebf64d7aa389210fc1c2181994f1d3a87
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/render/backend/uniform.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/render/backend/uniform.cpp b/src/render/backend/uniform.cpp index 24b7b88ef..0369f3f5e 100644 --- a/src/render/backend/uniform.cpp +++ b/src/render/backend/uniform.cpp @@ -48,8 +48,57 @@ namespace { const int qNodeIdTypeId = qMetaTypeId<Qt3DCore::QNodeId>(); +// glUniform*fv/glUniform*iv/glUniform*uiv -> only handles sizeof(float)/sizeof(int) +int byteSizeForMetaType(int type) +{ + switch (type) { + case QMetaType::Bool: + case QMetaType::Int: + case QMetaType::UInt: + case QMetaType::ULongLong: + case QMetaType::LongLong: + case QMetaType::Long: + case QMetaType::ULong: + case QMetaType::Short: + case QMetaType::UShort: + case QMetaType::Char: + case QMetaType::UChar: + return sizeof(int); + + case QMetaType::Float: + case QMetaType::Double: // Assumes conversion to float + return sizeof(float); + + case QMetaType::QPoint: + case QMetaType::QSize: + return 2 * sizeof(int); + + case QMetaType::QRect: + return 4 * sizeof(int); + + case QMetaType::QPointF: + case QMetaType::QSizeF: + case QMetaType::QVector2D: + return 2 * sizeof(float); + + case QMetaType::QVector3D: + return 3 * sizeof(float); + + case QMetaType::QRectF: + case QMetaType::QVector4D: + case QMetaType::QColor: + return 4 * sizeof(float); + + case QMetaType::QMatrix4x4: + return 16 * sizeof(float); + default: + Q_UNREACHABLE(); + return -1; + } } +} // anonymous + UniformValue UniformValue::fromVariant(const QVariant &variant) { // Texture/Buffer case @@ -153,6 +202,28 @@ UniformValue UniformValue::fromVariant(const QVariant &variant) memcpy(v.data<float>(), mat44.constData(), 16 * sizeof(float)); break; } + case QMetaType::QVariantList: { + const QVariantList variants = variant.toList(); + if (variants.size() < 1) + break; + + const int listEntryType = variants.first().userType(); + const int stride = byteSizeForMetaType(listEntryType) / sizeof(float); + // Resize v.m_data + v.m_data.resize(stride * variants.size()); + + int idx = 0; + for (const QVariant &variant : variants) { + Q_ASSERT_X(variant.userType() == listEntryType, + Q_FUNC_INFO, + "Uniform array doesn't contain elements of the same type"); + UniformValue vi = UniformValue::fromVariant(variant); + memcpy(v.data<float>() + idx, vi.data<float>(), stride * sizeof(float)); + idx += stride; + } + break; + } + default: Q_UNREACHABLE(); } |