update bubble-emitter to use new mesh 61/39561/6
authorXiangyin Ma <x1.ma@samsung.com>
Mon, 18 May 2015 17:59:52 +0000 (18:59 +0100)
committerXiangyin Ma <x1.ma@samsung.com>
Fri, 22 May 2015 10:46:43 +0000 (11:46 +0100)
Change-Id: I2a46b496e3c1f4938978416f518b1330e62fa328

12 files changed:
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.h
automated-tests/src/dali-toolkit/utc-Dali-BubbleEmitter.cpp
dali-toolkit/internal/controls/bubble-effect/bubble-actor.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/bubble-effect/bubble-actor.h [new file with mode: 0644]
dali-toolkit/internal/controls/bubble-effect/bubble-effect.h [new file with mode: 0644]
dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.cpp
dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.h
dali-toolkit/internal/controls/bubble-effect/color-adjuster.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/public-api/controls/bubble-effect/bubble-emitter.cpp
dali-toolkit/public-api/controls/bubble-effect/bubble-emitter.h
dali-toolkit/public-api/file.list

index 36cb94b..516b366 100644 (file)
@@ -1548,6 +1548,30 @@ public: // TEST FUNCTIONS
   inline TraceCallStack& GetDrawTrace() { return mDrawTrace; }
 
   template <typename T>
+  inline bool GetUniformValue( const char* name, T& value ) const
+  {
+    for( ProgramUniformMap::const_iterator program_it = mUniforms.begin();
+          program_it != mUniforms.end();
+          ++program_it )
+    {
+      const UniformIDMap &uniformIDs = program_it->second;
+
+      UniformIDMap::const_iterator uniform_it = uniformIDs.find( name );
+      if( uniform_it != uniformIDs.end() )
+      {
+        // found one matching uniform name, lets check the value...
+        GLuint programId = program_it->first;
+        GLint uniformId = uniform_it->second;
+
+        const ProgramUniformValue<T> &mProgramUniforms = GetProgramUniformsForType( value );
+        return mProgramUniforms.GetUniformValue( programId, uniformId, value );
+      }
+    }
+    return false;
+  }
+
+
+  template <typename T>
   inline bool CheckUniformValue( const char* name, const T& value ) const
   {
     for( ProgramUniformMap::const_iterator program_it = mUniforms.begin();
index e6062f2..33a0c2c 100644 (file)
@@ -24,8 +24,6 @@
 
 #include <dali.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <dali/devel-api/actors/mesh-actor.h>
-#include <dali/devel-api/modeling/material.h>
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -140,13 +138,40 @@ int UtcDaliBubbleEmitterNew(void)
   END_TEST;
 }
 
+int UtcDaliBubbleEmitterDownCast01(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline(" UtcDaliBubbleEmitterDownCast01 ");
+
+  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
+
+  BaseHandle handle(emitter);
+  BubbleEmitter emitter2 = BubbleEmitter::DownCast(handle);
+  DALI_TEST_EQUALS( (bool)emitter2, true, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliBubbleEmitterDownCast02(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline(" UtcDaliBubbleEmitterDownCast02 ");
+
+  Handle handle = Handle::New(); // Create a custom object
+  BubbleEmitter emitter = BubbleEmitter::DownCast(handle);
+  DALI_TEST_EQUALS( (bool)emitter, false, TEST_LOCATION );
+  END_TEST;
+}
+
 int UtcDaliBubbleEmitterGetRootActor(void)
 {
   ToolkitTestApplication application;
   tet_infoline( " UtcDaliBubbleEmitterGetRootActor " );
 
   Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
-  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
+  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 270, Vector2( 5.f, 10.f ));
 
   Actor root = emitter.GetRootActor();
   DALI_TEST_CHECK( root );
@@ -175,56 +200,39 @@ int UtcDaliBubbleEmitterSetBackground(void)
   END_TEST;
 }
 
-int UtcDaliBubbleEmitterSetShapeImage(void)
+//TODO: test case for BubbleEmitter::SetShapeImage(Image)
+// To test that the bubble-shape image is successfully switched in the sampler
+/*int UtcDaliBubbleEmitterSetShapeImage(void)
 {
-  ToolkitTestApplication application;
-  tet_infoline( " UtcDaliBubbleEmitterSetShapeImage " );
-
-  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
-  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-
-  Actor root = emitter.GetRootActor();
-  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
-  Material material = bubbleMesh.GetMaterial();
-
-  DALI_TEST_CHECK( material.GetDiffuseTexture() == shapeImage1 );
-
-  Image shapeImage2 = CreateSolidColorImage( application, Color::RED, 8, 8 );
-  emitter.SetShapeImage( shapeImage2 );
-
-  DALI_TEST_CHECK( material.GetDiffuseTexture() == shapeImage2 );
-  END_TEST;
-}
+}*/
 
 int UtcDaliBubbleEmitterSetBubbleScale(void)
 {
   ToolkitTestApplication application;
   tet_infoline( " UtcDaliBubbleEmitterSetBubbleScale " );
 
-  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
-  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-
+  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 150, Vector2( 5.f, 10.f ));
   Actor root = emitter.GetRootActor();
-  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
-  ShaderEffect effect = bubbleMesh.GetShaderEffect();
-  DALI_TEST_CHECK( effect );
+  Stage::GetCurrent().Add( root );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+
+  Wait(application);
 
-  Property::Index scalePropertyIndex = effect.GetPropertyIndex( "uDynamicScale" );
   float scaleValue;
-  (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
-  DALI_TEST_EQUALS(scaleValue, 1.f, TEST_LOCATION );
+  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
+  DALI_TEST_EQUALS( scaleValue, 1.f, TEST_LOCATION );
 
   emitter.SetBubbleScale( 2.f );
-  application.SendNotification();
-  application.Render();
-  (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
-  DALI_TEST_EQUALS(scaleValue, 2.f, TEST_LOCATION );
+  Wait(application);
+  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
+  DALI_TEST_EQUALS( scaleValue, 2.f, TEST_LOCATION );
 
   emitter.SetBubbleScale( 0.5f );
-  application.SendNotification();
-  application.Render();
-  (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
-  DALI_TEST_EQUALS(scaleValue, 0.5f, TEST_LOCATION );
+  Wait(application);
+  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
+  DALI_TEST_EQUALS( scaleValue, 0.5f, TEST_LOCATION );
   END_TEST;
 }
 
@@ -233,8 +241,8 @@ int UtcDaliBubbleEmitterSetBubbleDensity01(void)
   ToolkitTestApplication application;
   tet_infoline( " UtcDaliBubbleEmitterSetBubbleDensity " );
 
-  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
-  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
+  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
 
   try
   {
@@ -254,8 +262,8 @@ int UtcDaliBubbleEmitterSetBubbleDensity02(void)
   ToolkitTestApplication application;
   tet_infoline( " UtcDaliBubbleEmitterSetBubbleDensity " );
 
-  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
-  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
+  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
 
   try
   {
@@ -274,27 +282,32 @@ int UtcDaliBubbleEmitterSetBlendMode(void)
   ToolkitTestApplication application;
   tet_infoline( " UtcDaliBubbleEmitterSetBlendMode " );
 
-  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
-  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-
+  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 150, Vector2( 5.f, 10.f ));
   Actor root = emitter.GetRootActor();
-  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
+  Stage::GetCurrent().Add( root );
 
-  BlendingFactor::Type srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha;
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  Wait(application);
+  DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
+  DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
+  DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
+  DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
 
   emitter.SetBlendMode( true );
-  bubbleMesh.GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-  DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
-  DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE );
-  DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ZERO );
-  DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE );
+  Wait(application);
+  DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
+  DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
+  DALI_TEST_EQUALS( (GLenum)GL_ZERO, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
+  DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
 
   emitter.SetBlendMode( false );
-  bubbleMesh.GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-  DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
-  DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE_MINUS_SRC_ALPHA );
-  DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ONE );
-  DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE_MINUS_SRC_ALPHA );
+  Wait(application);
+  DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
+  DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
+  DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
+  DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
+
   END_TEST;
 }
 
@@ -307,103 +320,90 @@ int UtcDaliBubbleEmitterEmitBubble(void)
   BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
 
   Actor root = emitter.GetRootActor();
