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-toolkit/dali-toolkit.h>
19 #include <dali/dali.h>
22 using namespace Toolkit;
24 #define MATERIALS_MAX 24
28 const char* BASIC_LIGHT_THEME(DEMO_STYLE_DIR "basic-light-theme.json");
29 const char* const CUSTOM_BASIC_LIGHT_THEME = "BasicLightButton";
42 {"Emerald", Vector3(0.0215f, 0.1745f, 0.0215f), Vector3(0.07568f, 0.61424f, 0.07568f), Vector3(0.633, 0.727811f, 0.633f), 0.6f},
43 {"Jade", Vector3(0.135f, 0.2225f, 0.1575f), Vector3(0.54f, 0.89f, 0.63f), Vector3(0.316228f, 0.316228f, 0.316228f), 0.1f},
44 {"Obsidian", Vector3(0.05375f, 0.05f, 0.06625f), Vector3(0.18275f, 0.17f, 0.22525f), Vector3(0.332741f, 0.328634f, 0.346435f), 0.3f},
45 {"Perl", Vector3(0.25f, 0.20725f, 0.20725f), Vector3(1.0f, 0.829f, 0.829f), Vector3(0.296648f, 0.296648f, 0.296648f), 0.088f},
46 {"Ruby", Vector3(0.1745f, 0.01175f, 0.01175f), Vector3(0.61424f, 0.04136f, 0.04136f), Vector3(0.727811f, 0.626959f, 0.626959f), 0.6f},
47 {"Turquoise", Vector3(0.1f, 0.18725f, 0.1745f), Vector3(0.396f, 0.74151f, 0.69102f), Vector3(0.297254, 0.30829f, 0.306678f), 0.1f},
48 {"Brass", Vector3(0.329412f, 0.223529f, 0.027451f), Vector3(0.780392f, 0.568627f, 0.113725f), Vector3(0.992157f, 0.941176f, 0.807843f), 0.21794872f},
49 {"Bronze", Vector3(0.2125f, 0.1275f, 0.054f), Vector3(0.714f, 0.4284f, 0.18144f), Vector3(0.393548f, 0.271906f, 0.166721f), 0.2f},
50 {"Chrome", Vector3(0.25f, 0.25f, 0.25f), Vector3(0.4f, 0.4f, 0.4f), Vector3(0.774597f, 0.774597f, 0.774597f), 0.6f},
51 {"Copper", Vector3(0.19125f, 0.0735f, 0.0225f), Vector3(0.7038f, 0.27048f, 0.0828f), Vector3(0.256777f, 0.137622f, 0.086014f), 0.1f},
52 {"Gold", Vector3(0.24725f, 0.1995f, 0.0745f), Vector3(0.75164f, 0.60648f, 0.22648f), Vector3(0.628281f, 0.555802f, 0.366065f), 0.4f},
53 {"Silver", Vector3(0.19225f, 0.19225f, 0.19225f), Vector3(0.50754f, 0.50754f, 0.50754f), Vector3(0.508273f, 0.508273f, 0.508273f), 0.4f},
54 {"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},
55 {"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},
56 {"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},
57 {"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},
58 {"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},
59 {"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},
60 {"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},
61 {"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},
62 {"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},
63 {"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},
64 {"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},
65 {"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
140 // This example shows per-pixel lighting of materials with different ambient, diffuse, specular and shininess parameters
142 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));
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().TouchedSignal().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.GetState() == 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[] = {
317 2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, 17, 16, 15, 20, 19, 18, 23, 22, 21, 26, 25, 24, 29, 28, 27, 32, 31, 30, 35, 34, 33};
318 mGeometry = Geometry::New();
319 mGeometry.AddVertexBuffer(vertexBuffer);
320 mGeometry.SetIndexBuffer(INDEX_CUBE,
321 sizeof(INDEX_CUBE) / sizeof(INDEX_CUBE[0]));
322 mGeometry.SetType(Geometry::TRIANGLES);
326 * Creates a shader using inlined variable VERTEX_SHADER and FRAGMENT_SHADER
328 * Shaders are very basic and all they do is transforming vertices and interpolating
329 * input per-vertex color.
331 void CreateCubeShader()
333 mShader = Shader::New(VERTEX_SHADER, FRAGMENT_SHADER);
335 float scale = 120.0f;
336 mShader.RegisterProperty("light.position", Vector3(1.2 * scale, scale, 2.0 * scale));
337 mShader.RegisterProperty("light.color", Vector3(1.0f, 1.0f, 1.0f));
338 mShader.RegisterProperty("viewPos", Vector3(0, 0, 3.0 * scale));
340 mShader.RegisterProperty("material.ambient", material[MaterialID].ambient);
341 mShader.RegisterProperty("material.diffuse", material[MaterialID].diffuse);
342 mShader.RegisterProperty("material.specular", material[MaterialID].specular);
343 mShader.RegisterProperty("material.shininess", material[MaterialID].shininess * 128.0f);
347 * Function creates renderer. It turns on depth test and depth write.
349 void CreateRenderer()
351 mRenderer = Renderer::New(mGeometry, mShader);
353 // Face culling is enabled to hide the backwards facing sides of the cube
354 // This is sufficient to render a single object; for more complex scenes depth-testing might be required
355 mRenderer.SetProperty(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK);
359 * Creates new actor and attaches renderer.
363 Window window = mApplication.GetWindow();
365 float quarterWindowWidth = window.GetSize().GetWidth() * 0.25f;
366 mActor = Actor::New();
367 mActor.SetProperty(Actor::Property::COLOR, Vector4(1.0f, 1.0f, 0.6f, 1.0f));
368 mActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
369 mActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
370 mActor.SetProperty(Actor::Property::SIZE, Vector3(quarterWindowWidth, quarterWindowWidth, quarterWindowWidth));
371 mActor.AddRenderer(mRenderer);
380 mAnimation = Animation::New(15.0f);
381 mAnimation.SetLooping(true);
382 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::ZAXIS));
383 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::YAXIS));
384 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::XAXIS));
389 Application& mApplication;
396 Animation mAnimation;
399 int DALI_EXPORT_API main(int argc, char** argv)
401 Application application = Application::New(&argc, &argv, BASIC_LIGHT_THEME);
402 BasicLightController test(application);
403 application.MainLoop();