Initial entryEffect support for ImageParticle
authorAlan Alpert <alan.alpert@nokia.com>
Mon, 22 Aug 2011 01:55:51 +0000 (11:55 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 24 Aug 2011 02:23:40 +0000 (04:23 +0200)
Implementation for tabled and above is different, coming in a later
commit.

Change-Id: I7ad16a173521bdcef4ddb68f594be7c942ddb505
Reviewed-on: http://codereview.qt.nokia.com/3280
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
examples/declarative/particles/trails/fireworks.qml
src/declarative/particles/defaultshaders/coloredvertex.shader
src/declarative/particles/defaultshaders/deformablevertex.shader
src/declarative/particles/defaultshaders/simplevertex.shader
src/declarative/particles/defaultshaders/spritevertex.shader
src/declarative/particles/qsgimageparticle.cpp
src/declarative/particles/qsgimageparticle_p.h

index b40b300..a84f5d8 100644 (file)
@@ -114,6 +114,7 @@ Rectangle{
         ImageParticle{
             particles: ["works", "fire", "splode"]
             source: "content/particle.png"
+            entryEffect: ImageParticle.Scale
         }
     }
 }
index cdbb130..5b83392 100644 (file)
@@ -5,6 +5,7 @@ attribute lowp vec4 vColor;
 
 uniform highp mat4 qt_Matrix;
 uniform highp float timestamp;
+uniform highp float entry;
 
 varying lowp vec4 fColor;
 
