Port the sparkle effect demo 76/86876/15
authorPaul Wisbey <p.wisbey@samsung.com>
Mon, 5 Sep 2016 09:44:53 +0000 (10:44 +0100)
committerPaul Wisbey <p.wisbey@samsung.com>
Thu, 8 Sep 2016 14:49:18 +0000 (15:49 +0100)
(Based on original demo by Xiangyin Ma)

Change-Id: I9ac5d9b9c4cb18a21d0a12fae0225af5527e405e

15 files changed:
demo/dali-demo.cpp
examples/sparkle/sparkle-effect-example.cpp [new file with mode: 0644]
examples/sparkle/sparkle-effect.h [new file with mode: 0644]
resources/images/sparkle_normal_background.png [new file with mode: 0755]
resources/images/sparkle_particle.png [new file with mode: 0755]
resources/po/as.po
resources/po/de.po
resources/po/en_GB.po
resources/po/en_US.po
resources/po/es.po
resources/po/ko.po
resources/po/ml.po
resources/po/ur.po
resources/po/zn_CH.po
shared/dali-demo-strings.h

index 28b1082..9df0c52 100644 (file)
@@ -81,6 +81,7 @@ int DALI_EXPORT_API main(int argc, char **argv)
   demo.AddExample(Example("mesh-visual.example", DALI_DEMO_STR_TITLE_MESH_VISUAL));
   demo.AddExample(Example("primitive-shapes.example", DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES));
   demo.AddExample(Example("styling.example", DALI_DEMO_STR_TITLE_STYLING));
+  demo.AddExample(Example("sparkle.example", DALI_DEMO_STR_TITLE_SPARKLE));
 
   demo.SortAlphabetically( true );
 
