X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Frenderers%2Fgradient%2Fgradient-renderer.cpp;h=30a587fa8ff3886581cfde7f20e15f717a1474ab;hb=refs%2Fchanges%2F40%2F49040%2F8;hp=85beb72f1e62b1bfe7ed3e8b6a4579db363e123c;hpb=4cc88bb89cb6ef65670780554480ecbbdecf0254;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp index 85beb72..30a587f 100644 --- a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp @@ -19,6 +19,7 @@ #include "gradient-renderer.h" // EXTERNAL INCLUDES +#include #include #include #include @@ -42,6 +43,9 @@ namespace Internal namespace { +const char * const RENDERER_TYPE("renderer-type"); +const char * const RENDERER_TYPE_VALUE("gradient-renderer"); + // properties: linear gradient const char * const GRADIENT_START_POSITION_NAME("gradient-start-position"); // Property::VECTOR2 const char * const GRADIENT_END_POSITION_NAME("gradient-end-position"); // Property::VECTOR2 @@ -58,6 +62,8 @@ const char * const GRADIENT_SPREAD_METHOD_NAME("gradient-spread-method"); // Pro // string values const char * const UNIT_USER_SPACE("user-space"); +const char * const UNIT_BOUNDING_BOX("object-bounding-box"); +const char * const SPREAD_PAD("pad"); const char * const SPREAD_REFLECT("reflect"); const char * const SPREAD_REPEAT("repeat"); @@ -65,8 +71,28 @@ const char * const SPREAD_REPEAT("repeat"); const char * const UNIFORM_ALIGNMENT_MATRIX_NAME( "uAlignmentMatrix" ); const char * const UNIFORM_TEXTULRE_NAME("sTexture"); +RendererFactoryCache::ShaderType GetShaderType( GradientRenderer::Type type, Gradient::GradientUnits units) +{ + if( type==GradientRenderer::LINEAR ) + { + if( units == Gradient::USER_SPACE_ON_USE ) + { + return RendererFactoryCache::GRADIENT_SHADER_LINEAR_USER_SPACE; + } + return RendererFactoryCache::GRADIENT_SHADER_LINEAR_BOUNDING_BOX; + } + else if( units == Gradient::USER_SPACE_ON_USE ) + { + return RendererFactoryCache::GRADIENT_SHADER_RADIAL_USER_SPACE; + } + + return RendererFactoryCache::GRADIENT_SHADER_RADIAL_BOUNDING_BOX; +} -const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( +const char* VERTEX_SHADER[] = +{ +// vertex shader for gradient units as USER_SPACE_ON_USE +DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n uniform mediump mat4 uMvpMatrix;\n uniform mediump vec3 uSize;\n @@ -81,9 +107,31 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( \n vTexCoord = (uAlignmentMatrix*vertexPosition.xyw).xy;\n }\n -); +), + +// vertex shader for gradient units as OBJECT_BOUNDING_BOX + DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump vec3 uSize;\n + uniform mediump mat3 uAlignmentMatrix;\n + varying mediump vec2 vTexCoord;\n + \n + void main()\n + {\n + mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n + vTexCoord = (uAlignmentMatrix*vertexPosition.xyw).xy;\n + \n + vertexPosition.xyz *= uSize;\n + gl_Position = uMvpMatrix * vertexPosition;\n + }\n +) +}; -const char* FRAGMENT_SHADER_LINEAR = DALI_COMPOSE_SHADER( +const char* FRAGMENT_SHADER[] = +{ +// fragment shader for linear gradient +DALI_COMPOSE_SHADER( uniform sampler2D sTexture;\n // sampler1D? uniform lowp vec4 uColor;\n varying mediump vec2 vTexCoord;\n @@ -92,9 +140,10 @@ const char* FRAGMENT_SHADER_LINEAR = DALI_COMPOSE_SHADER( {\n gl_FragColor = texture2D( sTexture, vec2( vTexCoord.y, 0.5 ) ) * uColor;\n }\n -); +), -const char* FRAGMENT_SHADER_RADIAL = DALI_COMPOSE_SHADER( +// fragment shader for radial gradient +DALI_COMPOSE_SHADER( uniform sampler2D sTexture;\n // sampler1D? uniform lowp vec4 uColor;\n varying mediump vec2 vTexCoord;\n @@ -103,7 +152,8 @@ const char* FRAGMENT_SHADER_RADIAL = DALI_COMPOSE_SHADER( {\n gl_FragColor = texture2D( sTexture, vec2( length(vTexCoord), 0.5 ) ) * uColor;\n }\n -); +) +}; Sampler::WrapMode GetWrapMode( Gradient::SpreadMethod spread ) { @@ -128,8 +178,9 @@ Sampler::WrapMode GetWrapMode( Gradient::SpreadMethod spread ) } -GradientRenderer::GradientRenderer() -:mGradientTransformIndex( Property::INVALID_INDEX ) +GradientRenderer::GradientRenderer( RendererFactoryCache& factoryCache ) +: ControlRenderer( factoryCache ), + mGradientType( LINEAR ) { } @@ -137,39 +188,27 @@ GradientRenderer::~GradientRenderer() { } -void GradientRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) +void GradientRenderer::DoInitialize( const Property::Map& propertyMap ) { - mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); - if( !(mImpl->mGeometry) ) + Gradient::GradientUnits gradientUnits = Gradient::OBJECT_BOUNDING_BOX; + Property::Value* unitsValue = propertyMap.Find( GRADIENT_UNITS_NAME ); + std::string units; + // The default unit is OBJECT_BOUNDING_BOX. + // Only need to set new units if 'user-space' + if( unitsValue && unitsValue->Get( units ) && units == UNIT_USER_SPACE ) { - mImpl->mGeometry = RendererFactoryCache::CreateQuadGeometry(); - factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry ); + gradientUnits = Gradient::USER_SPACE_ON_USE; } - Type gradientType; + mGradientType = LINEAR; if( propertyMap.Find( GRADIENT_RADIUS_NAME )) { - mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::GRADIENT_SHADER_RADIAL ); - if( !(mImpl->mShader) ) - { - mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RADIAL ); - factoryCache.SaveShader( RendererFactoryCache::GRADIENT_SHADER_RADIAL, mImpl->mShader ); - } - gradientType = RADIAL; - } - else - { - mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::GRADIENT_SHADER_LINEAR ); - if( !(mImpl->mShader) ) - { - mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_LINEAR ); - factoryCache.SaveShader( RendererFactoryCache::GRADIENT_SHADER_LINEAR, mImpl->mShader ); - } - gradientType = LINEAR; + mGradientType = RADIAL; } - if( NewGradient(gradientType, propertyMap) ) + if( NewGradient( mGradientType, propertyMap ) ) { + mGradient->SetGradientUnits( gradientUnits ); mGradientTransform = mGradient->GetAlignmentTransform(); } else @@ -181,19 +220,6 @@ void GradientRenderer::Initialize( RendererFactoryCache& factoryCache, const Pro void GradientRenderer::SetSize( const Vector2& size ) { ControlRenderer::SetSize( size ); - - if( mGradient->GetGradientUnits() == Gradient::OBJECT_BOUNDING_BOX ) - { - // Apply scaling - Matrix3 scaling( 1.f/(size.x+Math::MACHINE_EPSILON_100), 0.f, 0.f, - 0.f, 1.f/(size.y+Math::MACHINE_EPSILON_100), 0.f, 0.5f, 0.5f, 1.f ); - Matrix3::Multiply( mGradientTransform, scaling, mGradient->GetAlignmentTransform() ); - - if( mImpl->mRenderer ) - { - (mImpl->mRenderer).SetProperty( mGradientTransformIndex, mGradientTransform ); - } - } } void GradientRenderer::SetClipRect( const Rect& clipRect ) @@ -208,20 +234,103 @@ void GradientRenderer::SetOffset( const Vector2& offset ) //ToDo: renderer applies the offset } -void GradientRenderer::DoSetOnStage( Actor& actor ) +void GradientRenderer::DoCreatePropertyMap( Property::Map& map ) const { - mGradientTransformIndex = (mImpl->mRenderer).RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform ); + map.Clear(); + map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); + + Gradient::GradientUnits units = mGradient->GetGradientUnits(); + if( units == Gradient::USER_SPACE_ON_USE ) + { + map.Insert( GRADIENT_UNITS_NAME, UNIT_USER_SPACE ); + } + else // if( units == Gradient::OBJECT_BOUNDING_BOX ) + { + map.Insert( GRADIENT_UNITS_NAME, UNIT_BOUNDING_BOX ); + } + + Gradient::SpreadMethod spread = mGradient->GetSpreadMethod(); + if( spread == Gradient::PAD ) + { + map.Insert( GRADIENT_SPREAD_METHOD_NAME, SPREAD_PAD ); + } + else if( spread == Gradient::REFLECT ) + { + map.Insert( GRADIENT_SPREAD_METHOD_NAME, SPREAD_REFLECT ); + } + else // if( units == Gradient::REPEAT ) + { + map.Insert( GRADIENT_SPREAD_METHOD_NAME, SPREAD_REPEAT ); + } + + const Vector& stops( mGradient->GetStops() ); + Property::Array offsets; + Property::Array colors; + for( unsigned int i=0; i( mGradient.Get() ); + map.Insert( GRADIENT_START_POSITION_NAME, gradient->GetStartPosition() ); + map.Insert( GRADIENT_END_POSITION_NAME, gradient->GetEndPosition() ); + } + else // if( &typeid( *mGradient ) == &typeid(RadialGradient) ) + { + RadialGradient* gradient = static_cast( mGradient.Get() ); + map.Insert( GRADIENT_CENTER_NAME, gradient->GetCenter() ); + map.Insert( GRADIENT_RADIUS_NAME, gradient->GetRadius() ); + } +} + +void GradientRenderer::InitializeRenderer( Dali::Renderer& renderer ) +{ + Geometry geometry = mFactoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); + if( !geometry ) + { + geometry = RendererFactoryCache::CreateQuadGeometry(); + mFactoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, geometry ); + } + + Gradient::GradientUnits gradientUnits = mGradient->GetGradientUnits(); + RendererFactoryCache::ShaderType shaderType = GetShaderType( mGradientType, gradientUnits ); + Shader shader = mFactoryCache.GetShader( shaderType ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER[gradientUnits], FRAGMENT_SHADER[ mGradientType ] ); + mFactoryCache.SaveShader( shaderType, shader ); + } + + Material material; + if( !renderer ) + { + material = Material::New( shader ); + renderer = Renderer::New( geometry, material ); + } + else + { + mImpl->mRenderer.SetGeometry( geometry ); + material = mImpl->mRenderer.GetMaterial(); + if( material ) + { + material.SetShader( shader ); + } + } Dali::BufferImage lookupTexture = mGradient->GenerateLookupTexture(); Sampler sampler = Sampler::New( lookupTexture, UNIFORM_TEXTULRE_NAME ); Sampler::WrapMode wrap = GetWrapMode( mGradient->GetSpreadMethod() ); sampler.SetWrapMode( wrap, wrap ); - Material material = (mImpl->mRenderer).GetMaterial(); - if( material ) - { - material.AddSampler( sampler ); - } + material.AddSampler( sampler ); + + renderer.RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform ); } bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& propertyMap) @@ -265,39 +374,29 @@ bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& prope Property::Value* stopColorValue = propertyMap.Find( GRADIENT_STOP_COLOR_NAME ); if( stopOffsetValue && stopColorValue ) { - Property::Array* offsetArray = stopOffsetValue->GetArray(); + Vector offsetArray; Property::Array* colorArray = stopColorValue->GetArray(); - if( offsetArray && colorArray ) + if( colorArray && GetStopOffsets( stopOffsetValue, offsetArray )) { - unsigned int numStop = offsetArray->Count() < colorArray->Count() ? - offsetArray->Count() : colorArray->Count(); - float offset; + unsigned int numStop = offsetArray.Count() < colorArray->Count() ? + offsetArray.Count() : colorArray->Count(); Vector4 color; for( unsigned int i=0; iGetElementAt(i)).Get(offset) - && (colorArray->GetElementAt(i)).Get(color) ) + if( (colorArray->GetElementAt(i)).Get(color) ) { - mGradient->AddStop( offset, color); + mGradient->AddStop( offsetArray[i], color); numValidStop++; } } } } + if( numValidStop < 1u ) // no valid stop { return false; } - Property::Value* unitsValue = propertyMap.Find( GRADIENT_UNITS_NAME ); - std::string units; - // The default unit is OBJECT_BOUNDING_BOX. - // Only need to set new units if 'user-space' - if( unitsValue && unitsValue->Get( units ) && units == UNIT_USER_SPACE ) - { - mGradient->SetGradientUnits( Gradient::USER_SPACE_ON_USE ); - } - Property::Value* spread = propertyMap.Find( GRADIENT_SPREAD_METHOD_NAME ); std::string stringValue ; // The default spread method is PAD. @@ -317,6 +416,53 @@ bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& prope return true; } +bool GradientRenderer::GetStopOffsets(const Property::Value* value, Vector& stopOffsets) +{ + Vector2 offset2; + if( value->Get( offset2 ) ) + { + stopOffsets.PushBack( offset2.x ); + stopOffsets.PushBack( offset2.y ); + return true; + } + + Vector3 offset3; + if( value->Get( offset3 ) ) + { + stopOffsets.PushBack( offset3.x ); + stopOffsets.PushBack( offset3.y ); + stopOffsets.PushBack( offset3.z ); + return true; + } + + Vector4 offset4; + if( value->Get( offset4 ) ) + { + stopOffsets.PushBack( offset4.x ); + stopOffsets.PushBack( offset4.y ); + stopOffsets.PushBack( offset4.z ); + stopOffsets.PushBack( offset4.w ); + return true; + } + + Property::Array* offsetArray = value->GetArray(); + if( offsetArray ) + { + unsigned int numStop = offsetArray->Count(); + float offset; + for( unsigned int i=0; iGetElementAt(i).Get(offset) ) + { + stopOffsets.PushBack( offset ); + } + } + return true; + } + + return false; +} + } // namespace Internal } // namespace Toolkit