X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Frenderers%2Fgradient%2Fgradient-renderer.cpp;h=f64ad61a11b6084834611848b42f19c1e557bf57;hp=396ded3f7b9cd7908555b78cab05f55d3f8ce7f3;hb=36ac338ff7e9c299ce45818d77aa8f71c63a45aa;hpb=933609809da8a14c306789bc01b461a5116180ed diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp index 396ded3..f64ad61 100644 --- a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -43,36 +44,56 @@ 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 +const char * const START_POSITION_NAME("startPosition"); // Property::VECTOR2 +const char * const END_POSITION_NAME("endPosition"); // Property::VECTOR2 // properties: radial gradient -const char * const GRADIENT_CENTER_NAME("gradient-center"); // Property::VECTOR2 -const char * const GRADIENT_RADIUS_NAME("gradient-radius"); // Property::FLOAT +const char * const CENTER_NAME("center"); // Property::VECTOR2 +const char * const RADIUS_NAME("radius"); // Property::FLOAT // properties: linear&radial gradient -const char * const GRADIENT_STOP_OFFSET_NAME("gradient-stop-offset"); // Property::Array FLOAT -const char * const GRADIENT_STOP_COLOR_NAME("gradient-stop-color"); // Property::Array VECTOR4 -const char * const GRADIENT_UNITS_NAME("gradient-units"); // Property::String "userSpaceOnUse | objectBoundingBox" -const char * const GRADIENT_SPREAD_METHOD_NAME("gradient-spread-method"); // Property::String "pad | reflect | repeat" +const char * const STOP_OFFSET_NAME("stopOffset"); // Property::Array FLOAT +const char * const STOP_COLOR_NAME("stopColor"); // Property::Array VECTOR4 +const char * const UNITS_NAME("units"); // Property::String "userSpaceOnUse | objectBoundingBox" +const char * const SPREAD_METHOD_NAME("spreadMethod"); // Property::String "pad | reflect | repeat" // string values -const char * const UNIT_USER_SPACE("user-space"); -const char * const UNIT_BOUNDING_BOX("object-bounding-box"); +const char * const UNIT_USER_SPACE("userSpace"); +const char * const UNIT_BOUNDING_BOX("objectBoundingBox"); const char * const SPREAD_PAD("pad"); const char * const SPREAD_REFLECT("reflect"); const char * const SPREAD_REPEAT("repeat"); // uniform names const char * const UNIFORM_ALIGNMENT_MATRIX_NAME( "uAlignmentMatrix" ); -const char * const UNIFORM_TEXTULRE_NAME("sTexture"); +// default offset value +const unsigned int DEFAULT_OFFSET_MINIMUM = 0.0f; +const unsigned int DEFAULT_OFFSET_MAXIMUM = 1.0f; -const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( +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[] = +{ +// 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 @@ -87,9 +108,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 @@ -98,9 +141,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 @@ -109,24 +153,25 @@ 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 ) +Dali::WrapMode::Type GetWrapMode( Gradient::SpreadMethod spread ) { switch(spread) { case Gradient::REPEAT: { - return Sampler::REPEAT; + return Dali::WrapMode::REPEAT; } case Gradient::REFLECT: { - return Sampler::MIRRORED_REPEAT; + return Dali::WrapMode::MIRRORED_REPEAT; } case Gradient::PAD: default: { - return Sampler::CLAMP_TO_EDGE; + return Dali::WrapMode::CLAMP_TO_EDGE; } } } @@ -134,48 +179,38 @@ Sampler::WrapMode GetWrapMode( Gradient::SpreadMethod spread ) } -GradientRenderer::GradientRenderer() -:mGradientTransformIndex( Property::INVALID_INDEX ) +GradientRenderer::GradientRenderer( RendererFactoryCache& factoryCache ) +: ControlRenderer( factoryCache ), + mGradientType( LINEAR ) { + mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA; } GradientRenderer::~GradientRenderer() { } -void GradientRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) +void GradientRenderer::DoInitialize( Actor& actor, 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( 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; - 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 + mGradientType = LINEAR; + if( propertyMap.Find( RADIUS_NAME )) { - 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 @@ -187,19 +222,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 ) @@ -214,33 +236,38 @@ void GradientRenderer::SetOffset( const Vector2& offset ) //ToDo: renderer applies the offset } -void GradientRenderer::CreatePropertyMap( Property::Map& map ) const +void GradientRenderer::DoSetOnStage( Actor& actor ) +{ + InitializeRenderer(); +} + +void GradientRenderer::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); - map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); + map.Insert( RENDERER_TYPE, GRADIENT_RENDERER ); Gradient::GradientUnits units = mGradient->GetGradientUnits(); if( units == Gradient::USER_SPACE_ON_USE ) { - map.Insert( GRADIENT_UNITS_NAME, UNIT_USER_SPACE ); + map.Insert( UNITS_NAME, UNIT_USER_SPACE ); } else // if( units == Gradient::OBJECT_BOUNDING_BOX ) { - map.Insert( GRADIENT_UNITS_NAME, UNIT_BOUNDING_BOX ); + map.Insert( UNITS_NAME, UNIT_BOUNDING_BOX ); } Gradient::SpreadMethod spread = mGradient->GetSpreadMethod(); if( spread == Gradient::PAD ) { - map.Insert( GRADIENT_SPREAD_METHOD_NAME, SPREAD_PAD ); + map.Insert( SPREAD_METHOD_NAME, SPREAD_PAD ); } else if( spread == Gradient::REFLECT ) { - map.Insert( GRADIENT_SPREAD_METHOD_NAME, SPREAD_REFLECT ); + map.Insert( SPREAD_METHOD_NAME, SPREAD_REFLECT ); } else // if( units == Gradient::REPEAT ) { - map.Insert( GRADIENT_SPREAD_METHOD_NAME, SPREAD_REPEAT ); + map.Insert( SPREAD_METHOD_NAME, SPREAD_REPEAT ); } const Vector& stops( mGradient->GetStops() ); @@ -249,48 +276,75 @@ void GradientRenderer::CreatePropertyMap( Property::Map& map ) const for( unsigned int i=0; i( mGradient.Get() ); - map.Insert( GRADIENT_START_POSITION_NAME, gradient->GetStartPosition() ); - map.Insert( GRADIENT_END_POSITION_NAME, gradient->GetEndPosition() ); + map.Insert( START_POSITION_NAME, gradient->GetStartPosition() ); + map.Insert( 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() ); + map.Insert( CENTER_NAME, gradient->GetCenter() ); + map.Insert( RADIUS_NAME, gradient->GetRadius() ); } } -void GradientRenderer::DoSetOnStage( Actor& actor ) +void GradientRenderer::InitializeRenderer() { - mGradientTransformIndex = (mImpl->mRenderer).RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform ); - - Dali::BufferImage lookupTexture = mGradient->GenerateLookupTexture(); - Sampler sampler = Sampler::New( lookupTexture, UNIFORM_TEXTULRE_NAME ); - Sampler::WrapMode wrap = GetWrapMode( mGradient->GetSpreadMethod() ); - sampler.SetWrapMode( wrap, wrap ); + Geometry geometry = mFactoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); + if( !geometry ) + { + geometry = Geometry::QUAD(); + mFactoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, geometry ); + } - Material material = (mImpl->mRenderer).GetMaterial(); - if( material ) + Gradient::GradientUnits gradientUnits = mGradient->GetGradientUnits(); + RendererFactoryCache::ShaderType shaderType = GetShaderType( mGradientType, gradientUnits ); + Shader shader = mFactoryCache.GetShader( shaderType ); + if( !shader ) { - material.AddSampler( sampler ); + shader = Shader::New( VERTEX_SHADER[gradientUnits], FRAGMENT_SHADER[ mGradientType ] ); + mFactoryCache.SaveShader( shaderType, shader ); } + + //Set up the texture set + TextureSet textureSet = TextureSet::New(); + Dali::Texture lookupTexture = mGradient->GenerateLookupTexture(); + textureSet.SetTexture( 0u, lookupTexture ); + Dali::WrapMode::Type wrap = GetWrapMode( mGradient->GetSpreadMethod() ); + Sampler sampler = Sampler::New(); + sampler.SetWrapMode( wrap, wrap ); + textureSet.SetSampler( 0u, sampler ); + + mImpl->mRenderer = Renderer::New( geometry, shader ); + mImpl->mRenderer.SetTextures( textureSet ); + + mImpl->mRenderer.RegisterProperty( UNIFORM_ALIGNMENT_MATRIX_NAME, mGradientTransform ); } bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& propertyMap) { if( gradientType==LINEAR ) { - Property::Value* startPositionValue = propertyMap.Find( GRADIENT_START_POSITION_NAME ); - Property::Value* endPositionValue = propertyMap.Find( GRADIENT_END_POSITION_NAME ); + Property::Value* startPositionValue = propertyMap.Find( START_POSITION_NAME ); + Property::Value* endPositionValue = propertyMap.Find( END_POSITION_NAME ); Vector2 startPosition; Vector2 endPosition; @@ -306,8 +360,8 @@ bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& prope } else // type==RADIAL { - Property::Value* centerValue = propertyMap.Find( GRADIENT_CENTER_NAME ); - Property::Value* radiusValue = propertyMap.Find( GRADIENT_RADIUS_NAME ); + Property::Value* centerValue = propertyMap.Find( CENTER_NAME ); + Property::Value* radiusValue = propertyMap.Find( RADIUS_NAME ); Vector2 center; float radius; if( centerValue && centerValue->Get(center) @@ -322,14 +376,15 @@ bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& prope } unsigned int numValidStop = 0u; - Property::Value* stopOffsetValue = propertyMap.Find( GRADIENT_STOP_OFFSET_NAME ); - Property::Value* stopColorValue = propertyMap.Find( GRADIENT_STOP_COLOR_NAME ); - if( stopOffsetValue && stopColorValue ) + Property::Value* stopOffsetValue = propertyMap.Find( STOP_OFFSET_NAME ); + Property::Value* stopColorValue = propertyMap.Find( STOP_COLOR_NAME ); + if( stopColorValue ) { Vector offsetArray; Property::Array* colorArray = stopColorValue->GetArray(); - if( colorArray && GetStopOffsets( stopOffsetValue, offsetArray )) + if( colorArray ) { + GetStopOffsets( stopOffsetValue, offsetArray ); unsigned int numStop = offsetArray.Count() < colorArray->Count() ? offsetArray.Count() : colorArray->Count(); Vector4 color; @@ -337,7 +392,7 @@ bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& prope { if( (colorArray->GetElementAt(i)).Get(color) ) { - mGradient->AddStop( offsetArray[i], color); + mGradient->AddStop( offsetArray[i], Vector4(color.r*color.a, color.g*color.a, color.b*color.a, color.a)); numValidStop++; } } @@ -349,16 +404,7 @@ bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& prope 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 ); + Property::Value* spread = propertyMap.Find( SPREAD_METHOD_NAME ); std::string stringValue ; // The default spread method is PAD. // Only need to set new spread if 'reflect' or 'repeat" @@ -377,51 +423,71 @@ bool GradientRenderer::NewGradient(Type gradientType, const Property::Map& prope return true; } -bool GradientRenderer::GetStopOffsets(const Property::Value* value, Vector& stopOffsets) +void 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 ) ) + if ( value ) // Only check valve type if a valid Property has been passed in { - 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; iGetType() ) { - if( offsetArray->GetElementAt(i).Get(offset) ) + case Property::VECTOR2: + { + Vector2 offset2; + value->Get( offset2 ); + stopOffsets.PushBack( offset2.x ); + stopOffsets.PushBack( offset2.y ); + break; + } + case Property::VECTOR3: + { + Vector3 offset3; + value->Get( offset3 ); + stopOffsets.PushBack( offset3.x ); + stopOffsets.PushBack( offset3.y ); + stopOffsets.PushBack( offset3.z ); + break; + } + case Property::VECTOR4: { - stopOffsets.PushBack( offset ); + Vector4 offset4; + value->Get( offset4 ); + stopOffsets.PushBack( offset4.x ); + stopOffsets.PushBack( offset4.y ); + stopOffsets.PushBack( offset4.z ); + stopOffsets.PushBack( offset4.w ); + break; + } + case Property::ARRAY: + { + 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 ); + } + } + } + break; + } + default: + { + DALI_LOG_WARNING("GetStopOffsets passed unsupported Property Map\n"); + // Unsupported Type } } - return true; } - return false; + if ( stopOffsets.Empty() ) + { + // Set default offset if none set by Property system, need a minimum and maximum + stopOffsets.PushBack( DEFAULT_OFFSET_MINIMUM ); + stopOffsets.PushBack( DEFAULT_OFFSET_MAXIMUM ); + } } } // namespace Internal