Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquick3dinstancing.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
5#include <QtQuick3DRuntimeRender/private/qssgrenderinstancetable_p.h>
6#include <QtQuick3DUtils/private/qssgutils_p.h>
7#include <QXmlStreamReader>
8#include <QtQml/QQmlFile>
9
11
123
128
132
138{
141 if (instanceCount && d->m_instanceCountOverride >= 0)
142 *instanceCount = qMin(d->m_instanceCountOverride, *instanceCount);
143 return retval;
144}
145
147{
148 Q_D(const QQuick3DInstancing);
149 return d->m_instanceCountOverride;
150}
151
153{
154 Q_D(const QQuick3DInstancing);
155 return d->m_hasTransparency;
156}
157
159{
160 Q_D(const QQuick3DInstancing);
161 return d->m_depthSortingEnabled;
162}
163
164const QQuick3DInstancing::InstanceTableEntry *QQuick3DInstancing::getInstanceEntry(int index)
165{
166 const QByteArray data = getInstanceBuffer(nullptr);
167 if (index >= int(data.size() / sizeof(InstanceTableEntry)))
168 return nullptr;
169 return reinterpret_cast<const QQuick3DInstancing::InstanceTableEntry*>(data.constData()) + index;
170}
171
176
178{
179 const QVector3D col0{row0[0], row1[0], row2[0]};
180 const QVector3D col1{row0[1], row1[1], row2[1]};
181 const QVector3D col2{row0[2], row1[2], row2[2]};
182 const float scaleX = col0.length();
183 const float scaleY = col1.length();
184 const float scaleZ = col2.length();
185 return QVector3D(scaleX, scaleY, scaleZ);
186}
187
189{
190 const QVector3D col0 = QVector3D(row0[0], row1[0], row2[0]).normalized();
191 const QVector3D col1 = QVector3D(row0[1], row1[1], row2[1]).normalized();
192 const QVector3D col2 = QVector3D(row0[2], row1[2], row2[2]).normalized();
193
194 const float data3x3[3*3] { // row-major order
195 col0[0], col1[0], col2[0],
196 col0[1], col1[1], col2[1],
197 col0[2], col1[2], col2[2],
198 };
199 QMatrix3x3 rot(data3x3);
200 return QQuaternion::fromRotationMatrix(rot).normalized();
201}
202
207
217QVector3D QQuick3DInstancing::instancePosition(int index)
218{
219 auto *entry = getInstanceEntry(index);
220 if (!entry)
221 return {};
222
223 return QVector3D{ entry->row0[3], entry->row1[3], entry->row2[3] };
224}
225
235QVector3D QQuick3DInstancing::instanceScale(int index)
236{
237 auto *entry = getInstanceEntry(index);
238 if (!entry)
239 return {};
240 return entry->getScale();
241}
242
252QQuaternion QQuick3DInstancing::instanceRotation(int index)
253{
254 const auto *entry = getInstanceEntry(index);
255 if (!entry)
256 return {};
257 return entry->getRotation();
258}
259
269QColor QQuick3DInstancing::instanceColor(int index)
270{
271 const auto *entry = getInstanceEntry(index);
272 if (!entry)
273 return {};
274 return entry->getColor();
275}
276
286QVector4D QQuick3DInstancing::instanceCustomData(int index)
287{
288 const auto *entry = getInstanceEntry(index);
289 if (!entry)
290 return {};
291 return entry->instanceData;
292}
293
295{
297 if (d->m_instanceCountOverride == instanceCountOverride)
298 return;
299
300 d->m_instanceCountOverride = instanceCountOverride;
301 d->m_instanceCountOverrideChanged = true;
304}
305
307{
309 if (d->m_hasTransparency == hasTransparency)
310 return;
311
312 d->m_hasTransparency = hasTransparency;
315}
316
318{
320 if (d->m_depthSortingEnabled == enabled)
321 return;
322
323 d->m_depthSortingEnabled = enabled;
326}
327
335{
338 d->m_instanceDataChanged = true;
340}
341
343{
345 if (!node) {
346 markAllDirty();
347 node = new QSSGRenderInstanceTable();
349 d->m_instanceDataChanged = true;
350 }
352 auto effectiveInstanceCount = [d]() {
353 if (d->m_instanceCountOverride >= 0)
354 return qMin(d->m_instanceCount, d->m_instanceCountOverride);
355 return d->m_instanceCount;
356 };
357 auto *instanceTable = static_cast<QSSGRenderInstanceTable *>(node);
358 if (d->m_instanceDataChanged) {
359 QByteArray buffer = getInstanceBuffer(&d->m_instanceCount);
360 instanceTable->setData(buffer, effectiveInstanceCount(), sizeof(InstanceTableEntry));
361 d->m_instanceDataChanged = false;
362 } else if (d->m_instanceCountOverrideChanged) {
363 instanceTable->setInstanceCountOverride(effectiveInstanceCount());
364 }
365 d->m_instanceCountOverrideChanged = false;
366 instanceTable->setHasTransparency(d->m_hasTransparency);
367 instanceTable->setDepthSorting(d->m_depthSortingEnabled);
368 return node;
369}
370
372 const QVector3D &eulerRotation, const QColor &color,
373 const QVector4D &customData)
374{
376
377 xform(0, 0) = scale[0];
378 xform(1, 1) = scale[1];
379 xform(2, 2) = scale[2];
380
381 QQuaternion quaternion = QQuaternion::fromEulerAngles(eulerRotation);
382 xform = QMatrix4x4(quaternion.toRotationMatrix()) * xform;
383
384 xform(0, 3) += position[0];
385 xform(1, 3) += position[1];
386 xform(2, 3) += position[2];
387
388 auto linearColor = QSSGUtils::color::sRGBToLinear(color);
389
390 return {
391 xform.row(0),
392 xform.row(1),
393 xform.row(2),
394 linearColor,
395 customData
396 };
397}
398
423 const QVector3D &eulerRotation, const QColor &color, const QVector4D &customData)
424{
425 return calculate(position, scale, eulerRotation, color, customData);
426}
427
441{
443
444 xform(0, 0) = scale[0];
445 xform(1, 1) = scale[1];
446 xform(2, 2) = scale[2];
447
448 xform = QMatrix4x4(rotation.toRotationMatrix()) * xform;
449
450 xform(0, 3) += position[0];
451 xform(1, 3) += position[1];
452 xform(2, 3) += position[2];
453
454 auto linearColor = QSSGUtils::color::sRGBToLinear(color);
455
456 return {
457 xform.row(0),
458 xform.row(1),
459 xform.row(2),
460 linearColor,
461 customData
462 };
463}
464
508
510
512{
513 if (m_dirty)
514 generateInstanceData();
515 if (instanceCount)
516 *instanceCount = m_instances.size();
517 return m_instanceData;
518}
519
520QQmlListProperty<QQuick3DInstanceListEntry> QQuick3DInstanceList::instances()
521{
522
523 return QQmlListProperty<QQuick3DInstanceListEntry>(this,
524 nullptr,
525 qmlAppendInstanceListEntry,
526 qmlInstanceListEntriesCount,
527 qmlInstanceListEntryAt,
528 qmlClearInstanceListEntries);
529}
530
539{
540 return m_instances.size();
541}
542
543void QQuick3DInstanceList::onInstanceDestroyed(QObject *object)
544{
545 if (m_instances.removeAll(object))
546 handleInstanceChange();
547}
548
549void QQuick3DInstanceList::qmlAppendInstanceListEntry(QQmlListProperty<QQuick3DInstanceListEntry> *list, QQuick3DInstanceListEntry *instance)
550{
551 if (instance == nullptr)
552 return;
553 auto *self = static_cast<QQuick3DInstanceList *>(list->object);
554 self->m_instances.push_back(instance);
555
556 if (instance->parentItem() == nullptr)
557 instance->setParentItem(self);
558 connect(instance, &QQuick3DInstanceListEntry::changed, self, &QQuick3DInstanceList::handleInstanceChange);
559 connect(instance, &QObject::destroyed, self, &QQuick3DInstanceList::onInstanceDestroyed);
560 self->handleInstanceChange();
561}
562
563QQuick3DInstanceListEntry *QQuick3DInstanceList::qmlInstanceListEntryAt(QQmlListProperty<QQuick3DInstanceListEntry> *list, qsizetype index)
564{
565 auto *self = static_cast<QQuick3DInstanceList *>(list->object);
566 return self->m_instances.at(index);
567}
568
569qsizetype QQuick3DInstanceList::qmlInstanceListEntriesCount(QQmlListProperty<QQuick3DInstanceListEntry> *list)
570{
571 auto *self = static_cast<QQuick3DInstanceList *>(list->object);
572 return self->m_instances.size();
573}
574
575void QQuick3DInstanceList::qmlClearInstanceListEntries(QQmlListProperty<QQuick3DInstanceListEntry> *list)
576{
577 auto *self = static_cast<QQuick3DInstanceList *>(list->object);
578 for (auto *instance : self->m_instances) {
579 disconnect(instance, &QObject::destroyed, self, &QQuick3DInstanceList::onInstanceDestroyed);
580 disconnect(instance, &QQuick3DInstanceListEntry::changed, self, &QQuick3DInstanceList::handleInstanceChange);
581 }
582 self->m_instances.clear();
583 self->handleInstanceChange();
584}
585
586void QQuick3DInstanceList::handleInstanceChange()
587{
588 m_dirty = true;
589 markDirty();
591}
592
593void QQuick3DInstanceList::generateInstanceData()
594{
595 m_dirty = false;
596 const int count = m_instances.size();
597
598 qsizetype tableSize = count * sizeof(InstanceTableEntry);
599 m_instanceData.resize(tableSize);
600 auto *array = reinterpret_cast<InstanceTableEntry*>(m_instanceData.data());
601 for (int i = 0; i < count; ++i) {
602 const auto *inst = m_instances.at(i);
603 if (inst->m_useEulerRotation)
604 array[i] = calculateTableEntry(inst->position(), inst->scale(), inst->eulerRotation(), inst->color(), inst->customData());
605 else
606 array[i] = calculateTableEntryFromQuaternion(inst->position(), inst->scale(), inst->rotation(), inst->color(), inst->customData());
607 }
608}
609
628
635{
636 if (m_position == position)
637 return;
638
639 m_position = position;
641 emit changed();
642}
643
650{
651 if (m_scale == scale)
652 return;
653
654 m_scale = scale;
656 emit changed();
657}
658
666{
667 if (m_useEulerRotation && m_eulerRotation == eulerRotation)
668 return;
669 m_eulerRotation = eulerRotation;
670 m_useEulerRotation = true;
672 emit changed();
673}
674
681{
682 if (!m_useEulerRotation && m_rotation == rotation)
683 return;
684
685 m_rotation = rotation;
686 m_useEulerRotation = false;
688 emit changed();
689}
690
697{
698 if (m_color == color)
699 return;
700
701 m_color = color;
703 emit changed();
704}
705
713{
714 if (m_customData == customData)
715 return;
716
717 m_customData = customData;
719 emit changed();
720}
721
797static constexpr quint16 currentMajorVersion = 1;
798
808
809static bool writeInstanceTable(QIODevice *out, const QByteArray &instanceData, int instanceCount)
810{
812
813 header.offset = sizeof(header);
814 header.count = instanceCount;
815
816 if (instanceData.size() != qsizetype(header.stride) * instanceCount) {
817 qWarning() << "inconsistent data";
818 return false;
819 }
820
821 // Ignoring endianness: Assume we always create on little-endian, and then special-case reading if we need to.
822
823 out->write(reinterpret_cast<const char *>(&header), sizeof(header));
824 out->write(instanceData.constData(), instanceData.size());
825 return true;
826}
827
828
830{
831 auto binaryFile = std::make_unique<QFile>(filename);
832 if (!binaryFile->open(QFile::ReadOnly))
833 return false;
834
835 constexpr auto headerSize = sizeof(QQuick3DInstancingBinaryFileHeader);
836 const quint64 fileSize = binaryFile->size();
837 if (fileSize < headerSize) {
838 qWarning() << "data file too small";
839 return false;
840 }
841 const char *data = reinterpret_cast<const char *>(binaryFile->map(0, fileSize));
842 const auto *header = reinterpret_cast<const QQuick3DInstancingBinaryFileHeader *>(data);
843
844 if (header->majorVersion > currentMajorVersion) {
845 qWarning() << "Version" << header->majorVersion << "is too new";
846 return false;
847 }
848
849 if (fileSize != headerSize + header->count * header->stride) {
850 qWarning() << "wrong data size";
851 return false;
852 }
853
854 delete m_dataFile;
855
856 // In order to use fromRawData safely, the file has to stay open so that the mmap stays valid
857 m_dataFile = binaryFile.release();
858
859 m_instanceData = QByteArray::fromRawData(data + header->offset, header->count * header->stride);
860 m_instanceCount = header->count;
861
862 return true;
863}
864
866{
867 QFile f(filename);
868 if (!f.open(QFile::ReadOnly))
869 return false;
870
871 bool valid = false;
872 QXmlStreamReader reader(&f);
873 int instances = 0;
874
875 //### Why is there not a QTextStream constructor that takes a QStringView
876 const auto toVector3D = [](const QStringView &str) {
877 float x, y, z;
878 QTextStream(str.toLocal8Bit()) >> x >> y >> z;
879 return QVector3D { x, y, z };
880 };
881 const auto toVector4D = [](const QStringView &str) {
882 float x, y, z, w;
883 QTextStream(str.toLocal8Bit()) >> x >> y >> z >> w;
884 return QVector4D { x, y, z, w };
885 };
886
887 QByteArray instanceData;
888
889 while (reader.readNextStartElement()) {
890
891 if (reader.name() == QLatin1String("InstanceTable")) {
892 valid = true;
893 while (reader.readNextStartElement()) {
894 if (reader.name() == QLatin1String("Instance")) {
897 QVector3D eulerRotation;
898 QQuaternion quaternion;
899 bool useQuaternion = false;
900 QVector4D custom;
901 QVector3D scale { 1, 1, 1 };
902 for (auto &attr : reader.attributes()) {
903 if (attr.name() == QLatin1String("color")) {
904 color = QColor::fromString(attr.value());
905 } else if (attr.name() == QLatin1String("position")) {
906 position = toVector3D(attr.value());
907 } else if (attr.name() == QLatin1String("eulerRotation")) {
908 eulerRotation = toVector3D(attr.value());
909 } else if (attr.name() == QLatin1String("scale")) {
910 scale = toVector3D(attr.value());
911 } else if (attr.name() == QLatin1String("quaternion")) {
912 quaternion = QQuaternion(toVector4D(attr.value()));
913 useQuaternion = true;
914 } else if (attr.name() == QLatin1String("custom")) {
915 custom = toVector4D(attr.value());
916 }
917 }
918 auto entry = useQuaternion ? calculateTableEntryFromQuaternion(position, scale, quaternion, color, custom)
919 : calculateTableEntry(position, scale, eulerRotation, color, custom);
920 instanceData.append(reinterpret_cast<const char *>(&entry), sizeof(entry));
921 instances++;
922 }
923 reader.skipCurrentElement();
924 }
925 } else {
926 reader.skipCurrentElement();
927 }
928 }
929
930 if (valid) {
931 m_instanceCount = instances;
932 m_instanceData = instanceData;
933 }
934
935 f.close();
936 return valid;
937}
938
940{
941 bool success = writeInstanceTable(out, m_instanceData, m_instanceCount);
942 return success ? m_instanceCount : -1;
943}
944
946{
947 return m_instanceCount;
948}
949
950bool QQuick3DFileInstancing::loadFromFile(const QUrl &source)
951{
952 const QQmlContext *context = qmlContext(this);
953
954 const QString filePath = QQmlFile::urlToLocalFileOrQrc(context ? context->resolvedUrl(source) : source);
955
956 if (filePath.endsWith(QStringLiteral(".bin")))
957 return loadFromBinaryFile(filePath);
958
959 const QString binaryFilePath = filePath + QStringLiteral(".bin");
960
961 int oldCount = m_instanceCount;
962 bool success = loadFromBinaryFile(binaryFilePath) || loadFromXmlFile(filePath);
963 if (m_instanceCount != oldCount)
965
966 return success;
967}
968
970
972{
973 delete m_dataFile;
974}
975
977{
978 return m_source;
979}
980
982{
983 if (m_source == newSource)
984 return;
985 m_source = newSource;
986 m_dirty = true;
987 markDirty();
988
990}
991
993{
994 if (m_dirty) {
995 if (!loadFromFile(m_source)) {
996 qWarning() << Q_FUNC_INFO << "could not load" << m_source;
997 m_instanceData = {};
998 m_instanceCount = 0;
999 }
1000 m_dirty = false;
1001 }
1002
1003 if (instanceCount)
1004 *instanceCount = m_instanceCount;
1005 return m_instanceData;
1006}
1007
1010 "QSSGRenderInstanceTableEntry and QQuick3DInstancing::InstanceTableEntry do not match");
1011
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:611
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:409
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
static QColor fromString(QAnyStringView name) noexcept
Definition qcolor.cpp:980
static QColor fromRgbF(float r, float g, float b, float a=1.0)
Static convenience function that returns a QColor constructed from the RGB color values,...
Definition qcolor.cpp:2427
\inmodule QtCore
Definition qfile.h:93
\inmodule QtCore \reentrant
Definition qiodevice.h:34
qsizetype size() const noexcept
Definition qlist.h:397
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
qsizetype removeAll(const AT &t)
Definition qlist.h:592
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to \l{QFile}.
Definition qqmlfile.cpp:742
The QQuaternion class represents a quaternion consisting of a vector and scalar.
void setSource(const QUrl &newSource)
int writeToBinaryFile(QIODevice *out)
QByteArray getInstanceBuffer(int *instanceCount) override
Implement this function to return the contents of the instance table.
bool loadFromBinaryFile(const QString &filename)
bool loadFromXmlFile(const QString &filename)
QQuick3DFileInstancing(QQuick3DObject *parent=nullptr)
QQuick3DInstanceListEntry(QQuick3DObject *parent=nullptr)
\qmltype InstanceListEntry \inherits Object3D \inqmlmodule QtQuick3D
void setRotation(QQuaternion rotation)
\qmlproperty quaternion QtQuick3D::InstanceListEntry::rotation
void setPosition(QVector3D position)
\qmlproperty vector3d QtQuick3D::InstanceListEntry::position
void setCustomData(QVector4D customData)
\qmlproperty vector4d QtQuick3D::InstanceListEntry::customData
void setScale(QVector3D scale)
\qmlproperty vector3d QtQuick3D::InstanceListEntry::scale
void setEulerRotation(QVector3D eulerRotation)
\qmlproperty vector3d QtQuick3D::InstanceListEntry::eulerRotation
void setColor(QColor color)
\qmlproperty vector3d QtQuick3D::InstanceListEntry::color
QQuick3DInstanceList(QQuick3DObject *parent=nullptr)
\qmltype InstanceList \inherits Instancing \inqmlmodule QtQuick3D
QByteArray getInstanceBuffer(int *instanceCount) override
Implement this function to return the contents of the instance table.
QQmlListProperty< QQuick3DInstanceListEntry > instances
\inmodule QtQuick3D \inherits QQuick3DObject
void depthSortingEnabledChanged()
void hasTransparencyChanged()
static InstanceTableEntry calculateTableEntryFromQuaternion(const QVector3D &position, const QVector3D &scale, const QQuaternion &rotation, const QColor &color, const QVector4D &customData={})
Converts the position scale rotation color and customData to the instance table format expected by th...
void setHasTransparency(bool hasTransparency)
virtual QByteArray getInstanceBuffer(int *instanceCount)=0
Implement this function to return the contents of the instance table.
QSSGRenderGraphObject * updateSpatialNode(QSSGRenderGraphObject *node) override
void markDirty()
Mark that the instance data has changed and must be uploaded again.
void setDepthSortingEnabled(bool enabled)
QByteArray instanceBuffer(int *instanceCount)
void instanceTableChanged()
void instanceCountOverrideChanged()
void setInstanceCountOverride(int instanceCountOverride)
QQuick3DInstancing(QQuick3DObject *parent=nullptr)
bool depthSortingEnabled
\qmlproperty bool Instancing::depthSortingEnabled
bool hasTransparency
\qmlproperty bool Instancing::hasTransparency
static InstanceTableEntry calculateTableEntry(const QVector3D &position, const QVector3D &scale, const QVector3D &eulerRotation, const QColor &color, const QVector4D &customData={})
Converts the position scale eulerRotation color and customData to the instance table format expected ...
\qmltype Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DObject \inherits QtObject
QQuick3DObject * parent
\qmlproperty Object3D QtQuick3D::Object3D::parent This property holds the parent of the Object3D in a...
void setParentItem(QQuick3DObject *parentItem)
virtual QSSGRenderGraphObject * updateSpatialNode(QSSGRenderGraphObject *node)
virtual void markAllDirty()
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
void push_back(QChar c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.h:957
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1226
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5506
QByteArray toLocal8Bit() const &
Definition qstring.h:638
\inmodule QtCore
\inmodule QtCore
Definition qurl.h:94
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
float length() const noexcept
Returns the length of the vector from the origin.
Definition qvectornd.h:690
QVector3D normalized() const noexcept
Returns the normalized unit vector form of this vector.
Definition qvectornd.h:695
The QVector4D class represents a vector or vertex in 4D space.
Definition qvectornd.h:330
QString str
[2]
Combined button and popup list for selecting options.
@ white
Definition qnamespace.h:31
QString self
Definition language.cpp:58
static void * context
#define Q_FUNC_INFO
static int instanceCount
static QString header(const QString &name)
static const qint64 headerSize
static QVector3D toVector3D(const QDoubleVector3D &in)
#define qWarning
Definition qlogging.h:166
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLuint index
[2]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
const void GLsizei GLsizei stride
GLenum GLuint buffer
GLuint color
[2]
GLint y
GLsizei GLsizei GLchar * source
GLuint entry
GLenum array
GLenum GLenum GLenum GLenum GLenum scale
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
static QQuick3DInstancing::InstanceTableEntry calculate(const QVector3D &position, const QVector3D &scale, const QVector3D &eulerRotation, const QColor &color, const QVector4D &customData)
static constexpr quint16 currentMajorVersion
\qmltype FileInstancing \inherits Instancing \inqmlmodule QtQuick3D
static bool writeInstanceTable(QIODevice *out, const QByteArray &instanceData, int instanceCount)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
#define emit
unsigned int quint32
Definition qtypes.h:50
unsigned short quint16
Definition qtypes.h:48
unsigned long long quint64
Definition qtypes.h:61
ptrdiff_t qsizetype
Definition qtypes.h:165
#define enabled
QList< int > list
[14]
QTextStream out(stdout)
[7]
myObject disconnect()
[26]
Definition moc.h:23