X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Frenderers%2Fnpatch%2Fnpatch-renderer.cpp;h=10f851f5943c9e83d4e99e29d4c52a84d27a54d3;hb=18c250b7c2de9dba09bff61a6425c67f490e5d41;hp=aa52f3e9afce81df11455eb3e58b32abc05ffa55;hpb=a41be0bf03293b22c95b2fa206aa87357e0d406a;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp index aa52f3e..10f851f 100644 --- a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp @@ -49,6 +49,32 @@ const char * const BORDER_ONLY("border-only"); std::string TEXTURE_UNIFORM_NAME = "sTexture"; +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 vec2 uNinePatchFactorsX[ FACTOR_SIZE_X ];\n + uniform mediump vec2 uNinePatchFactorsY[ FACTOR_SIZE_Y ];\n + \n + void main()\n + {\n + mediump vec2 fixedFactor = vec2( uNinePatchFactorsX[ int( ( aPosition.x + 1.0 ) * 0.5 ) ].x, uNinePatchFactorsY[ int( ( aPosition.y + 1.0 ) * 0.5 ) ].x );\n + mediump vec2 stretch = vec2( uNinePatchFactorsX[ int( ( aPosition.x ) * 0.5 ) ].y, uNinePatchFactorsY[ int( ( aPosition.y ) * 0.5 ) ].y );\n + \n + mediump vec2 fixedTotal = vec2( uNinePatchFactorsX[ FACTOR_SIZE_X - 1 ].x, uNinePatchFactorsY[ FACTOR_SIZE_Y - 1 ].x );\n + mediump vec2 stretchTotal = vec2( uNinePatchFactorsX[ FACTOR_SIZE_X - 1 ].y, uNinePatchFactorsY[ FACTOR_SIZE_Y - 1 ].y );\n + \n + mediump vec4 vertexPosition = vec4( ( fixedFactor + ( uSize.xy - fixedTotal ) * stretch / stretchTotal ), 0.0, 1.0 );\n + vertexPosition.xy -= uSize.xy * vec2( 0.5, 0.5 );\n + vertexPosition = uMvpMatrix * vertexPosition;\n + \n + vTexCoord = ( fixedFactor + stretch ) / ( fixedTotal + stretchTotal );\n + \n + gl_Position = vertexPosition;\n + }\n +); + const char* VERTEX_SHADER_3X3 = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n varying mediump vec2 vTexCoord;\n @@ -146,12 +172,43 @@ void AddVertex( Vector< Vector2 >& vertices, unsigned int x, unsigned int y ) vertices.PushBack( Vector2( x, y ) ); } +void RegisterStretchProperties( Material& material, const char * uniformName, const NinePatchImage::StretchRanges& stretchPixels, uint16_t imageExtent) +{ + uint16_t prevEnd = 0; + uint16_t prevFix = 0; + uint16_t prevStretch = 0; + unsigned int i = 1; + for( NinePatchImage::StretchRanges::ConstIterator it = stretchPixels.Begin(); it != stretchPixels.End(); ++it, ++i ) + { + uint16_t start = it->GetX(); + uint16_t end = it->GetY(); + + uint16_t fix = prevFix + start - prevEnd; + uint16_t stretch = prevStretch + end - start; + + std::stringstream uniform; + uniform << uniformName << "[" << i << "]"; + material.RegisterProperty( uniform.str(), Vector2( fix, stretch ) ); + + prevEnd = end; + prevFix = fix; + prevStretch = stretch; + } + + { + prevFix += imageExtent - prevEnd; + std::stringstream uniform; + uniform << uniformName << "[" << i << "]"; + material.RegisterProperty( uniform.str(), Vector2( prevFix, prevStretch ) ); + } +} + } //unnamed namespace /////////////////NPatchRenderer//////////////// -NPatchRenderer::NPatchRenderer() -: ControlRenderer(), +NPatchRenderer::NPatchRenderer( RendererFactoryCache& factoryCache ) +: ControlRenderer( factoryCache ), mBorderOnly( false ) { } @@ -160,10 +217,8 @@ NPatchRenderer::~NPatchRenderer() { } -void NPatchRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) +void NPatchRenderer::DoInitialize( const Property::Map& propertyMap ) { - Initialize(factoryCache); - Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME ); if( imageURLValue ) { @@ -217,6 +272,72 @@ void NPatchRenderer::SetOffset( const Vector2& offset ) //ToDo: renderer applies the offset } +void NPatchRenderer::InitializeRenderer( Renderer& renderer ) +{ + Geometry geometry; + Shader shader; + if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 ) + { + if( !mBorderOnly ) + { + geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY ); + if( !geometry ) + { + geometry = CreateGeometry( Uint16Pair( 3, 3 ) ); + mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY, geometry ); + } + } + else + { + geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY ); + if( !geometry ) + { + geometry = CreateGeometryBorder( Uint16Pair( 3, 3 ) ); + mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY, geometry ); + } + } + + shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER ); + mFactoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, shader ); + } + } + else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0) + { + Uint16Pair gridSize( 2 * mStretchPixelsX.Size() + 1, 2 * mStretchPixelsY.Size() + 1 ); + geometry = !mBorderOnly ? CreateGeometry( gridSize ) : CreateGeometryBorder( gridSize ); + + std::stringstream vertexShader; + vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n" + << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n" + << VERTEX_SHADER; + + shader = Shader::New( vertexShader.str(), FRAGMENT_SHADER ); + } + else + { + DALI_LOG_ERROR("The 9 patch image '%s' doesn't have any valid stretch borders and so is not a valid 9 patch image\n", mImageUrl.c_str() ); + CreateErrorImage(); + } + + if( !renderer ) + { + Material material = Material::New( shader ); + renderer = Renderer::New( geometry, material ); + } + else + { + mImpl->mRenderer.SetGeometry( geometry ); + Material material = mImpl->mRenderer.GetMaterial(); + if( material ) + { + material.SetShader( shader ); + } + } +} + void NPatchRenderer::DoSetOnStage( Actor& actor ) { if( !mCroppedImage ) @@ -230,6 +351,8 @@ void NPatchRenderer::DoSetOnStage( Actor& actor ) { InitialiseFromImage( mImage ); } + + InitializeRenderer( mImpl->mRenderer ); } if( mCroppedImage ) @@ -243,7 +366,7 @@ void NPatchRenderer::DoSetOffStage( Actor& actor ) mCroppedImage.Reset(); } -void NPatchRenderer::CreatePropertyMap( Property::Map& map ) const +void NPatchRenderer::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); @@ -258,35 +381,6 @@ void NPatchRenderer::CreatePropertyMap( Property::Map& map ) const map.Insert( BORDER_ONLY, mBorderOnly ); } -void NPatchRenderer::Initialize( RendererFactoryCache& factoryCache ) -{ - mNinePatchGeometry = factoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY ); - if( !(mNinePatchGeometry) ) - { - mNinePatchGeometry = CreateGeometry( Uint16Pair( 3, 3 ) ); - factoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY, mNinePatchGeometry ); - } - - mNinePatchBorderGeometry = factoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY ); - if( !(mNinePatchBorderGeometry) ) - { - mNinePatchBorderGeometry = CreateGeometryBorder( Uint16Pair( 3, 3 ) ); - factoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY, mNinePatchBorderGeometry ); - } - - mNinePatchShader = factoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER ); - if( !mNinePatchShader ) - { - mNinePatchShader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER ); - factoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, mNinePatchShader ); - } - - mImpl->mGeometry = mNinePatchGeometry; - mImpl->mShader = mNinePatchShader; - - mImageUrl.clear(); -} - void NPatchRenderer::SetImage( const std::string& imageUrl, bool borderOnly ) { mBorderOnly = borderOnly; @@ -338,13 +432,6 @@ void NPatchRenderer::InitialiseFromImage( NinePatchImage nPatch ) mStretchPixelsX = nPatch.GetStretchPixelsX(); mStretchPixelsY = nPatch.GetStretchPixelsY(); - - if( mStretchPixelsX.Size() > 0 && mStretchPixelsY.Size() > 0 ) - { - //only 9 patch supported for now - mImpl->mGeometry = !mBorderOnly ? mNinePatchGeometry : mNinePatchBorderGeometry; - mImpl->mShader = mNinePatchShader; - } } void NPatchRenderer::CreateErrorImage() @@ -368,8 +455,6 @@ void NPatchRenderer::CreateErrorImage() mStretchPixelsY.Clear(); mStretchPixelsY.PushBack( Uint16Pair( 0, mImageSize.GetHeight() ) ); - mImpl->mGeometry = mNinePatchGeometry; - mImpl->mShader = mNinePatchShader; } void NPatchRenderer::ApplyImageToSampler() @@ -377,35 +462,37 @@ void NPatchRenderer::ApplyImageToSampler() Material material = mImpl->mRenderer.GetMaterial(); if( material ) { - Sampler sampler; - for( std::size_t i = 0; i < material.GetNumberOfSamplers(); ++i ) + int index = material.GetTextureIndex( TEXTURE_UNIFORM_NAME ); + if( index > -1 ) { - sampler = material.GetSamplerAt( i ); - if( sampler.GetUniformName() == TEXTURE_UNIFORM_NAME ) - { - sampler.SetImage( mCroppedImage ); - break; - } + material.SetTextureImage( index, mCroppedImage ); } - if( !sampler ) + else { - sampler = Sampler::New( mCroppedImage, TEXTURE_UNIFORM_NAME ); - material.AddSampler( sampler ); + material.AddTexture( mCroppedImage, TEXTURE_UNIFORM_NAME ); } - if( mStretchPixelsX.Size() > 0 && mStretchPixelsY.Size() > 0 ) + if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 ) { - //only 9 patch supported for now + //special case for 9 patch Uint16Pair stretchX = mStretchPixelsX[ 0 ]; Uint16Pair stretchY = mStretchPixelsY[ 0 ]; uint16_t stretchWidth = stretchX.GetY() - stretchX.GetX(); uint16_t stretchHeight = stretchY.GetY() - stretchY.GetX(); - sampler.RegisterProperty( "uFixed[0]", Vector2::ZERO ); - sampler.RegisterProperty( "uFixed[1]", Vector2( stretchX.GetX(), stretchY.GetX()) ); - sampler.RegisterProperty( "uFixed[2]", Vector2( mImageSize.GetWidth() - stretchWidth, mImageSize.GetHeight() - stretchHeight ) ); - sampler.RegisterProperty( "uStretchTotal", Vector2( stretchWidth, stretchHeight ) ); + material.RegisterProperty( "uFixed[0]", Vector2::ZERO ); + material.RegisterProperty( "uFixed[1]", Vector2( stretchX.GetX(), stretchY.GetX()) ); + material.RegisterProperty( "uFixed[2]", Vector2( mImageSize.GetWidth() - stretchWidth, mImageSize.GetHeight() - stretchHeight ) ); + material.RegisterProperty( "uStretchTotal", Vector2( stretchWidth, stretchHeight ) ); + } + else + { + material.RegisterProperty( "uNinePatchFactorsX[0]", Vector2::ZERO ); + material.RegisterProperty( "uNinePatchFactorsY[0]", Vector2::ZERO ); + + RegisterStretchProperties( material, "uNinePatchFactorsX", mStretchPixelsX, mImageSize.GetWidth() ); + RegisterStretchProperties( material, "uNinePatchFactorsY", mStretchPixelsY, mImageSize.GetHeight() ); } } }