Commit f3cb1a11444ddb050d17036b93275eb55f2fca51

Authored by Agnelo Vaz
2 parents 8a802312 6732861a

[dali_1.3.52] Merge branch 'devel/master'

Change-Id: I0ee0d96e977ab7ba39471783eb1c792b23317fb0
demo/dali-demo.cpp
... ... @@ -44,6 +44,8 @@ int DALI_EXPORT_API main(int argc, char **argv)
44 44 demo.AddExample(Example("fpp-game.example", DALI_DEMO_STR_TITLE_FPP_GAME));
45 45 demo.AddExample(Example("item-view.example", DALI_DEMO_STR_TITLE_ITEM_VIEW));
46 46 demo.AddExample(Example("mesh-visual.example", DALI_DEMO_STR_TITLE_MESH_VISUAL));
  47 + demo.AddExample(Example("metaball-explosion.example", DALI_DEMO_STR_TITLE_METABALL_EXPLOSION));
  48 + demo.AddExample(Example("metaball-refrac.example", DALI_DEMO_STR_TITLE_METABALL_REFRAC));
47 49 demo.AddExample(Example("motion-blur.example", DALI_DEMO_STR_TITLE_MOTION_BLUR));
48 50 demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION));
49 51 demo.AddExample(Example("renderer-stencil.example", DALI_DEMO_STR_TITLE_RENDERER_STENCIL));
... ...
examples/image-view-url/image-view-url-example.cpp
... ... @@ -139,7 +139,7 @@ private:
139 139 Pixel::RGB888,
140 140 unsigned(TARGET_SIZE.width),
141 141 unsigned(TARGET_SIZE.height));
142   - auto framebuffer = FrameBuffer::New(TARGET_SIZE.width, TARGET_SIZE.height, Pixel::RGB888);
  142 + auto framebuffer = FrameBuffer::New(TARGET_SIZE.width, TARGET_SIZE.height, FrameBuffer::Attachment::NONE );
143 143 framebuffer.AttachColorTexture(mOutputTexture);
144 144  
145 145 renderTask.SetFrameBuffer(framebuffer);
... ...
examples/layouting/animation-example.cpp
... ... @@ -17,6 +17,7 @@
17 17  
18 18 #include <string>
19 19 #include "animation-example.h"
  20 +#include <dali/devel-api/actors/actor-devel.h>
20 21 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
21 22 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
22 23 #include <dali-toolkit/devel-api/controls/control-devel.h>
... ... @@ -65,15 +66,17 @@ void CreateChild( ImageView&amp; child, int index, Size size )
65 66 {
66 67 child = ImageView::New();
67 68 Property::Map imagePropertyMap;
68   - imagePropertyMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE;
69   - imagePropertyMap[ Toolkit::ImageVisual::Property::URL ] = IMAGE_PATH[ index ];
  69 + imagePropertyMap[ Visual::Property::TYPE ] = Toolkit::Visual::IMAGE;
  70 + imagePropertyMap[ ImageVisual::Property::URL ] = IMAGE_PATH[ index ];
70 71 imagePropertyMap[ ImageVisual::Property::DESIRED_WIDTH ] = size.width;
71 72 imagePropertyMap[ ImageVisual::Property::DESIRED_HEIGHT ] = size.height;
  73 + imagePropertyMap[ ImageVisual::Property::FITTING_MODE ] = FittingMode::SCALE_TO_FILL;
72 74 child.SetProperty( Toolkit::ImageView::Property::IMAGE, imagePropertyMap );
73 75 std::string name = "ImageView";
74 76 name.append( 1, '0' + index );
75 77 child.SetName( name );
76   - child.SetAnchorPoint( AnchorPoint::TOP_LEFT );
  78 + child.SetAnchorPoint( AnchorPoint::CENTER );
  79 + child.SetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT, false );
77 80 }
78 81  
79 82 // Create set layout transition. A parent opacity increases 'ease in out' from semi-transparent to fully opaque and children pulse in order
... ... @@ -93,6 +96,19 @@ LayoutTransitionData CreateOnSetLayoutTransition( Control&amp; container )
93 96 // Apply to parent only
94 97 layoutTransitionData.AddPropertyAnimator( container, map );
95 98  
  99 + // Reset scale after possible focus animation
  100 + {
  101 + Property::Map map;
  102 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE;
  103 + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE;
  104 + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  105 + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
  106 + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
  107 + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f));
  108 + layoutTransitionData.AddPropertyAnimator( Actor(), map );
  109 + }
  110 +
  111 + // Children pulses in/out
96 112 for( size_t i = 0; i < container.GetChildCount(); i++ )
97 113 {
98 114 Property::Map map;
... ... @@ -106,6 +122,18 @@ LayoutTransitionData CreateOnSetLayoutTransition( Control&amp; container )
106 122 layoutTransitionData.AddPropertyAnimator( container.GetChildAt( i ), map );
107 123 }
108 124  
  125 + // Children move
  126 + {
  127 + Property::Map map;
  128 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
  129 + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  130 + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR )
  131 + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
  132 + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
  133 + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) );
  134 + layoutTransitionData.AddPropertyAnimator( Actor(), map );
  135 + }
  136 +
109 137 return layoutTransitionData;
110 138 }
111 139  
... ... @@ -124,13 +152,25 @@ LayoutTransitionData CreateOnChildAddTransition( Control&amp; parent )
124 152 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
125 153 layoutTransitionData.AddPropertyAnimator( parent, map );
126 154  
  155 + // Reset scale after possible focus animation
  156 + {
  157 + Property::Map map;
  158 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE;
  159 + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE;
  160 + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  161 + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
  162 + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
  163 + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
  164 + layoutTransitionData.AddPropertyAnimator( Actor(), map );
  165 + }
  166 +
127 167 // New child is growing
128 168 {
129 169 Property::Map map;
130 170 map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_ADD;
131   - map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
132   - map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = Vector3( 0.0f, 0.0f, 0 );
133   - map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 100.0f, 100.0f, 0 );
  171 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE;
  172 + map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = Vector3::ZERO;
  173 + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE;
134 174 map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
135 175 .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR )
136 176 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
... ... @@ -152,6 +192,18 @@ LayoutTransitionData CreateOnChildAddTransition( Control&amp; parent )
152 192 layoutTransitionData.AddPropertyAnimator( Actor(), map );
153 193 }
154 194  
  195 + // Other just move
  196 + {
  197 + Property::Map map;
  198 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
  199 + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  200 + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR )
  201 + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
  202 + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
  203 + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) );
  204 + layoutTransitionData.AddPropertyAnimator( Actor(), map );
  205 + }
  206 +
155 207 return layoutTransitionData;
156 208 }
157 209  
... ... @@ -160,56 +212,112 @@ LayoutTransitionData CreateOnChildRemoveTransition( Control&amp; container )
160 212 {
161 213 auto layoutTransitionData = LayoutTransitionData::New();
162 214  
163   - // Apply animation to remaining children
164   - Property::Map map;
165   - map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
166   - map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
167   - .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::SIN )
168   - .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
169   - .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
170   - .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
171   - layoutTransitionData.AddPropertyAnimator( Actor(), map );
  215 + // Reset scale after possible focus animation
  216 + {
  217 + Property::Map map;
  218 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE;
  219 + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE;
  220 + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  221 + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
  222 + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
  223 + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f));
  224 + layoutTransitionData.AddPropertyAnimator( Actor(), map );
  225 + }
  226 +
  227 + // Apply animation to remaining children - sin shaking
  228 + {
  229 + Property::Map map;
  230 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
  231 + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  232 + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::SIN )
  233 + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
  234 + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
  235 + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
  236 + layoutTransitionData.AddPropertyAnimator( Actor(), map );
  237 + }
  238 +
  239 + // Add a linear to reduce a linear to half
  240 + {
  241 + Property::Map map;
  242 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
  243 + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  244 + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR )
  245 + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
  246 + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
  247 + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
  248 + layoutTransitionData.AddPropertyAnimator( Actor(), map );
  249 + }
172 250  
173 251 return layoutTransitionData;
174 252 }
175 253  
176   -// Create child focus transition. A focus gained child grows 115% and focus lost child gets its original size back
177   -LayoutTransitionData CreateOnChildFocusTransition( Control& parent )
  254 +// Create child focus transition. A focus gained child grows 120% and focus lost child gets its original size back
  255 +LayoutTransitionData CreateOnChildFocusTransition( Control& parent, bool affectsSiblings )
178 256 {
179 257 auto layoutTransitionData = LayoutTransitionData::New();
180 258  
  259 + // Focus gain child animation
181 260 {
182 261 Property::Map map;
183 262 map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_FOCUS_GAINED;
184   - map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
185   - map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 115.0f, 115.0f, 0 );
  263 + map[ LayoutTransitionData::AnimatorKey::AFFECTS_SIBLINGS ] = affectsSiblings;
  264 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE;
  265 + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 1.2f, 1.2f, 1.0f );
186 266 map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  267 + .Add( LayoutTransitionData::AnimatorKey::TYPE, LayoutTransitionData::Animator::ANIMATE_TO )
187 268 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
188 269 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
189 270 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) );
190 271 layoutTransitionData.AddPropertyAnimator( Actor(), map );
191 272 }
192 273  
  274 + // Focus lost child animation
193 275 {
194 276 Property::Map map;
195 277 map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_FOCUS_LOST;
196   - map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
197   - map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 100.0f, 100.0f, 0 );
  278 + map[ LayoutTransitionData::AnimatorKey::AFFECTS_SIBLINGS ] = affectsSiblings;
  279 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE;
  280 + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 1.0f, 1.0f, 1.0f );
198 281 map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  282 + .Add( LayoutTransitionData::AnimatorKey::TYPE, LayoutTransitionData::Animator::ANIMATE_TO )
199 283 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
200 284 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
201 285 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) );
202 286 layoutTransitionData.AddPropertyAnimator( Actor(), map );
203 287 }
204 288  
  289 + // Linear children positioning
  290 + {
  291 + Property::Map map;
  292 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
  293 + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value();
  294 + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  295 + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
  296 + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
  297 + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) );
  298 + layoutTransitionData.AddPropertyAnimator( Actor(), map );
  299 + }
  300 +
