Using migrated Public Visual API
[platform/core/uifw/dali-demo.git] / examples / mesh-morph / mesh-morph-example.cpp
1 /*
2  * Copyright (c) 2017 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 <dali-toolkit/dali-toolkit.h>
20
21 // INTERNAL INCLUDES
22 #include "shared/view.h"
23
24 using namespace Dali;
25
26 namespace
27 {
28
29 #define MAKE_SHADER(A)#A
30
31 const char* VERTEX_SHADER = MAKE_SHADER(
32 attribute mediump vec2    aInitPos;
33 attribute mediump vec2    aFinalPos;
34 attribute mediump vec3    aColor;
35 uniform   mediump mat4    uMvpMatrix;
36 uniform   mediump vec3    uSize;
37 uniform   mediump float   uDelta;
38 uniform   lowp    vec4    uColor;
39 varying   lowp    vec4    vColor;
40
41 void main()
42 {
43   mediump vec4 vertexPosition = vec4(mix(aInitPos, aFinalPos, uDelta), 0.0, 1.0);
44   vertexPosition.xyz *= uSize;
45   vertexPosition = uMvpMatrix * vertexPosition;
46   gl_Position = vertexPosition;
47   vColor = vec4(aColor, 0.) * uColor;
48 }
49 );
50
51 const char* FRAGMENT_SHADER = MAKE_SHADER(
52 varying   lowp    vec4    vColor;
53
54 void main()
55 {
56   gl_FragColor = vColor;
57 }
58 );
59
60 Geometry CreateGeometry()
61 {
62   // Create vertices
63   struct VertexPosition { Vector2 position; };
64   struct VertexColor { Vector3 color; };
65
66   VertexPosition quad[] = {
67     // yellow
68     { Vector2(-.5, -.5) },
69     { Vector2( .0,  .0) },
70     { Vector2(-.5,  .5) },
71
72     // green
73     { Vector2(-.5, -.5) },
74     { Vector2( .5, -.5) },
75     { Vector2( .0,  .0) },
76
77     // blue
78     { Vector2(.5,  -.5)  },
79     { Vector2(.5,   .0)  },
80     { Vector2(.25, -.25) },
81
82     // red
83     { Vector2(.25, -.25) },
84     { Vector2(.5,   .0)  },
85     { Vector2(.25,  .25) },
86     { Vector2(.25,  .25) },
87     { Vector2(.0,   .0)  },
88     { Vector2(.25, -.25) },
89
90     // cyan
91     { Vector2( .0,  .0)  },
92     { Vector2( .25, .25) },
93     { Vector2(-.25, .25) },
94
95     // magenta
96     { Vector2(-.25, .25) },
97     { Vector2( .25, .25) },
98     { Vector2( .0,  .5)  },
99     { Vector2( .0,  .5)  },
100     { Vector2(-.5,  .5)  },
101     { Vector2(-.25, .25) },
102
103     // orange
104     { Vector2( .5, .0) },
105     { Vector2( .5, .5) },
106     { Vector2( .0, .5) },
107   };
108
109   float bigSide = 0.707106781;
110   float side = bigSide * .5f;
111  // float smallSide = side * .5f;
112
113   Vector2 pA = Vector2( side, .25 );
114   Vector2 pB = pA + Vector2( 0., bigSide );
115   Vector2 pC = pB + Vector2( -bigSide, 0. );
116   Vector2 pD = pA + Vector2(-.5, -.5 );
117   Vector2 pE = pD + Vector2( .0, 1. );
118   Vector2 pF = pD + Vector2(-side, side );
119   Vector2 pF2 = pD + Vector2( 0., bigSide );
120   Vector2 pG = pD + Vector2(-.25, .25 );
121   Vector2 pH = pD + Vector2( -.5, .0 );
122   Vector2 pI = pD + Vector2(-.25, -.25 );
123   Vector2 pJ = pD + Vector2( 0., -.5);
124   Vector2 pK = pD + Vector2(-.5, -.5);
125   Vector2 pL = pB + Vector2(0, -side);
126   Vector2 pM = pL + Vector2(side, -side);
127   Vector2 pN = pB + Vector2(side, -side);
128
129   VertexPosition cat[] = {
130     // yellow
131     { pA },
132     { pB },
133     { pC },
134
135     // green
136     { pD },
137     { pA },
138     { pE },
139
140     // blue
141     { pJ },
142     { pD },
143     { pI },
144
145     // red
146     { pI },
147     { pD },
148     { pG },
149     { pG },
150     { pH },
151     { pI },
152
153     // cyan
154     { pI },
155     { pH },
156     { pK },
157
158     // magenta
159     { pL },
160     { pM },
161     { pN },
162     { pN },
163     { pB },
164     { pL },
165
166     // orange
167     { pD },
168     { pF2 },
169     { pF },
170   };
171
172   VertexColor colors[] = {
173     // yellow
174     { Vector3( 1., 1., 0. ) },
175     { Vector3( 1., 1., 0. ) },
176     { Vector3( 1., 1., 0. ) },
177
178     // green
179     { Vector3( 0., 1., 0. ) },
180     { Vector3( 0., 1., 0. ) },
181     { Vector3( 0., 1., 0. ) },
182
183     // blue
184     { Vector3( 0., 0., 1. ) },
185     { Vector3( 0., 0., 1. ) },
186     { Vector3( 0., 0., 1. ) },
187
188     // red
189     { Vector3( 1., 0., 0. ) },
190     { Vector3( 1., 0., 0. ) },
191     { Vector3( 1., 0., 0. ) },
192     { Vector3( 1., 0., 0. ) },
193     { Vector3( 1., 0., 0. ) },
194     { Vector3( 1., 0., 0. ) },
195
196     // cyan
197     { Vector3( 0., 1., 1. ) },
198     { Vector3( 0., 1., 1. ) },
199     { Vector3( 0., 1., 1. ) },
200
201     // magenta
202     { Vector3( 1., 0., 1. ) },
203     { Vector3( 1., 0., 1. ) },
204     { Vector3( 1., 0., 1. ) },
205     { Vector3( 1., 0., 1. ) },
206     { Vector3( 1., 0., 1. ) },
207     { Vector3( 1., 0., 1. ) },
208
209     // orange
210     { Vector3( 1., 0.5, 0. ) },
211     { Vector3( 1., 0.5, 0. ) },
212     { Vector3( 1., 0.5, 0. ) },
213
214   };
215
216   unsigned int numberOfVertices = sizeof(quad)/sizeof(VertexPosition);
217
218   Property::Map initialPositionVertexFormat;
219   initialPositionVertexFormat["aInitPos"] = Property::VECTOR2;
220   PropertyBuffer initialPositionVertices = PropertyBuffer::New( initialPositionVertexFormat );
221   initialPositionVertices.SetData( quad, numberOfVertices );
222
223   Property::Map finalPositionVertexFormat;
224   finalPositionVertexFormat["aFinalPos"] = Property::VECTOR2;
225   PropertyBuffer finalPositionVertices = PropertyBuffer::New( finalPositionVertexFormat );
226   finalPositionVertices.SetData( cat, numberOfVertices );
227
228   Property::Map colorVertexFormat;
229   colorVertexFormat["aColor"] = Property::VECTOR3;
230   PropertyBuffer colorVertices = PropertyBuffer::New( colorVertexFormat );
231   colorVertices.SetData( colors, numberOfVertices );
232
233   // Create the geometry object
234   Geometry texturedQuadGeometry = Geometry::New();
235   texturedQuadGeometry.AddVertexBuffer( initialPositionVertices );
236   texturedQuadGeometry.AddVertexBuffer( finalPositionVertices );
237   texturedQuadGeometry.AddVertexBuffer( colorVertices );
238
239   return texturedQuadGeometry;
240 }
241
242 inline float StationarySin( float progress ) ///< Single revolution
243 {
244   float val = cosf(progress * 2.0f * Math::PI) + .5f;
245   val = val > 1.f ? 1.f : val;
246   val = val < 0.f ? 0.f : val;
247   return val;
248 }
249
250 } // anonymous namespace
251
252 // This example shows how to use a simple mesh
253 //
254 class ExampleController : public ConnectionTracker
255 {
256 public:
257
258   /**
259    * The example controller constructor.
260    * @param[in] application The application instance
261    */
262   ExampleController( Application& application )
263   : mApplication( application )
264   {
265     // Connect to the Application's Init signal
266     mApplication.InitSignal().Connect( this, &ExampleController::Create );
267   }
268
269   /**
270    * The example controller destructor
271    */
272   ~ExampleController()
273   {
274     // Nothing to do here;
275   }
276
277   /**
278    * Invoked upon creation of application
279    * @param[in] application The application instance
280    */
281   void Create( Application& application )
282   {
283     Stage stage = Stage::GetCurrent();
284     stage.KeyEventSignal().Connect(this, &ExampleController::OnKeyEvent);
285
286     mStageSize = stage.GetSize();
287
288     // The Init signal is received once (only) during the Application lifetime
289
290     // Hide the indicator bar
291     application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
292
293     mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
294     mGeometry = CreateGeometry();
295     mRenderer = Renderer::New( mGeometry, mShader );
296
297     mMeshActor = Actor::New();
298     mMeshActor.AddRenderer( mRenderer );
299     mMeshActor.SetSize(400, 400);
300
301     Property::Index morphDeltaIndex = mMeshActor.RegisterProperty( "uDelta", 0.f );
302
303     mRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, 0 );
304
305     mMeshActor.SetParentOrigin( ParentOrigin::CENTER );
306     mMeshActor.SetAnchorPoint( AnchorPoint::CENTER );
307     stage.Add( mMeshActor );
308
309     Animation  animation = Animation::New(10);
310     animation.AnimateTo( Property( mMeshActor, morphDeltaIndex ), 1.f, StationarySin );
311     animation.SetLooping( true );
312     animation.Play();
313
314     stage.SetBackgroundColor(Vector4(0.0f, 0.2f, 0.2f, 1.0f));
315   }
316
317   /**
318    * Invoked whenever the quit button is clicked
319    * @param[in] button the quit button
320    */
321   bool OnQuitButtonClicked( Toolkit::Button button )
322   {
323     // quit the application
324     mApplication.Quit();
325     return true;
326   }
327
328   void OnKeyEvent(const KeyEvent& event)
329   {
330     if(event.state == KeyEvent::Down)
331     {
332       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
333       {
334         mApplication.Quit();
335       }
336     }
337   }
338
339 private:
340
341   Application&  mApplication;                             ///< Application instance
342   Vector3 mStageSize;                                     ///< The size of the stage
343
344   Shader   mShader;
345   Geometry mGeometry;
346   Renderer mRenderer;
347   Actor    mMeshActor;
348   Timer    mMorphTimer;
349 };
350
351 void RunTest( Application& application )
352 {
353   ExampleController test( application );
354
355   application.MainLoop();
356 }
357
358 // Entry point for Linux & SLP applications
359 //
360 int DALI_EXPORT_API main( int argc, char **argv )
361 {
362   Application application = Application::New( &argc, &argv );
363
364   RunTest( application );
365
366   return 0;
367 }