CarouselEffect CarouselEffect::New() { // append the default version std::string vertexShader( "uniform float uRadius;\n" "uniform mediump vec2 uCenter;\n" "uniform mediump vec2 uAnglePerUnit;\n" "\n" "void main()\n" "{\n" " vec4 world = uModelView * vec4(aPosition,1.0);\n" " vec2 d = (world.xy - uCenter) * uAnglePerUnit;\n" " float a = length(d);\n" " float cs = cos(radians(a));\n" " world.z -= cs * uRadius;\n" " gl_Position = uProjection * world;\n" " \n" " vTexCoord = aTexCoord;\n" "}\n"); ShaderEffect shaderEffectCustom = ShaderEffect::New(vertexShader, "", GeometryType( GEOMETRY_TYPE_IMAGE | GEOMETRY_TYPE_TEXT ), ShaderEffect::GeometryHints( ShaderEffect::HINT_GRID | ShaderEffect::HINT_DEPTH_BUFFER )); // Pass ownership to CarouselEffect through overloaded constructor, So that it now has access to the // Dali::ShaderEffect implementation CarouselEffect handle( shaderEffectCustom ); handle.SetUniform( RADIUS_PROPERTY_NAME, 0.0f ); handle.SetUniform( CENTER_PROPERTY_NAME, Vector2( 0.0f, 0.0f ) ); handle.SetUniform( ANGLE_PER_UNIT_PROPERTY_NAME, Vector2( 0.0f, 0.0f ) ); return handle; }
/** \brief Create a structured cube grid \param lowerLeft Lower left corner of the grid \param upperRight Upper right corner of the grid \param elements Number of elements in each coordinate direction */ static std::unique_ptr<GridType> createCubeGrid(const FieldVector<ctype, dim> &lowerLeft, const FieldVector<ctype, dim> &upperRight, const array<int, dim> &elements) { // The grid factory GridFactory<GridType> factory; if (MPIHelper::getCollectiveCommunication().rank() == 0) { // Insert uniformly spaced vertices array<int, dim> vertices = elements; for (int i = 0; i < vertices.size(); ++i) vertices[i]++; // Insert vertices for structured grid into the factory insertVertices(factory, lowerLeft, upperRight, vertices); // Compute the index offsets needed to move to the adjacent // vertices in the different coordinate directions array<int, dim> unitOffsets = computeUnitOffsets(vertices); // Compute an element template (the cube at (0,...,0). All // other cubes are constructed by moving this template around int nCorners = 1 << dim; std::vector<int> cornersTemplate(nCorners, 0); for (int i = 0; i < nCorners; i++) for (int j = 0; j < dim; j++) if (i & (1 << j)) cornersTemplate[i] += unitOffsets[j]; // Insert elements MultiIndex index(elements); // Compute the total number of elementss to be created int numElements = index.cycle(); for (int i = 0; i < numElements; i++, ++index) { // 'base' is the index of the lower left element corner int base = 0; for (int j = 0; j < dim; j++) base += index[j] * unitOffsets[j]; // insert new element std::vector<int> corners = cornersTemplate; for (size_t j = 0; j < corners.size(); j++) corners[j] += base; factory.insertElement(GeometryType(GeometryType::cube, dim), corners); } } // if(rank == 0) // Create the grid and hand it to the calling method return std::unique_ptr<GridType>(factory.createGrid()); }
static void DoApply( ImageActor actor, const std::string& maskImage, const Vector2& maskSize, Vector4 maskBorder ) { const char* ALPHA_MASK_VERTEX_SHADER_SOURCE = "uniform vec2 uImageSize; \n" "uniform vec2 uMaskSize; \n" "varying vec2 vMaskTexCoord; \n" " \n" "void main() \n" "{ \n" " gl_Position = uMvpMatrix * vec4(aPosition, 1.0); \n" " \n" " // Ignore mask UVs for image \n" " \n" " highp vec2 halfImageSize = uImageSize * 0.5; \n" " vTexCoord = (aPosition.xy + halfImageSize) / uImageSize; \n" " \n" " // UVs were calculated for image size, so convert for mask size \n" " \n" " highp vec2 halfMaskSize = uMaskSize * 0.5; \n" " highp vec2 halfSizeDelta = halfImageSize - halfMaskSize; \n" " \n" " highp vec2 maskPosition = aPosition.xy; \n" " maskPosition.x -= halfSizeDelta.x * sign(aPosition.x); \n" " maskPosition.y -= halfSizeDelta.y * sign(aPosition.y); \n" " \n" " vMaskTexCoord = (maskPosition + halfMaskSize) / uMaskSize; \n" "} \n"; const char* ALPHA_MASK_FRAGMENT_SHADER_SOURCE = "varying vec2 vMaskTexCoord; \n" " \n" "void main() \n" "{ \n" " highp vec4 mask = texture2D(sEffect, vMaskTexCoord); \n" " gl_FragColor = texture2D(sTexture, vTexCoord) * uColor * vec4(1,1,1,mask.a); \n" "} \n"; ShaderEffect maskEffect = ShaderEffect::New( ALPHA_MASK_VERTEX_SHADER_SOURCE, ALPHA_MASK_FRAGMENT_SHADER_SOURCE, GeometryType( GEOMETRY_TYPE_IMAGE ), ShaderEffect::GeometryHints( ShaderEffect::HINT_BLENDING ) ); maskEffect.SetEffectImage( Image::New( maskImage ) ); maskEffect.SetUniform( "uImageSize", Vector2(0,0) /*Constrained to actor size*/ ); maskEffect.ApplyConstraint( Constraint::New<Vector2>( maskEffect.GetPropertyIndex("uImageSize"), Source(actor, Actor::SIZE), NinePatchMaskEffectSizeConstraint() ) ); maskEffect.SetUniform( "uMaskSize", maskSize ); // Actor must provide nine-patch style geometry for this effect to work actor.SetStyle( ImageActor::STYLE_NINE_PATCH ); actor.SetNinePatchBorder( maskBorder ); actor.SetShaderEffect( maskEffect ); }
ShearEffect ShearEffect::New() { // append the default version std::string vertexShader( "uniform mediump vec2 uCenter;\n" "uniform mediump float uAngleXAxis;\n" "uniform mediump float uAngleYAxis;\n" "\n" "void main()\n" "{\n" "mediump vec4 world = uModelView * vec4(aPosition,1.0);\n" "\n" "world.x = world.x + tan(radians(uAngleXAxis)) * (world.y - uCenter.y * world.w);\n" "world.y = world.y + tan(radians(uAngleYAxis)) * (world.x - uCenter.x * world.w);\n" "\n" "gl_Position = uProjection * world;\n" "\n" "vTexCoord = aTexCoord;\n" "}" ); // Create the implementation, temporarily owned on stack, ShaderEffect shaderEffectCustom = Dali::ShaderEffect::New( vertexShader, "", GeometryType( GEOMETRY_TYPE_IMAGE | GEOMETRY_TYPE_TEXT ), GeometryHints( HINT_GRID )); // Pass ownership to ShearEffect through overloaded constructor, So that it now has access to the // Dali::ShaderEffect implementation Dali::Toolkit::ShearEffect handle( shaderEffectCustom ); handle.SetUniform( CENTER_PROPERTY_NAME, Vector2(0.0f, 0.0f), COORDINATE_TYPE_VIEWPORT_POSITION ); handle.SetUniform( ANGLE_X_AXIS_PROPERTY_NAME, 0.0f); handle.SetUniform( ANGLE_Y_AXIS_PROPERTY_NAME, 0.0f); return handle; }
/** \brief Create a structured simplex grid This works in all dimensions. The Coxeter-Freudenthal-Kuhn triangulation is used, which splits each cube into dim! simplices. See Allgower and Georg, 'Numerical Path Following' for a description. */ static std::unique_ptr<GridType> createSimplexGrid(const FieldVector<ctype, dim> &lowerLeft, const FieldVector<ctype, dim> &upperRight, const array<int, dim> &elements) { // The grid factory GridFactory<GridType> factory; if (MPIHelper::getCollectiveCommunication().rank() == 0) { // Insert uniformly spaced vertices array<int, dim> vertices = elements; for (std::size_t i = 0; i < vertices.size(); i++) vertices[i]++; insertVertices(factory, lowerLeft, upperRight, vertices); // Compute the index offsets needed to move to the adjacent // vertices in the different coordinate directions array<int, dim> unitOffsets = computeUnitOffsets(vertices); // Insert the elements std::vector<int> corners(dim + 1); // Loop over all "cubes", and split up each cube into dim! // (factorial) simplices MultiIndex elementsIndex(elements); int cycle = elementsIndex.cycle(); for (int i = 0; i < cycle; ++elementsIndex, i++) { // 'base' is the index of the lower left element corner int base = 0; for (int j = 0; j < dim; j++) base += elementsIndex[j] * unitOffsets[j]; // each permutation of the unit vectors gives a simplex. std::vector<unsigned int> permutation(dim); for (int j = 0; j < dim; j++) permutation[j] = j; // A hack for triangular lattices: swap the two last // vertices of every second triangle to uniformize orientation // of their normals int triangle = 0; do { // Make a simplex std::vector<unsigned int> corners(dim + 1); corners[0] = base; for (int j = 0; j < dim; j++) corners[j + 1] = corners[j] + unitOffsets[permutation[j]]; if (dim == 2 && triangle == 1) std::swap(corners[1], corners[2]); ++triangle; factory.insertElement(GeometryType(GeometryType::simplex, dim), corners); } while (std::next_permutation(permutation.begin(), permutation.end())); } } // if(rank == 0) // Create the grid and hand it to the calling method return std::unique_ptr<GridType>(factory.createGrid()); }
MotionStretchEffect MotionStretchEffect::New() { // Dali vertexSource prefix for reference: // precision highp float; // attribute vec3 aPosition; // attribute vec2 aTexCoord; // uniform mat4 uMvpMatrix; // uniform mat4 uModelView; // uniform mat3 uNormalMatrix; // uniform mat4 uProjection; // uniform vec4 uColor; // varying vec2 vTexCoord; std::string vertexSource; vertexSource = "uniform mat4 uModelLastFrame;\n" "uniform float uTimeDelta;\n" "uniform float uGeometryStretchFactor;\n" "uniform float uSpeedScalingFactor;\n" // outputs "varying vec2 vModelSpaceCenterToPos;\n" "varying vec2 vScreenSpaceVelocityVector;\n" "varying float vSpeed;\n" "void main()\n" "{\n" // get view space position of vertex this frame and last frame " vec4 vertex = vec4(aPosition, 1.0);\n" " vec4 viewSpaceVertex = uModelView * vertex;\n" " vec4 viewSpaceVertexLastFrame = uViewMatrix * uModelLastFrame * vertex;\n" // work out vertex's last movement in view space " vec3 viewSpacePosDelta = viewSpaceVertex.xyz - viewSpaceVertexLastFrame.xyz;\n" " float reciprocalTimeDelta = 1.0 / ((uTimeDelta > 0.0) ? uTimeDelta : 0.01);\n" // get clip space position of vertex this frame and last frame " vec4 clipSpaceVertex = uMvpMatrix * vertex;\n" " vec4 clipSpaceVertexLastFrame = uProjection * viewSpaceVertexLastFrame;\n" // decide how much this vertex is 'trailing', i.e. at the back of the object relative to its direction of motion. We do this // by assuming the objects model space origin is at its center and taking the dot product of the vector from center to vertex with the motion direction " float t = 0.0;\n" " float posDeltaLength = length(viewSpacePosDelta);\n" " if(posDeltaLength > 0.001)\n" // avoid div by 0 if object has barely moved " {\n" " vec4 viewSpaceCenterToPos = uModelView * vec4(aPosition, 0.0);\n" " float centerToVertexDist = length(viewSpaceCenterToPos);\n" " if(centerToVertexDist > 0.001)\n" // avoid div by 0 if object has vertex at model space origin " {\n" " vec3 viewSpacePosDeltaNormalised = viewSpacePosDelta / posDeltaLength;\n" " vec3 viewSpaceCenterToPosNormalised = viewSpaceCenterToPos.xyz / centerToVertexDist;\n" " t = (dot(viewSpacePosDeltaNormalised, viewSpaceCenterToPosNormalised) * 0.5 ) + 0.5;\n" // scale and bias from [-1..1] to [0..1] " }\n" " }\n" // output vertex position lerped with its last position, based on how much it is trailing, // this stretches the geom back along where it has just been, giving a warping effect // We raise t to a power in order that non-trailing vertices are effected much more than trailing ones // Note: we must take account of time delta to convert position delta into a velocity, so changes are smooth (take into account frame time correctly) " gl_Position = mix(clipSpaceVertexLastFrame, clipSpaceVertex, t * t * t * uGeometryStretchFactor * reciprocalTimeDelta);\n" // work out vertex's last movement in normalised device coordinates [-1..1] space, i.e. perspective divide " vec2 ndcVertex = clipSpaceVertex.xy / clipSpaceVertex.w;\n" " vec2 ndcVertexLastFrame = clipSpaceVertexLastFrame.xy / clipSpaceVertexLastFrame.w;\n" // scale and bias so that a value of 1.0 corresponds to screen size (NDC is [-1..1] = 2) " vScreenSpaceVelocityVector = ((ndcVertex - ndcVertexLastFrame) * 0.5 * reciprocalTimeDelta);\n" " vScreenSpaceVelocityVector.y = -vScreenSpaceVelocityVector.y;\n" // TODO negated due to y being inverted in our coordinate system? // calculate a scaling factor proportional to velocity, which we can use to tweak how things look " vSpeed = length(vScreenSpaceVelocityVector) * uSpeedScalingFactor;\n" " vSpeed = clamp(vSpeed, 0.0, 1.0);\n" // provide fragment shader with vector from center of object to pixel (assumes the objects model space origin is at its center and verts have same z) " vModelSpaceCenterToPos = aPosition.xy;\n" " vTexCoord = aTexCoord;\n" "}\n"; // Dali fragmentSource prefix for reference: // precision highp float; // uniform sampler2D sTexture; // uniform sampler2D sEffect; // uniform vec4 uColor; // varying vec2 vTexCoord; std::string fragmentSource; fragmentSource = "precision mediump float;\n" "uniform vec2 uObjectFadeStart;\n" "uniform vec2 uObjectFadeEnd;\n" "uniform float uAlphaScale;\n" // inputs "varying vec2 vModelSpaceCenterToPos;\n" "varying vec2 vScreenSpaceVelocityVector;\n" "varying float vSpeed;\n" "void main()\n" "{\n" // calculate an alpha value that will fade the object towards its extremities, we need this to avoid an unsightly hard edge between color values of // the stretched object and the background. Use smoothstep also to hide any hard edges (discontinuities) in rate of change of this alpha gradient " vec2 centerToPixel = abs( vModelSpaceCenterToPos );\n" " vec2 fadeToEdges = smoothstep(0.0, 1.0, 1.0 - ((centerToPixel - uObjectFadeStart) / (uObjectFadeEnd - uObjectFadeStart)));\n" " float fadeToEdgesScale = fadeToEdges.x * fadeToEdges.y * uAlphaScale;\n" // apply global scaler " fadeToEdgesScale = mix(1.0, fadeToEdgesScale, vSpeed);\n" // fade proportional to speed, so opaque when at rest // standard actor texel " vec4 colActor = texture2D(sTexture, vTexCoord);\n" " gl_FragColor = colActor;\n" " gl_FragColor.a *= fadeToEdgesScale;\n" // fade actor to its edges based on speed of motion " gl_FragColor *= uColor;\n" "}"; // NOTE: we must turn on alpha blending for the actor (HINT_BLENDING) ShaderEffect shader = ShaderEffect::New( vertexSource, fragmentSource, GeometryType( GEOMETRY_TYPE_IMAGE ), ShaderEffect::GeometryHints( ShaderEffect::HINT_BLENDING | ShaderEffect::HINT_GRID ) ); MotionStretchEffect handle( shader ); ////////////////////////////////////// // Register uniform properties // // // factors that scale the look, defaults handle.SetUniform( MOTION_STRETCH_GEOMETRY_STRETCH_SCALING_FACTOR_PROPERTY_NAME, MOTION_STRETCH_GEOM_STRETCH_SCALING_FACTOR ); handle.SetUniform( MOTION_STRETCH_SPEED_SCALING_FACTOR_PROPERTY_NAME, MOTION_STRETCH_SPEED_SCALING_FACTOR ); handle.SetUniform( MOTION_STRETCH_OBJECT_FADE_START_PROPERTY_NAME, MOTION_STRETCH_OBJECT_FADE_START ); handle.SetUniform( MOTION_STRETCH_OBJECT_FADE_END_PROPERTY_NAME, MOTION_STRETCH_OBJECT_FADE_END ); handle.SetUniform( MOTION_STRETCH_ALPHA_SCALE_PROPERTY_NAME, MOTION_STRETCH_ALPHA_SCALE ); handle.SetUniform( MOTION_STRETCH_MODELVIEW_LASTFRAME, Matrix::IDENTITY ); return handle; }