205 301 return layoutTransitionData;
206 302 }
207 303  
208 304 // An example of custom default transition, ease in for position animation, ease out for size animation
209   -LayoutTransitionData CreateCustomDefaultTransition( Control& parent )
  305 +LayoutTransitionData CreateCustomDefaultTransition( Control& control )
210 306 {
211 307 auto layoutTransitionData = LayoutTransitionData::New();
  308 + // Resets control scale after possible focus animation
  309 + {
  310 + Property::Map map;
  311 + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE;
  312 + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE;
  313 + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
  314 + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
  315 + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
  316 + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
  317 + layoutTransitionData.AddPropertyAnimator( control, map );
  318 + }
212 319  
  320 + // Moves control ease in
213 321 {
214 322 Property::Map map;
215 323 map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
... ... @@ -218,9 +326,10 @@ LayoutTransitionData CreateCustomDefaultTransition( Control&amp; parent )
218 326 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
219 327 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
220 328 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) );
221   - layoutTransitionData.AddPropertyAnimator( parent, map );
  329 + layoutTransitionData.AddPropertyAnimator( control, map );
222 330 }
223 331  
  332 + // Sizes control ease out
224 333 {
225 334 Property::Map map;
226 335 map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
... ... @@ -229,7 +338,7 @@ LayoutTransitionData CreateCustomDefaultTransition( Control&amp; parent )
229 338 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
230 339 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
231 340 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) );
232   - layoutTransitionData.AddPropertyAnimator( parent, map );
  341 + layoutTransitionData.AddPropertyAnimator( control, map );
233 342 }
234 343  
235 344 return layoutTransitionData;
... ... @@ -318,16 +427,16 @@ void AnimationExample::Create()
318 427 mHorizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
319 428 mHorizontalLayout.SetAlignment( LinearLayout::Alignment::CENTER_HORIZONTAL | LinearLayout::Alignment::CENTER_VERTICAL );
320 429 mHorizontalLayout.SetAnimateLayout(true);
321   - mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer ) );
  430 + mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer, true ) );
322 431 mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE, CreateOnChildRemoveTransition( mAnimationContainer ) );
323 432 mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, CreateOnChildAddTransition( mAnimationContainer ) );
324 433  
325 434 DevelControl::SetLayout( mAnimationContainer, mHorizontalLayout );
326 435  
327 436 mGridLayout = Grid::New();
328   - mGridLayout.SetAnimateLayout(true);
329   - mGridLayout.SetNumberOfColumns(2);
330   - mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer ) );
  437 + mGridLayout.SetAnimateLayout( true );
  438 + mGridLayout.SetNumberOfColumns( 2 );
  439 + mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer, false ) );
331 440 mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE, CreateOnChildRemoveTransition( mAnimationContainer ) );
332 441 mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, CreateOnChildAddTransition( mAnimationContainer ) );
333 442  
... ... @@ -335,8 +444,7 @@ void AnimationExample::Create()
335 444 stage.Add( mAnimationContainer );
336 445 }
337 446  
338   -// Remove controls added by this example from stage mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer ) );
339   -
  447 +// Remove controls added by this example from stage