diff --git a/examples/sparkle/sparkle-effect-example.cpp b/examples/sparkle/sparkle-effect-example.cpp
new file mode 100644 (file)
index 0000000..1cc465a
--- /dev/null
@@ -0,0 +1,568 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+#include <sstream>
+#include <algorithm>
+#include <map>
+
+#include "shared/utility.h"
+#include "sparkle-effect.h"
+
+using namespace Dali;
+using Dali::Toolkit::ImageView;
+
+using namespace SparkleEffect;
+
+namespace // unnamed namespace
+{
+
+//background image for normal status
+const char * const CIRCLE_BACKGROUND_IMAGE( DEMO_IMAGE_DIR "sparkle_normal_background.png" );
+//particle shape image
+const char * const PARTICLE_IMAGE( DEMO_IMAGE_DIR "sparkle_particle.png" );
+
+float EaseOutSquare( float progress )
+{
+  return 1.0f - (1.0f-progress) * (1.0f-progress);
+}
+
+float CustomBounce( float progress )
+{
+  float p = 1.f-progress;
+  p *=p;
+  return 17.68f*p*p*p*progress;
+}
+
+float Mix( const Vector2& range, float a )
+{
+  return range.x * a + range.y*(1.f-a)-0.001f;
+}
+
+const Vector4 BACKGROUND_COLOR( 0.f, 0.f, 0.05f, 1.f );
+
+} // unnamed namespace
+
+// This example shows a sparkle particle effect
+//
+class SparkleEffectExample : public ConnectionTracker
+{
+public:
+
+  /**
+   * Create the SparkleEffectExample
+   * @param[in] application The DALi application instance
+   */
+  SparkleEffectExample( Application& application )
+  : mApplication( application ),
+    mAnimationIndex( 0u ),
+    mShaking( false )
+  {
+    mApplication.InitSignal().Connect( this, &SparkleEffectExample::OnInit );
+  }
+
+private:
+
+  /**
+   * Initialize the SparkleEffectExample
+   * @param[in] application The DALi application instance
+   */
+  void OnInit( Application& application )
+  {
+    Stage stage = Stage::GetCurrent();
+    stage.KeyEventSignal().Connect(this, &SparkleEffectExample::OnKeyEvent);
+    stage.SetBackgroundColor( BACKGROUND_COLOR );
+
+    mCircleBackground = ImageView::New( CIRCLE_BACKGROUND_IMAGE );
+    mCircleBackground.SetParentOrigin( ParentOrigin::CENTER );
+    mCircleBackground.SetAnchorPoint( AnchorPoint::CENTER );
+
+    stage.Add( mCircleBackground );
+
+    mEffect = SparkleEffect::New();
+
+    mMeshActor = CreateMeshActor();
+
+    stage.Add( mMeshActor );
+
+    mMeshActor.SetPosition( ACTOR_POSITION );
+    mMeshActor.SetScale( ACTOR_SCALE );
+
+    mTapDetector = TapGestureDetector::New();
+    mTapDetector.Attach(mCircleBackground);
+    mTapDetector.DetectedSignal().Connect( this, &SparkleEffectExample::OnTap );
+
+    mPanGestureDetector = PanGestureDetector::New();
+    mPanGestureDetector.DetectedSignal().Connect( this, &SparkleEffectExample::OnPan );
+    mPanGestureDetector.Attach( mCircleBackground );
+
+    PlayWanderAnimation( 35.f );
+  }
+
+  /**
+   * Create the mesh representing all the particles
+   */
+  Actor CreateMeshActor()
+  {
+    // shuffling to assign the color in random order
+    unsigned int* shuffleArray = new unsigned int[NUM_PARTICLE];
+    for( unsigned int i = 0; i<NUM_PARTICLE; i++ )
+    {
+      shuffleArray[i] = i;
+    }
+    std::random_shuffle(&shuffleArray[0],&shuffleArray[NUM_PARTICLE]);
+
+    // Create vertices
+
+    std::vector< Vertex > vertices;
+    std::vector< unsigned short > faces;
+
+    for( unsigned int i = 0; i<NUM_PARTICLE; i++ )
+    {
+      float colorIndex = GetColorIndex( shuffleArray[i] );
+      AddParticletoMesh( vertices, faces, PATHS[i], colorIndex );
+    }
+
+    delete [] shuffleArray;
+
+    Property::Map vertexFormat;
+    vertexFormat["aTexCoord"] = Property::VECTOR2;
+    vertexFormat["aParticlePath0"] = Property::VECTOR2;
+    vertexFormat["aParticlePath1"] = Property::VECTOR2;
+    vertexFormat["aParticlePath2"] = Property::VECTOR2;
+    vertexFormat["aParticlePath3"] = Property::VECTOR2;
+    vertexFormat["aParticlePath4"] = Property::VECTOR2;
+    vertexFormat["aParticlePath5"] = Property::VECTOR2;
+
+    PropertyBuffer propertyBuffer = PropertyBuffer::New( vertexFormat );
+    propertyBuffer.SetData( &vertices[0], vertices.size() );
+
+    Geometry geometry = Geometry::New();
+    geometry.AddVertexBuffer( propertyBuffer );
+    geometry.SetIndexBuffer( &faces[0], faces.size() );
+    geometry.SetType( Geometry::TRIANGLES );
+
+    Texture particleTexture = DemoHelper::LoadTexture( PARTICLE_IMAGE );
+    TextureSet textureSet = TextureSet::New();
+    textureSet.SetTexture( 0u, particleTexture );
+
+    Renderer renderer = Renderer::New( geometry, mEffect );
+    renderer.SetTextures( textureSet );
+
+    Actor meshActor = Actor::New();
+    meshActor.SetParentOrigin( ParentOrigin::CENTER );
+    meshActor.SetSize( 1, 1 );
+    meshActor.AddRenderer( renderer );
+
+    return meshActor;
+  }
+
+  /**
+   * Defines a rule to assign particle with a color according to its index
+   */
+  float GetColorIndex( unsigned int particleIndex )
+  {
+    unsigned int thereshold = 0;
+    for( unsigned int i = 0; i<NUM_COLOR; i++ )
+    {
+      thereshold += PARTICLE_COLORS[i].numParticle;
+      if( particleIndex < thereshold)
+      {
+        return i + Mix( PARTICLE_COLORS[i].AlphaRange, static_cast<float>(thereshold-particleIndex)/PARTICLE_COLORS[i].numParticle );
+      }
+    }
+    return NUM_COLOR-1;
+  }
+
+  /**
+   * All a particle to the mesh by giving the moving path and color index
+   *
+   * Two triangles per particle
+   *  0---------3
+   *   |\      |
+   *   |  \    |
+   *   |    \  |
+   *   |      \|
+   *  1---------2
+   *
+   * The information we need to pass in through attribute include:
+   *
+   *   path which contains 12 integer
+   *          ---- passed in 6 Vector2 attributes
+   *
+   *   color index, particle index and textureCoor( (0,0) or (1,0) or (0,1) or (1,1)  )
+   *          ---- package these info into texCood attribute as: (+-colorIndex, +-particleIndex)
+   */
+  void AddParticletoMesh( std::vector< Vertex >& vertices,
+                          std::vector< unsigned short >& faces,
+                          MovingPath& movingPath,
+                          float colorIndex )
+  {
+    unsigned int idx = vertices.size();
+
+    // store the path into position and normal, which would be decoded inside the shader
+    Vector2 particlePath0( movingPath[0],  movingPath[1] );
+    Vector2 particlePath1( movingPath[2],  movingPath[3] );
+    Vector2 particlePath2( movingPath[4],  movingPath[5] );
+    Vector2 particlePath3( movingPath[6],  movingPath[7] );
+    Vector2 particlePath4( movingPath[8],  movingPath[9] );
+    Vector2 particlePath5( movingPath[10], movingPath[11] );
+
+    float particleIdx = static_cast<float>(idx/4 + 1); // count from 1
+    float colorIdx = colorIndex+1.f; // count from 1
+    vertices.push_back( Vertex( Vector2(-colorIdx, -particleIdx), particlePath0, particlePath1, particlePath2, particlePath3, particlePath4, particlePath5 ) );
+    vertices.push_back( Vertex( Vector2(-colorIdx,  particleIdx), particlePath0, particlePath1, particlePath2, particlePath3, particlePath4, particlePath5 ) );
+    vertices.push_back( Vertex( Vector2( colorIdx,  particleIdx), particlePath0, particlePath1, particlePath2, particlePath3, particlePath4, particlePath5 ) );
+    vertices.push_back( Vertex( Vector2( colorIdx, -particleIdx), particlePath0, particlePath1, particlePath2, particlePath3, particlePath4, particlePath5 ) );
+
+    faces.push_back(idx);
+    faces.push_back(idx+1);
+    faces.push_back(idx+2);
+
+    faces.push_back(idx);
+    faces.push_back(idx+2);
+    faces.push_back(idx+3);
+  }
+
+  /*
+   * Main key event handler
+   */
+  void OnKeyEvent(const KeyEvent& event)
+  {
+    if(event.state == KeyEvent::Down)
+    {
+      if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
+      {
+        mApplication.Quit();
+      }
+    }
+  }
+
+  /**
+   * Callback of the TapGesture
+   */
+  void OnTap( Actor actor, const TapGesture& tap )
+  {
+    {
+      PlayTapAnimation(5.f, tap.localPoint);
+    }
+  }
+
+  /**
+   * Callback of the PanGesture
+   */
+  void OnPan( Actor actor, const PanGesture& gesture )
+  {
+    if( gesture.state == Gesture::Finished )
+    {
+      switch(mAnimationIndex)
+      {
+      case 0:
+      {
+        PlayParticleFadeAnimation(0, NUM_PARTICLE, 0.f, 3.f );
+        break;
+      }
+      case 1:
+      {
+        PlayBreakAnimation(2.0f);
+        break;
+      }
+      case 2:
+      {
+        PlayShakeAnimation(0.5f, 2.5f);
+        break;
+      }
+      default:
+      {
+        break;
+      }
+     }
+
+      mAnimationIndex = (mAnimationIndex+1)%3;
+    }
+  }
+
+  /**
+   * Animate the particle position to make them wandering on the screen with 'seemingly' random fade in/out
+   * @param[in] duration The duration for the particle to move a cycle on the path. the bigger this value the slower the floating movement.
+   * @param[in] looping Infinite playing or not
+   */
+  void PlayWanderAnimation( float duration, bool looping = true )
+  {
+    Animation wanderAnimation= Animation::New(duration);
+    wanderAnimation.AnimateTo( Property( mEffect, PERCENTAGE_UNIFORM_NAME ), 1.f );
+    wanderAnimation.SetLooping(looping); // infinite playing
+
+    wanderAnimation.Play();
+  }
+
+  /**
+   * Accelerate the particle moving speed
+   * @param[in] cycle How many extra cycles to move during the animation
+   * @param[in] duration The duration for the animation
+   */
+  void PlayShakeAnimation(  float cycle, float duration )
+  {
+    if( mShaking )
+    {
+      return;
+    }
+    DestroyAnimation( mTapAnimationAux );
+
+    float accelaration = GetFloatUniformValue( ACCELARATION_UNIFORM_NAME );
+    mEffect.SetProperty( mEffect.GetPropertyIndex(ACCELARATION_UNIFORM_NAME), accelaration - int( accelaration) ); // Set the value as its fractional part
+    Animation shakeAnimation = Animation::New(duration);
+    shakeAnimation.AnimateBy( Property( mEffect, ACCELARATION_UNIFORM_NAME ), cycle, AlphaFunction::EASE_OUT );
+    shakeAnimation.FinishedSignal().Connect( this, &SparkleEffectExample::OnShakeAnimationFinished );
+
+    shakeAnimation.Play();
+    mShaking = true;
+  }
+
+  /**
+   * Animate the particles to appear from center and spread all over around
+   * @param[in] duration The duration for the animation
+   */
+  void PlayBreakAnimation( float duration )
+  {
+    if( GetFloatUniformValue(BREAK_UNIFORM_NAME) > 0.f )
+    {
+      return;
+    }
+
+    // Stop the fading / tap animation before the breaking
+    DestroyAnimation( mFadeAnimation);
+    mTapIndices.x = mTapIndices.y;
+    mEffect.SetProperty( mEffect.GetPropertyIndex( TAP_INDICES_UNIFORM_NAME ), mTapIndices );
+    mEffect.SetProperty( mEffect.GetPropertyIndex( ACCELARATION_UNIFORM_NAME ), 0.f );
+
+    // prepare the animation by setting the uniform to the required value
+    mEffect.SetProperty( mEffect.GetPropertyIndex( BREAK_UNIFORM_NAME ), 1.f );
+    mMeshActor.SetScale(0.01f);
+    mEffect.SetProperty( mEffect.GetPropertyIndex( "uScale" ), 0.01f );
+    mMeshActor.SetPosition( 0.f, 0.f, 1.f );
+
+    Animation breakAnimation = Animation::New(duration*1.5f);
+    breakAnimation.AnimateTo( Property(mMeshActor, Actor::Property::SCALE), Vector3(ACTOR_SCALE,ACTOR_SCALE,ACTOR_SCALE), EaseOutSquare);
+    breakAnimation.AnimateTo( Property( mEffect, "uScale" ), ACTOR_SCALE, EaseOutSquare);
+    breakAnimation.AnimateTo( Property(mMeshActor, Actor::Property::POSITION), ACTOR_POSITION, EaseOutSquare);
+    breakAnimation.FinishedSignal().Connect( this, &SparkleEffectExample::OnBreakAnimationFinished );
+
+    float timeUnit = duration/ (NUM_PARTICLE+1) /(NUM_PARTICLE+1) ;
+    std::ostringstream oss;
+    for(unsigned int i = 0; i<NUM_PARTICLE; i++)
+    {
+      oss.str("");
+      oss<< OPACITY_UNIFORM_NAME<< i << "]";
+      mEffect.SetProperty( mEffect.GetPropertyIndex( oss.str() ), 0.01f);
+      float timeSlice = timeUnit*i*i;
+      breakAnimation.AnimateTo( Property( mEffect, oss.str() ), 1.f, AlphaFunction::EASE_IN_OUT_SINE, TimePeriod( timeSlice*0.5f, timeSlice ) );
+    }
+
+    breakAnimation.Play();
+  }
+
+  /**
+   * Animate the particle opacity
+   * Particles with index between startIndex ~ startIndex+numParticle-1 fade to the target opacity one after another
+   * @param[in] startIndex The index of the first particle
+   * @param[in] numParticle The number of particle to change opacity
+   * @param[in] targetValue The final opacity
+   * @param[in] duration The duration for the animation
+   */
+  void PlayParticleFadeAnimation( unsigned int startIndex, unsigned int numParticle, float targetValue, float duration )
+  {
+    if( GetFloatUniformValue(BREAK_UNIFORM_NAME) > 0.f )
+    {
+      return;
+    }
+
+    // start the opacity animation one particle after another gradually
+    float timeSlice = duration / (numParticle+1);
+    float fadeDuration = timeSlice>0.5f ? timeSlice : 0.5f;
+
+    Animation fadeAnimation= Animation::New(duration+fadeDuration*2.f);
+    std::ostringstream oss;
+    for(unsigned int i = startIndex; i<numParticle; i++)
+    {
+      if( i>=NUM_PARTICLE ) break; // out of bound
+
+      oss.str("");
+      oss<< OPACITY_UNIFORM_NAME<< i << "]";
+      fadeAnimation.AnimateTo(Property( mEffect, oss.str()), targetValue, TimePeriod( timeSlice*i, fadeDuration*2.f ));
+    }
+
+    fadeAnimation.Play();
+    mFadeAnimation = fadeAnimation;
+    mFadeAnimation.FinishedSignal().Connect( this, &SparkleEffectExample::OnFadeAnimationFinished );
+  }
+
+  /**
+   * Push the particles to the edge all around the circle then bounce back
+   * @param[in] duration The duration for the animation
+   * @param[in] tapPoint The position of the tap point
+   */
+  void PlayTapAnimation(float duration, const Vector2& tapPoint )
+  {
+    if( mTapIndices.y > mTapIndices.x && mTapAnimation.GetCurrentProgress() < 0.2f)
+    {
+      return;
+    }
+
+    Animation animation= Animation::New(duration);
+    int idx = int(mTapIndices.y)%MAXIMUM_ANIMATION_COUNT;
+    mTapIndices.y += 1.f;
+
+    std::ostringstream oss;
+    oss<< TAP_OFFSET_UNIFORM_NAME<< idx << "]";
+    mEffect.SetProperty( mEffect.GetPropertyIndex( oss.str() ), 0.f);
+    animation.AnimateTo( Property( mEffect, oss.str() ), 0.75f, CustomBounce);
+
+    oss.str("");
+    oss<< TAP_POINT_UNIFORM_NAME<< idx << "]";
+    mEffect.SetProperty( mEffect.GetPropertyIndex( oss.str() ), tapPoint/ACTOR_SCALE);
+
+    mEffect.SetProperty( mEffect.GetPropertyIndex( TAP_INDICES_UNIFORM_NAME ), mTapIndices);
+
+    if(!mShaking)
+    {
+      mTapAnimationAux = Animation::New(duration*0.2f);
+      mTapAnimationAux.AnimateBy( Property( mEffect, ACCELARATION_UNIFORM_NAME ), 0.15f, AlphaFunction::EASE_IN_OUT );
+      mTapAnimationAux.Play();
+    }
+    animation.Play();
+    mTapAnimationIndexPair[animation] = static_cast<int>(mTapIndices.y -1.f);
+    animation.FinishedSignal().Connect( this, &SparkleEffectExample::OnTapAnimationFinished );
+    mTapAnimation = animation;
+  }
+
+  /**
+   * Callback of the animation finished signal
+   */
+  void OnShakeAnimationFinished( Animation& animation)
+  {
+    mShaking = false;
+  }
+
+  /**
+   * Callback of the animation finished signal
+   */
+  void OnFadeAnimationFinished( Animation& animation)
+  {
+    mFadeAnimation.Clear();
+    mFadeAnimation.Reset();
+  }
+
+  /**
+   * Callback of the animation finished signal
+   */
+  void OnBreakAnimationFinished( Animation& animation)
+  {
+    mEffect.SetProperty( mEffect.GetPropertyIndex( BREAK_UNIFORM_NAME ), 0.f );
+  }
+
+  /**
+   * Callback of the animation finished signal
+   */
+  void OnTapAnimationFinished( Animation& animation )
+  {
+    if( mTapAnimationIndexPair[animation] ==  static_cast<int>(mTapIndices.x) )
+    {
+      mTapIndices.x += 1.f;
+      if( mTapIndices.x >= mTapIndices.y )
+      {
+        mTapIndices = Vector2::ZERO;
+      }
+      mEffect.SetProperty( mEffect.GetPropertyIndex( TAP_INDICES_UNIFORM_NAME ), mTapIndices);
+    }
+
+    mTapAnimationIndexPair.erase( animation );
+    if( mTapAnimationIndexPair.size() < 1 && mTapIndices != Vector2::ZERO)
+    {
+      mTapIndices = Vector2::ZERO;
+      mEffect.SetProperty( mEffect.GetPropertyIndex( TAP_INDICES_UNIFORM_NAME ), mTapIndices);
+    }
+
+    animation.Clear();
+    animation.Reset();
+  }
+
+  /**
+   * Helper retrieve a uniform value from the Sparkle effect shader
+   * @param[in] uniformName The uniform
+   * @return The float value
+   */
+  float GetFloatUniformValue( const std::string& uniformName )
+  {
+    float value;
+    mEffect.GetProperty(mEffect.GetPropertyIndex(uniformName)).Get(value);
+    return value;
+  }
+
+  /**
+   * Terminate the given animation
+   */
+  void DestroyAnimation( Animation& animation )
+  {
+    if( animation )
+    {
+      animation.Clear();
+      animation.Reset();
+    }
+  }
+
+private:
+
+  Application&       mApplication;
+  Shader             mEffect;
+  ImageView          mCircleBackground;
+  Actor              mMeshActor;
+
+  PanGestureDetector mPanGestureDetector;
+  TapGestureDetector mTapDetector;
+
+  Animation          mFadeAnimation;
+  Animation          mTapAnimation;
+  Animation          mTapAnimationAux;
+
+  Vector2            mTapIndices;
+  unsigned int       mAnimationIndex;
+  bool               mShaking;
+
+  std::map< Animation, int > mTapAnimationIndexPair;
+};
+
+void RunTest( Application& application )
+{
+  SparkleEffectExample theApp( application );
+
+  application.MainLoop();
+}
+
+// Entry point for Linux & Tizen applications
+//
+int DALI_EXPORT_API main( int argc, char **argv )
+{
+  Application application = Application::New( &argc, &argv );
+
+  RunTest( application );
+
+  return 0;
+}
+
diff --git a/examples/sparkle/sparkle-effect.h b/examples/sparkle/sparkle-effect.h
new file mode 100644 (file)
index 0000000..f37e1e6
--- /dev/null
@@ -0,0 +1,393 @@
+#ifndef DALI_SPARKLE_EFFECT_H
+#define DALI_SPARKLE_EFFECT_H
+
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+using namespace Dali;
+using Dali::Toolkit::ImageView;
+
+/************************************************************/
+/* Custom sparkle effect shader******************************/
+/************************************************************/
+
+namespace SparkleEffect
+{
+  // uniform which controls the position of particle on the path
+  const std::string PERCENTAGE_UNIFORM_NAME( "uPercentage" );
+  // uniform array of particle color, set their value as the PARTICLE_COLORS given below
+  const std::string PARTICLE_COLOR_UNIFORM_NAME("uParticleColors[");
+  // uniform array of particle opacity
+  const std::string OPACITY_UNIFORM_NAME("uOpacity[");
+  // uniform which offsets the path control point, with this values >=0, the paths are squeezed towards the GatheringPoint
+  const std::string ACCELARATION_UNIFORM_NAME("uAcceleration");
+  // uniform which indicates the ongoing tap animations
+  const std::string TAP_INDICES_UNIFORM_NAME("uTapIndices");
+  // uniform which controls how much the offset of the midpoints relative to the start/end points of the cubic bezier curve when the path is squeezed for tap animation
+  const std::string TAP_OFFSET_UNIFORM_NAME("uTapOffset[");
+  // uniform which gives the position of the tapping, in this way the particles will be pushed away from this point
+  const std::string TAP_POINT_UNIFORM_NAME("uTapPoint[");
+  // uniform which trigger the break animation, set to 1.0 when break animation is playing, otherwise set to 0.0
+  const std::string BREAK_UNIFORM_NAME("uBreak");
+
+  /****************particle colors******************/
+
+  struct ParticleColor
+  {
+    Vector3 RGB;
+    Vector2 AlphaRange;
+    unsigned int numParticle;
+  };
+
+  ParticleColor PARTICLE_COLORS[]=
+  {
+    { Vector3( 0.f,   240.f, 255.f )/255.f, Vector2( 0.2f, 1.f ),  22 }, // 00f0ff, opacity 20%~100%
+    { Vector3( 89.f,  151.f, 239.f )/255.f, Vector2( 0.2f, 0.5f ), 12 }, // 5997ef, opacity 20%~50%
+    { Vector3( 181.f, 181.f, 207.f )/255.f, Vector2( 0.5f, 1.f ),  22 }, // b5b5cf, opacity 50%~100%
+    { Vector3( 147.f, 147.f, 170.f )/255.f, Vector2( 0.5f, 0.5f ), 22 }, // 9393aa, opacity 50%~50%
+    { Vector3( 145.f, 145.f, 201.f )/255.f, Vector2( 1.f, 1.f ),   12 }, // 91bdc9, opacity 100%~100%
+    { Vector3( 145.f, 145.f, 201.f )/255.f, Vector2( 0.2f, 0.2f ), 21 }  // 91bdc9, opacity 20%~20%
+  };
+  const unsigned int NUM_COLOR( sizeof( PARTICLE_COLORS ) / sizeof( PARTICLE_COLORS[0] ) );
+
+  /***************particle moving paths********************/
+
+  typedef int MovingPath[12];
+
+  // these paths are defined inside the circle which has the center at (250, 250) and the radius as 250
+  MovingPath PATHS[]=
+  { // each path is composed of two cubic b-curves: (p0, p1, p2, p3) & (p3, p4, p5, p0)
+    // p0        p1        p2       p3        p4        p5
+    { 280,273,  386,41,  489,141,  491,199,  494,256,  230,394  },
+    { 129,226,  357,120, 150,491,  291,406,  433,320,  47,283   },
+    { 96,264,   356,133, 446,196,  370,297,  294,399,  -169,384 },
+    { 345,110,  359,186,  14,393,  4,247,  -6,101,  321,-28 },
+    { 166,161,  128,353,  566,200,  487,304,  413,403,  203,-32 },
+    { 193,286,  106,331,  206,569,  334,477,  462,385,  279,240 },
+    { 336,247,  293,232,  301,465,  346,479,  390,493,  374,261 },
+    { 250,72,  314,72,  332,495,  250,497,  168,499,  161,72 },
+    { 48,387,  32,241,  452,558,  433,358,  411,121,  62,523 },
+    { 300,32,  159,27,  442,568,  186,492,  -70,415,  551,41 },
+    { 479,150,  503,203,  216,403,  163,298,  110,193,  448,78 },
+    { 346,75,  311,97,  336,196,  389,160,  442,123,  383,51 },
+    { 90,61,  54,96,  218,373,  294,300,  370,227,  141,11 },
+    { 126,225,  240,280,  378,29,  221,16,  64,4,  11,170 },
+    { 308,101,  243,22,  -10,271,  22,352,  49,422,  396,208 },
+    { 193,188,  174,302,  502,389,  500,250,  498,111,  212,72 },
+    { 227,3,  16,35,  577,309,  428,423,  279,537,  438,-28 },
+    { 410,58,  387,18,  22,179,  154,277,  286,374,  459,142 },
+    { 178,272,  109,299,  144,429,  218,396,  293,362,  221,254 },
+    { 247,46,  98,5,  -91,357,  160,431,  412,505,  397,88 },
+    { 41,112,  22,144,  123,273,  158,187,  192,101,  75,56 },
+    { 8,300,  23,340,  267,294,  238,218,  209,142,  -20,226 },
+    { 112,256,  24,270,  -1,470,  154,433,  308,396,  201,242 },
+    { 212,277,  267,346,  509,202,  452,103,  398,8,  150,199 },
+    { 154,205,  146,287,  496,282,  492,194,  488,107,  160,140 },
+    { 281,350,  365,318,  415,476,  332,482,  248,489,  204,379 },
+    { 327,23,  346,81,  154,319,  123,207,  92,95,  313,-21 },
+    { 323,233,  283,307,  454,420,  478,354,  501,288,  374,136 },
+    { 318,186,  311,252,  488,248,  481,168,  474,87,  328,76 },
+    { 7,192,  -10,270,  249,398,  269,307,  290,216,  25,111 },
+    { 148,22,  98,22,  25,458,  125,458,  225,458,  198,22 },
+    { 349,32,  307,39,  492,416,  399,446,  305,477,  460,16 },
+    { 147,474,  222,554,  392,154,  486,240,  581,325,  73,394 },
+    { 57,186,  13,200,  51,398,  114,374,  178,349,  97,174 },
+    { 257,192,  198,188,  162,345,  240,349,  319,354,  316,197 },
+    { 242,4,  283,21,  30,172,  81,215,  133,257,  209,-10 },
+    { 149,408,  165,442,  472,340,  444,275,  416,210,  120,348 },
+    { 106,271,  136,359,  483,370,  422,186,  360,2,  76,186 },
+    { 120,146,  29,224,  469,262,  346,390,  222,518,  393,-87 },
+    { 318,265,  415,280,  398,537,  247,491,  96,446,  222,249 },
+    { 171,275,  207,246,  274,469,  237,497,  199,525,  139,300 },
+    { 196,84,  135,105,  256,510,  334,486,  412,462,  280,55 },
+    { 485,314,  452,170,  158,606,  111,411,  55,179,  515,446 },
+    { 134,54,  266,4,  175,607,  392,451,  609,296,  -100,144 },
+    { 3,229,  -1,287,  334,383,  350,267,  366,150,  10,151 },
+    { 105,115,  146,125,  154,227,  92,209,  30,192,  62,105 },
+    { 343,20,  388,42,  323,357,  228,313,  132,269,  278,-10 },
+    { 362,186,  271,274,  60,82,  204,19,  349,-44,  453,97 },
+    { 145,128,  181,32,  501,185,  498,272,  495,347,  97,257 },
+    { 286,172,  342,274,  59,463,  16,331,  -27,198,  231,69 },
+    { 194,7,  404,-32,  -38,410,  140,469,  317,528,  -16,45 },
+    { 39,120,  48,74,  445,109,  352,244,  259,379,  20,215 },
+    { 328,247,  402,250,  411,384,  330,377,  248,370,  281,244 },
+    { 189,56,  317,-31,  610,240,  396,392,  183,543,  61,144 },
+    { 402,53,  430,77,  376,231,  315,161,  255,91,  351,10 },
+    { 496,218,  494,260,  249,296,  251,214,  254,133,  498,139 },
+    { 381,210,  469,195,  557,376,  399,391,  241,407,  292,226 },
+    { 297,263,  267,346,  -8,289,  14,176,  35,69,  331,168 },
+    { 329,187,  363,263,  30,371,  5,287,  -19,203,  302,128 },
+    { 257,354,  168,351,  171,516,  252,496,  333,475,  340,356 },
+    { 106,60,  107,121,  366,284,  359,168,  352,52,  105,14 },
+    { 178,257,  240,314,  115,476,  71,421,  28,367,  98,182 },
+    { 163,213,  191,273,  22,327,  3,248,  -17,170,  118,113 },
+    { 459,117,  500,185,  297,390,  248,311,  199,232,  416,46 },
+    { 270,3,  317,-14,  528,375,  434,407,  339,440,  223,19 },
+    { 88,76,  130,68,  78,485,  176,483,  274,482,  -22,96 },
+    { 422,428,  378,528,  88,205,  26,317,  -36,428,  467,328 },
+    { 414,127,  460,125,  489,325,  421,322,  353,320,  372,128 },
+    { 227,197,  281,174,  367,311,  294,340,  221,370,  173,220 },
+    { 180,14,  147,44,  436,104,  401,161,  366,219,  207,-10 },
+    { 400,367,  395,404,  71,406,  77,336,  82,265,  407,300 },
+    { 396,222,  396,316,  71,439,  70,245,  68,51,  396,132 },
+    { 342,109,  454,153,  49,332,  208,413,  367,494,  8,-23 },
+    { 147,167,  222,137,  266,169,  231,199,  197,229,  129,178 },
+    { 227,272,  310,243,  277,313,  322,266,  367,219,  207,313 },
+    { 279,192,  339,233,  396,211,  367,182,  338,152,  228,194 },
+    { 236,20,  283,75,  346,26,  338,71,  330,116,  207,17 },
+    { 129,83,  164,23,  158,14,  179,11,  200,8,  91,78 },
+    { 86,231,  129,293,  164,421,  104,348,  44,275,  66,200 },
+    { 193,328,  197,278,  240,348,  276,305,  311,263,  199,354 },
+    { 231,364,  241,209,  309,104,  326,236,  342,367,  225,424 },
+    { 414,230,  398,328,  446,445,  467,363,  489,281,  373,254 },
+    { 289,122,  332,123,  348,161,  322,158,  297,156,  275,125 },
+    { 142,235,  199,308,  402,229,  283,218,  164,206,  130,206 },
+    { 174,396,  210,387,  328,501,  246,455,  165,409,  138,394 },
+    { 288,388,  366,357,  372,458,  393,400,  414,343,  249,431 },
+    { 351,278,  409,369,  497,316,  437,288,  376,260,  351,243 },
+    { 87,134,  181,77,  311,121,  206,140,  101,160,  61,159 },
+    { 95,195,  126,208,  133,258,  110,236,  88,215,  95,195 },
+    { 140,293,  158,330,  169,275,  184,299,  198,323,  126,313 },
+    { 336,319,  383,357,  388,278,  393,333,  397,388,  311,325 },
+    { 338,107,  434,209,  -37,469,  151,287,  338,104,  285,50 },
+    { 403,134,  446,182,  378,318,  386,233,  393,149,  360,98 },
+    { 366,82,  413,93,  416,158,  390,118,  364,78,  336,75 },
+    { 448,188,  448,230,  465,269,  470,225,  474,181,  448,177 },
+    { 121,398,  142,418,  126,475,  111,436,  96,396,  100,382 },
+    { 40,296,  90,352,  170,310,  143,350,  116,391,  7,300 },
+    { 25,203,  45,241,  70,204,  45,248,  19,293,  4,204 },
+    { 243,222,  225,275,  345,256,  296,237,  247,218,  249,199 },
+    { 159,149,  282,133,  284,199,  226,191,  169,184,  147,160 },
+    { 149,257,  290,322,  151,374,  166,338,  182,302,  116,263 },
+    { 255,285,  354,327,  234,287,  279,327,  323,367,  193,290 },
+    { 188,220,  353,190,  290,354,  348,293,  407,231,  152,248 },
+    { 305,122,  382,174,  402,229,  366,198,  329,167,  297,127 },
+    { 378,260,  406,267,  390,330,  384,293,  377,257,  366,263 },
+    { 178,396,  357,365,  273,461,  248,431,  223,401,  157,412 },
+    { 180,89,  258,88,  302,94,  255,115,  207,136,  166,96 },
+    { 81,197,  139,232,  39,257,  94,259,  150,261,  58,200 },
+    { 314,89,  378,40,  383,38,  389,42,  395,45,  267,90 },
+    { 371,141,  482,233,  508,244,  498,272,  488,299,  307,157 },
+    { 339,348,  361,465,  382,477,  406,442,  430,406,  269,369 }
+  };
+  const unsigned int NUM_PARTICLE( sizeof( PATHS ) / sizeof( PATHS[0] ) );
+
+  const float PARTICLE_SIZE = 13.f;
+
+  const float ACTOR_SCALE = 0.704f; // resize 500*500 to 352*352, a bit smaller than 360*360
+  const Vector3 ACTOR_POSITION( -176.f, -176.f, 1.f);
+
+  const int MAXIMUM_ANIMATION_COUNT = 30;
+
+  // Geometry format used by the SparkeEffect
+  struct Vertex
+  {
+    Vertex( const Vector2& texCoord,
+            const Vector2& aParticlePath0,
+            const Vector2& aParticlePath1,
+            const Vector2& aParticlePath2,
+            const Vector2& aParticlePath3,
+            const Vector2& aParticlePath4,
+            const Vector2& aParticlePath5 )
+    : aTexCoord( texCoord ),
+      aParticlePath0( aParticlePath0 ),
+      aParticlePath1( aParticlePath1 ),
+      aParticlePath2( aParticlePath2 ),
+      aParticlePath3( aParticlePath3 ),
+      aParticlePath4( aParticlePath4 ),
+      aParticlePath5( aParticlePath5 )
+    {
+    }
+
+    Vector2 aTexCoord;
+    Vector2 aParticlePath0;
+    Vector2 aParticlePath1;
+    Vector2 aParticlePath2;
+    Vector2 aParticlePath3;
+    Vector2 aParticlePath4;
+    Vector2 aParticlePath5;
+  };
+
+  /**
+   * Create a SparkleEffect object.
+   * @return A handle to a newly allocated SparkleEffect
+   */
+  Shader New()
+  {
+    std::string vertexShader = DALI_COMPOSE_SHADER(
+      precision highp float;\n
+      \n
+      attribute vec2  aTexCoord;\n
+      uniform   mat4  uMvpMatrix;\n
+      varying   vec2  vTexCoord;\n
+      \n
+      attribute vec2  aParticlePath0;\n
+      attribute vec2  aParticlePath1;\n
+      attribute vec2  aParticlePath2;\n
+      attribute vec2  aParticlePath3;\n
+      attribute vec2  aParticlePath4;\n
+      attribute vec2  aParticlePath5;\n
+      \n
+      uniform float uPercentage;\n
+      uniform float uPercentageMarked;\n
+      uniform vec3  uParticleColors[NUM_COLOR];\n
+      uniform float uOpacity[NUM_PARTICLE];\n
+      uniform vec2  uTapIndices;
+      uniform float uTapOffset[MAXIMUM_ANIMATION_COUNT];\n
+      uniform vec2  uTapPoint[MAXIMUM_ANIMATION_COUNT];\n
+      uniform float uAcceleration;\n
+      uniform float uRadius;\n
+      uniform float uScale;\n
+      uniform float uBreak;\n
+      \n
+      varying lowp vec4 vColor;\n
+      \n
+      void main()\n
+      {\n
+        // we store the particle index inside texCoord attribute
+        float idx = abs(aTexCoord.y)-1.0;\n
+        \n
+        // early out if the particle is invisible
+        if(uOpacity[int(idx)]<1e-5)\n
+        {\n
+          gl_Position = vec4(0.0);\n
+          vColor = vec4(0.0);\n
+          return;\n
+        }\n
+        \n
+        // As the movement along the b-curve has nonuniform speed with a uniform increasing parameter 'uPercentage'
+        // we give different particles the different 'percentage' to make them looks more random
+        float increment = idx / float(NUM_PARTICLE)*5.0;
+        float percentage = mod(uPercentage +uAcceleration+increment, 1.0);
+        \n
+        vec2 p0; vec2 p1; vec2 p2; vec2 p3;
+        // calculate the particle position by using the cubic b-curve equation
+        if(percentage<0.5)\n // particle on the first b-curve
+        {\n
+          p0 = aParticlePath0;\n
+          p1 = aParticlePath1;\n
+          p2 = aParticlePath2;\n
+          p3 = aParticlePath3;\n
+        }\n
+        else\n
+        {\n
+          p0 = aParticlePath3;\n
+          p1 = aParticlePath4;\n
+          p2 = aParticlePath5;\n
+          p3 = aParticlePath0;\n
+        }\n
+        float t = mod( percentage*2.0, 1.0);\n
+        vec2 position = (1.0-t)*(1.0-t)*(1.0-t)*p0 + 3.0*(1.0-t)*(1.0-t)*t*p1+3.0*(1.0-t)*t*t*p2 + t*t*t*p3;\n
+        \n
+        vec2 referencePoint = mix(p0,p3,0.5);\n
+        float maxAnimationCount = float(MAXIMUM_ANIMATION_COUNT);\n
+        \n
+        for( float i=uTapIndices.x; i<uTapIndices.y; i+=1.0 )\n
+        {
+          int id = int( mod(i+0.5,maxAnimationCount ) );\n
+          vec2 edgePoint = normalize(referencePoint-uTapPoint[id])*uRadius+vec2(uRadius);\n
+          position = mix( position, edgePoint, uTapOffset[id] ) ;\n
+        }\n
+        \n
+        position = mix( position, vec2( 250.0,250.0 ),uBreak*(1.0-uOpacity[int(idx)]) ) ;
+        \n
+        // vertex position on the mesh: (sign(aTexCoord.x), sign(aTexCoord.y))*PARTICLE_HALF_SIZE
+        gl_Position = uMvpMatrix * vec4( position.x+sign(aTexCoord.x)*PARTICLE_HALF_SIZE/uScale,
+                                         position.y+sign(aTexCoord.y)*PARTICLE_HALF_SIZE/uScale,
+                                         0.0, 1.0 );\n
+        \n
+        // we store the color index inside texCoord attribute
+        float colorIndex = abs(aTexCoord.x);
+        vColor.rgb = uParticleColors[int(colorIndex)-1];\n
+        vColor.a = fract(colorIndex) * uOpacity[int(idx)];\n
+        \n
+        // produce a 'seemingly' random fade in/out
+        percentage = mod(uPercentage+increment+0.15, 1.0);\n
+        float ramdomOpacity = (min(percentage, 0.25)-0.15+0.9-max(percentage,0.9))*10.0;\n
+        vColor.a *=ramdomOpacity;\n
+        \n
+        vTexCoord = clamp(aTexCoord, 0.0, 1.0);\n
+      }\n
+    );
+
+    std::string fragmentShader = DALI_COMPOSE_SHADER(
+        precision highp float;\n
+        uniform sampler2D sTexture;\n
+        varying vec2      vTexCoord;\n
+        \n
+        varying lowp vec4 vColor;\n
+        \n
+        void main()\n
+        {\n
+          gl_FragColor = vColor;\n
+          gl_FragColor.a *= texture2D(sTexture, vTexCoord).a;\n
+        }\n
+    );
+
+    std::ostringstream vertexShaderStringStream;
+    vertexShaderStringStream<< "#define NUM_COLOR "<< NUM_COLOR << "\n"
+                            << "#define NUM_PARTICLE "<< NUM_PARTICLE << "\n"
+                            << "#define PARTICLE_HALF_SIZE "<< PARTICLE_SIZE*ACTOR_SCALE/2.f << "\n"
+                            << "#define MAXIMUM_ANIMATION_COUNT "<<MAXIMUM_ANIMATION_COUNT<<"\n"
+                            << vertexShader;
+
+    Shader handle = Shader::New( vertexShaderStringStream.str(), fragmentShader );
+
+    // set the particle colors
+    std::ostringstream oss;
+    for( unsigned int i = 0; i < NUM_COLOR; i++ )
+    {
+      oss.str("");
+      oss<< PARTICLE_COLOR_UNIFORM_NAME<< i << "]";
+      handle.RegisterProperty(oss.str(), PARTICLE_COLORS[i].RGB);
+    }
+    handle.RegisterProperty( "uRadius", 250.f );
+    handle.RegisterProperty( "uScale", ACTOR_SCALE );
+
+    // set the initial uniform values
+
+    for( unsigned int i = 0; i < NUM_PARTICLE; i++ )
+    {
+      oss.str("");
+      oss<< OPACITY_UNIFORM_NAME << i << "]";
+      handle.RegisterProperty(oss.str(), 1.f);
+    }
+    handle.RegisterProperty( PERCENTAGE_UNIFORM_NAME, 0.f );
+    handle.RegisterProperty( ACCELARATION_UNIFORM_NAME, 0.f );
+    handle.RegisterProperty( BREAK_UNIFORM_NAME, 0.f);
+    handle.RegisterProperty( TAP_INDICES_UNIFORM_NAME, Vector2::ZERO);
+
+    for( int i = 0; i < MAXIMUM_ANIMATION_COUNT; i++ )
+    {
+      oss.str("");
+      oss<< TAP_OFFSET_UNIFORM_NAME << i << "]";
+      handle.RegisterProperty(oss.str(), 0.f);
+
+      oss.str("");
+      oss<< TAP_POINT_UNIFORM_NAME << i << "]";
+      handle.RegisterProperty(oss.str(), Vector2( 250.0f,250.0f ));
+    }
+
+    return handle;
+  }
+
+}; // namespace SparkleEffect
+
+#endif // DALI_SPARKLE_EFFECT_H
diff --git a/resources/images/sparkle_normal_background.png b/resources/images/sparkle_normal_background.png
new file mode 100755 (executable)
index 0000000..a416be0
Binary files /dev/null and b/resources/images/sparkle_normal_background.png differ
diff --git a/resources/images/sparkle_particle.png b/resources/images/sparkle_particle.png
new file mode 100755 (executable)
index 0000000..836153e
Binary files /dev/null and b/resources/images/sparkle_particle.png differ
index 5accc36..9ce9243 100755 (executable)
@@ -106,6 +106,9 @@ msgstr "লিপি"
 msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW"
 msgstr "স্ক্ৰ'ল কৰক"
 
