Commit 475e959d61138abb18e3192f5e7accf294427fe0
1 parent
770d0315
Added Waves example.
- tilt, or if not supported, pan, to rotate light; - double tap to trigger color transition; Change-Id: I7de09c65309f6b069566cf330ebf18904d36a885
Showing
9 changed files
with
984 additions
and
4 deletions
com.samsung.dali-demo.xml
| @@ -325,6 +325,9 @@ | @@ -325,6 +325,9 @@ | ||
| 325 | <ui-application appid="web-view.example" exec="/usr/apps/com.samsung.dali-demo/bin/web-view.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | 325 | <ui-application appid="web-view.example" exec="/usr/apps/com.samsung.dali-demo/bin/web-view.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> |
| 326 | <label>Web View</label> | 326 | <label>Web View</label> |
| 327 | </ui-application> | 327 | </ui-application> |
| 328 | + <ui-application appid="waves.example" exec="/usr/apps/com.samsung.dali-demo/bin/waves.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> | ||
| 329 | + <label>Waves</label> | ||
| 330 | + </ui-application> | ||
| 328 | 331 | ||
| 329 | <!-- END OF ALPHABETICAL ORDER SORT. --> | 332 | <!-- END OF ALPHABETICAL ORDER SORT. --> |
| 330 | 333 |
demo/dali-demo.cpp
| @@ -38,6 +38,7 @@ int DALI_EXPORT_API main(int argc, char** argv) | @@ -38,6 +38,7 @@ int DALI_EXPORT_API main(int argc, char** argv) | ||
| 38 | // Create the demo launcher | 38 | // Create the demo launcher |
| 39 | DaliTableView demo(app); | 39 | DaliTableView demo(app); |
| 40 | 40 | ||
| 41 | + demo.AddExample(Example("animated-gradient-card-active.example", DALI_DEMO_STR_TITLE_CARD_ACTIVE)); | ||
| 41 | demo.AddExample(Example("blocks.example", DALI_DEMO_STR_TITLE_BLOCKS)); | 42 | demo.AddExample(Example("blocks.example", DALI_DEMO_STR_TITLE_BLOCKS)); |
| 42 | demo.AddExample(Example("bezier-curve.example", DALI_DEMO_STR_TITLE_BEZIER_CURVE)); | 43 | demo.AddExample(Example("bezier-curve.example", DALI_DEMO_STR_TITLE_BEZIER_CURVE)); |
| 43 | demo.AddExample(Example("bubble-effect.example", DALI_DEMO_STR_TITLE_BUBBLES)); | 44 | demo.AddExample(Example("bubble-effect.example", DALI_DEMO_STR_TITLE_BUBBLES)); |
| @@ -54,12 +55,11 @@ int DALI_EXPORT_API main(int argc, char** argv) | @@ -54,12 +55,11 @@ int DALI_EXPORT_API main(int argc, char** argv) | ||
| 54 | demo.AddExample(Example("reflection-demo.example", DALI_DEMO_STR_TITLE_REFLECTION)); | 55 | demo.AddExample(Example("reflection-demo.example", DALI_DEMO_STR_TITLE_REFLECTION)); |
| 55 | demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION)); | 56 | demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION)); |
| 56 | demo.AddExample(Example("renderer-stencil.example", DALI_DEMO_STR_TITLE_RENDERER_STENCIL)); | 57 | demo.AddExample(Example("renderer-stencil.example", DALI_DEMO_STR_TITLE_RENDERER_STENCIL)); |
| 57 | - demo.AddExample(Example("shadows-and-lights.example", DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS)); | ||
| 58 | - demo.AddExample(Example("sparkle.example", DALI_DEMO_STR_TITLE_SPARKLE)); | ||
| 59 | demo.AddExample(Example("rendering-skybox.example", DALI_DEMO_STR_TITLE_SKYBOX)); | 58 | demo.AddExample(Example("rendering-skybox.example", DALI_DEMO_STR_TITLE_SKYBOX)); |
| 60 | demo.AddExample(Example("rendering-basic-pbr.example", DALI_DEMO_STR_TITLE_PBR)); | 59 | demo.AddExample(Example("rendering-basic-pbr.example", DALI_DEMO_STR_TITLE_PBR)); |
| 61 | - demo.AddExample(Example("animated-gradient-call-active.example", DALI_DEMO_STR_TITLE_CALL_ACTIVE)); | ||
| 62 | - demo.AddExample(Example("animated-gradient-card-active.example", DALI_DEMO_STR_TITLE_CARD_ACTIVE)); | 60 | + demo.AddExample(Example("shadows-and-lights.example", DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS)); |
| 61 | + demo.AddExample(Example("sparkle.example", DALI_DEMO_STR_TITLE_SPARKLE)); | ||
| 62 | + demo.AddExample(Example("waves.example", DALI_DEMO_STR_TITLE_WAVES)); | ||
| 63 | 63 | ||
| 64 | demo.SortAlphabetically(true); | 64 | demo.SortAlphabetically(true); |
| 65 | 65 |
examples/waves/utils.cpp
0 → 100644
| 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 | +} |
examples/waves/utils.h
0 → 100644
| 1 | +#ifndef WAVES_UTILS_H_ | ||
| 2 | +#define WAVES_UTILS_H_ | ||
| 3 | +/* | ||
| 4 | + * Copyright (c) 2020 Samsung Electronics Co., Ltd. | ||
| 5 | + * | ||
| 6 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 7 | + * you may not use this file except in compliance with the License. | ||
| 8 | + * You may obtain a copy of the License at | ||
| 9 | + * | ||
| 10 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 11 | + * | ||
| 12 | + * Unless required by applicable law or agreed to in writing, software | ||
| 13 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 14 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 15 | + * See the License for the specific language governing permissions and | ||
| 16 | + * limitations under the License. | ||
| 17 | + * | ||
| 18 | + */ | ||
| 19 | +#include "dali/public-api/actors/actor.h" | ||
| 20 | +#include "dali/public-api/rendering/geometry.h" | ||
| 21 | +#include "dali/public-api/rendering/renderer.h" | ||
| 22 | +#include "dali/public-api/rendering/shader.h" | ||
| 23 | +#include "dali/public-api/rendering/texture.h" | ||
| 24 | +#include "dali/public-api/math/vector3.h" | ||
| 25 | +#include <cmath> | ||
| 26 | + | ||
| 27 | +// | ||
| 28 | +// Maths | ||
| 29 | +// | ||
| 30 | +inline | ||
| 31 | +float FastFloor(float x) | ||
| 32 | +{ | ||
| 33 | + return static_cast<int>(x) - static_cast<int>(x < 0); | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +inline | ||
| 37 | +float Sign(float x) | ||
| 38 | +{ | ||
| 39 | + return float(x > 0.f) - float(x < .0f); | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +template <typename T> | ||
| 43 | +inline | ||
| 44 | +typename std::decay<T>::type Lerp( | ||
| 45 | + const T& min, const T& max, float alpha) | ||
| 46 | +{ | ||
| 47 | + return min + (max - min) * alpha; | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +template <typename T> | ||
| 51 | +T Normalized(T v) | ||
| 52 | +{ | ||
| 53 | + v.Normalize(); | ||
| 54 | + return v; | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +// | ||
| 58 | +// Files | ||
| 59 | +// | ||
| 60 | +///@brief Converts RGB values (in the 0..1 range) to HSL, where hue is in degrees, | ||
| 61 | +/// in the 0..360 range, and saturation and lightness are in the 0..1 range. | ||
| 62 | +Dali::Vector3 ToHueSaturationLightness(Dali::Vector3 rgb); | ||
| 63 | + | ||
| 64 | +///@brief Converts HSL values, where hue is in degrees, in the 0..360 range, and | ||
| 65 | +/// saturation and lightness are in 0..1 to RGB (in the 0..1 range) | ||
| 66 | +Dali::Vector3 FromHueSaturationLightness(Dali::Vector3 hsl); | ||
| 67 | + | ||
| 68 | +// | ||
| 69 | +// Dali entities | ||
| 70 | +// | ||
| 71 | +using VertexFn = Dali::Vector2(*)(const Dali::Vector2&); | ||
| 72 | + | ||
| 73 | +///@brief Creates a tesselated quad with @a xVerts vertices horizontally and @a yVerts | ||
| 74 | +/// vertices vertically. Allows the use of an optional @a shaderFn, which can be used to | ||
| 75 | +/// modify the vertex positions - these will be in the [{ 0.f, 0.f}, { 1.f, 1.f}] range. | ||
| 76 | +/// After returning from the shader, they're transformed | ||
| 77 | +Dali::Geometry CreateTesselatedQuad(unsigned int xVerts, unsigned int yVerts, | ||
| 78 | + Dali::Vector2 scale, VertexFn positionFn = nullptr, VertexFn texCoordFn = nullptr); | ||
| 79 | + | ||
| 80 | +Dali::Texture LoadTexture(const std::string& path); | ||
| 81 | + | ||
| 82 | +enum RendererOptions | ||
| 83 | +{ | ||
| 84 | + OPTION_NONE = 0x0, | ||
| 85 | + OPTION_BLEND = 0x01, | ||
| 86 | + OPTION_DEPTH_TEST = 0x02, | ||
| 87 | + OPTION_DEPTH_WRITE = 0x04 | ||
| 88 | +}; | ||
| 89 | + | ||
| 90 | +///@brief Creates a renderer with the given @a textures set, @a geometry, @a shader | ||
| 91 | +/// and @a options from above. | ||
| 92 | +///@note Back face culling is on. | ||
| 93 | +///@note If textures is not a valid handle, an empty texture set will be created. | ||
| 94 | +Dali::Renderer CreateRenderer(Dali::TextureSet textures, Dali::Geometry geometry, | ||
| 95 | + Dali::Shader shader, uint32_t options = OPTION_NONE); | ||
| 96 | + | ||
| 97 | +///@brief Sets @a actor's anchor point and parent origin to center. | ||
| 98 | +void CenterActor(Dali::Actor actor); | ||
| 99 | + | ||
| 100 | +///@brief Creates an empty and centered actor. | ||
| 101 | +Dali::Actor CreateActor(); | ||
| 102 | + | ||
| 103 | +///@brief Creates a copy of @a original, sharing the same geometry and shader and | ||
| 104 | +/// copying each properties. | ||
| 105 | +///@note Breaks if @a original has any custom properties. TODO: fix. | ||
| 106 | +Dali::Renderer CloneRenderer(Dali::Renderer original); | ||
| 107 | + | ||
| 108 | +///@brief Creates a copy of @a original, cloning each renderer, and a select set | ||
| 109 | +/// of properties: parent origin, anchor point, size, position, orientation, scale, | ||
| 110 | +/// visible, color and name. | ||
| 111 | +///@note Does not copy resize policy related properties, as setting those, even if | ||
| 112 | +/// default, will break the ability to specify a size for the actor in Z. | ||
| 113 | +Dali::Actor CloneActor(Dali::Actor original); | ||
| 114 | + | ||
| 115 | +#endif /* EXAMPLES_PARTICLES_UTILS_H_ */ |
examples/waves/waves-example.cpp
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (c) 2020 Samsung Electronics Co., Ltd. | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 ( "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 | + | ||
| 18 | +// INTERNAL INCLUDES | ||
| 19 | +#include "utils.h" | ||
| 20 | +#include "dali/devel-api/adaptor-framework/tilt-sensor.h" | ||
| 21 | +#include "dali/public-api/adaptor-framework/application.h" | ||
| 22 | +#include "dali/public-api/adaptor-framework/key.h" | ||
| 23 | +#include "dali/public-api/animation/animation.h" | ||
| 24 | +#include "dali/public-api/events/pan-gesture-detector.h" | ||
| 25 | +#include "dali/public-api/events/tap-gesture-detector.h" | ||
| 26 | +#include "dali/public-api/events/key-event.h" | ||
| 27 | +#include "dali/public-api/actors/camera-actor.h" | ||
| 28 | +#include "dali/public-api/actors/layer.h" | ||
| 29 | +#include "dali/public-api/render-tasks/render-task.h" | ||
| 30 | +#include "dali/public-api/render-tasks/render-task-list.h" | ||
| 31 | +#include <fstream> | ||
| 32 | +#include <iostream> | ||
| 33 | +#include <numeric> | ||
| 34 | + | ||
| 35 | +using namespace Dali; | ||
| 36 | + | ||
| 37 | +namespace | ||
| 38 | +{ | ||
| 39 | + | ||
| 40 | +constexpr std::string_view WAVES_VSH = | ||
| 41 | + "#define FMA(a, b, c) ((a) * (b) + (c))\n" // fused multiply-add | ||
| 42 | +DALI_COMPOSE_SHADER( | ||
| 43 | + precision highp float; | ||
| 44 | + | ||
| 45 | + const float kTile = 1.; | ||
| 46 | + | ||
| 47 | + const float kPi = 3.1415926535; | ||
| 48 | + const float kEpsilon = 1. / 32.; | ||
| 49 | + | ||
| 50 | + // DALI uniforms | ||
| 51 | + uniform vec3 uSize; | ||
| 52 | + uniform mat4 uModelView; | ||
| 53 | + uniform mat4 uProjection; | ||
| 54 | + uniform mat3 uNormalMatrix; | ||
| 55 | + | ||
| 56 | + // our uniforms | ||
| 57 | + uniform float uTime; | ||
| 58 | + uniform vec2 uScrollScale; | ||
| 59 | + uniform float uWaveRate; | ||
| 60 | + uniform float uWaveAmplitude; | ||
| 61 | + uniform float uParallaxAmount; | ||
| 62 | + | ||
| 63 | + attribute vec2 aPosition; | ||
| 64 | + attribute vec2 aTexCoord; | ||
| 65 | + | ||
| 66 | + varying vec2 vUv; | ||
| 67 | + varying vec3 vViewPos; | ||
| 68 | + varying vec3 vNormal; | ||
| 69 | + varying float vHeight; | ||
| 70 | + | ||
| 71 | + float CubicHermite(float B, float C, float t) | ||
| 72 | + { | ||
| 73 | + float dCB = (C - B) * .5; | ||
| 74 | + float A = B - dCB; | ||
| 75 | + float D = B + dCB; | ||
| 76 | + vec3 p = vec3(D + .5 * (((B - C) * 3.) - A), A - 2.5 * B + 2. * C - D, | ||
| 77 | + .5 * (C - A)); | ||
| 78 | + return FMA(FMA(FMA(p.x, t, p.y), t, p.z), t, B); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + float Hash(float n) | ||
| 82 | + { | ||
| 83 | + return fract(sin(n) * 43751.5453123); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + float HeightAtTile(vec2 pos) | ||
| 87 | + { | ||
| 88 | + float rate = Hash(Hash(pos.x) * Hash(pos.y)); | ||
| 89 | + | ||
| 90 | + return (sin(uTime * rate * uWaveRate) * .5 + .5) * uWaveAmplitude; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + float CalculateHeight(vec2 position) | ||
| 94 | + { | ||
| 95 | + vec2 tile = floor(position); | ||
| 96 | + position = fract(position); | ||
| 97 | + | ||
| 98 | + vec2 cp = vec2( | ||
| 99 | + CubicHermite( | ||
| 100 | + HeightAtTile(tile + vec2( kTile * -0.5, kTile * -0.5)), | ||
| 101 | + HeightAtTile(tile + vec2( kTile * +0.5, kTile * -0.5)), | ||
| 102 | + position.x), | ||
| 103 | + CubicHermite( | ||
| 104 | + HeightAtTile(tile + vec2( kTile * -0.5, kTile * +0.5)), | ||
| 105 | + HeightAtTile(tile + vec2( kTile * +0.5, kTile * +0.5)), | ||
| 106 | + position.x) | ||
| 107 | + ); | ||
| 108 | + | ||
| 109 | + return CubicHermite(cp.x, cp.y, position.y); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + vec3 CalculateNormal(vec2 position) | ||
| 113 | + { | ||
| 114 | + vec3 normal = vec3( | ||
| 115 | + CalculateHeight(vec2(position.x - kEpsilon, position.y)) - | ||
| 116 | + CalculateHeight(vec2(position.x + kEpsilon, position.y)), | ||
| 117 | + .25, | ||
| 118 | + CalculateHeight(vec2(position.x, position.y - kEpsilon)) - | ||
| 119 | + CalculateHeight(vec2(position.x, position.y + kEpsilon)) | ||
| 120 | + ); | ||
| 121 | + return normal; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + void main() | ||
| 125 | + { | ||
| 126 | + vUv = aTexCoord; | ||
| 127 | + | ||
| 128 | + vec2 scrollPosition = aPosition * uScrollScale + vec2(0., uTime * -kPi); | ||
| 129 | + vNormal = uNormalMatrix * CalculateNormal(scrollPosition); | ||
| 130 | + | ||
| 131 | + float h = CalculateHeight(scrollPosition); | ||
| 132 | + vHeight = h * uParallaxAmount; | ||
| 133 | + vec3 position = vec3(aPosition.x, h, aPosition.y); | ||
| 134 | + | ||
| 135 | + vec4 viewPosition = uModelView * vec4(position * uSize, 1.); | ||
| 136 | + vViewPos = -viewPosition.xyz; | ||
| 137 | + | ||
| 138 | + gl_Position = uProjection * viewPosition; | ||
| 139 | + }); | ||
| 140 | + | ||
| 141 | +constexpr std::string_view WAVES_FSH = DALI_COMPOSE_SHADER( | ||
| 142 | + precision highp float; | ||
| 143 | + | ||
| 144 | + uniform vec4 uColor; // DALi | ||
| 145 | + uniform sampler2D uNormalMap; // DALi | ||
| 146 | + | ||
| 147 | + uniform vec3 uInvLightDir; | ||
| 148 | + uniform vec3 uLightColorSqr; | ||
| 149 | + uniform vec3 uAmbientColor; | ||
| 150 | + | ||
| 151 | + uniform float uNormalMapWeight; | ||
| 152 | + uniform float uSpecularity; | ||
| 153 | + | ||
| 154 | + varying vec2 vUv; | ||
| 155 | + varying vec3 vNormal; | ||
| 156 | + varying vec3 vViewPos; | ||
| 157 | + varying float vHeight; | ||
| 158 | + | ||
| 159 | + float Rand(vec2 co) | ||
| 160 | + { | ||
| 161 | + return fract(sin(dot(co.xy, vec2(12.98981, 78.2331))) * 43758.5453); | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + float Sum(vec3 v) | ||
| 165 | + { | ||
| 166 | + return v.x + v.y + v.z; | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + void main() | ||
| 170 | + { | ||
| 171 | + vec3 viewPos = normalize(vViewPos); | ||
| 172 | + vec2 uv2 = vUv + vViewPos.xy / vViewPos.z * vHeight + vec2(.5, 0.); | ||
| 173 | + | ||
| 174 | + vec3 perturbNormal = texture2D(uNormalMap, vUv).rgb * 2. - 1.; | ||
| 175 | + vec3 perturbNormal2 = texture2D(uNormalMap, uv2).rgb * 2. - 1.; | ||
| 176 | + vec3 normal = normalize(vNormal + perturbNormal * uNormalMapWeight); | ||
| 177 | + vec3 normal2 = normalize(vNormal + perturbNormal2 * uNormalMapWeight); | ||
| 178 | + | ||
| 179 | + vec3 color = uAmbientColor; | ||
| 180 | + float d = max(0., dot(normal, -uInvLightDir)); | ||
| 181 | + color += uColor.rgb * d; | ||
| 182 | + | ||
| 183 | + vec3 reflected = reflect(uInvLightDir, normal); | ||
| 184 | + d = max(0., dot(reflected, viewPos)); | ||
| 185 | + color += pow(d, uSpecularity) * uLightColorSqr; | ||
| 186 | + | ||
| 187 | + reflected = reflect(uInvLightDir, normal2); | ||
| 188 | + d = max(0., dot(reflected, viewPos)); | ||
| 189 | + color += pow(d, uSpecularity) * uLightColorSqr; | ||
| 190 | + | ||
| 191 | + gl_FragColor = vec4(color, 1.); | ||
| 192 | + }); | ||
| 193 | + | ||
| 194 | +const float TIME_STEP = 0.0952664626; | ||
| 195 | + | ||
| 196 | +const std::string UNIFORM_LIGHT_COLOR_SQR = "uLightColorSqr"; | ||
| 197 | +const std::string UNIFORM_AMBIENT_COLOR = "uAmbientColor"; | ||
| 198 | +const std::string UNIFORM_INV_LIGHT_DIR = "uInvLightDir"; | ||
| 199 | +const std::string UNIFORM_SCROLL_SCALE = "uScrollScale"; | ||
| 200 | +const std::string UNIFORM_WAVE_RATE = "uWaveRate"; | ||
| 201 | +const std::string UNIFORM_WAVE_AMPLITUDE = "uWaveAmplitude"; | ||
| 202 | +const std::string UNIFORM_NORMAL_MAP_WEIGHT = "uNormalMapWeight"; | ||
| 203 | +const std::string UNIFORM_SPECULARITY = "uSpecularity"; | ||
| 204 | +const std::string UNIFORM_PARALLAX_AMOUNT = "uParallaxAmount"; | ||
| 205 | +const std::string UNIFORM_TIME = "uTime"; | ||
| 206 | + | ||
| 207 | +const Vector3 WAVES_COLOR { .78f, .64f, .26f }; | ||
| 208 | +const Vector3 LIGHT_COLOR { 1.0f, 0.91f, 0.6f }; | ||
| 209 | +const Vector3 AMBIENT_COLOR { .002f, .001f, .001f }; | ||
| 210 | + | ||
| 211 | +const Vector3 INV_LIGHT_DIR = Normalized(Vector3{ .125f, .8f, -.55f }); | ||
| 212 | + | ||
| 213 | +const Vector2 SCROLL_SCALE{ 1.f, 3.5f }; | ||
| 214 | +const float WAVE_RATE = 12.17f; | ||
| 215 | +const float WAVE_AMPLITUDE = 1.f; | ||
| 216 | +const float NORMAL_MAP_WEIGHT = 0.05f; | ||
| 217 | +const float SPECULARITY = 512.f; | ||
| 218 | +const float PARALLAX_AMOUNT = .25f; | ||
| 219 | + | ||
| 220 | +const float TILT_RANGE_DEGREES = 30.f; | ||
| 221 | + | ||
| 222 | +const float TRANSITION_DURATION = 1.2f; | ||
| 223 | +const float TRANSITION_TIME_SCALE = 6.f; | ||
| 224 | + | ||
| 225 | +const std::string_view NORMAL_MAP_NAME = "noise512.png"; | ||
| 226 | + | ||
| 227 | +Vector3 RandomColor() | ||
| 228 | +{ | ||
| 229 | + float r = .5f + (rand() % RAND_MAX) / float(RAND_MAX) * .5f; | ||
| 230 | + float g = .5f + (rand() % RAND_MAX) / float(RAND_MAX) * .5f; | ||
| 231 | + float b = .5f + (rand() % RAND_MAX) / float(RAND_MAX) * .5f; | ||
| 232 | + return Vector3(r, g, b); | ||
| 233 | +} | ||
| 234 | + | ||
| 235 | +class TiltFilter | ||
| 236 | +{ | ||
| 237 | +public: | ||
| 238 | + void Reset() | ||
| 239 | + { | ||
| 240 | + std::fill(mTiltSamples, mTiltSamples + FILTER_SIZE, Vector2(.0f, .0f)); | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + void Add(Dali::Vector2 tilt) | ||
| 244 | + { | ||
| 245 | + mTiltSamples[mIdxNextSample] = tilt; | ||
| 246 | + mIdxNextSample = (mIdxNextSample + 1) % FILTER_SIZE; | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + Dali::Vector2 Filter() const | ||
| 250 | + { | ||
| 251 | + return std::accumulate(mTiltSamples, mTiltSamples + FILTER_SIZE, Vector2(.0f, .0f)) / FILTER_SIZE; | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | +private: | ||
| 255 | + enum { FILTER_SIZE = 8u }; | ||
| 256 | + | ||
| 257 | + Dali::Vector2 mTiltSamples[FILTER_SIZE]; | ||
| 258 | + size_t mIdxNextSample = 0; | ||
| 259 | +}; | ||
| 260 | + | ||
| 261 | +} // nonamespace | ||
| 262 | + | ||
| 263 | +class WavesExample : public ConnectionTracker | ||
| 264 | +{ | ||
| 265 | +public: | ||
| 266 | + WavesExample( Application& app ) | ||
| 267 | + : mApp( app ) | ||
| 268 | + { | ||
| 269 | + mApp.InitSignal().Connect( this, &WavesExample::Create ); | ||
| 270 | + mApp.TerminateSignal().Connect( this, &WavesExample::Destroy ); | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + ~WavesExample() = default; | ||
| 274 | + | ||
| 275 | +private: | ||
| 276 | + Application& mApp; | ||
| 277 | + | ||
| 278 | + CameraActor mCamera; // no ownership | ||
| 279 | + | ||
| 280 | + Actor mWaves; | ||
| 281 | + Shader mWaveShader; | ||
| 282 | + | ||
| 283 | + Property::Index mUInvLightDir; | ||
| 284 | + Property::Index mULightColorSqr; | ||
| 285 | + Property::Index mUAmbientColor; | ||
| 286 | + Property::Index mUWaveRate; | ||
| 287 | + Property::Index mUWaveAmplitude; | ||
| 288 | + Property::Index mUScrollScale; | ||
| 289 | + Property::Index mUNormalMapWeight; | ||
| 290 | + Property::Index mUSpecularity; | ||
| 291 | + Property::Index mUParallaxAmount; | ||
| 292 | + Property::Index mUTime; | ||
| 293 | + | ||
| 294 | + TapGestureDetector mDoubleTapGesture; | ||
| 295 | + | ||
| 296 | + TiltSensor mTiltSensor; | ||
| 297 | + TiltFilter mTiltFilter; | ||
| 298 | + | ||
| 299 | + PanGestureDetector mPanGesture; | ||
| 300 | + | ||
| 301 | + Animation mTimeAnim; | ||
| 302 | + Animation mTransitionAnim; | ||
| 303 | + | ||
| 304 | + void Create( Application& application ) | ||
| 305 | + { | ||
| 306 | + Window window = application.GetWindow(); | ||
| 307 | + auto rootLayer = window.GetRootLayer(); | ||
| 308 | + | ||
| 309 | + window.SetBackgroundColor(Vector4(WAVES_COLOR * .5f)); | ||
| 310 | + | ||
| 311 | + // Get camera | ||
| 312 | + RenderTaskList tasks = window.GetRenderTaskList(); | ||
| 313 | + RenderTask mainPass = tasks.GetTask(0); | ||
| 314 | + CameraActor camera = mainPass.GetCameraActor(); | ||
| 315 | + mCamera = camera; | ||
| 316 | + | ||
| 317 | + // NOTE: watchface doesn't tolerate modification of the camera well; | ||
| 318 | + /// we're better off rotating the world. | ||
| 319 | + Quaternion baseOrientation (Radian(Degree(-150.f)), Radian(M_PI), Radian(0.f)); | ||
| 320 | + | ||
| 321 | + auto shader = CreateShader(); | ||
| 322 | + | ||
| 323 | + // Create geometry | ||
| 324 | + Geometry geom = CreateTesselatedQuad(16, 64, Vector2{ .25f, 3.8f }, [](const Vector2& v) { | ||
| 325 | + float y = v.y + .5f; // 0..1 | ||
| 326 | + y = std::sqrt(y) - .5f; // perspective correction - increase vertex density closer to viewer | ||
| 327 | + | ||
| 328 | + float x = v.x + v.x * (1.f - y) * 5.5f; | ||
| 329 | + | ||
| 330 | + y -= .24f; // further translation | ||
| 331 | + return Vector2{ x, y }; | ||
| 332 | + }, [](const Vector2& v) { | ||
| 333 | + return Vector2{ v.x, std::sqrt(v.y) }; | ||
| 334 | + }); | ||
| 335 | + | ||
| 336 | + // Create texture | ||
| 337 | + auto normalMap = LoadTexture(std::string(DEMO_IMAGE_DIR) + NORMAL_MAP_NAME.data()); | ||
| 338 | + | ||
| 339 | + TextureSet textures = TextureSet::New(); | ||
| 340 | + textures.SetTexture(0, normalMap); | ||
| 341 | + | ||
| 342 | + Sampler sampler = Sampler::New(); | ||
| 343 | + sampler.SetFilterMode(FilterMode::NEAREST, FilterMode::NEAREST); | ||
| 344 | + sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::REPEAT); | ||
| 345 | + textures.SetSampler(0, sampler); | ||
| 346 | + | ||
| 347 | + // Create renderer | ||
| 348 | + Renderer renderer = CreateRenderer(textures, geom, shader, OPTION_DEPTH_TEST | OPTION_DEPTH_WRITE); | ||
| 349 | + | ||
| 350 | + auto waves = CreateActor(); | ||
| 351 | + auto size = Vector2(window.GetSize()); | ||
| 352 | + waves.SetProperty(Actor::Property::SIZE, Vector3(size.x, 100.f, size.y)); | ||
| 353 | + waves.SetProperty(Actor::Property::ORIENTATION, baseOrientation); | ||
| 354 | + waves.SetProperty(Actor::Property::COLOR, WAVES_COLOR); | ||
| 355 | + waves.AddRenderer(renderer); | ||
| 356 | + | ||
| 357 | + window.Add(waves); | ||
| 358 | + mWaves = waves; | ||
| 359 | + | ||
| 360 | + window.KeyEventSignal().Connect( this, &WavesExample::OnKeyEvent ); | ||
| 361 | + | ||
| 362 | + // Setup double tap detector for color change | ||
| 363 | + mDoubleTapGesture = TapGestureDetector::New(2); | ||
| 364 | + mDoubleTapGesture.Attach(rootLayer); | ||
| 365 | + mDoubleTapGesture.DetectedSignal().Connect(this, &WavesExample::OnDoubleTap); | ||
| 366 | + | ||
| 367 | + // Touch controls | ||
| 368 | + mTiltSensor = TiltSensor::Get(); | ||
| 369 | + if ( mTiltSensor.Start() ) | ||
| 370 | + { | ||
| 371 | + // Get notifications when the device is tilted | ||
| 372 | + mTiltSensor.TiltedSignal().Connect( this, &WavesExample::OnTilted ); | ||
| 373 | + } | ||
| 374 | + else | ||
| 375 | + { | ||
| 376 | + mPanGesture = PanGestureDetector::New(); | ||
| 377 | + mPanGesture.Attach(rootLayer); | ||
| 378 | + mPanGesture.DetectedSignal().Connect(this, &WavesExample::OnPan); | ||
| 379 | + } | ||
| 380 | + | ||
| 381 | + // Register for suspend / resume | ||
| 382 | + application.PauseSignal().Connect(this, &WavesExample::OnPause); | ||
| 383 | + application.ResumeSignal().Connect(this, &WavesExample::OnResume); | ||
| 384 | + | ||
| 385 | + // Create animation for the simulation of time | ||
| 386 | + Animation animTime = Animation::New(1.f); | ||
| 387 | + animTime.AnimateBy(Property(mWaveShader, mUTime), TIME_STEP); | ||
| 388 | + animTime.FinishedSignal().Connect(this, &WavesExample::OnTimeAnimFinished); | ||
| 389 | + animTime.Play(); | ||
| 390 | + mTimeAnim = animTime; | ||
| 391 | + } | ||
| 392 | + | ||
| 393 | + void Destroy( Application& app) | ||
| 394 | + { | ||
| 395 | + mCamera.Reset(); | ||
| 396 | + | ||
| 397 | + mDoubleTapGesture.Reset(); | ||
| 398 | + mPanGesture.Reset(); | ||
| 399 | + | ||
| 400 | + UnparentAndReset(mWaves); | ||
| 401 | + } | ||
| 402 | + | ||
| 403 | + Shader CreateShader() | ||
| 404 | + { | ||
| 405 | + Vector3 lightColorSqr{ LIGHT_COLOR }; | ||
| 406 | + Vector3 ambientColor = AMBIENT_COLOR; | ||
| 407 | + Vector3 invLightDir = INV_LIGHT_DIR; | ||
| 408 | + Vector2 scrollScale = SCROLL_SCALE; | ||
| 409 | + float waveRate = WAVE_RATE; | ||
| 410 | + float waveAmp = WAVE_AMPLITUDE; | ||
| 411 | + float normalMapWeight = NORMAL_MAP_WEIGHT; | ||
| 412 | + float specularity = SPECULARITY; | ||
| 413 | + float parallaxAmount = PARALLAX_AMOUNT; | ||
| 414 | + if (mWaveShader) | ||
| 415 | + { | ||
| 416 | + lightColorSqr = mWaveShader.GetProperty(mULightColorSqr).Get<Vector3>(); | ||
| 417 | + ambientColor = mWaveShader.GetProperty(mUAmbientColor).Get<Vector3>(); | ||
| 418 | + invLightDir = mWaveShader.GetProperty(mUInvLightDir).Get<Vector3>(); | ||
| 419 | + scrollScale = mWaveShader.GetProperty(mUScrollScale).Get<Vector2>(); | ||
| 420 | + waveRate = mWaveShader.GetProperty(mUWaveRate).Get<float>(); | ||
| 421 | + waveAmp = mWaveShader.GetProperty(mUWaveAmplitude).Get<float>(); | ||
| 422 | + normalMapWeight = mWaveShader.GetProperty(mUNormalMapWeight).Get<float>(); | ||
| 423 | + specularity = mWaveShader.GetProperty(mUSpecularity).Get<float>(); | ||
| 424 | + } | ||
| 425 | + | ||
| 426 | + Shader shader = Shader::New(WAVES_VSH.data(), WAVES_FSH.data(), Shader::Hint::MODIFIES_GEOMETRY); | ||
| 427 | + mULightColorSqr = shader.RegisterProperty(UNIFORM_LIGHT_COLOR_SQR, lightColorSqr); | ||
| 428 | + mUAmbientColor = shader.RegisterProperty(UNIFORM_AMBIENT_COLOR, ambientColor); | ||
| 429 | + mUInvLightDir = shader.RegisterProperty(UNIFORM_INV_LIGHT_DIR, invLightDir); | ||
| 430 | + mUScrollScale = shader.RegisterProperty(UNIFORM_SCROLL_SCALE, scrollScale); | ||
| 431 | + mUWaveRate = shader.RegisterProperty(UNIFORM_WAVE_RATE, waveRate); | ||
| 432 | + mUWaveAmplitude = shader.RegisterProperty(UNIFORM_WAVE_AMPLITUDE, waveAmp); | ||
| 433 | + mUNormalMapWeight = shader.RegisterProperty(UNIFORM_NORMAL_MAP_WEIGHT, normalMapWeight); | ||
| 434 | + mUSpecularity = shader.RegisterProperty(UNIFORM_SPECULARITY, specularity); | ||
| 435 | + mUParallaxAmount = shader.RegisterProperty(UNIFORM_PARALLAX_AMOUNT, parallaxAmount); | ||
| 436 | + mUTime = shader.RegisterProperty(UNIFORM_TIME, 0.f); | ||
| 437 | + | ||
| 438 | + auto window = mApp.GetWindow(); | ||
| 439 | + shader.RegisterProperty("uScreenHalfSize", Vector2(window.GetSize()) * .5f); | ||
| 440 | + mWaveShader = shader; | ||
| 441 | + | ||
| 442 | + return shader; | ||
| 443 | + } | ||
| 444 | + | ||
| 445 | + void TriggerColorTransition(Vector3 wavesColor, Vector3 lightColor) | ||
| 446 | + { | ||
| 447 | + if (mTransitionAnim) | ||
| 448 | + { | ||
| 449 | + mTransitionAnim.Stop(); | ||
| 450 | + } | ||
| 451 | + | ||
| 452 | + mTimeAnim.FinishedSignal().Disconnect(this, &WavesExample::OnTimeAnimFinished); | ||
| 453 | + mTimeAnim.Stop(); | ||
| 454 | + | ||
| 455 | + Animation anim = Animation::New(TRANSITION_DURATION); | ||
| 456 | + anim.AnimateTo(Property(mWaves, Actor::Property::COLOR), Vector4(wavesColor), AlphaFunction::EASE_IN_OUT); | ||
| 457 | + anim.AnimateTo(Property(mWaveShader, mULightColorSqr), lightColor * lightColor, AlphaFunction::EASE_IN_OUT); | ||
| 458 | + anim.AnimateBy(Property(mWaveShader, mUTime), TRANSITION_DURATION * TIME_STEP * TRANSITION_TIME_SCALE, AlphaFunction::EASE_IN_OUT); | ||
| 459 | + anim.FinishedSignal().Connect(this, &WavesExample::OnTransitionFinished); | ||
| 460 | + anim.Play(); | ||
| 461 | + mTransitionAnim = anim; | ||
| 462 | + } | ||
| 463 | + | ||
| 464 | + void OnTimeAnimFinished(Animation& anim) | ||
| 465 | + { | ||
| 466 | + anim.Play(); | ||
| 467 | + } | ||
| 468 | + | ||
| 469 | + void OnTransitionFinished(Animation& anim) | ||
| 470 | + { | ||
| 471 | + mTransitionAnim.Reset(); | ||
| 472 | + mTimeAnim.FinishedSignal().Connect(this, &WavesExample::OnTimeAnimFinished); | ||
| 473 | + mTimeAnim.Play(); | ||
| 474 | + } | ||
| 475 | + | ||
| 476 | + void OnPause(Application& app) | ||
| 477 | + { | ||
| 478 | + mTimeAnim.Pause(); | ||
| 479 | + mTiltSensor.Stop(); | ||
| 480 | + } | ||
| 481 | + | ||
| 482 | + void OnResume(Application& app) | ||
| 483 | + { | ||
| 484 | + mTiltSensor.Start(); | ||
| 485 | + mTimeAnim.Play(); | ||
| 486 | + } | ||
| 487 | + | ||
| 488 | + void OnKeyEvent(const KeyEvent& event) | ||
| 489 | + { | ||
| 490 | + if ( event.GetState() == KeyEvent::UP) // single keystrokes | ||
| 491 | + { | ||
| 492 | + if( IsKey( event, DALI_KEY_ESCAPE ) || IsKey( event, DALI_KEY_BACK ) ) | ||
| 493 | + { | ||
| 494 | + mApp.Quit(); | ||
| 495 | + } | ||
| 496 | + } | ||
| 497 | + } | ||
| 498 | + | ||
| 499 | + void OnDoubleTap(Actor /*actor*/, const TapGesture& gesture) | ||
| 500 | + { | ||
| 501 | + Vector3 lightColor = mWaveShader.GetProperty(mULightColorSqr).Get<Vector3>(); | ||
| 502 | + TriggerColorTransition(lightColor, RandomColor()); | ||
| 503 | + } | ||
| 504 | + | ||
| 505 | + void OnPan(Actor actor, const PanGesture& gesture) | ||
| 506 | + { | ||
| 507 | + auto tilt = gesture.GetDisplacement() / Vector2(mApp.GetWindow().GetSize()); | ||
| 508 | + switch (gesture.GetState()) | ||
| 509 | + { | ||
| 510 | + case GestureState::STARTED: | ||
| 511 | + mTiltFilter.Add(tilt); | ||
| 512 | + break; | ||
| 513 | + | ||
| 514 | + case GestureState::CONTINUING: | ||
| 515 | + mTiltFilter.Add(mTiltFilter.Filter() + tilt); | ||
| 516 | + break; | ||
| 517 | + | ||
| 518 | + default: | ||
| 519 | + break; | ||
| 520 | + } | ||
| 521 | + | ||
| 522 | + UpdateLightDirection(); | ||
| 523 | + } | ||
| 524 | + | ||
| 525 | + void OnTilted( const TiltSensor& sensor) | ||
| 526 | + { | ||
| 527 | + mTiltFilter.Add(Vector2(sensor.GetPitch(), sensor.GetRoll())); | ||
| 528 | + | ||
| 529 | + UpdateLightDirection(); | ||
| 530 | + } | ||
| 531 | + | ||
| 532 | + void UpdateLightDirection() | ||
| 533 | + { | ||
| 534 | + Vector2 tilt = mTiltFilter.Filter(); | ||
| 535 | + Quaternion q(Radian(tilt.y), Radian(-tilt.x), Radian(0.f)); | ||
| 536 | + Vector3 lightDir = q.Rotate(INV_LIGHT_DIR); | ||
| 537 | + mWaveShader.SetProperty(mUInvLightDir, lightDir); | ||
| 538 | + } | ||
| 539 | +}; | ||
| 540 | + | ||
| 541 | +int DALI_EXPORT_API main( int argc, char **argv ) | ||
| 542 | +{ | ||
| 543 | + Application application = Application::New( &argc, &argv, DEMO_THEME_PATH ); | ||
| 544 | + WavesExample example( application); | ||
| 545 | + application.MainLoop(); | ||
| 546 | + return 0; | ||
| 547 | +} |
resources/images/noise512.png
0 → 100644
765 KB
resources/po/en_GB.po
| @@ -283,6 +283,9 @@ msgstr "Skybox" | @@ -283,6 +283,9 @@ msgstr "Skybox" | ||
| 283 | msgid "DALI_DEMO_STR_TITLE_PBR" | 283 | msgid "DALI_DEMO_STR_TITLE_PBR" |
| 284 | msgstr "PBR" | 284 | msgstr "PBR" |
| 285 | 285 | ||
| 286 | +msgid "DALI_DEMO_STR_TITLE_WAVES" | ||
| 287 | +msgstr "Waves" | ||
| 288 | + | ||
| 286 | msgid "DALI_DEMO_STR_TITLE_WEB_VIEW" | 289 | msgid "DALI_DEMO_STR_TITLE_WEB_VIEW" |
| 287 | msgstr "Web View" | 290 | msgstr "Web View" |
| 288 | 291 |
resources/po/en_US.po
| @@ -300,3 +300,6 @@ msgstr "Text Visual" | @@ -300,3 +300,6 @@ msgstr "Text Visual" | ||
| 300 | 300 | ||
| 301 | msgid "DALI_DEMO_STR_TITLE_TEXT_LABEL_BITMAP_FONT" | 301 | msgid "DALI_DEMO_STR_TITLE_TEXT_LABEL_BITMAP_FONT" |
| 302 | msgstr "Text Bitmap Font" | 302 | msgstr "Text Bitmap Font" |
| 303 | + | ||
| 304 | +msgid "DALI_DEMO_STR_TITLE_WAVES" | ||
| 305 | +msgstr "Waves" |
shared/dali-demo-strings.h
| @@ -130,6 +130,7 @@ extern "C" | @@ -130,6 +130,7 @@ extern "C" | ||
| 130 | #define DALI_DEMO_STR_TITLE_TOOLTIP dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TOOLTIP") | 130 | #define DALI_DEMO_STR_TITLE_TOOLTIP dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TOOLTIP") |
| 131 | #define DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE") | 131 | #define DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE") |
| 132 | #define DALI_DEMO_STR_TITLE_VISUAL_TRANSITIONS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_VISUAL_TRANSITIONS") | 132 | #define DALI_DEMO_STR_TITLE_VISUAL_TRANSITIONS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_VISUAL_TRANSITIONS") |
| 133 | +#define DALI_DEMO_STR_TITLE_WAVES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_WAVES") | ||
| 133 | #define DALI_DEMO_STR_TITLE_WEB_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_WEB_VIEW") | 134 | #define DALI_DEMO_STR_TITLE_WEB_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_WEB_VIEW") |
| 134 | #define DALI_DEMO_STR_TITLE_TEXT_RENDERER dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_RENDERER") | 135 | #define DALI_DEMO_STR_TITLE_TEXT_RENDERER dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_RENDERER") |
| 135 | #define DALI_DEMO_STR_TITLE_TEXT_VISUAL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_VISUAL") | 136 | #define DALI_DEMO_STR_TITLE_TEXT_VISUAL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_VISUAL") |
| @@ -233,6 +234,7 @@ extern "C" | @@ -233,6 +234,7 @@ extern "C" | ||
| 233 | #define DALI_DEMO_STR_TITLE_TOOLTIP "Tooltip" | 234 | #define DALI_DEMO_STR_TITLE_TOOLTIP "Tooltip" |
| 234 | #define DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE "Visual Fitting Mode" | 235 | #define DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE "Visual Fitting Mode" |
| 235 | #define DALI_DEMO_STR_TITLE_VISUAL_TRANSITIONS "Visual Transitions" | 236 | #define DALI_DEMO_STR_TITLE_VISUAL_TRANSITIONS "Visual Transitions" |
| 237 | +#define DALI_DEMO_STR_TITLE_WAVES "Waves" | ||
| 236 | #define DALI_DEMO_STR_TITLE_WEB_VIEW "Web View" | 238 | #define DALI_DEMO_STR_TITLE_WEB_VIEW "Web View" |
| 237 | #define DALI_DEMO_STR_TITLE_TEXT_RENDERER "Text Renderer" | 239 | #define DALI_DEMO_STR_TITLE_TEXT_RENDERER "Text Renderer" |
| 238 | #define DALI_DEMO_STR_TITLE_TEXT_VISUAL "Text Visual" | 240 | #define DALI_DEMO_STR_TITLE_TEXT_VISUAL "Text Visual" |