[dali_2.3.43] Merge branch 'devel/master'
[platform/core/uifw/dali-demo.git] / examples / waves / waves-example.cpp
index 9689772..d6904b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (   "License");
  * you may not use this file except in compliance with the License.
  */
 
 // INTERNAL INCLUDES
-#include "utils.h"
+#include <fstream>
+#include <iostream>
+#include <numeric>
 #include "dali/devel-api/adaptor-framework/tilt-sensor.h"
+#include "dali/public-api/actors/camera-actor.h"
+#include "dali/public-api/actors/layer.h"
 #include "dali/public-api/adaptor-framework/application.h"
 #include "dali/public-api/adaptor-framework/key.h"
 #include "dali/public-api/animation/animation.h"
+#include "dali/public-api/events/key-event.h"
 #include "dali/public-api/events/pan-gesture-detector.h"
 #include "dali/public-api/events/tap-gesture-detector.h"
-#include "dali/public-api/events/key-event.h"
-#include "dali/public-api/actors/camera-actor.h"
-#include "dali/public-api/actors/layer.h"
-#include "dali/public-api/render-tasks/render-task.h"
 #include "dali/public-api/render-tasks/render-task-list.h"
-#include <fstream>
-#include <iostream>
-#include <numeric>
+#include "dali/public-api/render-tasks/render-task.h"
+#include "utils.h"
+
+#include "generated/waves-frag.h"
+#include "generated/waves-vert.h"
 
 using namespace Dali;
 
 namespace
 {
-
-constexpr std::string_view WAVES_VSH =
-  "#define FMA(a, b, c) ((a) * (b) + (c))\n"  // fused multiply-add
-DALI_COMPOSE_SHADER(
-  precision highp float;
-
-  const float kTile = 1.;
-
-  const float kPi = 3.1415926535;
-  const float kEpsilon = 1. / 32.;
-
-  // DALI uniforms
-  uniform vec3 uSize;
-  uniform mat4 uModelView;
-  uniform mat4 uProjection;
-  uniform mat3 uNormalMatrix;
-
-  // our uniforms
-  uniform float uTime;
-  uniform vec2 uScrollScale;
-  uniform float uWaveRate;
-  uniform float uWaveAmplitude;
-  uniform float uParallaxAmount;
-
-  attribute vec2 aPosition;
-  attribute vec2 aTexCoord;
-
-  varying vec2 vUv;
-  varying vec3 vViewPos;
-  varying vec3 vNormal;
-  varying float vHeight;
-
-  float CubicHermite(float B, float C, float t)
-  {
-    float dCB = (C - B) * .5;
-    float A = B - dCB;
-    float D = B + dCB;
-    vec3 p = vec3(D + .5 * (((B - C) * 3.) - A), A - 2.5 * B + 2. * C - D,
-      .5 * (C - A));
-    return FMA(FMA(FMA(p.x, t, p.y), t, p.z), t, B);
-  }
-
-  float Hash(float n)
-  {
-    return fract(sin(n) * 43751.5453123);
-  }
-
-  float HeightAtTile(vec2 pos)
-  {
-    float rate = Hash(Hash(pos.x) * Hash(pos.y));
-
-    return (sin(uTime * rate * uWaveRate) * .5 + .5) * uWaveAmplitude;
- }
-
-  float CalculateHeight(vec2 position)
-  {
-    vec2 tile = floor(position);
-    position = fract(position);
-
-    vec2 cp = vec2(
-      CubicHermite(
-        HeightAtTile(tile + vec2( kTile * -0.5, kTile * -0.5)),
-        HeightAtTile(tile + vec2( kTile * +0.5, kTile * -0.5)),
-        position.x),
-      CubicHermite(
-        HeightAtTile(tile + vec2( kTile * -0.5, kTile * +0.5)),
-        HeightAtTile(tile + vec2( kTile * +0.5, kTile * +0.5)),
-        position.x)
-    );
-
-    return CubicHermite(cp.x, cp.y, position.y);
-  }
-
-  vec3 CalculateNormal(vec2 position)
-  {
-    vec3 normal = vec3(
-      CalculateHeight(vec2(position.x - kEpsilon, position.y)) -
-        CalculateHeight(vec2(position.x + kEpsilon, position.y)),
-      .25,
-      CalculateHeight(vec2(position.x, position.y - kEpsilon)) -
-        CalculateHeight(vec2(position.x, position.y + kEpsilon))
-    );
-    return normal;
-  }
-
-  void main()
-  {
-    vUv = aTexCoord;
-
-    vec2 scrollPosition = aPosition * uScrollScale + vec2(0., uTime * -kPi);
-    vNormal = uNormalMatrix * CalculateNormal(scrollPosition);
-
-    float h = CalculateHeight(scrollPosition);
-    vHeight = h * uParallaxAmount;
-    vec3 position = vec3(aPosition.x, h, aPosition.y);
-
-    vec4 viewPosition = uModelView * vec4(position * uSize, 1.);
-    vViewPos = -viewPosition.xyz;
-
-    gl_Position = uProjection * viewPosition;
-  });
-
-constexpr std::string_view WAVES_FSH = DALI_COMPOSE_SHADER(
-  precision highp float;
-
-  uniform vec4 uColor; // DALi
-  uniform sampler2D uNormalMap; // DALi
-
-  uniform vec3 uInvLightDir;
-  uniform vec3 uLightColorSqr;
-  uniform vec3 uAmbientColor;
-
-  uniform float uNormalMapWeight;
-  uniform float uSpecularity;
-
-  varying vec2 vUv;
-  varying vec3 vNormal;
-  varying vec3 vViewPos;
-  varying float vHeight;
-
-  float Rand(vec2 co)
-  {
-    return fract(sin(dot(co.xy, vec2(12.98981, 78.2331))) * 43758.5453);
-  }
-
-  float Sum(vec3 v)
-  {
-    return v.x + v.y + v.z;
-  }
-
-  void main()
-  {
-    vec3 viewPos = normalize(vViewPos);
-    vec2 uv2 = vUv + vViewPos.xy / vViewPos.z * vHeight + vec2(.5, 0.);
-
-    vec3 perturbNormal = texture2D(uNormalMap, vUv).rgb * 2. - 1.;
-    vec3 perturbNormal2 = texture2D(uNormalMap, uv2).rgb * 2. - 1.;
-    vec3 normal = normalize(vNormal + perturbNormal * uNormalMapWeight);
-    vec3 normal2 = normalize(vNormal + perturbNormal2 * uNormalMapWeight);
-
-    vec3 color = uAmbientColor;
-    float d = max(0., dot(normal, -uInvLightDir));
-    color += uColor.rgb * d;
-
-    vec3 reflected = reflect(uInvLightDir, normal);
-    d = max(0., dot(reflected, viewPos));
-    color += pow(d, uSpecularity) * uLightColorSqr;
-
-    reflected = reflect(uInvLightDir, normal2);
-    d = max(0., dot(reflected, viewPos));
-    color += pow(d, uSpecularity) * uLightColorSqr;
-
-    gl_FragColor = vec4(color, 1.);
-  });
-
 const float TIME_STEP = 0.0952664626;
 
-const std::string UNIFORM_LIGHT_COLOR_SQR = "uLightColorSqr";
-const std::string UNIFORM_AMBIENT_COLOR = "uAmbientColor";
-const std::string UNIFORM_INV_LIGHT_DIR = "uInvLightDir";
-const std::string UNIFORM_SCROLL_SCALE = "uScrollScale";
-const std::string UNIFORM_WAVE_RATE = "uWaveRate";
-const std::string UNIFORM_WAVE_AMPLITUDE = "uWaveAmplitude";
+const std::string UNIFORM_LIGHT_COLOR_SQR   = "uLightColorSqr";
+const std::string UNIFORM_AMBIENT_COLOR     = "uAmbientColor";
+const std::string UNIFORM_INV_LIGHT_DIR     = "uInvLightDir";
+const std::string UNIFORM_SCROLL_SCALE      = "uScrollScale";
+const std::string UNIFORM_WAVE_RATE         = "uWaveRate";
+const std::string UNIFORM_WAVE_AMPLITUDE    = "uWaveAmplitude";
 const std::string UNIFORM_NORMAL_MAP_WEIGHT = "uNormalMapWeight";
-const std::string UNIFORM_SPECULARITY = "uSpecularity";
-const std::string UNIFORM_PARALLAX_AMOUNT = "uParallaxAmount";
-const std::string UNIFORM_TIME = "uTime";
+const std::string UNIFORM_SPECULARITY       = "uSpecularity";
+const std::string UNIFORM_PARALLAX_AMOUNT   = "uParallaxAmount";
+const std::string UNIFORM_TIME              = "uTime";
 
-const Vector3 WAVES_COLOR { .78f, .64f, .26f };
-const Vector3 LIGHT_COLOR { 1.0f, 0.91f, 0.6f };
-const Vector3 AMBIENT_COLOR { .002f, .001f, .001f };
+const Vector3 WAVES_COLOR{.78f, .64f, .26f};
+const Vector3 LIGHT_COLOR{1.0f, 0.91f, 0.6f};
+const Vector3 AMBIENT_COLOR{.002f, .001f, .001f};
 
-const Vector3 INV_LIGHT_DIR = Normalized(Vector3{ .125f, .8f, -.55f });
+const Vector3 INV_LIGHT_DIR = Normalized(Vector3{.125f, .8f, -.55f});
 
-const Vector2 SCROLL_SCALE{ 1.f, 3.5f };
-const float WAVE_RATE = 12.17f;
-const float WAVE_AMPLITUDE = 1.f;
-const float NORMAL_MAP_WEIGHT = 0.05f;
-const float SPECULARITY = 512.f;
-const float PARALLAX_AMOUNT = .25f;
+const Vector2 SCROLL_SCALE{1.f, 3.5f};
+const float   WAVE_RATE         = 12.17f;
+const float   WAVE_AMPLITUDE    = 1.f;
+const float   NORMAL_MAP_WEIGHT = 0.05f;
+const float   SPECULARITY       = 512.f;
+const float   PARALLAX_AMOUNT   = .25f;
 
 const float TILT_RANGE_DEGREES = 30.f;
 
-const float TRANSITION_DURATION = 1.2f;
+const float TRANSITION_DURATION   = 1.2f;
 const float TRANSITION_TIME_SCALE = 6.f;
 
 const std::string_view NORMAL_MAP_NAME = "noise512.png";
@@ -243,7 +91,7 @@ public:
   void Add(Dali::Vector2 tilt)
   {
     mTiltSamples[mIdxNextSample] = tilt;
-    mIdxNextSample = (mIdxNextSample + 1) % FILTER_SIZE;
+    mIdxNextSample               = (mIdxNextSample + 1) % FILTER_SIZE;
   }
 
   Dali::Vector2 Filter() const
@@ -252,22 +100,25 @@ public:
   }
 
 private:
