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