Updated demos to use DALi clang-format
[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-toolkit/dali-toolkit.h>
20 #include <dali/devel-api/actors/actor-devel.h>
21
22 // INTERNAL INCLUDES
23 #include "shared/view.h"
24
25 using namespace Dali;
26
27 namespace
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     mediump vec4 vertexPosition = vec4(mix(aInitPos, aFinalPos, uDelta), 0.0, 1.0);
43     vertexPosition.xyz *= uSize;
44     vertexPosition = uMvpMatrix * vertexPosition;
45     gl_Position    = vertexPosition;
46     vColor         = vec4(aColor, 0.) * uColor;
47   });
48
49 const char* FRAGMENT_SHADER = MAKE_SHADER(
50   varying lowp vec4 vColor;
51
52   void main() {
53     gl_FragColor = vColor;
54   });
55
56 Geometry CreateGeometry()
57 {
58   // Create vertices
59   struct VertexPosition
60   {
61     Vector2 position;
62   };
63   struct VertexColor
64   {
65     Vector3 color;
66   };
67
68   VertexPosition quad[] = {
69     // yellow
70     {Vector2(-.5, -.5)},
71     {Vector2(.0, .0)},
72     {Vector2(-.5, .5)},
73
74     // green
75     {Vector2(-.5, -.5)},
76     {Vector2(.5, -.5)},
77     {Vector2(.0, .0)},
78
79     // blue
80     {Vector2(.5, -.5)},
81     {Vector2(.5, .0)},
82     {Vector2(.25, -.25)},
83
84     // red
85     {Vector2(.25, -.25)},
86     {Vector2(.5, .0)},
87     {Vector2(.25, .25)},
88     {Vector2(.25, .25)},
89     {Vector2(.0, .0)},
90     {Vector2(.25, -.25)},
91
92     // cyan
93     {Vector2(.0, .0)},
94     {Vector2(.25, .25)},
95     {Vector2(-.25, .25)},
96
97     // magenta
98     {Vector2(-.25, .25)},
99     {Vector2(.25, .25)},
100     {Vector2(.0, .5)},
101     {Vector2(.0, .5)},
102     {Vector2(-.5, .5)},
103     {Vector2(-.25, .25)},
104
105     // orange
106     {Vector2(.5, .0)},
107     {Vector2(.5, .5)},
108     {Vector2(.0, .5)},
109   };
110
111   float bigSide = 0.707106781;
112   float side    = bigSide * .5f;
113   // float smallSide = side * .5f;
114
115   Vector2 pA  = Vector2(side, .25);
116   Vector2 pB  = pA + Vector2(0., bigSide);
117   Vector2 pC  = pB + Vector2(-bigSide, 0.);
118   Vector2 pD  = pA + Vector2(-.5, -.5);
119   Vector2 pE  = pD + Vector2(.0, 1.);
120   Vector2 pF  = pD + Vector2(-side, side);
121   Vector2 pF2 = pD + Vector2(0., bigSide);
122   Vector2 pG  = pD + Vector2(-.25, .25);
123   Vector2 pH  = pD + Vector2(-.5, .0);
124   Vector2 pI  = pD + Vector2(-.25, -.25);
125   Vector2 pJ  = pD + Vector2(0., -.5);
126   Vector2 pK  = pD + Vector2(-.5, -.5);
127   Vector2 pL  = pB + Vector2(0, -side);
128   Vector2 pM  = pL + Vector2(side, -side);
129   Vector2 pN  = pB + Vector2(side, -side);
130
131   VertexPosition cat[] = {
132     // yellow
133     {pA},
134     {pB},
135     {pC},
136
137     // green
138     {pD},
139     {pA},
140     {pE},
141
142     // blue
143     {pJ},
144     {pD},
145     {pI},
146
147     // red
148     {pI},
149     {pD},
150     {pG},
151     {pG},
152     {pH},
153     {pI},
154
155     // cyan
156     {pI},
157     {pH},
158     {pK},
159
160     // magenta
161     {pL},
162     {pM},
163     {pN},
164     {pN},
165     {pB},
166     {pL},
167
168     // orange
169     {pD},
170     {pF2},
171     {pF},
172   };
173
174   VertexColor colors[] = {
175     // yellow
176     {Vector3(1., 1., 0.)},
177     {Vector3(1., 1., 0.)},
178     {Vector3(1., 1., 0.)},
179
180     // green
181     {Vector3(0., 1., 0.)},
182     {Vector3(0., 1., 0.)},
183     {Vector3(0., 1., 0.)},
184
185     // blue
186     {Vector3(0., 0., 1.)},
187     {Vector3(0., 0., 1.)},
188     {Vector3(0., 0., 1.)},
189
190     // red
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     {Vector3(1., 0., 0.)},
197
198     // cyan
199     {Vector3(0., 1., 1.)},
200     {Vector3(0., 1., 1.)},
201     {Vector3(0., 1., 1.)},
202
203     // magenta
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     {Vector3(1., 0., 1.)},
210
211     // orange
212     {Vector3(1., 0.5, 0.)},
213     {Vector3(1., 0.5, 0.)},
214     {Vector3(1., 0.5, 0.)},
215
216   };
217
218   unsigned int numberOfVertices = sizeof(quad) / sizeof(VertexPosition);
219
220   Property::Map initialPositionVertexFormat;
221   initialPositionVertexFormat["aInitPos"] = Property::VECTOR2;
222   VertexBuffer initialPositionVertices    = VertexBuffer::New(initialPositionVertexFormat);
223   initialPositionVertices.SetData(quad, numberOfVertices);
224
225   Property::Map finalPositionVertexFormat;
226   finalPositionVertexFormat["aFinalPos"] = Property::VECTOR2;
227   VertexBuffer finalPositionVertices     = VertexBuffer::New(finalPositionVertexFormat);
228   finalPositionVertices.SetData(cat, numberOfVertices);
229
230   Property::Map colorVertexFormat;
231   colorVertexFormat["aColor"] = Property::VECTOR3;
232   VertexBuffer colorVertices  = VertexBuffer::New(colorVertexFormat);
233   colorVertices.SetData(colors, numberOfVertices);
234
235   // Create the geometry object
236   Geometry texturedQuadGeometry = Geometry::New();
237   texturedQuadGeometry.AddVertexBuffer(initialPositionVertices);
238   texturedQuadGeometry.AddVertexBuffer(finalPositionVertices);
239   texturedQuadGeometry.AddVertexBuffer(colorVertices);
240
241   return texturedQuadGeometry;
242 }
243
244 inline float StationarySin(float progress) ///< Single revolution
245 {
246   float val = cosf(progress * 2.0f * Math::PI) + .5f;
247   val       = val > 1.f ? 1.f : val;
248   val       = val < 0.f ? 0.f : val;
249   return val;
250 }
251
252 } // anonymous namespace
253
254 // This example shows how to use a simple mesh
255 //
256 class ExampleController : public ConnectionTracker
257 {
258 public:
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.GetState() == 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   Application& mApplication; ///< Application instance
340   Vector3      mWindowSize;  ///< The size of the window
341
342   Shader   mShader;
343   Geometry mGeometry;
344   Renderer mRenderer;
345   Actor    mMeshActor;
346   Timer    mMorphTimer;
347 };
348
349 int DALI_EXPORT_API main(int argc, char** argv)
350 {
351   Application       application = Application::New(&argc, &argv);
352   ExampleController test(application);
353   application.MainLoop();
354   return 0;
355 }