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
552
553
554
555
556
557
559
560
561
562
563
564
566
567
568
569
570
571
572
573
574
575
576
577
579
580
581
582
583
584
585
587
588
589
590
591
592
593
595
596
597
598
599
600
601
603
604
605
606
607
608
609
610
611
612
613
615
616
617
618
619
620
621
623
624
625
626
627
628
630
631
632
633
634
635
637
638
639
640
642
643
644
645
646
647
649
650
651
652
653
654
655
656
658
659
660
661
662
663
665
666
667
668
669
670
672
673
674
675
676
677
678
679
680
681
682
683
684
686
687
688
689
690
691
692
695
696
697
698
701QQuickImageParticle::QQuickImageParticle(QQuickItem* parent)
702 : QQuickParticlePainter(parent)
703 , m_color_variation(0.0)
704 , m_outgoingNode(
nullptr)
705 , m_material(
nullptr)
706 , m_alphaVariation(0.0)
708 , m_redVariation(0.0)
709 , m_greenVariation(0.0)
710 , m_blueVariation(0.0)
712 , m_rotationVariation(0)
713 , m_rotationVelocity(0)
714 , m_rotationVelocityVariation(0)
715 , m_autoRotation(
false)
718 , m_spriteEngine(
nullptr)
719 , m_spritesInterpolate(
true)
720 , m_explicitColor(
false)
721 , m_explicitRotation(
false)
722 , m_explicitDeformation(
false)
723 , m_explicitAnimation(
false)
724 , m_bypassOptimizations(
false)
726 , m_targetPerfLevel(Unknown)
728 , m_entryEffect(Fade)
729 , m_startedImageLoading(0)
731 , m_apiChecked(
false)
733 , m_previousActive(
false)
735 setFlag(ItemHasContents);
738QQuickImageParticle::~QQuickImageParticle()
743QQmlListProperty<QQuickSprite> QQuickImageParticle::sprites()
745 return QQmlListProperty<QQuickSprite>(
this, &m_sprites,
746 spriteAppend, spriteCount, spriteAt,
747 spriteClear, spriteReplace, spriteRemoveLast);
750void QQuickImageParticle::sceneGraphInvalidated()
753 m_material =
nullptr;
754 delete m_outgoingNode;
755 m_outgoingNode =
nullptr;
756 m_apiChecked =
false;
759void QQuickImageParticle::setImage(
const QUrl &image)
761 if (image.isEmpty()){
770 m_image.reset(
new ImageData);
771 if (image == m_image->source)
773 m_image->source = image;
779void QQuickImageParticle::setColortable(
const QUrl &table)
781 if (table.isEmpty()){
783 m_colorTable.reset();
784 emit colortableChanged();
790 m_colorTable.reset(
new ImageData);
791 if (table == m_colorTable->source)
793 m_colorTable->source = table;
794 emit colortableChanged();
798void QQuickImageParticle::setSizetable(
const QUrl &table)
800 if (table.isEmpty()){
803 emit sizetableChanged();
809 m_sizeTable.reset(
new ImageData);
810 if (table == m_sizeTable->source)
812 m_sizeTable->source = table;
813 emit sizetableChanged();
817void QQuickImageParticle::setOpacitytable(
const QUrl &table)
819 if (table.isEmpty()){
820 if (m_opacityTable) {
821 m_opacityTable.reset();
822 emit opacitytableChanged();
828 m_opacityTable.reset(
new ImageData);
829 if (table == m_opacityTable->source)
831 m_opacityTable->source = table;
832 emit opacitytableChanged();
836void QQuickImageParticle::setColor(
const QColor &color)
838 if (color == m_color)
842 m_explicitColor =
true;
843 checkPerfLevel(ColoredPoint);
846void QQuickImageParticle::setColorVariation(qreal var)
848 if (var == m_color_variation)
850 m_color_variation = var;
851 emit colorVariationChanged();
852 m_explicitColor =
true;
853 checkPerfLevel(ColoredPoint);
856void QQuickImageParticle::setAlphaVariation(qreal arg)
858 if (m_alphaVariation != arg) {
859 m_alphaVariation = arg;
860 emit alphaVariationChanged(arg);
862 m_explicitColor =
true;
863 checkPerfLevel(ColoredPoint);
866void QQuickImageParticle::setAlpha(qreal arg)
868 if (m_alpha != arg) {
870 emit alphaChanged(arg);
872 m_explicitColor =
true;
873 checkPerfLevel(ColoredPoint);
876void QQuickImageParticle::setRedVariation(qreal arg)
878 if (m_redVariation != arg) {
879 m_redVariation = arg;
880 emit redVariationChanged(arg);
882 m_explicitColor =
true;
883 checkPerfLevel(ColoredPoint);
886void QQuickImageParticle::setGreenVariation(qreal arg)
888 if (m_greenVariation != arg) {
889 m_greenVariation = arg;
890 emit greenVariationChanged(arg);
892 m_explicitColor =
true;
893 checkPerfLevel(ColoredPoint);
896void QQuickImageParticle::setBlueVariation(qreal arg)
898 if (m_blueVariation != arg) {
899 m_blueVariation = arg;
900 emit blueVariationChanged(arg);
902 m_explicitColor =
true;
903 checkPerfLevel(ColoredPoint);
906void QQuickImageParticle::setRotation(qreal arg)
908 if (m_rotation != arg) {
910 emit rotationChanged(arg);
912 m_explicitRotation =
true;
913 checkPerfLevel(Deformable);
916void QQuickImageParticle::setRotationVariation(qreal arg)
918 if (m_rotationVariation != arg) {
919 m_rotationVariation = arg;
920 emit rotationVariationChanged(arg);
922 m_explicitRotation =
true;
923 checkPerfLevel(Deformable);
926void QQuickImageParticle::setRotationVelocity(qreal arg)
928 if (m_rotationVelocity != arg) {
929 m_rotationVelocity = arg;
930 emit rotationVelocityChanged(arg);
932 m_explicitRotation =
true;
933 checkPerfLevel(Deformable);
936void QQuickImageParticle::setRotationVelocityVariation(qreal arg)
938 if (m_rotationVelocityVariation != arg) {
939 m_rotationVelocityVariation = arg;
940 emit rotationVelocityVariationChanged(arg);
942 m_explicitRotation =
true;
943 checkPerfLevel(Deformable);
946void QQuickImageParticle::setAutoRotation(
bool arg)
948 if (m_autoRotation != arg) {
949 m_autoRotation = arg;
950 emit autoRotationChanged(arg);
952 m_explicitRotation =
true;
953 checkPerfLevel(Deformable);
956void QQuickImageParticle::setXVector(QQuickDirection* arg)
958 if (m_xVector != arg) {
960 emit xVectorChanged(arg);
962 m_explicitDeformation =
true;
963 checkPerfLevel(Deformable);
966void QQuickImageParticle::setYVector(QQuickDirection* arg)
968 if (m_yVector != arg) {
970 emit yVectorChanged(arg);
972 m_explicitDeformation =
true;
973 checkPerfLevel(Deformable);
976void QQuickImageParticle::setSpritesInterpolate(
bool arg)
978 if (m_spritesInterpolate != arg) {
979 m_spritesInterpolate = arg;
980 emit spritesInterpolateChanged(arg);
984void QQuickImageParticle::setBypassOptimizations(
bool arg)
986 if (m_bypassOptimizations != arg) {
987 m_bypassOptimizations = arg;
988 emit bypassOptimizationsChanged(arg);
994void QQuickImageParticle::setEntryEffect(EntryEffect arg)
996 if (m_entryEffect != arg) {
999 getState(m_material)->entry = (qreal) m_entryEffect;
1000 emit entryEffectChanged(arg);
1004void QQuickImageParticle::resetColor()
1006 m_explicitColor =
false;
1007 for (
auto groupId : groupIds()) {
1008 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
1009 if (d->colorOwner ==
this) {
1010 d->colorOwner =
nullptr;
1015 m_color_variation = 0.0f;
1016 m_redVariation = 0.0f;
1017 m_blueVariation = 0.0f;
1018 m_greenVariation = 0.0f;
1020 m_alphaVariation = 0.0f;
1023void QQuickImageParticle::resetRotation()
1025 m_explicitRotation =
false;
1026 for (
auto groupId : groupIds()) {
1027 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
1028 if (d->rotationOwner ==
this) {
1029 d->rotationOwner =
nullptr;
1034 m_rotationVariation = 0;
1035 m_rotationVelocity = 0;
1036 m_rotationVelocityVariation = 0;
1037 m_autoRotation =
false;
1040void QQuickImageParticle::resetDeformation()
1042 m_explicitDeformation =
false;
1043 for (
auto groupId : groupIds()) {
1044 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
1045 if (d->deformationOwner ==
this) {
1046 d->deformationOwner =
nullptr;
1054 m_xVector =
nullptr;
1055 m_yVector =
nullptr;
1058void QQuickImageParticle::reset()
1060 QQuickParticlePainter::reset();
1061 m_pleaseReset =
true;
1066void QQuickImageParticle::invalidateSceneGraph()
1071void QQuickImageParticle::createEngine()
1074 delete m_spriteEngine;
1075 if (m_sprites.size()) {
1076 m_spriteEngine =
new QQuickSpriteEngine(m_sprites,
this);
1077 connect(m_spriteEngine, &QQuickStochasticEngine::stateChanged,
1078 this, &QQuickImageParticle::spriteAdvance, Qt::DirectConnection);
1079 m_explicitAnimation =
true;
1081 m_spriteEngine =
nullptr;
1082 m_explicitAnimation =
false;
1088 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType,
true),
1089 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1090 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType)
1096 ( 2 + 4 + 4 ) *
sizeof(
float),
1097 SimplePointParticle_Attributes
1101 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType,
true),
1102 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1103 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1104 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1110 ( 2 + 4 + 4 ) *
sizeof(
float) + 4 *
sizeof(uchar),
1111 ColoredPointParticle_Attributes
1115 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType,
true),
1116 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1117 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1118 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1119 QSGGeometry::Attribute::create(4, 4, QSGGeometry::UnsignedByteType),
1125 ( 2 + 4 + 4 ) *
sizeof(
float) + (4 + 4) *
sizeof(uchar),
1126 ColoredParticle_Attributes
1130 QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType),
1131 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1132 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1133 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1134 QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType),
1135 QSGGeometry::Attribute::create(5, 4, QSGGeometry::UnsignedByteType),
1141 (4 + 4 + 4 + 4) *
sizeof(
float) + (4 + 4) *
sizeof(uchar),
1142 DeformableParticle_Attributes
1146 QSGGeometry::Attribute::create(0, 4, QSGGeometry::FloatType),
1147 QSGGeometry::Attribute::create(1, 4, QSGGeometry::FloatType),
1148 QSGGeometry::Attribute::create(2, 4, QSGGeometry::FloatType),
1149 QSGGeometry::Attribute::create(3, 4, QSGGeometry::UnsignedByteType),
1150 QSGGeometry::Attribute::create(4, 4, QSGGeometry::FloatType),
1151 QSGGeometry::Attribute::create(5, 4, QSGGeometry::UnsignedByteType),
1152 QSGGeometry::Attribute::create(6, 3, QSGGeometry::FloatType),
1153 QSGGeometry::Attribute::create(7, 3, QSGGeometry::FloatType)
1159 (4 + 4 + 4 + 4 + 3 + 3) *
sizeof(
float) + (4 + 4) *
sizeof(uchar),
1160 SpriteParticle_Attributes
1163void QQuickImageParticle::clearShadows()
1165 foreach (
const QList<QQuickParticleData*> data, m_shadowData)
1167 m_shadowData.clear();
1171QQuickParticleData* QQuickImageParticle::getShadowDatum(QQuickParticleData* datum)
1174 if (datum->systemIndex == -1)
1176 if (!m_shadowData.contains(datum->groupId)) {
1177 QQuickParticleGroupData* gd = m_system->groupData[datum->groupId];
1178 QList<QQuickParticleData*> data;
1179 const int gdSize = gd->size();
1180 data.reserve(gdSize);
1181 for (
int i = 0; i < gdSize; i++) {
1182 QQuickParticleData* datum =
new QQuickParticleData;
1183 *datum = *(gd->data[i]);
1186 m_shadowData.insert(datum->groupId, data);
1190 return m_shadowData[datum->groupId][datum->index];
1193void QQuickImageParticle::checkPerfLevel(PerformanceLevel level)
1195 if (m_targetPerfLevel < level) {
1196 m_targetPerfLevel = level;
1201bool QQuickImageParticle::loadingSomething()
1203 return (m_image && m_image->pix.isLoading())
1204 || (m_colorTable && m_colorTable->pix.isLoading())
1205 || (m_sizeTable && m_sizeTable->pix.isLoading())
1206 || (m_opacityTable && m_opacityTable->pix.isLoading())
1207 || (m_spriteEngine && m_spriteEngine->isLoading());
1210void QQuickImageParticle::mainThreadFetchImageData()
1212 const QQmlContext *context =
nullptr;
1213 QQmlEngine *engine =
nullptr;
1214 const auto loadPix = [&](ImageData *image) {
1216 context = qmlContext(
this);
1217 engine = context->engine();
1219 image->pix.load(engine, context->resolvedUrl(image->source));
1224 m_image->pix.clear(
this);
1225 loadPix(m_image.get());
1229 m_spriteEngine->startAssemblingImage();
1232 loadPix(m_colorTable.get());
1235 loadPix(m_sizeTable.get());
1238 loadPix(m_opacityTable.get());
1240 m_startedImageLoading = 2;
1243void QQuickImageParticle::buildParticleNodes(QSGNode** passThrough)
1247 if (*passThrough || loadingSomething())
1250 if (m_startedImageLoading == 0) {
1251 m_startedImageLoading = 1;
1253 QQuickImageParticle::staticMetaObject.invokeMethod(
this,
"mainThreadFetchImageData", Qt::QueuedConnection);
1254 }
else if (m_startedImageLoading == 2) {
1255 finishBuildParticleNodes(passThrough);
1261void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
1266 if (m_count * 4 > 0xffff) {
1268 qmlInfo(
this) <<
"ImageParticle: Too many particles - maximum 16383 per ImageParticle";
1275 m_debugMode = m_system->m_debugMode;
1277 if (m_sprites.size() || m_bypassOptimizations) {
1278 perfLevel = Sprites;
1279 }
else if (m_colorTable || m_sizeTable || m_opacityTable) {
1281 }
else if (m_autoRotation || m_rotation || m_rotationVariation
1282 || m_rotationVelocity || m_rotationVelocityVariation
1283 || m_xVector || m_yVector) {
1284 perfLevel = Deformable;
1285 }
else if (m_alphaVariation || m_alpha != 1.0 || m_color.isValid() || m_color_variation
1286 || m_redVariation || m_blueVariation || m_greenVariation) {
1287 perfLevel = ColoredPoint;
1289 perfLevel = SimplePoint;
1292 for (
auto groupId : groupIds()) {
1294 for (QQuickParticlePainter* p : std::as_const(m_system->groupData[groupId]->painters)) {
1295 QQuickImageParticle* other = qobject_cast<QQuickImageParticle*>(p);
1297 if (other->perfLevel > perfLevel) {
1298 if (other->perfLevel >= Tabled){
1299 if (perfLevel < Deformable)
1300 perfLevel = Deformable;
1302 perfLevel = other->perfLevel;
1304 }
else if (other->perfLevel < perfLevel) {
1314 if (perfLevel < Colored && !m_rhi->isFeatureSupported(QRhi::VertexShaderPointSize))
1315 perfLevel = Colored;
1317 if (perfLevel >= ColoredPoint && !m_color.isValid())
1318 m_color = QColor(Qt::white);
1320 m_targetPerfLevel = perfLevel;
1324 m_material =
nullptr;
1329 QImage opacitytable;
1331 bool imageLoaded =
false;
1332 switch (perfLevel) {
1335 if (!m_spriteEngine) {
1336 qWarning() <<
"ImageParticle: No sprite engine...";
1340 image = m_spriteEngine->assembledImage();
1345 m_material =
new SpriteMaterial;
1346 ImageMaterialData *state = getState(m_material);
1348 state->texture = QSGPlainTexture::fromImage(image);
1349 state->animSheetSize = QSizeF(image.size() / image.devicePixelRatio());
1351 m_spriteEngine->setCount(m_count);
1357 m_material =
new TabledMaterial;
1360 if (m_colorTable->pix.isReady())
1361 colortable = m_colorTable->pix.image();
1363 qmlWarning(
this) <<
"Error loading color table: " << m_colorTable->pix.error();
1367 if (m_sizeTable->pix.isReady())
1368 sizetable = m_sizeTable->pix.image();
1370 qmlWarning(
this) <<
"Error loading size table: " << m_sizeTable->pix.error();
1373 if (m_opacityTable) {
1374 if (m_opacityTable->pix.isReady())
1375 opacitytable = m_opacityTable->pix.image();
1377 qmlWarning(
this) <<
"Error loading opacity table: " << m_opacityTable->pix.error();
1380 if (colortable.isNull()){
1381 colortable = QImage(1,1,QImage::Format_ARGB32_Premultiplied);
1382 colortable.fill(Qt::white);
1384 ImageMaterialData *state = getState(m_material);
1385 state->colorTable = QSGPlainTexture::fromImage(colortable);
1393 m_material =
new DeformableMaterial;
1399 m_material =
new ColoredMaterial;
1405 m_material =
new ColoredPointMaterial;
1411 m_material =
new SimplePointMaterial;
1412 ImageMaterialData *state = getState(m_material);
1414 if (!m_image || !m_image->pix.isReady()) {
1416 qmlWarning(
this) << m_image->pix.error();
1422 state->texture = QSGPlainTexture::fromImage(m_image->pix.image());
1424 state->texture->setFiltering(QSGTexture::Linear);
1425 state->entry = (qreal) m_entryEffect;
1428 m_material->setFlag(QSGMaterial::Blending | QSGMaterial::RequiresFullMatrix);
1433 for (
auto groupId : groupIds()) {
1434 int count = m_system->groupData[groupId]->size();
1435 QSGGeometryNode* node =
new QSGGeometryNode();
1436 node->setMaterial(m_material);
1437 node->markDirty(QSGNode::DirtyMaterial);
1439 m_nodes.insert(groupId, node);
1440 m_idxStarts.insert(groupId, m_lastIdxStart);
1441 m_startsIdx.append(std::make_pair(m_lastIdxStart, groupId));
1442 m_lastIdxStart += count;
1445 int vCount = count * 4;
1446 int iCount = count * 6;
1449 if (perfLevel == Sprites)
1450 g =
new QSGGeometry(SpriteParticle_AttributeSet, vCount, iCount);
1451 else if (perfLevel == Tabled)
1452 g =
new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount);
1453 else if (perfLevel == Deformable)
1454 g =
new QSGGeometry(DeformableParticle_AttributeSet, vCount, iCount);
1455 else if (perfLevel == Colored)
1456 g =
new QSGGeometry(ColoredParticle_AttributeSet, vCount, iCount);
1457 else if (perfLevel == ColoredPoint)
1458 g =
new QSGGeometry(ColoredPointParticle_AttributeSet, count, 0);
1460 g =
new QSGGeometry(SimplePointParticle_AttributeSet, count, 0);
1462 node->setFlag(QSGNode::OwnsGeometry);
1463 node->setGeometry(g);
1464 if (perfLevel <= ColoredPoint){
1465 g->setDrawingMode(QSGGeometry::DrawPoints);
1467 qDebug(
"Using point sprites");
1469 g->setDrawingMode(QSGGeometry::DrawTriangles);
1472 for (
int p=0; p < count; ++p)
1475 if (perfLevel == Sprites)
1476 initTexCoords<SpriteVertex>((SpriteVertex*)g->vertexData(), vCount);
1477 else if (perfLevel == Tabled)
1478 initTexCoords<DeformableVertex>((DeformableVertex*)g->vertexData(), vCount);
1479 else if (perfLevel == Deformable)
1480 initTexCoords<DeformableVertex>((DeformableVertex*)g->vertexData(), vCount);
1481 else if (perfLevel == Colored)
1482 initTexCoords<ColoredVertex>((ColoredVertex*)g->vertexData(), vCount);
1484 if (perfLevel > ColoredPoint){
1485 quint16 *indices = g->indexDataAsUShort();
1486 for (
int i=0; i < count; ++i) {
1499 if (perfLevel == Sprites)
1502 foreach (QSGGeometryNode* node, m_nodes){
1503 if (node == *(m_nodes.begin()))
1504 node->setFlag(QSGGeometryNode::OwnsMaterial);
1506 (*(m_nodes.begin()))->appendChildNode(node);
1509 *node = *(m_nodes.begin());
1513QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
1515 if (!m_apiChecked || m_windowChanged) {
1516 m_apiChecked =
true;
1517 m_windowChanged =
false;
1519 QSGRenderContext *rc = QQuickItemPrivate::get(
this)->sceneGraphRenderContext();
1520 QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc);
1524 QSGRendererInterface::GraphicsApi api = rif->graphicsApi();
1525 const bool isRhi = QSGRendererInterface::isApiRhiBased(api);
1527 if (!node && !isRhi)
1531 m_rhi =
static_cast<QRhi *>(rif->getResource(m_window, QSGRendererInterface::RhiResource));
1535 if (isRhi && !m_rhi) {
1536 qWarning(
"Failed to query QRhi, particles disabled");
1540 m_dpr = m_window ? m_window->devicePixelRatio() : 1.0;
1547 delete m_outgoingNode;
1548 m_outgoingNode = node;
1553 m_idxStarts.clear();
1554 m_startsIdx.clear();
1557 m_material =
nullptr;
1559 m_pleaseReset =
false;
1560 m_startedImageLoading = 0;
1561 }
else if (!m_material) {
1566 if (m_system && m_system->isRunning() && !m_system->isPaused()){
1567 bool dirty = prepareNextFrame(&node);
1571 foreach (QSGGeometryNode* n, m_nodes)
1572 n->markDirty(QSGNode::DirtyGeometry);
1574 }
else if (m_startedImageLoading < 2) {
1580 node = m_outgoingNode;
1581 m_outgoingNode =
nullptr;
1587bool QQuickImageParticle::prepareNextFrame(QSGNode **node)
1589 if (*node ==
nullptr){
1590 buildParticleNodes(node);
1592 qDebug() <<
"QQuickImageParticle Feature level: " << perfLevel;
1593 qDebug() <<
"QQuickImageParticle Nodes: ";
1595 for (
auto it = m_nodes.keyBegin(), end = m_nodes.keyEnd(); it != end; ++it) {
1596 qDebug() <<
"Group " << *it <<
" (" << m_system->groupData[*it]->size()
1598 count += m_system->groupData[*it]->size();
1600 qDebug() <<
"Total count: " << count;
1602 if (*node ==
nullptr)
1605 qint64 timeStamp = m_system->systemSync(
this);
1607 qreal time = timeStamp / 1000.;
1613 m_spriteEngine->updateSprites(timeStamp);
1614 spritesUpdate(time);
1622 getState(m_material)->timestamp = time;
1626 bool active =
false;
1627 for (
auto groupId : groupIds()) {
1628 if (m_system->groupData[groupId]->isActive()) {
1634 const bool dirty = active || m_previousActive;
1636 foreach (QSGGeometryNode* node, m_nodes)
1637 node->markDirty(QSGNode::DirtyMaterial);
1640 m_previousActive = active;
1644void QQuickImageParticle::spritesUpdate(qreal time)
1646 ImageMaterialData *state = getState(m_material);
1648 for (
auto groupId : groupIds()) {
1649 for (QQuickParticleData* mainDatum : std::as_const(m_system->groupData[groupId]->data)) {
1650 QSGGeometryNode *node = m_nodes[groupId];
1655 QQuickParticleData* datum = (mainDatum->animationOwner ==
this ? mainDatum : getShadowDatum(mainDatum));
1657 for (
int i = 0; i<m_startsIdx.size(); i++) {
1658 if (m_startsIdx[i].second == groupId){
1659 spriteIdx = m_startsIdx[i].first + datum->index;
1667 if (datum->frameDuration > 0) {
1668 qreal frame = (time - datum->animT)/(datum->frameDuration / 1000.0);
1669 frame = qBound((qreal)0.0, frame, (qreal)((qreal)datum->frameCount - 1.0));
1670 if (m_spritesInterpolate)
1671 progress = std::modf(frame,&frameAt);
1673 std::modf(frame,&frameAt);
1676 if (datum->frameAt >= datum->frameCount){
1678 m_spriteEngine->advance(spriteIdx);
1680 frameAt = datum->frameAt;
1682 if (m_spriteEngine->sprite(spriteIdx)->reverse())
1683 frameAt = (datum->frameCount - 1) - frameAt;
1684 QSizeF sheetSize = state->animSheetSize;
1685 qreal y = datum->animY / sheetSize.height();
1686 qreal w = datum->animWidth / sheetSize.width();
1687 qreal h = datum->animHeight / sheetSize.height();
1688 qreal x1 = datum->animX / sheetSize.width();
1691 if (frameAt < (datum->frameCount-1))
1694 SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData();
1695 spriteVertices += datum->index*4;
1696 for (
int i=0; i<4; i++) {
1697 spriteVertices[i].animX1 = x1;
1698 spriteVertices[i].animY1 = y;
1699 spriteVertices[i].animX2 = x2;
1700 spriteVertices[i].animW = w;
1701 spriteVertices[i].animH = h;
1702 spriteVertices[i].animProgress = progress;
1708void QQuickImageParticle::spriteAdvance(
int spriteIdx)
1710 if (!m_startsIdx.size())
1715 for (i = 0; i<m_startsIdx.size(); i++) {
1716 if (spriteIdx < m_startsIdx[i].first) {
1717 gIdx = m_startsIdx[i-1].second;
1722 gIdx = m_startsIdx[i-1].second;
1723 int pIdx = spriteIdx - m_startsIdx[i-1].first;
1725 QQuickParticleData* mainDatum = m_system->groupData[gIdx]->data[pIdx];
1726 QQuickParticleData* datum = (mainDatum->animationOwner ==
this ? mainDatum : getShadowDatum(mainDatum));
1728 datum->animIdx = m_spriteEngine->spriteState(spriteIdx);
1729 datum->animT = m_spriteEngine->spriteStart(spriteIdx)/1000.0;
1730 datum->frameCount = m_spriteEngine->spriteFrames(spriteIdx);
1731 datum->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / datum->frameCount;
1732 datum->animX = m_spriteEngine->spriteX(spriteIdx);
1733 datum->animY = m_spriteEngine->spriteY(spriteIdx);
1734 datum->animWidth = m_spriteEngine->spriteWidth(spriteIdx);
1735 datum->animHeight = m_spriteEngine->spriteHeight(spriteIdx);
1738void QQuickImageParticle::initialize(
int gIdx,
int pIdx)
1741 QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
1742 qreal redVariation = m_color_variation + m_redVariation;
1743 qreal greenVariation = m_color_variation + m_greenVariation;
1744 qreal blueVariation = m_color_variation + m_blueVariation;
1746 if (m_spriteEngine) {
1747 spriteIdx = m_idxStarts[gIdx] + datum->index;
1748 if (spriteIdx >= m_spriteEngine->count())
1749 m_spriteEngine->setCount(spriteIdx+1);
1753 float rotationVelocity;
1758 if (m_explicitAnimation && m_spriteEngine){
1759 if (!datum->animationOwner)
1760 datum->animationOwner =
this;
1761 QQuickParticleData* writeTo = (datum->animationOwner ==
this ? datum : getShadowDatum(datum));
1762 writeTo->animT = writeTo->t;
1764 if (m_spriteEngine){
1765 m_spriteEngine->start(spriteIdx);
1766 writeTo->frameCount = m_spriteEngine->spriteFrames(spriteIdx);
1767 writeTo->frameDuration = m_spriteEngine->spriteDuration(spriteIdx) / writeTo->frameCount;
1768 writeTo->animIdx = 0;
1769 writeTo->frameAt = -1;
1770 writeTo->animX = m_spriteEngine->spriteX(spriteIdx);
1771 writeTo->animY = m_spriteEngine->spriteY(spriteIdx);
1772 writeTo->animWidth = m_spriteEngine->spriteWidth(spriteIdx);
1773 writeTo->animHeight = m_spriteEngine->spriteHeight(spriteIdx);
1776 ImageMaterialData *state = getState(m_material);
1777 QQuickParticleData* writeTo = getShadowDatum(datum);
1778 writeTo->animT = datum->t;
1779 writeTo->frameCount = 1;
1780 writeTo->frameDuration = 60000000.0;
1781 writeTo->frameAt = -1;
1782 writeTo->animIdx = 0;
1784 writeTo->animX = writeTo->animY = 0;
1785 writeTo->animWidth = state->animSheetSize.width();
1786 writeTo->animHeight = state->animSheetSize.height();
1792 if (m_explicitDeformation){
1793 if (!datum->deformationOwner)
1794 datum->deformationOwner =
this;
1796 const QPointF &ret = m_xVector->sample(QPointF(datum->x, datum->y));
1797 if (datum->deformationOwner ==
this) {
1798 datum->xx = ret.x();
1799 datum->xy = ret.y();
1801 QQuickParticleData* shadow = getShadowDatum(datum);
1802 shadow->xx = ret.x();
1803 shadow->xy = ret.y();
1807 const QPointF &ret = m_yVector->sample(QPointF(datum->x, datum->y));
1808 if (datum->deformationOwner ==
this) {
1809 datum->yx = ret.x();
1810 datum->yy = ret.y();
1812 QQuickParticleData* shadow = getShadowDatum(datum);
1813 shadow->yx = ret.x();
1814 shadow->yy = ret.y();
1819 if (m_explicitRotation){
1820 if (!datum->rotationOwner)
1821 datum->rotationOwner =
this;
1822 rotation = qDegreesToRadians(
1823 m_rotation + (m_rotationVariation
1824 - 2 * QRandomGenerator::global()->bounded(m_rotationVariation)));
1825 rotationVelocity = qDegreesToRadians(
1827 + (m_rotationVelocityVariation
1828 - 2 * QRandomGenerator::global()->bounded(m_rotationVelocityVariation)));
1829 autoRotate = m_autoRotation ? 1 : 0;
1830 if (datum->rotationOwner ==
this) {
1831 datum->rotation = rotation;
1832 datum->rotationVelocity = rotationVelocity;
1833 datum->autoRotate = autoRotate;
1835 QQuickParticleData* shadow = getShadowDatum(datum);
1836 shadow->rotation = rotation;
1837 shadow->rotationVelocity = rotationVelocity;
1838 shadow->autoRotate = autoRotate;
1847 if (m_explicitColor) {
1848 if (!datum->colorOwner)
1849 datum->colorOwner =
this;
1850 const auto rgbColor = m_color.toRgb();
1851 color.r = rgbColor.red() * (1 - redVariation) + QRandomGenerator::global()->bounded(256) * redVariation;
1852 color.g = rgbColor.green() * (1 - greenVariation) + QRandomGenerator::global()->bounded(256) * greenVariation;
1853 color.b = rgbColor.blue() * (1 - blueVariation) + QRandomGenerator::global()->bounded(256) * blueVariation;
1854 color.a = m_alpha * rgbColor.alpha() * (1 - m_alphaVariation) + QRandomGenerator::global()->bounded(256) * m_alphaVariation;
1855 if (datum->colorOwner ==
this)
1856 datum->color = color;
1858 getShadowDatum(datum)->color = color;
1866void QQuickImageParticle::commit(
int gIdx,
int pIdx)
1870 QSGGeometryNode *node = m_nodes[gIdx];
1873 QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
1874 SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData();
1875 DeformableVertex *deformableVertices = (DeformableVertex *) node->geometry()->vertexData();
1876 ColoredVertex *coloredVertices = (ColoredVertex *) node->geometry()->vertexData();
1877 ColoredPointVertex *coloredPointVertices = (ColoredPointVertex *) node->geometry()->vertexData();
1878 SimplePointVertex *simplePointVertices = (SimplePointVertex *) node->geometry()->vertexData();
1881 spriteVertices += pIdx*4;
1882 for (
int i=0; i<4; i++){
1883 spriteVertices[i].x = datum->x - m_systemOffset.x();
1884 spriteVertices[i].y = datum->y - m_systemOffset.y();
1885 spriteVertices[i].t = datum->t;
1886 spriteVertices[i].lifeSpan = datum->lifeSpan;
1887 spriteVertices[i].size = datum->size;
1888 spriteVertices[i].endSize = datum->endSize;
1889 spriteVertices[i].vx = datum->vx;
1890 spriteVertices[i].vy = datum->vy;
1891 spriteVertices[i].ax = datum->ax;
1892 spriteVertices[i].ay = datum->ay;
1893 if (m_explicitDeformation && datum->deformationOwner !=
this) {
1894 QQuickParticleData* shadow = getShadowDatum(datum);
1895 spriteVertices[i].xx = shadow->xx;
1896 spriteVertices[i].xy = shadow->xy;
1897 spriteVertices[i].yx = shadow->yx;
1898 spriteVertices[i].yy = shadow->yy;
1900 spriteVertices[i].xx = datum->xx;
1901 spriteVertices[i].xy = datum->xy;
1902 spriteVertices[i].yx = datum->yx;
1903 spriteVertices[i].yy = datum->yy;
1905 if (m_explicitRotation && datum->rotationOwner !=
this) {
1906 QQuickParticleData* shadow = getShadowDatum(datum);
1907 spriteVertices[i].rotation = shadow->rotation;
1908 spriteVertices[i].rotationVelocity = shadow->rotationVelocity;
1909 spriteVertices[i].autoRotate = shadow->autoRotate;
1911 spriteVertices[i].rotation = datum->rotation;
1912 spriteVertices[i].rotationVelocity = datum->rotationVelocity;
1913 spriteVertices[i].autoRotate = datum->autoRotate;
1916 if (m_explicitColor && datum->colorOwner !=
this) {
1917 QQuickParticleData* shadow = getShadowDatum(datum);
1918 spriteVertices[i].color = shadow->color;
1920 spriteVertices[i].color = datum->color;
1926 deformableVertices += pIdx*4;
1927 for (
int i=0; i<4; i++){
1928 deformableVertices[i].x = datum->x - m_systemOffset.x();
1929 deformableVertices[i].y = datum->y - m_systemOffset.y();
1930 deformableVertices[i].t = datum->t;
1931 deformableVertices[i].lifeSpan = datum->lifeSpan;
1932 deformableVertices[i].size = datum->size;
1933 deformableVertices[i].endSize = datum->endSize;
1934 deformableVertices[i].vx = datum->vx;
1935 deformableVertices[i].vy = datum->vy;
1936 deformableVertices[i].ax = datum->ax;
1937 deformableVertices[i].ay = datum->ay;
1938 if (m_explicitDeformation && datum->deformationOwner !=
this) {
1939 QQuickParticleData* shadow = getShadowDatum(datum);
1940 deformableVertices[i].xx = shadow->xx;
1941 deformableVertices[i].xy = shadow->xy;
1942 deformableVertices[i].yx = shadow->yx;
1943 deformableVertices[i].yy = shadow->yy;
1945 deformableVertices[i].xx = datum->xx;
1946 deformableVertices[i].xy = datum->xy;
1947 deformableVertices[i].yx = datum->yx;
1948 deformableVertices[i].yy = datum->yy;
1950 if (m_explicitRotation && datum->rotationOwner !=
this) {
1951 QQuickParticleData* shadow = getShadowDatum(datum);
1952 deformableVertices[i].rotation = shadow->rotation;
1953 deformableVertices[i].rotationVelocity = shadow->rotationVelocity;
1954 deformableVertices[i].autoRotate = shadow->autoRotate;
1956 deformableVertices[i].rotation = datum->rotation;
1957 deformableVertices[i].rotationVelocity = datum->rotationVelocity;
1958 deformableVertices[i].autoRotate = datum->autoRotate;
1960 if (m_explicitColor && datum->colorOwner !=
this) {
1961 QQuickParticleData* shadow = getShadowDatum(datum);
1962 deformableVertices[i].color = shadow->color;
1964 deformableVertices[i].color = datum->color;
1969 coloredVertices += pIdx*4;
1970 for (
int i=0; i<4; i++){
1971 coloredVertices[i].x = datum->x - m_systemOffset.x();
1972 coloredVertices[i].y = datum->y - m_systemOffset.y();
1973 coloredVertices[i].t = datum->t;
1974 coloredVertices[i].lifeSpan = datum->lifeSpan;
1975 coloredVertices[i].size = datum->size;
1976 coloredVertices[i].endSize = datum->endSize;
1977 coloredVertices[i].vx = datum->vx;
1978 coloredVertices[i].vy = datum->vy;
1979 coloredVertices[i].ax = datum->ax;
1980 coloredVertices[i].ay = datum->ay;
1981 if (m_explicitColor && datum->colorOwner !=
this) {
1982 QQuickParticleData* shadow = getShadowDatum(datum);
1983 coloredVertices[i].color = shadow->color;
1985 coloredVertices[i].color = datum->color;
1990 coloredPointVertices += pIdx*1;
1991 for (
int i=0; i<1; i++){
1992 coloredPointVertices[i].x = datum->x - m_systemOffset.x();
1993 coloredPointVertices[i].y = datum->y - m_systemOffset.y();
1994 coloredPointVertices[i].t = datum->t;
1995 coloredPointVertices[i].lifeSpan = datum->lifeSpan;
1996 coloredPointVertices[i].size = datum->size;
1997 coloredPointVertices[i].endSize = datum->endSize;
1998 coloredPointVertices[i].vx = datum->vx;
1999 coloredPointVertices[i].vy = datum->vy;
2000 coloredPointVertices[i].ax = datum->ax;
2001 coloredPointVertices[i].ay = datum->ay;
2002 if (m_explicitColor && datum->colorOwner !=
this) {
2003 QQuickParticleData* shadow = getShadowDatum(datum);
2004 coloredPointVertices[i].color = shadow->color;
2006 coloredPointVertices[i].color = datum->color;
2011 simplePointVertices += pIdx*1;
2012 for (
int i=0; i<1; i++){
2013 simplePointVertices[i].x = datum->x - m_systemOffset.x();
2014 simplePointVertices[i].y = datum->y - m_systemOffset.y();
2015 simplePointVertices[i].t = datum->t;
2016 simplePointVertices[i].lifeSpan = datum->lifeSpan;
2017 simplePointVertices[i].size = datum->size;
2018 simplePointVertices[i].endSize = datum->endSize;
2019 simplePointVertices[i].vx = datum->vx;
2020 simplePointVertices[i].vy = datum->vy;
2021 simplePointVertices[i].ax = datum->ax;
2022 simplePointVertices[i].ay = datum->ay;
2034#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