aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/particles/qsgcustomparticle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/particles/qsgcustomparticle.cpp')
-rw-r--r--src/declarative/particles/qsgcustomparticle.cpp143
1 files changed, 71 insertions, 72 deletions
diff --git a/src/declarative/particles/qsgcustomparticle.cpp b/src/declarative/particles/qsgcustomparticle.cpp
index 808ff1c427..f91307ed5c 100644
--- a/src/declarative/particles/qsgcustomparticle.cpp
+++ b/src/declarative/particles/qsgcustomparticle.cpp
@@ -44,16 +44,8 @@
#include <cstdlib>
QT_BEGIN_NAMESPACE
-/*
- "uniform highp mat4 qt_ModelViewProjectionMatrix; \n"
- "attribute highp vec4 qt_Vertex; \n"
- "attribute highp vec2 qt_MultiTexCoord0; \n"
- "varying highp vec2 qt_TexCoord0; \n"
- "void main() { \n"
- " qt_TexCoord0 = qt_MultiTexCoord0; \n"
- " gl_Position = qt_ModelViewProjectionMatrix * qt_Vertex; \n"
- "}";
-*/
+
+//TODO: Can we make the code such that you don't have to copy the whole vertex shader just to add one little calculation?
//Includes comments because the code isn't self explanatory
static const char qt_particles_default_vertex_code[] =
"attribute highp vec2 vPos; \n"
@@ -86,23 +78,6 @@ static const char qt_particles_default_fragment_code[] =//TODO: Default frag req
" gl_FragColor = texture2D(source, fTex) * qt_Opacity; \n"
"}";
-/*
-static const char qt_particles_default_vertex_code[] =
- "attribute highp vec2 vPos; \n"
- "attribute highp vec2 vTex; \n"
- "uniform highp mat4 qt_ModelViewProjectionMatrix; \n"
- "void main() { \n"
- " highp float currentSize = 1000.0; \n"
- " highp vec2 pos = vec2(100.0,100.0) \n"
- " - currentSize / 2. + currentSize * vTex; // adjust size \n"
- " gl_Position = qt_ModelViewProjectionMatrix * vec4(pos.x, pos.y, 0, 1); \n"
- "}";
-static const char qt_particles_default_fragment_code[] =//TODO: Default frag requires source?
- "void main() { \n"
- " gl_FragColor = vec4(0,255,0,255); \n"
- "}";
-*/
-
static const char qt_position_attribute_name[] = "qt_Vertex";
static const char qt_texcoord_attribute_name[] = "qt_MultiTexCoord0";
@@ -148,8 +123,36 @@ QSGCustomParticle::QSGCustomParticle(QSGItem* parent)
: QSGParticlePainter(parent)
, m_pleaseReset(true)
, m_dirtyData(true)
+ , m_resizePending(false)
{
setFlag(QSGItem::ItemHasContents);
+ m_defaultVertices = new PlainVertices;
+ PlainVertex* vertices = (PlainVertex*) m_defaultVertices;
+ for (int i=0; i<4; ++i) {
+ vertices[i].x = 0;
+ vertices[i].y = 0;
+ vertices[i].t = -1;
+ vertices[i].lifeSpan = 0;
+ vertices[i].size = 0;
+ vertices[i].endSize = 0;
+ vertices[i].sx = 0;
+ vertices[i].sy = 0;
+ vertices[i].ax = 0;
+ vertices[i].ay = 0;
+ vertices[i].r = 0;
+ }
+
+ 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;
}
void QSGCustomParticle::componentComplete()
@@ -199,10 +202,17 @@ void QSGCustomParticle::setVertexShader(const QByteArray &code)
emit vertexShaderChanged();
}
-void QSGCustomParticle::setCount(int c)
+void QSGCustomParticle::resize(int oldCount, int newCount)
{
- QSGParticlePainter::setCount(c);
- m_pleaseReset = true;
+ if(!m_node)
+ return;
+ if(!m_resizePending){
+ m_pendingResizeVector.resize(oldCount);
+ PlainVertices *particles = (PlainVertices *) m_node->geometry()->vertexData();
+ for(int i=0; i<oldCount; i++)
+ m_pendingResizeVector[i] = &particles[i];
+ }
+ groupShuffle(m_pendingResizeVector, m_defaultVertices);
}
void QSGCustomParticle::reset()
@@ -401,6 +411,8 @@ QSGNode *QSGCustomParticle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
m_pleaseReset = false;
m_dirtyData = false;
}
+ if(m_resizePending)
+ performPendingResize();
if(m_system && m_system->isRunning())
prepareNextFrame();
@@ -425,6 +437,32 @@ void QSGCustomParticle::prepareNextFrame(){
buildData();
}
+void QSGCustomParticle::performPendingResize()
+{
+ m_resizePending = false;
+ if(!m_node)
+ return;
+ Q_ASSERT(m_pendingResizeVector.size() == m_count);//XXX
+ PlainVertices tmp[m_count];//###More vast memcpys that will decrease performance
+ for(int i=0; i<m_count; i++)
+ tmp[i] = *m_pendingResizeVector[i];
+ m_node->setFlag(QSGNode::OwnsGeometry, false);
+ m_node->geometry()->allocate(m_count*4, m_count*6);
+ memcpy(m_node->geometry()->vertexData(), tmp, sizeof(PlainVertices) * m_count);
+ 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);
+}
+
QSGShaderEffectNode* QSGCustomParticle::buildCustomNode()
{
if (m_count * 4 > 0xffff) {
@@ -437,6 +475,7 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNode()
return 0;
}
+ m_resizePending = false;//reset resizes as well.
//Create Particle Geometry
int vCount = m_count * 4;
@@ -446,32 +485,9 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNode()
PlainVertex *vertices = (PlainVertex *) g->vertexData();
for (int p=0; p<m_count; ++p) {
double r = rand()/(double)RAND_MAX;//TODO: Seed?
- for (int i=0; i<4; ++i) {
- vertices[i].x = 0;
- vertices[i].y = 0;
- vertices[i].t = -1;
- vertices[i].lifeSpan = 0;
- vertices[i].size = 0;
- vertices[i].endSize = 0;
- vertices[i].sx = 0;
- vertices[i].sy = 0;
- vertices[i].ax = 0;
- vertices[i].ay = 0;
+ memcpy(vertices, m_defaultVertices, sizeof(PlainVertices));
+ for(int i=0; i<4; i++)
vertices[i].r = r;
- }
-
- 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();
@@ -493,23 +509,6 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNode()
node->setGeometry(g);
node->setMaterial(&m_material);
- /*
- //For debugging, just use grid vertices like ShaderEffect
- node->setGeometry(0);
- QSGShaderEffectMesh* mesh = new QSGGridMesh();
- node->setFlag(QSGNode::OwnsGeometry, false);
-
- qDebug() << m_source.attributeNames;
- QSGGeometry* geometry = node->geometry();
- geometry = mesh->updateGeometry(geometry, m_source.attributeNames, QRectF(0,0,width(),height()));
- if(!geometry)
- qDebug() << "Should have written the error handling";
- else
- qDebug() << "Mesh Loaded";
- node->setGeometry(geometry);
- qDebug() << QString("INIT") << geometry << (QObject*)node;
- node->setFlag(QSGNode::OwnsGeometry, true);
- */
QSGShaderEffectProgram s = m_source;
if (s.fragmentCode.isEmpty())
s.fragmentCode = qt_particles_default_fragment_code;