2 * Copyright (c) 2022 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>
21 #include "generated/rendering-basic-light-frag.h"
22 #include "generated/rendering-basic-light-vert.h"
25 using namespace Toolkit;
27 #define MATERIALS_MAX 24
31 const char* BASIC_LIGHT_THEME(DEMO_STYLE_DIR "basic-light-theme.json");
32 const char* const CUSTOM_BASIC_LIGHT_THEME = "BasicLightButton";
45 {"Emerald", Vector3(0.0215f, 0.1745f, 0.0215f), Vector3(0.07568f, 0.61424f, 0.07568f), Vector3(0.633, 0.727811f, 0.633f), 0.6f},
46 {"Jade", Vector3(0.135f, 0.2225f, 0.1575f), Vector3(0.54f, 0.89f, 0.63f), Vector3(0.316228f, 0.316228f, 0.316228f), 0.1f},
47 {"Obsidian", Vector3(0.05375f, 0.05f, 0.06625f), Vector3(0.18275f, 0.17f, 0.22525f), Vector3(0.332741f, 0.328634f, 0.346435f), 0.3f},
48 {"Perl", Vector3(0.25f, 0.20725f, 0.20725f), Vector3(1.0f, 0.829f, 0.829f), Vector3(0.296648f, 0.296648f, 0.296648f), 0.088f},
49 {"Ruby", Vector3(0.1745f, 0.01175f, 0.01175f), Vector3(0.61424f, 0.04136f, 0.04136f), Vector3(0.727811f, 0.626959f, 0.626959f), 0.6f},
50 {"Turquoise", Vector3(0.1f, 0.18725f, 0.1745f), Vector3(0.396f, 0.74151f, 0.69102f), Vector3(0.297254, 0.30829f, 0.306678f), 0.1f},
51 {"Brass", Vector3(0.329412f, 0.223529f, 0.027451f), Vector3(0.780392f, 0.568627f, 0.113725f), Vector3(0.992157f, 0.941176f, 0.807843f), 0.21794872f},
52 {"Bronze", Vector3(0.2125f, 0.1275f, 0.054f), Vector3(0.714f, 0.4284f, 0.18144f), Vector3(0.393548f, 0.271906f, 0.166721f), 0.2f},
53 {"Chrome", Vector3(0.25f, 0.25f, 0.25f), Vector3(0.4f, 0.4f, 0.4f), Vector3(0.774597f, 0.774597f, 0.774597f), 0.6f},
54 {"Copper", Vector3(0.19125f, 0.0735f, 0.0225f), Vector3(0.7038f, 0.27048f, 0.0828f), Vector3(0.256777f, 0.137622f, 0.086014f), 0.1f},
55 {"Gold", Vector3(0.24725f, 0.1995f, 0.0745f), Vector3(0.75164f, 0.60648f, 0.22648f), Vector3(0.628281f, 0.555802f, 0.366065f), 0.4f},
56 {"Silver", Vector3(0.19225f, 0.19225f, 0.19225f), Vector3(0.50754f, 0.50754f, 0.50754f), Vector3(0.508273f, 0.508273f, 0.508273f), 0.4f},
57 {"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},
58 {"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},
59 {"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},
60 {"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},
61 {"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},
62 {"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},
63 {"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},
64 {"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},
65 {"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},
66 {"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},
67 {"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},
68 {"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 // This example shows per-pixel lighting of materials with different ambient, diffuse, specular and shininess parameters
76 class BasicLightController : public ConnectionTracker
79 BasicLightController(Application& application)
80 : mApplication(application)
82 // Connect to the Application's Init signal
83 mApplication.InitSignal().Connect(this, &BasicLightController::Create);
86 ~BasicLightController()
88 // Nothing to do here;
91 // The Init signal is received once (only) during the Application lifetime
92 void Create(Application& application)
94 // Get a handle to the window
95 Window window = application.GetWindow();
96 window.SetBackgroundColor(Color::BLACK);
97 mLabel = TextLabel::New(material[MaterialID].name);
98 mLabel.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
99 mLabel.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.5f, 0.0f, 0.5f));
100 mLabel.SetProperty(Actor::Property::SIZE, Vector2(window.GetSize().GetWidth() * 0.5f, window.GetSize().GetHeight() * 0.083f));
101 mLabel.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER");
102 mLabel.SetProperty(TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER");
103 mLabel.SetProperty(TextLabel::Property::TEXT_COLOR, Vector4(1.0f, 1.0f, 1.0f, 1.0f));
105 mButton = PushButton::New();
106 mButton.SetProperty(Button::Property::LABEL, "Exit");
107 mButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
108 mButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
109 mButton.ClickedSignal().Connect(this, &BasicLightController::OnExit);
110 mButton.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.5f, 0.1f, 0.5f));
111 mButton.SetStyleName(CUSTOM_BASIC_LIGHT_THEME);
112 mButton.SetProperty(Actor::Property::COLOR, Vector4(material[MaterialID].diffuse) + Vector4(0.0f, 0.0f, 0.0f, 1.0f));
115 // Step 1. Create shader
118 // Step 2. Prepare geometry
119 CreateCubeGeometry();
121 // Step 3. Create a renderer
124 // Step 4. Create an Actor
127 // Step 5. Play animation to rotate the cube
130 // Respond to a click anywhere on the window
131 window.GetRootLayer().TouchedSignal().Connect(this, &BasicLightController::OnTouch);
133 // Respond to key events
134 window.KeyEventSignal().Connect(this, &BasicLightController::OnKeyEvent);
138 * This function will change the material of the cube when touched
140 bool OnTouch(Actor actor, const TouchEvent& touch)
142 if(touch.GetState(0) == PointState::UP)
145 MaterialID %= MATERIALS_MAX;
147 mShader.SetProperty(mShader.GetPropertyIndex("material.ambient"), material[MaterialID].ambient);
148 mShader.SetProperty(mShader.GetPropertyIndex("material.diffuse"), material[MaterialID].diffuse);
149 mShader.SetProperty(mShader.GetPropertyIndex("material.specular"), material[MaterialID].specular);
150 mShader.SetProperty(mShader.GetPropertyIndex("material.shininess"), material[MaterialID].shininess * 128.0f);
151 mLabel.SetProperty(TextLabel::Property::TEXT, material[MaterialID].name);
152 mButton.SetProperty(Actor::Property::COLOR, Vector4(material[MaterialID].diffuse) + Vector4(0.0f, 0.0f, 0.0f, 1.0f));
158 * This function will the terminate the application when the exit button is pressed
160 bool OnExit(Button button)
167 * @brief Called when any key event is received
169 * Will use this to quit the application if Back or the Escape key is received
170 * @param[in] event The key event information
172 void OnKeyEvent(const KeyEvent& event)
174 if(event.GetState() == KeyEvent::DOWN)
176 if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
184 * This function creates a cube geometry including texture coordinates.
185 * Also it demonstrates using the indexed draw feature by setting an index array.
187 void CreateCubeGeometry()
195 const Vector3 NORMAL0(-1.0f, 0.0f, 0.0f);
196 const Vector3 NORMAL1(0.0f, 1.0f, 0.0f);
197 const Vector3 NORMAL2(0.0f, -1.0f, 0.0f);
198 const Vector3 NORMAL3(0.0f, 0.0f, 1.0f);
199 const Vector3 NORMAL4(1.0f, 0.0f, 0.0f);
200 const Vector3 NORMAL5(0.0f, 0.0f, -1.0f);
202 Vertex vertices[] = {
203 {Vector3(1.0f, -1.0f, -1.0f), NORMAL5},
204 {Vector3(-1.0f, 1.0f, -1.0f), NORMAL5},
205 {Vector3(1.0f, 1.0f, -1.0f), NORMAL5},
206 {Vector3(-1.0f, 1.0f, 1.0f), NORMAL3},
207 {Vector3(1.0f, -1.0f, 1.0f), NORMAL3},
208 {Vector3(1.0f, 1.0f, 1.0f), NORMAL3},
209 {Vector3(1.0f, 1.0f, 1.0f), NORMAL4},
210 {Vector3(1.0f, -1.0f, -1.0f), NORMAL4},
211 {Vector3(1.0f, 1.0f, -1.0f), NORMAL4},
212 {Vector3(1.0f, -1.0f, 1.0f), NORMAL1},
213 {Vector3(-1.0f, -1.0f, -1.0f), NORMAL1},
214 {Vector3(1.0f, -1.0f, -1.0f), NORMAL1},
215 {Vector3(-1.0f, -1.0f, -1.0f), NORMAL0},
216 {Vector3(-1.0f, 1.0f, 1.0f), NORMAL0},
217 {Vector3(-1.0f, 1.0f, -1.0f), NORMAL0},
218 {Vector3(1.0f, 1.0f, -1.0f), NORMAL2},
219 {Vector3(-1.0f, 1.0f, 1.0f), NORMAL2},
220 {Vector3(1.0f, 1.0f, 1.0f), NORMAL2},
221 {Vector3(1.0f, -1.0f, -1.0f), NORMAL5},
222 {Vector3(-1.0f, -1.0f, -1.0f), NORMAL5},
223 {Vector3(-1.0f, 1.0f, -1.0f), NORMAL5},
224 {Vector3(-1.0f, 1.0f, 1.0f), NORMAL3},
225 {Vector3(-1.0f, -1.0f, 1.0f), NORMAL3},
226 {Vector3(1.0f, -1.0f, 1.0f), NORMAL3},
227 {Vector3(1.0f, 1.0f, 1.0f), NORMAL4},
228 {Vector3(1.0f, -1.0f, 1.0f), NORMAL4},
229 {Vector3(1.0f, -1.0f, -1.0f), NORMAL4},
230 {Vector3(1.0f, -1.0f, 1.0f), NORMAL1},
231 {Vector3(-1.0f, -1.0f, 1.0f), NORMAL1},
232 {Vector3(-1.0f, -1.0f, -1.0f), NORMAL1},
233 {Vector3(-1.0f, -1.0f, -1.0f), NORMAL0},
234 {Vector3(-1.0f, -1.0f, 1.0f), NORMAL0},
235 {Vector3(-1.0f, 1.0f, 1.0f), NORMAL0},
236 {Vector3(1.0f, 1.0f, -1.0f), NORMAL2},
237 {Vector3(-1.0f, 1.0f, -1.0f), NORMAL2},
238 {Vector3(-1.0f, 1.0f, 1.0f), NORMAL2},
241 Property::Map property;
242 property.Insert("aPosition", Property::VECTOR3);
243 property.Insert("aNormal", Property::VECTOR3);
245 VertexBuffer vertexBuffer = VertexBuffer::New(property);
247 vertexBuffer.SetData(vertices, sizeof(vertices) / sizeof(Vertex));
250 const unsigned short INDEX_CUBE[] = {
251 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};
252 mGeometry = Geometry::New();
253 mGeometry.AddVertexBuffer(vertexBuffer);
254 mGeometry.SetIndexBuffer(INDEX_CUBE,
255 sizeof(INDEX_CUBE) / sizeof(INDEX_CUBE[0]));
256 mGeometry.SetType(Geometry::TRIANGLES);
260 * Creates a shader using inlined variable SHADER_RENDERING_BASIC_LIGHT_VERT and SHADER_RENDERING_BASIC_LIGHT_FRAG
262 * Shaders are very basic and all they do is transforming vertices and interpolating
263 * input per-vertex color.
265 void CreateCubeShader()
267 mShader = Shader::New(SHADER_RENDERING_BASIC_LIGHT_VERT, SHADER_RENDERING_BASIC_LIGHT_FRAG);
269 float scale = 120.0f;
270 mShader.RegisterProperty("light.position", Vector3(1.2 * scale, scale, 2.0 * scale));
271 mShader.RegisterProperty("light.color", Vector3(1.0f, 1.0f, 1.0f));
272 mShader.RegisterProperty("viewPos", Vector3(0, 0, 3.0 * scale));
274 mShader.RegisterProperty("material.ambient", material[MaterialID].ambient);
275 mShader.RegisterProperty("material.diffuse", material[MaterialID].diffuse);
276 mShader.RegisterProperty("material.specular", material[MaterialID].specular);
277 mShader.RegisterProperty("material.shininess", material[MaterialID].shininess * 128.0f);
281 * Function creates renderer. It turns on depth test and depth write.
283 void CreateRenderer()
285 mRenderer = Renderer::New(mGeometry, mShader);
287 // Face culling is enabled to hide the backwards facing sides of the cube
288 // This is sufficient to render a single object; for more complex scenes depth-testing might be required
289 mRenderer.SetProperty(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK);
293 * Creates new actor and attaches renderer.
297 Window window = mApplication.GetWindow();
298 const auto windowSize = window.GetSize();
300 const float quarterWindowSize = std::min(windowSize.GetWidth(), windowSize.GetHeight()) * 0.25f;
301 mActor = Actor::New();
302 mActor.SetProperty(Actor::Property::COLOR, Vector4(1.0f, 1.0f, 0.6f, 1.0f));
303 mActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
304 mActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
305 mActor.SetProperty(Actor::Property::SIZE, Vector3(quarterWindowSize, quarterWindowSize, quarterWindowSize));
306 mActor.AddRenderer(mRenderer);
315 mAnimation = Animation::New(15.0f);
316 mAnimation.SetLooping(true);
317 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::ZAXIS));
318 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::YAXIS));
319 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::XAXIS));
324 Application& mApplication;
331 Animation mAnimation;
334 int DALI_EXPORT_API main(int argc, char** argv)
336 Application application = Application::New(&argc, &argv, BASIC_LIGHT_THEME);
337 BasicLightController test(application);
338 application.MainLoop();