Merge branch 'devel/new_mesh' into devel/master
[platform/core/uifw/dali-demo.git] / examples / new-window / new-window-example.cpp
1 /*
2  * Copyright (c) 2014 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 // EXTERNAL INCLUDES
18 #include <dali/devel-api/rendering/renderer.h>
19 #include <dali-toolkit/dali-toolkit.h>
20 #include <dali-toolkit/devel-api/controls/bubble-effect/bubble-emitter.h>
21
22 #include <cstdio>
23 #include <iostream>
24
25 // INTERNAL INCLUDES
26 #include "shared/view.h"
27
28 using namespace Dali;
29 using namespace Dali::Toolkit;
30
31 class NewWindowController;
32
33 namespace
34 {
35 const char * const BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-2.jpg" );
36 const char * const TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
37 const char * const LOSE_CONTEXT_IMAGE( DALI_IMAGE_DIR "icon-cluster-wobble.png" );
38 const char * const BASE_IMAGE( DALI_IMAGE_DIR "gallery-large-14.jpg" );
39 const char * const EFFECT_IMAGE( DALI_IMAGE_DIR "gallery-large-18.jpg" );
40 const char * const LOGO_IMAGE(DALI_IMAGE_DIR "dali-logo.png");
41
42 const float EXPLOSION_DURATION(1.2f);
43 const unsigned int EMIT_INTERVAL_IN_MS(40);
44 const float TRACK_DURATION_IN_MS(970);
45
46 Application gApplication;
47 NewWindowController* gNewWindowController(NULL);
48
49 #define MAKE_SHADER(A)#A
50
51 const char* VERTEX_COLOR_MESH = MAKE_SHADER(
52 attribute mediump vec3  aPosition;\n
53 attribute lowp    vec3  aColor;\n
54 uniform   mediump mat4  uMvpMatrix;\n
55 uniform   mediump vec3  uSize;\n
56 varying   lowp    vec3  vColor;\n
57 \n
58 void main()\n
59 {\n
60   gl_Position = uMvpMatrix * vec4( aPosition*uSize, 1.0 );\n
61   vColor = aColor;\n
62 }\n
63 );
64
65 const char* FRAGMENT_COLOR_MESH = MAKE_SHADER(
66 uniform lowp vec4  uColor;\n
67 varying lowp vec3  vColor;\n
68 \n
69 void main()\n
70 {\n
71   gl_FragColor = vec4(vColor,1.0)*uColor;
72 }\n
73 );
74
75 const char* VERTEX_TEXTURE_MESH = MAKE_SHADER(
76 attribute mediump vec3  aPosition;\n
77 attribute highp   vec2  aTexCoord;\n
78 uniform   mediump mat4  uMvpMatrix;\n
79 uniform   mediump vec3  uSize;\n
80 varying   mediump vec2  vTexCoord;\n
81 \n
82 void main()\n
83 {\n
84   gl_Position = uMvpMatrix * vec4( aPosition*uSize, 1.0 );\n
85   vTexCoord = aTexCoord;\n
86 }\n
87 );
88
89 const char* FRAGMENT_TEXTURE_MESH = MAKE_SHADER(
90 varying mediump vec2  vTexCoord;\n
91 uniform lowp    vec4  uColor;\n
92 uniform sampler2D     sTexture;\n
93 \n
94 void main()\n
95 {\n
96   gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;
97 }\n
98 );
99
100 const char* FRAGMENT_BLEND_SHADER = MAKE_SHADER(
101 uniform mediump float alpha;\n
102 \n
103 void main()\n
104 {\n
105   mediump vec4 fragColor = texture2D(sTexture, vTexCoord);\n
106   mediump vec4 fxColor   = texture2D(sEffect, vTexCoord);\n
107   gl_FragColor = mix(fragColor,fxColor, alpha);\n
108 }\n
109 );
110
111 }; // anonymous namespace
112
113
114 class NewWindowController : public ConnectionTracker
115 {
116 public:
117   NewWindowController( Application& app );
118   void Create( Application& app );
119   void Destroy( Application& app );
120
121   void AddBubbles(const Vector2& stageSize);
122   void AddMeshActor();
123   void AddBlendingImageActor();
124   void AddTextLabel();
125
126   ImageActor CreateBlurredMirrorImage(const char* imageName);
127   FrameBufferImage CreateFrameBufferForImage(const char* imageName, Image image, ShaderEffect shaderEffect);
128   void SetUpBubbleEmission( const Vector2& emitPosition, const Vector2& direction );
129   Geometry CreateMeshGeometry();
130   ShaderEffect CreateColorModifierer( const Vector3& rgbDelta );
131
132   static void NewWindow(void);
133
134   bool OnTrackTimerTick();
135   void OnKeyEvent(const KeyEvent& event);
136   bool OnLoseContextButtonClicked( Toolkit::Button button );
137   void OnContextLost();
138   void OnContextRegained();
139
140 private:
141   Application                mApplication;
142   TextLabel                  mTextActor;
143
144   Toolkit::Control           mView;                              ///< The View instance.
145   Toolkit::ToolBar           mToolBar;                           ///< The View's Toolbar.
146   TextLabel                  mTitleActor;                        ///< The Toolbar's Title.
147   Layer                      mContentLayer;                      ///< Content layer (scrolling cluster content)
148   Toolkit::PushButton        mLoseContextButton;
149
150   Toolkit::BubbleEmitter     mEmitter;
151   Timer                      mEmitTrackTimer;
152   bool                       mNeedNewAnimation;
153   unsigned int               mAnimateComponentCount;
154   Animation                  mEmitAnimation;
155 };
156
157
158 NewWindowController::NewWindowController( Application& application )
159 : mApplication(application),
160   mNeedNewAnimation(true)
161 {
162   mApplication.InitSignal().Connect(this, &NewWindowController::Create);
163   mApplication.TerminateSignal().Connect(this, &NewWindowController::Destroy);
164 }
165
166 void NewWindowController::Create( Application& app )
167 {
168   Stage stage = Stage::GetCurrent();
169   stage.SetBackgroundColor(Color::YELLOW);
170
171   stage.KeyEventSignal().Connect(this, &NewWindowController::OnKeyEvent);
172
173   // The Init signal is received once (only) during the Application lifetime
174
175   // Hide the indicator bar
176   mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
177
178   mContentLayer = DemoHelper::CreateView( app,
179                                           mView,
180                                           mToolBar,
181                                           "",
182                                           TOOLBAR_IMAGE,
183                                           "Context recovery" );
184
185   Size stageSize = stage.GetSize();
186   Image backgroundImage = ResourceImage::New( BACKGROUND_IMAGE, Dali::ImageDimensions( stageSize.x, stageSize.y ), Dali::FittingMode::SCALE_TO_FILL, Dali::SamplingMode::BOX_THEN_LINEAR );
187   ImageActor backgroundActor = ImageActor::New( backgroundImage );
188   backgroundActor.SetParentOrigin( ParentOrigin::CENTER );
189   backgroundActor.SetZ(-2.f);
190   mContentLayer.Add(backgroundActor);
191
192   // Point the default render task at the view
193   RenderTaskList taskList = stage.GetRenderTaskList();
194   RenderTask defaultTask = taskList.GetTask( 0u );
195   if ( defaultTask )
196   {
197     defaultTask.SetSourceActor( mView );
198   }
199
200   mLoseContextButton = Toolkit::PushButton::New();
201   mLoseContextButton.SetBackgroundImage( ResourceImage::New( LOSE_CONTEXT_IMAGE ) );
202   mLoseContextButton.ClickedSignal().Connect( this, &NewWindowController::OnLoseContextButtonClicked );
203   mToolBar.AddControl( mLoseContextButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
204
205   Actor logoLayoutActor = Actor::New();
206   logoLayoutActor.SetParentOrigin(ParentOrigin::CENTER);
207   logoLayoutActor.SetPosition(0.0f, -200.0f, 0.0f);
208   logoLayoutActor.SetScale(0.5f);
209   mContentLayer.Add(logoLayoutActor);
210
211   Image image = ResourceImage::New(LOGO_IMAGE);
212   ImageActor imageActor = ImageActor::New(image);
213   imageActor.SetName("dali-logo");
214   imageActor.SetParentOrigin(ParentOrigin::CENTER);
215   imageActor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
216   logoLayoutActor.Add(imageActor);
217
218   ImageActor mirrorImageActor = CreateBlurredMirrorImage(LOGO_IMAGE);
219   mirrorImageActor.SetParentOrigin(ParentOrigin::CENTER);
220   mirrorImageActor.SetAnchorPoint(AnchorPoint::TOP_CENTER);
221   logoLayoutActor.Add(mirrorImageActor);
222
223   AddBubbles(stage.GetSize());
224   AddMeshActor();
225   AddBlendingImageActor();
226   AddTextLabel();
227
228   stage.ContextLostSignal().Connect(this, &NewWindowController::OnContextLost);
229   stage.ContextRegainedSignal().Connect(this, &NewWindowController::OnContextRegained);
230 }
231
232 void NewWindowController::Destroy( Application& app )
233 {
234   UnparentAndReset(mTextActor);
235 }
236
237 void NewWindowController::AddBubbles(const Vector2& stageSize)
238 {
239   mEmitter = Toolkit::BubbleEmitter::New( stageSize,
240                                           ResourceImage::New( DALI_IMAGE_DIR "bubble-ball.png" ),
241                                           200, Vector2( 5.0f, 5.0f ) );
242
243   Image background = ResourceImage::New(BACKGROUND_IMAGE);
244   mEmitter.SetBackground( background, Vector3(0.5f, 0.f,0.5f) );
245   mEmitter.SetBubbleDensity( 9.f );
246   Actor bubbleRoot = mEmitter.GetRootActor();
247   mContentLayer.Add( bubbleRoot );
248   bubbleRoot.SetParentOrigin(ParentOrigin::CENTER);
249   bubbleRoot.SetZ(0.1f);
250
251   mEmitTrackTimer = Timer::New( EMIT_INTERVAL_IN_MS );
252   mEmitTrackTimer.TickSignal().Connect(this, &NewWindowController::OnTrackTimerTick);
253   mEmitTrackTimer.Start();
254 }
255
256 void NewWindowController::AddMeshActor()
257 {
258   Geometry meshGeometry = CreateMeshGeometry();
259
260   // Create a coloured mesh
261   Shader shaderColorMesh = Shader::New( VERTEX_COLOR_MESH, FRAGMENT_COLOR_MESH );
262   Material colorMeshmaterial = Material::New( shaderColorMesh );
263   Renderer colorMeshRenderer = Renderer::New( meshGeometry, colorMeshmaterial );
264
265   Actor colorMeshActor = Actor::New();
266   colorMeshActor.AddRenderer( colorMeshRenderer );
267   colorMeshActor.SetSize( 175.f,175.f );
268   colorMeshActor.SetParentOrigin( ParentOrigin::CENTER );
269   colorMeshActor.SetAnchorPoint(AnchorPoint::TOP_CENTER);
270   colorMeshActor.SetPosition(Vector3(0.0f, 50.0f, 0.0f));
271   colorMeshActor.SetOrientation( Degree(75.f), Vector3::XAXIS );
272   colorMeshActor.SetName("ColorMeshActor");
273   mContentLayer.Add( colorMeshActor );
274
275  // Create a textured mesh
276   Image effectImage = ResourceImage::New(EFFECT_IMAGE);
277   Sampler sampler = Sampler::New(effectImage, "sTexture");
278
279   Shader shaderTextureMesh = Shader::New( VERTEX_TEXTURE_MESH, FRAGMENT_TEXTURE_MESH );
280   Material textureMeshMaterial = Material::New( shaderTextureMesh );
281   textureMeshMaterial.AddSampler( sampler );
282   Renderer textureMeshRenderer = Renderer::New( meshGeometry, textureMeshMaterial );
283
284   Actor textureMeshActor = Actor::New();
285   textureMeshActor.AddRenderer( textureMeshRenderer );
286   textureMeshActor.SetSize( 175.f,175.f );
287   textureMeshActor.SetParentOrigin( ParentOrigin::CENTER );
288   textureMeshActor.SetAnchorPoint(AnchorPoint::TOP_CENTER);
289   textureMeshActor.SetPosition(Vector3(0.0f, 200.0f, 0.0f));
290   textureMeshActor.SetOrientation( Degree(75.f), Vector3::XAXIS );
291   textureMeshActor.SetName("TextureMeshActor");
292   mContentLayer.Add( textureMeshActor );
293 }
294
295 void NewWindowController::AddBlendingImageActor()
296 {
297   ShaderEffect colorModifier = CreateColorModifierer(Vector3( 0.5f, 0.5f, 0.5f ));
298   Image effectImage = ResourceImage::New(EFFECT_IMAGE);
299   FrameBufferImage fb2 = CreateFrameBufferForImage( EFFECT_IMAGE, effectImage, colorModifier );
300
301   ImageActor tmpActor = ImageActor::New(fb2);
302   mContentLayer.Add(tmpActor);
303   tmpActor.SetParentOrigin(ParentOrigin::CENTER_RIGHT);
304   tmpActor.SetAnchorPoint(AnchorPoint::TOP_RIGHT);
305   tmpActor.SetPosition(Vector3(0.0f, 150.0f, 0.0f));
306   tmpActor.SetScale(0.25f);
307
308   // create blending shader effect
309   ShaderEffect blendShader = ShaderEffect::New( "", FRAGMENT_BLEND_SHADER );
310   blendShader.SetEffectImage( fb2 );
311   blendShader.SetUniform("alpha", 0.5f);
312
313   Image baseImage = ResourceImage::New(BASE_IMAGE);
314   ImageActor blendActor = ImageActor::New( baseImage );
315   blendActor.SetParentOrigin(ParentOrigin::CENTER_RIGHT);
316   blendActor.SetAnchorPoint(AnchorPoint::BOTTOM_RIGHT);
317   blendActor.SetPosition(Vector3(0.0f, 100.0f, 0.0f));
318   blendActor.SetSize(140, 140);
319   blendActor.SetShaderEffect( blendShader );
320   mContentLayer.Add(blendActor);
321 }
322
323 void NewWindowController::AddTextLabel()
324 {
325   mTextActor = TextLabel::New("Some text");
326   mTextActor.SetParentOrigin(ParentOrigin::CENTER);
327   mTextActor.SetColor(Color::RED);
328   mTextActor.SetName("PushMe text");
329   mContentLayer.Add( mTextActor );
330 }
331
332 ImageActor NewWindowController::CreateBlurredMirrorImage(const char* imageName)
333 {
334   Image image = ResourceImage::New(imageName);
335
336   Uint16Pair intFboSize = ResourceImage::GetImageSize(imageName);
337   Vector2 FBOSize = Vector2( intFboSize.GetWidth(), intFboSize.GetHeight() );
338   FrameBufferImage fbo = FrameBufferImage::New( FBOSize.width, FBOSize.height, Pixel::RGBA8888);
339
340   GaussianBlurView gbv = GaussianBlurView::New(5, 2.0f, Pixel::RGBA8888, 0.5f, 0.5f, true);
341   gbv.SetBackgroundColor(Color::TRANSPARENT);
342   gbv.SetUserImageAndOutputRenderTarget( image, fbo );
343   gbv.SetSize(FBOSize);
344   Stage::GetCurrent().Add(gbv);
345   gbv.ActivateOnce();
346
347   ImageActor blurredActor = ImageActor::New(fbo);
348   blurredActor.SetSize(FBOSize);
349   blurredActor.SetScale(1.0f, -1.0f, 1.0f);
350   return blurredActor;
351 }
352
353 FrameBufferImage NewWindowController::CreateFrameBufferForImage(const char* imageName, Image image, ShaderEffect shaderEffect)
354 {
355   Stage stage = Stage::GetCurrent();
356   Uint16Pair intFboSize = ResourceImage::GetImageSize(imageName);
357   Vector2 FBOSize = Vector2(intFboSize.GetWidth(), intFboSize.GetHeight());
358
359   FrameBufferImage framebuffer = FrameBufferImage::New(FBOSize.x, FBOSize.y );
360
361   RenderTask renderTask = stage.GetRenderTaskList().CreateTask();
362
363   ImageActor imageActor = ImageActor::New(image);
364   imageActor.SetName("Source image actor");
365   if(shaderEffect)
366   {
367     imageActor.SetShaderEffect(shaderEffect);
368   }
369   imageActor.SetParentOrigin(ParentOrigin::CENTER);
370   imageActor.SetAnchorPoint(AnchorPoint::CENTER);
371   imageActor.SetScale(1.0f, -1.0f, 1.0f);
372   stage.Add(imageActor); // Not in default image view
373
374   CameraActor cameraActor = CameraActor::New(FBOSize);
375   cameraActor.SetParentOrigin(ParentOrigin::CENTER);
376   cameraActor.SetFieldOfView(Math::PI*0.25f);
377   cameraActor.SetNearClippingPlane(1.0f);
378   cameraActor.SetAspectRatio(FBOSize.width / FBOSize.height);
379   cameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
380   cameraActor.SetPosition(0.0f, 0.0f, ((FBOSize.height * 0.5f) / tanf(Math::PI * 0.125f)));
381   stage.Add(cameraActor);
382
383   renderTask.SetSourceActor(imageActor);
384   renderTask.SetInputEnabled(false);
385   renderTask.SetTargetFrameBuffer(framebuffer);
386   renderTask.SetCameraActor( cameraActor );
387   renderTask.SetClearColor( Color::TRANSPARENT );
388   renderTask.SetClearEnabled( true );
389   renderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
390
391   return framebuffer;
392 }
393
394 void NewWindowController::SetUpBubbleEmission( const Vector2& emitPosition, const Vector2& direction)
395 {
396   if( mNeedNewAnimation )
397   {
398     float duration = Random::Range(1.f, 1.5f);
399     mEmitAnimation = Animation::New( duration );
400     mNeedNewAnimation = false;
401     mAnimateComponentCount = 0;
402   }
403
404   mEmitter.EmitBubble( mEmitAnimation, emitPosition, direction, Vector2(10,10) );
405
406   mAnimateComponentCount++;
407
408   if( mAnimateComponentCount % 6 ==0 )
409   {
410     mEmitAnimation.Play();
411     mNeedNewAnimation = true;
412   }
413 }
414
415 Geometry NewWindowController::CreateMeshGeometry()
416 {
417   // Create vertices and specify their color
418   struct Vertex
419   {
420     Vector3 position;
421     Vector2 textureCoordinates;
422     Vector3 color;
423   };
424
425   Vertex vertexData[5] = {
426     { Vector3(  0.0f,  0.0f, 0.5f ), Vector2(0.5f, 0.5f), Vector3(1.0f, 1.0f, 1.0f) },
427     { Vector3( -0.5f, -0.5f, 0.0f ), Vector2(0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f) },
428     { Vector3(  0.5f, -0.5f, 0.0f ), Vector2(1.0f, 0.0f), Vector3(1.0f, 1.0f, 0.0f) },
429     { Vector3( -0.5f,  0.5f, 0.0f ), Vector2(0.0f, 1.0f), Vector3(0.0f, 1.0f, 0.0f) },
430     { Vector3(  0.5f,  0.5f, 0.0f ), Vector2(1.0f, 1.0f), Vector3(0.0f, 0.0f, 1.0f) }  };
431
432   Property::Map vertexFormat;
433   vertexFormat["aPosition"] = Property::VECTOR3;
434   vertexFormat["aTexCoord"] = Property::VECTOR2;
435   vertexFormat["aColor"] = Property::VECTOR3;
436   PropertyBuffer vertices = PropertyBuffer::New( vertexFormat, 5 );
437   vertices.SetData( vertexData );
438
439   // Specify all the faces
440   unsigned int indexData[12] = { 0,1,3,0,2,4,0,3,4,0,2,1 };
441   Property::Map indexFormat;
442   indexFormat["indices"] = Property::UNSIGNED_INTEGER;
443   PropertyBuffer indices = PropertyBuffer::New( indexFormat, 12 );
444   indices.SetData( indexData );
445
446   // Create the geometry object
447   Geometry geometry = Geometry::New();
448   geometry.AddVertexBuffer( vertices );
449   geometry.SetIndexBuffer( indices );
450
451   return geometry;
452 }
453
454 ShaderEffect NewWindowController::CreateColorModifierer( const Vector3& rgbDelta )
455 {
456  std::string fragmentShader = MAKE_SHADER(
457    precision highp float;\n
458    uniform vec3 uRGBDelta;\n
459    uniform float uIgnoreAlpha;\n
460    float rand(vec2 co) \n
461    {\n
462      return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); \n}
463    \n
464    void main() {\n
465      vec4 color = texture2D(sTexture, vTexCoord); \n
466      // modify the hsv Value
467      color.rgb += uRGBDelta * rand(vTexCoord); \n
468      // if the new vale exceeds one, then decrease it
469      color.rgb -= max(color.rgb*2.0 - vec3(2.0), 0.0);\n
470      // if the new vale drops below zero, then increase it
471      color.rgb -= min(color.rgb*2.0, 0.0);\n
472      gl_FragColor = color; \n
473    }\n
474  );
475
476  ShaderEffect shaderEffect = ShaderEffect::New("", fragmentShader);
477  shaderEffect.SetUniform( "uRGBDelta", rgbDelta );
478
479  return shaderEffect;
480 }
481
482 void NewWindowController::NewWindow(void)
483 {
484   PositionSize posSize(0, 0, 720, 1280);
485   gApplication.ReplaceWindow(posSize, "NewWindow"); // Generates a new window
486 }
487
488 bool NewWindowController::OnLoseContextButtonClicked( Toolkit::Button button )
489 {
490   // Add as an idle callback to avoid ProcessEvents being recursively called.
491   mApplication.AddIdle( MakeCallback( NewWindowController::NewWindow ) );
492   return true;
493 }
494
495 bool NewWindowController::OnTrackTimerTick()
496 {
497   static int time=0;
498   const float radius(250.0f);
499
500   time += EMIT_INTERVAL_IN_MS;
501   float modTime = time / TRACK_DURATION_IN_MS;
502   float angle = 2.0f*Math::PI*modTime;
503
504   Vector2 position(radius*cosf(angle), radius*-sinf(angle));
505   Vector2 aimPos(radius*2*sinf(angle), radius*2*-cosf(angle));
506   Vector2 direction = aimPos-position;
507   Vector2 stageSize = Stage::GetCurrent().GetSize();
508
509   SetUpBubbleEmission( stageSize*0.5f+position, direction );
510   SetUpBubbleEmission( stageSize*0.5f+position*0.75f, direction );
511   SetUpBubbleEmission( stageSize*0.5f+position*0.7f, direction );
512
513   return true;
514 }
515
516 void NewWindowController::OnKeyEvent(const KeyEvent& event)
517 {
518   if(event.state == KeyEvent::Down)
519   {
520     if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
521     {
522       mApplication.Quit();
523     }
524   }
525 }
526
527 void NewWindowController::OnContextLost()
528 {
529   printf("Stage reporting context loss\n");
530 }
531
532 void NewWindowController::OnContextRegained()
533 {
534   printf("Stage reporting context regain\n");
535 }
536
537 void RunTest(Application& app)
538 {
539   gNewWindowController = new NewWindowController(app);
540   app.MainLoop(Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
541 }
542
543 // Entry point for Linux & Tizen applications
544 //
545 int main(int argc, char **argv)
546 {
547   gApplication = Application::New(&argc, &argv, DALI_DEMO_THEME_PATH);
548   RunTest(gApplication);
549
550   return 0;
551 }