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 | 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
resources/po/en_US.po
shared/dali-demo-strings.h
| ... | ... | @@ -130,6 +130,7 @@ extern "C" |
| 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 "C" |
| 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" | ... | ... |