340 448 void AnimationExample::Remove()
341 449 {
342 450 if ( mAnimationContainer )
... ...
examples/metaball-explosion/metaball-explosion-example.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + *
  16 + */
  17 +
  18 +// EXTERNAL INCLUDES
  19 +#include <cstdio>
  20 +#include <string>
  21 +#include <cstdint> // uint32_t, uint16_t etc
  22 +
  23 +#include <dali/public-api/rendering/renderer.h>
  24 +#include <dali/public-api/rendering/texture.h>
  25 +#include <dali/public-api/rendering/texture-set.h>
  26 +#include <dali/public-api/rendering/frame-buffer.h>
  27 +#include <dali/public-api/math/random.h>
  28 +
  29 +// INTERNAL INCLUDES
  30 +#include "shared/utility.h" // DemoHelper::LoadTexture
  31 +
  32 +using namespace Dali;
  33 +
  34 +namespace // unnamed namespace for constants
  35 +{
  36 +// background image
  37 +const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-2.jpg" );
  38 +
  39 +// number of metaballs
  40 +constexpr uint32_t METABALL_NUMBER = 6;
  41 +
  42 +/**
  43 + * Vertex shader code for metaball
  44 + */
  45 +const char* const METABALL_VERTEX_SHADER = DALI_COMPOSE_SHADER (
  46 + attribute mediump vec2 aPosition;\n
  47 + attribute mediump vec2 aTexture;\n
  48 + uniform mediump mat4 uMvpMatrix;\n
  49 + uniform mediump vec3 uSize;\n
  50 + uniform lowp vec4 uColor;\n
  51 + varying mediump vec2 vTexCoord;\n
  52 +
  53 + void main()\n
  54 + {\n
  55 + vTexCoord = aTexture;\n
  56 + mediump vec4 vertexPosition = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n
  57 + gl_Position = uMvpMatrix * vertexPosition;\n
  58 + }\n
  59 +);
  60 +
  61 +/**
  62 + * Fragment shader code for metaball
  63 + */
  64 +const char* const METABALL_FRAG_SHADER = DALI_COMPOSE_SHADER (
  65 + precision mediump float;\n
  66 + varying vec2 vTexCoord;\n
  67 + uniform vec2 uPositionMetaball;\n
  68 + uniform vec2 uPositionVar;\n
  69 + uniform vec2 uGravityVector;\n
  70 + uniform float uRadius;\n
  71 + uniform float uRadiusVar;\n
  72 + void main()\n
  73 + {\n
  74 + vec2 adjustedCoords = vTexCoord * 2.0 - 1.0;\n
  75 + vec2 finalMetaballPosition = uPositionMetaball + uGravityVector + uPositionVar;\n
  76 + \n
  77 + float finalRadius = uRadius + uRadiusVar;\n
  78 + vec2 distanceVec = adjustedCoords - finalMetaballPosition;\n
  79 + float result = dot(distanceVec, distanceVec);\n
  80 + float color = inversesqrt(result) * finalRadius;\n
  81 + \n
  82 + gl_FragColor = vec4(color,color,color,1.0);\n
  83 + }\n
  84 +);
  85 +
  86 +/**
  87 + * Fragment shader code for metaball and background composition with refraction effect
  88 + */
  89 +const char* const REFRACTION_FRAG_SHADER = DALI_COMPOSE_SHADER (
  90 + precision highp float;\n
  91 + varying vec2 vTexCoord;\n
  92 + uniform sampler2D sTexture;\n
  93 + uniform sampler2D sEffect;\n
  94 + uniform vec2 uPositionMetaball;\n
  95 + void main()\n
  96 + {\n
  97 + vec2 zoomCoords;\n
  98 + vec3 normal = vec3(0.0,0.0,1.0);\n
  99 + vec2 fakePos = vec2(0.0,0.0);\n
  100 + vec3 color = vec3(1.0, 1.0, 1.0);
  101 + float ambient = 0.2;
  102 + \n
  103 + vec4 metaColor = texture2D(sEffect, vTexCoord);\n
  104 + \n
  105 + vec2 adjustedCoords = vTexCoord.xy * vec2(2.0) - vec2(1.0);\n
  106 + fakePos = adjustedCoords.xy - vec2(uPositionMetaball.x, -uPositionMetaball.y);
  107 + float len = length(fakePos) + 0.01;\n
  108 + vec3 colorPos = vec3(0,0,1);
  109 + \n
  110 + if (metaColor.r > 0.85)\n
  111 + {\n
  112 + zoomCoords = ((vTexCoord - 0.5) * 0.9);\n
  113 + zoomCoords = zoomCoords + 0.5;\n
  114 + \n
  115 + float interpNormal = mix(0.7, 1.0, (metaColor.r - 0.85) * 4.);\n
  116 + normal.xyz = vec3(fakePos.x * (1.0 - interpNormal) / len, fakePos.y * (1.0 - interpNormal) / len, interpNormal);\n
  117 + normal.xyz = normalize(normal.xyz);\n
  118 + color = vec3(0.65, 1.0, 0);\n
  119 + colorPos = vec3(fakePos.x,fakePos.y,0);
  120 + }\n
  121 + else if (metaColor.r > 0.75)\n
  122 + {\n
  123 + float interpolation = mix(0.9, 1.15, (0.85 - metaColor.r) * 10.0);\n
  124 + zoomCoords = ((vTexCoord - 0.5) * interpolation);\n
  125 + zoomCoords = zoomCoords + 0.5;\n
  126 + \n
  127 + float interpNormal = mix(0.7, 0.0, (0.85 - metaColor.r) * 10.0);\n
  128 + normal.xyz = vec3(fakePos.x * (1.0 - interpNormal) / len, fakePos.y * (1.0 - interpNormal) / len, interpNormal);\n
  129 + normal.xyz = normalize(normal.xyz);\n
  130 + color = vec3(0.65, 1.0, 0);\n
  131 + colorPos = vec3(fakePos.x,fakePos.y,0);
  132 + }\n
  133 + else\n
  134 + {\n
  135 + zoomCoords = vTexCoord;\n
  136 + normal = vec3(0,0,0);\n
  137 + ambient = 0.5;\n
  138 + }\n
  139 + \n
  140 + vec3 lightPosition = vec3(-750.0,-1000.0,2000.0);\n
  141 + vec3 vertex = vec3(adjustedCoords.x,adjustedCoords.y,0.0);\n
  142 + \n
  143 + vec3 vecToLight = normalize( lightPosition - vertex );\n
  144 + \n
  145 + float lightDiffuse = dot( vecToLight, normal );\n
  146 + lightDiffuse = max(0.0,lightDiffuse);\n
  147 + lightDiffuse = lightDiffuse * 0.5 + 0.5;
  148 + \n
  149 + vec3 vertexToEye = vec3(0,0,1) - vertex;\n
  150 + vertexToEye = normalize(vertexToEye);
  151 + vec3 lightReflect = normalize(reflect(-vecToLight, normal));\n
  152 + float specularFactor = max(0.0,dot(vertexToEye, lightReflect));\n
  153 + specularFactor = pow(specularFactor, 32.0) * 0.7;
  154 + \n
  155 + vec4 texColor = texture2D(sTexture, zoomCoords);\n
  156 + gl_FragColor.rgb = texColor.rgb * ambient + color.rgb * texColor.rgb * lightDiffuse + vec3(specularFactor);\n
  157 + gl_FragColor.a = 1.0;
  158 + }\n
  159 + );
  160 +
  161 +/**
  162 + * Metadata for each ball
  163 + */
  164 +struct MetaballInfo
  165 +{
  166 + Actor actor;
  167 + Vector2 position;
  168 + float radius;
  169 + float initRadius;
  170 +
  171 + //new shader stuff
  172 + Property::Index positionIndex;
  173 + Property::Index positionVarIndex;
  174 +};
  175 +
  176 +} // unnamed namespace
  177 +
  178 +/**
  179 + * Demo using Metaballs
  180 + *
  181 + * When the metaball is clicked it explodes to smaller balls
  182 + */
  183 +class MetaballExplosionController : public ConnectionTracker
  184 +{
  185 +public:
  186 +
  187 + /**
  188 + * Constructor
  189 + * @param application
  190 + */
  191 + MetaballExplosionController( Application& application );
  192 +
  193 + /**
  194 + * Destructor
  195 + */
  196 + virtual ~MetaballExplosionController();
  197 +
  198 + /**
  199 + * Creates the metaballs and initializes the scene
  200 + */
  201 + void Create( Application& app );
  202 +
  203 + /**
  204 + * Touch event handler to center metaballs at touch position
  205 + * and start explosion animation on release
  206 + */
  207 + bool OnTouch( Actor actor, const TouchData& touch );
  208 +
  209 + /**
  210 + * Key event handler to quit application on escape or back key
  211 + */
  212 + void OnKeyEvent(const KeyEvent& event);
  213 +
  214 +private: // Data
  215 +
  216 + Application& mApplication;
  217 + Vector2 mScreenSize;
  218 +
  219 + Texture mBackgroundTexture;
  220 + FrameBuffer mMetaballFBO;
  221 + Texture mMetaballFBOTexture;
  222 +
  223 + Actor mMetaballRoot;
  224 + MetaballInfo mMetaballs[METABALL_NUMBER];
  225 +
  226 + Property::Index mPositionIndex;
  227 + Actor mCompositionActor;
  228 +
  229 + //Motion
  230 + Vector2 mCurrentTouchPosition;
  231 + Vector2 mMetaballPosVariation;
  232 + Vector2 mMetaballPosVariationFrom;
  233 + Vector2 mMetaballPosVariationTo;
  234 + Vector2 mMetaballCenter;
  235 +
  236 + //Animations
  237 + Animation mPositionVarAnimation[METABALL_NUMBER];
  238 +
  239 + uint32_t mDispersion;
  240 + Animation mDispersionAnimation[METABALL_NUMBER];
  241 +
  242 + Timer mTimerDispersion;
  243 +
  244 + float mTimeMultiplier;
  245 +
  246 + // Private helper functions
  247 +
  248 + /**
  249 + * Create a mesh data with the geometry for the metaball rendering
  250 + * @param aspectMappedTexture whether texture coords should be mapped based on aspect ratio
  251 + */
  252 + Geometry CreateGeometry( bool aspectMappedTexture = true );
  253 +
  254 + /**
  255 + * Create a actors and renderers for the metaballs
  256 + */
  257 + void CreateMetaballActors();
  258 +
  259 + /**
  260 + * Create the render task and FBO to render the metaballs into a texture
  261 + */
  262 + void CreateMetaballImage();
  263 +
  264 + /**
  265 + * Create the the final composition
  266 + */
  267 + void CreateComposition();
  268 +
  269 + /**
  270 + * Function to create animations for the small variations of position inside the metaball
  271 + */
  272 + void CreateAnimations();
  273 +
  274 + /**
  275 + * Function to reset metaball state
  276 + */
  277 + void ResetMetaballs( bool resetAnims );
  278 +
  279 + /**
  280 + * Function to create disperse each of the ball that compose the metaball when exploding
  281 + */
  282 + void DisperseBallAnimation( uint32_t ball );
  283 +
  284 + /**
  285 + * Function to make metaballs come back to reset position
  286 + */
  287 + void LaunchResetMetaballPosition( Animation& source );
  288 +
  289 + /**
  290 + * Function to set things at the end of the animation
  291 + */
  292 + void EndDisperseAnimation( Animation& source );
  293 +
  294 + /**
  295 + * Function to init dispersion of the metaballs one by one using a timer
  296 + * (so not all the balls begin moving at the same time)
  297 + */
  298 + bool OnTimerDispersionTick();
  299 +
  300 + /**
  301 + * Function to set the actual position of the metaballs when the user clicks the screen
  302 + */
  303 + void SetPositionToMetaballs( const Vector2& metaballCenter );
  304 +};
  305 +
  306 +/**
  307 + * Implementation
  308 + */
  309 +
  310 +MetaballExplosionController::MetaballExplosionController( Application& application )
  311 +: mApplication( application ),
  312 + mScreenSize(),
  313 + mBackgroundTexture(),
  314 + mMetaballFBO(),
  315 + mMetaballFBOTexture(),
  316 + mMetaballRoot(),
  317 + mMetaballs(),
  318 + mPositionIndex(),
  319 + mCompositionActor(),
  320 + mCurrentTouchPosition(),
  321 + mMetaballPosVariation(),
  322 + mMetaballPosVariationFrom(),
  323 + mMetaballPosVariationTo(),
  324 + mMetaballCenter(),
  325 + mPositionVarAnimation(),
  326 + mDispersion( 0 ),
  327 + mDispersionAnimation(),
  328 + mTimerDispersion(),
  329 + mTimeMultiplier( 1.0f )
  330 +{
  331 + // Connect to the Application's Init signal
  332 + mApplication.InitSignal().Connect( this, &MetaballExplosionController::Create );
  333 +}
  334 +
  335 +MetaballExplosionController::~MetaballExplosionController()
  336 +{
  337 + // Nothing to do here;
  338 +}
  339 +
  340 +void MetaballExplosionController::Create( Application& app )
  341 +{
  342 + Stage stage = Stage::GetCurrent();
  343 +
  344 + stage.KeyEventSignal().Connect( this, &MetaballExplosionController::OnKeyEvent );
  345 +
  346 + mScreenSize = stage.GetSize();
  347 +
  348 + mTimeMultiplier = 1.0f;
  349 +
  350 + stage.SetBackgroundColor(Color::BLACK);
  351 +
  352 + // Load background texture
  353 + mBackgroundTexture = DemoHelper::LoadTexture( BACKGROUND_IMAGE );
  354 +
  355 + srand( static_cast<uint32_t>( time(0) ) );
  356 +
  357 + //Create internal data
  358 + CreateMetaballActors();
  359 + CreateMetaballImage();
  360 + CreateComposition();
  361 +
  362 + CreateAnimations();
  363 +
  364 + mDispersion = 0;
  365 + mTimerDispersion = Timer::New( 150 );
  366 + mTimerDispersion.TickSignal().Connect( this, &MetaballExplosionController::OnTimerDispersionTick );
  367 +
  368 + // Connect the callback to the touch signal on the mesh actor
  369 + stage.GetRootLayer().TouchSignal().Connect( this, &MetaballExplosionController::OnTouch );
  370 +}
  371 +
  372 +Geometry MetaballExplosionController::CreateGeometry( bool aspectMappedTexture )
  373 +{
  374 + const float aspect = mScreenSize.y / mScreenSize.x;
  375 +
  376 + // Create vertices and specify their color
  377 + const float xsize = mScreenSize.x * 0.5;
  378 +
  379 + // Create the meshdata for the metaballs
  380 + struct VertexPosition { Vector2 position; };
  381 + struct VertexTexture { Vector2 texture; };
  382 +
  383 + VertexPosition vertices[] =
  384 + {
  385 + { Vector2( -xsize, -xsize * aspect ) },
  386 + { Vector2( xsize, -xsize * aspect ) },
  387 + { Vector2( -xsize, xsize * aspect ) },
  388 + { Vector2( xsize, xsize * aspect ) }
  389 + };
  390 +
  391 + const float textureAspect = (aspectMappedTexture) ? aspect : 1.0f;
  392 + VertexTexture textures[] =
  393 + {
  394 + { Vector2( 0.0f, 0.0f ) },
  395 + { Vector2( 1.0f, 0.0f ) },
  396 + { Vector2( 0.0f, 1.0f * textureAspect ) },
  397 + { Vector2( 1.0f, 1.0f * textureAspect ) }
  398 + };
  399 +
  400 + uint32_t numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
  401 +
  402 + // Vertices
  403 + Property::Map positionVertexFormat;
  404 + positionVertexFormat["aPosition"] = Property::VECTOR2;
  405 + PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat );
  406 + positionVertices.SetData( vertices, numberOfVertices );
  407 +
  408 + // Textures
  409 + Property::Map textureVertexFormat;
  410 + textureVertexFormat["aTexture"] = Property::VECTOR2;
  411 + PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat );
  412 + textureVertices.SetData( textures, numberOfVertices );
  413 +
  414 + // Indices
  415 + const uint16_t indices[] = { 0, 3, 1, 0, 2, 3 };
  416 +
  417 + // Create the geometry object
  418 + Geometry texturedQuadGeometry = Geometry::New();
  419 + texturedQuadGeometry.AddVertexBuffer( positionVertices );
  420 + texturedQuadGeometry.AddVertexBuffer( textureVertices );
  421 +
  422 + texturedQuadGeometry.SetIndexBuffer ( &indices[0], sizeof( indices )/ sizeof( indices[0] ) );
  423 +
  424 + return texturedQuadGeometry;
  425 +}
  426 +
  427 +void MetaballExplosionController::CreateMetaballActors()
  428 +{
  429 + // Create the shader for the metaballs, tell DALi that shader modifies geometry so we dont need to set a meaningless size
  430 + Shader shader = Shader::New( METABALL_VERTEX_SHADER, METABALL_FRAG_SHADER, Shader::Hint::MODIFIES_GEOMETRY );
  431 +
  432 + Geometry metaballGeom = CreateGeometry();
  433 + // Reuse same renderer for each actor
  434 + Renderer renderer = Renderer::New( metaballGeom, shader );
  435 + renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
  436 + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE );
  437 + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE );
  438 + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE );
  439 + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE );
  440 +
  441 + //Initialization of each of the metaballs
  442 + for( uint32_t i = 0; i < METABALL_NUMBER; i++ )
  443 + {
  444 + mMetaballs[i].position = Vector2(0.0f, 0.0f);
  445 + mMetaballs[i].radius = mMetaballs[i].initRadius = Random::Range(0.05f,0.07f);
  446 +
  447 + mMetaballs[i].actor = Actor::New( );
  448 + mMetaballs[i].actor.SetName( "Metaball" );
  449 + mMetaballs[i].actor.SetScale( 1.0f );
  450 + mMetaballs[i].actor.SetParentOrigin( ParentOrigin::CENTER );
  451 + mMetaballs[i].actor.AddRenderer( renderer );
  452 +
  453 + mMetaballs[i].positionIndex = mMetaballs[i].actor.RegisterProperty( "uPositionMetaball", mMetaballs[i].position );
  454 +
  455 + mMetaballs[i].positionVarIndex = mMetaballs[i].actor.RegisterProperty( "uPositionVar", Vector2(0.f,0.f) );
  456 +
  457 + mMetaballs[i].actor.RegisterProperty( "uGravityVector", Vector2(Random::Range(-0.2,0.2),Random::Range(-0.2,0.2)) );
  458 + mMetaballs[i].actor.RegisterProperty( "uRadius", mMetaballs[i].radius );
  459 + mMetaballs[i].actor.RegisterProperty( "uRadiusVar", 0.f );
  460 + }
  461 +
  462 + // Root creation
  463 + mMetaballRoot = Actor::New();
  464 + mMetaballRoot.SetParentOrigin( ParentOrigin::CENTER );
  465 + for( uint32_t i = 0; i < METABALL_NUMBER; i++ )
  466 + {
  467 + mMetaballRoot.Add( mMetaballs[i].actor );
  468 + }
  469 +
  470 +}
  471 +
  472 +void MetaballExplosionController::CreateMetaballImage()
  473 +{
  474 + // Create an FBO and a render task to create to render the metaballs with a fragment shader
  475 + Stage stage = Stage::GetCurrent();
  476 +
  477 + mMetaballFBO = FrameBuffer::New( mScreenSize.x, mScreenSize.y, FrameBuffer::Attachment::NONE );
  478 + mMetaballFBOTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
  479 + Pixel::RGB888,
  480 + mScreenSize.x, mScreenSize.y );
  481 + mMetaballFBO.AttachColorTexture( mMetaballFBOTexture );
  482 +
  483 + stage.Add(mMetaballRoot);
  484 +
  485 + // Create the render task used to render the metaballs
  486 + RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
  487 + RenderTask task = taskList.CreateTask();
  488 + task.SetRefreshRate( RenderTask::REFRESH_ALWAYS );
  489 + task.SetSourceActor( mMetaballRoot );
  490 + task.SetExclusive( true );
  491 + task.SetClearColor( Color::BLACK );
  492 + task.SetClearEnabled( true );
  493 + task.SetFrameBuffer( mMetaballFBO );
  494 +}
  495 +
  496 +void MetaballExplosionController::CreateComposition()
  497 +{
  498 + //Create new shader
  499 + Shader shader = Shader::New( METABALL_VERTEX_SHADER, REFRACTION_FRAG_SHADER );
  500 +
  501 + // Create new texture set
  502 + auto textureSet = TextureSet::New();
  503 + textureSet.SetTexture( 0u, mBackgroundTexture );
  504 + textureSet.SetTexture( 1u, mMetaballFBOTexture );
  505 +
  506 + // Create geometry
  507 + Geometry metaballGeom = CreateGeometry( false );
  508 +
  509 + Renderer mRenderer = Renderer::New( metaballGeom, shader );
  510 + mRenderer.SetTextures( textureSet );
  511 +
  512 + // Create actor
  513 + mCompositionActor = Actor::New( );
  514 + mCompositionActor.SetParentOrigin(ParentOrigin::CENTER);
  515 + mCompositionActor.SetPosition(Vector3(0.0f, 0.0f, 0.0f));
  516 + mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y);
  517 + mCompositionActor.AddRenderer( mRenderer );
  518 +
  519 + Vector2 metaballCenter(0.0,0);
  520 + metaballCenter.x = metaballCenter.x * 0.5;
  521 + metaballCenter.y = metaballCenter.y * 0.5;
  522 + mPositionIndex = mCompositionActor.RegisterProperty( "uPositionMetaball", metaballCenter );
  523 +
  524 + SetPositionToMetaballs( metaballCenter );
  525 +
  526 + mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y);
  527 +
  528 + Stage stage = Stage::GetCurrent();
  529 + stage.Add( mCompositionActor );
  530 +}
  531 +
  532 +void MetaballExplosionController::CreateAnimations()
  533 +{
  534 + Vector2 direction;
  535 +
  536 + for( uint32_t i = 0; i < METABALL_NUMBER; i++ )
  537 + {
  538 + KeyFrames keySinCosVariation = KeyFrames::New();
  539 + Vector2 sinCosVariation( 0,0 );
  540 +
  541 + direction.x = Random::Range( -100.f,100.f );
  542 + direction.y = Random::Range( -100.f,100.f );
  543 +
  544 + direction.Normalize();
  545 + direction *= 0.1f;
  546 +
  547 + for( uint32_t j = 0; j < 360; j++ )
  548 + {
  549 + sinCosVariation.x = sinf( j * Math::PI/180.f ) * direction.x;
  550 + sinCosVariation.y = cosf( j * Math::PI/180.f ) * direction.y;
  551 + float key = j/360.f;
  552 + keySinCosVariation.Add( key, sinCosVariation );
  553 + }
  554 +
  555 + mPositionVarAnimation[i] = Animation::New( 3.f );
  556 + mPositionVarAnimation[i].AnimateBetween( Property( mMetaballs[i].actor, mMetaballs[i].positionVarIndex ), keySinCosVariation );
  557 + mPositionVarAnimation[i].SetLooping( true );
  558 + mPositionVarAnimation[i].Play();
  559 + }
  560 +}
  561 +
  562 +void MetaballExplosionController::ResetMetaballs( bool resetAnims )
  563 +{
  564 + for( uint32_t i = 0; i < METABALL_NUMBER; i++ )
  565 + {
  566 + if( mDispersionAnimation[i] )
  567 + {
  568 + mDispersionAnimation[i].Clear();
  569 + }
  570 +
  571 + mMetaballs[i].position = Vector2( 0.0f, 0.0f );
  572 + mMetaballs[i].actor.SetProperty( mMetaballs[i].positionIndex, mMetaballs[i].position );
  573 + }
  574 + mTimerDispersion.Stop();
  575 + mDispersion = 0;
  576 +
  577 + mCompositionActor.SetProperty( mPositionIndex, Vector2(0,0) );
  578 +}
  579 +
  580 +void MetaballExplosionController::DisperseBallAnimation( uint32_t ball )
  581 +{
  582 + Vector2 position;
  583 + position.x = Random::Range(-1.5f,1.5f);
  584 + position.y = Random::Range(-1.5f,1.5f);
  585 +
  586 + mDispersionAnimation[ball] = Animation::New(2.0f * mTimeMultiplier);
  587 + mDispersionAnimation[ball].AnimateTo( Property(mMetaballs[ball].actor, mMetaballs[ball].positionIndex), position);
  588 + mDispersionAnimation[ball].Play();
  589 +
  590 + if( ball == METABALL_NUMBER - 1 )
  591 + {
  592 + mDispersionAnimation[ball].FinishedSignal().Connect( this, &MetaballExplosionController::LaunchResetMetaballPosition );
  593 + }
  594 +}
  595 +
  596 +void MetaballExplosionController::LaunchResetMetaballPosition( Animation& source )
  597 +{
  598 + for( uint32_t i = 0; i < METABALL_NUMBER; i++ )
  599 + {
  600 + mDispersionAnimation[i] = Animation::New( 1.5f + i * 0.25f * mTimeMultiplier );
  601 + mDispersionAnimation[i].AnimateTo(Property( mMetaballs[i].actor, mMetaballs[i].positionIndex), Vector2(0,0) );
  602 + mDispersionAnimation[i].Play();
  603 +
  604 + if( i == METABALL_NUMBER - 1 )
  605 + {
  606 + mDispersionAnimation[i].FinishedSignal().Connect( this, &MetaballExplosionController::EndDisperseAnimation );
  607 + }
  608 + }
  609 +}
  610 +
  611 +void MetaballExplosionController::EndDisperseAnimation( Animation& source )
  612 +{
  613 + mCompositionActor.SetProperty( mPositionIndex, Vector2(0,0) );
  614 +}
  615 +
  616 +bool MetaballExplosionController::OnTimerDispersionTick()
  617 +{
  618 + if( mDispersion < METABALL_NUMBER )
  619 + {
  620 + DisperseBallAnimation( mDispersion );
  621 + mDispersion++;
  622 + }
  623 + return true;
  624 +}
  625 +
  626 +void MetaballExplosionController::SetPositionToMetaballs( const Vector2& metaballCenter )
  627 +{
  628 + //We set the position for the metaballs based on click position
  629 + for( uint32_t i = 0; i < METABALL_NUMBER; i++ )
  630 + {
  631 + mMetaballs[i].position = metaballCenter;
  632 + mMetaballs[i].actor.SetProperty( mMetaballs[i].positionIndex, mMetaballs[i].position );
  633 + }
  634 +
  635 + mCompositionActor.SetProperty( mPositionIndex, metaballCenter );
  636 +}
  637 +
  638 +bool MetaballExplosionController::OnTouch( Actor actor, const TouchData& touch )
  639 +{
  640 + float aspectR = mScreenSize.y / mScreenSize.x;
  641 +
  642 + switch( touch.GetState( 0 ) )
  643 + {
  644 + case PointState::DOWN:
  645 + {
  646 + ResetMetaballs(true);
  647 +
  648 + const Vector2 screen = touch.GetScreenPosition( 0 );
  649 + Vector2 metaballCenter = Vector2( (screen.x / mScreenSize.x) - 0.5f, (aspectR * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5f ) * 2.0f;
  650 + SetPositionToMetaballs(metaballCenter);
  651 +
  652 + break;
  653 + }
  654 + case PointState::MOTION:
  655 + {
  656 + const Vector2 screen = touch.GetScreenPosition( 0 );
  657 + Vector2 metaballCenter = Vector2( (screen.x / mScreenSize.x) - 0.5f, (aspectR * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5f ) * 2.0f;
  658 + SetPositionToMetaballs(metaballCenter);
  659 + break;
  660 + }
  661 + case PointState::UP:
  662 + case PointState::LEAVE:
  663 + case PointState::INTERRUPTED:
  664 + {
  665 + mTimerDispersion.Start();
  666 + break;
  667 + }
  668 + default:
  669 + break;
  670 + }
  671 + return true;
  672 +}
  673 +
  674 +void MetaballExplosionController::OnKeyEvent(const KeyEvent& event)
  675 +{
  676 + if(event.state == KeyEvent::Down)
  677 + {
  678 + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
  679 + {
  680 + mApplication.Quit();
  681 + }
  682 + }
  683 +}
  684 +
  685 +/**
  686 + * Main entry point
  687 + */
  688 +int32_t DALI_EXPORT_API main( int argc, char **argv )
  689 +{
  690 + Application application = Application::New( &argc, &argv );
  691 +
  692 + MetaballExplosionController test( application );
  693 +
  694 + application.MainLoop();
  695 +
  696 + return 0;
  697 +}
... ...
examples/metaball-refrac/metaball-refrac-example.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + *
  16 + */
  17 +
  18 +// EXTERNAL INCLUDES
  19 +#include <cstdio>
  20 +#include <string>
  21 +#include <cstdint> // uint32_t, uint16_t etc
  22 +
  23 +#include <dali/public-api/rendering/renderer.h>
  24 +#include <dali/public-api/rendering/texture.h>
  25 +#include <dali/public-api/rendering/texture-set.h>
  26 +#include <dali/public-api/rendering/frame-buffer.h>
  27 +
  28 +// INTERNAL INCLUDES
  29 +#include "shared/utility.h" // DemoHelper::LoadTexture
  30 +
  31 +using namespace Dali;
  32 +
  33 +namespace // unnamed namespace for constants
  34 +{
  35 +const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-2.jpg" );
  36 +const float GRAVITY_X(0);
  37 +const float GRAVITY_Y(-0.09);
  38 +
  39 +// number of metaballs
  40 +constexpr uint32_t METABALL_NUMBER = 6;
  41 +
  42 +/**
  43 + * Vertex shader for metaballs
  44 + */
  45 +const char* const METABALL_VERTEX_SHADER = DALI_COMPOSE_SHADER (
  46 + attribute mediump vec2 aPosition;\n
  47 + attribute mediump vec2 aTexture;\n
  48 + uniform mediump mat4 uMvpMatrix;\n
  49 + uniform mediump vec3 uSize;\n
  50 + uniform lowp vec4 uColor;\n
  51 + varying mediump vec2 vTexCoord;\n
  52 +
  53 + void main()\n
  54 + {\n
  55 + mediump vec4 vertexPosition = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n
  56 + vertexPosition = uMvpMatrix * vertexPosition;\n
  57 + gl_Position = vertexPosition;\n
  58 + vTexCoord = aTexture;\n
  59 + }\n
  60 +);
  61 +
  62 +/**
  63 + * Fragment shader for metaballs
  64 + */
  65 +const char* const METABALL_FRAG_SHADER = DALI_COMPOSE_SHADER (
  66 + precision mediump float;\n
  67 + varying vec2 vTexCoord;\n
  68 + uniform vec2 uPositionMetaball;\n
  69 + uniform vec2 uPositionVar;\n
  70 + uniform vec2 uGravityVector;\n
  71 + uniform float uRadius;\n
  72 + uniform float uRadiusVar;\n
  73 + uniform float uAspect;\n
  74 + void main()\n
  75 + {\n
  76 + vec2 adjustedCoords = vTexCoord * 2.0 - 1.0;\n
  77 + vec2 finalMetaballPosition = uPositionMetaball + uGravityVector + uPositionVar;\n
  78 +
  79 + float distance = (adjustedCoords.x - finalMetaballPosition.x) * (adjustedCoords.x - finalMetaballPosition.x) +
  80 + (adjustedCoords.y - finalMetaballPosition.y) * (adjustedCoords.y - finalMetaballPosition.y);\n
  81 + float finalRadius = uRadius + uRadiusVar;\n
  82 + float color = finalRadius / sqrt( distance );\n
  83 + vec2 bordercolor = vec2(0.0,0.0);\n
  84 + if (vTexCoord.x < 0.1)\n
  85 + {\n
  86 + bordercolor.x = (0.1 - vTexCoord.x) * 0.8;\n
  87 + }\n
  88 + if (vTexCoord.x > 0.9)\n
  89 + {\n
  90 + bordercolor.x = (vTexCoord.x - 0.9) * 0.8;\n
  91 + }\n
  92 + if (vTexCoord.y < 0.1)\n
  93 + {\n
  94 + bordercolor.y = (0.1 - vTexCoord.y) * 0.8;\n
  95 + }\n
  96 + if (vTexCoord.y > (0.9 * uAspect))\n
  97 + {\n
  98 + bordercolor.y = (vTexCoord.y - (0.9 * uAspect)) * 0.8;\n
  99 + }\n
  100 + float border = (bordercolor.x + bordercolor.y) * 0.5;\n
  101 + gl_FragColor = vec4(color + border,color + border,color + border,1.0);\n
  102 + }\n
  103 +);
  104 +
  105 +/**
  106 + * Fragment shader code for metaball and background composition with refraction effect
  107 + */
  108 +const char* const REFRACTION_FRAG_SHADER = DALI_COMPOSE_SHADER (
  109 + precision mediump float;\n
  110 + varying vec2 vTexCoord;\n
  111 + uniform sampler2D sTexture;\n
  112 + uniform sampler2D sEffect;\n
  113 + void main()\n
  114 + {\n
  115 + vec4 metaColor = texture2D(sEffect, vTexCoord);\n
  116 + vec2 zoomCoords;\n
  117 + float bright = 1.0;\n
  118 + if (metaColor.r > 0.85)\n
  119 + {\n
  120 + zoomCoords = ((vTexCoord - 0.5) * 0.95) + 0.5;\n
  121 + }\n
  122 + else if (metaColor.r > 0.78)\n
  123 + {\n
  124 + float interpolation = mix(0.95, 1.05, (0.85 - metaColor.r) * 50.0);\n
  125 + zoomCoords = ((vTexCoord - 0.5) * interpolation) + 0.5;\n
  126 + bright = 1.2;\n
  127 + }\n
  128 + else\n
  129 + {\n
  130 + zoomCoords = vTexCoord;\n
  131 + }\n
  132 +
  133 + gl_FragColor = texture2D(sTexture, zoomCoords) * bright;\n
  134 + }\n
  135 + );
  136 +
  137 +/**
  138 + * Fragment shader code when there's no effect
  139 + */
  140 +const char* const FRAG_SHADER = DALI_COMPOSE_SHADER (
  141 + precision mediump float;\n
  142 + varying vec2 vTexCoord;\n
  143 + uniform sampler2D sTexture;\n
  144 + void main()\n
  145 + {\n
  146 + gl_FragColor = texture2D(sTexture, vTexCoord);\n
  147 + }\n
  148 +);
  149 +
  150 +/**
  151 + * Metadata for each ball
  152 + */
  153 +struct MetaballInfo
  154 +{
  155 + Actor actor;
  156 + Vector2 position;
  157 + float radius;
  158 + float initRadius;
  159 +
  160 + //Properties needed for animations
  161 + Property::Index positionIndex;
  162 + Property::Index positionVarIndex;
  163 + Property::Index gravityIndex;
  164 + Property::Index radiusIndex;
  165 + Property::Index radiusVarIndex;
  166 + Property::Index aspectIndex;
  167 +};
  168 +
  169 +} // unnamed namespace
  170 +
  171 +/**
  172 + * Demo using Metaballs
  173 + *
  174 + * When the metaball is clicked it starts to grow and fuses into the closest edge of screen
  175 + */
  176 +class MetaballRefracController : public ConnectionTracker
  177 +{
  178 +public:
  179 +
  180 + /**
  181 + * Constructor
  182 + * @param application
  183 + */
  184 + MetaballRefracController( Application& application );
  185 +
  186 + /**
  187 + * Destructor
  188 + */
  189 + virtual ~MetaballRefracController();
  190 +
  191 + /**
  192 + * Creates the metaballs and initializes the scene
  193 + */
  194 + void Create( Application& app );
  195 +
  196 + /**
  197 + * Touch handler, start the grow animation and creates additional metaballs
  198 + */
  199 + bool OnTouch( Actor actor, const TouchData& touch );
  200 +
  201 + /**
  202 + * Key event callback to quit the application on escape or back key
  203 + */
  204 + void OnKeyEvent( const KeyEvent& event );
  205 +
  206 +private: // Data
  207 +
  208 + Application& mApplication;
  209 + Vector2 mScreenSize;
  210 +
  211 + Texture mBackgroundTexture;
  212 + FrameBuffer mMetaballFBO;
  213 + Texture mMetaballFBOTexture;
  214 +
  215 + Actor mMetaballRoot;
  216 + MetaballInfo mMetaballs[METABALL_NUMBER];
  217 +
  218 + Actor mCompositionActor;
  219 +
  220 + //Motion
  221 + Vector2 mCurrentTouchPosition;
  222 + Vector2 mMetaballPosVariation;
  223 + Vector2 mMetaballPosVariationFrom;
  224 + Vector2 mMetaballPosVariationTo;
  225 + Vector2 mMetaballCenter;
  226 +
  227 + Vector2 mGravity;
  228 + Vector2 mGravityVar;
  229 +
  230 + Renderer mRendererRefraction;
  231 + TextureSet mTextureSetRefraction;
  232 + Shader mShaderRefraction;
  233 + TextureSet mTextureSetNormal;
  234 + Shader mShaderNormal;
  235 +
  236 + // Animations
  237 + Animation mGravityAnimation[METABALL_NUMBER];
  238 + Animation mRadiusDecAnimation[METABALL_NUMBER];
  239 + Animation mRadiusIncFastAnimation[METABALL_NUMBER];
  240 + Animation mRadiusIncSlowAnimation[METABALL_NUMBER];
  241 + Animation mRadiusVarAnimation[METABALL_NUMBER];
  242 + Animation mPositionVarAnimation[METABALL_NUMBER];
  243 +
  244 + // Private Helper functions
  245 +
  246 + /**
  247 + * Create a mesh data with the geometry for the metaball rendering
  248 + * @param aspectMappedTexture whether texture coords should be mapped based on aspect ratio
  249 + */
  250 + Geometry CreateGeometry( bool aspectMappedTexture = true );
  251 +
  252 + /**
  253 + * Create a actor for the metaballs
  254 + */
  255 + void CreateMetaballActors();
  256 +
  257 + /**
  258 + * Create the render task and FBO to render the metaballs into a texture
  259 + */
  260 + void CreateMetaballImage();
  261 +
  262 + /**
  263 + * Create the the final composition
  264 + */
  265 + void CreateComposition();
  266 +
  267 + /**
  268 + * Create all the metaballs animations (gravity, movement, size, etc.)
  269 + */
  270 + void CreateAnimations();
  271 +
  272 + /**
  273 + * Function to launch the grow slow radius for the metaballs, and also the small variations for metaball[2] and [3]
  274 + */
  275 + void LaunchRadiusIncSlowAnimations( Animation& source );
  276 +
  277 + /**
  278 + * Function to launch the animation to get the metaball[1] back to the center
  279 + */
  280 + void LaunchGetBackToPositionAnimation( Animation& source );
  281 +
  282 + /**
  283 + * Function to stop all animations related to the click of the user in the screen
  284 + */
  285 + void StopClickAnimations();
  286 +
  287 + /**
  288 + * Function to stop all animations related to the after click of the user in the screen
  289 + */
  290 + void StopAfterClickAnimations();
  291 +
  292 + /**
  293 + * Function that resets the sate of the different Metaballs
  294 + */
  295 + void ResetMetaballsState();
  296 +
  297 + /**
  298 + * Function to set the actual position of the metaballs when the user clicks the screen
  299 + */
  300 + void SetPositionToMetaballs( const Vector2& metaballCenter );
  301 +
  302 +};
  303 +
  304 +/**
  305 + * Implementation
  306 + */
  307 +
  308 +MetaballRefracController::MetaballRefracController( Application& application )
  309 + : mApplication( application )
  310 +{
  311 + // Connect to the Application's Init signal
  312 + mApplication.InitSignal().Connect( this, &MetaballRefracController::Create );
  313 +}
  314 +
  315 +MetaballRefracController::~MetaballRefracController()
  316 +{
  317 + // Nothing to do here;
  318 +}
  319 +
  320 +void MetaballRefracController::Create( Application& app )
  321 +{
  322 + Stage stage = Stage::GetCurrent();
  323 +
  324 + stage.KeyEventSignal().Connect( this, &MetaballRefracController::OnKeyEvent );
  325 +
  326 + mScreenSize = stage.GetSize();
  327 +
  328 + stage.SetBackgroundColor(Color::BLACK);
  329 +
  330 + // Load background texture
  331 + mBackgroundTexture = DemoHelper::LoadTexture( BACKGROUND_IMAGE );
  332 +
  333 + mGravity = Vector2(GRAVITY_X,GRAVITY_Y);
  334 + mGravityVar = Vector2(0,0);
  335 +
  336 + CreateMetaballActors();
  337 + CreateMetaballImage();
  338 + CreateComposition();
  339 + CreateAnimations();
  340 +
  341 + // Connect the callback to the touch signal on the mesh actor
  342 + stage.GetRootLayer().TouchSignal().Connect( this, &MetaballRefracController::OnTouch );
  343 +}
  344 +
  345 +Geometry MetaballRefracController::CreateGeometry( bool aspectMappedTexture )
  346 +{
  347 + const float aspect = mScreenSize.y / mScreenSize.x;
  348 +
  349 + // Create vertices and specify their color
  350 + const float xsize = mScreenSize.x * 0.5;
  351 +
  352 + // Create the meshdata for the metaballs
  353 + struct VertexPosition { Vector2 position; };
  354 + struct VertexTexture { Vector2 texture; };
  355 +
  356 + VertexPosition vertices[] =
  357 + {
  358 + { Vector2( -xsize, -xsize * aspect ) },
  359 + { Vector2( xsize, -xsize * aspect ) },
  360 + { Vector2( -xsize, xsize * aspect ) },
  361 + { Vector2( xsize, xsize * aspect ) }
  362 + };
  363 +
  364 + const float textureAspect = (aspectMappedTexture) ? aspect : 1.0f;
  365 + VertexTexture textures[] =
  366 + {
  367 + { Vector2( 0.0f, 0.0f ) },
  368 + { Vector2( 1.0f, 0.0f ) },
  369 + { Vector2( 0.0f, 1.0f * textureAspect ) },
  370 + { Vector2( 1.0f, 1.0f * textureAspect ) }
  371 + };
  372 +
  373 + uint32_t numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
  374 +
  375 + // Vertices
  376 + Property::Map positionVertexFormat;
  377 + positionVertexFormat["aPosition"] = Property::VECTOR2;
  378 + PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat );
  379 + positionVertices.SetData( vertices, numberOfVertices );
  380 +
  381 + // Textures
  382 + Property::Map textureVertexFormat;
  383 + textureVertexFormat["aTexture"] = Property::VECTOR2;
  384 + PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat );
  385 + textureVertices.SetData( textures, numberOfVertices );
  386 +
  387 + // Indices
  388 + const uint16_t indices[] = { 0, 3, 1, 0, 2, 3 };
  389 +
  390 + // Create the geometry object
  391 + Geometry texturedQuadGeometry = Geometry::New();
  392 + texturedQuadGeometry.AddVertexBuffer( positionVertices );
  393 + texturedQuadGeometry.AddVertexBuffer( textureVertices );
  394 +
  395 + texturedQuadGeometry.SetIndexBuffer ( &indices[0], sizeof( indices )/ sizeof( indices[0] ) );
  396 +
  397 + return texturedQuadGeometry;
  398 +}
  399 +
  400 +void MetaballRefracController::CreateMetaballActors()
  401 +{
  402 + const float aspect = mScreenSize.y / mScreenSize.x;
  403 +
  404 + // Create the renderer for the metaballs
  405 + Shader shader = Shader::New( METABALL_VERTEX_SHADER, METABALL_FRAG_SHADER, Shader::Hint::MODIFIES_GEOMETRY );
  406 + Geometry metaballGeometry = CreateGeometry();
  407 + Renderer renderer = Renderer::New( metaballGeometry, shader );
  408 + renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
  409 + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE );
  410 + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE );
  411 + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE );
  412 + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE );
  413 +
  414 + // Each metaball has a different radius
  415 + mMetaballs[0].radius = mMetaballs[0].initRadius = 0.0145f;
  416 + mMetaballs[1].radius = mMetaballs[1].initRadius = 0.012f;
  417 + mMetaballs[2].radius = mMetaballs[2].initRadius = 0.0135f;
  418 + mMetaballs[3].radius = mMetaballs[3].initRadius = 0.0135f;
  419 +
  420 + // Initialization of each of the metaballs
  421 + for( uint32_t i = 0 ; i < METABALL_NUMBER ; i++ )
  422 + {
  423 + mMetaballs[i].position = Vector2(0.0f, 0.0f);
  424 +
  425 + mMetaballs[i].actor = Actor::New();
  426 + mMetaballs[i].actor.SetName( "Metaball" );
  427 + mMetaballs[i].actor.SetScale( 1.0f );
  428 + mMetaballs[i].actor.SetParentOrigin( ParentOrigin::CENTER );
  429 +
  430 +
  431 + mMetaballs[i].actor.AddRenderer( renderer );
  432 +
  433 + mMetaballs[i].positionIndex = mMetaballs[i].actor.RegisterProperty( "uPositionMetaball", mMetaballs[i].position );
  434 + mMetaballs[i].positionVarIndex = mMetaballs[i].actor.RegisterProperty( "uPositionVar", Vector2(0.f,0.f) );
  435 + mMetaballs[i].gravityIndex = mMetaballs[i].actor.RegisterProperty( "uGravityVector", Vector2(0.f,0.f) );
  436 + mMetaballs[i].radiusIndex = mMetaballs[i].actor.RegisterProperty( "uRadius", mMetaballs[i].radius );
  437 + mMetaballs[i].radiusVarIndex = mMetaballs[i].actor.RegisterProperty( "uRadiusVar", 0.f );
  438 + mMetaballs[i].aspectIndex = mMetaballs[i].actor.RegisterProperty( "uAspect", aspect );
  439 + }
  440 +
  441 + //Root creation
  442 + mMetaballRoot = Actor::New();
  443 + mMetaballRoot.SetParentOrigin( ParentOrigin::CENTER );
  444 + for( uint32_t i = 0 ; i < METABALL_NUMBER ; i++ )
  445 + {
  446 + mMetaballRoot.Add( mMetaballs[i].actor );
  447 + }
  448 +}
  449 +
  450 +void MetaballRefracController::CreateMetaballImage()
  451 +{
  452 + // Create an FBO and a render task to create to render the metaballs with a fragment shader
  453 + Stage stage = Stage::GetCurrent();
  454 + mMetaballFBO = FrameBuffer::New( mScreenSize.x, mScreenSize.y, FrameBuffer::Attachment::NONE );
  455 + mMetaballFBOTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
  456 + Pixel::RGB888,
  457 + mScreenSize.x, mScreenSize.y );
  458 + mMetaballFBO.AttachColorTexture( mMetaballFBOTexture );
  459 +
  460 + stage.Add(mMetaballRoot);
  461 +
  462 + //Creation of the render task used to render the metaballs
  463 + RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
  464 + RenderTask task = taskList.CreateTask();
  465 + task.SetRefreshRate( RenderTask::REFRESH_ALWAYS );
  466 + task.SetSourceActor( mMetaballRoot );
  467 + task.SetExclusive( true );
  468 + task.SetClearColor( Color::BLACK );
  469 + task.SetClearEnabled( true );
  470 + task.SetFrameBuffer( mMetaballFBO );
  471 +}
  472 +
  473 +void MetaballRefracController::CreateComposition()
  474 +{
  475 + // Create Refraction shader and renderer
  476 + mShaderRefraction = Shader::New( METABALL_VERTEX_SHADER, REFRACTION_FRAG_SHADER );
  477 +
  478 + // Create new texture set
  479 + mTextureSetRefraction = TextureSet::New();
  480 + mTextureSetRefraction.SetTexture( 0u, mBackgroundTexture );
  481 + mTextureSetRefraction.SetTexture( 1u, mMetaballFBOTexture );
  482 +
  483 + // Create normal shader
  484 + mShaderNormal = Shader::New( METABALL_VERTEX_SHADER, FRAG_SHADER );
  485 +
  486 + // Create new texture set
  487 + mTextureSetNormal = TextureSet::New();
  488 + mTextureSetNormal.SetTexture( 0u, mBackgroundTexture );
  489 +
  490 + // Create actor
  491 + mCompositionActor = Actor::New( );
  492 + mCompositionActor.SetParentOrigin(ParentOrigin::CENTER);
  493 + mCompositionActor.SetPosition(Vector3(0.0f, 0.0f, 0.0f));
  494 + mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y);
  495 +
  496 + // Create geometry
  497 + Geometry metaballGeometry = CreateGeometry( false );
  498 + mRendererRefraction = Renderer::New( metaballGeometry, mShaderNormal );
  499 + mRendererRefraction.SetTextures( mTextureSetNormal );
  500 + mCompositionActor.AddRenderer( mRendererRefraction );
  501 +
  502 + Stage stage = Stage::GetCurrent();
  503 + stage.Add( mCompositionActor );
  504 +}
  505 +
  506 +void MetaballRefracController::CreateAnimations()
  507 +{
  508 + uint32_t i = 0;
  509 + float key;
  510 +
  511 + mPositionVarAnimation[1] = Animation::New( 2.f );
  512 + mPositionVarAnimation[1].SetLooping( false );
  513 + mPositionVarAnimation[1].Pause();
  514 + mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
  515 +
  516 + KeyFrames keySinCosVariation = KeyFrames::New();
  517 + Vector2 sinCosVariation(0,0);
  518 + for( i = 0 ; i < 360; i++ )
  519 + {
  520 + sinCosVariation.x = 0.05f * ( -sinf(i * Math::PI_OVER_180) + cosf(i * Math::PI_OVER_180) );
  521 + sinCosVariation.y = 0.05f * ( sinf(i * Math::PI_OVER_180) - cosf(i * Math::PI_OVER_180) );
  522 + key = i/360.f;
  523 + keySinCosVariation.Add(key, sinCosVariation);
  524 + }
  525 +
  526 + mPositionVarAnimation[2] = Animation::New(6.f);
  527 + mPositionVarAnimation[2].AnimateBetween(Property( mMetaballs[2].actor, mMetaballs[2].positionVarIndex ), keySinCosVariation);
  528 + mPositionVarAnimation[2].SetLooping( true );
  529 + mPositionVarAnimation[2].Pause();
  530 +
  531 + KeyFrames keyCosSinVariation = KeyFrames::New();
  532 + Vector2 cosSinVariation(0,0);
  533 + for( i = 0 ; i < 360; i++ )
  534 + {
  535 + cosSinVariation.x = 0.05f * ( -sinf(i * Math::PI_OVER_180) - cosf(i * Math::PI_OVER_180) );
  536 + cosSinVariation.y = 0.05f * ( sinf(i * Math::PI_OVER_180) + cosf(i * Math::PI_OVER_180) );
  537 + key = i/360.f;
  538 + keyCosSinVariation.Add(key, cosSinVariation);
  539 + }
  540 +
  541 + mPositionVarAnimation[3] = Animation::New(6.f);
  542 + mPositionVarAnimation[3].AnimateBetween(Property( mMetaballs[3].actor, mMetaballs[3].positionVarIndex ), keyCosSinVariation);
  543 + mPositionVarAnimation[3].SetLooping( true );
  544 + mPositionVarAnimation[3].Pause();
  545 +
  546 + //Animations for gravity
  547 + for( i = 0 ; i < METABALL_NUMBER; i++ )
  548 + {
  549 + mGravityAnimation[i] = Animation::New( 25.f );
  550 + mGravityAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].gravityIndex ), mGravity * 25.f * 3.f );
  551 + mGravityAnimation[i].SetLooping( false );
  552 + mGravityAnimation[i].Pause();
  553 + }
  554 +
  555 + //Animation to decrease size of metaballs when there is no click
  556 + for( i = 0 ; i < METABALL_NUMBER; i++ )
  557 + {
  558 + mRadiusDecAnimation[i] = Animation::New( 25.f );
  559 + mRadiusDecAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), -0.004f * 25.f * 3.f );
  560 + mRadiusDecAnimation[i].SetLooping( false );
  561 + mRadiusDecAnimation[i].Pause();
  562 + }
  563 +
  564 + // Animation to grow the size of the metaballs the first second of the click
  565 + for( i = 0 ; i < METABALL_NUMBER; i++ )
  566 + {
  567 + mRadiusIncFastAnimation[i] = Animation::New( 0.3f );
  568 + mRadiusIncFastAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.06f );
  569 + mRadiusIncFastAnimation[i].SetLooping( false );
  570 + mRadiusIncFastAnimation[i].Pause();
  571 + }
  572 + mRadiusIncFastAnimation[0].FinishedSignal().Connect( this, &MetaballRefracController::LaunchRadiusIncSlowAnimations );
  573 +
  574 + // Animation to grow the size of the metaballs afterwards
  575 + for( i = 0 ; i < METABALL_NUMBER; i++ )
  576 + {
  577 + mRadiusIncSlowAnimation[i] = Animation::New( 20.f );
  578 + mRadiusIncSlowAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.04f );
  579 + mRadiusIncSlowAnimation[i].SetLooping( false );
  580 + mRadiusIncSlowAnimation[i].Pause();
  581 + }
  582 +
  583 + // Keyframes of a sin function
  584 + KeyFrames keySin = KeyFrames::New();
  585 + float val;
  586 + for( i = 0 ; i < 360; i++ )
  587 + {
  588 + val = 0.01f * sin(i * Math::PI/180.f);
  589 + key = i/360.f;
  590 + keySin.Add(key, val);
  591 + }
  592 +
  593 + //Animation to change the size of the metaball
  594 + mRadiusVarAnimation[2] = Animation::New( 8.f );
  595 + mRadiusVarAnimation[2].AnimateBetween( Property( mMetaballs[2].actor, mMetaballs[2].radiusVarIndex ), keySin );
  596 + mRadiusVarAnimation[2].SetLooping( true );
  597 +
  598 + // Keyframes of a cos function
  599 + KeyFrames keyCos = KeyFrames::New();
  600 + for( i = 0 ; i < 360; i++ )
  601 + {
  602 + val = 0.01f * cos(i * Math::PI/180.f);
  603 + key = i/360.f;
  604 + keyCos.Add(key, val);
  605 + }
  606 +
  607 + //Animation to change the size of the metaball
  608 + mRadiusVarAnimation[3] = Animation::New( 8.f );
  609 + mRadiusVarAnimation[3].AnimateBetween( Property( mMetaballs[3].actor, mMetaballs[3].radiusVarIndex ), keyCos );
  610 + mRadiusVarAnimation[3].SetLooping( true );
  611 +}
  612 +
  613 +void MetaballRefracController::LaunchGetBackToPositionAnimation( Animation& source )
  614 +{
  615 + mMetaballPosVariationTo = Vector2(0,0);
  616 +
  617 + mPositionVarAnimation[1] = Animation::New( 1.f );
  618 + mPositionVarAnimation[1].SetLooping( false );
  619 + mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), Vector2(0,0) );
  620 + mPositionVarAnimation[1].Play();
  621 +}
  622 +
  623 +void MetaballRefracController::LaunchRadiusIncSlowAnimations( Animation& source )
  624 +{
  625 + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
  626 + {
  627 + mRadiusIncSlowAnimation[i].Play();
  628 + }
  629 + mPositionVarAnimation[2].Play();
  630 + mPositionVarAnimation[3].Play();
  631 +}
  632 +
  633 +void MetaballRefracController::StopClickAnimations()
  634 +{
  635 + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
  636 + {
  637 + mRadiusIncSlowAnimation[i].Stop();
  638 + mRadiusIncFastAnimation[i].Stop();
  639 + }
  640 + mPositionVarAnimation[1].Stop();
  641 + mPositionVarAnimation[2].Stop();
  642 + mPositionVarAnimation[3].Stop();
  643 +}
  644 +
  645 +void MetaballRefracController::StopAfterClickAnimations()
  646 +{
  647 + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
  648 + {
  649 + mGravityAnimation[i].Stop();
  650 + mRadiusDecAnimation[i].Stop();
  651 +
  652 + mMetaballs[i].radius = mMetaballs[i].initRadius;
  653 +
  654 + mMetaballs[i].actor.SetProperty( mMetaballs[i].gravityIndex, Vector2(0,0) );
  655 + mMetaballs[i].actor.SetProperty( mMetaballs[i].radiusIndex, mMetaballs[i].radius );
  656 + mMetaballs[i].actor.SetProperty( mMetaballs[i].radiusVarIndex, 0.f );
  657 + }
  658 + mRadiusVarAnimation[2].Stop();
  659 + mRadiusVarAnimation[3].Stop();
  660 +}
  661 +
  662 +void MetaballRefracController::ResetMetaballsState()
  663 +{
  664 + mRendererRefraction.SetTextures( mTextureSetNormal );
  665 + mRendererRefraction.SetShader( mShaderNormal );
  666 +
  667 + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
  668 + {
  669 + mMetaballs[i].radius = mMetaballs[i].initRadius;
  670 + }
  671 +
  672 + mMetaballPosVariationTo = Vector2(0,0);
  673 + mMetaballPosVariationFrom = Vector2(0,0);
  674 + mMetaballPosVariation = Vector2(0,0);
  675 + mGravityVar = Vector2(0,0);
  676 +}
  677 +
  678 +void MetaballRefracController::SetPositionToMetaballs( const Vector2& metaballCenter )
  679 +{
  680 + //We set the position for the metaballs based on click position
  681 + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
  682 + {
  683 + mMetaballs[i].position = metaballCenter;
  684 + mMetaballs[i].actor.SetProperty( mMetaballs[i].positionIndex, mMetaballs[i].position );
  685 + }
  686 +}
  687 +
  688 +bool MetaballRefracController::OnTouch( Actor actor, const TouchData& touch )
  689 +{
  690 + const float aspect = mScreenSize.y / mScreenSize.x;
  691 + switch( touch.GetState( 0 ) )
  692 + {
  693 + case PointState::DOWN:
  694 + {
  695 + StopAfterClickAnimations();
  696 + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
  697 + {
  698 + mRadiusIncFastAnimation[i].Play();
  699 + }
  700 + mRadiusVarAnimation[2].Play();
  701 + mRadiusVarAnimation[3].Play();
  702 +
  703 + //We draw with the refraction-composition shader
  704 + mRendererRefraction.SetTextures( mTextureSetRefraction );
  705 + mRendererRefraction.SetShader( mShaderRefraction );
  706 + mCurrentTouchPosition = touch.GetScreenPosition( 0 );
  707 +
  708 + //we use the click position for the metaballs
  709 + Vector2 metaballCenter = Vector2( (mCurrentTouchPosition.x / mScreenSize.x) - 0.5f,
  710 + (aspect * (mScreenSize.y - mCurrentTouchPosition.y) / mScreenSize.y) - 0.5f ) * 2.0f;
  711 + SetPositionToMetaballs(metaballCenter);
  712 + break;
  713 + }
  714 + case PointState::MOTION:
  715 + {
  716 + Vector2 screen = touch.GetScreenPosition( 0 );
  717 + Vector2 displacement = screen - mCurrentTouchPosition;
  718 + mCurrentTouchPosition = screen;
  719 +
  720 + mMetaballPosVariationTo.x += ( displacement.x / mScreenSize.x ) * 2.2f;
  721 + mMetaballPosVariationTo.y += (-displacement.y / mScreenSize.y ) * 2.2f;
  722 +
  723 + if (mPositionVarAnimation[1])
  724 + {
  725 + mPositionVarAnimation[1].FinishedSignal().Disconnect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
  726 + mPositionVarAnimation[1].Stop();
  727 + }
  728 + mPositionVarAnimation[1] = Animation::New( 1.f );
  729 + mPositionVarAnimation[1].SetLooping( false );
  730 + mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), mMetaballPosVariationTo );
  731 + mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
  732 + mPositionVarAnimation[1].Play();
  733 +
  734 + //we use the click position for the metaballs
  735 + Vector2 metaballCenter = Vector2( (screen.x / mScreenSize.x) - 0.5f,
  736 + (aspect * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5f) * 2.0f;
  737 + SetPositionToMetaballs(metaballCenter);
  738 + break;
  739 + }
  740 + case PointState::UP:
  741 + case PointState::LEAVE:
  742 + case PointState::INTERRUPTED:
  743 + {
  744 + //Stop click animations
  745 + StopClickAnimations();
  746 +
  747 + //Launch out of screen animations
  748 + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
  749 + {
  750 + mGravityAnimation[i].Play();
  751 + }
  752 +
  753 + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
  754 + {
  755 + mRadiusDecAnimation[i].Play();
  756 + }
  757 + break;
  758 + }
  759 + default:
  760 + break;
  761 + }
  762 + return true;
  763 +}
  764 +
  765 +void MetaballRefracController::OnKeyEvent(const KeyEvent& event)
  766 +{
  767 + if( event.state == KeyEvent::Down )
  768 + {
  769 + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
  770 + {
  771 + mApplication.Quit();
  772 + }
  773 + }
  774 +}
  775 +
  776 +/**
  777 + * Main entry point
  778 + */
  779 +int32_t DALI_EXPORT_API main( int argc, char **argv )
  780 +{
  781 + Application application = Application::New( &argc, &argv );
  782 +
  783 + MetaballRefracController test( application );
  784 + application.MainLoop();
  785 +
  786 + return 0;
  787 +}