@@ -19,6 +20,18 @@ void main() {
     if (t < 0. || t > 1.)
         currentSize = 0.;
 
+    lowp float fFade = 1.;
+
+    if (entry == 1.){
+        highp float fadeIn = min(t * 10., 1.);
+        highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
+        fFade = fadeIn * fadeOut;
+    }else if(entry == 2.){
+        highp float sizeIn = min(t * 10., 1.);
+        highp float sizeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
+        currentSize = currentSize * sizeIn * sizeOut;
+    }
+
     gl_PointSize = currentSize;
 
     highp vec2 pos = vPos
@@ -27,8 +40,5 @@ void main() {
 
     gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
 
-    highp float fadeIn = min(t * 10., 1.);
-    highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
-
-    fColor = vColor * (fadeIn * fadeOut);
+    fColor = vColor * (fFade);
 }
index 0019984..ab6acde 100644 (file)
@@ -8,6 +8,7 @@ attribute lowp vec4 vColor;
 
 uniform highp mat4 qt_Matrix;
 uniform highp float timestamp;
+uniform highp float entry;
 
 varying highp vec2 fTex;
 varying lowp vec4 fColor;
@@ -24,6 +25,18 @@ void main() {
     if (t < 0. || t > 1.)
         currentSize = 0.;
 
+    lowp float fFade = 1.;
+
+    if (entry == 1.){
+        highp float fadeIn = min(t * 10., 1.);
+        highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
+        fFade = fadeIn * fadeOut;
+    }else if(entry == 2.){
+        highp float sizeIn = min(t * 10., 1.);
+        highp float sizeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
+        currentSize = currentSize * sizeIn * sizeOut;
+    }
+
     highp vec2 pos;
     highp float rotation = vRotation.x + vRotation.y * t * vData.y;
     if(vRotation.z == 1.0){
@@ -48,8 +61,5 @@ void main() {
 
     gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
 
-    highp float fadeIn = min(t * 10., 1.);
-    highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
-
-    fColor = vColor * (fadeIn * fadeOut);
+    fColor = vColor * fFade;
 }
index 1c07363..c287e15 100644 (file)
@@ -4,20 +4,30 @@ attribute highp vec4 vVec; // x,y = constant speed,  z,w = acceleration
 
 uniform highp mat4 qt_Matrix;
 uniform highp float timestamp;
+uniform highp float entry;
 
 varying lowp float fFade;
 
 void main() {                                           
-    highp float size = vData.z;
-    highp float endSize = vData.w;
-
     highp float t = (timestamp - vData.x) / vData.y;
 
-    highp float currentSize = mix(size, endSize, t * t);
+    highp float currentSize = mix(vData.z, vData.w, t * t);
 
     if (t < 0. || t > 1.)
         currentSize = 0.;
 
+    fFade = 1.;
+
+    if (entry == 1.){
+        highp float fadeIn = min(t * 10., 1.);
+        highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
+        fFade = fadeIn * fadeOut;
+    }else if(entry == 2.){
+        highp float sizeIn = min(t * 10., 1.);
+        highp float sizeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
+        currentSize = currentSize * sizeIn * sizeOut;
+    }
+
     gl_PointSize = currentSize;
 
     highp vec2 pos = vPos
@@ -26,8 +36,4 @@ void main() {
 
     gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
 
-    highp float fadeIn = min(t * 10., 1.);
-    highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
-
-    fFade = fadeIn * fadeOut;
 }
index 7d89726..c28e74c 100644 (file)
@@ -20,8 +20,6 @@ varying lowp vec4 fColor;
 
 
 void main() {
-    highp float size = vData.z;
-    highp float endSize = vData.w;
 
     highp float t = (timestamp - vData.x) / vData.y;
 
@@ -58,7 +56,7 @@ void main() {
         frameTex.y = 1. * ((vAnimData.x + 1.)/animcount);
     fTexB = frameTex;
 
-    highp float currentSize = mix(size, endSize, t * t);
+    highp float currentSize = mix(vData.z, vData.w, t * t);
 
     if (t < 0. || t > 1.)
         currentSize = 0.;
@@ -89,5 +87,4 @@ void main() {
 
     fColor = vColor;
     tt = t;
-
 }
index 7a46541..aac07b9 100644 (file)
@@ -78,6 +78,7 @@ class ImageMaterialData
     QSGTexture *opacitytable;
 
     qreal timestamp;
+    qreal entry;
     qreal framecount;
     qreal animcount;
 };
@@ -120,6 +121,7 @@ public:
         program()->setUniformValue("opacitytable", 3);
         glFuncs = QGLContext::currentContext()->functions();
         m_timestamp_id = program()->uniformLocation("timestamp");
+        m_entry_id = program()->uniformLocation("entry");
     }
 
     void updateState(const TabledMaterialData* d, const TabledMaterialData*) {
@@ -139,8 +141,10 @@ public:
         program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
         program()->setUniformValue("framecount", (float) 1);
         program()->setUniformValue("animcount", (float) 1);
+        program()->setUniformValue(m_entry_id, (float) d->entry);
     }
 
+    int m_entry_id;
     int m_timestamp_id;
     QByteArray m_vertex_code;
     QByteArray m_fragment_code;
@@ -181,6 +185,7 @@ public:
         program()->setUniformValue("texture", 0);
         glFuncs = QGLContext::currentContext()->functions();
         m_timestamp_id = program()->uniformLocation("timestamp");
+        m_entry_id = program()->uniformLocation("entry");
     }
 
     void updateState(const DeformableMaterialData* d, const DeformableMaterialData*) {
@@ -188,8 +193,10 @@ public:
         d->texture->bind();
 
         program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
+        program()->setUniformValue(m_entry_id, (float) d->entry);
     }
 
+    int m_entry_id;
     int m_timestamp_id;
     QByteArray m_vertex_code;
     QByteArray m_fragment_code;
@@ -235,6 +242,7 @@ public:
         m_timestamp_id = program()->uniformLocation("timestamp");
         m_framecount_id = program()->uniformLocation("framecount");
         m_animcount_id = program()->uniformLocation("animcount");
+        m_entry_id = program()->uniformLocation("entry");
     }
 
     void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) {
@@ -254,11 +262,13 @@ public:
         program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
         program()->setUniformValue(m_framecount_id, (float) d->framecount);
         program()->setUniformValue(m_animcount_id, (float) d->animcount);
+        program()->setUniformValue(m_entry_id, (float) d->entry);
     }
 
     int m_timestamp_id;
     int m_framecount_id;
     int m_animcount_id;
+    int m_entry_id;
     QByteArray m_vertex_code;
     QByteArray m_fragment_code;
     QGLFunctions* glFuncs;
@@ -313,6 +323,7 @@ public:
         program()->setUniformValue("texture", 0);
         glFuncs = QGLContext::currentContext()->functions();
         m_timestamp_id = program()->uniformLocation("timestamp");
+        m_entry_id = program()->uniformLocation("entry");
     }
 
     void updateState(const ColoredMaterialData* d, const ColoredMaterialData*) {
@@ -320,9 +331,11 @@ public:
         d->texture->bind();
 
         program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
+        program()->setUniformValue(m_entry_id, (float) d->entry);
     }
 
     int m_timestamp_id;
+    int m_entry_id;
     QByteArray m_vertex_code;
     QByteArray m_fragment_code;
     QGLFunctions* glFuncs;
@@ -377,6 +390,7 @@ public:
         program()->setUniformValue("texture", 0);
         glFuncs = QGLContext::currentContext()->functions();
         m_timestamp_id = program()->uniformLocation("timestamp");
+        m_entry_id = program()->uniformLocation("entry");
     }
 
     void updateState(const SimpleMaterialData* d, const SimpleMaterialData*) {
@@ -384,9 +398,11 @@ public:
         d->texture->bind();
 
         program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
+        program()->setUniformValue(m_entry_id, (float) d->entry);
     }
 
     int m_timestamp_id;
