Updated all files to new format
[platform/core/uifw/dali-demo.git] / examples / particles / particle-view.cpp
index 36db679..3194143 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 (the "License");
  * you may not use this file except in compliance with the License.
  *
  */
 #include "particle-view.h"
-#include "utils.h"
 #include "dali/public-api/animation/constraints.h"
+#include "utils.h"
+
+#include "generated/particle-view-frag.h"
+#include "generated/particle-view-simple-frag.h"
+#include "generated/particle-view-simple-vert.h"
+#include "generated/particle-view-vert.h"
 
 //#define ENABLE_DEBUG_VOLUME
 
@@ -26,227 +31,35 @@ using namespace Dali;
 
 namespace
 {
-
 const uint32_t POPULATION_GRANULARITY = 128;
 
-///@brief Shader for billboarded particles, where the vertices of the particles
-/// are supplied as vec3 position (particle position) + vec2 sub-position.
-const char* const PARTICLES_VSH = USE_GLSL_VERSION(300 es)
-DALI_COMPOSE_SHADER(
-  precision lowp float;
-  uniform mat4 uModelView; // DALi
-  uniform mat4 uProjection; // DALi
-  uniform vec3 uSize; // DALi
-  uniform vec4 uColor; // DALi
-
-  uniform vec3 uSecondaryColor;
-  uniform vec2 uDepthRange; // x is zNear, y is 1.f / (zFar - zNear)
-  uniform float uTwinkleFrequency;
-  uniform float uTwinkleSizeScale;
-  uniform float uTwinkleOpacityWeight;
-  uniform float uTime;
-  uniform float uFocalLength;
-  uniform float uAperture;
-  uniform float uPopulation;
-
-  struct Scatter
-  {
-    float radiusSqr;
-    float amount;
-    vec3 ray;
-  };
-
-  const int SCATTER_VARS = 6; // Must match ParticleView::mScatterProps' size.
-  uniform Scatter uScatter[SCATTER_VARS];
-
-  const int POPULATION_GRANULARITY = 128;
-  uniform float uOrderLookUp[POPULATION_GRANULARITY];
-
-  in vec3 aPosition;
-  in float aSeed;
-  in vec4 aPath;
-  in vec2 aSubPosition;
-  in float aSize;
-
-  flat out float vDepth;
-  flat out float vFocalDistance;
-  out vec2 vUvUnit;
-  flat out float vOpacity;
-  flat out vec3 vColor; // ignore alpha
-
-  float bezier(vec3 control, float alpha)
-  {
-    return mix(mix(control.x, control.y, alpha), mix(control.y, control.z, alpha), alpha);
-  }
-
-  void main() {
-    // Get random order from the look-up table, based on particle ID.
-    int particleId = gl_VertexID / 6;
-    float order = uOrderLookUp[particleId & (POPULATION_GRANULARITY - 1)];
-
-    // Get twinkle scalar
-    float twinkle = sin(uTime * floor(uTwinkleFrequency * aSeed) + fract(aSeed * 1.17137));
-
-    // Add Motion
-    float s = sin(uTime + aSeed) * .5f + .5f;  // different phase for all
-    // NOTE: you'd think that taking the bezier() calls apart would save 4 mix() calls, since
-    // the mix()es (of xy / yz / zw / wx) are all calculated twice. It turns out that the MALI
-    // compiler is already doing this; leaving it as is for readability.
-    float bx0 = bezier(aPath.xyz, s);
-    float bx1 = bezier(aPath.zwx, s);
-    float by0 = bezier(aPath.yzw, s);
-    float by1 = bezier(aPath.wxy, s);
-    vec3 motion = vec3(mix(bx0, bx1, s), mix(by0, by1, s), 0.f);
-
-    // Model to view position
-    vec3 position3 = aPosition * uSize + motion;
-
-    vec4 position = uModelView * vec4(position3, 1.f);
-
-    // Add scatter - calculated in view space, using view ray
-    vec3 normalizedPos = position.xyz / uSize;
-    for (int i = 0; i < SCATTER_VARS; ++i)
-    {
-      vec2 scatterDist = (normalizedPos - uScatter[i].ray * dot(uScatter[i].ray, normalizedPos)).xy;
-
-      // NOTE: replacing the division with a multiplication (by inverse) oddly results in more instructions (MALI).
-      float scatter = max(0.f, uScatter[i].radiusSqr - dot(scatterDist, scatterDist)) *
-        uScatter[i].amount / aSize;
-      position.xy += scatter * normalize(scatterDist) * uSize.xy;
-    }
-
-    // Calculate normalised depth and distance from focal plane
-    float depth = (position.z - uDepthRange.x) * uDepthRange.y;
-    vDepth = depth;
-
-    float focalDist = (uFocalLength - depth) * uAperture;
-    focalDist *= focalDist;
-    vFocalDistance = max(focalDist, 1e-6f);    // NOTE: was clamp(..., 1.f); side effect: out of focus particles get squashed at higher aperture values.
-
-    // Calculate expiring scale - for size and opacity.
-    float expiringScale = smoothstep(order + 1.f, order, uPopulation);
-
-    // Calculate billboard position and size
-    vec2 subPosition = aSubPosition * aSize *
-      (1.f + twinkle * aSeed * uTwinkleSizeScale) *
-      expiringScale;
-
-    // Insist on hacking the size? Do it here...
-    float sizeHack = depth + .5f;
-    // NOTE: sizeHack *= sizeHack looked slightly better.
-    subPosition *= sizeHack;
-
-    vec3 subPositionView = vec3(subPosition, 0.);
-
-    // Add billboards to view position.
-    position += vec4(subPositionView, 0.f);
-
-    // subPosition doubles as normalized (-1..1) UV.
-    vUvUnit = aSubPosition;
-
-    // Vary opacity (actor alpha) by time as well as expiring scale.
-    vOpacity = uColor.a * expiringScale *
-      (1.0f + aSeed + twinkle * uTwinkleOpacityWeight) / (2.0f + uTwinkleOpacityWeight);
-
-    // Randomize RGB using seed.
-    vec3 mixColor = vec3(fract(aSeed), fract(aSeed * 16.f), fract(aSeed * 256.f));
-    vColor = mix(uColor.rgb, uSecondaryColor, mixColor);
-
-    gl_Position = uProjection * position;
-  });
-
-///@brief Fragment shader for particles, which simulates depth of field
-/// using a combination of procedural texturing, alpha testing and alpha
-/// blending.
-const char* const PARTICLES_FSH = USE_GLSL_VERSION(300 es)
-DALI_COMPOSE_SHADER(
-  precision lowp float;
-  uniform float uAlphaTestRefValue;
-  uniform vec2 uFadeRange; // near, far
-  in vec2 vUvUnit;
-  flat in float vDepth;
-  flat in float vFocalDistance;
-  flat in float vOpacity;
-  flat in vec3 vColor;
-  out vec4 oFragColor;
-
-  const float REF_VALUE_THRESHOLD = 1. / 64.;
-
-  void main() {
-    // Softened disc pattern from normalized UVs
-    float value = 1.f - dot(vUvUnit, vUvUnit);
-
-    // Decrease area of particles 'in-focus'.
-    float refValue = (1.f - vFocalDistance) * .5f;
-    float threshold = REF_VALUE_THRESHOLD * (1.f + vDepth);
-    float alpha = pow(value, vFocalDistance) * smoothstep(refValue - threshold, refValue + threshold, value);
-    if (alpha < uAlphaTestRefValue)
-    {
-      discard;
-    }
-
-    // Apply opacity
-    alpha *= vOpacity;
-    alpha *= alpha;
-
-    // Fade particles out as they get close to the near and far clipping planes
-    alpha *= smoothstep(.0f, uFadeRange.x, vDepth) * smoothstep(1.f, uFadeRange.y, vDepth);
-
-    oFragColor = vec4(vColor, alpha);
-  });
-
-///@brief Shader for simple textured geometry.
-const char* const SIMPLE_VSH = USE_GLSL_VERSION(300 es)
-DALI_COMPOSE_SHADER(
-  precision mediump float;
-  uniform mat4 uMvpMatrix;//by DALi
-  uniform vec3 uSize;  // by DALi
-  in vec3 aPosition;
-  void main() {
-    gl_Position = uMvpMatrix * vec4(aPosition * uSize, 1.f);
-  });
-
-///@brief Shader for an unlit, unfogged, textured mesh.
-const char* const SIMPLE_FSH = USE_GLSL_VERSION(300 es)
-DALI_COMPOSE_SHADER(
-  precision mediump float;
-  uniform vec4 uColor;
-  out vec4 oFragColor;
-
-  void main() {
-    oFragColor = uColor;
-  });
-
-
 uint32_t GetSkipValue(uint32_t count, uint32_t prime)
 {
   uint32_t skip = 0;
   do
   {
     skip = (rand() % prime) * count * count + (rand() % prime) * count + (rand() % prime);
-  }
-  while (skip % prime == 0);
+  } while(skip % prime == 0);
   return skip;
 }
 