-  enum { FILTER_SIZE = 8u };
+  enum
+  {
+    FILTER_SIZE = 8u
+  };
 
   Dali::Vector2 mTiltSamples[FILTER_SIZE];
-  size_t mIdxNextSample = 0;
+  size_t        mIdxNextSample = 0;
 };
 
-} // nonamespace
+} // namespace
 
 class WavesExample : public ConnectionTracker
 {
 public:
-  WavesExample( Application& app )
-  : mApp( app )
+  WavesExample(Application& app)
+  : mApp(app)
   {
-    mApp.InitSignal().Connect( this, &WavesExample::Create );
-    mApp.TerminateSignal().Connect( this, &WavesExample::Destroy );
+    mApp.InitSignal().Connect(this, &WavesExample::Create);
+    mApp.TerminateSignal().Connect(this, &WavesExample::Destroy);
   }
 
   ~WavesExample() = default;
@@ -275,9 +126,9 @@ public:
 private:
   Application& mApp;
 
-  CameraActor mCamera;  // no ownership
+  CameraActor mCamera; // no ownership
 
-  Actor mWaves;
+  Actor  mWaves;
   Shader mWaveShader;
 
   Property::Index mUInvLightDir{Property::INVALID_INDEX};
@@ -301,37 +152,35 @@ private:
   Animation mTimeAnim;
   Animation mTransitionAnim;
 
-  void Create( Application& application )
+  void Create(Application& application)
   {
-    Window window = application.GetWindow();
-    auto rootLayer = window.GetRootLayer();
+    Window window    = application.GetWindow();
+    auto   rootLayer = window.GetRootLayer();
 
     window.SetBackgroundColor(Vector4(WAVES_COLOR * .5f));
 
     // Get camera
-    RenderTaskList tasks = window.GetRenderTaskList();
-    RenderTask mainPass = tasks.GetTask(0);
-    CameraActor camera = mainPass.GetCameraActor();
-    mCamera = camera;
+    RenderTaskList tasks    = window.GetRenderTaskList();
+    RenderTask     mainPass = tasks.GetTask(0);
+    CameraActor    camera   = mainPass.GetCameraActor();
+    mCamera                 = camera;
 
     // NOTE: watchface doesn't tolerate modification of the camera well;
     /// we're better off rotating the world.
-    Quaternion baseOrientation (Radian(Degree(-150.f)), Radian(M_PI), Radian(0.f));
+    Quaternion baseOrientation(Radian(Degree(-150.f)), Radian(M_PI), Radian(0.f));
 
     auto shader = CreateShader();
 
     // Create geometry
-    Geometry geom = CreateTesselatedQuad(16, 64, Vector2{ .25f, 3.8f }, [](const Vector2& v) {
+    Geometry geom = CreateTesselatedQuad(
+      16, 64, Vector2{.25f, 3.8f}, [](const Vector2& v) {
       float y = v.y + .5f;  // 0..1
       y = std::sqrt(y) - .5f; // perspective correction - increase vertex density closer to viewer
 
       float x = v.x + v.x * (1.f - y) * 5.5f;
 
       y -= .24f;  // further translation
-      return Vector2{ x, y };
-    }, [](const Vector2& v) {
-      return Vector2{ v.x, std::sqrt(v.y) };
-    });
+      return Vector2{ x, y }; }, [](const Vector2& v) { return Vector2{v.x, std::sqrt(v.y)}; });
 
     // Create texture
     auto normalMap = LoadTexture(std::string(DEMO_IMAGE_DIR) + NORMAL_MAP_NAME.data());
@@ -348,7 +197,7 @@ private:
     Renderer renderer = CreateRenderer(textures, geom, shader, OPTION_DEPTH_TEST | OPTION_DEPTH_WRITE);
 
     auto waves = CreateActor();
-    auto size = Vector2(window.GetSize());
+    auto size  = Vector2(window.GetSize());
     waves.SetProperty(Actor::Property::SIZE, Vector3(size.x, 100.f, size.y));
     waves.SetProperty(Actor::Property::ORIENTATION, baseOrientation);
     waves.SetProperty(Actor::Property::COLOR, WAVES_COLOR);
@@ -357,7 +206,7 @@ private:
     window.Add(waves);
     mWaves = waves;
 
-    window.KeyEventSignal().Connect( this, &WavesExample::OnKeyEvent );
+    window.KeyEventSignal().Connect(this, &WavesExample::OnKeyEvent);
 
     // Setup double tap detector for color change
     mDoubleTapGesture = TapGestureDetector::New(2);
@@ -366,10 +215,10 @@ private:
 
     // Touch controls
     mTiltSensor = TiltSensor::Get();
-    if ( mTiltSensor.Start() )
+    if(mTiltSensor.Start())
     {
       // Get notifications when the device is tilted
-      mTiltSensor.TiltedSignal().Connect( this, &WavesExample::OnTilted );
+      mTiltSensor.TiltedSignal().Connect(this, &WavesExample::OnTilted);
     }
     else
     {
@@ -390,7 +239,7 @@ private:
     mTimeAnim = animTime;
   }
 
-  void Destroy( Application& app)
+  void Destroy(Application& app)
   {
     mCamera.Reset();
 
@@ -402,38 +251,38 @@ private:
 
   Shader CreateShader()
   {
-    Vector3 lightColorSqr{ LIGHT_COLOR };
-    Vector3 ambientColor = AMBIENT_COLOR;
-    Vector3 invLightDir = INV_LIGHT_DIR;
-    Vector2 scrollScale = SCROLL_SCALE;
-    float waveRate = WAVE_RATE;
-    float waveAmp = WAVE_AMPLITUDE;
-    float normalMapWeight = NORMAL_MAP_WEIGHT;
-    float specularity = SPECULARITY;
-    float parallaxAmount = PARALLAX_AMOUNT;
-    if (mWaveShader)
+    Vector3 lightColorSqr{LIGHT_COLOR};
+    Vector3 ambientColor    = AMBIENT_COLOR;
+    Vector3 invLightDir     = INV_LIGHT_DIR;
+    Vector2 scrollScale     = SCROLL_SCALE;
+    float   waveRate        = WAVE_RATE;
+    float   waveAmp         = WAVE_AMPLITUDE;
+    float   normalMapWeight = NORMAL_MAP_WEIGHT;
+    float   specularity     = SPECULARITY;
+    float   parallaxAmount  = PARALLAX_AMOUNT;
+    if(mWaveShader)
     {
-      lightColorSqr = mWaveShader.GetProperty(mULightColorSqr).Get<Vector3>();
-      ambientColor = mWaveShader.GetProperty(mUAmbientColor).Get<Vector3>();
-      invLightDir = mWaveShader.GetProperty(mUInvLightDir).Get<Vector3>();
-      scrollScale = mWaveShader.GetProperty(mUScrollScale).Get<Vector2>();
-      waveRate = mWaveShader.GetProperty(mUWaveRate).Get<float>();
-      waveAmp = mWaveShader.GetProperty(mUWaveAmplitude).Get<float>();
+      lightColorSqr   = mWaveShader.GetProperty(mULightColorSqr).Get<Vector3>();
+      ambientColor    = mWaveShader.GetProperty(mUAmbientColor).Get<Vector3>();
+      invLightDir     = mWaveShader.GetProperty(mUInvLightDir).Get<Vector3>();
+      scrollScale     = mWaveShader.GetProperty(mUScrollScale).Get<Vector2>();
+      waveRate        = mWaveShader.GetProperty(mUWaveRate).Get<float>();
+      waveAmp         = mWaveShader.GetProperty(mUWaveAmplitude).Get<float>();
       normalMapWeight = mWaveShader.GetProperty(mUNormalMapWeight).Get<float>();
-      specularity = mWaveShader.GetProperty(mUSpecularity).Get<float>();
+      specularity     = mWaveShader.GetProperty(mUSpecularity).Get<float>();
     }
 
-    Shader shader = Shader::New(WAVES_VSH.data(), WAVES_FSH.data(), Shader::Hint::MODIFIES_GEOMETRY);
-    mULightColorSqr = shader.RegisterProperty(UNIFORM_LIGHT_COLOR_SQR, lightColorSqr);
-    mUAmbientColor = shader.RegisterProperty(UNIFORM_AMBIENT_COLOR, ambientColor);
-    mUInvLightDir = shader.RegisterProperty(UNIFORM_INV_LIGHT_DIR, invLightDir);
-    mUScrollScale = shader.RegisterProperty(UNIFORM_SCROLL_SCALE, scrollScale);
-    mUWaveRate = shader.RegisterProperty(UNIFORM_WAVE_RATE, waveRate);
-    mUWaveAmplitude = shader.RegisterProperty(UNIFORM_WAVE_AMPLITUDE, waveAmp);
+    Shader shader     = Shader::New(SHADER_WAVES_VERT, SHADER_WAVES_FRAG, Shader::Hint::MODIFIES_GEOMETRY);
+    mULightColorSqr   = shader.RegisterProperty(UNIFORM_LIGHT_COLOR_SQR, lightColorSqr);
+    mUAmbientColor    = shader.RegisterProperty(UNIFORM_AMBIENT_COLOR, ambientColor);
+    mUInvLightDir     = shader.RegisterProperty(UNIFORM_INV_LIGHT_DIR, invLightDir);
+    mUScrollScale     = shader.RegisterProperty(UNIFORM_SCROLL_SCALE, scrollScale);
+    mUWaveRate        = shader.RegisterProperty(UNIFORM_WAVE_RATE, waveRate);
+    mUWaveAmplitude   = shader.RegisterProperty(UNIFORM_WAVE_AMPLITUDE, waveAmp);
     mUNormalMapWeight = shader.RegisterProperty(UNIFORM_NORMAL_MAP_WEIGHT, normalMapWeight);
-    mUSpecularity = shader.RegisterProperty(UNIFORM_SPECULARITY, specularity);
-    mUParallaxAmount = shader.RegisterProperty(UNIFORM_PARALLAX_AMOUNT, parallaxAmount);
-    mUTime = shader.RegisterProperty(UNIFORM_TIME, 0.f);
+    mUSpecularity     = shader.RegisterProperty(UNIFORM_SPECULARITY, specularity);
+    mUParallaxAmount  = shader.RegisterProperty(UNIFORM_PARALLAX_AMOUNT, parallaxAmount);
+    mUTime            = shader.RegisterProperty(UNIFORM_TIME, 0.f);
 
     auto window = mApp.GetWindow();
     shader.RegisterProperty("uScreenHalfSize", Vector2(window.GetSize()) * .5f);
@@ -444,7 +293,7 @@ private:
 
   void TriggerColorTransition(Vector3 wavesColor, Vector3 lightColor)
   {
-    if (mTransitionAnim)
+    if(mTransitionAnim)
     {
       mTransitionAnim.Stop();
     }
@@ -487,9 +336,9 @@ private:
 
   void OnKeyEvent(const KeyEvent& event)
   {
-    if ( event.GetState() == KeyEvent::UP)  // single keystrokes
+    if(event.GetState() == KeyEvent::UP) // single keystrokes
     {
-      if( IsKey( event, DALI_KEY_ESCAPE ) || IsKey( event, DALI_KEY_BACK ) )
+      if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
       {
         mApp.Quit();
       }
@@ -505,24 +354,24 @@ private:
   void OnPan(Actor actor, const PanGesture& gesture)
   {
     auto tilt = gesture.GetDisplacement() / Vector2(mApp.GetWindow().GetSize());
-    switch (gesture.GetState())
+    switch(gesture.GetState())
     {
-    case GestureState::STARTED:
-      mTiltFilter.Add(tilt);
-      break;
+      case GestureState::STARTED:
+        mTiltFilter.Add(tilt);
+        break;
 
-    case GestureState::CONTINUING:
-      mTiltFilter.Add(mTiltFilter.Filter() + tilt);
-      break;
+      case GestureState::CONTINUING:
+        mTiltFilter.Add(mTiltFilter.Filter() + tilt);
+        break;
 
-    default:
-      break;
+      default:
+        break;
     }
 
     UpdateLightDirection();
   }
 
-  void OnTilted( const TiltSensor& sensor)
+  void OnTilted(const TiltSensor& sensor)
   {
     mTiltFilter.Add(Vector2(sensor.GetPitch(), sensor.GetRoll()));
 
@@ -531,17 +380,17 @@ private:
 
   void UpdateLightDirection()
   {
-    Vector2 tilt = mTiltFilter.Filter();
+    Vector2    tilt = mTiltFilter.Filter();
     Quaternion q(Radian(tilt.y), Radian(-tilt.x), Radian(0.f));
-    Vector3 lightDir = q.Rotate(INV_LIGHT_DIR);
+    Vector3    lightDir = q.Rotate(INV_LIGHT_DIR);
     mWaveShader.SetProperty(mUInvLightDir, lightDir);
   }
 };
 
-int DALI_EXPORT_API main( int argc, char **argv )
+int DALI_EXPORT_API main(int argc, char** argv)
 {
-  Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
-  WavesExample example( application);
+  Application  application = Application::New(&argc, &argv, DEMO_THEME_PATH);
+  WavesExample example(application);
   application.MainLoop();
   return 0;
 }