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