Commit 475e959d61138abb18e3192f5e7accf294427fe0

Authored by György Straub
1 parent 770d0315

Added Waves example.

- tilt, or if not supported, pan, to rotate light;
- double tap to trigger color transition;

Change-Id: I7de09c65309f6b069566cf330ebf18904d36a885
com.samsung.dali-demo.xml
... ... @@ -325,6 +325,9 @@
325 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 326 <label>Web View</label>
327 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 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 38 // Create the demo launcher
39 39 DaliTableView demo(app);
40 40  
  41 + demo.AddExample(Example("animated-gradient-card-active.example", DALI_DEMO_STR_TITLE_CARD_ACTIVE));
41 42 demo.AddExample(Example("blocks.example", DALI_DEMO_STR_TITLE_BLOCKS));
42 43 demo.AddExample(Example("bezier-curve.example", DALI_DEMO_STR_TITLE_BEZIER_CURVE));
43 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 55 demo.AddExample(Example("reflection-demo.example", DALI_DEMO_STR_TITLE_REFLECTION));
55 56 demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION));
56 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 58 demo.AddExample(Example("rendering-skybox.example", DALI_DEMO_STR_TITLE_SKYBOX));
60 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 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 &quot;Skybox&quot;
283 283 msgid "DALI_DEMO_STR_TITLE_PBR"
284 284 msgstr "PBR"
285 285  
  286 +msgid "DALI_DEMO_STR_TITLE_WAVES"
  287 +msgstr "Waves"
  288 +
286 289 msgid "DALI_DEMO_STR_TITLE_WEB_VIEW"
287 290 msgstr "Web View"
288 291  
... ...
resources/po/en_US.po
... ... @@ -300,3 +300,6 @@ msgstr &quot;Text Visual&quot;
300 300  
301 301 msgid "DALI_DEMO_STR_TITLE_TEXT_LABEL_BITMAP_FONT"
302 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 &quot;C&quot;
130 130 #define DALI_DEMO_STR_TITLE_TOOLTIP dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TOOLTIP")
131 131 #define DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE")
132 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 134 #define DALI_DEMO_STR_TITLE_WEB_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_WEB_VIEW")
134 135 #define DALI_DEMO_STR_TITLE_TEXT_RENDERER dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_RENDERER")
135 136 #define DALI_DEMO_STR_TITLE_TEXT_VISUAL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_VISUAL")
... ... @@ -233,6 +234,7 @@ extern &quot;C&quot;
233 234 #define DALI_DEMO_STR_TITLE_TOOLTIP "Tooltip"
234 235 #define DALI_DEMO_STR_TITLE_VISUAL_FITTING_MODE "Visual Fitting Mode"
235 236 #define DALI_DEMO_STR_TITLE_VISUAL_TRANSITIONS "Visual Transitions"
  237 +#define DALI_DEMO_STR_TITLE_WAVES "Waves"
236 238 #define DALI_DEMO_STR_TITLE_WEB_VIEW "Web View"
237 239 #define DALI_DEMO_STR_TITLE_TEXT_RENDERER "Text Renderer"
238 240 #define DALI_DEMO_STR_TITLE_TEXT_VISUAL "Text Visual"
... ...