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;
31 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
32 attribute mediump vec3 aPosition;\n // DALi shader builtin
33 attribute mediump vec2 aTexCoord;\n // DALi shader builtin
34 uniform mediump mat4 uMvpMatrix;\n // DALi shader builtin
35 uniform mediump vec3 uSize;\n // DALi shader builtin
37 varying mediump vec2 vTexCoord;\n
40 mediump vec4 vertexPosition = vec4(aPosition, 1.0);\n
41 vertexPosition.xyz *= uSize;\n
42 vTexCoord = aTexCoord;\n
43 gl_Position = uMvpMatrix * vertexPosition;\n
50 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
51 uniform sampler2D uTexture;\n
53 varying mediump vec2 vTexCoord;\n
56 mediump vec4 texColor = texture2D( uTexture, vTexCoord );\n
57 gl_FragColor = texColor;\n
62 const char* TEXTURE_URL = DEMO_IMAGE_DIR "wood.png";
66 // This example shows how to create textured cube
68 class TexturedCubeController : public ConnectionTracker
71 TexturedCubeController(Application& application)
72 : mApplication(application)
74 // Connect to the Application's Init signal
75 mApplication.InitSignal().Connect(this, &TexturedCubeController::Create);
78 ~TexturedCubeController()
80 // Nothing to do here;
83 // The Init signal is received once (only) during the Application lifetime
84 void Create(Application& application)
86 // Get a handle to the window
87 Window window = application.GetWindow();
88 window.SetBackgroundColor(Color::WHITE);
90 // Step 1. Create shader
93 // Step 2. Load a texture
96 // Step 3. Prepare geometry
99 // Step 4. Create a renderer
102 // Step 5. Create an Actor
105 // Step 6. Play animation to rotate the cube
108 // Respond to a click anywhere on the window
109 window.GetRootLayer().TouchedSignal().Connect(this, &TexturedCubeController::OnTouch);
111 // Respond to key events
112 window.KeyEventSignal().Connect(this, &TexturedCubeController::OnKeyEvent);
115 bool OnTouch(Actor actor, const TouchEvent& touch)
117 // quit the application
123 * @brief Called when any key event is received
125 * Will use this to quit the application if Back or the Escape key is received
126 * @param[in] event The key event information
128 void OnKeyEvent(const KeyEvent& event)
130 if(event.GetState() == KeyEvent::DOWN)
132 if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
140 * @brief CreateCubeGeometry
141 * This function creates a cube geometry including texture coordinates.
142 * Also it demonstrates using the indexed draw feature by setting an index array.
144 void CreateCubeGeometry()
152 Vertex vertices[] = {
153 {Vector3(1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
154 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 0.0)},
155 {Vector3(1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)},
156 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
157 {Vector3(1.0f, -1.0f, 1.0f), Vector2(0.0, 0.0)},
158 {Vector3(1.0f, 1.0f, 1.0f), Vector2(0.0, 1.0)},
159 {Vector3(1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
160 {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
161 {Vector3(1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)},
162 {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 1.0)},
163 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
164 {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 1.0)},
165 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
166 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
167 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)},
168 {Vector3(1.0f, 1.0f, -1.0f), Vector2(1.0, 1.0)},
169 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
170 {Vector3(1.0f, 1.0f, 1.0f), Vector2(0.0, 1.0)},
171 {Vector3(1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
172 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 0.0)},
173 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 0.0)},
174 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
175 {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
176 {Vector3(1.0f, -1.0f, 1.0f), Vector2(0.0, 0.0)},
177 {Vector3(1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
178 {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
179 {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
180 {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 1.0)},
181 {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
182 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
183 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
184 {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
185 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
186 {Vector3(1.0f, 1.0f, -1.0f), Vector2(1.0, 1.0)},
187 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(1.0, 0.0)},
188 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
191 VertexBuffer vertexBuffer = VertexBuffer::New(Property::Map()
192 .Add("aPosition", Property::VECTOR3)
193 .Add("aTexCoord", Property::VECTOR2));
194 vertexBuffer.SetData(vertices, sizeof(vertices) / sizeof(Vertex));
197 const unsigned short INDEX_CUBE[] = {
198 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};
199 mGeometry = Geometry::New();
200 mGeometry.AddVertexBuffer(vertexBuffer);
201 mGeometry.SetIndexBuffer(INDEX_CUBE,
202 sizeof(INDEX_CUBE) / sizeof(INDEX_CUBE[0]));
203 mGeometry.SetType(Geometry::TRIANGLES);
207 * Creates a shader using inlined variable VERTEX_SHADER and FRAGMENT_SHADER
209 * Shaders are very basic and all they do is transforming vertices and sampling
212 void CreateCubeShader()
214 mShader = Shader::New(VERTEX_SHADER, FRAGMENT_SHADER);
218 * This function loads a pixel data from a file. In order to load it we use SyncImageLoader utility.
219 * If loading succeeds returned PixelData object can be used to create a texture.
220 * Texture must be uploaded. In the end the texture must be set on the TextureSet object.
224 // Load image from file
225 PixelData pixels = SyncImageLoader::Load(TEXTURE_URL);
227 Texture texture = Texture::New(TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight());
228 texture.Upload(pixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight());
231 mTextureSet = TextureSet::New();
232 mTextureSet.SetTexture(0, texture);
236 * Function creates renderer. It turns on depth test and depth write.
238 void CreateRenderer()
240 mRenderer = Renderer::New(mGeometry, mShader);
241 mRenderer.SetTextures(mTextureSet);
243 // Face culling is enabled to hide the backwards facing sides of the cube
244 // This is sufficient to render a single object; for more complex scenes depth-testing might be required
245 mRenderer.SetProperty(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK);
249 * Creates new actor and attaches renderer.
253 Window window = mApplication.GetWindow();
255 float quarterWindowWidth = window.GetSize().GetWidth() * 0.25f;
256 mActor = Actor::New();
257 mActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
258 mActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
259 mActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 0.0f));
260 mActor.SetProperty(Actor::Property::SIZE, Vector3(quarterWindowWidth, quarterWindowWidth, quarterWindowWidth));
261 mActor.AddRenderer(mRenderer);
270 mAnimation = Animation::New(5.0f);
271 mAnimation.SetLooping(true);
272 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::ZAXIS));
273 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::YAXIS));
274 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::XAXIS));
279 Application& mApplication;
284 TextureSet mTextureSet;
286 Animation mAnimation;
289 int DALI_EXPORT_API main(int argc, char** argv)
291 Application application = Application::New(&argc, &argv);
292 TexturedCubeController test(application);
293 application.MainLoop();