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