+msgid "DALI_DEMO_STR_TITLE_SPARKLE"
+msgstr "তাৰকা"
+
 msgid "DALI_DEMO_STR_TITLE_STYLING"
 msgstr "শৈলী"
 
index 0aea6b5..d4df93e 100755 (executable)
@@ -106,6 +106,9 @@ msgstr "Scripting"
 msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW"
 msgstr "Scroll-Ansicht"
 
+msgid "DALI_DEMO_STR_TITLE_SPARKLE"
+msgstr "Funkeln"
+
 msgid "DALI_DEMO_STR_TITLE_STYLING"
 msgstr "Styling"
 
index a62e46a..426ecb0 100755 (executable)
@@ -106,6 +106,9 @@ msgstr "Script-based UI"
 msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW"
 msgstr "Scroll View"
 
+msgid "DALI_DEMO_STR_TITLE_SPARKLE"
+msgstr "Sparkle"
+
 msgid "DALI_DEMO_STR_TITLE_STYLING"
 msgstr "Styling"
 
index 217b42f..48470fc 100755 (executable)
@@ -106,6 +106,9 @@ msgstr "Script-based UI"
 msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW"
 msgstr "Scroll View"
 
+msgid "DALI_DEMO_STR_TITLE_SPARKLE"
+msgstr "Sparkle"
+
 msgid "DALI_DEMO_STR_TITLE_STYLING"
 msgstr "Styling"
 
