DALi Version 2.0.11
[platform/core/uifw/dali-demo.git] / examples / waves / utils.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17 #include "utils.h"
18 #include "dali-toolkit/dali-toolkit.h"
19 #include <fstream>
20
21 using namespace Dali;
22 using namespace Dali::Toolkit;
23
24 Vector3 ToHueSaturationLightness(Vector3 rgb)
25 {
26   float min = std::min(rgb.r, std::min(rgb.g, rgb.b));
27   float max = std::max(rgb.r, std::max(rgb.g, rgb.b));
28
29   Vector3 hsl(max - min, 0.f, (max + min) * .5f);
30   if (hsl.x * hsl.x > .0f)
31   {
32     hsl.y = hsl.x / max;
33     if (max == rgb.r)
34     {
35       hsl.x = (rgb.g - rgb.b) / hsl.x;
36     }
37     else if(max == rgb.g)
38     {
39       hsl.x = 2.f + (rgb.b - rgb.r) / hsl.x;
40     }
41     else
42     {
43       hsl.x = 4.f + (rgb.r - rgb.g) / hsl.x;
44     }
45     hsl.x *= 60.f;
46     if (hsl.x < 0.f)
47     {
48       hsl.x += 360.f;
49     }
50   }
51   else
52   {
53     hsl.y = 0.f;
54   }
55
56   return hsl;
57 }
58
59 Vector3 FromHueSaturationLightness(Vector3 hsl)
60 {
61   Vector3 rgb;
62   if (hsl.y * hsl.y > 0.f)
63   {
64     if(hsl.x >= 360.f)
65     {
66       hsl.x -= 360.f;
67     }
68     hsl.x /= 60.f;
69
70     int i = FastFloor(hsl.x);
71     float ff = hsl.x - i;
72     float p = hsl.z * (1.0 - hsl.y);
73     float q = hsl.z * (1.0 - (hsl.y * ff));
74     float t = hsl.z * (1.0 - (hsl.y * (1.f - ff)));
75
76     switch (i)
77     {
78     case 0:
79       rgb.r = hsl.z;
80       rgb.g = t;
81       rgb.b = p;
82       break;
83
84     case 1:
85       rgb.r = q;
86       rgb.g = hsl.z;
87       rgb.b = p;
88       break;
89
90     case 2:
91       rgb.r = p;
92       rgb.g = hsl.z;
93       rgb.b = t;
94       break;
95
96     case 3:
97       rgb.r = p;
98       rgb.g = q;
99       rgb.b = hsl.z;
100       break;
101
102     case 4:
103       rgb.r = t;
104       rgb.g = p;
105       rgb.b = hsl.z;
106       break;
107
108     case 5:
109     default:
110       rgb.r = hsl.z;
111       rgb.g = p;
112       rgb.b = q;
113       break;
114     }
115   }
116   else
117   {
118     rgb = Vector3::ONE * hsl.z;
119   }
120
121   return rgb;
122 }
123
124 Geometry CreateTesselatedQuad(unsigned int xVerts, unsigned int yVerts,
125   Vector2 scale, VertexFn positionFn, VertexFn texCoordFn)
126 {
127   DALI_ASSERT_DEBUG(xVerts > 1 && yVerts > 1);
128   int numVerts = xVerts * yVerts;
129   struct Vertex
130   {
131     Vector2 aPosition;
132     Vector2 aTexCoord;
133   };
134   std::vector<Vertex> vertices;
135   vertices.reserve( numVerts);
136
137   float dx = 1.f / (xVerts - 1);
138   float dz = 1.f / (yVerts - 1);
139
140   Vector2 pos{ 0.f, 0.f };
141   for (unsigned int i = 0; i < yVerts; ++i)
142   {
143     pos.x = float(int((i & 1) * 2) - 1) * dx * .25f;
144     for (unsigned int j = 0; j < xVerts; ++j)
145     {
146       auto vPos = pos + Vector2{ -.5f, -.5f };
147       vertices.push_back(Vertex{ (positionFn ? positionFn(vPos) : vPos) * scale,
148         texCoordFn ? texCoordFn(pos) : pos });
149       pos.x += dx;
150     }
151
152     pos.y += dz;
153   }
154
155   VertexBuffer vertexBuffer = VertexBuffer::New( Property::Map()
156     .Add( "aPosition", Property::VECTOR2 )
157     .Add( "aTexCoord", Property::VECTOR2 ));
158   vertexBuffer.SetData(vertices.data(), vertices.size());
159
160   int numInds = (xVerts - 1) * (yVerts - 1) * 6;
161   std::vector<uint16_t> indices;
162   indices.reserve(numInds);
163
164   for (unsigned int i = 1; i < yVerts; ++i)
165   {
166     if ((i & 1) == 0)
167     {
168       for (unsigned int j = 1; j < xVerts; ++j)
169       {
170         int iBase = i * xVerts + j;
171         indices.push_back(iBase);
172         indices.push_back(iBase - 1);
173         indices.push_back(iBase - xVerts - 1);
174         indices.push_back(indices.back());
175         indices.push_back(iBase - xVerts);
176         indices.push_back(iBase);
177       }
178     }
179     else
180     {
181       for (unsigned int j = 1; j < xVerts; ++j)
182       {
183         int iBase = i * xVerts + j;
184         indices.push_back(iBase);
185         indices.push_back(iBase - 1);
186         indices.push_back(iBase - xVerts);
187         indices.push_back(indices.back());
188         indices.push_back(iBase - 1);
189         indices.push_back(iBase - xVerts - 1);
190       }
191     }
192   }
193
194   Geometry geom = Geometry::New();
195   geom.AddVertexBuffer(vertexBuffer);
196   geom.SetIndexBuffer(indices.data(), indices.size());
197   return geom;
198 }
199
200 Texture LoadTexture(const std::string& path)
201 {
202   PixelData pixelData = SyncImageLoader::Load(path);
203
204   Texture texture = Texture::New(TextureType::TEXTURE_2D, pixelData.GetPixelFormat(),
205     pixelData.GetWidth(), pixelData.GetHeight());
206   texture.Upload(pixelData);
207   return texture;
208 }
209
210 Renderer CreateRenderer(TextureSet textures, Geometry geometry, Shader shader, uint32_t options)
211 {
212   Renderer renderer = Renderer::New(geometry, shader);
213   renderer.SetProperty(Renderer::Property::BLEND_MODE,
214     (options & OPTION_BLEND) ? BlendMode::ON : BlendMode::OFF);
215   renderer.SetProperty(Renderer::Property::DEPTH_TEST_MODE,
216     (options & OPTION_DEPTH_TEST) ? DepthTestMode::ON : DepthTestMode::OFF);
217   renderer.SetProperty(Renderer::Property::DEPTH_WRITE_MODE,
218     (options & OPTION_DEPTH_WRITE) ? DepthWriteMode::ON : DepthWriteMode::OFF);
219   renderer.SetProperty(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::BACK);
220
221   if (!textures)
222   {
223     textures = TextureSet::New();
224   }
225
226   renderer.SetTextures(textures);
227   return renderer;
228 }
229
230 void CenterActor(Actor actor)
231 {
232   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
233   actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
234 }
235
236 Actor CreateActor()
237 {
238   auto actor = Actor::New();
239   CenterActor(actor);
240   return actor;
241 }
242
243 Renderer CloneRenderer(Renderer original)
244 {
245   Geometry geom = original.GetGeometry();
246   Shader shader = original.GetShader();
247   Renderer clone = Renderer::New(geom, shader);
248
249   // Copy properties.
250   Property::IndexContainer indices;
251   original.GetPropertyIndices(indices);
252
253   for (auto& i: indices)
254   {
255     auto actualIndex = Dali::PropertyRanges::DEFAULT_RENDERER_PROPERTY_START_INDEX + i;
256     clone.SetProperty(actualIndex, original.GetProperty(actualIndex));
257   }
258
259   // Copy texture references (and create TextureSet, if there's any textures).
260   TextureSet ts = original.GetTextures();
261   clone.SetTextures(ts);
262
263   return clone;
264 }
265
266 Actor CloneActor(Actor original)
267 {
268   using namespace Dali;
269
270   auto clone = Actor::New();
271   clone.SetProperty(Actor::Property::NAME, original.GetProperty(Actor::Property::NAME));
272
273   // Copy properties.
274   // Don't copy every single one of them.
275   // Definitely don't copy resize policy related things, which will internally enable
276   // relayout, which in turn will result in losing the ability to set Z size.
277   for (auto i : {
278     Actor::Property::PARENT_ORIGIN,
279     Actor::Property::ANCHOR_POINT,
280     Actor::Property::SIZE,
281     Actor::Property::POSITION,
282     Actor::Property::ORIENTATION,
283     Actor::Property::SCALE,
284     Actor::Property::VISIBLE,
285     Actor::Property::COLOR,
286     Actor::Property::NAME,
287   })
288   {
289     clone.SetProperty(i, original.GetProperty(i));
290   }
291
292   // Clone renderers.
293   for(unsigned int i = 0; i < original.GetRendererCount(); ++i)
294   {
295     auto rClone = CloneRenderer(original.GetRendererAt(i));
296     clone.AddRenderer(rClone);
297   }
298
299   // Recurse into children.
300   for(unsigned int i = 0; i < original.GetChildCount(); ++i)
301   {
302     Actor newChild = CloneActor(original.GetChildAt(i));
303     clone.Add(newChild);
304   }
305
306   return clone;
307 }