X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftransition-effects%2Fcube-transition-effect-impl.cpp;h=5a76197fbca3b05fde4da5717b8307283991d45b;hp=444a3fd1834f1517d35c6fe7d87af9fd6771060e;hb=e9d852fcdacc5788785bfe0b617bd757794e8208;hpb=005f449f3648e36e0cc997735b58b0ebb7a6390b diff --git a/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp b/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp index 444a3fd..5a76197 100644 --- a/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp +++ b/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp @@ -20,11 +20,10 @@ // EXTERNAL INCLUDES #include // for strcmp -#include -#include #include #include -#include +#include +#include namespace Dali { @@ -41,30 +40,90 @@ namespace // Setup properties, signals and actions using the type-registry. DALI_TYPE_REGISTRATION_BEGIN( Toolkit::CubeTransitionEffect, Dali::BaseHandle, NULL ); -DALI_SIGNAL_REGISTRATION( Toolkit, CubeTransitionEffect, "transition-completed", SIGNAL_TRANSITION_COMPLETED ) +DALI_SIGNAL_REGISTRATION( Toolkit, CubeTransitionEffect, "transitionCompleted", SIGNAL_TRANSITION_COMPLETED ) DALI_TYPE_REGISTRATION_END() +const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + varying mediump vec2 vTexCoord;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump vec3 uSize;\n + uniform mediump vec4 uTextureRect;\n + \n + void main()\n + {\n + mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n + vertexPosition.xyz *= uSize;\n + vertexPosition = uMvpMatrix * vertexPosition;\n + \n + vTexCoord = aPosition + vec2(0.5);\n + vTexCoord = mix(uTextureRect.xy, uTextureRect.zw, vTexCoord);\n + + gl_Position = vertexPosition;\n + }\n +); + +const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform lowp vec4 uColor;\n + uniform lowp vec4 uSamplerRect; + \n + void main()\n + {\n + gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n + }\n +); + +Actor CreateTile( const Vector4& samplerRect ) +{ + Actor tile = Actor::New(); + tile.SetAnchorPoint( AnchorPoint::CENTER ); + tile.RegisterProperty( "uTextureRect", samplerRect ); + return tile; +} + + +Geometry CreateQuadGeometry() +{ + const float halfWidth = 0.5f; + const float halfHeight = 0.5f; + struct QuadVertex { Vector2 position;}; + QuadVertex quadVertexData[4] = + { + { Vector2(-halfWidth, -halfHeight) }, + { Vector2( halfWidth, -halfHeight) }, + { Vector2(-halfWidth, halfHeight) }, + { Vector2( halfWidth, halfHeight) } + }; + + Property::Map quadVertexFormat; + quadVertexFormat["aPosition"] = Property::VECTOR2; + PropertyBuffer quadVertices = PropertyBuffer::New( quadVertexFormat ); + quadVertices.SetData( quadVertexData, 4 ); + + // Create the geometry object + Geometry geometry = Geometry::New(); + geometry.AddVertexBuffer( quadVertices ); + geometry.SetGeometryType( Geometry::TRIANGLE_STRIP ); + + return geometry; +} + } const Vector4 CubeTransitionEffect::FULL_BRIGHTNESS( 1.0f, 1.0f, 1.0f, 1.0f ); const Vector4 CubeTransitionEffect::HALF_BRIGHTNESS( 0.5f, 0.5f, 0.5f, 1.0f ); -CubeTransitionEffect::CubeTransitionEffect( unsigned int numRows, unsigned int numColumns, Size viewAreaSize ) -: mNumRows( numRows ), - mNumColumns( numColumns ), - mViewAreaSize( viewAreaSize ), - mRotateIndex( 0 ), - mContainerIndex( 0 ), - mChangeTurningDirection( false ), - mIsToNextImage( true ), - mIsImageLoading( false ), - mAnimationDuration( 1.f ), +CubeTransitionEffect::CubeTransitionEffect( unsigned int rows, unsigned int columns ) +: Control( ControlBehaviour( 0 ) ), + mRows( rows ), + mColumns( columns ), mIsAnimating( false ), mIsPaused( false ), - mCubeDisplacement( 0.f ), - mFirstTransition( true ), - mBufferIndex( 0 ) + mAnimationDuration( 1.f ), + mCubeDisplacement( 0.f ) { } @@ -72,81 +131,185 @@ CubeTransitionEffect::~CubeTransitionEffect() { } -void CubeTransitionEffect::Initialize() +void CubeTransitionEffect::SetTargetRight( unsigned int idx ) +{ + mBoxType[ idx ] = RIGHT; + + mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f ); + + mTargetTiles[ idx ].SetParentOrigin( Vector3( 1.f, 0.5f, 0.5f) ); + mTargetTiles[ idx ].SetOrientation( Degree( 90.f ), Vector3::YAXIS ); +} + +void CubeTransitionEffect::SetTargetLeft( unsigned int idx ) { - //create root actor for the cube transition effect, only visible during the transition - mRoot = Actor::New(); - mRoot.SetParentOrigin( ParentOrigin::CENTER ); - mRoot.SetAnchorPoint( AnchorPoint::CENTER ); - mRoot.SetVisible(false); - - // create two groups of tiles, - // and one group of actors (cubes) serving as parents of every two tiles (one from each image). - unsigned int totalNum = mNumColumns* mNumRows; - mBoxes.resize( totalNum ); - mTiles[0].resize( totalNum ); - mTiles[1].resize( totalNum ); - mTileSize = Vector2( mViewAreaSize.width / mNumColumns, mViewAreaSize.height / mNumRows ); - const Vector3 basePosition( (-mViewAreaSize.width + mTileSize.width) * 0.5f, - (-mViewAreaSize.height + mTileSize.height) * 0.5f, - -mTileSize.width * 0.5f ); - - Image placeHolder = BufferImage::WHITE(); - for( unsigned int y = 0; y < mNumRows; y++ ) + mBoxType[ idx ] = LEFT; + + mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f ); + + mTargetTiles[ idx ].SetParentOrigin( Vector3( 0.f, 0.5f, 0.5f) ); + mTargetTiles[ idx ].SetOrientation( Degree( -90.f ), Vector3::YAXIS ); +} + +void CubeTransitionEffect::SetTargetBottom( unsigned int idx ) +{ + mBoxType[ idx ] = BOTTOM; + + mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f ); + + mTargetTiles[ idx ].SetParentOrigin( Vector3( 0.5f, 0.f, 0.5f) ); + mTargetTiles[ idx ].SetOrientation( Degree( 90.f ), Vector3::XAXIS ); +} + +void CubeTransitionEffect::SetTargetTop( unsigned int idx ) +{ + mBoxType[ idx ] = TOP; + + mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f ); + + mTargetTiles[ idx ].SetParentOrigin( Vector3( 0.5f, 1.f, 0.5f) ); + mTargetTiles[ idx ].SetOrientation( Degree( -90.f ), Vector3::XAXIS ); +} + +void CubeTransitionEffect::OnRelayout( const Vector2& size, RelayoutContainer& container ) +{ + mTileSize = Vector2( size.x / mColumns, size.y / mRows ); + + mBoxRoot.SetProperty( Actor::Property::SIZE_WIDTH, size.x ); + mBoxRoot.SetProperty( Actor::Property::SIZE_HEIGHT, size.y ); + mBoxRoot.SetProperty( Actor::Property::SIZE_DEPTH, 1.0f ); + + for( size_t i = 0; i < mBoxes.size(); ++i ) { - float positionY = y * mTileSize.height + basePosition.y; - for( unsigned int x = 0; x < mNumColumns; x++) + mBoxes[ i ].SetProperty( Actor::Property::SIZE_WIDTH, mTileSize.x ); + mBoxes[ i ].SetProperty( Actor::Property::SIZE_HEIGHT, mTileSize.y ); + + switch( mBoxType[i] ) { - unsigned int idx = y*mNumColumns + x; - Actor actor( Actor::New() ); - mBoxes[idx] = actor; - actor.SetParentOrigin( ParentOrigin::CENTER ); - actor.SetAnchorPoint( AnchorPoint::CENTER ); - actor.SetPosition( x * mTileSize.width + basePosition.x, - positionY, - basePosition.z ); - mRoot.Add( actor ); - - mTiles[ 0 ][idx] = CreateTile( placeHolder, FULL_BRIGHTNESS ); - actor.Add( mTiles[ 0 ][idx] ); - - mTiles[ 1 ][idx] = CreateTile( placeHolder, HALF_BRIGHTNESS ); - actor.Add( mTiles[ 1 ][idx] ); + case LEFT: + case RIGHT: + { + mBoxes[ i ].SetProperty( Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f ); + mBoxes[ i ].SetProperty( Actor::Property::SIZE_DEPTH, mTileSize.x ); + break; + } + case BOTTOM: + case TOP: + { + mBoxes[ i ].SetProperty( Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f ); + mBoxes[ i ].SetProperty( Actor::Property::SIZE_DEPTH, mTileSize.y ); + break; + } } } - // helper actor to create a off-screen image using shader effect - mEmptyImage = ImageActor::New( placeHolder ); - mEmptyImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); - mEmptyImage.SetParentOrigin( ParentOrigin::CENTER ); - mEmptyImage.SetAnchorPoint( AnchorPoint::CENTER ); - mFullImageCreator = FullAreaImageCreator::New(); - mEmptyImage.SetShaderEffect( mFullImageCreator ); - Stage::GetCurrent().Add(mEmptyImage); - - // set up off-screen render task - RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); - mOffScreenTask = taskList.CreateTask(); - mOffScreenTask.SetSourceActor(mEmptyImage); - mOffScreenTask.SetExclusive(true); - mOffScreenBuffer[0] = FrameBufferImage::New(mViewAreaSize.x, mViewAreaSize.y); - mOffScreenBuffer[1] = FrameBufferImage::New(mViewAreaSize.x, mViewAreaSize.y); - mOffScreenTask.SetTargetFrameBuffer(mOffScreenBuffer[mBufferIndex]); - mOffScreenTask.SetRefreshRate(RenderTask::REFRESH_ONCE); + for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it ) + { + it->SetProperty( Actor::Property::SIZE_WIDTH, mTileSize.x ); + it->SetProperty( Actor::Property::SIZE_HEIGHT, mTileSize.y ); + } + for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it ) + { + it->SetProperty( Actor::Property::SIZE_WIDTH, mTileSize.x ); + it->SetProperty( Actor::Property::SIZE_HEIGHT, mTileSize.y ); + } +} + +void CubeTransitionEffect::Initialize() +{ + Self().RegisterProperty( "uTextureRect", Vector4( 0.0f, 0.0f, 1.0f, 1.0f ) ); + + mBoxType.Resize(mColumns * mRows); + + //create the box parents + mBoxRoot = Actor::New(); + mBoxRoot.SetParentOrigin( ParentOrigin::CENTER ); + mBoxRoot.SetAnchorPoint( AnchorPoint::CENTER ); + + mCurrentTiles.clear(); + mTargetTiles.clear(); + + mCurrentTiles.reserve( mColumns * mRows ); + mTargetTiles.reserve( mColumns * mRows ); + + Vector2 gridSizeInv( 1.0f / mColumns, 1.0f / mRows ); + Vector3 offset( 0.5f * gridSizeInv.x, 0.5f * gridSizeInv.y, 0.0f ); + + Vector3 anchor; + for( unsigned int y = 0; y < mRows; ++y, anchor.y += 1.0f / mRows ) + { + anchor.x = 0.0f; + for( unsigned int x = 0; x RemoveRenderer( mCurrentRenderer ); + } + mCurrentRenderer.Reset(); + } + + if( mTargetRenderer ) + { + for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it ) + { + it->RemoveRenderer( mTargetRenderer ); + } + mTargetRenderer.Reset(); + } + + Control::OnStageDisconnection(); } void CubeTransitionEffect::SetTransitionDuration( float duration ) @@ -169,92 +332,102 @@ float CubeTransitionEffect::GetCubeDisplacement() const return mCubeDisplacement; } -Actor CubeTransitionEffect::GetRoot() +bool CubeTransitionEffect::IsTransitioning() { - return mRoot; + return mIsAnimating; } -bool CubeTransitionEffect::IsTransiting() +void CubeTransitionEffect::SetCurrentImage( Image image ) { - return mIsImageLoading || mIsAnimating; -} + mCurrentImage = image; -void CubeTransitionEffect::SetCurrentImage( ImageActor imageActor ) -{ - mContainerIndex = std::abs(mRotateIndex) % 2; - SetImage( imageActor ); -} + if( mCurrentRenderer ) + { + Material material = mCurrentRenderer.GetMaterial(); -void CubeTransitionEffect::SetTargetImage( ImageActor imageActor ) -{ - mContainerIndex = std::abs( mRotateIndex+1 ) % 2; - SetImage( imageActor ); + int index = material.GetTextureIndex("sTexture" ); + if( index != -1 ) + { + material.SetTextureImage( index, mCurrentImage ); + } + else + { + material.AddTexture( mCurrentImage, "sTexture" ); + } + } } -void CubeTransitionEffect::SetImage( ImageActor imageActor ) +void CubeTransitionEffect::SetTargetImage( Image image ) { - mCurrentImage = imageActor; + mTargetImage = image; - Image image = imageActor.GetImage(); - ResourceImage resourceImage = ResourceImage::DownCast( image ); - mBufferIndex = mBufferIndex^1; - - //must make sure the image is already loaded before using its attributes - if( resourceImage && resourceImage.GetLoadingState() != ResourceLoadingSucceeded ) + if( mTargetRenderer ) { - mIsImageLoading = true; - resourceImage.LoadingFinishedSignal().Connect( this, &CubeTransitionEffect::OnImageLoaded ); - } - else - { - mIsImageLoading = false; - PrepareTiles( image ); + Material material = mTargetRenderer.GetMaterial(); + material.AddTexture( mTargetImage, "sTexture" ); } } void CubeTransitionEffect::StartTransition( bool toNextImage ) { + Vector3 size = Self().GetCurrentSize(); if( toNextImage ) { - StartTransition( Vector2( mViewAreaSize.width, mViewAreaSize.height*0.5f ), Vector2( -10.f, 0.f ) ); + StartTransition( Vector2(size.x* 0.5f, size.y*0.5f), Vector2( -10.f, 0.f ) ); } else { - StartTransition( Vector2( 0, mViewAreaSize.height*0.5f ), Vector2( 10.f, 0.f )); + StartTransition( Vector2(size.x* 0.5f, size.y*0.5f), Vector2( 10.f, 0.f )); } } void CubeTransitionEffect::StartTransition( Vector2 panPosition, Vector2 panDisplacement ) { - mRoot.SetVisible( true ); - mCurrentImage.SetVisible( false ); - bool toNextImage = ( panDisplacement.x < 0 ) ? true : false; - if( mIsToNextImage != toNextImage ) + if( !mCurrentRenderer ) { - mChangeTurningDirection = true; + DALI_LOG_ERROR( "Trying to transition a cube transition without an image set" ); + return; } - else + + //create the target renderer + Material material = Material::New( mCurrentRenderer.GetMaterial().GetShader() ); + if( mTargetImage ) { - mChangeTurningDirection = false; + material.AddTexture( mTargetImage, "sTexture" ); } - mIsToNextImage = toNextImage; + Geometry geometry = mCurrentRenderer.GetGeometry(); + mTargetRenderer = Renderer::New( geometry, material ); - if( mIsToNextImage ) + int depthIndex = mCurrentRenderer.GetProperty(Renderer::Property::DEPTH_INDEX); + mTargetRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex ); + + for( size_t i = 0; i < mBoxes.size(); ++i ) { - mRotateIndex += 1.f; + mBoxes[ i ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) ); } - else + + for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it ) { - mRotateIndex -= 1.f; + it->SetParentOrigin( Vector3( 0.5f, 0.5f, 1.0f) ); + it->SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) ); + it->AddRenderer( mCurrentRenderer ); } + for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it ) + { + it->AddRenderer( mTargetRenderer ); + } + + Self().RemoveRenderer( mCurrentRenderer ); + Self().Add( mBoxRoot ); if(mAnimation) { mAnimation.Clear(); mAnimation.Reset(); } + mAnimation = Animation::New( mAnimationDuration ); - mAnimation.FinishedSignal().Connect(this, &CubeTransitionEffect::OnTransitionFinished); + mAnimation.FinishedSignal().Connect( this, &CubeTransitionEffect::OnTransitionFinished ); OnStartTransition( panPosition, panDisplacement ); } @@ -279,90 +452,61 @@ void CubeTransitionEffect::ResumeTransition() void CubeTransitionEffect::StopTransition() { - if( mIsAnimating ) - { - mAnimation.Clear(); - mAnimation.Reset(); - mIsPaused = false; - - //reset the position of the cubes - //reset the color of the tiles - //all these status should be the same as the final state when the transition animation is finished completely - const Vector3 basePosition( (-mViewAreaSize.width + mTileSize.width) * 0.5f, - (-mViewAreaSize.height + mTileSize.height) * 0.5f, - -mTileSize.width * 0.5f ); - unsigned int anotherIndex = mContainerIndex^1; - for( unsigned int y = 0; y < mNumRows; y++ ) - { - float positionY = y * mTileSize.height + basePosition.y; - for( unsigned int x = 0; x < mNumColumns; x++) - { - unsigned int idx = y*mNumColumns + x; - mBoxes[idx].SetPosition( x * mTileSize.width + basePosition.x, - positionY, - basePosition.z ); - mTiles[mContainerIndex][idx].SetColor( FULL_BRIGHTNESS ); - mTiles[anotherIndex][idx].SetColor( HALF_BRIGHTNESS); - } - } - - // reset the rotation of the cubes, which is different process for different derived classes - OnStopTransition(); - - mRoot.SetVisible(false); - mCurrentImage.SetVisible(true); - mIsAnimating = false; - mFirstTransition = false; - } -} - -void CubeTransitionEffect::OnImageLoaded(ResourceImage image) -{ - mIsImageLoading = false; - PrepareTiles( image ); + ResetToInitialState(); } -/** - * Set sub-image to each tile. - * @param[in] image The image content of the imageActor for transition - */ -void CubeTransitionEffect::PrepareTiles( Image image ) +void CubeTransitionEffect::ResetToInitialState() { - // Fit the image to view area, while keeping the aspect; FitKeepAspectRatio(imageSize, viewAreaSize) - float scale = std::min( mViewAreaSize.width / image.GetWidth(), mViewAreaSize.height / image.GetHeight() ); - Vector2 imageSize(image.GetWidth()*scale, image.GetHeight()*scale); + mAnimation.Clear(); + mAnimation.Reset(); + mIsAnimating = false; - mFullImageCreator.SetEffectImage(image); - mFullImageCreator.SetRegionSize(mViewAreaSize, imageSize); + Self().Remove( mBoxRoot ); - mOffScreenTask.SetTargetFrameBuffer(mOffScreenBuffer[mBufferIndex]); - mOffScreenTask.SetRefreshRate(RenderTask::REFRESH_ONCE); + for( size_t i = 0; i < mBoxes.size(); ++i ) + { + mBoxes[ i ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) ); + } - ImageActor::PixelArea pixelArea( 0, 0, mViewAreaSize.x / mNumColumns, mViewAreaSize.y / mNumRows); + for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it ) + { + it->SetParentOrigin( Vector3( 0.5f, 0.5f, 1.0f) ); + it->SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) ); + it->SetProperty( Actor::Property::COLOR, FULL_BRIGHTNESS ); + } + if( mCurrentRenderer ) + { + for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it ) + { + it->RemoveRenderer( mCurrentRenderer ); + } + Self().AddRenderer( mCurrentRenderer ); + } - for( unsigned int y = 0; y < mNumRows; y++ ) + for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it ) + { + it->SetProperty( Actor::Property::COLOR, HALF_BRIGHTNESS ); + } + if( mTargetRenderer ) { - pixelArea.y = y * pixelArea.height; - for( unsigned int x = 0; x < mNumColumns; x++) + for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it ) { - pixelArea.x = x * pixelArea.width; - unsigned int idx = y*mNumColumns + x; - mTiles[mContainerIndex][idx].SetImage( mOffScreenBuffer[mBufferIndex]); - mTiles[mContainerIndex][idx].SetPixelArea( pixelArea ); + it->RemoveRenderer( mTargetRenderer ); } } } - void CubeTransitionEffect::OnTransitionFinished(Animation& source) { - mRoot.SetVisible(false); - mCurrentImage.SetVisible(true); - mIsAnimating = false; - mFirstTransition = false; + + std::swap( mCurrentTiles, mTargetTiles ); + std::swap( mCurrentRenderer, mTargetRenderer ); + std::swap( mCurrentImage, mTargetImage ); + + ResetToInitialState(); //Emit signal - Toolkit::CubeTransitionEffect handle( this ); + Toolkit::CubeTransitionEffect handle( GetOwner() ); mTransitionCompletedSignal.Emit( handle, mCurrentImage ); }