index 3611ed6..068fff5 100755 (executable)
@@ -106,6 +106,9 @@ msgstr "Interfaz definida por Script"
 msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW"
 msgstr "Vista de desplazamiento"
 
+msgid "DALI_DEMO_STR_TITLE_SPARKLE"
+msgstr "Brillar"
+
 msgid "DALI_DEMO_STR_TITLE_STYLING"
 msgstr "Estilo"
 
index e3d16c7..820e5e7 100755 (executable)
@@ -106,6 +106,9 @@ msgstr "스크립팅"
 msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW"
 msgstr "스크롤 뷰"
 
+msgid "DALI_DEMO_STR_TITLE_SPARKLE"
+msgstr "불꽃"
+
 msgid "DALI_DEMO_STR_TITLE_STYLING"
 msgstr "스타일링"
 
index eabc095..a06bdcb 100755 (executable)
@@ -106,6 +106,9 @@ msgstr "സ്ക്രിപ്റ്റ്"
 msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW"
 msgstr "സ്ക്രോള്ചെയ്യുക കാഴ്ച"
 
+msgid "DALI_DEMO_STR_TITLE_SPARKLE"
+msgstr "നക്ഷത്ര"
+
 msgid "DALI_DEMO_STR_TITLE_STYLING"
 msgstr "ശൈലി"
 
