diff options
Diffstat (limited to 'src/declarative/particles/qsgimageparticle.cpp')
-rw-r--r-- | src/declarative/particles/qsgimageparticle.cpp | 410 |
1 files changed, 138 insertions, 272 deletions
diff --git a/src/declarative/particles/qsgimageparticle.cpp b/src/declarative/particles/qsgimageparticle.cpp index 15bc88b4c3..836236c13e 100644 --- a/src/declarative/particles/qsgimageparticle.cpp +++ b/src/declarative/particles/qsgimageparticle.cpp @@ -305,62 +305,6 @@ QSGImageParticle::QSGImageParticle(QSGItem* parent) , m_lastLevel(Unknown) { setFlag(ItemHasContents); - //TODO: Clean up defaults here and in custom - m_defaultUltra = new UltraVertices; - m_defaultSimple = new SimpleVertices; - UltraVertex *vertices = (UltraVertex *) m_defaultUltra; - SimpleVertex *vertices2 = (SimpleVertex *) m_defaultSimple; - for (int i=0; i<4; ++i) { - vertices2[i].x = vertices[i].x = 0; - vertices2[i].y = vertices[i].y = 0; - vertices2[i].t = vertices[i].t = -1; - vertices2[i].lifeSpan = vertices[i].lifeSpan = 0; - vertices2[i].size = vertices[i].size = 0; - vertices2[i].endSize = vertices[i].endSize = 0; - vertices2[i].sx = vertices[i].sx = 0; - vertices2[i].sy = vertices[i].sy = 0; - vertices2[i].ax = vertices[i].ax = 0; - vertices2[i].ay = vertices[i].ay = 0; - vertices[i].xx = 1; - vertices[i].xy = 0; - vertices[i].yx = 0; - vertices[i].yy = 1; - vertices[i].rotation = 0; - vertices[i].rotationSpeed = 0; - vertices[i].autoRotate = 0; - vertices[i].animIdx = -1; - vertices[i].frameDuration = 1; - vertices[i].frameCount = 0; - vertices[i].animT = -1; - vertices[i].color.r = 255; - vertices[i].color.g = 255; - vertices[i].color.b = 255; - vertices[i].color.a = 255; - } - - vertices[0].tx = 0; - vertices[0].ty = 0; - - vertices[1].tx = 1; - vertices[1].ty = 0; - - vertices[2].tx = 0; - vertices[2].ty = 1; - - vertices[3].tx = 1; - vertices[3].ty = 1; - - vertices2[0].tx = 0; - vertices2[0].ty = 0; - - vertices2[1].tx = 1; - vertices2[1].ty = 0; - - vertices2[2].tx = 0; - vertices2[2].ty = 1; - - vertices2[3].tx = 1; - vertices2[3].ty = 1; } QDeclarativeListProperty<QSGSprite> QSGImageParticle::sprites() @@ -411,7 +355,7 @@ void QSGImageParticle::setColor(const QColor &color) return; m_color = color; emit colorChanged(); - if(perfLevel < Coloured) + if(perfLevel < Colored) reset(); } @@ -421,7 +365,7 @@ void QSGImageParticle::setColorVariation(qreal var) return; m_color_variation = var; emit colorVariationChanged(); - if(perfLevel < Coloured) + if(perfLevel < Colored) reset(); } @@ -431,7 +375,7 @@ void QSGImageParticle::setAlphaVariation(qreal arg) m_alphaVariation = arg; emit alphaVariationChanged(arg); } - if(perfLevel < Coloured) + if(perfLevel < Colored) reset(); } @@ -441,7 +385,7 @@ void QSGImageParticle::setAlpha(qreal arg) m_alpha = arg; emit alphaChanged(arg); } - if(perfLevel < Coloured) + if(perfLevel < Colored) reset(); } @@ -451,7 +395,7 @@ void QSGImageParticle::setRedVariation(qreal arg) m_redVariation = arg; emit redVariationChanged(arg); } - if(perfLevel < Coloured) + if(perfLevel < Colored) reset(); } @@ -461,7 +405,7 @@ void QSGImageParticle::setGreenVariation(qreal arg) m_greenVariation = arg; emit greenVariationChanged(arg); } - if(perfLevel < Coloured) + if(perfLevel < Colored) reset(); } @@ -471,7 +415,7 @@ void QSGImageParticle::setBlueVariation(qreal arg) m_blueVariation = arg; emit blueVariationChanged(arg); } - if(perfLevel < Coloured) + if(perfLevel < Colored) reset(); } @@ -619,9 +563,34 @@ QSGGeometryNode* QSGImageParticle::buildSimpleParticleNode() QSGGeometry *g = new QSGGeometry(SimpleParticle_AttributeSet, vCount, iCount); g->setDrawingMode(GL_TRIANGLES); - SimpleVertices *vertices = (SimpleVertices *) g->vertexData(); - for (int p=0; p<m_count; ++p) - memcpy(vertices++, m_defaultSimple, sizeof(SimpleVertices)); + SimpleVertex *vertices = (SimpleVertex *) g->vertexData(); + for (int p=0; p<m_count; ++p){ + for(int i=0; i<4; i++){ + vertices[i].x = m_data[p]->x; + vertices[i].y = m_data[p]->y; + vertices[i].t = m_data[p]->t; + vertices[i].size = m_data[p]->size; + vertices[i].endSize = m_data[p]->endSize; + vertices[i].sx = m_data[p]->sx; + vertices[i].sy = m_data[p]->sy; + vertices[i].ax = m_data[p]->ax; + vertices[i].ay = m_data[p]->ay; + } + //reload(p); + vertices[0].tx = 0; + vertices[0].ty = 0; + + vertices[1].tx = 1; + vertices[1].ty = 0; + + vertices[2].tx = 0; + vertices[2].ty = 1; + + vertices[3].tx = 1; + vertices[3].ty = 1; + + vertices += 4; + } quint16 *indices = g->indexDataAsUShort(); for (int i=0; i<m_count; ++i) { @@ -635,6 +604,9 @@ QSGGeometryNode* QSGImageParticle::buildSimpleParticleNode() indices += 6; } + m_node = new QSGGeometryNode(); + m_node->setGeometry(g); + if (m_material) { delete m_material; m_material = 0; @@ -644,28 +616,24 @@ QSGGeometryNode* QSGImageParticle::buildSimpleParticleNode() m_material->texture = sceneGraphEngine()->createTextureFromImage(image); m_material->texture->setFiltering(QSGTexture::Linear); m_material->framecount = 1; - m_node = new QSGGeometryNode(); - m_node->setGeometry(g); m_node->setMaterial(m_material); m_last_particle = 0; - return m_node; } QSGGeometryNode* QSGImageParticle::buildParticleNode() { if (m_count * 4 > 0xffff) { - printf("UltraParticle: Too many particles... \n");//####Why is this here? + printf("UltraParticle: Too many particles... \n");//### Why is this here? return 0; } if(m_count <= 0) { - printf("UltraParticle: Too few particles... \n"); + qDebug() << "UltraParticle: Too few particles... \n";//XXX: Is now a vaild intermediate state... return 0; } - m_resizePending = false; if(!m_sprites.count() && !m_bloat && m_colortable_name.isEmpty() && m_sizetable_name.isEmpty() @@ -705,38 +673,29 @@ QSGGeometryNode* QSGImageParticle::buildParticleNode() QSGGeometry *g = new QSGGeometry(UltraParticle_AttributeSet, vCount, iCount); g->setDrawingMode(GL_TRIANGLES); + m_node = new QSGGeometryNode(); + m_node->setGeometry(g); UltraVertex *vertices = (UltraVertex *) g->vertexData(); - SimpleVertex *oldSimple = (SimpleVertex *) m_lastData;//TODO: Other levels - if(m_lastLevel == 1) - qDebug() << "Theta" << m_lastLevel << oldSimple[0].x << oldSimple[0].y << oldSimple[0].t; for (int p=0; p<m_count; ++p) { - memcpy(vertices, m_defaultUltra, sizeof(UltraVertices)); - if (m_lastLevel == 1 && m_lastCount > p) {//Transplant/IntermediateVertices? - for (int i=0; i<4; ++i) { - vertices[i].x = oldSimple[i].x; - vertices[i].y = oldSimple[i].y; - vertices[i].t = oldSimple[i].t; - vertices[i].lifeSpan = oldSimple[i].lifeSpan; - vertices[i].size = oldSimple[i].size; - vertices[i].endSize = oldSimple[i].endSize; - vertices[i].sx = oldSimple[i].sx; - vertices[i].sy = oldSimple[i].sy; - vertices[i].ax = oldSimple[i].ax; - vertices[i].ay = oldSimple[i].ay; - /* - vertices[i].frameDuration = oldSimple[i].lifeSpan; - vertices[i].frameCount = 1; - vertices[i].animT = oldSimple[i].t; - */ - } - } + reload(p);//reload gets geometry from node + + vertices[0].tx = 0; + vertices[0].ty = 0; + + vertices[1].tx = 1; + vertices[1].ty = 0; + + vertices[2].tx = 0; + vertices[2].ty = 1; + + vertices[3].tx = 1; + vertices[3].ty = 1; vertices += 4; - oldSimple += 4; } - quint16 *indices = g->indexDataAsUShort();//TODO: Speed gains by copying this over if count unchanged? + quint16 *indices = g->indexDataAsUShort(); for (int i=0; i<m_count; ++i) { int o = i * 4; indices[0] = o; @@ -780,8 +739,6 @@ QSGGeometryNode* QSGImageParticle::buildParticleNode() m_spriteEngine->setCount(m_count); } - m_node = new QSGGeometryNode(); - m_node->setGeometry(g); m_node->setMaterial(m_material); m_last_particle = 0; @@ -789,92 +746,11 @@ QSGGeometryNode* QSGImageParticle::buildParticleNode() return m_node; } -void QSGImageParticle::resize(int oldCount, int newCount) -{ - //If perf level changes at the same time as a resize, we reset instead of doing pending resize - if(!m_node) - return; - switch(perfLevel){ - default: - case Sprites: - if(m_spriteEngine) - reset();//TODO: Handle sprite resizeing (have to shuffle the engine too...) - case Coloured: - case Deformable: - case Tabled: - if(!m_resizePending){ - m_resizePendingUltra.resize(oldCount); - UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData(); - for(int i=0; i<oldCount; i++) - m_resizePendingUltra[i] = &particles[i]; - } - groupShuffle(m_resizePendingUltra, m_defaultUltra); - break; - case Simple: - if(!m_resizePending){ - m_resizePendingSimple.resize(oldCount); - SimpleVertices *particles = (SimpleVertices *) m_node->geometry()->vertexData(); - for(int i=0; i<oldCount; i++) - m_resizePendingSimple[i] = &particles[i]; - } - groupShuffle(m_resizePendingSimple, m_defaultSimple); - break; - } - m_resizePending = true; -} - -void QSGImageParticle::performPendingResize() -{ - m_resizePending = false; - if(!m_node) - return; - UltraVertices tmp1[m_count];//###More vast memcpys that will decrease performance - SimpleVertices tmp2[m_count];//###More vast memcpys that will decrease performance - switch(perfLevel){ - case Sprites: - case Coloured: - case Deformable: - case Tabled: - Q_ASSERT(m_resizePendingUltra.size() == m_count);//XXX - for(int i=0; i<m_count; i++){ - Q_ASSERT(m_resizePendingUltra[i]); - tmp1[i] = *m_resizePendingUltra[i]; - } - m_node->setFlag(QSGNode::OwnsGeometry, false); - m_node->geometry()->allocate(m_count*4, m_count*6); - memcpy(m_node->geometry()->vertexData(), tmp1, sizeof(UltraVertices) * m_count); - m_node->setFlag(QSGNode::OwnsGeometry, true); - break; - case Simple: - Q_ASSERT(m_resizePendingSimple.size() == m_count);//XXX - for(int i=0; i<m_count; i++) - tmp2[i] = *m_resizePendingSimple[i]; - m_node->setFlag(QSGNode::OwnsGeometry, false); - m_node->geometry()->allocate(m_count*4, m_count*6); - memcpy(m_node->geometry()->vertexData(), tmp2, sizeof(SimpleVertices) * m_count); - m_node->setFlag(QSGNode::OwnsGeometry, true); - break; - } - quint16 *indices = m_node->geometry()->indexDataAsUShort(); - for (int i=0; i<m_count; ++i) { - int o = i * 4; - indices[0] = o; - indices[1] = o + 1; - indices[2] = o + 2; - indices[3] = o + 1; - indices[4] = o + 3; - indices[5] = o + 2; - indices += 6; - } - m_node->setFlag(QSGNode::OwnsGeometry, true); -} - QSGNode *QSGImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) { if(m_pleaseReset){ if(m_node){ if(perfLevel == 1){ - qDebug() << "Beta"; m_lastCount = m_node->geometry()->vertexCount() / 4; m_lastData = qMalloc(m_lastCount*sizeof(SimpleVertices)); memcpy(m_lastData, m_node->geometry()->vertexData(), m_lastCount * sizeof(SimpleVertices));//TODO: Multiple levels @@ -889,8 +765,6 @@ QSGNode *QSGImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) m_material = 0; m_pleaseReset = false; } - if(m_resizePending) - performPendingResize(); if(m_system && m_system->isRunning()) prepareNextFrame(); @@ -904,7 +778,7 @@ QSGNode *QSGImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) void QSGImageParticle::prepareNextFrame() { - if (m_node == 0){ //TODO: Staggered loading (as emitted) + if (m_node == 0){//TODO: Staggered loading (as emitted) m_node = buildParticleNode(); if(m_node == 0) return; @@ -935,67 +809,14 @@ void QSGImageParticle::prepareNextFrame() } } -template <typename VT> -IntermediateVertices* transplant(IntermediateVertices* iv, VT &v) -{//Deliberate typemangling cast - iv->v1 = (UltraVertex*)&(v.v1); - iv->v2 = (UltraVertex*)&(v.v2); - iv->v3 = (UltraVertex*)&(v.v3); - iv->v4 = (UltraVertex*)&(v.v4); - return iv; -} - -IntermediateVertices* QSGImageParticle::fetchIntermediateVertices(int pos) -{ - //Note that this class ruins typesafety for you. Maybe even thread safety. - //TODO: Something better, possibly with templates or inheritance - static IntermediateVertices iv; - SimpleVertices *sv; - UltraVertices *uv; - switch(perfLevel){ - case Simple: - sv = (SimpleVertices *) m_node->geometry()->vertexData(); - return transplant(&iv, sv[pos]); - case Coloured: - case Deformable: - case Tabled: - case Sprites: - default: - uv = (UltraVertices *) m_node->geometry()->vertexData(); - return transplant(&iv,uv[pos]); - } -} - void QSGImageParticle::reloadColor(const Color4ub &c, QSGParticleData* d) { - UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData(); - int pos = particleTypeIndex(d); - UltraVertices &p = particles[pos]; - p.v1.color = p.v2.color = p.v3.color = p.v4.color = c; + d->color = c; + //TODO: get index for reload - or make function take an index } -void QSGImageParticle::reload(QSGParticleData *d) +void QSGImageParticle::initialize(int idx) { - if (m_node == 0) - return; - - int pos = particleTypeIndex(d); - IntermediateVertices* p = fetchIntermediateVertices(pos); - - //Perhaps we could be more efficient? - vertexCopy(*p->v1, d->pv); - vertexCopy(*p->v2, d->pv); - vertexCopy(*p->v3, d->pv); - vertexCopy(*p->v4, d->pv); -} - -void QSGImageParticle::load(QSGParticleData *d) -{ - if (m_node == 0) - return; - - int pos = particleTypeIndex(d); - IntermediateVertices* p = fetchIntermediateVertices(pos);//Remember this removes typesafety! Color4ub color; qreal redVariation = m_color_variation + m_redVariation; qreal greenVariation = m_color_variation + m_greenVariation; @@ -1003,66 +824,111 @@ void QSGImageParticle::load(QSGParticleData *d) switch(perfLevel){//Fall-through is intended on all of them case Sprites: // Initial Sprite State - p->v1->animT = p->v2->animT = p->v3->animT = p->v4->animT = p->v1->t; - p->v1->animIdx = p->v2->animIdx = p->v3->animIdx = p->v4->animIdx = 0; + m_data[idx]->animT = m_data[idx]->t; + m_data[idx]->animIdx = 0; if(m_spriteEngine){ - m_spriteEngine->startSprite(pos); - p->v1->frameCount = p->v2->frameCount = p->v3->frameCount = p->v4->frameCount = m_spriteEngine->spriteFrames(pos); - p->v1->frameDuration = p->v2->frameDuration = p->v3->frameDuration = p->v4->frameDuration = m_spriteEngine->spriteDuration(pos); + m_spriteEngine->startSprite(idx); + m_data[idx]->frameCount = m_spriteEngine->spriteFrames(idx); + m_data[idx]->frameDuration = m_spriteEngine->spriteDuration(idx); }else{ - p->v1->frameCount = p->v2->frameCount = p->v3->frameCount = p->v4->frameCount = 1; - p->v1->frameDuration = p->v2->frameDuration = p->v3->frameDuration = p->v4->frameDuration = 9999; + m_data[idx]->frameCount = 1; + m_data[idx]->frameDuration = 9999; } case Tabled: case Deformable: //Initial Rotation if(m_xVector){ - const QPointF &ret = m_xVector->sample(QPointF(d->pv.x, d->pv.y)); - p->v1->xx = p->v2->xx = p->v3->xx = p->v4->xx = ret.x(); - p->v1->xy = p->v2->xy = p->v3->xy = p->v4->xy = ret.y(); + const QPointF &ret = m_xVector->sample(QPointF(m_data[idx]->x, m_data[idx]->y)); + m_data[idx]->xx = ret.x(); + m_data[idx]->xy = ret.y(); } if(m_yVector){ - const QPointF &ret = m_yVector->sample(QPointF(d->pv.x, d->pv.y)); - p->v1->yx = p->v2->yx = p->v3->yx = p->v4->yx = ret.x(); - p->v1->yy = p->v2->yy = p->v3->yy = p->v4->yy = ret.y(); + const QPointF &ret = m_yVector->sample(QPointF(m_data[idx]->x, m_data[idx]->y)); + m_data[idx]->yx = ret.x(); + m_data[idx]->yy = ret.y(); } - p->v1->rotation = p->v2->rotation = p->v3->rotation = p->v4->rotation = + m_data[idx]->rotation = (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV; - p->v1->rotationSpeed = p->v2->rotationSpeed = p->v3->rotationSpeed = p->v4->rotationSpeed = + m_data[idx]->rotationSpeed = (m_rotationSpeed + (m_rotationSpeedVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationSpeedVariation) ) * CONV; - p->v1->autoRotate = p->v2->autoRotate = p->v3->autoRotate = p->v4->autoRotate = m_autoRotation?1.0:0.0; - case Coloured: + m_data[idx]->autoRotate = m_autoRotation?1.0:0.0; + case Colored: //Color initialization // Particle color color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation; color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation; color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation; color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation; - p->v1->color = p->v2->color = p->v3->color = p->v4->color = color; + m_data[idx]->color = color; default: break; } - - vertexCopy(*p->v1, d->pv); - vertexCopy(*p->v2, d->pv); - vertexCopy(*p->v3, d->pv); - vertexCopy(*p->v4, d->pv); } -/* -void QSGImageParticle::verticesUpgrade(void *prev, void *next) +void QSGImageParticle::reload(int idx) { - PerformanceLevel copyLevel = qMin(perfLevel, m_lastLevel); - switch(perfLevel){//Intentional fall-through - case Sprites: - if(copyLevel >= Sprites) - case Tabled: - case Deformable: - case Coloured: + if(!m_node) + return; + + m_node->setFlag(QSGNode::OwnsGeometry, false); + UltraVertex *ultraVertices = (UltraVertex *) m_node->geometry()->vertexData(); + SimpleVertex *simpleVertices = (SimpleVertex *) m_node->geometry()->vertexData(); + switch(perfLevel){ + case Sprites: + ultraVertices += idx*4; + for(int i=0; i<4; i++){ + ultraVertices[i].x = m_data[idx]->x - m_systemOffset.x(); + ultraVertices[i].y = m_data[idx]->y - m_systemOffset.y(); + ultraVertices[i].t = m_data[idx]->t; + ultraVertices[i].lifeSpan = m_data[idx]->lifeSpan; + ultraVertices[i].size = m_data[idx]->size; + ultraVertices[i].endSize = m_data[idx]->endSize; + ultraVertices[i].sx = m_data[idx]->sx; + ultraVertices[i].sy = m_data[idx]->sy; + ultraVertices[i].ax = m_data[idx]->ax; + ultraVertices[i].ay = m_data[idx]->ay; + ultraVertices[i].xx = m_data[idx]->xx; + ultraVertices[i].xy = m_data[idx]->xy; + ultraVertices[i].yx = m_data[idx]->yx; + ultraVertices[i].yy = m_data[idx]->yy; + ultraVertices[i].rotation = m_data[idx]->rotation; + ultraVertices[i].rotationSpeed = m_data[idx]->rotationSpeed; + ultraVertices[i].autoRotate = m_data[idx]->autoRotate; + ultraVertices[i].animIdx = m_data[idx]->animIdx; + ultraVertices[i].frameDuration = m_data[idx]->frameDuration; + ultraVertices[i].frameCount = m_data[idx]->frameCount; + ultraVertices[i].animT = m_data[idx]->animT; + ultraVertices[i].color.r = m_data[idx]->color.r; + ultraVertices[i].color.g = m_data[idx]->color.g; + ultraVertices[i].color.b = m_data[idx]->color.b; + ultraVertices[i].color.a = m_data[idx]->color.a; + } + break; + case Tabled://TODO: Us + case Deformable: + case Colored: + case Simple: + simpleVertices += idx*4; + for(int i=0; i<4; i++){ + simpleVertices[i].x = m_data[idx]->x - m_systemOffset.x(); + simpleVertices[i].y = m_data[idx]->y - m_systemOffset.y(); + simpleVertices[i].t = m_data[idx]->t; + simpleVertices[i].lifeSpan = m_data[idx]->lifeSpan; + simpleVertices[i].size = m_data[idx]->size; + simpleVertices[i].endSize = m_data[idx]->endSize; + simpleVertices[i].sx = m_data[idx]->sx; + simpleVertices[i].sy = m_data[idx]->sy; + simpleVertices[i].ax = m_data[idx]->ax; + simpleVertices[i].ay = m_data[idx]->ay; + } + break; + default: + break; } + m_node->setFlag(QSGNode::OwnsGeometry, true); } -*/ + QT_END_NAMESPACE |