... ...
packaging/com.samsung.dali-demo.spec
... ... @@ -2,7 +2,7 @@
2 2  
3 3 Name: com.samsung.dali-demo
4 4 Summary: The OpenGLES Canvas Core Demo
5   -Version: 1.3.51
  5 +Version: 1.3.52
6 6 Release: 1
7 7 Group: System/Libraries
8 8 License: Apache-2.0
... ...
resources/po/as.po
... ... @@ -76,6 +76,12 @@ msgstr &quot;মেশ অঙ্কুৰিত&quot;
76 76 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
77 77 msgstr "3D অনুগামী"
78 78  
  79 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  80 +msgstr "মেটাবল মহা-বিস্ফোৰণবাদ"
  81 +
  82 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  83 +msgstr "মেটাবল প্ৰতিসৰিত"
  84 +
79 85 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
80 86 msgstr "অস্পষ্ট"
81 87  
... ...
resources/po/de.po
... ... @@ -76,6 +76,12 @@ msgstr &quot;Mesh Veränderung&quot;
76 76 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
77 77 msgstr "3D-Modelle"
78 78  
  79 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  80 +msgstr "Metaball Explosion"
  81 +
  82 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  83 +msgstr "Metaball Brechung"
  84 +
79 85 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
80 86 msgstr "Bewegungsunschärfe"
81 87  
... ...
resources/po/en_GB.po
... ... @@ -112,6 +112,12 @@ msgstr &quot;Mesh Morph&quot;
112 112 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
113 113 msgstr "Mesh Visual"
114 114  
  115 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  116 +msgstr "Metaball Explosion"
  117 +
  118 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  119 +msgstr "Metaball Refraction"
  120 +