@@ -131,4 +134,4 @@ msgid "DALI_DEMO_STR_TITLE_TEXT_SCROLLING"
 msgstr "ടെക്സ്റ്റ് സ്ക്രോളിംഗ്"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
-msgstr "ചെരിവ് സെൻസർ"
\ No newline at end of file
+msgstr "ചെരിവ് സെൻസർ"
index a3b8d12..73f1730 100755 (executable)
@@ -106,6 +106,9 @@ msgstr "سکرپٹ"
 msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW"
 msgstr "سکرول ویو"
 
+msgid "DALI_DEMO_STR_TITLE_SPARKLE"
+msgstr "سٹار"
+
 msgid "DALI_DEMO_STR_TITLE_STYLING"
 msgstr "سٹائل"
 
index c340d63..7613037 100755 (executable)
@@ -106,6 +106,9 @@ msgstr "脚本用户界面"
 msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW"
 msgstr "滚动视图"
 
+msgid "DALI_DEMO_STR_TITLE_SPARKLE"
+msgstr "火花"
+
 msgid "DALI_DEMO_STR_TITLE_STYLING"
 msgstr "样式"
 
@@ -131,4 +134,4 @@ msgid "DALI_DEMO_STR_TITLE_TEXT_SCROLLING"
 msgstr "滚动文字"
 
 msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR"
-msgstr "倾斜传感器"
\ No newline at end of file
+msgstr "倾斜传感器"
index f191dcb..a829853 100644 (file)
@@ -68,6 +68,7 @@ extern "C"
 #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL            dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERER_STENCIL")
 #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI             dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI")
 #define DALI_DEMO_STR_TITLE_SCROLL_VIEW                 dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCROLL_VIEW")
+#define DALI_DEMO_STR_TITLE_SPARKLE                     dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SPARKLE")
 #define DALI_DEMO_STR_TITLE_STYLING                     dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_STYLING")
 #define DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM            dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM")
 #define DALI_DEMO_STR_TITLE_TEXTURED_MESH               dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXTURED_MESH")
@@ -116,6 +117,7 @@ extern "C"
 #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL            "Renderer Stencils"
 #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI             "Script Based UI"
 #define DALI_DEMO_STR_TITLE_SCROLL_VIEW                 "Scroll View"
+#define DALI_DEMO_STR_TITLE_SPARKLE                     "Sparkle"
 #define DALI_DEMO_STR_TITLE_STYLING                     "Styling"
 #define DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM            "Super Blur and Bloom"
 #define DALI_DEMO_STR_TITLE_TEXTURED_MESH               "Mesh Texture"