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=ed71b14586719254ec6f67d9f4264509939d33a8;hp=888322aea71577fa228a966c0263f7e7ed092d2f;hb=54fbf47db890d0479d19d780de5ea5d860924632;hpb=38382f3ad88c5da38c255a31834774a60c1d502a 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 888322a..ed71b14 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,13 @@ // EXTERNAL INCLUDES #include // for strcmp -#include -#include #include #include -#include +#include +#include + +// INTERNAL INCLUDES +#include namespace Dali { @@ -41,30 +43,63 @@ namespace // Setup properties, signals and actions using the type-registry. DALI_TYPE_REGISTRATION_BEGIN( Toolkit::CubeTransitionEffect, Dali::BaseHandle, NULL ); -DALI_SIGNAL_REGISTRATION( 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; +} + } 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,83 +107,186 @@ CubeTransitionEffect::~CubeTransitionEffect() { } -void CubeTransitionEffect::Initialize() +void CubeTransitionEffect::SetTargetRight( 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 ] = 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 ) +{ + 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.SetRelayoutEnabled( false ); - mEmptyImage.SetSize(Stage::GetCurrent().GetSize()); - 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 ) @@ -171,92 +309,95 @@ float CubeTransitionEffect::GetCubeDisplacement() const return mCubeDisplacement; } -Actor CubeTransitionEffect::GetRoot() +bool CubeTransitionEffect::IsTransitioning() { - return mRoot; + return mIsAnimating; } -bool CubeTransitionEffect::IsTransiting() +void CubeTransitionEffect::SetCurrentTexture( Texture texture ) { - return mIsImageLoading || mIsAnimating; -} + mCurrentTexture = texture; -void CubeTransitionEffect::SetCurrentImage( ImageActor imageActor ) -{ - mContainerIndex = std::abs(mRotateIndex) % 2; - SetImage( imageActor ); -} - -void CubeTransitionEffect::SetTargetImage( ImageActor imageActor ) -{ - mContainerIndex = std::abs( mRotateIndex+1 ) % 2; - SetImage( imageActor ); + if( mCurrentRenderer ) + { + TextureSet textureSet = mCurrentRenderer.GetTextures(); + textureSet.SetTexture( 0u, mCurrentTexture); + } } -void CubeTransitionEffect::SetImage( ImageActor imageActor ) +void CubeTransitionEffect::SetTargetTexture( Texture texture ) { - mCurrentImage = imageActor; - - Image image = imageActor.GetImage(); - ResourceImage resourceImage = ResourceImage::DownCast( image ); - mBufferIndex = mBufferIndex^1; + mTargetTexture = texture; - //must make sure the image is already loaded before using its attributes - if( resourceImage && resourceImage.GetLoadingState() != ResourceLoadingSucceeded ) - { - mIsImageLoading = true; - resourceImage.LoadingFinishedSignal().Connect( this, &CubeTransitionEffect::OnImageLoaded ); - } - else + if( mTargetRenderer ) { - mIsImageLoading = false; - PrepareTiles( image ); + TextureSet textureSet = mTargetRenderer.GetTextures(); + textureSet.SetTexture( 0u, mTargetTexture ); } } 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 + TextureSet textureSet = TextureSet::New(); + if( mTargetTexture ) + { + textureSet.SetTexture( 0u, mTargetTexture ); + } + Geometry geometry = mCurrentRenderer.GetGeometry(); + Shader shader( mCurrentRenderer.GetShader() ); + mTargetRenderer = Renderer::New( geometry, shader ); + mTargetRenderer.SetTextures( textureSet ); + + 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 ) { - mChangeTurningDirection = false; + mBoxes[ i ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) ); } - mIsToNextImage = toNextImage; - if( mIsToNextImage ) + 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 ); } - else + for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it ) { - mRotateIndex -= 1.f; + 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 ); } @@ -281,91 +422,62 @@ 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; - } + ResetToInitialState(); } -void CubeTransitionEffect::OnImageLoaded(ResourceImage image) +void CubeTransitionEffect::ResetToInitialState() { - mIsImageLoading = false; - PrepareTiles( image ); -} - -/** - * Set sub-image to each tile. - * @param[in] image The image content of the imageActor for transition - */ -void CubeTransitionEffect::PrepareTiles( Image image ) -{ - // 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( mCurrentTexture, mTargetTexture ); + + ResetToInitialState(); //Emit signal - Toolkit::CubeTransitionEffect handle( this ); - mTransitionCompletedSignal.Emit( handle, mCurrentImage ); + Toolkit::CubeTransitionEffect handle( GetOwner() ); + mTransitionCompletedSignal.Emit( handle, mCurrentTexture ); } Toolkit::CubeTransitionEffect::TransitionCompletedSignalType& CubeTransitionEffect::TransitionCompletedSignal()