2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "border-renderer.h"
22 #include <dali/integration-api/debug.h>
25 #include <dali-toolkit/internal/controls/renderers/renderer-factory-impl.h>
26 #include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
27 #include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
40 const char * const COLOR_NAME("border-color");
41 const char * const COLOR_UNIFORM_NAME("uBorderColor");
42 const char * const SIZE_NAME("border-size");
43 const char * const SIZE_UNIFORM_NAME("uBorderSize");
45 const char * const POSITION_ATTRIBUTE_NAME("aPosition");
46 const char * const DRIFT_ATTRIBUTE_NAME("aDrift");
47 const char * const INDEX_NAME("indices");
50 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
51 attribute mediump vec2 aPosition;\n
52 attribute mediump vec2 aDrift;\n
53 uniform mediump mat4 uMvpMatrix;\n
54 uniform mediump vec3 uSize;\n
55 uniform mediump float uBorderSize;\n
59 vec2 position = aPosition*uSize.xy + aDrift*uBorderSize;\n
60 gl_Position = uMvpMatrix * vec4(position, 0.0, 1.0);\n
64 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
65 uniform lowp vec4 uColor;\n
66 uniform lowp vec4 uBorderColor;\n
70 gl_FragColor = uBorderColor*uColor;\n
75 BorderRenderer::BorderRenderer()
77 mBorderColor( Color::TRANSPARENT ),
79 mBorderColorIndex( Property::INVALID_INDEX ),
80 mBorderSizeIndex( Property::INVALID_INDEX )
84 BorderRenderer::~BorderRenderer()
88 void BorderRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
90 Initialize( factoryCache );
92 Property::Value* color = propertyMap.Find( COLOR_NAME );
93 if( !( color && color->Get(mBorderColor) ) )
95 DALI_LOG_ERROR( "Fail to provide a border color to the BorderRenderer object" );
98 Property::Value* size = propertyMap.Find( SIZE_NAME );
99 if( !( size && size->Get(mBorderSize) ) )
101 DALI_LOG_ERROR( "Fail to provide a border size to the BorderRenderer object" );
105 void BorderRenderer::SetClipRect( const Rect<int>& clipRect )
107 ControlRenderer::SetClipRect( clipRect );
109 //ToDo: renderer responds to the clipRect change
112 void BorderRenderer::DoSetOnStage( Actor& actor )
114 mBorderColorIndex = (mImpl->mRenderer).RegisterProperty( COLOR_UNIFORM_NAME, mBorderColor );
115 if( mBorderColor.a < 1.f )
117 (mImpl->mRenderer).GetMaterial().SetBlendMode( BlendingMode::ON );
119 mBorderSizeIndex = (mImpl->mRenderer).RegisterProperty( SIZE_UNIFORM_NAME, mBorderSize );
122 void BorderRenderer::Initialize( RendererFactoryCache& factoryCache)
124 mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::BORDER_GEOMETRY );
125 if( !(mImpl->mGeometry) )
127 mImpl->mGeometry = CreateBorderGeometry();
128 factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry );
131 mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::BORDER_SHADER );
132 if( !(mImpl->mShader) )
134 mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
135 factoryCache.SaveShader( RendererFactoryCache::COLOR_SHADER, mImpl->mShader );
139 void BorderRenderer::SetBorderColor(const Vector4& color)
141 mBorderColor = color;
143 if( mImpl->mIsOnStage )
145 (mImpl->mRenderer).SetProperty( mBorderColorIndex, color );
146 if( color.a < 1.f && (mImpl->mRenderer).GetMaterial().GetBlendMode() != BlendingMode::ON)
148 (mImpl->mRenderer).GetMaterial().SetBlendMode( BlendingMode::ON );
153 void BorderRenderer::SetBorderSize( float size )
157 if( mImpl->mIsOnStage )
159 (mImpl->mRenderer).SetProperty( mBorderSizeIndex, size );
164 * Vertices and triangles of the border geometry:
166 * vertex position = aPosition*uSize.xy + aDrift*uBorderSize;
179 Geometry BorderRenderer::CreateBorderGeometry()
181 const float halfWidth = 0.5f;
182 const float halfHeight = 0.5f;
183 struct BorderVertex { Vector2 position; Vector2 drift;};
184 BorderVertex borderVertexData[16] =
186 { Vector2(-halfWidth, -halfHeight), Vector2(0.f, 0.f) },
187 { Vector2(-halfWidth, -halfHeight), Vector2(1.f, 0.f) },
188 { Vector2(halfWidth, -halfHeight), Vector2(-1.f, 0.f) },
189 { Vector2(halfWidth, -halfHeight), Vector2(0.f, 0.f) },
191 { Vector2(-halfWidth, -halfHeight), Vector2(0.f, 1.f) },
192 { Vector2(-halfWidth, -halfHeight), Vector2(1.f, 1.f) },
193 { Vector2(halfWidth, -halfHeight), Vector2(-1.f, 1.f) },
194 { Vector2(halfWidth, -halfHeight), Vector2(0.f, 1.f) },
196 { Vector2(-halfWidth, halfHeight), Vector2(0.f, -1.f) },
197 { Vector2(-halfWidth, halfHeight), Vector2(1.f, -1.f) },
198 { Vector2(halfWidth, halfHeight), Vector2(-1.f, -1.f) },
199 { Vector2(halfWidth, halfHeight), Vector2(0.f, -1.f) },
201 { Vector2(-halfWidth, halfHeight), Vector2(0.f, 0.f) },
202 { Vector2(-halfWidth, halfHeight), Vector2(1.f, 0.f) },
203 { Vector2(halfWidth, halfHeight), Vector2(-1.f, 0.f) },
204 { Vector2(halfWidth, halfHeight), Vector2(0.f, 0.f) },
207 Property::Map borderVertexFormat;
208 borderVertexFormat[POSITION_ATTRIBUTE_NAME] = Property::VECTOR2;
209 borderVertexFormat[DRIFT_ATTRIBUTE_NAME] = Property::VECTOR2;
210 PropertyBuffer borderVertices = PropertyBuffer::New( borderVertexFormat, 16 );
211 borderVertices.SetData(borderVertexData);
214 unsigned int indexData[48] = { 0, 4, 1, 1, 4, 5, 1, 5, 2, 2, 5, 6, 2, 6,3, 3, 6, 7,
215 4, 8, 5, 5, 8, 9, 6, 10, 7, 7, 10, 11,
216 8, 12, 9, 9, 12, 13, 9, 13, 10, 10, 13, 14, 10, 11, 14, 11, 14, 15};
218 Property::Map indexFormat;
219 indexFormat[INDEX_NAME] = Property::INTEGER;
220 PropertyBuffer indices = PropertyBuffer::New( indexFormat, 48 );
221 indices.SetData(indexData);
223 // Create the geometry object
224 Geometry geometry = Geometry::New();
225 geometry.AddVertexBuffer( borderVertices );
226 geometry.SetIndexBuffer( indices );
231 } // namespace Internal
233 } // namespace Toolkit