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"
23 #include <dali/public-api/animation/constraints.h>
24 #include <dali/public-api/common/stage.h>
25 #include <dali/public-api/render-tasks/render-task-list.h>
41 const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
43 const char* const SPREAD_FRAGMENT_SOURCE =
45 "precision highp float;\n"
46 "uniform float uSpread;\n"
47 "uniform vec2 uTexScale;\n"
50 " vec4 color = texture2D( sTexture, vTexCoord);\n"
51 "# ifdef DEBUG_RENDER\n"
52 " if( vTexCoord.s < 0.495 )\n"
54 "# endif //def DEBUG_RENDER\n"
55 " int spread = int(uSpread);\n"
56 " for( int i = 1; i <= spread; ++i )\n"
58 " vec2 offset = uTexScale * float(i);\n"
59 " color = max( texture2D( sTexture, vTexCoord + offset), color );\n"
60 " color = max( texture2D( sTexture, vTexCoord - offset), color );\n"
62 "# ifdef DEBUG_RENDER\n"
64 " else if( vTexCoord.s <= 0.505 )\n"
66 " color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
68 "# endif //def DEBUG_RENDER\n"
69 " gl_FragColor = color;\n"
76 SpreadFilter::SpreadFilter()
82 SpreadFilter::~SpreadFilter()
86 void SpreadFilter::SetSpread( float spread )
91 void SpreadFilter::Enable()
93 mCameraActor = CameraActor::New();
94 mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
96 // create actor to render input with applied emboss effect
97 mActorForInput = ImageActor::New( mInputImage );
98 mActorForInput.SetParentOrigin( ParentOrigin::CENTER );
99 mActorForInput.SetSize(mTargetSize);
100 mActorForInput.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
102 // create internal offscreen for result of horizontal pass
103 mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED );
105 // create an actor to render mImageForHorz for vertical blur pass
106 mActorForHorz = ImageActor::New( mImageForHorz );
107 mActorForHorz.SetParentOrigin( ParentOrigin::CENTER );
108 mActorForHorz.SetSize(mTargetSize);
109 mActorForHorz.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
111 mRootActor.Add( mActorForInput );
112 mRootActor.Add( mActorForHorz );
113 mRootActor.Add( mCameraActor );
115 std::ostringstream fragmentSource;
118 fragmentSource << "#define DEBUG_RENDER\n";
120 fragmentSource << SPREAD_FRAGMENT_SOURCE;
122 mShaderForHorz = ShaderEffect::New( "", fragmentSource.str() );
123 mActorForInput.SetShaderEffect( mShaderForHorz );
124 mShaderForHorz.SetUniform( "uSpread", mSpread );
125 mShaderForHorz.SetUniform( "uTexScale", Vector2( 1.0f / mTargetSize.width, 0.0f ) );
127 mShaderForVert = ShaderEffect::New( "", fragmentSource.str() );
128 mActorForHorz.SetShaderEffect( mShaderForVert );
129 mShaderForVert.SetUniform( "uSpread", mSpread );
130 mShaderForVert.SetUniform( "uTexScale", Vector2( 0.0f, 1.0f / mTargetSize.height ) );
136 void SpreadFilter::Disable()
142 mRootActor.Remove( mCameraActor );
143 mCameraActor.Reset();
148 mRootActor.Remove( mActorForInput );
149 mActorForInput.Reset();
154 mRootActor.Remove( mActorForHorz );
155 mActorForHorz.Reset();
158 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
160 if( mRenderTaskForHorz )
162 taskList.RemoveTask(mRenderTaskForHorz);
164 if( mRenderTaskForVert )
166 taskList.RemoveTask(mRenderTaskForVert);
173 void SpreadFilter::Refresh()
175 if( mRenderTaskForHorz )
177 mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
180 if( mRenderTaskForVert )
182 mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
186 void SpreadFilter::SetSize( const Vector2& size )
191 mActorForInput.SetSize(mTargetSize);
195 mActorForHorz.SetSize(mTargetSize);
199 void SpreadFilter::SetupCamera()
201 // Create and place a camera for the embossing render, corresponding to its render target size
202 mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
203 mCameraActor.SetNearClippingPlane(1.0f);
204 mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height);
205 mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
206 mCameraActor.SetRotation(Quaternion(M_PI, Vector3::YAXIS));
207 mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
210 void SpreadFilter::CreateRenderTasks()
212 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
214 // perform a horizontal blur targeting the internal buffer
215 mRenderTaskForHorz = taskList.CreateTask();
216 mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
217 mRenderTaskForHorz.SetSourceActor( mActorForInput );
218 mRenderTaskForHorz.SetExclusive(true);
219 mRenderTaskForHorz.SetInputEnabled( false );
220 mRenderTaskForHorz.SetClearEnabled( true );
221 mRenderTaskForHorz.SetClearColor( mBackgroundColor );
222 mRenderTaskForHorz.SetTargetFrameBuffer( mImageForHorz );
223 mRenderTaskForHorz.SetCameraActor( mCameraActor );
225 // use the internal buffer and perform a horizontal blur targeting the output buffer
226 mRenderTaskForVert = taskList.CreateTask();
227 mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
228 mRenderTaskForVert.SetSourceActor( mActorForHorz );
229 mRenderTaskForVert.SetExclusive(true);
230 mRenderTaskForVert.SetInputEnabled( false );
231 mRenderTaskForVert.SetClearEnabled( true );
232 mRenderTaskForVert.SetClearColor( mBackgroundColor );
233 mRenderTaskForVert.SetTargetFrameBuffer( mOutputImage );
234 mRenderTaskForVert.SetCameraActor( mCameraActor );
237 } // namespace Internal
239 } // namespace Toolkit