+    int m_entry_id;
     QByteArray m_vertex_code;
     QByteArray m_fragment_code;
     QGLFunctions* glFuncs;
@@ -463,6 +479,21 @@ public:
 /*!
     \qmlproperty list<Sprite> QtQuick.Particles2::ImageParticle::sprites
 */
+/*!
+    \qmlproperty EntryEffect QtQuick.Particles2::ImageParticle::entryEffect
+
+    This property provides basic and cheap entrance and exit effects for the particles.
+    For fine-grained control, see sizeTable and opacityTable.
+
+    Acceptable values are
+    \list
+    \o None: Particles just appear and disappear.
+    \o Fade: Particles fade in from 0. opacity at the start of their life, and fade out to 0. at the end.
+    \o Scale: Particles scale in from 0 size at the start of their life, and scale back to 0 at the end.
+    \endlist
+
+    Default value is Fade.
+*/
 
 
 QSGImageParticle::QSGImageParticle(QSGItem* parent)
@@ -488,6 +519,7 @@ QSGImageParticle::QSGImageParticle(QSGItem* parent)
     , perfLevel(Unknown)
     , m_lastLevel(Unknown)
     , m_debugMode(false)
+    , m_entryEffect(Fade)
 {
     setFlag(ItemHasContents);
     m_debugMode = qmlParticlesDebug();
@@ -690,6 +722,16 @@ void QSGImageParticle::setBloat(bool arg)
         reset();
 }
 
+void QSGImageParticle::setEntryEffect(EntryEffect arg)
+{
+    if (m_entryEffect != arg) {
+        m_entryEffect = arg;
+        if (m_material)
+            getState<ImageMaterialData>(m_material)->entry = (qreal) m_entryEffect;
+        emit entryEffectChanged(arg);
+    }
+}
+
 void QSGImageParticle::reset()
 {
     QSGParticlePainter::reset();
@@ -859,6 +901,7 @@ QSGGeometryNode* QSGImageParticle::buildParticleNodes()
             m_material = SimpleMaterial::createMaterial();
         getState<ImageMaterialData>(m_material)->texture = sceneGraphEngine()->createTextureFromImage(image);
         getState<ImageMaterialData>(m_material)->texture->setFiltering(QSGTexture::Linear);
+        getState<ImageMaterialData>(m_material)->entry = (qreal) m_entryEffect;
         m_material->setFlag(QSGMaterial::Blending);
     }
 
index ff21556..eb890e2 100644 (file)
@@ -176,7 +176,10 @@ class QSGImageParticle : public QSGParticlePainter
     //yVector is the same, but top-left to bottom-left. The particle is always a parallelogram.
     Q_PROPERTY(QSGStochasticDirection* yVector READ yVector WRITE setYVector NOTIFY yVectorChanged)
     Q_PROPERTY(QDeclarativeListProperty<QSGSprite> sprites READ sprites)
+
+    Q_PROPERTY(EntryEffect entryEffect READ entryEffect WRITE setEntryEffect NOTIFY entryEffectChanged)
     Q_PROPERTY(bool bloat READ bloat WRITE setBloat NOTIFY bloatChanged)//Just a debugging property to bypass optimizations
+    Q_ENUMS(EntryEffect)
 public:
     explicit QSGImageParticle(QSGItem *parent = 0);
     virtual ~QSGImageParticle();
@@ -185,6 +188,12 @@ public:
     QDeclarativeListProperty<QSGSprite> sprites();
     QSGSpriteEngine* spriteEngine() {return m_spriteEngine;}
 
+    enum EntryEffect {
+        None = 0,
+        Fade = 1,
+        Scale = 2
+    };
+
     enum PerformanceLevel{//TODO: Expose?
         Unknown = 0,
         Simple,
@@ -240,6 +249,8 @@ public:
 
     bool bloat() const { return m_bloat; }
 
+    EntryEffect entryEffect() const { return m_entryEffect; }
+
 signals:
 
     void imageChanged();
@@ -277,6 +288,8 @@ signals:
 
     void bloatChanged(bool arg);
 
+    void entryEffectChanged(EntryEffect arg);
+
 public slots:
     void reloadColor(const Color4ub &c, QSGParticleData* d);
     void setAlphaVariation(qreal arg);
@@ -305,6 +318,8 @@ public slots:
 
     void setBloat(bool arg);
 
+    void setEntryEffect(EntryEffect arg);
+
 protected:
     void reset();
     virtual void initialize(int gIdx, int pIdx);
@@ -385,6 +400,7 @@ private:
     MaterialData* getState(QSGMaterial* m){
         return static_cast<QSGSimpleMaterial<MaterialData> *>(m)->state();
     }
+    EntryEffect m_entryEffect;
 };
 
 QT_END_NAMESPACE