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>
22 using namespace Toolkit;
24 #define MATERIALS_MAX 24
29 const char* BASIC_LIGHT_THEME( DEMO_STYLE_DIR "basic-light-theme.json" );
30 const char* const CUSTOM_BASIC_LIGHT_THEME = "BasicLightButton";
43 {"Emerald", Vector3( 0.0215f, 0.1745f, 0.0215f ), Vector3( 0.07568f, 0.61424f, 0.07568f ), Vector3( 0.633, 0.727811f, 0.633f ), 0.6f },
44 {"Jade", Vector3( 0.135f, 0.2225f, 0.1575f ), Vector3( 0.54f, 0.89f, 0.63f ), Vector3( 0.316228f, 0.316228f, 0.316228f ), 0.1f },
45 {"Obsidian", Vector3( 0.05375f, 0.05f, 0.06625f ), Vector3( 0.18275f, 0.17f, 0.22525f ), Vector3( 0.332741f, 0.328634f, 0.346435f ), 0.3f },
46 {"Perl", Vector3( 0.25f, 0.20725f, 0.20725f ), Vector3( 1.0f, 0.829f, 0.829f ), Vector3( 0.296648f, 0.296648f, 0.296648f ), 0.088f },
47 {"Ruby", Vector3( 0.1745f, 0.01175f, 0.01175f ), Vector3( 0.61424f, 0.04136f, 0.04136f ), Vector3( 0.727811f, 0.626959f, 0.626959f ), 0.6f },
48 {"Turquoise", Vector3( 0.1f, 0.18725f, 0.1745f ), Vector3( 0.396f, 0.74151f, 0.69102f ), Vector3( 0.297254, 0.30829f, 0.306678f ), 0.1f },
49 {"Brass", Vector3( 0.329412f, 0.223529f, 0.027451f ), Vector3( 0.780392f, 0.568627f, 0.113725f ), Vector3( 0.992157f, 0.941176f, 0.807843f ), 0.21794872f },
50 {"Bronze", Vector3( 0.2125f, 0.1275f, 0.054f ), Vector3( 0.714f, 0.4284f, 0.18144f ), Vector3( 0.393548f, 0.271906f, 0.166721f ), 0.2f },
51 {"Chrome", Vector3( 0.25f, 0.25f, 0.25f ), Vector3( 0.4f, 0.4f, 0.4f), Vector3( 0.774597f, 0.774597f, 0.774597f ), 0.6f },
52 {"Copper", Vector3( 0.19125f, 0.0735f, 0.0225f ), Vector3( 0.7038f, 0.27048f, 0.0828f ), Vector3( 0.256777f, 0.137622f, 0.086014f ), 0.1f },
53 {"Gold", Vector3( 0.24725f, 0.1995f, 0.0745f ), Vector3( 0.75164f, 0.60648f, 0.22648f ), Vector3( 0.628281f, 0.555802f, 0.366065f ), 0.4f },
54 {"Silver", Vector3( 0.19225f, 0.19225f, 0.19225f ), Vector3( 0.50754f, 0.50754f, 0.50754f ), Vector3( 0.508273f, 0.508273f, 0.508273f ), 0.4f },
55 {"Black plastic", Vector3( 0.0f, 0.0f, 0.0f ), Vector3( 0.01f, 0.01f, 0.01f ), Vector3( 0.50f, 0.50f, 0.50f ), 0.25f },
56 {"Cyan plastic", Vector3( 0.0f, 0.1f, 0.06f ), Vector3( 0.0f, 0.50980392f, 0.50980392f ), Vector3( 0.50196078f, 0.50196078f, 0.50196078f ), 0.25f },
57 {"Green plastic", Vector3( 0.0f, 0.0f, 0.0f ), Vector3( 0.1f, 0.35f, 0.1f ), Vector3( 0.45, 0.55, 0.45 ), 0.25f },
58 {"Red plastic", Vector3( 0.0f, 0.0f, 0.0f ), Vector3( 0.5f, 0.0f, 0.0f ), Vector3( 0.7f, 0.6f, 0.6f ), 0.25f },
59 {"White plastic", Vector3( 0.0f, 0.0f, 0.0f ), Vector3( 0.55f, 0.55f, 0.55f ), Vector3( 0.7f, 0.7f, 0.7f ), 0.25f },
60 {"Yellow plastic", Vector3( 0.0f, 0.0f, 0.0f ), Vector3( 0.5f, 0.5f, 0.0f ), Vector3( 0.6f, 0.6f, 0.5f ), 0.25f },
61 {"Black rubber", Vector3( 0.02f, 0.02f, 0.02f ), Vector3( 0.01f, 0.01f, 0.01f ), Vector3( 0.4f, 0.4f, 0.4f ), 0.078125f },
62 {"Cyan rubber", Vector3( 0.0f, 0.05f, 0.05f ), Vector3( 0.4f, 0.5f, 0.5f ), Vector3( 0.04f, 0.7f, 0.7f ), 0.078125f },
63 {"Green rubber", Vector3( 0.0f, 0.05f, 0.0f ), Vector3( 0.4f, 0.5f, 0.4f ), Vector3( 0.04f, 0.7f, 0.04f ), 0.078125f },
64 {"Red rubber", Vector3( 0.05f, 0.0f, 0.0f ), Vector3( 0.5f, 0.4f, 0.4f ), Vector3( 0.7f, 0.04f, 0.04f ), 0.078125f },
65 {"White rubber", Vector3( 0.05f, 0.05f, 0.05f ), Vector3( 0.5f, 0.5f, 0.5f ), Vector3( 0.7f, 0.7f, 0.7f ), 0.078125f },
66 {"Yellow rubber", Vector3( 0.05f, 0.05f, 0.0f ), Vector3( 0.5f, 0.5f, 0.4f ), Vector3( 0.7f, 0.7f, 0.04f ), 0.078125f }
74 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
75 attribute mediump vec3 aPosition;\n // DALi shader builtin
76 attribute mediump vec3 aNormal;\n // DALi shader builtin
77 uniform mediump mat4 uMvpMatrix;\n // DALi shader builtin
78 uniform mediump vec3 uSize;\n // DALi shader builtin
79 uniform mediump mat4 uModelView;\n // DALi shader builtin
80 uniform mediump mat3 uNormalMatrix;\n // DALi shader builtin
82 varying mediump vec3 vNormal;\n
83 varying mediump vec3 vFragPos;\n
87 mediump vec4 vertexPosition = vec4(aPosition, 1.0);\n
88 vertexPosition.xyz *= uSize;\n
89 vFragPos = vec3(uModelView * vertexPosition);\n
90 vNormal = uNormalMatrix * aNormal;\n
92 gl_Position = uMvpMatrix * vertexPosition;\n
99 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
100 varying mediump vec3 vNormal;\n
101 varying mediump vec3 vFragPos;\n
102 uniform mediump vec3 viewPos;\n // custom uniform
105 mediump vec3 ambient;\n
106 mediump vec3 diffuse;\n
107 mediump vec3 specular;\n
108 mediump float shininess;\n
111 mediump vec3 position;\n
112 mediump vec3 color;\n
114 uniform Material material;\n // custom uniform
115 uniform Light light;\n // custom uniform
120 mediump vec3 ambient = material.ambient * light.color;\n
122 mediump vec3 norm = normalize(vNormal);\n
123 mediump vec3 lightDir = normalize(light.position - vFragPos);\n
124 mediump float diff = max(dot(norm, lightDir), 0.0);\n
125 mediump vec3 diffuse = material.diffuse * diff * light.color;\n
128 mediump vec3 viewDir = normalize(viewPos - vFragPos);\n
129 mediump vec3 reflectDir = reflect(-lightDir, norm); \n
130 mediump float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);\n
131 mediump vec3 specular = material.specular * spec * light.color; \n
132 mediump vec3 result = (ambient + diffuse + specular);\n
133 gl_FragColor = vec4(result, 1.0);\n
139 // This example shows per-pixel lighting of materials with different ambient, diffuse, specular and shininess parameters
141 class BasicLightController : public ConnectionTracker
145 BasicLightController( Application& application )
146 : mApplication( application )
148 // Connect to the Application's Init signal
149 mApplication.InitSignal().Connect( this, &BasicLightController::Create );
152 ~BasicLightController()
154 // Nothing to do here;
157 // The Init signal is received once (only) during the Application lifetime
158 void Create( Application& application )
160 // Get a handle to the window
161 Window window = application.GetWindow();
162 window.SetBackgroundColor( Color::BLACK );
163 mLabel = TextLabel::New( material[MaterialID].name );
164 mLabel.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER );
165 mLabel.SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 0.5f, 0.0f, 0.5f ) );
166 mLabel.SetProperty( Actor::Property::SIZE, Vector2( window.GetSize().GetWidth() * 0.5f, window.GetSize().GetHeight() * 0.083f ) );
167 mLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
168 mLabel.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
169 mLabel.SetProperty( TextLabel::Property::TEXT_COLOR, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ));
170 window.Add( mLabel );
171 mButton = PushButton::New();
172 mButton.SetProperty( Button::Property::LABEL, "Exit" );
173 mButton.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
174 mButton.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
175 mButton.ClickedSignal().Connect( this, &BasicLightController::OnExit );
176 mButton.SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 0.5f, 0.1f, 0.5f ) );
177 mButton.SetStyleName(CUSTOM_BASIC_LIGHT_THEME);
178 mButton.SetProperty( Actor::Property::COLOR, Vector4( material[MaterialID].diffuse) + Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) );
181 // Step 1. Create shader
184 // Step 2. Prepare geometry
185 CreateCubeGeometry();
187 // Step 3. Create a renderer
190 // Step 4. Create an Actor
193 // Step 5. Play animation to rotate the cube
196 // Respond to a click anywhere on the window
197 window.GetRootLayer().TouchSignal().Connect( this, &BasicLightController::OnTouch );
199 // Respond to key events
200 window.KeyEventSignal().Connect( this, &BasicLightController::OnKeyEvent );
204 * This function will change the material of the cube when touched
206 bool OnTouch( Actor actor, const TouchEvent& touch )
208 if(touch.GetState(0) == PointState::UP)
211 MaterialID %= MATERIALS_MAX;
213 mShader.SetProperty( mShader.GetPropertyIndex( "material.ambient" ), material[MaterialID].ambient );
214 mShader.SetProperty( mShader.GetPropertyIndex( "material.diffuse" ), material[MaterialID].diffuse );
215 mShader.SetProperty( mShader.GetPropertyIndex( "material.specular" ), material[MaterialID].specular );
216 mShader.SetProperty( mShader.GetPropertyIndex( "material.shininess" ), material[MaterialID].shininess * 128.0f );
217 mLabel.SetProperty( TextLabel::Property::TEXT, material[MaterialID].name );
218 mButton.SetProperty( Actor::Property::COLOR, Vector4(material[MaterialID].diffuse) + Vector4(0.0f, 0.0f, 0.0f, 1.0f) );
224 * This function will the terminate the application when the exit button is pressed
226 bool OnExit( Button button )
233 * @brief Called when any key event is received
235 * Will use this to quit the application if Back or the Escape key is received
236 * @param[in] event The key event information
238 void OnKeyEvent( const KeyEvent& event )
240 if( event.state == KeyEvent::Down )
242 if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
250 * This function creates a cube geometry including texture coordinates.
251 * Also it demonstrates using the indexed draw feature by setting an index array.
253 void CreateCubeGeometry()
261 const Vector3 NORMAL0(-1.0f, 0.0f, 0.0f );
262 const Vector3 NORMAL1( 0.0f, 1.0f, 0.0f );
263 const Vector3 NORMAL2( 0.0f,-1.0f, 0.0f );
264 const Vector3 NORMAL3( 0.0f, 0.0f, 1.0f );
265 const Vector3 NORMAL4( 1.0f, 0.0f, 0.0f );
266 const Vector3 NORMAL5( 0.0f, 0.0f,-1.0f );
268 Vertex vertices[] = {
269 { Vector3( 1.0f,-1.0f,-1.0f ), NORMAL5 },
270 { Vector3( -1.0f, 1.0f,-1.0f ), NORMAL5 },
271 { Vector3( 1.0f, 1.0f,-1.0f ), NORMAL5 },
272 { Vector3( -1.0f, 1.0f, 1.0f ), NORMAL3 },
273 { Vector3( 1.0f,-1.0f, 1.0f ), NORMAL3 },
274 { Vector3( 1.0f, 1.0f, 1.0f ), NORMAL3 },
275 { Vector3( 1.0f, 1.0f, 1.0f ), NORMAL4 },
276 { Vector3( 1.0f,-1.0f,-1.0f ), NORMAL4 },
277 { Vector3( 1.0f, 1.0f,-1.0f ), NORMAL4 },
278 { Vector3( 1.0f,-1.0f, 1.0f ), NORMAL1 },
279 { Vector3( -1.0f,-1.0f,-1.0f ), NORMAL1 },
280 { Vector3( 1.0f,-1.0f,-1.0f ), NORMAL1 },
281 { Vector3( -1.0f,-1.0f,-1.0f ), NORMAL0 },
282 { Vector3( -1.0f, 1.0f, 1.0f ), NORMAL0 },
283 { Vector3( -1.0f, 1.0f,-1.0f ), NORMAL0 },
284 { Vector3( 1.0f, 1.0f,-1.0f ), NORMAL2 },
285 { Vector3( -1.0f, 1.0f, 1.0f ), NORMAL2 },
286 { Vector3( 1.0f, 1.0f, 1.0f ), NORMAL2 },
287 { Vector3( 1.0f,-1.0f,-1.0f ), NORMAL5 },
288 { Vector3( -1.0f,-1.0f,-1.0f ), NORMAL5 },
289 { Vector3( -1.0f, 1.0f,-1.0f ), NORMAL5 },
290 { Vector3( -1.0f, 1.0f, 1.0f ), NORMAL3 },
291 { Vector3( -1.0f,-1.0f, 1.0f ), NORMAL3 },
292 { Vector3( 1.0f,-1.0f, 1.0f ), NORMAL3 },
293 { Vector3( 1.0f, 1.0f, 1.0f ), NORMAL4 },
294 { Vector3( 1.0f,-1.0f, 1.0f ), NORMAL4 },
295 { Vector3( 1.0f,-1.0f,-1.0f ), NORMAL4 },
296 { Vector3( 1.0f,-1.0f, 1.0f ), NORMAL1 },
297 { Vector3( -1.0f,-1.0f, 1.0f ), NORMAL1 },
298 { Vector3( -1.0f,-1.0f,-1.0f ), NORMAL1 },
299 { Vector3( -1.0f,-1.0f,-1.0f ), NORMAL0 },
300 { Vector3( -1.0f,-1.0f, 1.0f ), NORMAL0 },
301 { Vector3( -1.0f, 1.0f, 1.0f ), NORMAL0 },
302 { Vector3( 1.0f, 1.0f,-1.0f ), NORMAL2 },
303 { Vector3( -1.0f, 1.0f,-1.0f ), NORMAL2 },
304 { Vector3( -1.0f, 1.0f, 1.0f ), NORMAL2 },
307 Property::Map property;
308 property.Insert( "aPosition", Property::VECTOR3 );
309 property.Insert( "aNormal", Property::VECTOR3 );
311 VertexBuffer vertexBuffer = VertexBuffer::New( property );
313 vertexBuffer.SetData( vertices, sizeof(vertices) / sizeof(Vertex) );
316 const unsigned short INDEX_CUBE[] = {
330 mGeometry = Geometry::New();
331 mGeometry.AddVertexBuffer( vertexBuffer );
332 mGeometry.SetIndexBuffer( INDEX_CUBE,
333 sizeof(INDEX_CUBE)/sizeof(INDEX_CUBE[0])
335 mGeometry.SetType( Geometry::TRIANGLES );
339 * Creates a shader using inlined variable VERTEX_SHADER and FRAGMENT_SHADER
341 * Shaders are very basic and all they do is transforming vertices and interpolating
342 * input per-vertex color.
344 void CreateCubeShader()
346 mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
348 float scale = 120.0f;
349 mShader.RegisterProperty( "light.position",Vector3( 1.2 * scale, scale, 2.0 * scale ) );
350 mShader.RegisterProperty( "light.color", Vector3( 1.0f, 1.0f, 1.0f ) );
351 mShader.RegisterProperty( "viewPos", Vector3( 0, 0, 3.0 * scale ) );
353 mShader.RegisterProperty( "material.ambient", material[MaterialID].ambient );
354 mShader.RegisterProperty( "material.diffuse", material[MaterialID].diffuse );
355 mShader.RegisterProperty( "material.specular", material[MaterialID].specular );
356 mShader.RegisterProperty( "material.shininess", material[MaterialID].shininess * 128.0f );
360 * Function creates renderer. It turns on depth test and depth write.
362 void CreateRenderer()
364 mRenderer = Renderer::New( mGeometry, mShader );
366 // Face culling is enabled to hide the backwards facing sides of the cube
367 // This is sufficient to render a single object; for more complex scenes depth-testing might be required
368 mRenderer.SetProperty( Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK );
372 * Creates new actor and attaches renderer.
376 Window window = mApplication.GetWindow();
378 float quarterWindowWidth = window.GetSize().GetWidth() * 0.25f;
379 mActor = Actor::New();
380 mActor.SetProperty( Actor::Property::COLOR, Vector4( 1.0f, 1.0f, 0.6f, 1.0f ) );
381 mActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
382 mActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
383 mActor.SetProperty( Actor::Property::SIZE, Vector3( quarterWindowWidth, quarterWindowWidth, quarterWindowWidth ) );
384 mActor.AddRenderer( mRenderer );
385 window.Add( mActor );
393 mAnimation = Animation::New( 15.0f );
394 mAnimation.SetLooping( true );
395 mAnimation.AnimateBy( Property( mActor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( 360 )), Vector3::ZAXIS ) );
396 mAnimation.AnimateBy( Property( mActor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( 360 )), Vector3::YAXIS ) );
397 mAnimation.AnimateBy( Property( mActor, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( 360 )), Vector3::XAXIS ) );
402 Application& mApplication;
409 Animation mAnimation;
412 int DALI_EXPORT_API main( int argc, char **argv )
414 Application application = Application::New( &argc, &argv, BASIC_LIGHT_THEME);
415 BasicLightController test( application );
416 application.MainLoop();