2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 #include "spread-filter.h"
37 const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
39 const char* const SPREAD_FRAGMENT_SOURCE =
41 "uniform float uSpread;\n"
42 "uniform vec2 uTexScale;\n"
45 " vec4 color = texture2D( sTexture, vTexCoord);\n"
46 "# ifdef DEBUG_RENDER\n"
47 " if( vTexCoord.s < 0.495 )\n"
49 "# endif //def DEBUG_RENDER\n"
50 " int spread = int(uSpread);\n"
51 " for( int i = 1; i <= spread; ++i )\n"
53 " vec2 offset = uTexScale * float(i);\n"
54 " color = max( texture2D( sTexture, vTexCoord + offset), color );\n"
55 " color = max( texture2D( sTexture, vTexCoord - offset), color );\n"
57 "# ifdef DEBUG_RENDER\n"
59 " else if( vTexCoord.s <= 0.505 )\n"
61 " color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
63 "# endif //def DEBUG_RENDER\n"
64 " gl_FragColor = color;\n"
71 SpreadFilter::SpreadFilter()
77 SpreadFilter::~SpreadFilter()
81 void SpreadFilter::SetSpread( float spread )
86 void SpreadFilter::Enable()
88 mCameraActor = CameraActor::New();
89 mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
91 // create actor to render input with applied emboss effect
92 mActorForInput = ImageActor::New( mInputImage );
93 mActorForInput.SetParentOrigin( ParentOrigin::CENTER );
94 mActorForInput.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
95 mActorForInput.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
97 // create internal offscreen for result of horizontal pass
98 mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::Unused );
100 // create an actor to render mImageForHorz for vertical blur pass
101 mActorForHorz = ImageActor::New( mImageForHorz );
102 mActorForHorz.SetParentOrigin( ParentOrigin::CENTER );
103 mActorForHorz.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
104 mActorForHorz.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
106 mRootActor.Add( mActorForInput );
107 mRootActor.Add( mActorForHorz );
108 mRootActor.Add( mCameraActor );
110 std::ostringstream fragmentSource;
113 fragmentSource << "#define DEBUG_RENDER\n";
115 fragmentSource << SPREAD_FRAGMENT_SOURCE;
117 mShaderForHorz = ShaderEffect::New( "", fragmentSource.str() );
118 mActorForInput.SetShaderEffect( mShaderForHorz );
119 mShaderForHorz.SetUniform( "uSpread", mSpread );
120 mShaderForHorz.SetUniform( "uTexScale", Vector2( 1.0f / mTargetSize.width, 0.0f ) );
122 mShaderForVert = ShaderEffect::New( "", fragmentSource.str() );
123 mActorForHorz.SetShaderEffect( mShaderForVert );
124 mShaderForVert.SetUniform( "uSpread", mSpread );
125 mShaderForVert.SetUniform( "uTexScale", Vector2( 0.0f, 1.0f / mTargetSize.height ) );
131 void SpreadFilter::Disable()
137 mRootActor.Remove( mCameraActor );
138 mCameraActor.Reset();
143 mRootActor.Remove( mActorForInput );
144 mActorForInput.Reset();
149 mRootActor.Remove( mActorForHorz );
150 mActorForHorz.Reset();
153 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
155 if( mRenderTaskForHorz )
157 taskList.RemoveTask(mRenderTaskForHorz);
159 if( mRenderTaskForVert )
161 taskList.RemoveTask(mRenderTaskForVert);
168 void SpreadFilter::Refresh()
170 if( mRenderTaskForHorz )
172 mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
175 if( mRenderTaskForVert )
177 mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
181 void SpreadFilter::SetupCamera()
183 // Create and place a camera for the embossing render, corresponding to its render target size
184 mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
185 mCameraActor.SetNearClippingPlane(1.0f);
186 mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height);
187 mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
188 mCameraActor.SetRotation(Quaternion(M_PI, Vector3::YAXIS));
189 mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
192 void SpreadFilter::CreateRenderTasks()
194 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
196 // perform a horizontal blur targeting the internal buffer
197 mRenderTaskForHorz = taskList.CreateTask();
198 mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
199 mRenderTaskForHorz.SetSourceActor( mActorForInput );
200 mRenderTaskForHorz.SetExclusive(true);
201 mRenderTaskForHorz.SetInputEnabled( false );
202 mRenderTaskForHorz.SetClearEnabled( true );
203 mRenderTaskForHorz.SetClearColor( mBackgroundColor );
204 mRenderTaskForHorz.SetTargetFrameBuffer( mImageForHorz );
205 mRenderTaskForHorz.SetCameraActor( mCameraActor );
207 // use the internal buffer and perform a horizontal blur targeting the output buffer
208 mRenderTaskForVert = taskList.CreateTask();
209 mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
210 mRenderTaskForVert.SetSourceActor( mActorForHorz );
211 mRenderTaskForVert.SetExclusive(true);
212 mRenderTaskForVert.SetInputEnabled( false );
213 mRenderTaskForVert.SetClearEnabled( true );
214 mRenderTaskForVert.SetClearColor( mBackgroundColor );
215 mRenderTaskForVert.SetTargetFrameBuffer( mOutputImage );
216 mRenderTaskForVert.SetCameraActor( mCameraActor );
219 } // namespace Internal
221 } // namespace Toolkit