35bbc399dcccd8451fdee7c9ea1094009468fb5c
[platform/core/uifw/dali-demo.git] / examples / mesh-morph / mesh-morph-example.cpp
1 /*
2  * Copyright (c) 2020 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/devel-api/actors/actor-devel.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   VertexBuffer initialPositionVertices = VertexBuffer::New( initialPositionVertexFormat );
222   initialPositionVertices.SetData( quad, numberOfVertices );
223
224   Property::Map finalPositionVertexFormat;
225   finalPositionVertexFormat["aFinalPos"] = Property::VECTOR2;
226   VertexBuffer finalPositionVertices = VertexBuffer::New( finalPositionVertexFormat );
227   finalPositionVertices.SetData( cat, numberOfVertices );
228
229   Property::Map colorVertexFormat;
230   colorVertexFormat["aColor"] = Property::VECTOR3;
231   VertexBuffer colorVertices = VertexBuffer::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     Window window = application.GetWindow();
285     window.KeyEventSignal().Connect(this, &ExampleController::OnKeyEvent);
286
287     mWindowSize = window.GetSize();
288
289     // The Init signal is received once (only) during the Application lifetime
290
291     mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
292     mGeometry = CreateGeometry();
293     mRenderer = Renderer::New( mGeometry, mShader );
294
295     mMeshActor = Actor::New();
296     mMeshActor.AddRenderer( mRenderer );
297     mMeshActor.SetProperty( Actor::Property::SIZE, Vector2(400, 400) );
298     mMeshActor.SetProperty( DevelActor::Property::UPDATE_SIZE_HINT, Vector2(480, 700) );
299
300     Property::Index morphDeltaIndex = mMeshActor.RegisterProperty( "uDelta", 0.f );
301
302     mRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, 0 );
303
304     mMeshActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
305     mMeshActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
306     window.Add( mMeshActor );
307
308     Animation  animation = Animation::New(10);
309     animation.AnimateTo( Property( mMeshActor, morphDeltaIndex ), 1.f, StationarySin );
310     animation.SetLooping( true );
311     animation.Play();
312
313     window.SetBackgroundColor(Vector4(0.0f, 0.2f, 0.2f, 1.0f));
314   }
315
316   /**
317    * Invoked whenever the quit button is clicked
318    * @param[in] button the quit button
319    */
320   bool OnQuitButtonClicked( Toolkit::Button button )
321   {
322     // quit the application
323     mApplication.Quit();
324     return true;
325   }
326
327   void OnKeyEvent(const KeyEvent& event)
328   {
329     if(event.state == KeyEvent::Down)
330     {
331       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
332       {
333         mApplication.Quit();
334       }
335     }
336   }
337
338 private:
339
340   Application&  mApplication;                             ///< Application instance
341   Vector3 mWindowSize;                                     ///< The size of the window
342
343   Shader   mShader;
344   Geometry mGeometry;
345   Renderer mRenderer;
346   Actor    mMeshActor;
347   Timer    mMorphTimer;
348 };
349
350 int DALI_EXPORT_API main( int argc, char **argv )
351 {
352   Application application = Application::New( &argc, &argv );
353   ExampleController test( application );
354   application.MainLoop();
355   return 0;
356 }