1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the Declarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include <private/qsgcontext_p.h>
43 #include <private/qsgadaptationlayer_p.h>
45 #include <qsgtexturematerial.h>
46 #include <qsgtexture.h>
48 #include "qsgimageparticle_p.h"
49 #include "qsgparticleemitter_p.h"
50 #include "qsgsprite_p.h"
51 #include "qsgspriteengine_p.h"
52 #include <QGLFunctions>
53 #include <qsgengine.h>
57 const float CONV = 0.017453292519943295;
58 class UltraMaterial : public QSGMaterial
61 UltraMaterial(bool withSprites=false)
65 , usesSprites(withSprites)
67 setFlag(Blending, true);
78 virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
79 virtual QSGMaterialShader *createShader() const;
80 virtual int compare(const QSGMaterial *other) const
82 return this - static_cast<const UltraMaterial *>(other);
86 QSGTexture *colortable;
87 QSGTexture *sizetable;
88 QSGTexture *opacitytable;
95 class UltraMaterialData : public QSGMaterialShader
98 UltraMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0)
100 QFile vf(vertexFile ? vertexFile : ":defaultshaders/ultravertex.shader");
101 vf.open(QFile::ReadOnly);
102 m_vertex_code = vf.readAll();
104 QFile ff(fragmentFile ? fragmentFile : ":defaultshaders/ultrafragment.shader");
105 ff.open(QFile::ReadOnly);
106 m_fragment_code = ff.readAll();
108 Q_ASSERT(!m_vertex_code.isNull());
109 Q_ASSERT(!m_fragment_code.isNull());
113 QSGMaterialShader::deactivate();
115 for (int i=0; i<8; ++i) {
116 program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
120 virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
122 UltraMaterial *m = static_cast<UltraMaterial *>(newEffect);
123 state.context()->functions()->glActiveTexture(GL_TEXTURE1);
124 m->colortable->bind();
125 program()->setUniformValue(m_colortable_id, 1);
127 state.context()->functions()->glActiveTexture(GL_TEXTURE2);
128 m->sizetable->bind();
129 program()->setUniformValue(m_sizetable_id, 2);
131 state.context()->functions()->glActiveTexture(GL_TEXTURE3);
132 m->opacitytable->bind();
133 program()->setUniformValue(m_opacitytable_id, 3);
135 state.context()->functions()->glActiveTexture(GL_TEXTURE0);//Investigate why this screws up Text{} if placed before 1
138 program()->setUniformValue(m_opacity_id, state.opacity());
139 program()->setUniformValue(m_timestamp_id, (float) m->timestamp);
140 program()->setUniformValue(m_framecount_id, (float) m->framecount);
141 program()->setUniformValue(m_animcount_id, (float) m->animcount);
143 if (state.isMatrixDirty())
144 program()->setUniformValue(m_matrix_id, state.combinedMatrix());
147 virtual void initialize() {
148 m_colortable_id = program()->uniformLocation("colortable");
149 m_sizetable_id = program()->uniformLocation("sizetable");
150 m_opacitytable_id = program()->uniformLocation("opacitytable");
151 m_matrix_id = program()->uniformLocation("matrix");
152 m_opacity_id = program()->uniformLocation("opacity");
153 m_timestamp_id = program()->uniformLocation("timestamp");
154 m_framecount_id = program()->uniformLocation("framecount");
155 m_animcount_id = program()->uniformLocation("animcount");
158 virtual const char *vertexShader() const { return m_vertex_code.constData(); }
159 virtual const char *fragmentShader() const { return m_fragment_code.constData(); }
161 virtual char const *const *attributeNames() const {
162 static const char *attr[] = {
176 virtual bool isColorTable() const { return false; }
183 int m_opacitytable_id;
187 QByteArray m_vertex_code;
188 QByteArray m_fragment_code;
190 static float chunkOfBytes[1024];
192 float UltraMaterialData::chunkOfBytes[1024];
194 QSGMaterialShader *UltraMaterial::createShader() const
196 if(usesSprites)//TODO: Perhaps just swap the shaders, and don't mind the extra vector?
197 return new UltraMaterialData;
199 return new UltraMaterialData;
203 class SimpleMaterial : public UltraMaterial
205 virtual QSGMaterialShader *createShader() const;
206 virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
209 class SimpleMaterialData : public QSGMaterialShader
212 SimpleMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0)
214 QFile vf(vertexFile ? vertexFile : ":defaultshaders/simplevertex.shader");
215 vf.open(QFile::ReadOnly);
216 m_vertex_code = vf.readAll();
218 QFile ff(fragmentFile ? fragmentFile : ":defaultshaders/simplefragment.shader");
219 ff.open(QFile::ReadOnly);
220 m_fragment_code = ff.readAll();
222 Q_ASSERT(!m_vertex_code.isNull());
223 Q_ASSERT(!m_fragment_code.isNull());
227 QSGMaterialShader::deactivate();
229 for (int i=0; i<8; ++i) {
230 program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
234 virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
236 UltraMaterial *m = static_cast<UltraMaterial *>(newEffect);
237 state.context()->functions()->glActiveTexture(GL_TEXTURE0);
240 program()->setUniformValue(m_opacity_id, state.opacity());
241 program()->setUniformValue(m_timestamp_id, (float) m->timestamp);
243 if (state.isMatrixDirty())
244 program()->setUniformValue(m_matrix_id, state.combinedMatrix());
247 virtual void initialize() {
248 m_matrix_id = program()->uniformLocation("matrix");
249 m_opacity_id = program()->uniformLocation("opacity");
250 m_timestamp_id = program()->uniformLocation("timestamp");
253 virtual const char *vertexShader() const { return m_vertex_code.constData(); }
254 virtual const char *fragmentShader() const { return m_fragment_code.constData(); }
256 virtual char const *const *attributeNames() const {
257 static const char *attr[] = {
267 virtual bool isColorTable() const { return false; }
273 QByteArray m_vertex_code;
274 QByteArray m_fragment_code;
276 static float chunkOfBytes[1024];
278 float SimpleMaterialData::chunkOfBytes[1024];
280 QSGMaterialShader *SimpleMaterial::createShader() const {
281 return new SimpleMaterialData;
284 QSGImageParticle::QSGImageParticle(QSGItem* parent)
285 : QSGParticlePainter(parent)
287 , m_color_variation(0.0)
290 , m_alphaVariation(0.0)
292 , m_redVariation(0.0)
293 , m_greenVariation(0.0)
294 , m_blueVariation(0.0)
296 , m_autoRotation(false)
299 , m_rotationVariation(0)
301 , m_rotationSpeedVariation(0)
305 , m_lastLevel(Unknown)
307 setFlag(ItemHasContents);
310 QDeclarativeListProperty<QSGSprite> QSGImageParticle::sprites()
312 return QDeclarativeListProperty<QSGSprite>(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
315 void QSGImageParticle::setImage(const QUrl &image)
317 if (image == m_image_name)
319 m_image_name = image;
325 void QSGImageParticle::setColortable(const QUrl &table)
327 if (table == m_colortable_name)
329 m_colortable_name = table;
330 emit colortableChanged();
334 void QSGImageParticle::setSizetable(const QUrl &table)
336 if (table == m_sizetable_name)
338 m_sizetable_name = table;
339 emit sizetableChanged();
343 void QSGImageParticle::setOpacitytable(const QUrl &table)
345 if (table == m_opacitytable_name)
347 m_opacitytable_name = table;
348 emit opacitytableChanged();
352 void QSGImageParticle::setColor(const QColor &color)
354 if (color == m_color)
358 if(perfLevel < Colored)
362 void QSGImageParticle::setColorVariation(qreal var)
364 if (var == m_color_variation)
366 m_color_variation = var;
367 emit colorVariationChanged();
368 if(perfLevel < Colored)
372 void QSGImageParticle::setAlphaVariation(qreal arg)
374 if (m_alphaVariation != arg) {
375 m_alphaVariation = arg;
376 emit alphaVariationChanged(arg);
378 if(perfLevel < Colored)
382 void QSGImageParticle::setAlpha(qreal arg)
384 if (m_alpha != arg) {
386 emit alphaChanged(arg);
388 if(perfLevel < Colored)
392 void QSGImageParticle::setRedVariation(qreal arg)
394 if (m_redVariation != arg) {
395 m_redVariation = arg;
396 emit redVariationChanged(arg);
398 if(perfLevel < Colored)
402 void QSGImageParticle::setGreenVariation(qreal arg)
404 if (m_greenVariation != arg) {
405 m_greenVariation = arg;
406 emit greenVariationChanged(arg);
408 if(perfLevel < Colored)
412 void QSGImageParticle::setBlueVariation(qreal arg)
414 if (m_blueVariation != arg) {
415 m_blueVariation = arg;
416 emit blueVariationChanged(arg);
418 if(perfLevel < Colored)
422 void QSGImageParticle::setRotation(qreal arg)
424 if (m_rotation != arg) {
426 emit rotationChanged(arg);
428 if(perfLevel < Deformable)
432 void QSGImageParticle::setRotationVariation(qreal arg)
434 if (m_rotationVariation != arg) {
435 m_rotationVariation = arg;
436 emit rotationVariationChanged(arg);
438 if(perfLevel < Deformable)
442 void QSGImageParticle::setRotationSpeed(qreal arg)
444 if (m_rotationSpeed != arg) {
445 m_rotationSpeed = arg;
446 emit rotationSpeedChanged(arg);
448 if(perfLevel < Deformable)
452 void QSGImageParticle::setRotationSpeedVariation(qreal arg)
454 if (m_rotationSpeedVariation != arg) {
455 m_rotationSpeedVariation = arg;
456 emit rotationSpeedVariationChanged(arg);
458 if(perfLevel < Deformable)
462 void QSGImageParticle::setAutoRotation(bool arg)
464 if (m_autoRotation != arg) {
465 m_autoRotation = arg;
466 emit autoRotationChanged(arg);
468 if(perfLevel < Deformable)
472 void QSGImageParticle::setXVector(QSGStochasticDirection* arg)
474 if (m_xVector != arg) {
476 emit xVectorChanged(arg);
478 if(perfLevel < Deformable)
482 void QSGImageParticle::setYVector(QSGStochasticDirection* arg)
484 if (m_yVector != arg) {
486 emit yVectorChanged(arg);
488 if(perfLevel < Deformable)
492 void QSGImageParticle::setBloat(bool arg)
494 if (m_bloat != arg) {
496 emit bloatChanged(arg);
502 void QSGImageParticle::reset()
504 QSGParticlePainter::reset();
505 m_pleaseReset = true;
508 void QSGImageParticle::createEngine()
511 delete m_spriteEngine;
512 if(m_sprites.count())
513 m_spriteEngine = new QSGSpriteEngine(m_sprites, this);
519 static QSGGeometry::Attribute SimpleParticle_Attributes[] = {
520 { 0, 2, GL_FLOAT }, // Position
521 { 1, 2, GL_FLOAT }, // TexCoord
522 { 2, 4, GL_FLOAT }, // Data
523 { 3, 4, GL_FLOAT } // Vectors
526 static QSGGeometry::AttributeSet SimpleParticle_AttributeSet =
528 4, // Attribute Count
529 (2 + 2 + 4 + 4 ) * sizeof(float),
530 SimpleParticle_Attributes
533 static QSGGeometry::Attribute UltraParticle_Attributes[] = {
534 { 0, 2, GL_FLOAT }, // Position
535 { 1, 2, GL_FLOAT }, // TexCoord
536 { 2, 4, GL_FLOAT }, // Data
537 { 3, 4, GL_FLOAT }, // Vectors
538 { 4, 4, GL_UNSIGNED_BYTE }, // Colors
539 { 5, 4, GL_FLOAT }, // DeformationVectors
540 { 6, 3, GL_FLOAT }, // Rotation
541 { 7, 4, GL_FLOAT } // Anim Data
544 static QSGGeometry::AttributeSet UltraParticle_AttributeSet =
546 8, // Attribute Count
547 (2 + 2 + 4 + 4 + 4 + 4 + 3) * sizeof(float) + 4 * sizeof(uchar),
548 UltraParticle_Attributes
551 QSGGeometryNode* QSGImageParticle::buildSimpleParticleNode()
553 perfLevel = Simple;//TODO: Intermediate levels
554 QImage image = QImage(m_image_name.toLocalFile());
555 if (image.isNull()) {
556 printf("UltraParticle: loading image failed... '%s'\n", qPrintable(m_image_name.toLocalFile()));
559 int vCount = m_count * 4;
560 int iCount = m_count * 6;
561 qDebug() << "Simple Case";
563 QSGGeometry *g = new QSGGeometry(SimpleParticle_AttributeSet, vCount, iCount);
564 g->setDrawingMode(GL_TRIANGLES);
566 SimpleVertex *vertices = (SimpleVertex *) g->vertexData();
567 for (int p=0; p<m_count; ++p){
568 for(int i=0; i<4; i++){
569 vertices[i].x = m_data[p]->x;
570 vertices[i].y = m_data[p]->y;
571 vertices[i].t = m_data[p]->t;
572 vertices[i].size = m_data[p]->size;
573 vertices[i].endSize = m_data[p]->endSize;
574 vertices[i].sx = m_data[p]->sx;
575 vertices[i].sy = m_data[p]->sy;
576 vertices[i].ax = m_data[p]->ax;
577 vertices[i].ay = m_data[p]->ay;
595 quint16 *indices = g->indexDataAsUShort();
596 for (int i=0; i<m_count; ++i) {
607 m_node = new QSGGeometryNode();
608 m_node->setGeometry(g);
615 m_material = new SimpleMaterial();
616 m_material->texture = sceneGraphEngine()->createTextureFromImage(image);
617 m_material->texture->setFiltering(QSGTexture::Linear);
618 m_material->framecount = 1;
619 m_node->setMaterial(m_material);
625 QSGGeometryNode* QSGImageParticle::buildParticleNode()
627 if (m_count * 4 > 0xffff) {
628 printf("UltraParticle: Too many particles... \n");//### Why is this here?
633 qDebug() << "UltraParticle: Too few particles... \n";//XXX: Is now a vaild intermediate state...
637 if(!m_sprites.count() && !m_bloat
638 && m_colortable_name.isEmpty()
639 && m_sizetable_name.isEmpty()
640 && m_opacitytable_name.isEmpty()
642 && !m_rotation && !m_rotationVariation
643 && !m_rotationSpeed && !m_rotationSpeedVariation
644 && !m_alphaVariation && m_alpha == 1.0
645 && !m_redVariation && !m_blueVariation && !m_greenVariation
646 && !m_color.isValid()
648 return buildSimpleParticleNode();
649 perfLevel = Sprites;//TODO: intermediate levels
650 if(!m_color.isValid())//But we're in colored level (or higher)
651 m_color = QColor(Qt::white);
652 qDebug() << "Complex Case";
655 if(m_sprites.count()){
656 if (!m_spriteEngine) {
657 qWarning() << "UltraParticle: No sprite engine...";
660 image = m_spriteEngine->assembledImage();
661 if(image.isNull())//Warning is printed in engine
664 image = QImage(m_image_name.toLocalFile());
665 if (image.isNull()) {
666 printf("UltraParticle: loading image failed... '%s'\n", qPrintable(m_image_name.toLocalFile()));
671 int vCount = m_count * 4;
672 int iCount = m_count * 6;
674 QSGGeometry *g = new QSGGeometry(UltraParticle_AttributeSet, vCount, iCount);
675 g->setDrawingMode(GL_TRIANGLES);
676 m_node = new QSGGeometryNode();
677 m_node->setGeometry(g);
679 UltraVertex *vertices = (UltraVertex *) g->vertexData();
680 for (int p=0; p<m_count; ++p) {
681 reload(p);//reload gets geometry from node
698 quint16 *indices = g->indexDataAsUShort();
699 for (int i=0; i<m_count; ++i) {
716 QImage colortable(m_colortable_name.toLocalFile());
717 QImage sizetable(m_sizetable_name.toLocalFile());
718 QImage opacitytable(m_opacitytable_name.toLocalFile());
719 m_material = new UltraMaterial();
720 if(colortable.isNull())
721 colortable = QImage(":defaultshaders/identitytable.png");
722 if(sizetable.isNull())
723 sizetable = QImage(":defaultshaders/identitytable.png");
724 if(opacitytable.isNull())
725 opacitytable = QImage(":defaultshaders/defaultFadeInOut.png");
726 Q_ASSERT(!colortable.isNull());
727 Q_ASSERT(!sizetable.isNull());
728 Q_ASSERT(!opacitytable.isNull());
729 m_material->colortable = sceneGraphEngine()->createTextureFromImage(colortable);
730 m_material->sizetable = sceneGraphEngine()->createTextureFromImage(sizetable);
731 m_material->opacitytable = sceneGraphEngine()->createTextureFromImage(opacitytable);
733 m_material->texture = sceneGraphEngine()->createTextureFromImage(image);
734 m_material->texture->setFiltering(QSGTexture::Linear);
736 m_material->framecount = 1;
738 m_material->framecount = m_spriteEngine->maxFrames();
739 m_spriteEngine->setCount(m_count);
742 m_node->setMaterial(m_material);
749 QSGNode *QSGImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
754 m_lastCount = m_node->geometry()->vertexCount() / 4;
755 m_lastData = qMalloc(m_lastCount*sizeof(SimpleVertices));
756 memcpy(m_lastData, m_node->geometry()->vertexData(), m_lastCount * sizeof(SimpleVertices));//TODO: Multiple levels
758 m_lastLevel = perfLevel;
766 m_pleaseReset = false;
769 if(m_system && m_system->isRunning())
773 m_node->markDirty(QSGNode::DirtyMaterial);
779 void QSGImageParticle::prepareNextFrame()
781 if (m_node == 0){//TODO: Staggered loading (as emitted)
782 m_node = buildParticleNode();
785 qDebug() << "Feature level: " << perfLevel;
787 qint64 timeStamp = m_system->systemSync(this);
789 qreal time = timeStamp / 1000.;
790 m_material->timestamp = time;
793 if(m_spriteEngine){//perfLevel == Sprites?
794 m_material->animcount = m_spriteEngine->spriteCount();
795 UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData();
796 m_spriteEngine->updateSprites(timeStamp);
797 for(int i=0; i<m_count; i++){
798 UltraVertices &p = particles[i];
799 int curIdx = m_spriteEngine->spriteState(i);
800 if(curIdx != p.v1.animIdx){
801 p.v1.animIdx = p.v2.animIdx = p.v3.animIdx = p.v4.animIdx = curIdx;
802 p.v1.animT = p.v2.animT = p.v3.animT = p.v4.animT = m_spriteEngine->spriteStart(i)/1000.0;
803 p.v1.frameCount = p.v2.frameCount = p.v3.frameCount = p.v4.frameCount = m_spriteEngine->spriteFrames(i);
804 p.v1.frameDuration = p.v2.frameDuration = p.v3.frameDuration = p.v4.frameDuration = m_spriteEngine->spriteDuration(i);
808 m_material->animcount = 1;
812 void QSGImageParticle::reloadColor(const Color4ub &c, QSGParticleData* d)
815 //TODO: get index for reload - or make function take an index
818 void QSGImageParticle::initialize(int idx)
821 qreal redVariation = m_color_variation + m_redVariation;
822 qreal greenVariation = m_color_variation + m_greenVariation;
823 qreal blueVariation = m_color_variation + m_blueVariation;
824 switch(perfLevel){//Fall-through is intended on all of them
826 // Initial Sprite State
827 m_data[idx]->animT = m_data[idx]->t;
828 m_data[idx]->animIdx = 0;
830 m_spriteEngine->startSprite(idx);
831 m_data[idx]->frameCount = m_spriteEngine->spriteFrames(idx);
832 m_data[idx]->frameDuration = m_spriteEngine->spriteDuration(idx);
834 m_data[idx]->frameCount = 1;
835 m_data[idx]->frameDuration = 9999;
841 const QPointF &ret = m_xVector->sample(QPointF(m_data[idx]->x, m_data[idx]->y));
842 m_data[idx]->xx = ret.x();
843 m_data[idx]->xy = ret.y();
846 const QPointF &ret = m_yVector->sample(QPointF(m_data[idx]->x, m_data[idx]->y));
847 m_data[idx]->yx = ret.x();
848 m_data[idx]->yy = ret.y();
850 m_data[idx]->rotation =
851 (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV;
852 m_data[idx]->rotationSpeed =
853 (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV;
854 m_data[idx]->autoRotate = m_autoRotation?1.0:0.0;
856 //Color initialization
858 color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation;
859 color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation;
860 color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation;
861 color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation;
862 m_data[idx]->color = color;
868 void QSGImageParticle::reload(int idx)
873 m_node->setFlag(QSGNode::OwnsGeometry, false);
874 UltraVertex *ultraVertices = (UltraVertex *) m_node->geometry()->vertexData();
875 SimpleVertex *simpleVertices = (SimpleVertex *) m_node->geometry()->vertexData();
878 ultraVertices += idx*4;
879 for(int i=0; i<4; i++){
880 ultraVertices[i].x = m_data[idx]->x - m_systemOffset.x();
881 ultraVertices[i].y = m_data[idx]->y - m_systemOffset.y();
882 ultraVertices[i].t = m_data[idx]->t;
883 ultraVertices[i].lifeSpan = m_data[idx]->lifeSpan;
884 ultraVertices[i].size = m_data[idx]->size;
885 ultraVertices[i].endSize = m_data[idx]->endSize;
886 ultraVertices[i].sx = m_data[idx]->sx;
887 ultraVertices[i].sy = m_data[idx]->sy;
888 ultraVertices[i].ax = m_data[idx]->ax;
889 ultraVertices[i].ay = m_data[idx]->ay;
890 ultraVertices[i].xx = m_data[idx]->xx;
891 ultraVertices[i].xy = m_data[idx]->xy;
892 ultraVertices[i].yx = m_data[idx]->yx;
893 ultraVertices[i].yy = m_data[idx]->yy;
894 ultraVertices[i].rotation = m_data[idx]->rotation;
895 ultraVertices[i].rotationSpeed = m_data[idx]->rotationSpeed;
896 ultraVertices[i].autoRotate = m_data[idx]->autoRotate;
897 ultraVertices[i].animIdx = m_data[idx]->animIdx;
898 ultraVertices[i].frameDuration = m_data[idx]->frameDuration;
899 ultraVertices[i].frameCount = m_data[idx]->frameCount;
900 ultraVertices[i].animT = m_data[idx]->animT;
901 ultraVertices[i].color.r = m_data[idx]->color.r;
902 ultraVertices[i].color.g = m_data[idx]->color.g;
903 ultraVertices[i].color.b = m_data[idx]->color.b;
904 ultraVertices[i].color.a = m_data[idx]->color.a;
907 case Tabled://TODO: Us
911 simpleVertices += idx*4;
912 for(int i=0; i<4; i++){
913 simpleVertices[i].x = m_data[idx]->x - m_systemOffset.x();
914 simpleVertices[i].y = m_data[idx]->y - m_systemOffset.y();
915 simpleVertices[i].t = m_data[idx]->t;
916 simpleVertices[i].lifeSpan = m_data[idx]->lifeSpan;
917 simpleVertices[i].size = m_data[idx]->size;
918 simpleVertices[i].endSize = m_data[idx]->endSize;
919 simpleVertices[i].sx = m_data[idx]->sx;
920 simpleVertices[i].sy = m_data[idx]->sy;
921 simpleVertices[i].ax = m_data[idx]->ax;
922 simpleVertices[i].ay = m_data[idx]->ay;
929 m_node->setFlag(QSGNode::OwnsGeometry, true);