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>
21 #include "generated/rendering-textured-cube-vert.h"
22 #include "generated/rendering-textured-cube-frag.h"
25 using namespace Toolkit;
30 const char* TEXTURE_URL = DEMO_IMAGE_DIR "wood.png";
34 // This example shows how to create textured cube
36 class TexturedCubeController : public ConnectionTracker
39 TexturedCubeController(Application& application)
40 : mApplication(application)
42 // Connect to the Application's Init signal
43 mApplication.InitSignal().Connect(this, &TexturedCubeController::Create);
46 ~TexturedCubeController()
48 // Nothing to do here;
51 // The Init signal is received once (only) during the Application lifetime
52 void Create(Application& application)
54 // Get a handle to the window
55 Window window = application.GetWindow();
56 window.SetBackgroundColor(Color::WHITE);
58 // Step 1. Create shader
61 // Step 2. Load a texture
64 // Step 3. Prepare geometry
67 // Step 4. Create a renderer
70 // Step 5. Create an Actor
73 // Step 6. Play animation to rotate the cube
76 // Respond to a click anywhere on the window
77 window.GetRootLayer().TouchedSignal().Connect(this, &TexturedCubeController::OnTouch);
79 // Respond to key events
80 window.KeyEventSignal().Connect(this, &TexturedCubeController::OnKeyEvent);
83 bool OnTouch(Actor actor, const TouchEvent& touch)
85 // quit the application
91 * @brief Called when any key event is received
93 * Will use this to quit the application if Back or the Escape key is received
94 * @param[in] event The key event information
96 void OnKeyEvent(const KeyEvent& event)
98 if(event.GetState() == KeyEvent::DOWN)
100 if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
108 * @brief CreateCubeGeometry
109 * This function creates a cube geometry including texture coordinates.
110 * Also it demonstrates using the indexed draw feature by setting an index array.
112 void CreateCubeGeometry()
120 Vertex vertices[] = {
121 {Vector3(1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
122 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 0.0)},
123 {Vector3(1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)},
124 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
125 {Vector3(1.0f, -1.0f, 1.0f), Vector2(0.0, 0.0)},
126 {Vector3(1.0f, 1.0f, 1.0f), Vector2(0.0, 1.0)},
127 {Vector3(1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
128 {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
129 {Vector3(1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)},
130 {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 1.0)},
131 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
132 {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 1.0)},
133 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
134 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
135 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 1.0)},
136 {Vector3(1.0f, 1.0f, -1.0f), Vector2(1.0, 1.0)},
137 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
138 {Vector3(1.0f, 1.0f, 1.0f), Vector2(0.0, 1.0)},
139 {Vector3(1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
140 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 0.0)},
141 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(0.0, 0.0)},
142 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
143 {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
144 {Vector3(1.0f, -1.0f, 1.0f), Vector2(0.0, 0.0)},
145 {Vector3(1.0f, 1.0f, 1.0f), Vector2(1.0, 1.0)},
146 {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
147 {Vector3(1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
148 {Vector3(1.0f, -1.0f, 1.0f), Vector2(1.0, 1.0)},
149 {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
150 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(0.0, 0.0)},
151 {Vector3(-1.0f, -1.0f, -1.0f), Vector2(1.0, 1.0)},
152 {Vector3(-1.0f, -1.0f, 1.0f), Vector2(1.0, 0.0)},
153 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
154 {Vector3(1.0f, 1.0f, -1.0f), Vector2(1.0, 1.0)},
155 {Vector3(-1.0f, 1.0f, -1.0f), Vector2(1.0, 0.0)},
156 {Vector3(-1.0f, 1.0f, 1.0f), Vector2(0.0, 0.0)},
159 VertexBuffer vertexBuffer = VertexBuffer::New(Property::Map()
160 .Add("aPosition", Property::VECTOR3)
161 .Add("aTexCoord", Property::VECTOR2));
162 vertexBuffer.SetData(vertices, sizeof(vertices) / sizeof(Vertex));
165 const unsigned short INDEX_CUBE[] = {
166 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};
167 mGeometry = Geometry::New();
168 mGeometry.AddVertexBuffer(vertexBuffer);
169 mGeometry.SetIndexBuffer(INDEX_CUBE,
170 sizeof(INDEX_CUBE) / sizeof(INDEX_CUBE[0]));
171 mGeometry.SetType(Geometry::TRIANGLES);
175 * Creates a shader using SHADER_RENDERING_TEXTURED_CUBE_VERT and SHADER_RENDERING_TEXTURED_CUBE_FRAG
177 * Shaders are very basic and all they do is transforming vertices and sampling
180 void CreateCubeShader()
182 mShader = Shader::New(SHADER_RENDERING_TEXTURED_CUBE_VERT, SHADER_RENDERING_TEXTURED_CUBE_FRAG);
186 * This function loads a pixel data from a file. In order to load it we use SyncImageLoader utility.
187 * If loading succeeds returned PixelData object can be used to create a texture.
188 * Texture must be uploaded. In the end the texture must be set on the TextureSet object.
192 // Load image from file
193 PixelData pixels = SyncImageLoader::Load(TEXTURE_URL);
195 Texture texture = Texture::New(TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight());
196 texture.Upload(pixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight());
199 mTextureSet = TextureSet::New();
200 mTextureSet.SetTexture(0, texture);
204 * Function creates renderer. It turns on depth test and depth write.
206 void CreateRenderer()
208 mRenderer = Renderer::New(mGeometry, mShader);
209 mRenderer.SetTextures(mTextureSet);
211 // Face culling is enabled to hide the backwards facing sides of the cube
212 // This is sufficient to render a single object; for more complex scenes depth-testing might be required
213 mRenderer.SetProperty(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK);
217 * Creates new actor and attaches renderer.
221 Window window = mApplication.GetWindow();
223 float quarterWindowWidth = window.GetSize().GetWidth() * 0.25f;
224 mActor = Actor::New();
225 mActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
226 mActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
227 mActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 0.0f));
228 mActor.SetProperty(Actor::Property::SIZE, Vector3(quarterWindowWidth, quarterWindowWidth, quarterWindowWidth));
229 mActor.AddRenderer(mRenderer);
238 mAnimation = Animation::New(5.0f);
239 mAnimation.SetLooping(true);
240 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::ZAXIS));
241 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::YAXIS));
242 mAnimation.AnimateBy(Property(mActor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(360)), Vector3::XAXIS));
247 Application& mApplication;
252 TextureSet mTextureSet;
254 Animation mAnimation;
257 int DALI_EXPORT_API main(int argc, char** argv)
259 Application application = Application::New(&argc, &argv);
260 TexturedCubeController test(application);
261 application.MainLoop();