-}
+} // namespace
 
-ParticleView::ParticleView(const ParticleField& field, Dali::Actor world, Dali::CameraActor camera,
-  Dali::Geometry particleGeom)
+ParticleView::ParticleView(const ParticleField& field, Dali::Actor world, Dali::CameraActor camera, Dali::Geometry particleGeom)
 : mWorld(world),
   mParticleBoxSize(field.mBoxSize)
 {
-  if (!particleGeom)
+  if(!particleGeom)
   {
     // create particles
     particleGeom = field.MakeGeometry();
   }
 
   // create shader
-  Shader particleShader = Shader::New(PARTICLES_VSH, PARTICLES_FSH, Shader::Hint::MODIFIES_GEOMETRY);
+  Shader particleShader = Shader::New(SHADER_PARTICLE_VIEW_VERT, SHADER_PARTICLE_VIEW_FRAG, Shader::Hint::MODIFIES_GEOMETRY);
 
-  float zNear = camera.GetNearClippingPlane();
-  float zFar = camera.GetFarClippingPlane();
+  float         zNear = camera.GetNearClippingPlane();
+  float         zFar  = camera.GetFarClippingPlane();
   const Vector2 depthRange(zNear, 1.f / (zFar - zNear));
   particleShader.RegisterProperty("uDepthRange", depthRange);
 
@@ -254,16 +67,16 @@ ParticleView::ParticleView(const ParticleField& field, Dali::Actor world, Dali::
   particleShader.RegisterProperty("uTwinkleSizeScale", field.mTwinkleSizeScale);
   particleShader.RegisterProperty("uTwinkleOpacityWeight", field.mTwinkleOpacityWeight);
 
-  mPropPopulation = particleShader.RegisterProperty("uPopulation", 1.f);
-  mPropFocalLength = particleShader.RegisterProperty("uFocalLength", .5f);
-  mPropAperture = particleShader.RegisterProperty("uAperture", 8.f);
+  mPropPopulation        = particleShader.RegisterProperty("uPopulation", 1.f);
+  mPropFocalLength       = particleShader.RegisterProperty("uFocalLength", .5f);
+  mPropAperture          = particleShader.RegisterProperty("uAperture", 8.f);
   mPropAlphaTestRefValue = particleShader.RegisterProperty("uAlphaTestRefValue", 0.f);
-  mPropFadeRange = particleShader.RegisterProperty("uFadeRange", Vector2(0.f, 1.f));
+  mPropFadeRange         = particleShader.RegisterProperty("uFadeRange", Vector2(0.f, 1.f));
 
   // scatter variables
-  char nameBuffer[64];
+  char  nameBuffer[64];
   char* writep = nameBuffer + snprintf(nameBuffer, sizeof(nameBuffer), "uScatter[");
-  for (uint32_t i = 0; i < std::extent<decltype(mScatterProps)>::value; ++i)
+  for(uint32_t i = 0; i < std::extent<decltype(mScatterProps)>::value; ++i)
   {
     char* writep2 = writep + snprintf(writep, sizeof(nameBuffer) - std::distance(nameBuffer, writep), "%d].", i);
 
@@ -281,18 +94,18 @@ ParticleView::ParticleView(const ParticleField& field, Dali::Actor world, Dali::
   // Our particle mesh is sorted in Z; changing the population should remove
   // particles "randomly", not from one end.
   // Algorithm described in Mike McShaffry & al: Game Coding Complete.
-  const uint32_t prime = 131;  // next prime after POPULATION_GRANULARITY
-  const uint32_t skip = GetSkipValue(POPULATION_GRANULARITY, prime);
-  uint32_t next = 0;
+  const uint32_t prime = 131; // next prime after POPULATION_GRANULARITY
+  const uint32_t skip  = GetSkipValue(POPULATION_GRANULARITY, prime);
+  uint32_t       next  = 0;
 
   writep = nameBuffer + snprintf(nameBuffer, sizeof(nameBuffer), "uOrderLookUp[");
-  for (uint32_t i = 0; i < POPULATION_GRANULARITY; ++i)
+  for(uint32_t i = 0; i < POPULATION_GRANULARITY; ++i)
   {
-    do {
+    do
+    {
       next += skip;
       next %= prime;
-    }
-    while (next == 0 || next > POPULATION_GRANULARITY);
+    } while(next == 0 || next > POPULATION_GRANULARITY);
 
     snprintf(writep, sizeof(nameBuffer) - std::distance(nameBuffer, writep), "%d]", i);
     particleShader.RegisterProperty(nameBuffer, float(next - 1));
@@ -308,7 +121,7 @@ ParticleView::ParticleView(const ParticleField& field, Dali::Actor world, Dali::
 
   mParticleShader = particleShader;
 
-  auto renderer = CreateRenderer(TextureSet::New(), particleGeom, particleShader, OPTION_BLEND);
+  auto renderer        = CreateRenderer(TextureSet::New(), particleGeom, particleShader, OPTION_BLEND);
   auto masterParticles = CreateActor();
   masterParticles.SetProperty(Actor::Property::SIZE, field.mBoxSize);
   masterParticles.SetProperty(Actor::Property::VISIBLE, true);
@@ -318,7 +131,7 @@ ParticleView::ParticleView(const ParticleField& field, Dali::Actor world, Dali::
 
 #ifdef ENABLE_DEBUG_VOLUME
   Geometry cubeGeom = CreateCuboidWireframeGeometry();
-  renderer = CreateRenderer(renderer.GetTextures(), cubeGeom, Shader::New(SIMPLE_VSH, SIMPLE_FSH));
+  renderer          = CreateRenderer(renderer.GetTextures(), cubeGeom, Shader::New(SHADER_PARTICLE_VIEW_SIMPLE_VERT, SHADER_PARTICLE_VIEW_SIMPLE_FRAG));
   masterParticles.AddRenderer(renderer);
 #endif
 
@@ -331,19 +144,19 @@ ParticleView::~ParticleView()
   UnparentAndReset(mMasterParticles);
   UnparentAndReset(mSlaveParticles);
 
-  for (auto anim: { mAngularAnim, mLinearAnim })
+  for(auto anim : {mAngularAnim, mLinearAnim})
   {
-    if (anim)
+    if(anim)
     {
       anim.Stop();
       anim.Reset();
     }
   }
 
-  for (auto& s: mScatterProps)
+  for(auto& s : mScatterProps)
   {
     auto& anim = s.mAnim;
-    if (anim)
+    if(anim)
     {
       anim.Stop();
       anim.Reset();
@@ -388,23 +201,26 @@ void ParticleView::SetFadeRange(float near, float far)
 
 void ParticleView::SetAngularVelocity(float v)
 {
-  if (mAngularAnim)
+  if(mAngularAnim)
   {
     mAngularAnim.Stop();
     mAngularAnim.Clear();
     mAngularAnim.Reset();
   }
 
-  if (v * v > .0f)
+  if(v * v > .0f)
   {
     float sign = Sign(v);
-    auto anim = Animation::New(std::abs(2. * M_PI / v));
+    auto  anim = Animation::New(std::abs(2. * M_PI / v));
     anim.AnimateTo(Property(mMasterParticles, Actor::Property::ORIENTATION),
-      Quaternion(Radian(Degree(120. * sign)), Vector3::ZAXIS), TimePeriod(0., anim.GetDuration() / 3.));
+                   Quaternion(Radian(Degree(120. * sign)), Vector3::ZAXIS),
+                   TimePeriod(0., anim.GetDuration() / 3.));
     anim.AnimateTo(Property(mMasterParticles, Actor::Property::ORIENTATION),
-      Quaternion(Radian(Degree(240. * sign)), Vector3::ZAXIS), TimePeriod(anim.GetDuration() / 3., anim.GetDuration() / 3.));
+                   Quaternion(Radian(Degree(240. * sign)), Vector3::ZAXIS),
+                   TimePeriod(anim.GetDuration() / 3., anim.GetDuration() / 3.));
     anim.AnimateTo(Property(mMasterParticles, Actor::Property::ORIENTATION),
-      Quaternion(Radian(Degree(360. * sign)), Vector3::ZAXIS), TimePeriod(2. * anim.GetDuration() / 3., anim.GetDuration() / 3.));
+                   Quaternion(Radian(Degree(360. * sign)), Vector3::ZAXIS),
+                   TimePeriod(2. * anim.GetDuration() / 3., anim.GetDuration() / 3.));
     anim.SetLoopCount(0);
     anim.Play();
 
@@ -414,7 +230,7 @@ void ParticleView::SetAngularVelocity(float v)
 
 void ParticleView::SetLinearVelocity(float v)
 {
-  if (mLinearAnim)
+  if(mLinearAnim)
   {
     mLinearAnim.Stop();
     mLinearAnim.Clear();
@@ -422,13 +238,13 @@ void ParticleView::SetLinearVelocity(float v)
   }
   UnparentAndReset(mSlaveParticles);
 
-  if (v * v > .0f)
+  if(v * v > .0f)
   {
-    float sign = Sign(v);
+    float sign         = Sign(v);
     float directedSize = sign * mParticleBoxSize.z;
 
-    Actor slaveParticles = CloneActor(mMasterParticles);
-    Vector3 position = mMasterParticles.GetCurrentProperty(Actor::Property::POSITION).Get<Vector3>();
+    Actor   slaveParticles = CloneActor(mMasterParticles);
+    Vector3 position       = mMasterParticles.GetCurrentProperty(Actor::Property::POSITION).Get<Vector3>();
     slaveParticles.SetProperty(Actor::Property::POSITION, position + Vector3(0., 0., directedSize));
 
     auto propSecondaryColor = slaveParticles.RegisterProperty("uSecondaryColor", Vector3::XAXIS);
@@ -436,24 +252,21 @@ void ParticleView::SetLinearVelocity(float v)
     Actor world = mWorld.GetHandle();
     world.Add(slaveParticles);
 
-    if (sign < 0.)     // fix draw order
+    if(sign < 0.) // fix draw order
     {
       world.Remove(mMasterParticles);
       world.Add(mMasterParticles);
     }
 
-    Constraint constraint = Constraint::New<Vector4>(slaveParticles, Actor::Property::COLOR,
-      EqualToConstraint());
+    Constraint constraint = Constraint::New<Vector4>(slaveParticles, Actor::Property::COLOR, EqualToConstraint());
     constraint.AddSource(Source(mMasterParticles, Actor::Property::COLOR));
     constraint.Apply();
 
-    constraint = Constraint::New<Vector3>(slaveParticles, propSecondaryColor,
-      EqualToConstraint());
+    constraint = Constraint::New<Vector3>(slaveParticles, propSecondaryColor, EqualToConstraint());
     constraint.AddSource(Source(mMasterParticles, mPropSecondaryColor));
     constraint.Apply();
 
-    constraint = Constraint::New<Quaternion>(slaveParticles, Actor::Property::ORIENTATION,
-      EqualToConstraint());
+    constraint = Constraint::New<Quaternion>(slaveParticles, Actor::Property::ORIENTATION, EqualToConstraint());
     constraint.AddSource(Source(mMasterParticles, Actor::Property::ORIENTATION));
     constraint.Apply();
 
@@ -463,7 +276,7 @@ void ParticleView::SetLinearVelocity(float v)
     anim.SetLoopCount(0);
     anim.Play();
 
-    mLinearAnim = anim;
+    mLinearAnim     = anim;
     mSlaveParticles = slaveParticles;
   }
 }
@@ -473,7 +286,7 @@ void ParticleView::Scatter(float radius, float amount, float durationOut, float
   mActiveScatter = (mActiveScatter + 1) % std::extent<decltype(mScatterProps)>::value;
 
   auto& scatter = mScatterProps[mActiveScatter];
-  if (scatter.mAnim)
+  if(scatter.mAnim)
   {
     scatter.mAnim.Stop();
   }
@@ -482,12 +295,10 @@ void ParticleView::Scatter(float radius, float amount, float durationOut, float
   radius *= radius;
   mParticleShader.SetProperty(scatter.mPropRadius, radius);
 
-  Animation anim = Animation::New(durationOut + durationIn);
-  auto scatterAmount = Property(mParticleShader, scatter.mPropAmount);
-  anim.AnimateTo(scatterAmount, amount, AlphaFunction::EASE_OUT,
-    TimePeriod(0.f, durationOut));
-  anim.AnimateTo(scatterAmount, 0.f, AlphaFunction::EASE_IN_OUT_SINE,
-    TimePeriod(durationOut, durationIn));
+  Animation anim          = Animation::New(durationOut + durationIn);
+  auto      scatterAmount = Property(mParticleShader, scatter.mPropAmount);
+  anim.AnimateTo(scatterAmount, amount, AlphaFunction::EASE_OUT, TimePeriod(0.f, durationOut));
+  anim.AnimateTo(scatterAmount, 0.f, AlphaFunction::EASE_IN_OUT_SINE, TimePeriod(durationOut, durationIn));
   anim.Play();
 
   scatter.mAnim = anim;
@@ -496,25 +307,25 @@ void ParticleView::Scatter(float radius, float amount, float durationOut, float
 void ParticleView::SetScatterRay(Dali::Vector3 rayDir)
 {
   auto& scatter = mScatterProps[mActiveScatter];
-  mParticleShader.SetProperty(scatter.mPropRay, rayDir);;
+  mParticleShader.SetProperty(scatter.mPropRay, rayDir);
+  ;
 }
 
-void ParticleView::Fade(float duration, float target, AlphaFunction alphaFn,
-  std::function<void(Dali::Animation&)> onFinished)
+void ParticleView::Fade(float duration, float target, AlphaFunction alphaFn, std::function<void(Dali::Animation&)> onFinished)
 {
-  if (mFadeAnim)
+  if(mFadeAnim)
   {
     mFadeAnim.Stop();
   }
 
   Animation anim = Animation::New(duration);
   anim.AnimateTo(Property(mMasterParticles, Actor::Property::COLOR_ALPHA), target, alphaFn);
-  if (mSlaveParticles)
+  if(mSlaveParticles)
   {
     anim.AnimateTo(Property(mSlaveParticles, Actor::Property::COLOR_ALPHA), target, alphaFn);
   }
 
-  if (onFinished)
+  if(onFinished)
   {
     anim.FinishedSignal().Connect(this, onFinished);
   }
@@ -523,11 +334,10 @@ void ParticleView::Fade(float duration, float target, AlphaFunction alphaFn,
   mFadeAnim = anim;
 }
 
-void ParticleView::Fade(float duration, float target, float from, AlphaFunction alphaFn,
-  std::function<void(Dali::Animation&)> onFinished)
+void ParticleView::Fade(float duration, float target, float from, AlphaFunction alphaFn, std::function<void(Dali::Animation&)> onFinished)
 {
   mMasterParticles.SetProperty(Actor::Property::COLOR_ALPHA, from);
-  if (mSlaveParticles)
+  if(mSlaveParticles)
   {
     mSlaveParticles.SetProperty(Actor::Property::COLOR_ALPHA, from);
   }