2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <dali/dali.h>
24 #include <dali/devel-api/rendering/renderer.h>
25 #include <dali-toolkit/dali-toolkit.h>
27 #include "shared/view.h"
30 using namespace Dali::Toolkit;
34 const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-2.jpg" );
35 const char * const TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" );
37 const float GRAVITY_X(0);
38 const float GRAVITY_Y(-0.09);
41 #define METABALL_NUMBER 12
44 const char*const METABALL_VERTEX_SHADER = DALI_COMPOSE_SHADER (
45 attribute mediump vec2 aPosition;\n
46 attribute mediump vec2 aTexture;\n
47 uniform mediump mat4 uMvpMatrix;\n
48 uniform mediump vec3 uSize;\n
49 uniform lowp vec4 uColor;\n
50 varying mediump vec2 vTexCoord;\n
54 vTexCoord = aTexture;\n
55 mediump vec4 vertexPosition = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n
56 gl_Position = uMvpMatrix * vertexPosition;\n
61 const char*const METABALL_FRAG_SHADER = DALI_COMPOSE_SHADER (
62 precision mediump float;\n
63 varying vec2 vTexCoord;\n
64 uniform vec2 uPositionMetaball;\n
65 uniform vec2 uPositionVar;\n
66 uniform vec2 uGravityVector;\n
67 uniform float uRadius;\n
68 uniform float uRadiusVar;\n
71 vec2 adjustedCoords = vTexCoord * 2.0 - 1.0;\n
72 vec2 finalMetaballPosition = uPositionMetaball + uGravityVector + uPositionVar;\n
74 float finalRadius = uRadius + uRadiusVar;\n
75 vec2 distanceVec = adjustedCoords - finalMetaballPosition;\n
76 float result = dot(distanceVec, distanceVec);\n
77 float color = inversesqrt(result) * finalRadius;\n
79 gl_FragColor = vec4(color,color,color,1.0);\n
83 const char*const REFRACTION_FRAG_SHADER = DALI_COMPOSE_SHADER (
84 precision highp float;\n
85 varying vec2 vTexCoord;\n
86 uniform sampler2D sTexture;\n
87 uniform sampler2D sEffect;\n
88 uniform vec2 uPositionMetaball;\n
92 vec3 normal = vec3(0.0,0.0,1.0);\n
93 vec2 fakePos = vec2(0.0,0.0);\n
94 vec3 color = vec3(1.0, 1.0, 1.0);
97 vec4 metaColor = texture2D(sEffect, vTexCoord);\n
99 vec2 adjustedCoords = vTexCoord.xy * vec2(2.0) - vec2(1.0);\n
100 fakePos = adjustedCoords.xy - vec2(uPositionMetaball.x, -uPositionMetaball.y);
101 float len = length(fakePos) + 0.01;\n
102 vec3 colorPos = vec3(0,0,1);
104 if (metaColor.r > 0.85)\n
106 zoomCoords = ((vTexCoord - 0.5) * 0.9);\n
107 zoomCoords = zoomCoords + 0.5;\n
109 float interpNormal = mix(0.7, 1.0, (metaColor.r - 0.85) * 4.);\n
110 normal.xyz = vec3(fakePos.x * (1.0 - interpNormal) / len, fakePos.y * (1.0 - interpNormal) / len, interpNormal);\n
111 normal.xyz = normalize(normal.xyz);\n
112 color = vec3(0.65, 1.0, 0);\n
113 colorPos = vec3(fakePos.x,fakePos.y,0);
115 else if (metaColor.r > 0.75)\n
117 float interpolation = mix(0.9, 1.15, (0.85 - metaColor.r) * 10.0);\n
118 zoomCoords = ((vTexCoord - 0.5) * interpolation);\n
119 zoomCoords = zoomCoords + 0.5;\n
121 float interpNormal = mix(0.7, 0.0, (0.85 - metaColor.r) * 10.0);\n
122 normal.xyz = vec3(fakePos.x * (1.0 - interpNormal) / len, fakePos.y * (1.0 - interpNormal) / len, interpNormal);\n
123 normal.xyz = normalize(normal.xyz);\n
124 color = vec3(0.65, 1.0, 0);\n
125 colorPos = vec3(fakePos.x,fakePos.y,0);
129 zoomCoords = vTexCoord;\n
130 normal = vec3(0,0,0);\n
134 vec3 lightPosition = vec3(-750.0,-1000.0,2000.0);\n
135 vec3 vertex = vec3(adjustedCoords.x,adjustedCoords.y,0.0);\n
137 vec3 vecToLight = normalize( lightPosition - vertex );\n
139 float lightDiffuse = dot( vecToLight, normal );\n
140 lightDiffuse = max(0.0,lightDiffuse);\n
141 lightDiffuse = lightDiffuse * 0.5 + 0.5;
143 vec3 vertexToEye = vec3(0,0,1) - vertex;\n
144 vertexToEye = normalize(vertexToEye);
145 vec3 lightReflect = normalize(reflect(-vecToLight, normal));\n
146 float specularFactor = max(0.0,dot(vertexToEye, lightReflect));\n
147 specularFactor = pow(specularFactor, 32.0) * 0.7;
149 vec4 texColor = texture2D(sTexture, zoomCoords);\n
150 gl_FragColor.rgb = texColor.rgb * ambient + color.rgb * texColor.rgb * lightDiffuse + vec3(specularFactor);\n
151 gl_FragColor.a = 1.0;
155 const char*const FRAG_SHADER = DALI_COMPOSE_SHADER (
156 precision mediump float;\n
159 gl_FragColor = texture2D(sTexture, vTexCoord);\n
172 Property::Index positionIndex;
173 Property::Index positionVarIndex;
177 /**************************************************************************/
178 /* Demo using Metaballs ***********/
179 /* When the metaball is clicked it explodes in different balls ***********/
180 /**************************************************************************/
181 class MetaballExplosionController : public ConnectionTracker
184 MetaballExplosionController( Application& application );
185 ~MetaballExplosionController();
188 * Main create function, it creates the metaballs and all the related data
190 void Create( Application& app );
193 * Touch event function
195 bool OnTouch( Actor actor, const TouchEvent& touch );
200 void OnKeyEvent(const KeyEvent& event);
204 Application& mApplication;
210 FrameBufferImage mMetaballFBO;
213 MetaballInfo mMetaballs[METABALL_NUMBER];
215 Property::Index mPositionIndex;
216 Actor mCompositionActor;
219 Vector2 mCurrentTouchPosition;
220 Vector2 mMetaballPosVariation;
221 Vector2 mMetaballPosVariationFrom;
222 Vector2 mMetaballPosVariationTo;
223 Vector2 mMetaballCenter;
226 Animation mPositionVarAnimation[METABALL_NUMBER];
229 Animation mDispersionAnimation[METABALL_NUMBER];
231 Timer mTimerDispersion;
238 * Create a mesh data with the geometry for the metaball rendering
240 Geometry CreateGeometry();
243 * Create a mesh data with the geometry for the final composition
245 Geometry CreateGeometryComposition();
248 * Create a mesh actor for the metaballs
250 void CreateMetaballActors();
253 * Create the render task and FBO to render the metaballs into a texture
255 void CreateMetaballImage();
258 * Create a mesh image to render the final composition
260 void AddRefractionImage();
263 * Function to create animations for the small variations of position inside the metaball
265 void CreateAnimations();
268 * Function to reset metaball state
270 void ResetMetaballs(bool resetAnims);
273 * Function to create disperse each of the ball that compose the metaball when exploding
275 void DisperseBallAnimation(int ball);
278 * Function to make metaballs come back to reset position
280 void LaunchResetMetaballPosition(Animation &source);
283 * Function to set things at the end of the animation
285 void EndDisperseAnimation(Animation &source);
288 * Function to init dispersion of the metaballs one by one using a timer
289 * (so not all the balls begin moving at the same time)
291 bool OnTimerDispersionTick();
294 * Function to set the actual position of the metaballs when the user clicks the screen
296 void SetPositionToMetaballs(Vector2 & metaballCenter);
300 //-----------------------------------------------------------------------------------------------
306 MetaballExplosionController::MetaballExplosionController( Application& application )
307 : mApplication( application )
309 // Connect to the Application's Init signal
310 mApplication.InitSignal().Connect( this, &MetaballExplosionController::Create );
313 MetaballExplosionController::~MetaballExplosionController()
315 // Nothing to do here;
318 void MetaballExplosionController::Create( Application& app )
320 Stage stage = Stage::GetCurrent();
322 stage.KeyEventSignal().Connect(this, &MetaballExplosionController::OnKeyEvent);
324 mScreenSize = stage.GetSize();
328 stage.SetBackgroundColor(Color::BLACK);
330 //Set background image for the view
331 mBackImage = ResourceImage::New( BACKGROUND_IMAGE );
333 srand((unsigned)time(0));
335 //Create internal data
336 CreateMetaballActors();
337 CreateMetaballImage();
338 AddRefractionImage();
343 mTimerDispersion = Timer::New( 150 );
344 mTimerDispersion.TickSignal().Connect(this, &MetaballExplosionController::OnTimerDispersionTick);
346 // Connect the callback to the touch signal on the mesh actor
347 stage.GetRootLayer().TouchedSignal().Connect( this, &MetaballExplosionController::OnTouch );
350 Geometry MetaballExplosionController::CreateGeometry()
352 float aspect = (float)mScreenSize.y / (float)mScreenSize.x;
354 // Create vertices and specify their color
355 float xsize = mScreenSize.x * 0.5;
357 //We create the meshdata for the metaballs
358 struct VertexPosition { Vector2 position; };
359 struct VertexTexture { Vector2 texture; };
360 struct VertexNormal { Vector3 normal; };
362 VertexPosition vertices[] = {
363 { Vector2( -xsize, -xsize * aspect) },
364 { Vector2( xsize, -xsize * aspect) },
365 { Vector2( -xsize, xsize * aspect) },
366 { Vector2( xsize, xsize * aspect) }
369 VertexTexture textures[] = {
370 { Vector2(0.0f, 0.0f) },
371 { Vector2(1.0f, 0.0f) },
372 { Vector2(0.0f, 1.0f * aspect) },
373 { Vector2(1.0f, 1.0f * aspect) }
376 int indices[] = { 0, 3, 1, 0, 2, 3 };
378 unsigned int numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
381 Property::Map positionVertexFormat;
382 positionVertexFormat["aPosition"] = Property::VECTOR2;
383 PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat, numberOfVertices );
384 positionVertices.SetData(vertices);
387 Property::Map textureVertexFormat;
388 textureVertexFormat["aTexture"] = Property::VECTOR2;
389 PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat, numberOfVertices );
390 textureVertices.SetData(textures);
393 Property::Map indicesVertexFormat;
394 indicesVertexFormat["aIndices"] = Property::INTEGER;
395 PropertyBuffer indicesToVertices = PropertyBuffer::New( indicesVertexFormat, 6 );
396 indicesToVertices.SetData(indices);
398 // Create the geometry object
399 Geometry texturedQuadGeometry = Geometry::New();
400 texturedQuadGeometry.AddVertexBuffer( positionVertices );
401 texturedQuadGeometry.AddVertexBuffer( textureVertices );
403 texturedQuadGeometry.SetIndexBuffer ( indicesToVertices );
405 return texturedQuadGeometry;
408 Geometry MetaballExplosionController::CreateGeometryComposition()
410 float aspect = (float)mScreenSize.y / (float)mScreenSize.x;
412 // Create vertices and specify their color
413 float xsize = mScreenSize.x * 0.5;
415 //We create the meshdata for the metaballs
416 struct VertexPosition { Vector2 position; };
417 struct VertexTexture { Vector2 texture; };
418 struct VertexNormal { Vector3 normal; };
420 VertexPosition vertices[] = {
421 { Vector2( -xsize, -xsize * aspect) },
422 { Vector2( xsize, -xsize * aspect) },
423 { Vector2( -xsize, xsize * aspect) },
424 { Vector2( xsize, xsize * aspect) }
427 VertexTexture textures[] = {
428 { Vector2(0.0f, 0.0f) },
429 { Vector2(1.0f, 0.0f) },
430 { Vector2(0.0f, 1.0f) },
431 { Vector2(1.0f, 1.0f) }
434 int indices[] = { 0, 3, 1, 0, 2, 3 };
436 unsigned int numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
439 Property::Map positionVertexFormat;
440 positionVertexFormat["aPosition"] = Property::VECTOR2;
441 PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat, numberOfVertices );
442 positionVertices.SetData(vertices);
445 Property::Map textureVertexFormat;
446 textureVertexFormat["aTexture"] = Property::VECTOR2;
447 PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat, numberOfVertices );
448 textureVertices.SetData(textures);
451 Property::Map indicesVertexFormat;
452 indicesVertexFormat["aIndices"] = Property::INTEGER;
453 PropertyBuffer indicesToVertices = PropertyBuffer::New( indicesVertexFormat, 6 );
454 indicesToVertices.SetData(indices);
456 // Create the geometry object
457 Geometry texturedQuadGeometry = Geometry::New();
458 texturedQuadGeometry.AddVertexBuffer( positionVertices );
459 texturedQuadGeometry.AddVertexBuffer( textureVertices );
461 texturedQuadGeometry.SetIndexBuffer ( indicesToVertices );
463 return texturedQuadGeometry;
466 float randomNumber(float lowest, float highest)
468 float range=(highest-lowest);
469 return lowest+range*rand()/RAND_MAX;
472 void MetaballExplosionController::CreateMetaballActors()
474 //Create the shader for the metaballs
475 Shader shader = Shader::New( METABALL_VERTEX_SHADER, METABALL_FRAG_SHADER );
477 Material material = Material::New( shader );
478 material.SetBlendMode(BlendingMode::ON );
479 material.SetBlendFunc(BlendingFactor::ONE, BlendingFactor::ONE, BlendingFactor::ONE, BlendingFactor::ONE);
481 Geometry metaballGeom = CreateGeometry();
483 //Initialization of each of the metaballs
484 for( int i = 0; i < METABALL_NUMBER; i++ )
486 mMetaballs[i].position = Vector2(0.0f, 0.0f);
487 mMetaballs[i].radius = mMetaballs[i].initRadius = randomNumber(0.025f,0.035f);
489 mMetaballs[i].actor = Actor::New( );
490 mMetaballs[i].actor.SetName("Metaball");
491 mMetaballs[i].actor.SetScale( 1.0f );
492 mMetaballs[i].actor.SetParentOrigin( ParentOrigin::CENTER );
494 Renderer renderer = Renderer::New( metaballGeom, material );
495 mMetaballs[i].actor.AddRenderer( renderer );
497 mMetaballs[i].positionIndex = mMetaballs[i].actor.RegisterProperty( "uPositionMetaball", mMetaballs[i].position );
499 mMetaballs[i].positionVarIndex = mMetaballs[i].actor.RegisterProperty( "uPositionVar", Vector2(0.f,0.f) );
501 mMetaballs[i].actor.RegisterProperty( "uGravityVector", Vector2(randomNumber(-0.2,0.2),randomNumber(-0.2,0.2)) );
503 mMetaballs[i].actor.RegisterProperty( "uRadius", mMetaballs[i].radius );
505 mMetaballs[i].actor.RegisterProperty( "uRadiusVar", 0.f );
507 mMetaballs[i].actor.SetSize(400, 400);
511 mMetaballRoot = Actor::New();
512 mMetaballRoot.SetParentOrigin( ParentOrigin::CENTER );
513 for( int i = 0; i < METABALL_NUMBER; i++ )
515 mMetaballRoot.Add( mMetaballs[i].actor );
518 //Initialization of variables related to metaballs
519 mMetaballPosVariation = Vector2(0,0);
520 mMetaballPosVariationFrom = Vector2(0,0);
521 mMetaballPosVariationTo = Vector2(0,0);
522 mCurrentTouchPosition = Vector2(0,0);
525 void MetaballExplosionController::CreateMetaballImage()
527 //We create an FBO and a render task to create to render the metaballs with a fragment shader
528 Stage stage = Stage::GetCurrent();
529 mMetaballFBO = FrameBufferImage::New(mScreenSize.x, mScreenSize.y, Pixel::RGBA8888, RenderBuffer::COLOR_DEPTH);
532 stage.Add(mMetaballRoot);
534 //Creation of the render task used to render the metaballs
535 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
536 RenderTask task = taskList.CreateTask();
537 task.SetRefreshRate( RenderTask::REFRESH_ALWAYS );
538 task.SetSourceActor( mMetaballRoot );
539 task.SetExclusive(true);
540 task.SetClearColor( Color::BLACK );
541 task.SetClearEnabled( true );
542 task.SetTargetFrameBuffer( mMetaballFBO );
545 void MetaballExplosionController::AddRefractionImage()
547 //Create Gaussian blur for the rendered image
548 FrameBufferImage fbo;
549 fbo = FrameBufferImage::New( mScreenSize.x, mScreenSize.y, Pixel::RGBA8888, RenderBuffer::COLOR_DEPTH);
551 GaussianBlurView gbv = GaussianBlurView::New(5, 2.0f, Pixel::RGBA8888, 0.5f, 0.5f, true);
552 gbv.SetBackgroundColor(Color::TRANSPARENT);
553 gbv.SetUserImageAndOutputRenderTarget( mMetaballFBO, fbo );
554 gbv.SetSize(mScreenSize.x, mScreenSize.y);
555 Stage::GetCurrent().Add(gbv);
559 Shader shader = Shader::New( METABALL_VERTEX_SHADER, REFRACTION_FRAG_SHADER );
560 //Create new material
561 Material material = Material::New( shader );
564 material.AddTexture(mBackImage, "sTexture");
565 material.AddTexture(fbo, "sEffect");
568 Geometry metaballGeom = CreateGeometryComposition();
570 Renderer mRenderer = Renderer::New( metaballGeom, material );
572 mCompositionActor = Actor::New( );
573 mCompositionActor.SetParentOrigin(ParentOrigin::CENTER);
574 mCompositionActor.SetPosition(Vector3(0.0f, 0.0f, 0.0f));
575 mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y);
577 mCompositionActor.AddRenderer( mRenderer );
579 Vector2 metaballCenter(0.0,0);
580 metaballCenter.x = metaballCenter.x * 0.5;
581 metaballCenter.y = metaballCenter.y * 0.5;
583 mPositionIndex = mCompositionActor.RegisterProperty( "uPositionMetaball", metaballCenter );
585 SetPositionToMetaballs(metaballCenter);
587 mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y);
589 Stage stage = Stage::GetCurrent();
590 stage.Add( mCompositionActor );
593 void MetaballExplosionController::CreateAnimations()
597 for( int i = 0; i < METABALL_NUMBER; i++ )
600 KeyFrames keySinCosVariation = KeyFrames::New();
601 Vector2 sinCosVariation(0,0);
603 direction.x = randomNumber(-100.f,100.f);
604 direction.y = randomNumber(-100.f,100.f);
606 direction.Normalize();
609 for( int j = 0; j < 360; j++ )
611 sinCosVariation.x = sin(j * Math::PI/180.f) * direction.x;
612 sinCosVariation.y = cos(j * Math::PI/180.f) * direction.y;
614 keySinCosVariation.Add(key, sinCosVariation);
617 mPositionVarAnimation[i] = Animation::New(3.f);
618 mPositionVarAnimation[i].AnimateBetween(Property( mMetaballs[i].actor, mMetaballs[i].positionVarIndex ), keySinCosVariation);
619 mPositionVarAnimation[i].SetLooping( true );
620 mPositionVarAnimation[i].Play();
624 void MetaballExplosionController::ResetMetaballs(bool resetAnims)
626 for( int i = 0; i < METABALL_NUMBER; i++ )
628 if (mDispersionAnimation[i])
629 mDispersionAnimation[i].Clear();
631 mMetaballs[i].position = Vector2(0.0f, 0.0f);
632 mMetaballs[i].actor.SetProperty(mMetaballs[i].positionIndex, mMetaballs[i].position);
634 mTimerDispersion.Stop();
637 mCompositionActor.SetProperty( mPositionIndex, Vector2(0,0) );
640 void MetaballExplosionController::DisperseBallAnimation(int ball)
643 position.x = randomNumber(-1.5f,1.5f);
644 position.y = randomNumber(-1.5f,1.5f);
646 mDispersionAnimation[ball] = Animation::New(2.0f * mTimeMult);
647 mDispersionAnimation[ball].AnimateTo( Property(mMetaballs[ball].actor, mMetaballs[ball].positionIndex), position);
648 mDispersionAnimation[ball].Play();
650 if( ball == METABALL_NUMBER - 1 )
651 mDispersionAnimation[ball].FinishedSignal().Connect( this, &MetaballExplosionController::LaunchResetMetaballPosition );
654 void MetaballExplosionController::LaunchResetMetaballPosition(Animation &source)
656 for( int i = 0; i < METABALL_NUMBER; i++ )
658 mDispersionAnimation[i] = Animation::New(1.5f + i*0.25f*mTimeMult);
659 mDispersionAnimation[i].AnimateTo(Property(mMetaballs[i].actor, mMetaballs[i].positionIndex), Vector2(0,0));
660 mDispersionAnimation[i].Play();
662 if( i == METABALL_NUMBER - 1 )
663 mDispersionAnimation[i].FinishedSignal().Connect( this, &MetaballExplosionController::EndDisperseAnimation );
667 void MetaballExplosionController::EndDisperseAnimation(Animation &source)
669 mCompositionActor.SetProperty( mPositionIndex, Vector2(0,0) );
672 bool MetaballExplosionController::OnTimerDispersionTick()
674 if( mDispersion < METABALL_NUMBER )
676 DisperseBallAnimation(mDispersion);
682 void MetaballExplosionController::SetPositionToMetaballs(Vector2 & metaballCenter)
684 //We set the position for the metaballs based on click position
685 for( int i = 0; i < METABALL_NUMBER; i++ )
687 mMetaballs[i].position = metaballCenter;
688 mMetaballs[i].actor.SetProperty(mMetaballs[i].positionIndex, mMetaballs[i].position);
691 mCompositionActor.SetProperty( mPositionIndex, metaballCenter );
694 bool MetaballExplosionController::OnTouch( Actor actor, const TouchEvent& touch )
696 const TouchPoint &point = touch.GetPoint(0);
697 float aspectR = mScreenSize.y / mScreenSize.x;
699 switch( point.state )
701 case TouchPoint::Down:
703 ResetMetaballs(true);
705 Vector2 metaballCenter = Vector2((point.screen.x / mScreenSize.x) - 0.5, (aspectR * (mScreenSize.y - point.screen.y) / mScreenSize.y) - 0.5) * 2.0;
706 SetPositionToMetaballs(metaballCenter);
710 case TouchPoint::Motion:
712 Vector2 metaballCenter = Vector2((point.screen.x / mScreenSize.x) - 0.5, (aspectR * (mScreenSize.y - point.screen.y) / mScreenSize.y) - 0.5) * 2.0;
713 SetPositionToMetaballs(metaballCenter);
717 case TouchPoint::Leave:
718 case TouchPoint::Interrupted:
720 mTimerDispersion.Start();
729 void MetaballExplosionController::OnKeyEvent(const KeyEvent& event)
731 if(event.state == KeyEvent::Down)
733 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
741 //-----------------------------------------------------------------------------------------------
745 //-----------------------------------------------------------------------------------------------
747 void RunTest( Application& application )
749 MetaballExplosionController test( application );
751 application.MainLoop();
754 // Entry point for Linux & Tizen applications
756 int main( int argc, char **argv )
758 Application application = Application::New( &argc, &argv );
760 RunTest( application );