Commit 84c8bd6c49e6cfb475d5999edfa17ce7aa8ab4e7

Authored by Xiangyin Ma
1 parent 446388d5

(Shader Effect) update the bubble effect demo

[Issue#]
[Problem]
[Cause]
[Solution]

Change-Id: I13cf665cab3e0a1fac999700a73c6cc3027640f1
Signed-off-by: Xiangyin Ma <x1.ma@samsung.com>
examples/shader-effect/bubble-effect-example.cpp
... ... @@ -14,25 +14,18 @@
14 14 // limitations under the License.
15 15 //
16 16  
17   -#include <stdio.h>
18   -#include <unistd.h>
19   -#include <getopt.h>
20   -#include <sstream>
21 17 #include <dali/dali.h>
22   -#include "dali-toolkit/dali-toolkit.h"
23   -
  18 +#include <dali-toolkit/dali-toolkit.h>
24 19 #include "../shared/view.h"
25 20  
26 21 using namespace Dali;
27 22  
28   -using Dali::Material;
29   -
30 23 namespace
31 24 {
32   -const char * const TEXTURE_IMAGE ( DALI_IMAGE_DIR "bubble-effect-texture-border.png" );
33 25 const char * const TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
34 26 const char * const APPLICATION_TITLE( "Bubble Effect" );
35   -const char * const CHANGE_IMAGE_ICON( DALI_IMAGE_DIR "icon-change.png" );
  27 +const char * const CHANGE_BACKGROUND_ICON( DALI_IMAGE_DIR "icon-change.png" );
  28 +const char * const CHANGE_BUBBLE_SHAPE_ICON( DALI_IMAGE_DIR "icon-replace.png" );
36 29  
37 30 const char* BACKGROUND_IMAGES[]=
38 31 {
... ... @@ -42,180 +35,34 @@ const char* BACKGROUND_IMAGES[]=
42 35 DALI_IMAGE_DIR "background-4.jpg",
43 36 DALI_IMAGE_DIR "background-5.jpg",
44 37 };
45   -const unsigned int NUM_BACKGROUND_IMAGES( sizeof(BACKGROUND_IMAGES) / sizeof(BACKGROUND_IMAGES[0]) );
46   -
47   -const float MIN_DISTANCE( 2.f);
48   -const float MAX_DISTANCE( 200.f);
49   -const float BUBBLE_SIZE( 40.f );
50   -const float BUBBLE_MIN_SIZE( 5.f );
51   -const unsigned long MAX_TIME_INTERVAL(100);
52   -const unsigned int NUMBER_OF_BUBBLES( 100 ); //this value cannot be bigger than 100;
53   -const unsigned int NUMBER_OF_GROUP( 7 );
54   -const unsigned int TOTAL_NUMBER_OF_BUBBLES( NUMBER_OF_BUBBLES * NUMBER_OF_GROUP );
55   -} // unnamed namespace
56   -
57   -class BubbleEffect : public ShaderEffect
58   -{
59   -public:
60   -
61   - BubbleEffect()
62   - {}
63   -
64   - static BubbleEffect New( unsigned int numberOfBubble )
65   - {
66   - std::ostringstream meshVertexStringStream;
67   - meshVertexStringStream << "#define NUMBER_OF_BUBBLE "<< numberOfBubble << "\n";
68   - std::string meshVertex(
69   - " uniform float uGravity; \n"
70   - " uniform vec4 uStartAndEndPos[NUMBER_OF_BUBBLE];\n"
71   - " uniform float uEasing[NUMBER_OF_BUBBLE];\n"
72   - " uniform float uPercentage[NUMBER_OF_BUBBLE];\n"
73   - " uniform vec2 uStageSize; \n"
74   - " uniform vec2 offset[9]; \n"
75   - " varying float vPercentage;\n"
76   - " varying vec2 vEffectTexCoord;\n"
77   - " void main()\n"
78   - " {\n"
79   - " mediump vec4 position = vec4( aPosition.x, aPosition.y, 0.0, 1.0 );\n"
80   - " int zCoord = int(aPosition.z); \n"
81   - " int idx = int(mod(aPosition.z, float(NUMBER_OF_BUBBLE)));\n"
82   - " int groupIdx = (zCoord - idx) / NUMBER_OF_BUBBLE;\n"
83   - " vec4 startAndEnd = uStartAndEndPos[idx]; \n"
84   - " startAndEnd.zw += offset[groupIdx];\n"
85   - "\n"
86   - " if( uPercentage[idx] < 1.0 )\n"
87   - " {\n"
88   - " float positionDelta = uPercentage[idx];\n"
89   - " if (mod(uEasing[idx], 4.0) > 1.5) { positionDelta = pow(uPercentage[idx], 2.0); } \n"
90   - " else if (mod(uEasing[idx], 8.0) > 3.5) { positionDelta = 1.0 - pow((1.0-uPercentage[idx]),2.0); }\n"
91   - " else if (mod(uEasing[idx], 16.0) > 7.5) { positionDelta = pow(2.0, 10.0 * (uPercentage[idx] - 1.0)) - 0.001; }\n"
92   - " else if (mod(uEasing[idx], 32.0) > 15.5) { positionDelta = 1.001 * (-pow(2.0, -10.0 * uPercentage[idx]) + 1.0); }\n"
93   -
94   - " position.xy = position.xy + startAndEnd.xy + startAndEnd.zw * positionDelta; \n"
95   - " if (mod(uEasing[idx],64.0) > 31.5) { position.y = position.y - (0.5*uGravity * pow(uPercentage[idx]+0.1, 2.0)); }\n"
96   - " }\n"
97   - " gl_Position = uMvpMatrix * position;\n"
98   - "\n"
99   - " mediump vec2 start = uCustomTextureCoords.xy;\n"
100   - " mediump vec2 scale = uCustomTextureCoords.zw;\n"
101   - " vTexCoord = vec2( start.x + aTexCoord.x * scale.x, start.y + aTexCoord.y * scale.y );\n"
102   - " vPercentage = uPercentage[idx];\n"
103   - " vEffectTexCoord = startAndEnd.xy / uStageSize; \n"
104   - " }\n" );
105   - meshVertexStringStream << meshVertex;
106   -
107   - std::string meshFragment(
108   - " varying float vPercentage;\n"
109   - " varying vec2 vEffectTexCoord;\n"
110   - "\n"
111   - " void main()\n"
112   - " {\n"
113   - " vec4 fragColor = texture2D(sEffect, vEffectTexCoord);\n"
114   - " fragColor.rgb *= 1.2; \n"
115   - " fragColor *= uColor;\n"
116   - " fragColor.a *= texture2D(sTexture, vTexCoord).a * ( 1.0-vPercentage*vPercentage );\n"
117   - " gl_FragColor = fragColor;\n"
118   - " }\n");
119   -
120   - ShaderEffect shaderEffect = ShaderEffect::New( meshVertexStringStream.str(), meshFragment,
121   - GeometryType( GEOMETRY_TYPE_TEXTURED_MESH),
122   - ShaderEffect::GeometryHints( ShaderEffect::HINT_BLENDING ) );
123   - BubbleEffect handle( shaderEffect );
124   - handle.mNumOfBubbles = numberOfBubble;
125   - handle.SetUniform( "uGravity", 100.f );
126   - handle.SetUniform( "uStageSize", Stage::GetCurrent().GetSize() );
127   - for( unsigned int i=0; i<numberOfBubble; i++ )
128   - {
129   - handle.SetPercentage( i, 1.f);
130   - }
131   -
132   - srand(time(NULL));
133   -
134   - return handle;
135   - }
136   -
137   - void SetBubbleParameter(unsigned int idx, const Vector2& emitPosition, Vector2 direction)
138   - {
139   - Vector2 randomVec(rand()%400-200, rand()%400-200);
140   - float length = randomVec.Length();
141   - randomVec /= length;
142   - direction.Normalize();
143   - Vector2 endPos = (randomVec - direction*4.f);
144   - endPos.Normalize();
145   - Vector4 startAndEndPos( emitPosition.x, emitPosition.y, endPos.x*length, endPos.y*length );
146   - SetStartAndEndPos( idx, startAndEndPos );
147   -
148   - float easing = pow( 2, rand()%5-1 ) + ( rand()%2-1 )*32;
149   - SetEasing( idx, easing );
150   -
151   - SetPercentage( idx, 0.f);
152   -
153   - float offset = 100.f;
154   - SetUniform("offset[0]", Vector2(0.f,0.f));
155   - SetUniform("offset[1]", Vector2(offset,0.f));
156   - SetUniform("offset[2]", Vector2(-offset,0.f));
157   - SetUniform("offset[3]", Vector2(0.f,offset));
158   - SetUniform("offset[4]", Vector2(0.f,-offset));
159   - SetUniform("offset[5]", Vector2(offset,offset)*0.707f );
160   - SetUniform("offset[6]", Vector2(offset,-offset)*0.707f);
161   - SetUniform("offset[7]", Vector2(-offset,offset)*0.707f);
162   - SetUniform("offset[8]", Vector2(-offset,-offset)*0.707f);
163   - }
164   -
165   - std::string GetPercentagePropertyName( unsigned int idx ) const
166   - {
167   - assert( idx < mNumOfBubbles );
168   - std::ostringstream oss;
169   - oss<< "uPercentage["<< idx << "]";
170   - return oss.str();
171   - }
172   -
173   -private:
174   - // Helper for New()
175   - BubbleEffect( ShaderEffect handle )
176   - : ShaderEffect( handle )
177   - {}
178   -
179   - void SetStartAndEndPos( unsigned int idx, const Vector4& startAndEndPos )
180   - {
181   - assert( idx < mNumOfBubbles );
182   - std::ostringstream oss;
183   - oss<< "uStartAndEndPos["<< idx << "]";
184   - SetUniform( oss.str(), startAndEndPos );
185   - }
186   -
187   - void SetEasing( unsigned int idx, float easing )
188   - {
189   - assert( idx < mNumOfBubbles );
190   - std::ostringstream oss;
191   - oss<< "uEasing["<< idx << "]";
192   - SetUniform( oss.str(), easing );
193   - }
194   -
195   - void SetPercentage( unsigned int idx, float percentage )
196   - {
197   - assert( idx < mNumOfBubbles );
198   - std::ostringstream oss;
199   - oss<< "uPercentage["<< idx << "]";
200   - SetUniform( oss.str(), percentage );
201   - }
  38 +const unsigned int NUM_BACKGROUND_IMAGES( sizeof( BACKGROUND_IMAGES ) / sizeof( BACKGROUND_IMAGES[0] ) );
202 39  
203   -private:
204   -
205   - unsigned int mNumOfBubbles;
  40 +const char* BUBBLE_SHAPE_IMAGES[] =
  41 +{
  42 + DALI_IMAGE_DIR "blocks-ball.png",
  43 + DALI_IMAGE_DIR "icon-item-view-layout-spiral.png",
  44 + DALI_IMAGE_DIR "icon-replace.png",
  45 + DALI_IMAGE_DIR "icon-effect-cross.png"
206 46 };
  47 +const unsigned int NUM_BUBBLE_SHAPE_IMAGES( sizeof( BUBBLE_SHAPE_IMAGES ) / sizeof( BUBBLE_SHAPE_IMAGES[0] ) );
  48 +
  49 +const Vector2 DEFAULT_BUBBLE_SIZE( 10.f, 30.f );
  50 +const unsigned int DEFAULT_NUMBER_OF_BUBBLES( 1000 );
  51 +}// end LOCAL_STUFF
207 52  
  53 +// This example shows the usage of BubbleEmitter which displays lots of moving bubbles on the stage.
208 54 class BubbleEffectExample : public ConnectionTracker
209 55 {
210 56 public:
211 57 BubbleEffectExample(Application &app)
212 58 : mApp(app),
213   - mCurrentUniform( 0 ),
214   - mTouchable( false ),
215   - mLastTouchTime( 0 ),
216   - mRescoucesCleared( false ),
217   - mCurrentBackgroundImageId( 0 )
  59 + mHSVDelta( Vector3( 0.f, 0.f, 0.5f ) ),
  60 + mNeedNewAnimation( true ),
  61 + mTimerInterval( 16 ),
  62 + mCurrentBackgroundImageId( 0 ),
  63 + mCurrentBubbleShapeImageId( 0 )
218 64 {
  65 + // Connect to the Application's Init signal
219 66 app.InitSignal().Connect(this, &BubbleEffectExample::Create);
220 67 }
221 68  
... ... @@ -223,264 +70,221 @@ public:
223 70 {
224 71 }
225 72  
226   -public:
  73 +private:
227 74  
  75 + // The Init signal is received once (only) during the Application lifetime
228 76 void Create(Application& app)
229 77 {
230 78 Stage stage = Stage::GetCurrent();
231   - Vector2 size = stage.GetSize();
  79 + Vector2 stageSize = stage.GetSize();
  80 +
  81 + stage.KeyEventSignal().Connect(this, &BubbleEffectExample::OnKeyEvent);
232 82  
233 83 // Creates a default view with a default tool bar.
234 84 // The view is added to the stage.
235 85 Toolkit::ToolBar toolBar;
236   - mContent = DemoHelper::CreateView( app,
237   - mView,
238   - toolBar,
239   - "",
240   - TOOLBAR_IMAGE,
241   - APPLICATION_TITLE );
242   -
243   - // Create a effect toggle button. (right of toolbar)
244   - Image imageLayout = Image::New( CHANGE_IMAGE_ICON );
245   - Toolkit::PushButton layoutButton = Toolkit::PushButton::New();
246   - layoutButton.SetBackgroundImage(imageLayout);
247   - layoutButton.ClickedSignal().Connect( this, &BubbleEffectExample::OnImageChageIconClicked );
248   - toolBar.AddControl( layoutButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
249   -
250   - mRoot = Actor::New();
251   - mRoot.SetParentOrigin( ParentOrigin::CENTER );
252   - stage.Add(mRoot);
253   -
254   - mFrameBufferImage = FrameBufferImage::New( size.width/4.f, size.height/4.f, Pixel::RGBA8888, Dali::Image::Unused );
255   - mTimer = Timer::New( 1000 );
256   - mTimer.TickSignal().Connect( this, &BubbleEffectExample::ClearBlurResource );
257   -
258   - SetImage( BACKGROUND_IMAGES[ mCurrentBackgroundImageId ] );
259   -
260   - GenMaterial();
261   - MeshData meshData;
262   - ConstructBubbleMesh( meshData, NUMBER_OF_BUBBLES*9, BUBBLE_SIZE);
263   - for(unsigned int i=0; i < NUMBER_OF_GROUP; i++ )
  86 + Toolkit::View view;
  87 + Layer content = DemoHelper::CreateView( app,
  88 + view,
  89 + toolBar,
  90 + "",
  91 + TOOLBAR_IMAGE,
  92 + APPLICATION_TITLE );
  93 +
  94 + // Add a button to change background. (right of toolbar)
  95 + mChangeBackgroundButton = Toolkit::PushButton::New();
  96 + mChangeBackgroundButton.SetBackgroundImage( Image::New( CHANGE_BACKGROUND_ICON ) );
  97 + mChangeBackgroundButton.ClickedSignal().Connect( this, &BubbleEffectExample::OnChangeIconClicked );
  98 + toolBar.AddControl( mChangeBackgroundButton,
  99 + DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage,
  100 + Toolkit::Alignment::HorizontalRight,
  101 + DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
  102 + // Add a button to change bubble shape. ( left of bar )
  103 + mChangeBubbleShapeButton = Toolkit::PushButton::New();
  104 + mChangeBubbleShapeButton.SetBackgroundImage( Image::New( CHANGE_BUBBLE_SHAPE_ICON ) );
  105 + mChangeBubbleShapeButton.ClickedSignal().Connect( this, &BubbleEffectExample::OnChangeIconClicked );
  106 + toolBar.AddControl( mChangeBubbleShapeButton,
  107 + DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage,
  108 + Toolkit::Alignment::HorizontalLeft,
  109 + DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
  110 +
  111 + // Create and initialize the BubbleEmitter object
  112 + mBubbleEmitter = Toolkit::BubbleEmitter::New( stageSize,
  113 + Image::New( BUBBLE_SHAPE_IMAGES[mCurrentBubbleShapeImageId] ),
  114 + DEFAULT_NUMBER_OF_BUBBLES,
  115 + DEFAULT_BUBBLE_SIZE);
  116 + mBackgroundImage = Image::New( BACKGROUND_IMAGES[mCurrentBackgroundImageId] );
  117 + mBubbleEmitter.SetBackground( mBackgroundImage, mHSVDelta );
  118 +
  119 + // Get the root actor of all bubbles, and add it to stage.
  120 + Actor bubbleRoot = mBubbleEmitter.GetRootActor();
  121 + bubbleRoot.SetParentOrigin(ParentOrigin::CENTER);
  122 + bubbleRoot.SetZ(0.1f); // Make sure the bubbles displayed on top og the background.
  123 + content.Add( bubbleRoot );
  124 +
  125 + // Add the background image actor to stage
  126 + mBackgroundActor = ImageActor::New( mBackgroundImage );
  127 + view.SetBackground( mBackgroundActor );
  128 +
  129 + // Set up the timer to emit bubble regularly when the finger is touched down but not moved
  130 + mTimerForBubbleEmission = Timer::New( mTimerInterval );
  131 + mTimerForBubbleEmission.TickSignal().Connect(this, &BubbleEffectExample::OnTimerTick);
  132 +
  133 + // Connect the callback to the touch signal on the background
  134 + mBackgroundActor.TouchedSignal().Connect( this, &BubbleEffectExample::OnTouch );
  135 + }
  136 +
  137 +
  138 +/***********
  139 + * Emit bubbles
  140 + *****************/
  141 +
  142 + // Set up the animation of emitting bubbles, to be efficient, every animation controls multiple bubbles ( 4 here )
  143 + void SetUpAnimation( Vector2 emitPosition, Vector2 direction )
  144 + {
  145 + if( mNeedNewAnimation )
264 146 {
265   - mMesh[i] = Mesh::New( meshData );
266   - mMeshActor[i] = MeshActor::New( mMesh[i] );
267   - mMeshActor[i].SetAffectedByLighting( false );
268   - mMeshActor[i].SetParentOrigin(ParentOrigin::TOP_LEFT);
269   - stage.Add( mMeshActor[i] );
270   - mEffect[i] = BubbleEffect::New( NUMBER_OF_BUBBLES );
271   - mEffect[i].SetEffectImage( mFrameBufferImage );
272   - mMeshActor[i].SetShaderEffect( mEffect[i] );
  147 + float duration = Random::Range(1.f, 1.5f);
  148 + mEmitAnimation = Animation::New( duration );
  149 + mNeedNewAnimation = false;
  150 + mAnimateComponentCount = 0;
273 151 }
274 152  
275   - Stage::GetCurrent().KeyEventSignal().Connect(this, &BubbleEffectExample::OnKeyEvent);
  153 + mBubbleEmitter.EmitBubble( mEmitAnimation, emitPosition, direction + Vector2(0.f, 30.f) /* upwards */, Vector2(300, 600) );
  154 +
  155 + mAnimateComponentCount++;
  156 +
  157 + if( mAnimateComponentCount % 4 ==0 )
  158 + {
  159 + mEmitAnimation.Play();
  160 + mNeedNewAnimation = true;
  161 + }
276 162 }
277 163  
278   - void OnKeyEvent(const KeyEvent& event)
  164 + // Emit bubbles when the finger touches down but keep stationary.
  165 + // And stops emitting new bubble after being stationary for 2 seconds
  166 + bool OnTimerTick()
279 167 {
280   - if(event.state == KeyEvent::Down)
  168 + if(mEmitPosition == mCurrentTouchPosition) // finger is not moving
281 169 {
282   - if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
  170 + mNonMovementCount++;
  171 + if(mNonMovementCount < (1000 / mTimerInterval)) // 1 seconds
283 172 {
284   - mApp.Quit();
  173 + for(int i = 0; i < 4; i++) // emit 4 bubbles every timer tick
  174 + {
  175 + SetUpAnimation( mCurrentTouchPosition+Vector2(rand()%5, rand()%5), Vector2(rand()%60-30, rand()%100-50) );
  176 + }
285 177 }
286 178 }
287   - }
288   -
289   - void SetImage( const std::string& imagePath )
290   - {
291   - mTouchable = false;
292   -
293   - if( mScreen )
  179 + else
294 180 {
295   - mScreen.TouchedSignal().Disconnect( this, &BubbleEffectExample::OnTouch );
296   - mRoot.Remove( mScreen );
297   - ClearBlurResource();
  181 + mNonMovementCount = 0;
  182 + mEmitPosition = mCurrentTouchPosition;
298 183 }
299 184  
300   - Stage stage = Stage::GetCurrent();
301   -
302   - Image image = Image::New( imagePath );
303   - mScreen = ImageActor::New( image );
304   - mScreen.SetSize( stage.GetSize() );
305   - mScreen.SetZ( -1.f );
306   - mScreen.SetParentOrigin(ParentOrigin::CENTER);
307   - mRoot.Add(mScreen);
308   - mScreen.TouchedSignal().Connect( this, &BubbleEffectExample::OnTouch );
309   -
310   - mGaussianBlurView = Toolkit::GaussianBlurView::New( 7, 2.5f, Pixel::RGBA8888, 0.25f, 0.25f, true );
311   - mGaussianBlurView.SetParentOrigin(ParentOrigin::CENTER);
312   - mGaussianBlurView.SetSize(stage.GetSize());
313   - mGaussianBlurView.SetUserImageAndOutputRenderTarget( image, mFrameBufferImage );
314   - stage.Add( mGaussianBlurView );
315   - mGaussianBlurView.Activate();
316   -
317   - mRescoucesCleared = false;
318   - mTimer.Start();
319   -
320   - mTouchable = true;
  185 + return true;
321 186 }
322 187  
323   - bool ClearBlurResource()
  188 + // Callback function of the touch signal on the background
  189 + bool OnTouch(Dali::Actor actor, const Dali::TouchEvent& event)
324 190 {
325   - if( !mRescoucesCleared )
  191 + const TouchPoint &point = event.GetPoint(0);
  192 + switch(point.state)
326 193 {
327   - Stage::GetCurrent().Remove( mGaussianBlurView );
328   - mGaussianBlurView.Deactivate();
329   - mGaussianBlurView.Reset();
330   - mRescoucesCleared = true;
331   - }
332   - return false;
333   - }
  194 + case TouchPoint::Down:
  195 + {
  196 + mCurrentTouchPosition = point.screen;
  197 + mEmitPosition = point.screen;
  198 + mTimerForBubbleEmission.Start();
  199 + mNonMovementCount = 0;
334 200  
335   - void GenMaterial()
336   - {
337   - mCustomMaterial = Material::New("CustomMaterial");
338   - mCustomMaterial.SetOpacity(1.0f);
339   - mCustomMaterial.SetDiffuseColor(Color::WHITE);
340   - mCustomMaterial.SetAmbientColor(Vector4(0.0, 0.1, 0.1, 1.0));
341   - mCustomMaterial.SetMapU( Material::MAPPING_MODE_WRAP );
342   - mCustomMaterial.SetMapV( Material::MAPPING_MODE_WRAP );
343   - mCustomMaterial.SetDiffuseTexture( Image::New( TEXTURE_IMAGE ) );
344   - }
  201 + break;
  202 + }
  203 + case TouchPoint::Motion:
  204 + {
  205 + Vector2 displacement = point.screen - mCurrentTouchPosition;
  206 + mCurrentTouchPosition = point.screen;
  207 + //emit multiple bubbles along the moving direction when the finger moves quickly
  208 + float step = std::min(5.f, displacement.Length());
  209 + for( float i=0.25f; i<step; i=i+1.f)
  210 + {
  211 + SetUpAnimation( mCurrentTouchPosition+displacement*(i/step), displacement );
  212 + }
  213 + break;
  214 + }
  215 + case TouchPoint::Up:
  216 + case TouchPoint::Leave:
  217 + case TouchPoint::Interrupted:
  218 + {
  219 + mTimerForBubbleEmission.Stop();
  220 + break;
  221 + }
  222 + case TouchPoint::Stationary:
  223 + case TouchPoint::Last:
  224 + default:
  225 + {
  226 + break;
  227 + }
345 228  
346   - void AddVertex(MeshData::VertexContainer& vertices, Vector3 V, Vector2 UV)
347   - {
348   - MeshData::Vertex meshVertex;
349   - meshVertex.x = V.x;
350   - meshVertex.y = V.y;
351   - meshVertex.z = V.z;
352   - meshVertex.u = UV.x;
353   - meshVertex.v = UV.y;
354   - vertices.push_back(meshVertex);
  229 + }
  230 + return true;
355 231 }
356 232  
357   - void AddTriangle(MeshData::FaceIndices& faces,
358   - size_t v0, size_t v1, size_t v2)
  233 + bool OnChangeIconClicked( Toolkit::Button button )
359 234 {
360   - faces.push_back(v0);
361   - faces.push_back(v1);
362   - faces.push_back(v2);
363   - }
  235 + if(button == mChangeBackgroundButton)
  236 + {
  237 + mBackgroundImage = Image::New( BACKGROUND_IMAGES[ ++mCurrentBackgroundImageId % NUM_BACKGROUND_IMAGES ] );
364 238  
365   - void ConstructBubbleMesh( MeshData& meshData, unsigned int numOfBubble, int size )
366   - {
367   - MeshData::VertexContainer vertices;
368   - MeshData::FaceIndices faces;
369   - BoneContainer bones(0);
  239 + mBubbleEmitter.SetBackground( mBackgroundImage, mHSVDelta );
370 240  
371   - for(unsigned int index = 0; index < numOfBubble; index ++)
  241 + mBackgroundActor.SetImage( mBackgroundImage );
  242 + }
  243 + else if( button == mChangeBubbleShapeButton )
372 244 {
373   - float curSize = static_cast<float>( rand()%size + BUBBLE_MIN_SIZE);
374   - float depth = static_cast<float>( index );
375   - AddVertex( vertices, Vector3(0.f,0.f,depth), Vector2(0.f,0.f) );
376   - AddVertex( vertices, Vector3(0.f,curSize,depth), Vector2( 0.f,1.f ));
377   - AddVertex( vertices, Vector3(curSize,curSize,depth), Vector2(1.f,1.f) );
378   - AddVertex( vertices, Vector3(curSize,0.f,depth), Vector2(1.f,0.f) );
379   -
380   - unsigned int idx = index * 4;
381   - AddTriangle( faces, idx, idx+1, idx+2);
382   - AddTriangle( faces, idx, idx+2, idx+3);
  245 + mBubbleEmitter.SetShapeImage( Image::New( BUBBLE_SHAPE_IMAGES[ ++mCurrentBubbleShapeImageId % NUM_BUBBLE_SHAPE_IMAGES ] ) );
383 246 }
384   -
385   - meshData.SetData(vertices, faces, bones, mCustomMaterial);
386   - meshData.SetHasColor(false);
387   - meshData.SetHasNormals(true);
388   - meshData.SetHasTextureCoords(true);
  247 + return true;
389 248 }
390 249  
391   - void SetUpAnimation( Vector2 emitPosition, Vector2 direction )
  250 + /**
  251 + * Main key event handler
  252 + */
  253 + void OnKeyEvent(const KeyEvent& event)
392 254 {
393   - unsigned int curUniform = mCurrentUniform % NUMBER_OF_BUBBLES;
394   - unsigned int groupIdx = mCurrentUniform / NUMBER_OF_BUBBLES;
395   - mEffect[groupIdx].SetBubbleParameter(curUniform, emitPosition, direction);
396   - float duration = RandomRange( 1.f, 2.f );
397   - mAnimation[mCurrentUniform] = Animation::New( duration );
398   - mAnimationIndexPair[mAnimation[mCurrentUniform]] = mCurrentUniform;
399   - mAnimation[mCurrentUniform].AnimateTo( Property( mEffect[groupIdx], mEffect[groupIdx].GetPercentagePropertyName(curUniform) ),
400   - 1.f, AlphaFunctions::DoubleEaseInOutSine60 );
401   - mAnimation[mCurrentUniform].Play();
402   - mAnimation[mCurrentUniform].FinishedSignal().Connect(this, &BubbleEffectExample::OnAnimationFinished);
403   -
404   - mCurrentUniform = (mCurrentUniform + 1) % (TOTAL_NUMBER_OF_BUBBLES);
  255 + if(event.state == KeyEvent::Down)
  256 + {
  257 + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
  258 + {
  259 + mApp.Quit();
  260 + }
  261 + }
405 262 }
406 263  
407   - void OnAnimationFinished( Animation& source )
408   - {
409   - mAnimation[mAnimationIndexPair[source]].Reset();
410   - mAnimationIndexPair.erase( source );
411   - }
  264 +private:
412 265  
413   - float RandomRange(float f0, float f1)
414   - {
415   - return f0 + (rand() & 0xfff) * (f1-f0) * (1.0f/4095.0f);
416   - }
  266 + Application& mApp;
  267 + Image mBackgroundImage;
  268 + ImageActor mBackgroundActor;
417 269  
418   - bool OnTouch(Dali::Actor actor, const Dali::TouchEvent& event)
419   - {
420   - if(!mTouchable)
421   - {
422   - return false;
423   - }
  270 + Toolkit::BubbleEmitter mBubbleEmitter;
  271 + Vector3 mHSVDelta;
424 272  
425   - if ( event.GetPointCount() > 0 )
426   - {
427   - const TouchPoint &point = event.GetPoint(0);
428   - float distance = hypotf( point.local.x - mLastTouchPosition.x, point.local.y - mLastTouchPosition.y );
429   - if ( distance > MIN_DISTANCE )
430   - {
431   - // when the finger moves fast, interpolate linearly between two touch points
432   - if(event.time - mLastTouchTime < MAX_TIME_INTERVAL && distance < MAX_DISTANCE)
433   - {
434   - float num = floor(distance / MIN_DISTANCE);
435   - unsigned int numStep = static_cast<unsigned int>( num );
436   - Vector2 step = ( point.screen - mLastTouchPosition ) * MIN_DISTANCE / distance;
437   - for(unsigned int i = 0; i<numStep; i++)
438   - {
439   - SetUpAnimation( mLastTouchPosition + step*i, step );
440   - }
441   - }
442   - else
443   - {
444   - SetUpAnimation( point.screen, point.screen-mLastTouchPosition );
445   - }
  273 + Animation mEmitAnimation;
  274 + unsigned int mAnimateComponentCount;
  275 + bool mNeedNewAnimation;
446 276  
447   - mLastTouchTime = event.time;
448   - mLastTouchPosition = point.screen;
449   - }
450   - }
451   - return true;
452   - }
  277 + Timer mTimerForBubbleEmission;
  278 + unsigned int mNonMovementCount;
  279 + unsigned int mTimerInterval;
453 280  
454   - bool OnImageChageIconClicked( Toolkit::Button button )
455   - {
456   - mCurrentBackgroundImageId = (mCurrentBackgroundImageId + 1 ) % NUM_BACKGROUND_IMAGES;
457   - SetImage( BACKGROUND_IMAGES[ mCurrentBackgroundImageId ] );
458   - return true;
459   - }
  281 + Vector2 mCurrentTouchPosition;
  282 + Vector2 mEmitPosition;
460 283  
461   -private:
462   - Application& mApp;
463   - Actor mRoot;
464   - ImageActor mScreen;
465   - Mesh mMesh[NUMBER_OF_GROUP];
466   - MeshActor mMeshActor[NUMBER_OF_GROUP];
467   - Material mCustomMaterial;
468   - BubbleEffect mEffect[NUMBER_OF_GROUP];
469   - unsigned int mCurrentUniform;
470   - Animation mAnimation[TOTAL_NUMBER_OF_BUBBLES];
471   - bool mTouchable;
472   - std::map<Animation, unsigned int> mAnimationIndexPair;
473   - unsigned long mLastTouchTime;
474   - Vector2 mLastTouchPosition;
475   -
476   - Toolkit::GaussianBlurView mGaussianBlurView;
477   - FrameBufferImage mFrameBufferImage;
478   - Timer mTimer;
479   - bool mRescoucesCleared;
480   -
481   - Layer mContent;
482   - Toolkit::View mView;
483   - unsigned int mCurrentBackgroundImageId;
  284 + Toolkit::PushButton mChangeBackgroundButton;
  285 + Toolkit::PushButton mChangeBubbleShapeButton;
  286 + unsigned int mCurrentBackgroundImageId;
  287 + unsigned int mCurrentBubbleShapeImageId;
484 288 };
485 289  
486 290 /*****************************************************************************/
... ...