2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali/dali.h>
19 #include <dali-toolkit/dali-toolkit.h>
20 #include "shared/view.h"
25 using namespace Dali::Toolkit;
30 const char* APPLICATION_TITLE("Animated Shapes");
32 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER
34 attribute mediump vec3 aCoefficient;
35 uniform mediump mat4 uMvpMatrix;
36 uniform mediump vec3 uPosition[MAX_POINT_COUNT];
37 varying lowp vec2 vCoefficient;
40 int vertexId = int(aCoefficient.z);
41 gl_Position = uMvpMatrix * vec4(uPosition[vertexId], 1.0);
43 vCoefficient = aCoefficient.xy;
48 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER
50 uniform lowp vec4 uColor;
51 varying lowp vec2 vCoefficient;
54 lowp float C = (vCoefficient.x*vCoefficient.x-vCoefficient.y);
55 lowp float Cdx = dFdx(C);
56 lowp float Cdy = dFdy(C);
58 lowp float distance = float(C / sqrt(Cdx*Cdx + Cdy*Cdy));
59 lowp float alpha = 0.5 - distance;
60 gl_FragColor = vec4( uColor.rgb, uColor.a * alpha );
64 Shader CreateShader( unsigned int pointCount )
66 std::ostringstream vertexShader;
67 vertexShader << "#define MAX_POINT_COUNT "<< pointCount << "\n"<<VERTEX_SHADER;
69 std::ostringstream fragmentShader;
70 fragmentShader << "#extension GL_OES_standard_derivatives : enable "<< "\n"<<FRAGMENT_SHADER;
72 Shader shader = Shader::New( vertexShader.str(), fragmentShader.str() );
73 for( unsigned int i(0); i<pointCount; ++i )
75 std::ostringstream propertyName;
76 propertyName << "uPosition["<<i<<"]";
77 shader.RegisterProperty(propertyName.str(),Vector3(0.0f,0.0f,0.0f) );
85 // This example shows resolution independent rendering and animation of curves using the gpu.
87 class AnimatedShapesExample : public ConnectionTracker
91 AnimatedShapesExample( Application& application )
92 : mApplication( application )
94 // Connect to the Application's Init signal
95 mApplication.InitSignal().Connect( this, &AnimatedShapesExample::Create );
98 ~AnimatedShapesExample() = default;
100 // The Init signal is received once (only) during the Application lifetime
101 void Create( Application& application )
103 Window window = application.GetWindow();
104 const Vector2 windowSize = window.GetSize();
106 // Creates the background gradient
107 Toolkit::Control background = Dali::Toolkit::Control::New();
108 background[Actor::Property::ANCHOR_POINT] = Dali::AnchorPoint::CENTER;
109 background[Actor::Property::PARENT_ORIGIN] = Dali::ParentOrigin::CENTER;
110 background.SetResizePolicy( Dali::ResizePolicy::FILL_TO_PARENT, Dali::Dimension::ALL_DIMENSIONS );
112 Dali::Property::Map map;
113 map.Insert( Toolkit::Visual::Property::TYPE, Visual::GRADIENT );
114 Property::Array stopOffsets;
115 stopOffsets.PushBack( 0.0f );
116 stopOffsets.PushBack( 1.0f );
117 map.Insert( GradientVisual::Property::STOP_OFFSET, stopOffsets );
118 Property::Array stopColors;
119 stopColors.PushBack( Vector4( 0.0f,0.0f,1.0f,1.0f ) );
120 stopColors.PushBack( Vector4( 1.0f,1.0f,1.0f,1.0f ) );
121 map.Insert( GradientVisual::Property::STOP_COLOR, stopColors );
122 Vector2 halfWindowSize = windowSize * 0.5f;
123 map.Insert( GradientVisual::Property::START_POSITION, Vector2(0.0f,-halfWindowSize.y) );
124 map.Insert( GradientVisual::Property::END_POSITION, Vector2(0.0f,halfWindowSize.y) );
125 map.Insert( GradientVisual::Property::UNITS, GradientVisual::Units::USER_SPACE );
126 background[ Dali::Toolkit::Control::Property::BACKGROUND ] = map;
127 window.Add( background );
129 // Create a TextLabel for the application title.
130 Toolkit::TextLabel label = Toolkit::TextLabel::New( APPLICATION_TITLE );
131 label[ Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_CENTER ;
132 label[ Actor::Property::PARENT_ORIGIN] = Vector3( 0.5f, 0.0f, 0.5f );
133 label[ Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT ] = "CENTER";
134 label[ Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT] = "CENTER";
135 label[ Toolkit::TextLabel::Property::TEXT_COLOR ] = Color::WHITE;
138 CreateTriangleMorph(Vector3( windowSize.x*0.5f, windowSize.y*0.15f, 0.0f), 100.0f );
139 CreateCircleMorph( Vector3( windowSize.x*0.5f, windowSize.y*0.5f, 0.0f), 55.0f );
140 CreateQuadMorph( Vector3( windowSize.x*0.5f, windowSize.y*0.85f, 0.0f), 60.0f );
142 window.KeyEventSignal().Connect( this, &AnimatedShapesExample::OnKeyEvent );
145 void CreateTriangleMorph( Vector3 center, float side )
147 float h = ( side *0.5f ) / 0.866f;
149 Vector3 v0 = Vector3( -h, h, 0.0f );
150 Vector3 v1 = Vector3( 0.0f, -side * 0.366f, 0.0f );
151 Vector3 v2 = Vector3( h, h, 0.0f );
153 Vector3 v3 = v0 + ( ( v1 - v0 ) * 0.5f );
154 Vector3 v4 = v1 + ( ( v2 - v1 ) * 0.5f );
155 Vector3 v5 = v2 + ( ( v0 - v2 ) * 0.5f );
157 Shader shader = CreateShader( 12 );
158 shader[ "uPosition[0]"] = v0;
159 shader[ "uPosition[1]"] = v3;
160 shader[ "uPosition[2]"] = v1;
162 shader[ "uPosition[3]"] = v1;
163 shader[ "uPosition[4]"] = v4;
164 shader[ "uPosition[5]"] = v2;
166 shader[ "uPosition[6]"] = v2;
167 shader[ "uPosition[7]"] = v5;
168 shader[ "uPosition[8]"] = v0;
170 shader[ "uPosition[9]"] = v0;
171 shader[ "uPosition[10]"] = v1;
172 shader[ "uPosition[11]"] = v2;
176 static const Vector3 vertexData[] = { Dali::Vector3( 0.0f, 0.0f, 0.0f ),
177 Dali::Vector3( 0.5f, 0.0f, 1.0f ),
178 Dali::Vector3( 1.0f, 1.0f, 2.0f ),
180 Dali::Vector3( 0.0f, 0.0f, 3.0f ),
181 Dali::Vector3( 0.5f, 0.0f, 4.0f ),
182 Dali::Vector3( 1.0f, 1.0f, 5.0f ),
184 Dali::Vector3( 0.0f, 0.0f, 6.0f ),
185 Dali::Vector3( 0.5f, 0.0f, 7.0f ),
186 Dali::Vector3( 1.0f, 1.0f, 8.0f ),
188 Dali::Vector3( 0.0f, 1.0f, 9.0f ),
189 Dali::Vector3( 0.0f, 1.0f, 10.0f ),
190 Dali::Vector3( 0.0f, 1.0f, 11.0f )
193 unsigned short indexData[] = { 0, 2, 1, 3, 5, 4, 6, 8, 7, 9, 11, 10 };
195 //Create a vertex buffer for vertex positions and texture coordinates
196 Dali::Property::Map vertexFormat;
197 vertexFormat["aCoefficient"] = Dali::Property::VECTOR3;
198 Dali::PropertyBuffer vertexBuffer = Dali::PropertyBuffer::New( vertexFormat );
199 vertexBuffer.SetData( vertexData, sizeof(vertexData)/sizeof(vertexData[0]));
201 //Create the geometry
202 Dali::Geometry geometry = Dali::Geometry::New();
203 geometry.AddVertexBuffer( vertexBuffer );
204 geometry.SetIndexBuffer( indexData, sizeof(indexData)/sizeof(indexData[0]) );
206 Renderer renderer = Renderer::New( geometry, shader );
207 renderer[Renderer::Property::BLEND_MODE] = BlendMode::ON;
209 Actor actor = Actor::New();
210 actor[Actor::Property::SIZE ] = Vector2( 400.0f, 400.0f );
211 actor[Actor::Property::POSITION ] = center;
212 actor[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
213 actor[Actor::Property::COLOR] = Color::WHITE;
214 actor.AddRenderer( renderer );
216 Window window = mApplication.GetWindow();
220 Animation animation = Animation::New(5.0f);
221 KeyFrames k0 = KeyFrames::New();
223 k0.Add( 0.5f, v3 + Vector3(-150.0f,-150.0f,0.0f));
225 animation.AnimateBetween( Property(shader, "uPosition[1]"),k0, AlphaFunction::EASE_IN_OUT_SINE );
227 k0 = KeyFrames::New();
229 k0.Add( 0.5f, v4 + Vector3(150.0f,-150.0f,0.0f));
231 animation.AnimateBetween( Property(shader,"uPosition[4]"),k0, AlphaFunction::EASE_IN_OUT_SINE );
233 k0 = KeyFrames::New();
235 k0.Add( 0.5f, v5 + Vector3(0.0,150.0f,0.0f));
237 animation.AnimateBetween( Property(shader, "uPosition[7]"),k0, AlphaFunction::EASE_IN_OUT_SINE );
238 animation.SetLooping( true );
242 void CreateCircleMorph( Vector3 center, float radius )
244 Shader shader = CreateShader( 16 );
245 shader["uPosition[0]"] = Vector3( -radius, -radius, 0.0f );
246 shader["uPosition[1]"] = Vector3( 0.0f, -radius, 0.0f );
247 shader["uPosition[2]"] = Vector3( radius, -radius, 0.0f );
249 shader["uPosition[3]"] = Vector3( radius, -radius, 0.0f );
250 shader["uPosition[4]"] = Vector3( radius, 0.0f, 0.0f );
251 shader["uPosition[5]"] = Vector3( radius, radius, 0.0f );
253 shader["uPosition[6]"] = Vector3( radius, radius, 0.0f );
254 shader["uPosition[7]"] = Vector3( 0.0f, radius, 0.0f );
255 shader["uPosition[8]"] = Vector3( -radius, radius, 0.0f );
257 shader["uPosition[9]"] = Vector3( -radius, radius, 0.0f );
258 shader["uPosition[10]"] = Vector3( -radius, 0.0f, 0.0f );
259 shader["uPosition[11]"] = Vector3( -radius, -radius, 0.0f );
261 shader["uPosition[12]"] = Vector3( -radius, -radius, 0.0f );
262 shader["uPosition[13]"] = Vector3( radius, -radius, 0.0f );
263 shader["uPosition[14]"] = Vector3( radius, radius, 0.0f );
264 shader["uPosition[15]"] = Vector3( -radius, radius, 0.0f );
266 //shader["uLineWidth"), 2.0] ;
268 static const Vector3 vertexData[] = { Vector3( 0.0f, 0.0f, 0.0f ),
269 Vector3( 0.5f, 0.0f, 1.0f ),
270 Vector3( 1.0f, 1.0f, 2.0f ),
271 Vector3( 0.0f, 0.0f, 3.0f ),
272 Vector3( 0.5f, 0.0f, 4.0f ),
273 Vector3( 1.0f, 1.0f, 5.0f ),
274 Vector3( 0.0f, 0.0f, 6.0f ),
275 Vector3( 0.5f, 0.0f, 7.0f ),
276 Vector3( 1.0f, 1.0f, 8.0f ),
277 Vector3( 0.0f, 0.0f, 9.0f ),
278 Vector3( 0.5f, 0.0f, 10.0f ),
279 Vector3( 1.0f, 1.0f, 11.0f ),
280 Vector3( 0.0f, 1.0f, 12.0f ),
281 Vector3( 0.0f, 1.0f, 13.0f ),
282 Vector3( 0.0f, 1.0f, 14.0f ),
283 Vector3( 0.0f, 1.0f, 15.0f )};
285 short unsigned int indexData[] = { 0, 2, 1, 3, 5, 4, 6, 8, 7, 9, 11, 10, 12, 13, 14, 12, 14, 15 };
287 //Create a vertex buffer for vertex positions and texture coordinates
288 Dali::Property::Map vertexFormat;
289 vertexFormat["aCoefficient"] = Dali::Property::VECTOR3;
290 Dali::PropertyBuffer vertexBuffer = Dali::PropertyBuffer::New( vertexFormat );
291 vertexBuffer.SetData( vertexData, sizeof(vertexData)/sizeof(vertexData[0]));
293 //Create the geometry
294 Dali::Geometry geometry = Dali::Geometry::New();
295 geometry.AddVertexBuffer( vertexBuffer );
296 geometry.SetIndexBuffer( indexData, sizeof(indexData)/sizeof(indexData[0]) );
298 Renderer renderer = Renderer::New( geometry, shader );
299 renderer[ Renderer::Property::BLEND_MODE ] = BlendMode::ON;
301 Actor actor = Actor::New();
302 actor[ Actor::Property::SIZE] = Vector2( 400.0f, 400.0f );
303 actor[ Actor::Property::POSITION] = center;
304 actor[ Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
305 actor.AddRenderer( renderer );
307 Window window = mApplication.GetWindow();
311 Animation animation = Animation::New(5.0f);
312 KeyFrames k0 = KeyFrames::New();
313 k0.Add( 0.0f, Vector3( 0.0f,-radius*1.85, 0.0f ) );
314 k0.Add( 0.5f, Vector3( -radius*1.85, -radius*3.0f, 0.0f ) );
315 k0.Add( 1.0f, Vector3( 0.0f,-radius*1.85, 0.0f ) );
316 animation.AnimateBetween( Property( shader, shader.GetPropertyIndex("uPosition[1]") ),k0, AlphaFunction::EASE_IN_OUT_SINE );
318 k0 = KeyFrames::New();
319 k0.Add( 0.0f, Vector3( radius*1.85, 0.0f, 0.0f ) );
320 k0.Add( 0.5f, Vector3( radius*3.0f,-radius*1.85, 0.0f ) );
321 k0.Add( 1.0f, Vector3( radius*1.85,0.0f, 0.0f ) );
322 animation.AnimateBetween( Property(shader, shader.GetPropertyIndex("uPosition[4]")),k0, AlphaFunction::EASE_IN_OUT_SINE );
324 k0 = KeyFrames::New();
325 k0.Add( 0.0f, Vector3( 0.0f, radius*1.85, 0.0f ) );
326 k0.Add( 0.5f, Vector3( radius*1.85, radius*3.0f, 0.0f) );
327 k0.Add( 1.0f, Vector3( 0.0f, radius*1.85, 0.0f) );
328 animation.AnimateBetween( Property( shader, shader.GetPropertyIndex("uPosition[7]") ),k0, AlphaFunction::EASE_IN_OUT_SINE );
330 k0 = KeyFrames::New();
331 k0.Add( 0.0f, Vector3( -radius*1.85, 0.0f, 0.0f) );
332 k0.Add( 0.5f, Vector3(-radius*3.0f, radius*1.85, 0.0f) );
333 k0.Add( 1.0f, Vector3( -radius*1.85, 0.0f, 0.0f) );
334 animation.AnimateBetween( Property( shader, shader.GetPropertyIndex("uPosition[10]") ),k0, AlphaFunction::EASE_IN_OUT_SINE );
336 animation.AnimateBy( Property( actor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree(-90.0f) ), Vector3::ZAXIS ) );
337 animation.SetLooping( true );
341 void CreateQuadMorph( Vector3 center, float radius )
343 Shader shader = CreateShader( 16 );
344 shader["uPosition[0]"] = Vector3( -radius, -radius, 0.0f );
345 shader["uPosition[1]"] = Vector3( 0.0f, -radius, 0.0f );
346 shader["uPosition[2]"] = Vector3( radius, -radius, 0.0f );
348 shader["uPosition[3]"] = Vector3( radius, -radius, 0.0f );
349 shader["uPosition[4]"] = Vector3( radius, 0.0f, 0.0f );
350 shader["uPosition[5]"] = Vector3( radius, radius, 0.0f );
352 shader["uPosition[6]"] = Vector3( radius, radius, 0.0f );
353 shader["uPosition[7]"] = Vector3( 0.0f, radius, 0.0f );
354 shader["uPosition[8]"] = Vector3( -radius, radius, 0.0f );
356 shader["uPosition[9]"] = Vector3( -radius, radius, 0.0f );
357 shader["uPosition[10]"] = Vector3( -radius, 0.0f, 0.0f );
358 shader["uPosition[11]"] = Vector3( -radius, -radius, 0.0f );
360 shader["uPosition[12]"] = Vector3( -radius, -radius, 0.0f );
361 shader["uPosition[13]"] = Vector3( radius, -radius, 0.0f );
362 shader["uPosition[14]"] = Vector3( radius, radius, 0.0f );
363 shader["uPosition[15]"] = Vector3( -radius, radius, 0.0f );
365 static const Vector3 vertexData[] = { Dali::Vector3( 0.0f, 0.0f, 0.0f ),
366 Dali::Vector3( 0.5f, 0.0f, 1.0f ),
367 Dali::Vector3( 1.0f, 1.0f, 2.0f ),
369 Dali::Vector3( 0.0f, 0.0f, 3.0f ),
370 Dali::Vector3( 0.5f, 0.0f, 4.0f ),
371 Dali::Vector3( 1.0f, 1.0f, 5.0f ),
373 Dali::Vector3( 0.0f, 0.0f, 6.0f ),
374 Dali::Vector3( 0.5f, 0.0f, 7.0f ),
375 Dali::Vector3( 1.0f, 1.0f, 8.0f ),
377 Dali::Vector3( 0.0f, 0.0f, 9.0f ),
378 Dali::Vector3( 0.5f, 0.0f, 10.0f ),
379 Dali::Vector3( 1.0f, 1.0f, 11.0f ),
381 Dali::Vector3( 0.0f, 1.0f, 12.0f ),
382 Dali::Vector3( 0.0f, 1.0f, 13.0f ),
383 Dali::Vector3( 0.0f, 1.0f, 14.0f ),
384 Dali::Vector3( 0.0f, 1.0f, 15.0f ) };
386 short unsigned int indexData[] = { 0, 2, 1, 3, 5, 4, 6, 8, 7, 9, 11, 10, 12, 15, 14, 12, 14, 13 };
388 //Create a vertex buffer for vertex positions and texture coordinates
389 Dali::Property::Map vertexFormat;
390 vertexFormat["aCoefficient"] = Dali::Property::VECTOR3;
391 Dali::PropertyBuffer vertexBuffer = Dali::PropertyBuffer::New( vertexFormat );
392 vertexBuffer.SetData( vertexData, sizeof(vertexData)/sizeof(vertexData[0]));
394 //Create the geometry
395 Dali::Geometry geometry = Dali::Geometry::New();
396 geometry.AddVertexBuffer( vertexBuffer );
397 geometry.SetIndexBuffer( indexData, sizeof(indexData)/sizeof(indexData[0]) );
399 Renderer renderer = Renderer::New( geometry, shader );
400 renderer[Renderer::Property::BLEND_MODE] = BlendMode::ON;
402 Actor actor = Actor::New();
403 actor[Actor::Property::SIZE] = Vector2( 400.0f, 400.0f );
404 actor[Actor::Property::POSITION] = center;
405 actor[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
406 actor[Actor::Property::COLOR] = Vector4(1.0f,0.0f,0.0f,1.0f);
407 actor.AddRenderer( renderer );
409 Window window = mApplication.GetWindow();
413 Animation animation = Animation::New( 5.0f );
414 KeyFrames k0 = KeyFrames::New();
415 k0.Add( 0.0f, Vector3( 0.0f, -radius, 0.0f ) );
416 k0.Add( 0.5f, Vector3( 0.0f, -radius*4.0f, 0.0f ) );
417 k0.Add( 1.0f, Vector3( 0.0f, -radius, 0.0f ) );
418 animation.AnimateBetween( Property(shader, shader.GetPropertyIndex("uPosition[1]")),k0, AlphaFunction::EASE_IN_OUT_SINE );
420 k0 = KeyFrames::New();
421 k0.Add( 0.0f, Vector3( radius, 0.0f, 0.0f ) );
422 k0.Add( 0.5f, Vector3( radius*4.0f, 0.0f, 0.0f ) );
423 k0.Add( 1.0f, Vector3( radius, 0.0f, 0.0f ) );
424 animation.AnimateBetween( Property(shader, shader.GetPropertyIndex("uPosition[4]")),k0, AlphaFunction::EASE_IN_OUT_SINE );
426 k0 = KeyFrames::New();
427 k0.Add( 0.0f, Vector3( 0.0f, radius, 0.0f ) );
428 k0.Add( 0.5f, Vector3( 0.0f, radius*4.0f, 0.0f ) );
429 k0.Add( 1.0f, Vector3( 0.0f, radius, 0.0f ) );
430 animation.AnimateBetween( Property(shader, shader.GetPropertyIndex("uPosition[7]")),k0, AlphaFunction::EASE_IN_OUT_SINE );
432 k0 = KeyFrames::New();
433 k0.Add( 0.0f, Vector3( -radius, 0.0f, 0.0f ) );
434 k0.Add( 0.5f, Vector3( -radius*4.0f,0.0f, 0.0f ) );
435 k0.Add( 1.0f, Vector3( -radius, 0.0f, 0.0f ) );
436 animation.AnimateBetween( Property(shader, shader.GetPropertyIndex("uPosition[10]")),k0, AlphaFunction::EASE_IN_OUT_SINE );
438 animation.AnimateBy( Property( actor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree(90.0f) ), Vector3::ZAXIS ) );
439 animation.SetLooping( true );
444 * Main key event handler
446 void OnKeyEvent(const KeyEvent& event)
448 if( event.GetState() == KeyEvent::Down && (IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK )) )
455 Application& mApplication;
459 int DALI_EXPORT_API main( int argc, char **argv )
461 Application application = Application::New( &argc, &argv );
462 AnimatedShapesExample test( application );
463 application.MainLoop();