115 121 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
116 122 msgstr "Motion Blur"
117 123  
... ...
resources/po/en_US.po
... ... @@ -115,6 +115,12 @@ msgstr &quot;Mesh Morph&quot;
115 115 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
116 116 msgstr "Mesh Visual"
117 117  
  118 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  119 +msgstr "Metaball Explosion"
  120 +
  121 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  122 +msgstr "Metaball Refraction"
  123 +
118 124 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
119 125 msgstr "Motion Blur"
120 126  
... ...
resources/po/es.po
... ... @@ -76,6 +76,12 @@ msgstr &quot;Transformacion de geometrias&quot;
76 76 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
77 77 msgstr "Gemeotria 3D"
78 78  
  79 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  80 +msgstr "Explosion de metabolas"
  81 +
  82 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  83 +msgstr "Refraccion de metabolas"
  84 +
79 85 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
80 86 msgstr "Desenfoque de movimiento"
81 87  
... ...
resources/po/fi.po
... ... @@ -76,6 +76,12 @@ msgstr &quot;Polygoniverkon Muodonmuutos&quot;
76 76 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
77 77 msgstr "Polygoniverkkovisuaali"
78 78  
  79 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  80 +msgstr "Metaball Räjähdys"
  81 +
  82 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  83 +msgstr "Metaball Valon Taittumisella"
  84 +
