6#include <QtQuick/private/qsgcontext_p.h>
7#include <private/qsgadaptationlayer_p.h>
8#include <private/qquickitem_p.h>
9#include <QtQuick/qsgnode.h>
10#include <QtQuick/qsgtexture.h>
12#include <QRandomGenerator>
15#include <private/qquicksprite_p.h>
16#include <private/qquickspriteengine_p.h>
17#include <QSGRendererInterface>
18#include <QtQuick/private/qsgplaintexture_p.h>
19#include <private/qqmlglobal_p.h>
20#include <QtQml/qqmlinfo.h>
21#include <QtCore/QtMath>
29#define UNIFORM_ARRAY_SIZE 64
31class ImageMaterialData
35 : texture(
nullptr), colorTable(
nullptr)
44 QSGTexture *colorTable;
59 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_tabled.vert.qsb"), viewCount);
60 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_tabled.frag.qsb"), viewCount);
63 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
65 QByteArray *buf = renderState.uniformData();
67 const int shaderMatrixCount = newMaterial->viewCount();
68 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
70 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
71 if (renderState.isMatrixDirty()) {
72 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
73 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
77 if (renderState.isOpacityDirty()) {
78 const float opacity = renderState.opacity();
79 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
82 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
84 float entry =
float(state->entry);
85 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
87 float timestamp =
float(state->timestamp);
88 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
90 float *p =
reinterpret_cast<
float *>(buf->data() + 64 * shaderMatrixCount + 16);
92 *p = state->sizeTable[i];
95 p =
reinterpret_cast<
float *>(buf->data() + 64 * shaderMatrixCount + 16 + (
UNIFORM_ARRAY_SIZE * 4 * 4));
97 *p = state->opacityTable[i];
105 QSGMaterial *newMaterial, QSGMaterial *)
override
107 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
109 state->colorTable->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
110 *texture = state->colorTable;
111 }
else if (binding == 1) {
112 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
113 *texture = state->texture;
122 Q_UNUSED(renderMode);
127 ImageMaterialData *
state()
override {
return &m_state; }
130 static QSGMaterialType m_type;
131 ImageMaterialData m_state;
141 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_deformed.vert.qsb"), viewCount);
142 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_deformed.frag.qsb"), viewCount);
145 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
147 QByteArray *buf = renderState.uniformData();
149 const int shaderMatrixCount = newMaterial->viewCount();
150 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
152 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
153 if (renderState.isMatrixDirty()) {
154 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
155 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
159 if (renderState.isOpacityDirty()) {
160 const float opacity = renderState.opacity();
161 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
164 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
166 float entry =
float(state->entry);
167 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
169 float timestamp =
float(state->timestamp);
170 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
176 QSGMaterial *newMaterial, QSGMaterial *)
override
178 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
180 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
181 *texture = state->texture;
190 Q_UNUSED(renderMode);
195 ImageMaterialData *
state()
override {
return &m_state; }
198 static QSGMaterialType m_type;
199 ImageMaterialData m_state;
209 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_sprite.vert.qsb"), viewCount);
210 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_sprite.frag.qsb"), viewCount);
213 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
215 QByteArray *buf = renderState.uniformData();
217 const int shaderMatrixCount = newMaterial->viewCount();
218 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
220 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
221 if (renderState.isMatrixDirty()) {
222 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
223 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
227 if (renderState.isOpacityDirty()) {
228 const float opacity = renderState.opacity();
229 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
232 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
234 float entry =
float(state->entry);
235 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
237 float timestamp =
float(state->timestamp);
238 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
240 float *p =
reinterpret_cast<
float *>(buf->data() + 64 * shaderMatrixCount + 16);
242 *p = state->sizeTable[i];
245 p =
reinterpret_cast<
float *>(buf->data() + 64 * shaderMatrixCount + 16 + (
UNIFORM_ARRAY_SIZE * 4 * 4));
247 *p = state->opacityTable[i];
255 QSGMaterial *newMaterial, QSGMaterial *)
override
257 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
259 state->colorTable->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
260 *texture = state->colorTable;
261 }
else if (binding == 1) {
262 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
263 *texture = state->texture;
272 Q_UNUSED(renderMode);
277 ImageMaterialData *
state()
override {
return &m_state; }
280 static QSGMaterialType m_type;
281 ImageMaterialData m_state;
291 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_coloredpoint.vert.qsb"), viewCount);
292 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_coloredpoint.frag.qsb"), viewCount);
295 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
297 QByteArray *buf = renderState.uniformData();
299 const int shaderMatrixCount = newMaterial->viewCount();
300 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
302 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
303 if (renderState.isMatrixDirty()) {
304 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
305 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
309 if (renderState.isOpacityDirty()) {
310 const float opacity = renderState.opacity();
311 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
314 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
316 float entry =
float(state->entry);
317 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
319 float timestamp =
float(state->timestamp);
320 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
322 float dpr =
float(state->dpr);
323 memcpy(buf->data() + 64 * shaderMatrixCount + 12, &dpr, 4);
329 QSGMaterial *newMaterial, QSGMaterial *)
override
331 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
333 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
334 *texture = state->texture;
343 Q_UNUSED(renderMode);
348 ImageMaterialData *
state()
override {
return &m_state; }
351 static QSGMaterialType m_type;
352 ImageMaterialData m_state;
363 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_colored.vert.qsb"), viewCount);
364 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_colored.frag.qsb"), viewCount);
372 Q_UNUSED(renderMode);
377 ImageMaterialData *
state()
override {
return &m_state; }
380 static QSGMaterialType m_type;
381 ImageMaterialData m_state;
391 setShaderFileName(VertexStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_simplepoint.vert.qsb"), viewCount);
392 setShaderFileName(FragmentStage, QStringLiteral(
":/particles/shaders_ng/imageparticle_simplepoint.frag.qsb"), viewCount);
395 bool updateUniformData(RenderState &renderState, QSGMaterial *newMaterial, QSGMaterial *)
override
397 QByteArray *buf = renderState.uniformData();
399 const int shaderMatrixCount = newMaterial->viewCount();
400 const int matrixCount = qMin(renderState.projectionMatrixCount(), shaderMatrixCount);
402 for (
int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
403 if (renderState.isMatrixDirty()) {
404 const QMatrix4x4 m = renderState.combinedMatrix(viewIndex);
405 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
409 if (renderState.isOpacityDirty()) {
410 const float opacity = renderState.opacity();
411 memcpy(buf->data() + 64 * shaderMatrixCount, &opacity, 4);
414 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
416 float entry =
float(state->entry);
417 memcpy(buf->data() + 64 * shaderMatrixCount + 4, &entry, 4);
419 float timestamp =
float(state->timestamp);
420 memcpy(buf->data() + 64 * shaderMatrixCount + 8, ×tamp, 4);
422 float dpr =
float(state->dpr);
423 memcpy(buf->data() + 64 * shaderMatrixCount + 12, &dpr, 4);
429 QSGMaterial *newMaterial, QSGMaterial *)
override
431 ImageMaterialData *state =
static_cast<ImageMaterial *>(newMaterial)->state();
433 state->texture->commitTextureOperations(renderState.rhi(), renderState.resourceUpdateBatch());
434 *texture = state->texture;
443 Q_UNUSED(renderMode);
448 ImageMaterialData *
state()
override {
return &m_state; }
451 static QSGMaterialType m_type;
452 ImageMaterialData m_state;
460 for (
int i=0; i<size; i++)
464 QImage scaled = img.scaled(size,1);
465 for (
int i=0; i<size; i++)
466 array[i] = qAlpha(scaled.pixel(i,0))/255.0;
470
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
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
525
526
527
528
529
530
531
532
533
535
536
537
538
539
540
541
542
544
545
546
547
548
549
551
552
553
554
555
556
558
559
560
561
562
563
565
566
567
568
569
570
571
572
573
574
575
576
578
579
580
581
582
583
584
586
587
588
589
590
591
592
594
595
596
597
598
599
600
602
603
604
605
606
607
608
609
610
611
612
614
615
616
617
618
619
620
622
623
624
625
626
627
629
630
631
632
633
634
636
637
638
639
641
642
643
644
645
646
648
649
650
651
652
653
654
655
657
658
659
660
661
662
664
665
666
667
668
669
671
672
673
674
675
676
677
678
679
680
681
682
683
685
686
687
688
689
690
691
694
695
696
697
700QQuickImageParticle::QQuickImageParticle(QQuickItem* parent)
701 : QQuickParticlePainter(parent)
702 , m_color_variation(0.0)
703 , m_outgoingNode(
nullptr)
704 , m_material(
nullptr)
705 , m_alphaVariation(0.0)
707 , m_redVariation(0.0)
708 , m_greenVariation(0.0)
709 , m_blueVariation(0.0)
711 , m_rotationVariation(0)
712 , m_rotationVelocity(0)
713 , m_rotationVelocityVariation(0)
714 , m_autoRotation(
false)
717 , m_spriteEngine(
nullptr)
718 , m_spritesInterpolate(
true)
719 , m_explicitColor(
false)
720 , m_explicitRotation(
false)
721 , m_explicitDeformation(
false)
722 , m_explicitAnimation(
false)
723 , m_bypassOptimizations(
false)
725 , m_targetPerfLevel(Unknown)
727 , m_entryEffect(Fade)
728 , m_startedImageLoading(0)
730 , m_apiChecked(
false)
732 , m_previousActive(
false)
734 setFlag(ItemHasContents);
737QQuickImageParticle::~QQuickImageParticle()
742QQmlListProperty<QQuickSprite> QQuickImageParticle::sprites()
744 return QQmlListProperty<QQuickSprite>(
this, &m_sprites,
745 spriteAppend, spriteCount, spriteAt,
746 spriteClear, spriteReplace, spriteRemoveLast);
749void QQuickImageParticle::sceneGraphInvalidated()
752 m_material =
nullptr;
753 delete m_outgoingNode;
754 m_outgoingNode =
nullptr;
755 m_apiChecked =
false;
758void QQuickImageParticle::setImage(
const QUrl &image)
760 if (image.isEmpty()){
769 m_image.reset(
new ImageData);
770 if (image == m_image->source)
772 m_image->source = image;
778void QQuickImageParticle::setColortable(
const QUrl &table)
780 if (table.isEmpty()){
782 m_colorTable.reset();
783 emit colortableChanged();
789 m_colorTable.reset(
new ImageData);
790 if (table == m_colorTable->source)
792 m_colorTable->source = table;
793 emit colortableChanged();
797void QQuickImageParticle::setSizetable(
const QUrl &table)
799 if (table.isEmpty()){
802 emit sizetableChanged();
808 m_sizeTable.reset(
new ImageData);
809 if (table == m_sizeTable->source)
811 m_sizeTable->source = table;
812 emit sizetableChanged();
816void QQuickImageParticle::setOpacitytable(
const QUrl &table)
818 if (table.isEmpty()){
819 if (m_opacityTable) {
820 m_opacityTable.reset();
821 emit opacitytableChanged();
827 m_opacityTable.reset(
new ImageData);
828 if (table == m_opacityTable->source)
830 m_opacityTable->source = table;
831 emit opacitytableChanged();
835void QQuickImageParticle::setColor(
const QColor &color)
837 if (color == m_color)
841 m_explicitColor =
true;
842 checkPerfLevel(ColoredPoint);
845void QQuickImageParticle::setColorVariation(qreal var)
847 if (var == m_color_variation)
849 m_color_variation = var;
850 emit colorVariationChanged();
851 m_explicitColor =
true;
852 checkPerfLevel(ColoredPoint);
855void QQuickImageParticle::setAlphaVariation(qreal arg)
857 if (m_alphaVariation != arg) {
858 m_alphaVariation = arg;
859 emit alphaVariationChanged(arg);
861 m_explicitColor =
true;
862 checkPerfLevel(ColoredPoint);
865void QQuickImageParticle::setAlpha(qreal arg)
867 if (m_alpha != arg) {
869 emit alphaChanged(arg);
871 m_explicitColor =
true;
872 checkPerfLevel(ColoredPoint);
875void QQuickImageParticle::setRedVariation(qreal arg)
877 if (m_redVariation != arg) {
878 m_redVariation = arg;
879 emit redVariationChanged(arg);
881 m_explicitColor =
true;
882 checkPerfLevel(ColoredPoint);
885void QQuickImageParticle::setGreenVariation(qreal arg)
887 if (m_greenVariation != arg) {
888 m_greenVariation = arg;
889 emit greenVariationChanged(arg);
891 m_explicitColor =
true;
892 checkPerfLevel(ColoredPoint);
895void QQuickImageParticle::setBlueVariation(qreal arg)
897 if (m_blueVariation != arg) {
898 m_blueVariation = arg;
899 emit blueVariationChanged(arg);
901 m_explicitColor =
true;
902 checkPerfLevel(ColoredPoint);
905void QQuickImageParticle::setRotation(qreal arg)
907 if (m_rotation != arg) {
909 emit rotationChanged(arg);
911 m_explicitRotation =
true;
912 checkPerfLevel(Deformable);
915void QQuickImageParticle::setRotationVariation(qreal arg)
917 if (m_rotationVariation != arg) {
918 m_rotationVariation = arg;
919 emit rotationVariationChanged(arg);
921 m_explicitRotation =
true;
922 checkPerfLevel(Deformable);
925void QQuickImageParticle::setRotationVelocity(qreal arg)
927 if (m_rotationVelocity != arg) {
928 m_rotationVelocity = arg;
929 emit rotationVelocityChanged(arg);
931 m_explicitRotation =
true;
932 checkPerfLevel(Deformable);
935void QQuickImageParticle::setRotationVelocityVariation(qreal arg)
937 if (m_rotationVelocityVariation != arg) {
938 m_rotationVelocityVariation = arg;
939 emit rotationVelocityVariationChanged(arg);
941 m_explicitRotation =
true;
942 checkPerfLevel(Deformable);
945void QQuickImageParticle::setAutoRotation(
bool arg)
947 if (m_autoRotation != arg) {
948 m_autoRotation = arg;
949 emit autoRotationChanged(arg);
951 m_explicitRotation =
true;
952 checkPerfLevel(Deformable);
955void QQuickImageParticle::setXVector(QQuickDirection* arg)
957 if (m_xVector != arg) {
959 emit xVectorChanged(arg);
961 m_explicitDeformation =
true;
962 checkPerfLevel(Deformable);
965void QQuickImageParticle::setYVector(QQuickDirection* arg)
967 if (m_yVector != arg) {
969 emit yVectorChanged(arg);
971 m_explicitDeformation =
true;
972 checkPerfLevel(Deformable);
975void QQuickImageParticle::setSpritesInterpolate(
bool arg)
977 if (m_spritesInterpolate != arg) {
978 m_spritesInterpolate = arg;
979 emit spritesInterpolateChanged(arg);
983void QQuickImageParticle::setBypassOptimizations(
bool arg)
985 if (m_bypassOptimizations != arg) {
986 m_bypassOptimizations = arg;
987 emit bypassOptimizationsChanged(arg);
993void QQuickImageParticle::setEntryEffect(EntryEffect arg)
995 if (m_entryEffect != arg) {
998 getState(m_material)->entry = (qreal) m_entryEffect;
999 emit entryEffectChanged(arg);
1003void QQuickImageParticle::resetColor()
1005 m_explicitColor =
false;
1006 for (
auto groupId : groupIds()) {
1007 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
1008 if (d->colorOwner ==
this) {
1009 d->colorOwner =
nullptr;
1014 m_color_variation = 0.0f;
1015 m_redVariation = 0.0f;
1016 m_blueVariation = 0.0f;
1017 m_greenVariation = 0.0f;
1019 m_alphaVariation = 0.0f;
1022void QQuickImageParticle::resetRotation()
1024 m_explicitRotation =
false;
1025 for (
auto groupId : groupIds()) {
1026 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
1027 if (d->rotationOwner ==
this) {
1028 d->rotationOwner =
nullptr;
1033 m_rotationVariation = 0;
1034 m_rotationVelocity = 0;
1035 m_rotationVelocityVariation = 0;
1036 m_autoRotation =
false;
1039void QQuickImageParticle::resetDeformation()
1041 m_explicitDeformation =
false;
1042 for (
auto groupId : groupIds()) {
1043 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
1044 if (d->deformationOwner ==
this) {
1045 d->deformationOwner =
nullptr;
1053 m_xVector =
nullptr;
1054 m_yVector =
nullptr;
1057void QQuickImageParticle::reset()
1059 QQuickParticlePainter::reset();
1060 m_pleaseReset =
true;
1065void QQuickImageParticle::invalidateSceneGraph()
1070void QQuickImageParticle::createEngine()
1073 delete m_spriteEngine;
1074 if (m_sprites.size()) {
1075 m_spriteEngine =
new QQuickSpriteEngine(m_sprites,
this);
1076 connect(m_spriteEngine, &QQuickStochasticEngine::stateChanged,
1077 this, &QQuickImageParticle::spriteAdvance, Qt::DirectConnection);
1078 m_explicitAnimation =
true;
1080 m_spriteEngine =
nullptr;
1081 m_explicitAnimation =
false;
1087 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType,
true),
1088 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1089 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType)
1095 ( 2 + 4 + 4 ) *
sizeof(
float),
1096 SimplePointParticle_Attributes
1100 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType,
true),
1101 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1102 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1103 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1109 ( 2 + 4 + 4 ) *
sizeof(
float) + 4 *
sizeof(uchar),
1110 ColoredPointParticle_Attributes
1114 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType,
true),
1115 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1116 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1117 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1118 QSGGeometry::Attribute::create(4, 4, QSGGeometry::UnsignedByteType),
1124 ( 2 + 4 + 4 ) *
sizeof(
float) + (4 + 4) *
sizeof(uchar),
1125 ColoredParticle_Attributes
1129 QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType),
1130 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1131 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1132 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1133 QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType),
1134 QSGGeometry::Attribute::create(5, 4, QSGGeometry::UnsignedByteType),
1140 (4 + 4 + 4 + 4) *
sizeof(
float) + (4 + 4) *
sizeof(uchar),
1141 DeformableParticle_Attributes
1145 QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType),
1146 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1147 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1148 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1149 QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType),
1150 QSGGeometry::Attribute::create(5, 4, QSGGeometry::UnsignedByteType),
1151 QSGGeometry::Attribute::create(6, 3, QSGGeometry::FloatType),
1152 QSGGeometry::Attribute::create(7, 3, QSGGeometry::FloatType)
1158 (4 + 4 + 4 + 4 + 3 + 3) *
sizeof(
float) + (4 + 4) *
sizeof(uchar),
1159 SpriteParticle_Attributes
1162void QQuickImageParticle::clearShadows()
1164 foreach (
const QVector<QQuickParticleData*> data, m_shadowData)
1166 m_shadowData.clear();
1170QQuickParticleData* QQuickImageParticle::getShadowDatum(QQuickParticleData* datum)
1173 if (datum->systemIndex == -1)
1175 if (!m_shadowData.contains(datum->groupId)) {
1176 QQuickParticleGroupData* gd = m_system->groupData[datum->groupId];
1177 QVector<QQuickParticleData*> data;
1178 const int gdSize = gd->size();
1179 data.reserve(gdSize);
1180 for (
int i = 0; i < gdSize; i++) {
1181 QQuickParticleData* datum =
new QQuickParticleData;
1182 *datum = *(gd->data[i]);
1185 m_shadowData.insert(datum->groupId, data);
1189 return m_shadowData[datum->groupId][datum->index];
1192void QQuickImageParticle::checkPerfLevel(PerformanceLevel level)
1194 if (m_targetPerfLevel < level) {
1195 m_targetPerfLevel = level;
1200bool QQuickImageParticle::loadingSomething()
1202 return (m_image && m_image->pix.isLoading())
1203 || (m_colorTable && m_colorTable->pix.isLoading())
1204 || (m_sizeTable && m_sizeTable->pix.isLoading())
1205 || (m_opacityTable && m_opacityTable->pix.isLoading())
1206 || (m_spriteEngine && m_spriteEngine->isLoading());
1209void QQuickImageParticle::mainThreadFetchImageData()
1211 const QQmlContext *context =
nullptr;
1212 QQmlEngine *engine =
nullptr;
1213 const auto loadPix = [&](ImageData *image) {
1215 context = qmlContext(
this);
1216 engine = context->engine();
1218 image->pix.load(engine, context->resolvedUrl(image->source));
1223 m_image->pix.clear(
this);
1224 loadPix(m_image.get());
1228 m_spriteEngine->startAssemblingImage();
1231 loadPix(m_colorTable.get());
1234 loadPix(m_sizeTable.get());
1237 loadPix(m_opacityTable.get());
1239 m_startedImageLoading = 2;
1242void QQuickImageParticle::buildParticleNodes(QSGNode** passThrough)
1246 if (*passThrough || loadingSomething())
1249 if (m_startedImageLoading == 0) {
1250 m_startedImageLoading = 1;
1252 QQuickImageParticle::staticMetaObject.invokeMethod(
this,
"mainThreadFetchImageData", Qt::QueuedConnection);
1253 }
else if (m_startedImageLoading == 2) {
1254 finishBuildParticleNodes(passThrough);
1260void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
1265 if (m_count * 4 > 0xffff) {
1267 qmlInfo(
this) <<
"ImageParticle: Too many particles - maximum 16383 per ImageParticle";
1274 m_debugMode = m_system->m_debugMode;
1276 if (m_sprites.size() || m_bypassOptimizations) {
1277 perfLevel = Sprites;
1278 }
else if (m_colorTable || m_sizeTable || m_opacityTable) {
1280 }
else if (m_autoRotation || m_rotation || m_rotationVariation
1281 || m_rotationVelocity || m_rotationVelocityVariation
1282 || m_xVector || m_yVector) {
1283 perfLevel = Deformable;
1284 }
else if (m_alphaVariation || m_alpha != 1.0 || m_color.isValid() || m_color_variation
1285 || m_redVariation || m_blueVariation || m_greenVariation) {
1286 perfLevel = ColoredPoint;
1288 perfLevel = SimplePoint;
1291 for (
auto groupId : groupIds()) {
1293 for (QQuickParticlePainter* p : std::as_const(m_system->groupData[groupId]->painters)) {
1294 QQuickImageParticle* other = qobject_cast<QQuickImageParticle*>(p);
1296 if (other->perfLevel > perfLevel) {
1297 if (other->perfLevel >= Tabled){
1298 if (perfLevel < Deformable)
1299 perfLevel = Deformable;
1301 perfLevel = other->perfLevel;
1303 }
else if (other->perfLevel < perfLevel) {
1313 if (perfLevel < Colored && !m_rhi->isFeatureSupported(QRhi::VertexShaderPointSize))
1314 perfLevel = Colored;
1316 if (perfLevel >= ColoredPoint && !m_color.isValid())
1317 m_color = QColor(Qt::white);
1319 m_targetPerfLevel = perfLevel;
1323 m_material =
nullptr;
1328 QImage opacitytable;
1330 bool imageLoaded =
false;
1331 switch (perfLevel) {
1334 if (!m_spriteEngine) {
1335 qWarning() <<
"ImageParticle: No sprite engine...";
1339 image = m_spriteEngine->assembledImage();
1344 m_material =
new SpriteMaterial;
1345 ImageMaterialData *state = getState(m_material);
1347 state->texture = QSGPlainTexture::fromImage(image);
1348 state->animSheetSize = QSizeF(image.size() / image.devicePixelRatio());
1350 m_spriteEngine->setCount(m_count);
1356 m_material =
new TabledMaterial;
1359 if (m_colorTable->pix.isReady())
1360 colortable = m_colorTable->pix.image();
1362 qmlWarning(
this) <<
"Error loading color table: " << m_colorTable->pix.error();
1366 if (m_sizeTable->pix.isReady())
1367 sizetable = m_sizeTable->pix.image();
1369 qmlWarning(
this) <<
"Error loading size table: " << m_sizeTable->pix.error();
1372 if (m_opacityTable) {
1373 if (m_opacityTable->pix.isReady())
1374 opacitytable = m_opacityTable->pix.image();
1376 qmlWarning(
this) <<
"Error loading opacity table: " << m_opacityTable->pix.error();
1379 if (colortable.isNull()){
1380 colortable = QImage(1,1,QImage::Format_ARGB32_Premultiplied);
1381 colortable.fill(Qt::white);
1383 ImageMaterialData *state = getState(m_material);
1384 state->colorTable = QSGPlainTexture::fromImage(colortable);
1392 m_material =
new DeformableMaterial;
1398 m_material =
new ColoredMaterial;
1404 m_material =
new ColoredPointMaterial;
1410 m_material =
new SimplePointMaterial;
1411 ImageMaterialData *state = getState(m_material);
1413 if (!m_image || !m_image->pix.isReady()) {
1415 qmlWarning(
this) << m_image->pix.error();
1421 state->texture = QSGPlainTexture::fromImage(m_image->pix.image());
1423 state->texture->setFiltering(QSGTexture::Linear);
1424 state->entry = (qreal) m_entryEffect;
1427 m_material->setFlag(QSGMaterial::Blending | QSGMaterial::RequiresFullMatrix);
1432 for (
auto groupId : groupIds()) {
1433 int count = m_system->groupData[groupId]->size();
1434 QSGGeometryNode* node =
new QSGGeometryNode();
1435 node->setMaterial(m_material);
1436 node->markDirty(QSGNode::DirtyMaterial);
1438 m_nodes.insert(groupId, node);
1439 m_idxStarts.insert(groupId, m_lastIdxStart);
1440 m_startsIdx.append(std::make_pair(m_lastIdxStart, groupId));
1441 m_lastIdxStart += count;
1444 int vCount = count * 4;
1445 int iCount = count * 6;
1448 if (perfLevel == Sprites)
1449 g =
new QSGGeometry(SpriteParticle_AttributeSet, vCount, iCount);
1450 else if (perfLevel == Tabled)
1451 g =
new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount);
1452 else if (perfLevel == Deformable)
1453 g =
new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount);
1454 else if (perfLevel == Colored)
1455 g =
new QSGGeometry(ColoredParticle_AttributeSet, vCount, iCount);
1456 else if (perfLevel == ColoredPoint)
1457 g =
new QSGGeometry(ColoredPointParticle_AttributeSet, count, 0);
1459 g =
new QSGGeometry(SimplePointParticle_AttributeSet, count, 0);
1461 node->setFlag(QSGNode::OwnsGeometry);
1462 node->setGeometry(g);
1463 if (perfLevel <= ColoredPoint){
1464 g->setDrawingMode(QSGGeometry::DrawPoints);
1466 qDebug(
"Using point sprites");
1468 g->setDrawingMode(QSGGeometry::DrawTriangles);
1471 for (
int p=0; p < count; ++p)
1474 if (perfLevel == Sprites)
1475 initTexCoords<SpriteVertex>((SpriteVertex*)g->vertexData(), vCount);
1476 else if (perfLevel == Tabled)
1477 initTexCoords<DeformableVertex>((DeformableVertex*)g->vertexData(), vCount);
1478 else if (perfLevel == Deformable)
1479 initTexCoords<DeformableVertex>((DeformableVertex*)g->vertexData(), vCount);
1480 else if (perfLevel == Colored)
1481 initTexCoords<ColoredVertex>((ColoredVertex*)g->vertexData(), vCount);
1483 if (perfLevel > ColoredPoint){
1484 quint16 *indices = g->indexDataAsUShort();
1485 for (
int i=0; i < count; ++i) {
1498 if (perfLevel == Sprites)
1501 foreach (QSGGeometryNode* node, m_nodes){
1502 if (node == *(m_nodes.begin()))
1503 node->setFlag(QSGGeometryNode::OwnsMaterial);
1505 (*(m_nodes.begin()))->appendChildNode(node);
1508 *node = *(m_nodes.begin());
1512QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
1514 if (!m_apiChecked || m_windowChanged) {
1515 m_apiChecked =
true;
1516 m_windowChanged =
false;
1518 QSGRenderContext *rc = QQuickItemPrivate::get(
this)->sceneGraphRenderContext();
1519 QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
1523 QSGRendererInterface::GraphicsApi api = rif->graphicsApi();
1524 const bool isRhi = QSGRendererInterface::isApiRhiBased(api);
1526 if (!node && !isRhi)
1530 m_rhi =
static_cast<QRhi *>(rif->getResource(m_window, QSGRendererInterface::RhiResource));
1534 if (isRhi && !m_rhi) {
1535 qWarning(
"Failed to query QRhi, particles disabled");
1539 m_dpr = m_window ? m_window->devicePixelRatio() : 1.0;
1546 delete m_outgoingNode;
1547 m_outgoingNode = node;
1552 m_idxStarts.clear();
1553 m_startsIdx.clear();
1556 m_material =
nullptr;
1558 m_pleaseReset =
false;
1559 m_startedImageLoading = 0;
1560 }
else if (!m_material) {
1565 if (m_system && m_system->isRunning() && !m_system->isPaused()){
1566 bool dirty = prepareNextFrame(&node);
1570 foreach (QSGGeometryNode* n, m_nodes)
1571 n->markDirty(QSGNode::DirtyGeometry);
1573 }
else if (m_startedImageLoading < 2) {
1579 node = m_outgoingNode;
1580 m_outgoingNode =
nullptr;
1586bool QQuickImageParticle::prepareNextFrame(QSGNode **node)
1588 if (*node ==
nullptr){
1589 buildParticleNodes(node);
1591 qDebug() <<
"QQuickImageParticle Feature level: " << perfLevel;
1592 qDebug() <<
"QQuickImageParticle Nodes: ";
1594 for (
auto it = m_nodes.keyBegin(), end = m_nodes.keyEnd(); it != end; ++it) {
1595 qDebug() <<
"Group " << *it <<
" (" << m_system->groupData[*it]->size()
1597 count += m_system->groupData[*it]->size();
1599 qDebug() <<
"Total count: " << count;
1601 if (*node ==
nullptr)
1604 qint64 timeStamp = m_system->systemSync(
this);
1606 qreal time = timeStamp / 1000.;
1612 m_spriteEngine->updateSprites(timeStamp);
1613 spritesUpdate(time);
1621 getState(m_material)->timestamp = time;
1625 bool active =
false;
1626 for (
auto groupId : groupIds()) {
1627 if (m_system->groupData[groupId]->isActive()) {
1633 const bool dirty = active || m_previousActive;
1635 foreach (QSGGeometryNode* node, m_nodes)
1636 node->markDirty(QSGNode::DirtyMaterial);
1639 m_previousActive = active;
1643void QQuickImageParticle::spritesUpdate(qreal time)
1645 ImageMaterialData *state = getState(m_material);
1647 for (
auto groupId : groupIds()) {
1648 for (QQuickParticleData* mainDatum : std::as_const(m_system->groupData[groupId]->data)) {
1649 QSGGeometryNode *node = m_nodes[groupId];
1654 QQuickParticleData* datum = (mainDatum->animationOwner ==
this ? mainDatum : getShadowDatum(mainDatum));
1656 for (
int i = 0; i<m_startsIdx.size(); i++) {
1657 if (m_startsIdx[i].second == groupId){
1658 spriteIdx = m_startsIdx[i].first + datum->index;
1666 if (datum->frameDuration > 0) {
1667 qreal frame = (time - datum->animT)/(datum->frameDuration / 1000.0);
1668 frame = qBound((qreal)0.0, frame, (qreal)((qreal)datum->frameCount - 1.0));
1669 if (m_spritesInterpolate)
1670 progress = std::modf(frame,&frameAt);
1672 std::modf(frame,&frameAt);
1675 if (datum->frameAt >= datum->frameCount){
1677 m_spriteEngine->advance(spriteIdx);
1679 frameAt = datum->frameAt;
1681 if (m_spriteEngine->sprite(spriteIdx)->reverse())
1682 frameAt = (datum->frameCount - 1) - frameAt;
1683 QSizeF sheetSize = state->animSheetSize;
1684 qreal y = datum->animY / sheetSize.height();
1685 qreal w = datum->animWidth / sheetSize.width();
1686 qreal h = datum->animHeight / sheetSize.height();
1687 qreal x1 = datum->animX / sheetSize.width();
1690 if (frameAt < (datum->frameCount-1))
1693 SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData();
1694 spriteVertices += datum->index*4;
1695 for (
int i=0; i<4; i++) {
1696 spriteVertices[i].animX1 = x1;
1697 spriteVertices[i].animY1 = y;
1698 spriteVertices[i].animX2 = x2;
1699 spriteVertices[i].animW = w;
1700 spriteVertices[i].animH = h;
1701 spriteVertices[i].animProgress = progress;
1707void QQuickImageParticle::spriteAdvance(
int spriteIdx)
1709 if (!m_startsIdx.size())
1714 for (i = 0; i<m_startsIdx.size(); i++) {
1715 if (spriteIdx < m_startsIdx[i].first) {
1716 gIdx = m_startsIdx[i-1].second;
1721 gIdx = m_startsIdx[i-1].second;
1722 int pIdx = spriteIdx - m_startsIdx[i-1].first;
1724 QQuickParticleData* mainDatum = m_system->groupData[gIdx]->data[pIdx];
1725 QQuickParticleData* datum = (mainDatum->animationOwner ==
this ? mainDatum : getShadowDatum(mainDatum));
1727 datum->animIdx = m_spriteEngine->spriteState(spriteIdx);
1728 datum->animT = m_spriteEngine->spriteStart(spriteIdx)/1000.0;
1729 datum->frameCount = m_spriteEngine->spriteFrames(spriteIdx);
1730 datum->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / datum->frameCount;
1731 datum->animX = m_spriteEngine->spriteX(spriteIdx);
1732 datum->animY = m_spriteEngine->spriteY(spriteIdx);
1733 datum->animWidth = m_spriteEngine->spriteWidth(spriteIdx);
1734 datum->animHeight = m_spriteEngine->spriteHeight(spriteIdx);
1737void QQuickImageParticle::initialize(
int gIdx,
int pIdx)
1740 QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
1741 qreal redVariation = m_color_variation + m_redVariation;
1742 qreal greenVariation = m_color_variation + m_greenVariation;
1743 qreal blueVariation = m_color_variation + m_blueVariation;
1745 if (m_spriteEngine) {
1746 spriteIdx = m_idxStarts[gIdx] + datum->index;
1747 if (spriteIdx >= m_spriteEngine->count())
1748 m_spriteEngine->setCount(spriteIdx+1);
1752 float rotationVelocity;
1757 if (m_explicitAnimation && m_spriteEngine){
1758 if (!datum->animationOwner)
1759 datum->animationOwner =
this;
1760 QQuickParticleData* writeTo = (datum->animationOwner ==
this ? datum : getShadowDatum(datum));
1761 writeTo->animT = writeTo->t;
1763 if (m_spriteEngine){
1764 m_spriteEngine->start(spriteIdx);
1765 writeTo->frameCount = m_spriteEngine->spriteFrames(spriteIdx);
1766 writeTo->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / writeTo->frameCount;
1767 writeTo->animIdx = 0;
1768 writeTo->frameAt = -1;
1769 writeTo->animX = m_spriteEngine->spriteX(spriteIdx);
1770 writeTo->animY = m_spriteEngine->spriteY(spriteIdx);
1771 writeTo->animWidth = m_spriteEngine->spriteWidth(spriteIdx);
1772 writeTo->animHeight = m_spriteEngine->spriteHeight(spriteIdx);
1775 ImageMaterialData *state = getState(m_material);
1776 QQuickParticleData* writeTo = getShadowDatum(datum);
1777 writeTo->animT = datum->t;
1778 writeTo->frameCount = 1;
1779 writeTo->frameDuration = 60000000.0;
1780 writeTo->frameAt = -1;
1781 writeTo->animIdx = 0;
1783 writeTo->animX = writeTo->animY = 0;
1784 writeTo->animWidth = state->animSheetSize.width();
1785 writeTo->animHeight = state->animSheetSize.height();
1791 if (m_explicitDeformation){
1792 if (!datum->deformationOwner)
1793 datum->deformationOwner =
this;
1795 const QPointF &ret = m_xVector->sample(QPointF(datum->x, datum->y));
1796 if (datum->deformationOwner ==
this) {
1797 datum->xx = ret.x();
1798 datum->xy = ret.y();
1800 QQuickParticleData* shadow = getShadowDatum(datum);
1801 shadow->xx = ret.x();
1802 shadow->xy = ret.y();
1806 const QPointF &ret = m_yVector->sample(QPointF(datum->x, datum->y));
1807 if (datum->deformationOwner ==
this) {
1808 datum->yx = ret.x();
1809 datum->yy = ret.y();
1811 QQuickParticleData* shadow = getShadowDatum(datum);
1812 shadow->yx = ret.x();
1813 shadow->yy = ret.y();
1818 if (m_explicitRotation){
1819 if (!datum->rotationOwner)
1820 datum->rotationOwner =
this;
1821 rotation = qDegreesToRadians(
1822 m_rotation + (m_rotationVariation
1823 - 2 * QRandomGenerator::global()->bounded(m_rotationVariation)));
1824 rotationVelocity = qDegreesToRadians(
1826 + (m_rotationVelocityVariation
1827 - 2 * QRandomGenerator::global()->bounded(m_rotationVelocityVariation)));
1828 autoRotate = m_autoRotation ? 1 : 0;
1829 if (datum->rotationOwner ==
this) {
1830 datum->rotation = rotation;
1831 datum->rotationVelocity = rotationVelocity;
1832 datum->autoRotate = autoRotate;
1834 QQuickParticleData* shadow = getShadowDatum(datum);
1835 shadow->rotation = rotation;
1836 shadow->rotationVelocity = rotationVelocity;
1837 shadow->autoRotate = autoRotate;
1846 if (m_explicitColor) {
1847 if (!datum->colorOwner)
1848 datum->colorOwner =
this;
1849 const auto rgbColor = m_color.toRgb();
1850 color.r = rgbColor.red() * (1 - redVariation) + QRandomGenerator::global()->bounded(256) * redVariation;
1851 color.g = rgbColor.green() * (1 - greenVariation) + QRandomGenerator::global()->bounded(256) * greenVariation;
1852 color.b = rgbColor.blue() * (1 - blueVariation) + QRandomGenerator::global()->bounded(256) * blueVariation;
1853 color.a = m_alpha * rgbColor.alpha() * (1 - m_alphaVariation) + QRandomGenerator::global()->bounded(256) * m_alphaVariation;
1854 if (datum->colorOwner ==
this)
1855 datum->color = color;
1857 getShadowDatum(datum)->color = color;
1865void QQuickImageParticle::commit(
int gIdx,
int pIdx)
1869 QSGGeometryNode *node = m_nodes[gIdx];
1872 QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
1873 SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData();
1874 DeformableVertex *deformableVertices = (DeformableVertex *) node->geometry()->vertexData();
1875 ColoredVertex *coloredVertices = (ColoredVertex *) node->geometry()->vertexData();
1876 ColoredPointVertex *coloredPointVertices = (ColoredPointVertex *) node->geometry()->vertexData();
1877 SimplePointVertex *simplePointVertices = (SimplePointVertex *) node->geometry()->vertexData();
1880 spriteVertices += pIdx*4;
1881 for (
int i=0; i<4; i++){
1882 spriteVertices[i].x = datum->x - m_systemOffset.x();
1883 spriteVertices[i].y = datum->y - m_systemOffset.y();
1884 spriteVertices[i].t = datum->t;
1885 spriteVertices[i].lifeSpan = datum->lifeSpan;
1886 spriteVertices[i].size = datum->size;
1887 spriteVertices[i].endSize = datum->endSize;
1888 spriteVertices[i].vx = datum->vx;
1889 spriteVertices[i].vy = datum->vy;
1890 spriteVertices[i].ax = datum->ax;
1891 spriteVertices[i].ay = datum->ay;
1892 if (m_explicitDeformation && datum->deformationOwner !=
this) {
1893 QQuickParticleData* shadow = getShadowDatum(datum);
1894 spriteVertices[i].xx = shadow->xx;
1895 spriteVertices[i].xy = shadow->xy;
1896 spriteVertices[i].yx = shadow->yx;
1897 spriteVertices[i].yy = shadow->yy;
1899 spriteVertices[i].xx = datum->xx;
1900 spriteVertices[i].xy = datum->xy;
1901 spriteVertices[i].yx = datum->yx;
1902 spriteVertices[i].yy = datum->yy;
1904 if (m_explicitRotation && datum->rotationOwner !=
this) {
1905 QQuickParticleData* shadow = getShadowDatum(datum);
1906 spriteVertices[i].rotation = shadow->rotation;
1907 spriteVertices[i].rotationVelocity = shadow->rotationVelocity;
1908 spriteVertices[i].autoRotate = shadow->autoRotate;
1910 spriteVertices[i].rotation = datum->rotation;
1911 spriteVertices[i].rotationVelocity = datum->rotationVelocity;
1912 spriteVertices[i].autoRotate = datum->autoRotate;
1915 if (m_explicitColor && datum->colorOwner !=
this) {
1916 QQuickParticleData* shadow = getShadowDatum(datum);
1917 spriteVertices[i].color = shadow->color;
1919 spriteVertices[i].color = datum->color;
1925 deformableVertices += pIdx*4;
1926 for (
int i=0; i<4; i++){
1927 deformableVertices[i].x = datum->x - m_systemOffset.x();
1928 deformableVertices[i].y = datum->y - m_systemOffset.y();
1929 deformableVertices[i].t = datum->t;
1930 deformableVertices[i].lifeSpan = datum->lifeSpan;
1931 deformableVertices[i].size = datum->size;
1932 deformableVertices[i].endSize = datum->endSize;
1933 deformableVertices[i].vx = datum->vx;
1934 deformableVertices[i].vy = datum->vy;
1935 deformableVertices[i].ax = datum->ax;
1936 deformableVertices[i].ay = datum->ay;
1937 if (m_explicitDeformation && datum->deformationOwner !=
this) {
1938 QQuickParticleData* shadow = getShadowDatum(datum);
1939 deformableVertices[i].xx = shadow->xx;
1940 deformableVertices[i].xy = shadow->xy;
1941 deformableVertices[i].yx = shadow->yx;
1942 deformableVertices[i].yy = shadow->yy;
1944 deformableVertices[i].xx = datum->xx;
1945 deformableVertices[i].xy = datum->xy;
1946 deformableVertices[i].yx = datum->yx;
1947 deformableVertices[i].yy = datum->yy;
1949 if (m_explicitRotation && datum->rotationOwner !=
this) {
1950 QQuickParticleData* shadow = getShadowDatum(datum);
1951 deformableVertices[i].rotation = shadow->rotation;
1952 deformableVertices[i].rotationVelocity = shadow->rotationVelocity;
1953 deformableVertices[i].autoRotate = shadow->autoRotate;
1955 deformableVertices[i].rotation = datum->rotation;
1956 deformableVertices[i].rotationVelocity = datum->rotationVelocity;
1957 deformableVertices[i].autoRotate = datum->autoRotate;
1959 if (m_explicitColor && datum->colorOwner !=
this) {
1960 QQuickParticleData* shadow = getShadowDatum(datum);
1961 deformableVertices[i].color = shadow->color;
1963 deformableVertices[i].color = datum->color;
1968 coloredVertices += pIdx*4;
1969 for (
int i=0; i<4; i++){
1970 coloredVertices[i].x = datum->x - m_systemOffset.x();
1971 coloredVertices[i].y = datum->y - m_systemOffset.y();
1972 coloredVertices[i].t = datum->t;
1973 coloredVertices[i].lifeSpan = datum->lifeSpan;
1974 coloredVertices[i].size = datum->size;
1975 coloredVertices[i].endSize = datum->endSize;
1976 coloredVertices[i].vx = datum->vx;
1977 coloredVertices[i].vy = datum->vy;
1978 coloredVertices[i].ax = datum->ax;
1979 coloredVertices[i].ay = datum->ay;
1980 if (m_explicitColor && datum->colorOwner !=
this) {
1981 QQuickParticleData* shadow = getShadowDatum(datum);
1982 coloredVertices[i].color = shadow->color;
1984 coloredVertices[i].color = datum->color;
1989 coloredPointVertices += pIdx*1;
1990 for (
int i=0; i<1; i++){
1991 coloredPointVertices[i].x = datum->x - m_systemOffset.x();
1992 coloredPointVertices[i].y = datum->y - m_systemOffset.y();
1993 coloredPointVertices[i].t = datum->t;
1994 coloredPointVertices[i].lifeSpan = datum->lifeSpan;
1995 coloredPointVertices[i].size = datum->size;
1996 coloredPointVertices[i].endSize = datum->endSize;
1997 coloredPointVertices[i].vx = datum->vx;
1998 coloredPointVertices[i].vy = datum->vy;
1999 coloredPointVertices[i].ax = datum->ax;
2000 coloredPointVertices[i].ay = datum->ay;
2001 if (m_explicitColor && datum->colorOwner !=
this) {
2002 QQuickParticleData* shadow = getShadowDatum(datum);
2003 coloredPointVertices[i].color = shadow->color;
2005 coloredPointVertices[i].color = datum->color;
2010 simplePointVertices += pIdx*1;
2011 for (
int i=0; i<1; i++){
2012 simplePointVertices[i].x = datum->x - m_systemOffset.x();
2013 simplePointVertices[i].y = datum->y - m_systemOffset.y();
2014 simplePointVertices[i].t = datum->t;
2015 simplePointVertices[i].lifeSpan = datum->lifeSpan;
2016 simplePointVertices[i].size = datum->size;
2017 simplePointVertices[i].endSize = datum->endSize;
2018 simplePointVertices[i].vx = datum->vx;
2019 simplePointVertices[i].vy = datum->vy;
2020 simplePointVertices[i].ax = datum->ax;
2021 simplePointVertices[i].ay = datum->ay;
2033#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