2 * Copyright (c) 2014 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 "spread-filter.h"
38 const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
40 const char* const SPREAD_FRAGMENT_SOURCE =
42 "uniform float uSpread;\n"
43 "uniform vec2 uTexScale;\n"
46 " vec4 color = texture2D( sTexture, vTexCoord);\n"
47 "# ifdef DEBUG_RENDER\n"
48 " if( vTexCoord.s < 0.495 )\n"
50 "# endif //def DEBUG_RENDER\n"
51 " int spread = int(uSpread);\n"
52 " for( int i = 1; i <= spread; ++i )\n"
54 " vec2 offset = uTexScale * float(i);\n"
55 " color = max( texture2D( sTexture, vTexCoord + offset), color );\n"
56 " color = max( texture2D( sTexture, vTexCoord - offset), color );\n"
58 "# ifdef DEBUG_RENDER\n"
60 " else if( vTexCoord.s <= 0.505 )\n"
62 " color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
64 "# endif //def DEBUG_RENDER\n"
65 " gl_FragColor = color;\n"
72 SpreadFilter::SpreadFilter()
78 SpreadFilter::~SpreadFilter()
82 void SpreadFilter::SetSpread( float spread )
87 void SpreadFilter::Enable()
89 mCameraActor = CameraActor::New();
90 mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
92 // create actor to render input with applied emboss effect
93 mActorForInput = ImageActor::New( mInputImage );
94 mActorForInput.SetParentOrigin( ParentOrigin::CENTER );
95 mActorForInput.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
96 mActorForInput.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
98 // create internal offscreen for result of horizontal pass
99 mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::Unused );
101 // create an actor to render mImageForHorz for vertical blur pass
102 mActorForHorz = ImageActor::New( mImageForHorz );
103 mActorForHorz.SetParentOrigin( ParentOrigin::CENTER );
104 mActorForHorz.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
105 mActorForHorz.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
107 mRootActor.Add( mActorForInput );
108 mRootActor.Add( mActorForHorz );
109 mRootActor.Add( mCameraActor );
111 std::ostringstream fragmentSource;
114 fragmentSource << "#define DEBUG_RENDER\n";
116 fragmentSource << SPREAD_FRAGMENT_SOURCE;
118 mShaderForHorz = ShaderEffect::New( "", fragmentSource.str() );
119 mActorForInput.SetShaderEffect( mShaderForHorz );
120 mShaderForHorz.SetUniform( "uSpread", mSpread );
121 mShaderForHorz.SetUniform( "uTexScale", Vector2( 1.0f / mTargetSize.width, 0.0f ) );
123 mShaderForVert = ShaderEffect::New( "", fragmentSource.str() );
124 mActorForHorz.SetShaderEffect( mShaderForVert );
125 mShaderForVert.SetUniform( "uSpread", mSpread );
126 mShaderForVert.SetUniform( "uTexScale", Vector2( 0.0f, 1.0f / mTargetSize.height ) );
132 void SpreadFilter::Disable()
138 mRootActor.Remove( mCameraActor );
139 mCameraActor.Reset();
144 mRootActor.Remove( mActorForInput );
145 mActorForInput.Reset();
150 mRootActor.Remove( mActorForHorz );
151 mActorForHorz.Reset();
154 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
156 if( mRenderTaskForHorz )
158 taskList.RemoveTask(mRenderTaskForHorz);
160 if( mRenderTaskForVert )
162 taskList.RemoveTask(mRenderTaskForVert);
169 void SpreadFilter::Refresh()
171 if( mRenderTaskForHorz )
173 mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
176 if( mRenderTaskForVert )
178 mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
182 void SpreadFilter::SetupCamera()
184 // Create and place a camera for the embossing render, corresponding to its render target size
185 mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
186 mCameraActor.SetNearClippingPlane(1.0f);
187 mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height);
188 mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
189 mCameraActor.SetRotation(Quaternion(M_PI, Vector3::YAXIS));
190 mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
193 void SpreadFilter::CreateRenderTasks()
195 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
197 // perform a horizontal blur targeting the internal buffer
198 mRenderTaskForHorz = taskList.CreateTask();
199 mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
200 mRenderTaskForHorz.SetSourceActor( mActorForInput );
201 mRenderTaskForHorz.SetExclusive(true);
202 mRenderTaskForHorz.SetInputEnabled( false );
203 mRenderTaskForHorz.SetClearEnabled( true );
204 mRenderTaskForHorz.SetClearColor( mBackgroundColor );
205 mRenderTaskForHorz.SetTargetFrameBuffer( mImageForHorz );
206 mRenderTaskForHorz.SetCameraActor( mCameraActor );
208 // use the internal buffer and perform a horizontal blur targeting the output buffer
209 mRenderTaskForVert = taskList.CreateTask();
210 mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
211 mRenderTaskForVert.SetSourceActor( mActorForHorz );
212 mRenderTaskForVert.SetExclusive(true);
213 mRenderTaskForVert.SetInputEnabled( false );
214 mRenderTaskForVert.SetClearEnabled( true );
215 mRenderTaskForVert.SetClearColor( mBackgroundColor );
216 mRenderTaskForVert.SetTargetFrameBuffer( mOutputImage );
217 mRenderTaskForVert.SetCameraActor( mCameraActor );
220 } // namespace Internal
222 } // namespace Toolkit