2 * Copyright (c) 2021 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-textured-cube-frag.h"
22 #include "generated/rendering-textured-cube-vert.h"
25 using namespace Toolkit;
29 const char* TEXTURE_URL = DEMO_IMAGE_DIR "wood.png";
33 // This example shows how to create textured cube
35 class TexturedCubeController : public ConnectionTracker
38 TexturedCubeController(Application& application)
39 : mApplication(application)
41 // Connect to the Application's Init signal
42 mApplication.InitSignal().Connect(this, &TexturedCubeController::Create);
45 ~TexturedCubeController()
47 // Nothing to do here;
50 // The Init signal is received once (only) during the Application lifetime
51 void Create(Application& application)
53 // Get a handle to the window
54 Window window = application.GetWindow();
55 window.SetBackgroundColor(Color::WHITE);
57 // Step 1. Create shader
60 // Step 2. Load a texture
63 // Step 3. Prepare geometry
66 // Step 4. Create a renderer
69 // Step 5. Create an Actor
72 // Step 6. Play animation to rotate the cube
75 // Respond to a click anywhere on the window
76 window.GetRootLayer().TouchedSignal().Connect(this, &TexturedCubeController::OnTouch);
78 // Respond to key events
79 window.KeyEventSignal().Connect(this, &TexturedCubeController::OnKeyEvent);
82 bool OnTouch(Actor actor, const TouchEvent& touch)
84 // quit the application
90 * @brief Called when any key event is received
92 * Will use this to quit the application if Back or the Escape key is received
93 * @param[in] event The key event information
95 void OnKeyEvent(const KeyEvent& event)
97 if(event.GetState() == KeyEvent::DOWN)
99 if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
107 * @brief CreateCubeGeometry
108 * This function creates a cube geometry including texture coordinates.
109 * Also it demonstrates using the indexed draw feature by setting an index array.
111 void CreateCubeGeometry()
119 Vertex vertices[] = {
120 {Vector3(1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
121 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 0.0)},
122 {Vector3(1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)},
123 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
124 {Vector3(1.0f, -1.0f, 1.0f), Vector2(0.0, 0.0)},
125 {Vector3(1.0f, 1.0f, 1.0f), Vector2(0.0, 1.0)},
126 {Vector3(1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
127 {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
128 {Vector3(1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)},
129 {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 1.0)},
130 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
131 {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 1.0)},
132 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
133 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
134 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)},
135 {Vector3(1.0f, 1.0f, -1.0f), Vector2(1.0, 1.0)},
136 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
137 {Vector3(1.0f, 1.0f, 1.0f), Vector2(0.0, 1.0)},
138 {Vector3(1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
139 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 0.0)},
140 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 0.0)},
141 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
142 {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
143 {Vector3(1.0f, -1.0f, 1.0f), Vector2(0.0, 0.0)},
144 {Vector3(1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
145 {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
146 {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
147 {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 1.0)},
148 {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
149 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
150 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
151 {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
152 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
153 {Vector3(1.0f, 1.0f, -1.0f), Vector2(1.0, 1.0)},
154 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(1.0, 0.0)},
155 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
158 VertexBuffer vertexBuffer = VertexBuffer::New(Property::Map()
159 .Add("aPosition", Property::VECTOR3)
160 .Add("aTexCoord", Property::VECTOR2));
161 vertexBuffer.SetData(vertices, sizeof(vertices) / sizeof(Vertex));
164 const unsigned short INDEX_CUBE[] = {
165 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};
166 mGeometry = Geometry::New();
167 mGeometry.AddVertexBuffer(vertexBuffer);
168 mGeometry.SetIndexBuffer(INDEX_CUBE,
169 sizeof(INDEX_CUBE) / sizeof(INDEX_CUBE[0]));
170 mGeometry.SetType(Geometry::TRIANGLES);
174 * Creates a shader using SHADER_RENDERING_TEXTURED_CUBE_VERT and SHADER_RENDERING_TEXTURED_CUBE_FRAG
176 * Shaders are very basic and all they do is transforming vertices and sampling
179 void CreateCubeShader()
181 mShader = Shader::New(SHADER_RENDERING_TEXTURED_CUBE_VERT, SHADER_RENDERING_TEXTURED_CUBE_FRAG);
185 * This function loads a pixel data from a file. In order to load it we use SyncImageLoader utility.
186 * If loading succeeds returned PixelData object can be used to create a texture.
187 * Texture must be uploaded. In the end the texture must be set on the TextureSet object.
191 // Load image from file
192 PixelData pixels = SyncImageLoader::Load(TEXTURE_URL);
194 Texture texture = Texture::New(TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight());
195 texture.Upload(pixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight());
198 mTextureSet = TextureSet::New();
199 mTextureSet.SetTexture(0, texture);
203 * Function creates renderer. It turns on depth test and depth write.
205 void CreateRenderer()
207 mRenderer = Renderer::New(mGeometry, mShader);
208 mRenderer.SetTextures(mTextureSet);
210 // Face culling is enabled to hide the backwards facing sides of the cube
211 // This is sufficient to render a single object; for more complex scenes depth-testing might be required
212 mRenderer.SetProperty(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK);
216 * Creates new actor and attaches renderer.
220 Window window = mApplication.GetWindow();
222 float quarterWindowWidth = window.GetSize().GetWidth() * 0.25f;
223 mActor = Actor::New();
224 mActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
225 mActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
226 mActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 0.0f));
227 mActor.SetProperty(Actor::Property::SIZE, Vector3(quarterWindowWidth, quarterWindowWidth, quarterWindowWidth));
228 mActor.AddRenderer(mRenderer);
237 mAnimation = Animation::New(5.0f);
238 mAnimation.SetLooping(true);
239 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::ZAXIS));
240 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::YAXIS));
241 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::XAXIS));
246 Application& mApplication;
251 TextureSet mTextureSet;
253 Animation mAnimation;
256 int DALI_EXPORT_API main(int argc, char** argv)
258 Application application = Application::New(&argc, &argv);
259 TexturedCubeController test(application);
260 application.MainLoop();