2 * Copyright (c) 2017 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>
23 namespace // unnamed namespace
26 const char* TEXTURE_URL = DEMO_IMAGE_DIR "RadialEffect-280x280.png";
27 const unsigned int TEXTURE_WIDTH = 280;
28 const unsigned int TEXTURE_HEIGHT = 280;
30 const int NUMBER_OF_SIDES( 64 ); // number of sides of the polygon used as a stencil
31 const float INITIAL_DELAY( 2.0f ); // initial delay before showing the circle
32 const float PROGRESS_DURATION( 0.5f ); // number of seconds to fully show the circle
36 * Vertex shader for textured quad
38 const char* VERTEX_SHADER_TEXTURED = DALI_COMPOSE_SHADER(
39 attribute mediump vec2 aPosition;\n
40 uniform mediump mat4 uMvpMatrix;\n // DALi shader builtin
41 uniform mediump vec3 uSize;\n // DALi shader builtin
43 varying mediump vec2 vTexCoord;\n
46 mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
47 vertexPosition.xyz *= uSize;\n
48 vTexCoord = vec2(1.0, 1.0)*(aPosition + vec2(0.5) );\n
49 gl_Position = uMvpMatrix * vertexPosition;\n
54 * Fragment shaderfor textured quad
56 const char* FRAGMENT_SHADER_TEXTURED = DALI_COMPOSE_SHADER(
57 uniform sampler2D uTexture;\n
59 varying mediump vec2 vTexCoord;\n
62 mediump vec4 texColor = texture2D( uTexture, vTexCoord );\n
63 gl_FragColor = texColor;\n
68 * Vertex shader for polygon
70 const char* VERTEX_SHADER_BASIC = DALI_COMPOSE_SHADER(
71 attribute mediump vec3 aPosition;\n
72 uniform mediump mat4 uMvpMatrix;\n // DALi shader builtin
73 uniform mediump vec3 uSize;\n // DALi shader builtin
74 uniform mediump float uProgress;\n
76 varying mediump vec2 vTexCoord;\n
79 mediump vec4 vertexPosition = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n
81 float index = aPosition.z;\n
82 if( uProgress < index )\n
84 vertexPosition = vec4(0.0, 0.0, 0.0, 1.0);\n
87 vertexPosition.xyz *= uSize;\n
88 gl_Position = uMvpMatrix * vertexPosition;\n
93 * Fragment shader for polygon
95 const char* FRAGMENT_SHADER_BASIC = DALI_COMPOSE_SHADER(
99 gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 );\n
103 } // unnamed namespace
106 // This example shows how to render a radial progress indicator
108 class RadialProgressController : public ConnectionTracker
112 RadialProgressController( Application& application )
113 : mApplication( application )
115 // Connect to the Application's Init signal
116 mApplication.InitSignal().Connect( this, &RadialProgressController::Create );
119 ~RadialProgressController()
121 // Nothing to do here
124 // The Init signal is received once (only) during the Application lifetime
125 void Create( Application& application )
127 Stage stage = Stage::GetCurrent();
128 stage.SetBackgroundColor( Color::BLACK );
130 // 1. Create actor to show the effect
131 mActor = Actor::New();
132 mActor.SetAnchorPoint( AnchorPoint::CENTER );
133 mActor.SetParentOrigin( ParentOrigin::CENTER );
134 mActor.SetSize( Vector2( TEXTURE_WIDTH, TEXTURE_HEIGHT ) );
135 mActor.RegisterProperty("uProgress", float(1.0f) );
138 // 1. Create stencil renderer i.e. a triangle fan in the shape of a circle
139 Renderer stencilRenderer = CreatePolygon( NUMBER_OF_SIDES );
140 mActor.AddRenderer( stencilRenderer );
142 // 2. Create textured quad renderer
143 Renderer texturedQuad = CreateTexturedQuad( TEXTURE_URL );
144 mActor.AddRenderer( texturedQuad );
146 // 5. Animate the progress uniform
147 Animation animation = Animation::New( PROGRESS_DURATION + INITIAL_DELAY );
148 animation.AnimateTo( Property(mActor,"uProgress"), float(NUMBER_OF_SIDES+1), TimePeriod(INITIAL_DELAY, PROGRESS_DURATION) );
151 // 6. Exit the application when touched
152 stage.GetRootLayer().TouchSignal().Connect( this, &RadialProgressController::OnTouch );
155 bool OnTouch( Actor actor, const TouchData& touch )
157 // quit the application
163 * Generates stencil mask geometry. Geometry is rendered as
164 * a triangle fan and occupies square 2.0x2.0.
165 * @param[in] numberOfSides The more subdivisions the more smooth mask animation.
167 Renderer CreatePolygon( unsigned int numberOfSides )
169 float count( numberOfSides );
171 // compute radial step in radians
172 const float STEP( (2.0f * M_PI) / count );
175 std::vector< Vector3 > vertices;
176 vertices.push_back( Vector3::ZERO );
178 for( size_t i = 0; i <= numberOfSides; ++i )
180 vertices.push_back( Vector3( -0.5f * cos( angle ), -0.5f * sin( angle ), i+1 ) );
184 Property::Map vertexFormat;
185 vertexFormat[ "aPosition" ] = Property::VECTOR3;
187 // describe vertex format ( only 2-dimensional positions )
188 PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat );
189 vertexBuffer.SetData( vertices.data(), vertices.size() );
192 Geometry geometry = Geometry::New();
193 geometry.AddVertexBuffer( vertexBuffer );
194 geometry.SetType( Geometry::TRIANGLE_FAN );
196 Shader shader = Shader::New( VERTEX_SHADER_BASIC, FRAGMENT_SHADER_BASIC );
197 Renderer renderer = Renderer::New( geometry, shader );
199 // Setting stencil data. We don't want to render to the color buffer so
200 // with use of RenderMode property we specify that only stencil buffer will
202 renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::STENCIL );
204 // Set stencil function
205 renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION, StencilFunction::ALWAYS );
207 // Stencil function reference
208 renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION_REFERENCE, 1 );
210 // Stencil function mask
211 renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION_MASK, 0xFF );
213 // Set stencil operations
214 renderer.SetProperty( Renderer::Property::STENCIL_OPERATION_ON_FAIL, StencilOperation::KEEP );
215 renderer.SetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL, StencilOperation::KEEP );
216 renderer.SetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_PASS, StencilOperation::REPLACE );
218 // Stencil mask to write
219 renderer.SetProperty( Renderer::Property::STENCIL_MASK, 0xFF );
221 // Set depth index lower than textured quad renderer, so stencil will render first
222 renderer.SetProperty( Renderer::Property::DEPTH_INDEX, 1 );
228 * Creates textured quad renderer
230 Renderer CreateTexturedQuad( const char* url )
232 // Create shader & geometry needed by Renderer
234 Shader shader = Shader::New( VERTEX_SHADER_TEXTURED, FRAGMENT_SHADER_TEXTURED );
236 Property::Map vertexFormat;
237 vertexFormat["aPosition"] = Property::VECTOR2;
238 PropertyBuffer vertexBuffer = PropertyBuffer::New( vertexFormat );
240 const float P( 0.5f );
241 const Vector2 vertices[] = {
248 vertexBuffer.SetData( vertices, 4 );
250 // Instantiate quad geometry
251 Geometry geometry = Geometry::New();
252 geometry.AddVertexBuffer( vertexBuffer );
253 geometry.SetType( Geometry::TRIANGLE_STRIP );
256 PixelData pixelData = Toolkit::SyncImageLoader::Load( url );
257 Texture texture = Texture::New( TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight() );
258 texture.Upload( pixelData );
259 texture.GenerateMipmaps();
261 // Create texture set
262 TextureSet textureSet = TextureSet::New();
263 textureSet.SetTexture( 0, texture );
266 Renderer renderer = Renderer::New( geometry, shader );
267 renderer.SetTextures( textureSet );
269 // Set mode indicating we will use both stencil and color buffers
270 renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR_STENCIL );
272 // Stencil function - expecing drawing only when function mask matches exactly
273 renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION, StencilFunction::EQUAL );
274 renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION_REFERENCE, 1 );
275 renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION_MASK, 0xFF );
277 // We don't want to draw to the stencil, so setting stencil draw mask to 0
278 renderer.SetProperty( Renderer::Property::STENCIL_MASK, 0x00 );
280 // Make sure the quad will render after drawing to stencil buffer
281 renderer.SetProperty( Renderer::Property::DEPTH_INDEX, 2 );
288 Application& mApplication;
293 void RunTest( Application& application )
295 RadialProgressController test( application );
297 application.MainLoop();
300 // Entry point for Linux & Tizen applications
302 int DALI_EXPORT_API main( int argc, char **argv )
304 Application application = Application::New( &argc, &argv );
306 RunTest( application );