-  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
-  ShaderEffect effect = bubbleMesh.GetShaderEffect();
-  DALI_TEST_CHECK( effect );
+  Actor bubbleMesh = root.GetChildAt( 0 );
+  Stage::GetCurrent().Add( root );
+  DALI_TEST_CHECK( bubbleMesh );
 
-  Property::Index propertyIndex0 = effect.GetPropertyIndex( "uPercentage[0]" );
-  Property::Index propertyIndex1 = effect.GetPropertyIndex( "uPercentage[1]" );
+  Property::Index propertyIndex0 = bubbleMesh.GetPropertyIndex( "percentage-0" );
+  Property::Index propertyIndex1 = bubbleMesh.GetPropertyIndex( "percentage-1" );
   float value0, value1;
 
   Animation animation = Animation::New( 0.5f );
   emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
   emitter.EmitBubble( animation, Vector2(10.f,10.f), Vector2(5.f,5.f), Vector2(30.f,30.f) );
-  (effect.GetProperty(propertyIndex0)).Get( value0 );
-  (effect.GetProperty(propertyIndex1)).Get( value1 );
+  (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
+  (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
   DALI_TEST_EQUALS(value0, 0.f, TEST_LOCATION );
   DALI_TEST_EQUALS(value1, 0.f, TEST_LOCATION );
 
   animation.Play();
 
   Wait(application, 300);
-  (effect.GetProperty(propertyIndex0)).Get( value0 );
-  (effect.GetProperty(propertyIndex1)).Get( value1 );
+  propertyIndex0 = bubbleMesh.GetPropertyIndex( "percentage-0" );
+  propertyIndex1 = bubbleMesh.GetPropertyIndex( "percentage-1" );
+  (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
+  (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
   DALI_TEST_CHECK( value0 >= 0.6f );
   DALI_TEST_CHECK( value1 >= 0.6f );
 
-  Wait(application, 600);
-  (effect.GetProperty(propertyIndex0)).Get( value0 );
-  (effect.GetProperty(propertyIndex1)).Get( value1 );
+  Wait(application,500);
+  (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
+  (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
   DALI_TEST_EQUALS(value0, 1.f, TEST_LOCATION );
   DALI_TEST_EQUALS(value1, 1.f, TEST_LOCATION );
   END_TEST;
 }
 
-int UtcDaliBubbleEmitterStartExplosion(void)
+int UtcDaliBubbleEmitterRestore(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( " UtcDaliBubbleEmitterStartExplosion " );
+  tet_infoline( " UtcDaliBubbleEmitterRestore " );
 
-  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
-  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
+  Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 90, Vector2( 5.f, 10.f ));
   Actor root = emitter.GetRootActor();
-  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
-  ShaderEffect effect = bubbleMesh.GetShaderEffect();
-  DALI_TEST_CHECK( effect );
-
-  Property::Index propertyIndex = effect.GetPropertyIndex( "uMagnification" );
-  float value;
-  (effect.GetProperty(propertyIndex)).Get( value );
-  DALI_TEST_EQUALS(value, 1.f, TEST_LOCATION );
-
-  emitter.StartExplosion( 0.4, 4.f );
+  Stage::GetCurrent().Add( root );
 
-  Wait(application, 200); // 0.2s
-  (effect.GetProperty(propertyIndex)).Get( value );
-  DALI_TEST_CHECK( value >= 2.f );
+  Actor bubbleMesh = root.GetChildAt( 0 );
+  Renderer renderer = bubbleMesh.GetRendererAt( 0 );
+  DALI_TEST_CHECK( renderer );
 
-  Wait(application, 100); // 0.3s
-  (effect.GetProperty(propertyIndex)).Get( value );
-  DALI_TEST_CHECK( value >= 3.f );
+  TestGlAbstraction& gl = application.GetGlAbstraction();
 
-  Wait(application, 100); // 0.4s
-  (effect.GetProperty(propertyIndex)).Get( value );
-  DALI_TEST_EQUALS(value, 1.f, TEST_LOCATION );
-  END_TEST;
-}
+  float percentageValue;
+  Vector4 startEndPosValue;
 
-int UtcDaliBubbleEmitterRestore(void)
-{
-  ToolkitTestApplication application;
-  tet_infoline( " UtcDaliBubbleEmitterRestore " );
+  Animation animation = Animation::New( 0.5f );
+  emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
 
-  Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
-  BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-  Actor root = emitter.GetRootActor();
-  MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
-  ShaderEffect effect = bubbleMesh.GetShaderEffect();
-  DALI_TEST_CHECK( effect );
+  Wait(application);
 
-  Property::Index percentagePropertyIndex = effect.GetPropertyIndex( "uPercentage[0]" );
-  float percentage;
+  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
+  DALI_TEST_EQUALS( percentageValue, 0.f, TEST_LOCATION );
 
-  Animation animation = Animation::New( 0.5f );
-  emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
-  (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
-  DALI_TEST_EQUALS(percentage, 0.f, TEST_LOCATION );
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartAndEndPos[0]", startEndPosValue ) );
+  DALI_TEST_EQUALS( startEndPosValue.x, 40.f, TEST_LOCATION );
+  DALI_TEST_EQUALS( startEndPosValue.y, 40.f, TEST_LOCATION );
 
   animation.Play();
   Wait(application, 200);
   animation.Clear();
 
-  (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
-  DALI_TEST_CHECK( percentage < 0.5f && percentage >= 0.4);
+  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
+  DALI_TEST_CHECK( percentageValue < 0.5f && percentageValue >= 0.4);
+
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartAndEndPos[0]", startEndPosValue ) );
+  DALI_TEST_EQUALS( startEndPosValue.x, 40.f, TEST_LOCATION );
+  DALI_TEST_EQUALS( startEndPosValue.y, 40.f, TEST_LOCATION );
 
   emitter.Restore();
   application.SendNotification();
   application.Render();
 
-  (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
-  DALI_TEST_EQUALS(percentage, 1.f, TEST_LOCATION );
+  DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
+  DALI_TEST_EQUALS( percentageValue, 0.f, TEST_LOCATION );
+
+  DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartAndEndPos[0]", startEndPosValue ) );
+  DALI_TEST_EQUALS( startEndPosValue,  Vector4::ZERO, TEST_LOCATION );
   END_TEST;
 }
diff --git a/dali-toolkit/internal/controls/bubble-effect/bubble-actor.cpp b/dali-toolkit/internal/controls/bubble-effect/bubble-actor.cpp
new file mode 100644 (file)
index 0000000..d3b0563
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+// CLASS HEADER
+#include "bubble-actor.h"
+
+// EXTERNAL INCLUDES
+#include <cmath>
+#include <sstream>
+
+// INTERNAL INCLUDES
+
+namespace
+{
+
+/**
+ * Register a property and map it as uniform.
+ * @param[in] handle The handle to register new property.
+ * @param[in] propertyName The name of the property.
+ * @param[in] unifoemName The name of the uniform.
+ * @param[in] value The initial value of the property.
+ * @return The index of theproperty
+ */
+Dali::Property::Index RegisterUniform( Dali::Handle& handle,
+                                       const std::string& propertyName,
+                                       const std::string& uniformName,
+                                       Dali::Property::Value value)
+{
+  Dali::Property::Index propertyIndex = handle.RegisterProperty( propertyName, value );
+  handle.AddUniformMapping( propertyIndex, uniformName );
+
+  return propertyIndex;
+}
+
+}// end LOCAL_STUFF
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+BubbleActor::BubbleActor( unsigned int numberOfBubble,
+                          const Vector2& movementArea)
+: mMovementArea( movementArea ),
+  mNumBubble( numberOfBubble )
+{
+  mActor = Actor::New();
+}
+
+void BubbleActor::MakeRenderable( Geometry geometry, Material material  )
+{
+  if( mRenderer )
+  {
+    // This function is supposed to be called once
+    return;
+  }
+
+  mRenderer = Renderer::New( geometry, material );
+
+  mActor.AddRenderer( mRenderer );
+  mActor.SetSize( mMovementArea );
+  mActor.SetParentOrigin(ParentOrigin::TOP_LEFT);
+
+  // register uniforms
+  mIndexGravity = RegisterUniform( mActor, "gravity", "uGravity", 50.f );
+  mIndexDynamicScale = RegisterUniform( mActor, "dynamic-scale", "uDynamicScale", 1.f );
+
+  mIndexInvertedMovementArea = RegisterUniform( mActor, "inverted-movement-area", "uInvertedMovementArea", Vector2(1.f,1.f) / mMovementArea );
+
+  srand(time(NULL));
+  mIndicesOffset.resize(9);
+  int offset = mMovementArea.Length() / 10.f;
+  mIndicesOffset[0] = RegisterUniform(mActor, "offset-0", "offset[0]", Vector2(0.f,0.f));
+  mIndicesOffset[1] = RegisterUniform(mActor, "offset-1", "offset[1]", Vector2(rand()%offset,rand()%offset) );
+  mIndicesOffset[2] = RegisterUniform(mActor, "offset-2", "offset[2]", Vector2(rand()%offset,-rand()%offset) );
+  mIndicesOffset[3] = RegisterUniform(mActor, "offset-3", "offset[3]", Vector2(-rand()%offset,rand()%offset) );
+  mIndicesOffset[4] = RegisterUniform(mActor, "offset-4", "offset[4]", Vector2(-rand()%offset,-rand()%offset) );
+  mIndicesOffset[5] = RegisterUniform(mActor, "offset-5", "offset[5]", Vector2(rand()%offset,0.f));
+  mIndicesOffset[6] = RegisterUniform(mActor, "offset-6", "offset[6]", Vector2(-rand()%offset,0.f));
+  mIndicesOffset[7] = RegisterUniform(mActor, "offset-7", "offset[7]", Vector2(0.f,rand()%offset));
+  mIndicesOffset[8] = RegisterUniform(mActor, "offset-8", "offset[8]", Vector2(0.f,-rand()%offset));
+
+  Vector4 zeroVector;
+  mIndiceStartEndPos.resize( mNumBubble );
+  mIndicesPercentage.resize( mNumBubble );
+  for( unsigned int i=0; i<mNumBubble; i++ )
+  {
+    std::ostringstream ossProperty;
+    ossProperty<< "start-end-position-"<< i;
+
+    std::ostringstream ossUniform;
+    ossUniform<< "uStartAndEndPos["<< i << "]";
+    mIndiceStartEndPos[i] = RegisterUniform( mActor, ossProperty.str(), ossUniform.str(), zeroVector );
+
+    ossProperty.str("");
+    ossProperty<< "percentage-"<< i;
+
+    ossUniform.str("");
+    ossUniform<< "uPercentage["<< i << "]";
+    mIndicesPercentage[i] = RegisterUniform( mActor, ossProperty.str(), ossUniform.str(), 0.f );
+  }
+}
+
+Actor BubbleActor::GetMeshActor()
+{
+  return mActor;
+}
+
+void BubbleActor::SetGeometry( Geometry geometry )
+{
+  mRenderer.SetGeometry( geometry );
+}
+
+void BubbleActor::SetMovementArea( const Vector2& movementArea )
+{
+  if( movementArea == mMovementArea)
+  {
+    return;
+  }
+
+  mMovementArea = movementArea;
+  mActor.SetSize( mMovementArea );
+  mActor.SetProperty( mIndexInvertedMovementArea, Vector2(1.f,1.f) / mMovementArea );
+
+  int offset = mMovementArea.Length() / 10.f;
+  mActor.SetProperty( mIndicesOffset[1], Vector2(rand()%offset,rand()%offset) );
+  mActor.SetProperty( mIndicesOffset[2], Vector2(rand()%offset,-rand()%offset) );
+  mActor.SetProperty( mIndicesOffset[3], Vector2(-rand()%offset,rand()%offset) );
+  mActor.SetProperty( mIndicesOffset[4], Vector2(-rand()%offset,-rand()%offset) );
+  mActor.SetProperty( mIndicesOffset[5], Vector2(rand()%offset,0.f));
+  mActor.SetProperty( mIndicesOffset[6], Vector2(-rand()%offset,0.f));
+  mActor.SetProperty( mIndicesOffset[7], Vector2(0.f,rand()%offset));
+  mActor.SetProperty( mIndicesOffset[8], Vector2(0.f,-rand()%offset));
+}
+
+void BubbleActor::SetStartAndEndPosition( unsigned int index, const Vector4& startAndEndPosition )
+{
+  mActor.SetProperty( mIndiceStartEndPos[index], startAndEndPosition );
+}
+
+void BubbleActor::SetPercentage( unsigned int index, float percentage )
+{
+  mActor.SetProperty( mIndicesPercentage[index], percentage );
+}
+
+void BubbleActor::SetGravity( float gravity )
+{
+  mActor.SetProperty( mIndexGravity, gravity );
+}
+
+void BubbleActor::SetDynamicScale( float scale )
+{
+  mActor.SetProperty( mIndexDynamicScale, scale );
+}
+
+Property BubbleActor::GetPercentageProperty( unsigned int index )
+{
+  return Property( mActor, mIndicesPercentage[index] );
+}
+
+void BubbleActor::ResetProperties()
+{
+  Vector4 zeroVector;
+  for( unsigned int i=0; i<mNumBubble; i++ )
+  {
+    SetPercentage( i, 0.f);
+    SetStartAndEndPosition( i, zeroVector );
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/bubble-effect/bubble-actor.h b/dali-toolkit/internal/controls/bubble-effect/bubble-actor.h
new file mode 100644 (file)
index 0000000..39f6156
--- /dev/null
@@ -0,0 +1,152 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H_
+#define __DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H_
+
+/*
+ * Copyright (c) 2015 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/public-api/actors/actor.h>
+#include <dali/public-api/actors/renderer.h>
+#include <dali/public-api/object/property-buffer.h>
+#include <dali/public-api/object/property-map.h>
+#include <dali/public-api/shader-effects/material.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * BubbleActor is a group of bubbles.Each bubble can be moved separately.
+ * Its custom shader achieves similar effect of particle system by applying on a specially created mesh
+ * Each bubble is rendered on a patch with two triangles; and each mesh can contain multiple such patches, thus a group.
+ */
+class BubbleActor : public RefObject
+{
+public:
+
+  /**
+   * Constructor
+   * @param[in] numberOfBubble How many groups of uniforms are used to control the bubble movement.
+   * Note: Limited by the maximum available uniforms, this parameter cannot be bigger than 100.
+   * Ideally use one group of uniform to control one bubble.
+   * If the num of patches in the MeshActor is more than groups of uniforms,
+   * the uniform values will be shared by multiple bubbles. Allow up to 9 times.
+   * @param[in] movementArea The size of the bubble moving area, usually the same size as the background image actor.
+   * @return A newly allocated object.
+   */
+  BubbleActor( unsigned int numberOfBubble,
+               const Vector2& movementArea);
+
+  /**
+   * @brief Destructor
+   */
+  ~BubbleActor(){}
+
+  /**
+   * Prepare for the rendering: create and add renderer, and register properties
+   * @param[in] geometry The geometry to be used by the renderer
+   * @param[in] material The material to be used by the renderer
+   */
+  void MakeRenderable( Geometry geometry, Material material  );
+
+  /**
+   * Return the mesh actor which is used to display the bubbles
+   */
+  Actor GetMeshActor();
+
+  /**
+   * Sets the geometry to be used by the renderer
+   * @param[in] geometry The geometry to be used by the renderer
+   */
+  void SetGeometry( Geometry geometry );
+
+  /**
+   * Set the bubble movement area for the BubbleEffect
+   * @param[in] movementArea The size of bubble movement area; by default, it is the stage size
+   */
+  void SetMovementArea( const Vector2& movementArea );
+
+  /**
+   * Set the start and end positions of the index-th bubble's movement.
+   * @param[in] index Indicate which bubble these properties are applied on.
+   * @param[in] startAndEndPosition The start and the end position of movement.
+   */
+  void SetStartAndEndPosition( unsigned int index, const Vector4& startAndEndPosition );
+
+  /**
+   * Set the movement completed percentage of the index-th bubble.
+   * The bubble will appear at start position when percentage equals to zero,
+   * and disappear near end position (affected by gravity) when percentage equals to one.
+   * This percentage property is used to animate the bubble movement.
+   * @param[in] index Indicate which bubble this property is applied on.
+   * @param[in] percentage Set the percentage property value ( between zero and one ).
+   */
+  void SetPercentage( unsigned int index, float percentage );
+
+  /**
+   * Set the gravity applied to the y direction, which makes the bubbles no longer moving on a straight line.
+   * @param[in] gravity The gravity on the y direction.
+   */
+  void SetGravity( float gravity );
+
+  /**
+   * Set the scale factor applied to the bubbles
+   * @param[in] scale The scale factor applied on all bubbles.
+   */
+  void SetDynamicScale( float scale );
+
+  /**
+   * Get the idx-th percentage property.
+   * @param[in] idx The percentage property index.
+   * @return the idx-th percentage property.
+   */
+  Property GetPercentageProperty( unsigned int idx );
+
+  /**
+   * Reset the uniform values to default.
+   */
+  void ResetProperties();
+
+private:
+
+  Actor        mActor;
+  Renderer     mRenderer;
+
+  Vector2      mMovementArea;      ///< The size of the bubble moving area, usually the same size as the background image actor.
+
+  //properties mapped as uniforms
+  std::vector<Property::Index> mIndicesOffset;             ///< Indices of the properties mapping to uniform array 'uOffset'
+  std::vector<Property::Index> mIndiceStartEndPos;         ///< Indices of the properties mapping to uniform array 'uStartAndEndPos'
+  std::vector<Property::Index> mIndicesPercentage;         ///< Indices of the properties mapping to uniform array 'uPercentage'
+  Property::Index              mIndexGravity;              ///< Index of the property mapping to uniform 'uGravity'
+  Property::Index              mIndexDynamicScale;         ///< Index of the property mapping to uniform 'uDynamicScale'
+  Property::Index              mIndexInvertedMovementArea; ///< Index of the property mapping to uniform 'uInvertedMovementArea'
+
+  unsigned int mNumBubble;  ///< How many groups of uniforms are used to control the bubble movement.
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H_ */
diff --git a/dali-toolkit/internal/controls/bubble-effect/bubble-effect.h b/dali-toolkit/internal/controls/bubble-effect/bubble-effect.h
new file mode 100644 (file)
index 0000000..5f35d20
--- /dev/null
@@ -0,0 +1,131 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H_
+#define __DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H_
+
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <sstream>
+#include <dali/public-api/shader-effects/shader.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * Create the shader to be used by the material
+ * @param[in] numberOfBubble How many groups of uniforms are used to control the bubble movement.
+ * @return A handle to the newly created shader.
+ */
+inline Shader CreateBubbleShader( unsigned int numBubble )
+{
+  const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute mediump float   aIndex;\n
+  attribute mediump vec2    aPosition;\n
+  attribute highp   vec2    aTexCoord;\n
+  varying   mediump vec2    vTexCoord;\n
+  uniform   mediump mat4    uMvpMatrix;\n
+  // the gravity applied to the y direction
+  uniform mediump float uGravity;\n
+  // xy: the emit position of the bubble; zw: the destination of the bubble.
+  // The bubble is moving from (xy) to (zw plus the y drop influenced by gravity).
+  uniform vec4 uStartAndEndPos[NUMBER_OF_BUBBLE];\n
+  // The undergoing percentage of the bubble movement. 0.0: start from emit position, 1.0: reach the destination
+  uniform float uPercentage[NUMBER_OF_BUBBLE];\n
+  uniform vec2 uInvertedMovementArea;\n
+  // The bubble number is restricted by the available uniform num.
+  // To increase the displayed bubble, every uStartAndEndPos and uPercentage uniform is applied to a small bunch of bubbles (9 here)
+  // The offset defines the random offset between bubbles within the bunch.
+  uniform vec2 offset[9];\n
+  // This uniform is used to change the bubble size during running time
+  uniform float uDynamicScale;\n
+  varying float vPercentage;\n
+  varying vec2  vEffectTexCoord;\n
+  void main()\n
+  {\n
+    vec4 position = vec4( aPosition, 0.0, 1.0 );\n
+    // The Z coordinate is used to record the bubble index within current mesh actor
+    int index = int(aIndex); \n
+    //for some i between 0 ~ NUMBER_OF_BUBBLE-1: i,i+NUMBER_OF_BUBBLE, i+NUMBER_OF_BUBBLE*2, ... (up to i+NUMBER_OF_BUBBLE*8) belongs to the same bunch.
+    int groupIdx = index / NUMBER_OF_BUBBLE;\n
+    // The bubbles within the same bunch applies the same uniforms uStartAndEndPos[idx] & uPercentage[idx]
+    int idx = index - groupIdx*NUMBER_OF_BUBBLE;\n
+    float percentage = uPercentage[idx];
+    // early out if uPercentage is (zero || one) setting position to zero (zero sized triangles)
+    if( percentage <= 0.0 || percentage >= 1.0 )\n
+    {\n
+      gl_Position = vec4(0.0);\n
+      return;\n
+    }\n
+    vec4 startAndEnd = uStartAndEndPos[idx];\n
+    // The final position is added up different offset for bubbles
+    startAndEnd.zw += offset[groupIdx];\n
+    \n
+    // increase the bubble size from 0% to 100% during the first 1/5 of movement & apply the dynamic scale
+    // the new xy value containes both the new scale and new bubble position
+    position.xy *= uDynamicScale*min(percentage*5.0, 1.0);\n
+    position.xy += mix(startAndEnd.xy, startAndEnd.zw, percentage);\n
+    // The gravity is g*t*t on the y direction
+    position.y += uGravity * pow(percentage, 2.0);\n
+    gl_Position = uMvpMatrix * position;\n
+    \n
+    // Add multiple bubble shapes in the effect
+    vTexCoord = aTexCoord;\n
+    vPercentage = percentage;\n
+    // Use the emit position color for the bubble
+    vEffectTexCoord = startAndEnd.xy * uInvertedMovementArea;\n
+  }\n
+  );
+
+  const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+  varying mediump vec2  vTexCoord;\n
+  uniform lowp    vec4  uColor;\n
+  uniform sampler2D     sBackground;\n
+  uniform sampler2D     sBubbleShape;\n
+  varying mediump float vPercentage;\n
+  varying mediump vec2  vEffectTexCoord;\n
+  \n
+  void main()\n
+  {\n
+    // Get the emit pisition color, and Mix with the actor color
+    mediump vec4 fragColor = texture2D(sBackground, vEffectTexCoord)*uColor;\n
+    // Apply the shape defined by the texture contained in the material
+    // And make the opacity being 0.7, and animate from 0.7 to 0 during the last 1/3 of movement
+    fragColor.a  *= texture2D(sBubbleShape, vTexCoord).a * ( 2.1 - max( vPercentage*2.1, 1.4 ) );\n
+    gl_FragColor = fragColor;\n
+  }\n
+  );
+
+  std::ostringstream vertexShaderStringStream;
+  vertexShaderStringStream << "#define NUMBER_OF_BUBBLE "<< numBubble << "\n"
+                           << VERTEX_SHADER;
+  Shader shader = Shader::New( vertexShaderStringStream.str(), FRAGMENT_SHADER );
+
+  return shader;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+#endif /* __DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H_ */
index ae17a0d..08ccb15 100644 (file)
 #include "bubble-emitter-impl.h"
 
 // EXTERNAL INCLUDES
-#include <cmath>
 #include <dali/public-api/animation/animation.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
 #include <dali/public-api/images/resource-image.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/shader-effects/bubble-effect/color-adjuster.h>
+#include <dali-toolkit/internal/controls/bubble-effect/bubble-actor.h>
+#include <dali-toolkit/internal/controls/bubble-effect/color-adjuster.h>
+#include <dali-toolkit/internal/controls/bubble-effect/bubble-effect.h>
+
+namespace
+{
+struct Vertex
+{
+  float index;
+  Dali::Vector2 position;
+  Dali::Vector2 textureCoord;
+
+  Vertex()
+  {}
+
+  Vertex( float index, const Dali::Vector2& position, const Dali::Vector2& textureCoord )
+  : index( index ), position( position ), textureCoord( textureCoord )
+  {}
+};
+
+/**
+ * Return a random value between the given interval.
+ * @param[in] f0 The low bound
+ * @param[in] f1 The up bound
+ * @return A random value between the given interval
+ */
+float RandomRange(float f0, float f1)
+{
+  return f0 + (rand() & 0xfff) * (f1-f0) * (1.0f/4095.0f);
+}
+
+}
 
 namespace Dali
 {
@@ -40,24 +71,30 @@ BubbleEmitter::BubbleEmitter( const Vector2& movementArea,
                               unsigned int maximumNumberOfBubble,
                               const Vector2& bubbleSizeRange )
 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
-  mMovementArea( movementArea ),
   mShapeImage( shapeImage ),
-  mTotalNumOfBubble( maximumNumberOfBubble ),
-  mRenderTaskRunning(false),
+  mMovementArea( movementArea ),
   mBubbleSizeRange( bubbleSizeRange ),
-  mCurrentUniform( 0 ),
-  mDensity( 5 )
+  mDensity( 5 ),
+  mTotalNumOfBubble( maximumNumberOfBubble ),
+  mCurrentBubble( 0 ),
+  mRenderTaskRunning(false)
 {
-  // Calculate how many BubbleEffect shaders are required
+  // Calculate how many shaders are required
   if( mTotalNumOfBubble>100 )
   {
-    mNumBubblePerShader = 100;
-    mNumShader = mTotalNumOfBubble / 100;
+    mNumBubblePerActor = 100;
+    mNumActor = mTotalNumOfBubble / 100;
+    if( mNumActor*mNumBubblePerActor < mTotalNumOfBubble )
+    {
+      mNumActor++;
+      mNumBubblePerActor =  mTotalNumOfBubble / mNumActor+1;
+      mTotalNumOfBubble = mNumActor * mNumBubblePerActor;
+    }
   }
   else
   {
-    mNumBubblePerShader = mTotalNumOfBubble;
-    mNumShader = 1;
+    mNumBubblePerActor = mTotalNumOfBubble;
+    mNumActor = 1;
   }
 }
 
@@ -92,39 +129,27 @@ void BubbleEmitter::OnInitialize()
   // Prepare the frame buffer to store the color adjusted background image
   mEffectImage = FrameBufferImage::New( mMovementArea.width/4.f, mMovementArea.height/4.f, Pixel::RGBA8888, Dali::Image::UNUSED );
 
-  // Generate the material object, which is used by all meshActors
-  GenMaterial();
+  // Generate the samplers and geometry, which is used by all bubbleActors
+  mSamplerBackground = Sampler::New( mEffectImage, "sBackground" );
+  mSamplerBubbleShape = Sampler::New( mShapeImage, "sBubbleShape" );
+  mMeshGeometry =  CreateGeometry( mNumBubblePerActor*mDensity );
 
-  mMesh.resize( mNumShader );
-  mMeshActor.resize( mNumShader );
-  mEffect.resize( mNumShader );
+  Shader bubbleShader = CreateBubbleShader (mNumBubblePerActor );
+
+  mMaterial = Material::New( bubbleShader );
+  mMaterial.AddSampler( mSamplerBackground );
+  mMaterial.AddSampler( mSamplerBubbleShape );
+
+  mBubbleActors.resize( mNumActor );
 
   // Create the meshActor group and bubbleEffect group to emit bubbles following the given track, such as finger touch track.
-  MeshData meshData;
-  ConstructBubbleMesh( meshData, mNumBubblePerShader*mDensity);
-  for(unsigned int i=0; i < mNumShader; i++ )
+  for(unsigned int i=0; i < mNumActor; i++ )
   {
-    mMesh[i] = Mesh::New( meshData );
-    mMeshActor[i] = MeshActor::New( mMesh[i] );
-    mMeshActor[i].SetParentOrigin(ParentOrigin::TOP_LEFT);
-    mEffect[i] = BubbleEffect::New( mNumBubblePerShader );
-    mEffect[i].SetEffectImage( mEffectImage );
-    mEffect[i].SetMovementArea( mMovementArea );
-    mMeshActor[i].SetShaderEffect( mEffect[i] );
-    mBubbleRoot.Add( mMeshActor[i] );
+    mBubbleActors[i] = new BubbleActor( mNumBubblePerActor, mMovementArea );
+    (mBubbleActors[i])->MakeRenderable( mMeshGeometry, mMaterial );
+    mBubbleRoot.Add( (mBubbleActors[i])->GetMeshActor() );
   }
 
-  // Create the extra meshActor and bubbleEffect to emit bubbles in totally random angle.
-  MeshData meshDataForNoise;
-  ConstructBubbleMesh( meshDataForNoise, mNumBubblePerShader);
-  mMeshActorForNoise = MeshActor::New( Mesh::New(meshDataForNoise) );
-  mMeshActorForNoise.SetParentOrigin(ParentOrigin::TOP_LEFT);
-  mEffectForNoise = BubbleEffect::New( mNumBubblePerShader );
-  mEffectForNoise.SetMovementArea( mMovementArea );
-  mEffectForNoise.SetEffectImage( mEffectImage );
-  mMeshActorForNoise.SetShaderEffect( mEffectForNoise );
-  mBubbleRoot.Add( mMeshActorForNoise );
-
   // Create a cameraActor for the off screen render task.
   mCameraActor = CameraActor::New(mMovementArea);
   mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
@@ -150,7 +175,7 @@ void BubbleEmitter::SetBackground( Image bgImage, const Vector3& hsvDelta )
   sourceActor.SetParentOrigin(ParentOrigin::CENTER);
   Stage::GetCurrent().Add( sourceActor );
 
-  ColorAdjuster colorAdjuster = ColorAdjuster::New( hsvDelta, true /*ignore alpha to make bubble color always*/ );
+  ShaderEffect colorAdjuster = CreateColorAdjuster( hsvDelta, true /*ignore alpha to make bubble color always*/ );
   sourceActor.SetShaderEffect( colorAdjuster );
 
   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
@@ -167,16 +192,15 @@ void BubbleEmitter::SetBackground( Image bgImage, const Vector3& hsvDelta )
 
 void BubbleEmitter::SetShapeImage( Image shapeImage )
 {
-  mCustomMaterial.SetDiffuseTexture( shapeImage );
+  mSamplerBubbleShape.SetImage( shapeImage );
 }
 
 void BubbleEmitter::SetBubbleScale( float scale )
 {
-  for(unsigned int i=0; i < mNumShader; i++ )
+  for(unsigned int i=0; i < mNumActor; i++ )
   {
-    mEffect[i].SetDynamicScale( scale );
+    (mBubbleActors[i])->SetDynamicScale( scale );
   }
-  mEffectForNoise.SetDynamicScale( scale );
 }
 
 void BubbleEmitter::SetBubbleDensity( unsigned int density )
@@ -190,15 +214,30 @@ void BubbleEmitter::SetBubbleDensity( unsigned int density )
   else
   {
     mDensity = density;
-    MeshData meshData;
-    ConstructBubbleMesh( meshData, mNumBubblePerShader*mDensity);
-    for(unsigned int i=0; i < mNumShader; i++ )
+    mMeshGeometry =  CreateGeometry( mNumBubblePerActor*mDensity );
+    for(unsigned int i=0; i < mNumActor; i++ )
     {
-      mMesh[i].UpdateMeshData(meshData);
+      (mBubbleActors[i])->SetGeometry( mMeshGeometry );
     }
   }
 }
 
+void BubbleEmitter::SetBlendMode( bool enable )
+{
+  if(enable)
+  {
+    // linear overlay
+    mMaterial.SetBlendFunc(BlendingFactor::SRC_ALPHA, BlendingFactor::ONE,
+                           BlendingFactor::ZERO, BlendingFactor::ONE);
+  }
+  else
+  {
+    // using default blend func
+    mMaterial.SetBlendFunc( BlendingFactor::SRC_ALPHA,   BlendingFactor::ONE_MINUS_SRC_ALPHA,
+                            BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA );
+  }
+}
+
 // clear the resources created for the off screen rendering
 void BubbleEmitter::OnRenderFinished(RenderTask& source)
 {
@@ -206,7 +245,7 @@ void BubbleEmitter::OnRenderFinished(RenderTask& source)
   Actor sourceActor = source.GetSourceActor();
   if( sourceActor )
   {
-    RenderableActor renderable = RenderableActor::DownCast( sourceActor );
+    ImageActor renderable = ImageActor::DownCast( sourceActor );
     if( renderable )
     {
       renderable.RemoveShaderEffect();
@@ -228,152 +267,74 @@ void BubbleEmitter::OnContextRegained()
   }
 }
 
-void BubbleEmitter::SetBlendMode( bool enable )
-{
-  if(enable)
-  {
-    for(unsigned int i=0; i < mNumShader; i++ )
-    {
-      // linear overlay
-      // TODO: if BlendColor would be public api from renderable actor, then can optimize the constant color
-      mMeshActor[i].SetBlendFunc(BlendingFactor::SRC_ALPHA, BlendingFactor::ONE,
-                                 BlendingFactor::ZERO, BlendingFactor::ONE);
-    }
-    mMeshActorForNoise.SetBlendFunc(BlendingFactor::SRC_ALPHA, BlendingFactor::ONE,
-                                    BlendingFactor::ZERO, BlendingFactor::ONE);
-  }
-  else
-  {
-    for(unsigned int i=0; i < mNumShader; i++ )
-    {
-      // using default blend func
-      mMeshActor[i].SetBlendFunc( BlendingFactor::SRC_ALPHA,   BlendingFactor::ONE_MINUS_SRC_ALPHA,
-                                  BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA );
-    }
-    mMeshActorForNoise.SetBlendFunc( BlendingFactor::SRC_ALPHA,   BlendingFactor::ONE_MINUS_SRC_ALPHA,
-                                     BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA );
-  }
-}
-
 void BubbleEmitter::EmitBubble( Animation& animation, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement )
 {
-  unsigned int curUniform = mCurrentUniform  % mNumBubblePerShader;
-  unsigned int groupIdx = mCurrentUniform / mNumBubblePerShader;
-  SetBubbleParameter( mEffect[groupIdx], curUniform, emitPosition, direction, displacement);
-  animation.AnimateTo( Property( mEffect[groupIdx], mEffect[groupIdx].GetPercentagePropertyName(curUniform) ),
+  unsigned int curUniform = mCurrentBubble  % mNumBubblePerActor;
+  unsigned int groupIdx = mCurrentBubble / mNumBubblePerActor;
+  SetBubbleParameter( mBubbleActors[groupIdx], curUniform, emitPosition, direction, displacement);
+  animation.AnimateTo( (mBubbleActors[groupIdx])->GetPercentageProperty(curUniform),
                        1.f, AlphaFunction::LINEAR );
 
-  if( mCurrentUniform % mNumShader == 0 )
-  {
-    unsigned int uniform = mCurrentUniform / mNumShader;
-    SetBubbleParameter(mEffectForNoise, uniform, emitPosition, displacement);
-    animation.AnimateTo( Property( mEffectForNoise, mEffectForNoise.GetPercentagePropertyName(uniform) ),
-                         1.f, AlphaFunction::LINEAR );
-  }
-
-  mCurrentUniform = (mCurrentUniform + 1) % mTotalNumOfBubble;
-}
-
-void BubbleEmitter::StartExplosion( float duration, float multiple )
-{
-  Animation animation = Animation::New( duration );
-  for(unsigned int i=0; i < mNumShader; i++ )
-  {
-    animation.AnimateTo( Property( mEffect[i], mEffect[i].GetMagnificationPropertyName() ),
-                         multiple, AlphaFunction::EASE_OUT);
-  }
-  animation.AnimateTo( Property( mEffectForNoise, mEffectForNoise.GetMagnificationPropertyName() ),
-                       multiple, AlphaFunction::EASE_OUT);
-  animation.Play();
-
-  animation.FinishedSignal().Connect(this, &BubbleEmitter::OnExplosionFinished);
+  mCurrentBubble = (mCurrentBubble + 1) % mTotalNumOfBubble;
 }
 
 void BubbleEmitter::Restore()
 {
-  for(unsigned int i=0; i < mNumShader; i++ )
+  for(unsigned int i=0; i < mNumActor; i++ )
   {
-    mEffect[i].ResetParameters();
+    (mBubbleActors[i])->ResetProperties();
   }
-  mEffectForNoise.ResetParameters();
-}
-
-void BubbleEmitter::GenMaterial()
-{
-  mCustomMaterial = Material::New("CustomMaterial");
-  mCustomMaterial.SetOpacity(1.0f);
-  mCustomMaterial.SetDiffuseColor(Color::WHITE);
-  mCustomMaterial.SetAmbientColor(Vector4(0.0, 0.1, 0.1, 1.0));
-  mCustomMaterial.SetMapU( Material::MAPPING_MODE_WRAP );
-  mCustomMaterial.SetMapV( Material::MAPPING_MODE_WRAP );
-  mCustomMaterial.SetDiffuseTexture( mShapeImage );
 }
 
-void BubbleEmitter::AddVertex(MeshData::VertexContainer& vertices, Vector3 XYZ, Vector2 UV)
+Geometry BubbleEmitter::CreateGeometry( unsigned int numOfPatch )
 {
-  MeshData::Vertex meshVertex;
-  meshVertex.x = XYZ.x;
-  meshVertex.y = XYZ.y;
-  meshVertex.z = XYZ.z;
-  meshVertex.u = UV.x;
-  meshVertex.v = UV.y;
-  vertices.push_back(meshVertex);
-}
-
-void BubbleEmitter::AddTriangle(MeshData::FaceIndices& faces,
-size_t v0, size_t v1, size_t v2)
-{
-  faces.push_back(v0);
-  faces.push_back(v1);
-  faces.push_back(v2);
-}
+  unsigned int numVertex = numOfPatch*4u;
+  std::vector<Vertex> vertexData;
+  vertexData.reserve( numVertex );
 
-void BubbleEmitter::ConstructBubbleMesh( MeshData& meshData, unsigned int numOfBubble)
-{
-  MeshData::VertexContainer    vertices;
-  MeshData::FaceIndices        faces;
-  BoneContainer                bones(0);
+  unsigned int numIndex = numOfPatch*6u;
+  Vector<unsigned int> indexData;
+  indexData.Reserve( numIndex );
 
-  for(unsigned int index = 0; index < numOfBubble; index ++)
+  for(unsigned int i = 0; i < numOfPatch; i++)
   {
     float curSize = RandomRange(mBubbleSizeRange.x, mBubbleSizeRange.y);
-    if(rand()%100 < 1)
-    {
-      curSize *= 2.f;
-    }
-    float depth = static_cast<float>( index );
-    AddVertex( vertices, Vector3(0.f,0.f,depth), Vector2(0.f,0.f) );
-    AddVertex( vertices, Vector3(0.f,curSize,depth), Vector2( 0.f,1.f ));
-    AddVertex( vertices, Vector3(curSize,curSize,depth), Vector2(1.f,1.f) );
-    AddVertex( vertices, Vector3(curSize,0.f,depth), Vector2(1.f,0.f) );
+
+    float index = static_cast<float>( i );
+    vertexData.push_back( Vertex( index, Vector2(0.f,0.f),         Vector2(0.f,0.f) ) );
+    vertexData.push_back( Vertex( index, Vector2(0.f,curSize),     Vector2(0.f,1.f)  ) );
+    vertexData.push_back( Vertex( index, Vector2(curSize,curSize), Vector2(1.f,1.f)  ) );
+    vertexData.push_back( Vertex( index, Vector2(curSize,0.f),     Vector2(1.f,0.f)  ) );
 
     unsigned int idx = index * 4;
-    AddTriangle( faces, idx, idx+1, idx+2);
-    AddTriangle( faces, idx, idx+2, idx+3);
+    indexData.PushBack( idx );
+    indexData.PushBack( idx+1 );
+    indexData.PushBack( idx+2 );
+    indexData.PushBack( idx );
+    indexData.PushBack( idx+2 );
+    indexData.PushBack( idx+3 );
   }
 
-  meshData.SetData(vertices, faces, bones, mCustomMaterial);
-  meshData.SetHasColor(false);
-  meshData.SetHasTextureCoords(true);
-}
+  Property::Map vertexFormat;
+  vertexFormat["aIndex"] = Property::FLOAT;
+  vertexFormat["aPosition"] = Property::VECTOR2;
+  vertexFormat["aTexCoord"] = Property::VECTOR2;
+  PropertyBuffer vertices = PropertyBuffer::New( PropertyBuffer::STATIC, vertexFormat, numVertex  );
+  vertices.SetData( &vertexData[0] );
 
-void BubbleEmitter::SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform,
-                                        const Vector2& emitPosition, const Vector2& displacement )
-{
-  int halfRange = displacement.x / 2;
-  Vector2 randomVec(rand()%static_cast<int>(displacement.x) - halfRange, rand()%static_cast<int>(displacement.y) - halfRange);
-  if(randomVec.y > 0.0f)
-  {
-    randomVec.y *= 0.33f;
-  }
+  Property::Map indexFormat;
+  indexFormat["indices"] = Property::UNSIGNED_INTEGER;
+  PropertyBuffer indices = PropertyBuffer::New( PropertyBuffer::STATIC, indexFormat, numIndex  );
+  indices.SetData( &indexData[0] );
 
-  Vector4 startAndEndPos( emitPosition.x, emitPosition.y, emitPosition.x+randomVec.x, emitPosition.y+randomVec.y );
-  effect.SetStartAndEndPosition( curUniform, startAndEndPos );
+  Geometry geometry = Geometry::New();
+  geometry.AddVertexBuffer( vertices );
+  geometry.SetIndexBuffer( indices );
 
-  effect.SetPercentage( curUniform, 0.f);
+  return geometry;
 }
 
-void BubbleEmitter::SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform,
+void BubbleEmitter::SetBubbleParameter( BubbleActorPtr bubbleActor, unsigned int curUniform,
                                         const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement )
 {
   Vector2 dir(direction);
@@ -390,19 +351,9 @@ void BubbleEmitter::SetBubbleParameter( BubbleEffect& effect, unsigned int curUn
     randomVec.y *= 0.33f;
   }
   Vector4 startAndEndPos( emitPosition.x, emitPosition.y, emitPosition.x+randomVec.x, emitPosition.y+randomVec.y );
-  effect.SetStartAndEndPosition( curUniform, startAndEndPos );
+  bubbleActor->SetStartAndEndPosition( curUniform, startAndEndPos );
 
-  effect.SetPercentage( curUniform, 0.f);
-}
-
-void BubbleEmitter::OnExplosionFinished( Animation& source )
-{
-  Restore();
-}
-
-float BubbleEmitter::RandomRange(float f0, float f1)
-{
-  return f0 + (rand() & 0xfff) * (f1-f0) * (1.0f/4095.0f);
+  bubbleActor->SetPercentage( curUniform, 0.f);
 }
 
 } // namespace Internal
index 6cac58b..135a634 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_INTERNAL_BUBBLE_EMITTER_IMPL_H__
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 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.
 #include <dali/public-api/actors/camera-actor.h>
 #include <dali/public-api/actors/image-actor.h>
 #include <dali/public-api/common/stage.h>
+#include <dali/public-api/geometry/geometry.h>
 #include <dali/public-api/images/frame-buffer-image.h>
 #include <dali/public-api/render-tasks/render-task.h>
+#include <dali/public-api/shader-effects/sampler.h>
+#include <dali/public-api/shader-effects/material.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/bubble-effect/bubble-emitter.h>
-#include <dali-toolkit/public-api/shader-effects/bubble-effect/bubble-effect.h>
 
 namespace Dali
 {
@@ -39,6 +41,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class BubbleActor;
+typedef IntrusivePtr<BubbleActor> BubbleActorPtr;
+
 /**
  * BubbleEmitter implementation class.
  */
@@ -95,11 +100,6 @@ public:
   void EmitBubble( Animation& animation, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement );
 
   /**
-   * @copydoc Toolkit::BubbleEmitter::StartExplosion
-   */
-  void StartExplosion( float duration, float multiple );
-
-  /**
    * @copydoc Toolkit::BubbleEmitter::Restore
    */
   void Restore();
@@ -125,6 +125,13 @@ private:
   void OnInitialize();
 
   /**
+   * Create the geometry of a mesh.
+   * @param[in] numOfPatch The triangle number in the mesh is 2*numOfPatch; two triangles for each bubble.
+   * @return The mesh geometry.
+   */
+  Geometry CreateGeometry( unsigned int numOfPatch );
+
+  /**
    * Callback function of the finished signal of off-screen render task.
    * @param[in] source The render task used to create the color adjusted background image.
    */
@@ -136,98 +143,41 @@ private:
   void OnContextRegained();
 
   /**
-   * Generate the material object which is attached to the meshActor to describe its color, texture, texture mapping mode etc.
-   */
-  void GenMaterial();
-
-  /**
-   * Add a vertex to the mesh data.
-   * @param[in] vertices The collection of vertices.
-   * @param[in] XYZ The vertex position coordinates.
-   * @param[in] UV The vertex texture coordinate.
-   */
-  void AddVertex(MeshData::VertexContainer& vertices, Vector3 XYZ, Vector2 UV);
-
-  /**
-   * Add a triangle to the mesh data.
-   * @param[in] faces The collection od FaceIndex items.
-   * @param[in] v0 The index of the first point of the triangle.
-   * @param[in] v1 The index of the second point of the triangle.
-   * @param[in] v3 The index of the first point of the triangle.
-   */
-  void AddTriangle(MeshData::FaceIndices& faces,size_t v0, size_t v1, size_t v2);
-
-  /**
-   * Create a new mesh.
-   * @param[in] meshData The MeshData object which encompasses all the data required to describe and render the 3D mesh.
-   * @param[in] numberOfBubble The triangle number in the meshData is 2*numOfBubble; two triangles for each bubble
-   */
-  void ConstructBubbleMesh( MeshData& meshData, unsigned int numOfBubble);
-
-  /**
-   * Set the uniform values to the shader effect to emit a bubble
-   * @param[in] effect The BubbleEffect to render the current bubble
-   * @param[in] curUniform The index of the uniform array in the shader
-   * @param[in] emitPosition The start position of the bubble movement.
-   * @param[in] displacement The displacement used to bound the moving distance of the bubble.
-   */
-  void SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform,
-                           const Vector2& emitPosition, const Vector2& displacement );
-
-  /**
    * Set the uniform values to the shader effect to emit a bubble
-   * @param[in] effect The BubbleEffect to render the current bubble
+   * @param[in] bubbleActor The BubbleActor to render the current bubble
    * @param[in] curUniform The index of the uniform array in the shader
    * @param[in] emitPosition The start position of the bubble movement.
    * @param[in] direction The direction used to constrain the bubble to move in an adjacent direction around it.
    * @param[in] displacement The displacement used to bound the moving distance of the bubble.
    */
-  void SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform,
+  void SetBubbleParameter( BubbleActorPtr bubbleActor, unsigned int curUniform,
                            const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement );
 
-  /**
-   * Callback function of the explosion animation finished signal to reset the shader parameters
-   * @param[in] source The explosion animation.
-   */
-  void OnExplosionFinished( Animation& source );
-
-  /**
-   * Return a random value between the given interval.
-   * @param[in] f0 The low bound
-   * @param[in] f1 The up bound
-   * @return A random value between the given interval
-   */
-  float RandomRange(float f0, float f1);
-
 private:
 
-  Vector2                     mMovementArea;        ///< The size of the bubble moving area, usually the same size as the background image actor.
-  Image                       mShapeImage;          ///< The alpha channnel of this texture defines the bubble shape.
   Actor                       mBubbleRoot;          ///<The bubble root actor. Need to add it to stage to get the bubbles rendered.
-
-  unsigned int                mNumBubblePerShader;  ///< How many bubbles for each BubbleEffect shader.
-  unsigned int                mNumShader;           ///< How many BubbleEffect shaders are used.
-  unsigned int                mTotalNumOfBubble;    ///< mNumBubblePerShader*mNumShader.
-  bool                        mRenderTaskRunning;   ///< If the background render task is currently running
-
-  Vector2                     mBubbleSizeRange;     ///< The bubble size range.
-
-  std::vector<Mesh>           mMesh;                ///< The mesh vector, each mesh is used to create a meshActor which applies a BubbleEffect.
-  std::vector<MeshActor>      mMeshActor;           ///< The meshActor vector, its size is mNumShader.
-  MeshActor                   mMeshActorForNoise;   ///< An Extra mesh data to emit bubbles which emit bubble in totally random angle.
-  Material                    mCustomMaterial;      ///< The material object which is attached to the meshActor to describe its color, texture, texture mapping mode etc.
-
-  std::vector<BubbleEffect>   mEffect;              ///< The bubbleEffect vector, corresponding to the mMeshActoe vector.
-  BubbleEffect                mEffectForNoise;      ///< The extra bubbleEffect, corresponding to the mMeshActorForNoise.
-
-  unsigned int                mCurrentUniform;      ///< Keep track of the uniform index for the newly emitted bubble
-
-  Vector3                     mHSVDelta;            ///< The HSV difference used to adjust the background image color.
+  Image                       mShapeImage;          ///< The alpha channnel of this texture defines the bubble shape.
   Image                       mBackgroundImage;     ///< The original background image
   FrameBufferImage            mEffectImage;         ///< The image stores the adjusted color of the background image.The bubbles pick color from this image.
   CameraActor                 mCameraActor;         ///< The render task views the scene from the perspective of this actor.
 
+  Sampler                     mSamplerBackground;    ///< The sampler which provides the background image to material
+  Sampler                     mSamplerBubbleShape;   ///< The sampler which provides the bubble shape image to material
+  Geometry                    mMeshGeometry;         ///< The mesh geometry which contains the vertices and indices data
+  Material                    mMaterial;             ///< The material which controls the bubble display
+  std::vector<BubbleActorPtr> mBubbleActors;         ///< The meshActor vector, its size is mNumShader.
+
+  Vector2                     mMovementArea;        ///< The size of the bubble moving area, usually the same size as the background image actor.
+  Vector2                     mBubbleSizeRange;     ///< The size range of the bubbles; x component is the low bound, and y component is the up bound.
+  Vector3                     mHSVDelta;            ///< The HSV difference used to adjust the background image color.
+
+  unsigned int                mNumBubblePerActor;   ///< How many bubbles for each BubbleActor.
+  unsigned int                mNumActor;            ///< How many BubbleActors are used.
   unsigned int                mDensity;             ///< How many bubbles will emit at each time, they are controlled by same uniforms in the shader.
+  unsigned int                mTotalNumOfBubble;    ///< mNumBubblePerShader*mNumShader.
+  unsigned int                mCurrentBubble;       ///< Keep track of the index for the newly emitted bubble
+
+  bool                        mRenderTaskRunning;   ///< If the background render task is currently running
 
 };
 
diff --git a/dali-toolkit/internal/controls/bubble-effect/color-adjuster.h b/dali-toolkit/internal/controls/bubble-effect/color-adjuster.h
new file mode 100644 (file)
index 0000000..8e24326
--- /dev/null
@@ -0,0 +1,94 @@
+#ifndef __DALI_TOOLKIT_INTERNAL_COLOR_ADJUSTER_H_
+#define __DALI_TOOLKIT_INTERNAL_COLOR_ADJUSTER_H_
+
+/*
+ * Copyright (c) 2015 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/public-api/math/vector3.h>
+#include <dali/public-api/shader-effects/shader-effect.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+* Creates a new ColorAdjuster effect.
+* ColorAdjuster is a custom shader effect to adjust the image color in HSV space.
+* @param[in] hsvDelta The color difference to apply to the HSV channel.
+* @param[in] ignoreAlpha If true, the result color will be opaque even though source has alpha value
+* @return A handle to a newly allocated Dali resource.
+*/
+inline ShaderEffect CreateColorAdjuster( const Vector3& hsvDelta, bool ignoreAlpha = false )
+{
+  std::string fragmentShader = DALI_COMPOSE_SHADER(
+    precision highp float;\n
+    uniform vec3 uHSVDelta;\n
+    uniform float uIgnoreAlpha;\n
+    float rand(vec2 co) \n
+    {\n
+      return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); \n}
+    \n
+    vec3 rgb2hsv(vec3 c)\n
+    {\n
+      vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n
+      vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n
+      vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n
+      \n
+      float d = q.x - min(q.w, q.y);\n
+      float e = 1.0e-10;\n
+      return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n
+    }\n
+    vec3 hsv2rgb(vec3 c)\n
+    {\n
+      vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n
+      vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n
+      return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n
+    }\n
+    void main() {\n
+      vec4 color = texture2D(sTexture, vTexCoord); \n
+      vec3 hsvColor = rgb2hsv( color.rgb );\n
+      // modify the hsv Value
+      hsvColor += uHSVDelta * rand(vTexCoord); \n
+      // if the new vale exceeds one, then decrease it
+      hsvColor -= max(hsvColor*2.0 - vec3(2.0), 0.0);\n
+      // if the new vale drops below zero, then increase it
+      hsvColor -= min(hsvColor*2.0, 0.0);\n
+      color.rgb = hsv2rgb( hsvColor ); \n
+      // uIgnoreAlpha decide the result alpha will be 1.0 or source's alpha
+      color.a += uIgnoreAlpha;\n
+      gl_FragColor = color; \n
+    }\n
+  );
+
+  ShaderEffect shaderEffect = ShaderEffect::New("", fragmentShader);
+  shaderEffect.SetUniform( "uHSVDelta", hsvDelta );
+  shaderEffect.SetUniform( "uIgnoreAlpha", ignoreAlpha?1.0f:0.0f );
+
+  return shaderEffect;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_COLOR_ADJUSTER_H_ */
index 7eaa5cd..e9ea95a 100644 (file)
@@ -14,6 +14,8 @@ toolkit_src_files = \
    $(toolkit_src_dir)/builder/replacement.cpp \
    $(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \
    $(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \
+   $(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \
+   $(toolkit_src_dir)/controls/bubble-effect/bubble-actor.cpp \
    $(toolkit_src_dir)/controls/buttons/button-impl.cpp \
    $(toolkit_src_dir)/controls/buttons/check-box-button-impl.cpp \
    $(toolkit_src_dir)/controls/buttons/push-button-impl.cpp \
index b719b22..9c1fa2c 100644 (file)
@@ -109,11 +109,6 @@ void BubbleEmitter::EmitBubble( Animation& animation, const Vector2& emitPositio
   GetImpl(*this).EmitBubble( animation, emitPosition, direction, displacement );
 }
 
-void BubbleEmitter::StartExplosion( float duration, float multiple )
-{
-  GetImpl(*this).StartExplosion( duration, multiple );
-}
-
 void BubbleEmitter::Restore()
 {
   GetImpl(*this).Restore();
index 0141454..461e564 100644 (file)
@@ -131,9 +131,9 @@ public:
   /**
    * @brief Set the density of the bubble.
    *
-   * Ideally every bubble's moving track is controlled by different uniforms in BubbleEffect shaders.
+   * Ideally every bubble's moving track is controlled by different uniforms in shader.
    * To increase the density, 'density' number of bubbles are sharing one group of uniforms, but with random offsets between these bubbles.
-   * The available density is one to nine. The default density is five.
+   * The available densities are one to nine only. The default value is five.
    * By set the density bigger than one, instead of emit one bubble each time, a 'density' number of bubbles are emitted.
    * @param[in] density The density of the bubble.
    */
@@ -158,14 +158,6 @@ public:
   void EmitBubble( Animation& animation, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement );
 
   /**
-   * @brief Start an animation to enlarge every activated bubble's size and moving speed.
-   *
-   * @param[in] duration The duration of the animation
-   * @param[in] multiple The bubble size and moving speed will be increased gradually to multiple speed during the animation.
-   */
-  void StartExplosion( float duration, float multiple );
-
-  /**
    * @brief Reset all the parameters controlling the bubbles after animation.
    */
   void Restore();
index 9493cef..f275660 100755 (executable)
@@ -7,6 +7,7 @@ public_api_src_files = \
   $(public_api_src_dir)/controls/control-impl.cpp \
   $(public_api_src_dir)/controls/control.cpp \
   $(public_api_src_dir)/controls/alignment/alignment.cpp \
+  $(public_api_src_dir)/controls/bubble-effect/bubble-emitter.cpp \
   $(public_api_src_dir)/controls/buttons/button.cpp \
   $(public_api_src_dir)/controls/buttons/check-box-button.cpp \
   $(public_api_src_dir)/controls/buttons/push-button.cpp \