79 85 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
80 86 msgstr "Liikesumennus"
81 87  
... ...
resources/po/ko.po
... ... @@ -85,6 +85,12 @@ msgstr &quot;메쉬 형태&quot;
85 85 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
86 86 msgstr "메쉬 비주얼"
87 87  
  88 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  89 +msgstr "메타볼 폭발"
  90 +
  91 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  92 +msgstr "메타볼 굴절"
  93 +
88 94 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
89 95 msgstr "모션 블러"
90 96  
... ...
resources/po/ml.po
... ... @@ -76,6 +76,12 @@ msgstr &quot;മോർഫ് mesh&quot;
76 76 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
77 77 msgstr "3D മോഡലിങ്"
78 78  
  79 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  80 +msgstr "മെറ്റാ പന്ത് സ്ഫോടനം"
  81 +
  82 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  83 +msgstr "മെറ്റാ പന്ത് അപവർത്തനം"
  84 +
79 85 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
80 86 msgstr "അവ്യക്തമാക്കല്"
81 87  
... ...
resources/po/ur.po
... ... @@ -79,6 +79,12 @@ msgstr &quot;میش کی تبدیلی&quot;
79 79 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
80 80 msgstr "3D میش"
81 81  
  82 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  83 +msgstr "میٹابال دھماکہ"
  84 +
  85 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  86 +msgstr "میٹابال اپورتن"
  87 +
