4#include <QtCore/qtconfigmacros.h>
7#include <QtQuick/private/qsgcontext_p.h>
8#include <private/qsgadaptationlayer_p.h>
9#include <private/qquickitem_p.h>
10#include <QtQuick/qsgnode.h>
11#include <QtQuick/qsgtexture.h>
13#include <QRandomGenerator>
16#include <private/qquicksprite_p.h>
17#include <private/qquickspriteengine_p.h>
18#include <QSGRendererInterface>
19#include <QtQuick/private/qsgplaintexture_p.h>
20#include <private/qqmlglobal_p.h>
21#include <QtQml/qqmlinfo.h>
22#include <QtCore/QtMath>
30#define UNIFORM_ARRAY_SIZE 64
32class ImageMaterialData
36 : texture(
nullptr), colorTable(
nullptr)
45 QSGTexture *colorTable;
60 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_tabled.vert.qsb"), viewCount);
61 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_tabled.frag.qsb"), viewCount);
64 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
66 QByteArray *buf = renderState.uniformData();
68 const int shaderMatrixCount = newMaterial->viewCount();
69 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
71 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
72 if (renderState.isMatrixDirty()) {
73 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
74 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
78 if (renderState.isOpacityDirty()) {
79 const float opacity = renderState.opacity();
80 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
83 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
85 float entry =
float(state->entry);
86 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
88 float timestamp =
float(state->timestamp);
89 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
91 float *p =
reinterpret_cast<
float *>(buf->data() + 64 * shaderMatrixCount + 16);
93 *p = state->sizeTable[i];
96 p =
reinterpret_cast<
float *>(buf->data() + 64 * shaderMatrixCount + 16 + (
UNIFORM_ARRAY_SIZE * 4 * 4));
98 *p = state->opacityTable[i];
106 QSGMaterial *newMaterial, QSGMaterial *)
override
108 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
110 state->colorTable->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
111 *texture = state->colorTable;
112 }
else if (binding == 1) {
113 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
114 *texture = state->texture;
123 Q_UNUSED(renderMode);
128 ImageMaterialData *
state()
override {
return &m_state; }
131 static QSGMaterialType m_type;
132 ImageMaterialData m_state;
142 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_deformed.vert.qsb"), viewCount);
143 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_deformed.frag.qsb"), viewCount);
146 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
148 QByteArray *buf = renderState.uniformData();
150 const int shaderMatrixCount = newMaterial->viewCount();
151 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
153 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
154 if (renderState.isMatrixDirty()) {
155 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
156 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
160 if (renderState.isOpacityDirty()) {
161 const float opacity = renderState.opacity();
162 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
165 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
167 float entry =
float(state->entry);
168 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
170 float timestamp =
float(state->timestamp);
171 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
177 QSGMaterial *newMaterial, QSGMaterial *)
override
179 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
181 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
182 *texture = state->texture;
191 Q_UNUSED(renderMode);
196 ImageMaterialData *
state()
override {
return &m_state; }
199 static QSGMaterialType m_type;
200 ImageMaterialData m_state;
210 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_sprite.vert.qsb"), viewCount);
211 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_sprite.frag.qsb"), viewCount);
214 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
216 QByteArray *buf = renderState.uniformData();
218 const int shaderMatrixCount = newMaterial->viewCount();
219 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
221 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
222 if (renderState.isMatrixDirty()) {
223 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
224 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
228 if (renderState.isOpacityDirty()) {
229 const float opacity = renderState.opacity();
230 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
233 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
235 float entry =
float(state->entry);
236 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
238 float timestamp =
float(state->timestamp);
239 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
241 float *p =
reinterpret_cast<
float *>(buf->data() + 64 * shaderMatrixCount + 16);
243 *p = state->sizeTable[i];
246 p =
reinterpret_cast<
float *>(buf->data() + 64 * shaderMatrixCount + 16 + (
UNIFORM_ARRAY_SIZE * 4 * 4));
248 *p = state->opacityTable[i];
256 QSGMaterial *newMaterial, QSGMaterial *)
override
258 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
260 state->colorTable->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
261 *texture = state->colorTable;
262 }
else if (binding == 1) {
263 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
264 *texture = state->texture;
273 Q_UNUSED(renderMode);
278 ImageMaterialData *
state()
override {
return &m_state; }
281 static QSGMaterialType m_type;
282 ImageMaterialData m_state;
292 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_coloredpoint.vert.qsb"), viewCount);
293 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_coloredpoint.frag.qsb"), viewCount);
296 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
298 QByteArray *buf = renderState.uniformData();
300 const int shaderMatrixCount = newMaterial->viewCount();
301 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
303 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
304 if (renderState.isMatrixDirty()) {
305 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
306 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
310 if (renderState.isOpacityDirty()) {
311 const float opacity = renderState.opacity();
312 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
315 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
317 float entry =
float(state->entry);
318 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
320 float timestamp =
float(state->timestamp);
321 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
323 float dpr =
float(state->dpr);
324 memcpy(buf->data() + 64 * shaderMatrixCount + 12, &dpr, 4);
330 QSGMaterial *newMaterial, QSGMaterial *)
override
332 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
334 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
335 *texture = state->texture;
344 Q_UNUSED(renderMode);
349 ImageMaterialData *
state()
override {
return &m_state; }
352 static QSGMaterialType m_type;
353 ImageMaterialData m_state;
364 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_colored.vert.qsb"), viewCount);
365 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_colored.frag.qsb"), viewCount);
373 Q_UNUSED(renderMode);
378 ImageMaterialData *
state()
override {
return &m_state; }
381 static QSGMaterialType m_type;
382 ImageMaterialData m_state;
392 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_simplepoint.vert.qsb"), viewCount);
393 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_simplepoint.frag.qsb"), viewCount);
396 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
398 QByteArray *buf = renderState.uniformData();
400 const int shaderMatrixCount = newMaterial->viewCount();
401 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
403 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
404 if (renderState.isMatrixDirty()) {
405 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
406 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
410 if (renderState.isOpacityDirty()) {
411 const float opacity = renderState.opacity();
412 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
415 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
417 float entry =
float(state->entry);
418 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
420 float timestamp =
float(state->timestamp);
421 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
423 float dpr =
float(state->dpr);
424 memcpy(buf->data() + 64 * shaderMatrixCount + 12, &dpr, 4);
430 QSGMaterial *newMaterial, QSGMaterial *)
override
432 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
434 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
435 *texture = state->texture;
444 Q_UNUSED(renderMode);
449 ImageMaterialData *
state()
override {
return &m_state; }
452 static QSGMaterialType m_type;
453 ImageMaterialData m_state;
461 for (
int i=0; i<size; i++)
465 QImage scaled = img.scaled(size,1);
466 for (
int i=0; i<size; i++)
467 array[i] = qAlpha(scaled.pixel(i,0))/255.0;
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
526
527
528
529
530
531
532
533
534
536
537
538
539
540
541
542
543
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
579
580
581
582
583
584
586
587
588
589
590
591
592
593
594
595
596
597
599
600
601
602
603
604
605
607
608
609
610
611
612
613
615
616
617
618
619
620
621
623
624
625
626
627
628
629
630
631
632
633
635
636
637
638
639
640
641
643
644
645
646
647
648
650
651
652
653
654
655
657
658
659
660
662
663
664
665
666
667
669
670
671
672
673
674
675
676
678
679
680
681
682
683
685
686
687
688
689
690
692
693
694
695
696
697
698
699
700
701
702
703
704
706
707
708
709
710
711
712
715
716
717
718
721QQuickImageParticle::QQuickImageParticle(QQuickItem* parent)
722 : QQuickParticlePainter(parent)
723 , m_color_variation(0.0)
724 , m_outgoingNode(
nullptr)
725 , m_material(
nullptr)
726 , m_alphaVariation(0.0)
728 , m_redVariation(0.0)
729 , m_greenVariation(0.0)
730 , m_blueVariation(0.0)
732 , m_rotationVariation(0)
733 , m_rotationVelocity(0)
734 , m_rotationVelocityVariation(0)
735 , m_autoRotation(
false)
738 , m_spriteEngine(
nullptr)
739 , m_spritesInterpolate(
true)
740 , m_explicitColor(
false)
741 , m_explicitRotation(
false)
742 , m_explicitDeformation(
false)
743 , m_explicitAnimation(
false)
744 , m_bypassOptimizations(
false)
746 , m_targetPerfLevel(Unknown)
748 , m_entryEffect(Fade)
749 , m_startedImageLoading(0)
751 , m_apiChecked(
false)
753 , m_previousActive(
false)
755 setFlag(ItemHasContents);
758QQuickImageParticle::~QQuickImageParticle()
763QQmlListProperty<QQuickSprite> QQuickImageParticle::sprites()
765 return QQmlListProperty<QQuickSprite>(
this, &m_sprites,
766 spriteAppend, spriteCount, spriteAt,
767 spriteClear, spriteReplace, spriteRemoveLast);
770void QQuickImageParticle::sceneGraphInvalidated()
773 m_material =
nullptr;
774 delete m_outgoingNode;
775 m_outgoingNode =
nullptr;
776 m_apiChecked =
false;
779void QQuickImageParticle::setImage(
const QUrl &image)
781 if (image.isEmpty()){
790 m_image.reset(
new ImageData);
791 if (image == m_image->source)
793 m_image->source = image;
799void QQuickImageParticle::setColortable(
const QUrl &table)
801 if (table.isEmpty()){
803 m_colorTable.reset();
804 emit colortableChanged();
810 m_colorTable.reset(
new ImageData);
811 if (table == m_colorTable->source)
813 m_colorTable->source = table;
814 emit colortableChanged();
818void QQuickImageParticle::setSizetable(
const QUrl &table)
820 if (table.isEmpty()){
823 emit sizetableChanged();
829 m_sizeTable.reset(
new ImageData);
830 if (table == m_sizeTable->source)
832 m_sizeTable->source = table;
833 emit sizetableChanged();
837void QQuickImageParticle::setOpacitytable(
const QUrl &table)
839 if (table.isEmpty()){
840 if (m_opacityTable) {
841 m_opacityTable.reset();
842 emit opacitytableChanged();
848 m_opacityTable.reset(
new ImageData);
849 if (table == m_opacityTable->source)
851 m_opacityTable->source = table;
852 emit opacitytableChanged();
856void QQuickImageParticle::setColor(
const QColor &color)
858 if (color == m_color)
862 m_explicitColor =
true;
863 checkPerfLevel(ColoredPoint);
866void QQuickImageParticle::setColorVariation(qreal var)
868 if (var == m_color_variation)
870 m_color_variation = var;
871 emit colorVariationChanged();
872 m_explicitColor =
true;
873 checkPerfLevel(ColoredPoint);
876void QQuickImageParticle::setAlphaVariation(qreal arg)
878 if (m_alphaVariation != arg) {
879 m_alphaVariation = arg;
880 emit alphaVariationChanged(arg);
882 m_explicitColor =
true;
883 checkPerfLevel(ColoredPoint);
886void QQuickImageParticle::setAlpha(qreal arg)
888 if (m_alpha != arg) {
890 emit alphaChanged(arg);
892 m_explicitColor =
true;
893 checkPerfLevel(ColoredPoint);
896void QQuickImageParticle::setRedVariation(qreal arg)
898 if (m_redVariation != arg) {
899 m_redVariation = arg;
900 emit redVariationChanged(arg);
902 m_explicitColor =
true;
903 checkPerfLevel(ColoredPoint);
906void QQuickImageParticle::setGreenVariation(qreal arg)
908 if (m_greenVariation != arg) {
909 m_greenVariation = arg;
910 emit greenVariationChanged(arg);
912 m_explicitColor =
true;
913 checkPerfLevel(ColoredPoint);
916void QQuickImageParticle::setBlueVariation(qreal arg)
918 if (m_blueVariation != arg) {
919 m_blueVariation = arg;
920 emit blueVariationChanged(arg);
922 m_explicitColor =
true;
923 checkPerfLevel(ColoredPoint);
926void QQuickImageParticle::setRotation(qreal arg)
928 if (m_rotation != arg) {
930 emit rotationChanged(arg);
932 m_explicitRotation =
true;
933 checkPerfLevel(Deformable);
936void QQuickImageParticle::setRotationVariation(qreal arg)
938 if (m_rotationVariation != arg) {
939 m_rotationVariation = arg;
940 emit rotationVariationChanged(arg);
942 m_explicitRotation =
true;
943 checkPerfLevel(Deformable);
946void QQuickImageParticle::setRotationVelocity(qreal arg)
948 if (m_rotationVelocity != arg) {
949 m_rotationVelocity = arg;
950 emit rotationVelocityChanged(arg);
952 m_explicitRotation =
true;
953 checkPerfLevel(Deformable);
956void QQuickImageParticle::setRotationVelocityVariation(qreal arg)
958 if (m_rotationVelocityVariation != arg) {
959 m_rotationVelocityVariation = arg;
960 emit rotationVelocityVariationChanged(arg);
962 m_explicitRotation =
true;
963 checkPerfLevel(Deformable);
966void QQuickImageParticle::setAutoRotation(
bool arg)
968 if (m_autoRotation != arg) {
969 m_autoRotation = arg;
970 emit autoRotationChanged(arg);
972 m_explicitRotation =
true;
973 checkPerfLevel(Deformable);
976void QQuickImageParticle::setXVector(QQuickDirection* arg)
978 if (m_xVector != arg) {
980 emit xVectorChanged(arg);
982 m_explicitDeformation =
true;
983 checkPerfLevel(Deformable);
986void QQuickImageParticle::setYVector(QQuickDirection* arg)
988 if (m_yVector != arg) {
990 emit yVectorChanged(arg);
992 m_explicitDeformation =
true;
993 checkPerfLevel(Deformable);
996void QQuickImageParticle::setSpritesInterpolate(
bool arg)
998 if (m_spritesInterpolate != arg) {
999 m_spritesInterpolate = arg;
1000 emit spritesInterpolateChanged(arg);
1004void QQuickImageParticle::setBypassOptimizations(
bool arg)
1006 if (m_bypassOptimizations != arg) {
1007 m_bypassOptimizations = arg;
1008 emit bypassOptimizationsChanged(arg);
1014void QQuickImageParticle::setEntryEffect(EntryEffect arg)
1016 if (m_entryEffect != arg) {
1017 m_entryEffect = arg;
1019 getState(m_material)->entry = (qreal) m_entryEffect;
1020 emit entryEffectChanged(arg);
1024void QQuickImageParticle::resetColor()
1026 m_explicitColor =
false;
1027 for (
auto groupId : groupIds()) {
1028 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
1029 if (d->colorOwner ==
this) {
1030 d->colorOwner =
nullptr;
1035 m_color_variation = 0.0f;
1036 m_redVariation = 0.0f;
1037 m_blueVariation = 0.0f;
1038 m_greenVariation = 0.0f;
1040 m_alphaVariation = 0.0f;
1043void QQuickImageParticle::resetRotation()
1045 m_explicitRotation =
false;
1046 for (
auto groupId : groupIds()) {
1047 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
1048 if (d->rotationOwner ==
this) {
1049 d->rotationOwner =
nullptr;
1054 m_rotationVariation = 0;
1055 m_rotationVelocity = 0;
1056 m_rotationVelocityVariation = 0;
1057 m_autoRotation =
false;
1060void QQuickImageParticle::resetDeformation()
1062 m_explicitDeformation =
false;
1063 for (
auto groupId : groupIds()) {
1064 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
1065 if (d->deformationOwner ==
this) {
1066 d->deformationOwner =
nullptr;
1074 m_xVector =
nullptr;
1075 m_yVector =
nullptr;
1078void QQuickImageParticle::reset()
1080 QQuickParticlePainter::reset();
1081 m_pleaseReset =
true;
1086void QQuickImageParticle::invalidateSceneGraph()
1091void QQuickImageParticle::createEngine()
1094 delete m_spriteEngine;
1095 if (m_sprites.size()) {
1096 m_spriteEngine =
new QQuickSpriteEngine(m_sprites,
this);
1097 connect(m_spriteEngine, &QQuickStochasticEngine::stateChanged,
1098 this, &QQuickImageParticle::spriteAdvance, Qt::DirectConnection);
1099 m_explicitAnimation =
true;
1101 m_spriteEngine =
nullptr;
1102 m_explicitAnimation =
false;
1108 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType,
true),
1109 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1110 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType)
1116 ( 2 + 4 + 4 ) *
sizeof(
float),
1117 SimplePointParticle_Attributes
1121 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType,
true),
1122 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1123 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1124 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1130 ( 2 + 4 + 4 ) *
sizeof(
float) + 4 *
sizeof(uchar),
1131 ColoredPointParticle_Attributes
1135 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType,
true),
1136 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1137 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1138 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1139 QSGGeometry::Attribute::create(4, 4, QSGGeometry::UnsignedByteType),
1145 ( 2 + 4 + 4 ) *
sizeof(
float) + (4 + 4) *
sizeof(uchar),
1146 ColoredParticle_Attributes
1150 QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType),
1151 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1152 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1153 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1154 QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType),
1155 QSGGeometry::Attribute::create(5, 4, QSGGeometry::UnsignedByteType),
1161 (4 + 4 + 4 + 4) *
sizeof(
float) + (4 + 4) *
sizeof(uchar),
1162 DeformableParticle_Attributes
1166 QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType),
1167 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1168 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1169 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1170 QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType),
1171 QSGGeometry::Attribute::create(5, 4, QSGGeometry::UnsignedByteType),
1172 QSGGeometry::Attribute::create(6, 3, QSGGeometry::FloatType),
1173 QSGGeometry::Attribute::create(7, 3, QSGGeometry::FloatType)
1179 (4 + 4 + 4 + 4 + 3 + 3) *
sizeof(
float) + (4 + 4) *
sizeof(uchar),
1180 SpriteParticle_Attributes
1183void QQuickImageParticle::clearShadows()
1185 foreach (
const QList<QQuickParticleData*> data, m_shadowData)
1187 m_shadowData.clear();
1191QQuickParticleData* QQuickImageParticle::getShadowDatum(QQuickParticleData* datum)
1194 if (datum->systemIndex == -1)
1196 if (!m_shadowData.contains(datum->groupId)) {
1197 QQuickParticleGroupData* gd = m_system->groupData[datum->groupId];
1198 QList<QQuickParticleData*> data;
1199 const int gdSize = gd->size();
1200 data.reserve(gdSize);
1201 for (
int i = 0; i < gdSize; i++) {
1202 QQuickParticleData* datum =
new QQuickParticleData;
1203 *datum = *(gd->data[i]);
1206 m_shadowData.insert(datum->groupId, data);
1210 return m_shadowData[datum->groupId][datum->index];
1213void QQuickImageParticle::checkPerfLevel(PerformanceLevel level)
1215 if (m_targetPerfLevel < level) {
1216 m_targetPerfLevel = level;
1221bool QQuickImageParticle::loadingSomething()
1223 return (m_image && m_image->pix.isLoading())
1224 || (m_colorTable && m_colorTable->pix.isLoading())
1225 || (m_sizeTable && m_sizeTable->pix.isLoading())
1226 || (m_opacityTable && m_opacityTable->pix.isLoading())
1227 || (m_spriteEngine && m_spriteEngine->isLoading());
1230void QQuickImageParticle::mainThreadFetchImageData()
1232 const QQmlContext *context =
nullptr;
1233 QQmlEngine *engine =
nullptr;
1234 const auto loadPix = [&](ImageData *image) {
1236 context = qmlContext(
this);
1237 engine = context->engine();
1239 image->pix.load(engine, context->resolvedUrl(image->source));
1244 m_image->pix.clear(
this);
1245 loadPix(m_image.get());
1249 m_spriteEngine->startAssemblingImage();
1252 loadPix(m_colorTable.get());
1255 loadPix(m_sizeTable.get());
1258 loadPix(m_opacityTable.get());
1260 m_startedImageLoading = 2;
1263void QQuickImageParticle::buildParticleNodes(QSGNode** passThrough)
1267 if (*passThrough || loadingSomething())
1270 if (m_startedImageLoading == 0) {
1271 m_startedImageLoading = 1;
1273 QQuickImageParticle::staticMetaObject.invokeMethod(
this,
"mainThreadFetchImageData", Qt::QueuedConnection);
1274 }
else if (m_startedImageLoading == 2) {
1275 finishBuildParticleNodes(passThrough);
1281void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
1286 if (m_count * 4 > 0xffff) {
1288 qmlInfo(
this) <<
"ImageParticle: Too many particles - maximum 16383 per ImageParticle";
1295 m_debugMode = m_system->m_debugMode;
1297 if (m_sprites.size() || m_bypassOptimizations) {
1298 perfLevel = Sprites;
1299 }
else if (m_colorTable || m_sizeTable || m_opacityTable) {
1301 }
else if (m_autoRotation || m_rotation || m_rotationVariation
1302 || m_rotationVelocity || m_rotationVelocityVariation
1303 || m_xVector || m_yVector) {
1304 perfLevel = Deformable;
1305 }
else if (m_alphaVariation || m_alpha != 1.0 || m_color.isValid() || m_color_variation
1306 || m_redVariation || m_blueVariation || m_greenVariation) {
1307 perfLevel = ColoredPoint;
1309 perfLevel = SimplePoint;
1312 for (
auto groupId : groupIds()) {
1314 for (QQuickParticlePainter* p : std::as_const(m_system->groupData[groupId]->painters)) {
1315 QQuickImageParticle* other = qobject_cast<QQuickImageParticle*>(p);
1317 if (other->perfLevel > perfLevel) {
1318 if (other->perfLevel >= Tabled){
1319 if (perfLevel < Deformable)
1320 perfLevel = Deformable;
1322 perfLevel = other->perfLevel;
1324 }
else if (other->perfLevel < perfLevel) {
1334 if (perfLevel < Colored && !m_rhi->isFeatureSupported(QRhi::VertexShaderPointSize))
1335 perfLevel = Colored;
1337 if (perfLevel >= ColoredPoint && !m_color.isValid())
1338 m_color = QColor(Qt::white);
1340 m_targetPerfLevel = perfLevel;
1344 m_material =
nullptr;
1349 QImage opacitytable;
1351 bool imageLoaded =
false;
1352 switch (perfLevel) {
1355 if (!m_spriteEngine) {
1356 qWarning() <<
"ImageParticle: No sprite engine...";
1360 image = m_spriteEngine->assembledImage();
1365 m_material =
new SpriteMaterial;
1366 ImageMaterialData *state = getState(m_material);
1368 state->texture = QSGPlainTexture::fromImage(image);
1369 state->animSheetSize = QSizeF(image.size() / image.devicePixelRatio());
1371 m_spriteEngine->setCount(m_count);
1377 m_material =
new TabledMaterial;
1380 if (m_colorTable->pix.isReady())
1381 colortable = m_colorTable->pix.image();
1383 qmlWarning(
this) <<
"Error loading color table: " << m_colorTable->pix.error();
1387 if (m_sizeTable->pix.isReady())
1388 sizetable = m_sizeTable->pix.image();
1390 qmlWarning(
this) <<
"Error loading size table: " << m_sizeTable->pix.error();
1393 if (m_opacityTable) {
1394 if (m_opacityTable->pix.isReady())
1395 opacitytable = m_opacityTable->pix.image();
1397 qmlWarning(
this) <<
"Error loading opacity table: " << m_opacityTable->pix.error();
1400 if (colortable.isNull()){
1401 colortable = QImage(1,1,QImage::Format_ARGB32_Premultiplied);
1402 colortable.fill(Qt::white);
1404 ImageMaterialData *state = getState(m_material);
1405 state->colorTable = QSGPlainTexture::fromImage(colortable);
1413 m_material =
new DeformableMaterial;
1419 m_material =
new ColoredMaterial;
1425 m_material =
new ColoredPointMaterial;
1431 m_material =
new SimplePointMaterial;
1432 ImageMaterialData *state = getState(m_material);
1434 if (!m_image || !m_image->pix.isReady()) {
1436 qmlWarning(
this) << m_image->pix.error();
1442 state->texture = QSGPlainTexture::fromImage(m_image->pix.image());
1444 state->texture->setFiltering(QSGTexture::Linear);
1445 state->entry = (qreal) m_entryEffect;
1448 m_material->setFlag(QSGMaterial::Blending | QSGMaterial::RequiresFullMatrix);
1453 for (
auto groupId : groupIds()) {
1454 int count = m_system->groupData[groupId]->size();
1455 QSGGeometryNode* node =
new QSGGeometryNode();
1456 node->setMaterial(m_material);
1457 node->markDirty(QSGNode::DirtyMaterial);
1459 m_nodes.insert(groupId, node);
1460 m_idxStarts.insert(groupId, m_lastIdxStart);
1461 m_startsIdx.append(std::make_pair(m_lastIdxStart, groupId));
1462 m_lastIdxStart += count;
1465 int vCount = count * 4;
1466 int iCount = count * 6;
1469 if (perfLevel == Sprites)
1470 g =
new QSGGeometry(SpriteParticle_AttributeSet, vCount, iCount);
1471 else if (perfLevel == Tabled)
1472 g =
new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount);
1473 else if (perfLevel == Deformable)
1474 g =
new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount);
1475 else if (perfLevel == Colored)
1476 g =
new QSGGeometry(ColoredParticle_AttributeSet, vCount, iCount);
1477 else if (perfLevel == ColoredPoint)
1478 g =
new QSGGeometry(ColoredPointParticle_AttributeSet, count, 0);
1480 g =
new QSGGeometry(SimplePointParticle_AttributeSet, count, 0);
1482 node->setFlag(QSGNode::OwnsGeometry);
1483 node->setGeometry(g);
1484 if (perfLevel <= ColoredPoint){
1485 g->setDrawingMode(QSGGeometry::DrawPoints);
1487 qDebug(
"Using point sprites");
1489 g->setDrawingMode(QSGGeometry::DrawTriangles);
1492 for (
int p=0; p < count; ++p)
1495 if (perfLevel == Sprites)
1496 initTexCoords<SpriteVertex>((SpriteVertex*)g->vertexData(), vCount);
1497 else if (perfLevel == Tabled)
1498 initTexCoords<DeformableVertex>((DeformableVertex*)g->vertexData(), vCount);
1499 else if (perfLevel == Deformable)
1500 initTexCoords<DeformableVertex>((DeformableVertex*)g->vertexData(), vCount);
1501 else if (perfLevel == Colored)
1502 initTexCoords<ColoredVertex>((ColoredVertex*)g->vertexData(), vCount);
1504 if (perfLevel > ColoredPoint){
1505 quint16 *indices = g->indexDataAsUShort();
1506 for (
int i=0; i < count; ++i) {
1519 if (perfLevel == Sprites)
1522 foreach (QSGGeometryNode* node, m_nodes){
1523 if (node == *(m_nodes.begin()))
1524 node->setFlag(QSGGeometryNode::OwnsMaterial);
1526 (*(m_nodes.begin()))->appendChildNode(node);
1529 *node = *(m_nodes.begin());
1533QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
1535 if (!m_apiChecked || m_windowChanged) {
1536 m_apiChecked =
true;
1537 m_windowChanged =
false;
1539 QSGRenderContext *rc = QQuickItemPrivate::get(
this)->sceneGraphRenderContext();
1540 QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
1544 QSGRendererInterface::GraphicsApi api = rif->graphicsApi();
1545 const bool isRhi = QSGRendererInterface::isApiRhiBased(api);
1547 if (!node && !isRhi)
1551 m_rhi =
static_cast<QRhi *>(rif->getResource(m_window, QSGRendererInterface::RhiResource));
1555 if (isRhi && !m_rhi) {
1556 qWarning(
"Failed to query QRhi, particles disabled");
1560 m_dpr = m_window ? m_window->devicePixelRatio() : 1.0;
1567 delete m_outgoingNode;
1568 m_outgoingNode = node;
1573 m_idxStarts.clear();
1574 m_startsIdx.clear();
1577 m_material =
nullptr;
1579 m_pleaseReset =
false;
1580 m_startedImageLoading = 0;
1581 }
else if (!m_material) {
1586 if (m_system && m_system->isRunning() && !m_system->isPaused()){
1587 bool dirty = prepareNextFrame(&node);
1591 foreach (QSGGeometryNode* n, m_nodes)
1592 n->markDirty(QSGNode::DirtyGeometry);
1594 }
else if (m_startedImageLoading < 2) {
1600 node = m_outgoingNode;
1601 m_outgoingNode =
nullptr;
1607bool QQuickImageParticle::prepareNextFrame(QSGNode **node)
1609 if (*node ==
nullptr){
1610 buildParticleNodes(node);
1612 qDebug() <<
"QQuickImageParticle Feature level: " << perfLevel;
1613 qDebug() <<
"QQuickImageParticle Nodes: ";
1615 for (
auto it = m_nodes.keyBegin(), end = m_nodes.keyEnd(); it != end; ++it) {
1616 qDebug() <<
"Group " << *it <<
" (" << m_system->groupData[*it]->size()
1618 count += m_system->groupData[*it]->size();
1620 qDebug() <<
"Total count: " << count;
1622 if (*node ==
nullptr)
1625 qint64 timeStamp = m_system->systemSync(
this);
1627 qreal time = timeStamp / 1000.;
1633 m_spriteEngine->updateSprites(timeStamp);
1634 spritesUpdate(time);
1642 getState(m_material)->timestamp = time;
1646 bool active =
false;
1647 for (
auto groupId : groupIds()) {
1648 if (m_system->groupData[groupId]->isActive()) {
1654 const bool dirty = active || m_previousActive;
1656 foreach (QSGGeometryNode* node, m_nodes)
1657 node->markDirty(QSGNode::DirtyMaterial);
1660 m_previousActive = active;
1664void QQuickImageParticle::spritesUpdate(qreal time)
1666 ImageMaterialData *state = getState(m_material);
1668 for (
auto groupId : groupIds()) {
1669 for (QQuickParticleData* mainDatum : std::as_const(m_system->groupData[groupId]->data)) {
1670 QSGGeometryNode *node = m_nodes[groupId];
1675 QQuickParticleData* datum = (mainDatum->animationOwner ==
this ? mainDatum : getShadowDatum(mainDatum));
1677 for (
int i = 0; i<m_startsIdx.size(); i++) {
1678 if (m_startsIdx[i].second == groupId){
1679 spriteIdx = m_startsIdx[i].first + datum->index;
1687 if (datum->frameDuration > 0) {
1688 qreal frame = (time - datum->animT)/(datum->frameDuration / 1000.0);
1689 frame = qBound((qreal)0.0, frame, (qreal)((qreal)datum->frameCount - 1.0));
1690 if (m_spritesInterpolate)
1691 progress = std::modf(frame,&frameAt);
1693 std::modf(frame,&frameAt);
1696 if (datum->frameAt >= datum->frameCount){
1698 m_spriteEngine->advance(spriteIdx);
1700 frameAt = datum->frameAt;
1702 if (m_spriteEngine->sprite(spriteIdx)->reverse())
1703 frameAt = (datum->frameCount - 1) - frameAt;
1704 QSizeF sheetSize = state->animSheetSize;
1705 qreal y = datum->animY / sheetSize.height();
1706 qreal w = datum->animWidth / sheetSize.width();
1707 qreal h = datum->animHeight / sheetSize.height();
1708 qreal x1 = datum->animX / sheetSize.width();
1711 if (frameAt < (datum->frameCount-1))
1714 SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData();
1715 spriteVertices += datum->index*4;
1716 for (
int i=0; i<4; i++) {
1717 spriteVertices[i].animX1 = x1;
1718 spriteVertices[i].animY1 = y;
1719 spriteVertices[i].animX2 = x2;
1720 spriteVertices[i].animW = w;
1721 spriteVertices[i].animH = h;
1722 spriteVertices[i].animProgress = progress;
1728void QQuickImageParticle::spriteAdvance(
int spriteIdx)
1730 if (!m_startsIdx.size())
1735 for (i = 0; i<m_startsIdx.size(); i++) {
1736 if (spriteIdx < m_startsIdx[i].first) {
1737 gIdx = m_startsIdx[i-1].second;
1742 gIdx = m_startsIdx[i-1].second;
1743 int pIdx = spriteIdx - m_startsIdx[i-1].first;
1745 QQuickParticleData* mainDatum = m_system->groupData[gIdx]->data[pIdx];
1746 QQuickParticleData* datum = (mainDatum->animationOwner ==
this ? mainDatum : getShadowDatum(mainDatum));
1748 datum->animIdx = m_spriteEngine->spriteState(spriteIdx);
1749 datum->animT = m_spriteEngine->spriteStart(spriteIdx)/1000.0;
1750 datum->frameCount = m_spriteEngine->spriteFrames(spriteIdx);
1751 datum->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / datum->frameCount;
1752 datum->animX = m_spriteEngine->spriteX(spriteIdx);
1753 datum->animY = m_spriteEngine->spriteY(spriteIdx);
1754 datum->animWidth = m_spriteEngine->spriteWidth(spriteIdx);
1755 datum->animHeight = m_spriteEngine->spriteHeight(spriteIdx);
1758void QQuickImageParticle::initialize(
int gIdx,
int pIdx)
1761 QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
1762 qreal redVariation = m_color_variation + m_redVariation;
1763 qreal greenVariation = m_color_variation + m_greenVariation;
1764 qreal blueVariation = m_color_variation + m_blueVariation;
1766 if (m_spriteEngine) {
1767 spriteIdx = m_idxStarts[gIdx] + datum->index;
1768 if (spriteIdx >= m_spriteEngine->count())
1769 m_spriteEngine->setCount(spriteIdx+1);
1773 float rotationVelocity;
1778 if (m_explicitAnimation && m_spriteEngine){
1779 if (!datum->animationOwner)
1780 datum->animationOwner =
this;
1781 QQuickParticleData* writeTo = (datum->animationOwner ==
this ? datum : getShadowDatum(datum));
1782 writeTo->animT = writeTo->t;
1784 if (m_spriteEngine){
1785 m_spriteEngine->start(spriteIdx);
1786 writeTo->frameCount = m_spriteEngine->spriteFrames(spriteIdx);
1787 writeTo->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / writeTo->frameCount;
1788 writeTo->animIdx = 0;
1789 writeTo->frameAt = -1;
1790 writeTo->animX = m_spriteEngine->spriteX(spriteIdx);
1791 writeTo->animY = m_spriteEngine->spriteY(spriteIdx);
1792 writeTo->animWidth = m_spriteEngine->spriteWidth(spriteIdx);
1793 writeTo->animHeight = m_spriteEngine->spriteHeight(spriteIdx);
1796 ImageMaterialData *state = getState(m_material);
1797 QQuickParticleData* writeTo = getShadowDatum(datum);
1798 writeTo->animT = datum->t;
1799 writeTo->frameCount = 1;
1800 writeTo->frameDuration = 60000000.0;
1801 writeTo->frameAt = -1;
1802 writeTo->animIdx = 0;
1804 writeTo->animX = writeTo->animY = 0;
1805 writeTo->animWidth = state->animSheetSize.width();
1806 writeTo->animHeight = state->animSheetSize.height();
1812 if (m_explicitDeformation){
1813 if (!datum->deformationOwner)
1814 datum->deformationOwner =
this;
1816 const QPointF &ret = m_xVector->sample(QPointF(datum->x, datum->y));
1817 if (datum->deformationOwner ==
this) {
1818 datum->xx = ret.x();
1819 datum->xy = ret.y();
1821 QQuickParticleData* shadow = getShadowDatum(datum);
1822 shadow->xx = ret.x();
1823 shadow->xy = ret.y();
1827 const QPointF &ret = m_yVector->sample(QPointF(datum->x, datum->y));
1828 if (datum->deformationOwner ==
this) {
1829 datum->yx = ret.x();
1830 datum->yy = ret.y();
1832 QQuickParticleData* shadow = getShadowDatum(datum);
1833 shadow->yx = ret.x();
1834 shadow->yy = ret.y();
1839 if (m_explicitRotation){
1840 if (!datum->rotationOwner)
1841 datum->rotationOwner =
this;
1842 rotation = qDegreesToRadians(
1843 m_rotation + (m_rotationVariation
1844 - 2 * QRandomGenerator::global()->bounded(m_rotationVariation)));
1845 rotationVelocity = qDegreesToRadians(
1847 + (m_rotationVelocityVariation
1848 - 2 * QRandomGenerator::global()->bounded(m_rotationVelocityVariation)));
1849 autoRotate = m_autoRotation ? 1 : 0;
1850 if (datum->rotationOwner ==
this) {
1851 datum->rotation = rotation;
1852 datum->rotationVelocity = rotationVelocity;
1853 datum->autoRotate = autoRotate;
1855 QQuickParticleData* shadow = getShadowDatum(datum);
1856 shadow->rotation = rotation;
1857 shadow->rotationVelocity = rotationVelocity;
1858 shadow->autoRotate = autoRotate;
1867 if (m_explicitColor) {
1868 if (!datum->colorOwner)
1869 datum->colorOwner =
this;
1870 const auto rgbColor = m_color.toRgb();
1871 color.r = rgbColor.red() * (1 - redVariation) + QRandomGenerator::global()->bounded(256) * redVariation;
1872 color.g = rgbColor.green() * (1 - greenVariation) + QRandomGenerator::global()->bounded(256) * greenVariation;
1873 color.b = rgbColor.blue() * (1 - blueVariation) + QRandomGenerator::global()->bounded(256) * blueVariation;
1874 color.a = m_alpha * rgbColor.alpha() * (1 - m_alphaVariation) + QRandomGenerator::global()->bounded(256) * m_alphaVariation;
1875 if (datum->colorOwner ==
this)
1876 datum->color = color;
1878 getShadowDatum(datum)->color = color;
1886void QQuickImageParticle::commit(
int gIdx,
int pIdx)
1890 QSGGeometryNode *node = m_nodes[gIdx];
1893 QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
1894 SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData();
1895 DeformableVertex *deformableVertices = (DeformableVertex *) node->geometry()->vertexData();
1896 ColoredVertex *coloredVertices = (ColoredVertex *) node->geometry()->vertexData();
1897 ColoredPointVertex *coloredPointVertices = (ColoredPointVertex *) node->geometry()->vertexData();
1898 SimplePointVertex *simplePointVertices = (SimplePointVertex *) node->geometry()->vertexData();
1901 spriteVertices += pIdx*4;
1902 for (
int i=0; i<4; i++){
1903 spriteVertices[i].x = datum->x - m_systemOffset.x();
1904 spriteVertices[i].y = datum->y - m_systemOffset.y();
1905 spriteVertices[i].t = datum->t;
1906 spriteVertices[i].lifeSpan = datum->lifeSpan;
1907 spriteVertices[i].size = datum->size;
1908 spriteVertices[i].endSize = datum->endSize;
1909 spriteVertices[i].vx = datum->vx;
1910 spriteVertices[i].vy = datum->vy;
1911 spriteVertices[i].ax = datum->ax;
1912 spriteVertices[i].ay = datum->ay;
1913 if (m_explicitDeformation && datum->deformationOwner !=
this) {
1914 QQuickParticleData* shadow = getShadowDatum(datum);
1915 spriteVertices[i].xx = shadow->xx;
1916 spriteVertices[i].xy = shadow->xy;
1917 spriteVertices[i].yx = shadow->yx;
1918 spriteVertices[i].yy = shadow->yy;
1920 spriteVertices[i].xx = datum->xx;
1921 spriteVertices[i].xy = datum->xy;
1922 spriteVertices[i].yx = datum->yx;
1923 spriteVertices[i].yy = datum->yy;
1925 if (m_explicitRotation && datum->rotationOwner !=
this) {
1926 QQuickParticleData* shadow = getShadowDatum(datum);
1927 spriteVertices[i].rotation = shadow->rotation;
1928 spriteVertices[i].rotationVelocity = shadow->rotationVelocity;
1929 spriteVertices[i].autoRotate = shadow->autoRotate;
1931 spriteVertices[i].rotation = datum->rotation;
1932 spriteVertices[i].rotationVelocity = datum->rotationVelocity;
1933 spriteVertices[i].autoRotate = datum->autoRotate;
1936 if (m_explicitColor && datum->colorOwner !=
this) {
1937 QQuickParticleData* shadow = getShadowDatum(datum);
1938 spriteVertices[i].color = shadow->color;
1940 spriteVertices[i].color = datum->color;
1946 deformableVertices += pIdx*4;
1947 for (
int i=0; i<4; i++){
1948 deformableVertices[i].x = datum->x - m_systemOffset.x();
1949 deformableVertices[i].y = datum->y - m_systemOffset.y();
1950 deformableVertices[i].t = datum->t;
1951 deformableVertices[i].lifeSpan = datum->lifeSpan;
1952 deformableVertices[i].size = datum->size;
1953 deformableVertices[i].endSize = datum->endSize;
1954 deformableVertices[i].vx = datum->vx;
1955 deformableVertices[i].vy = datum->vy;
1956 deformableVertices[i].ax = datum->ax;
1957 deformableVertices[i].ay = datum->ay;
1958 if (m_explicitDeformation && datum->deformationOwner !=
this) {
1959 QQuickParticleData* shadow = getShadowDatum(datum);
1960 deformableVertices[i].xx = shadow->xx;
1961 deformableVertices[i].xy = shadow->xy;
1962 deformableVertices[i].yx = shadow->yx;
1963 deformableVertices[i].yy = shadow->yy;
1965 deformableVertices[i].xx = datum->xx;
1966 deformableVertices[i].xy = datum->xy;
1967 deformableVertices[i].yx = datum->yx;
1968 deformableVertices[i].yy = datum->yy;
1970 if (m_explicitRotation && datum->rotationOwner !=
this) {
1971 QQuickParticleData* shadow = getShadowDatum(datum);
1972 deformableVertices[i].rotation = shadow->rotation;
1973 deformableVertices[i].rotationVelocity = shadow->rotationVelocity;
1974 deformableVertices[i].autoRotate = shadow->autoRotate;
1976 deformableVertices[i].rotation = datum->rotation;
1977 deformableVertices[i].rotationVelocity = datum->rotationVelocity;
1978 deformableVertices[i].autoRotate = datum->autoRotate;
1980 if (m_explicitColor && datum->colorOwner !=
this) {
1981 QQuickParticleData* shadow = getShadowDatum(datum);
1982 deformableVertices[i].color = shadow->color;
1984 deformableVertices[i].color = datum->color;
1989 coloredVertices += pIdx*4;
1990 for (
int i=0; i<4; i++){
1991 coloredVertices[i].x = datum->x - m_systemOffset.x();
1992 coloredVertices[i].y = datum->y - m_systemOffset.y();
1993 coloredVertices[i].t = datum->t;
1994 coloredVertices[i].lifeSpan = datum->lifeSpan;
1995 coloredVertices[i].size = datum->size;
1996 coloredVertices[i].endSize = datum->endSize;
1997 coloredVertices[i].vx = datum->vx;
1998 coloredVertices[i].vy = datum->vy;
1999 coloredVertices[i].ax = datum->ax;
2000 coloredVertices[i].ay = datum->ay;
2001 if (m_explicitColor && datum->colorOwner !=
this) {
2002 QQuickParticleData* shadow = getShadowDatum(datum);
2003 coloredVertices[i].color = shadow->color;
2005 coloredVertices[i].color = datum->color;
2010 coloredPointVertices += pIdx*1;
2011 for (
int i=0; i<1; i++){
2012 coloredPointVertices[i].x = datum->x - m_systemOffset.x();
2013 coloredPointVertices[i].y = datum->y - m_systemOffset.y();
2014 coloredPointVertices[i].t = datum->t;
2015 coloredPointVertices[i].lifeSpan = datum->lifeSpan;
2016 coloredPointVertices[i].size = datum->size;
2017 coloredPointVertices[i].endSize = datum->endSize;
2018 coloredPointVertices[i].vx = datum->vx;
2019 coloredPointVertices[i].vy = datum->vy;
2020 coloredPointVertices[i].ax = datum->ax;
2021 coloredPointVertices[i].ay = datum->ay;
2022 if (m_explicitColor && datum->colorOwner !=
this) {
2023 QQuickParticleData* shadow = getShadowDatum(datum);
2024 coloredPointVertices[i].color = shadow->color;
2026 coloredPointVertices[i].color = datum->color;
2031 simplePointVertices += pIdx*1;
2032 for (
int i=0; i<1; i++){
2033 simplePointVertices[i].x = datum->x - m_systemOffset.x();
2034 simplePointVertices[i].y = datum->y - m_systemOffset.y();
2035 simplePointVertices[i].t = datum->t;
2036 simplePointVertices[i].lifeSpan = datum->lifeSpan;
2037 simplePointVertices[i].size = datum->size;
2038 simplePointVertices[i].endSize = datum->endSize;
2039 simplePointVertices[i].vx = datum->vx;
2040 simplePointVertices[i].vy = datum->vy;
2041 simplePointVertices[i].ax = datum->ax;
2042 simplePointVertices[i].ay = datum->ay;
2054#include "moc_qquickimageparticle_p.cpp"
ColoredMaterialRhiShader(int viewCount)
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
ImageMaterialData * state() override
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
ColoredPointMaterialRhiShader(int viewCount)
void updateSampledImage(RenderState &renderState, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
ImageMaterialData * state() override
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
void updateSampledImage(RenderState &renderState, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
ParticleSpriteMaterialRhiShader(int viewCount)
bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
SimplePointMaterialRhiShader(int viewCount)
void updateSampledImage(RenderState &renderState, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
ImageMaterialData * state() override
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
ImageMaterialData * state() override
bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
void updateSampledImage(RenderState &renderState, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
TabledMaterialRhiShader(int viewCount)
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
ImageMaterialData * state() override
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
static QSGGeometry::Attribute ColoredParticle_Attributes[]
static QSGGeometry::AttributeSet ColoredPointParticle_AttributeSet
static QSGGeometry::AttributeSet SpriteParticle_AttributeSet
static QSGGeometry::Attribute SimplePointParticle_Attributes[]
static QSGGeometry::Attribute SpriteParticle_Attributes[]
static QSGGeometry::AttributeSet ColoredParticle_AttributeSet
static QSGGeometry::AttributeSet DeformableParticle_AttributeSet
static QSGGeometry::Attribute DeformableParticle_Attributes[]
void fillUniformArrayFromImage(float *array, const QImage &img, int size)
static QSGGeometry::Attribute ColoredPointParticle_Attributes[]
#define UNIFORM_ARRAY_SIZE
static QSGGeometry::AttributeSet SimplePointParticle_AttributeSet