82 88 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
83 89 msgstr "دھندلانے کی حرکت"
84 90  
... ...
resources/po/zn_CH.po
... ... @@ -76,6 +76,12 @@ msgstr &quot;网格变形&quot;
76 76 msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL"
77 77 msgstr "3D模型"
78 78  
  79 +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION"
  80 +msgstr "元球爆炸"
  81 +
  82 +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC"
  83 +msgstr "元球折射"
  84 +
79 85 msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR"
80 86 msgstr "动作模糊"
81 87  
... ...
shared/dali-demo-strings.h
... ... @@ -73,6 +73,8 @@ extern &quot;C&quot;
73 73 #define DALI_DEMO_STR_TITLE_MAGNIFIER dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MAGNIFIER")
74 74 #define DALI_DEMO_STR_TITLE_MESH_MORPH dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MESH_MORPH")
75 75 #define DALI_DEMO_STR_TITLE_MESH_VISUAL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MESH_VISUAL")
  76 +#define DALI_DEMO_STR_TITLE_METABALL_EXPLOSION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION")
  77 +#define DALI_DEMO_STR_TITLE_METABALL_REFRAC dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_METABALL_REFRAC")
76 78 #define DALI_DEMO_STR_TITLE_MOTION_BLUR dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MOTION_BLUR")
77 79 #define DALI_DEMO_STR_TITLE_MOTION_STRETCH dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MOTION_STRETCH")
78 80 #define DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE")
... ... @@ -159,6 +161,8 @@ extern &quot;C&quot;
159 161 #define DALI_DEMO_STR_TITLE_MAGNIFIER "Magnifier"
160 162 #define DALI_DEMO_STR_TITLE_MESH_MORPH "Mesh Morph"
161 163 #define DALI_DEMO_STR_TITLE_MESH_VISUAL "Mesh Visual"
  164 +#define DALI_DEMO_STR_TITLE_METABALL_EXPLOSION "Metaball Explosion"
  165 +#define DALI_DEMO_STR_TITLE_METABALL_REFRAC "Metaball Refractions"
162 166 #define DALI_DEMO_STR_TITLE_MOTION_BLUR "Motion Blur"
163 167 #define DALI_DEMO_STR_TITLE_MOTION_STRETCH "Motion Stretch"
164 168 #define DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE "Native Image Source"
... ...