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 "uniform float uSpread;\n"
46 "uniform vec2 uTexScale;\n"
49 " vec4 color = texture2D( sTexture, vTexCoord);\n"
50 "# ifdef DEBUG_RENDER\n"
51 " if( vTexCoord.s < 0.495 )\n"
53 "# endif //def DEBUG_RENDER\n"
54 " int spread = int(uSpread);\n"
55 " for( int i = 1; i <= spread; ++i )\n"
57 " vec2 offset = uTexScale * float(i);\n"
58 " color = max( texture2D( sTexture, vTexCoord + offset), color );\n"
59 " color = max( texture2D( sTexture, vTexCoord - offset), color );\n"
61 "# ifdef DEBUG_RENDER\n"
63 " else if( vTexCoord.s <= 0.505 )\n"
65 " color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
67 "# endif //def DEBUG_RENDER\n"
68 " gl_FragColor = color;\n"
75 SpreadFilter::SpreadFilter()
81 SpreadFilter::~SpreadFilter()
85 void SpreadFilter::SetSpread( float spread )
90 void SpreadFilter::Enable()
92 mCameraActor = CameraActor::New();
93 mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
95 // create actor to render input with applied emboss effect
96 mActorForInput = ImageActor::New( mInputImage );
97 mActorForInput.SetParentOrigin( ParentOrigin::CENTER );
98 mActorForInput.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
99 mActorForInput.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
101 // create internal offscreen for result of horizontal pass
102 mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::Unused );
104 // create an actor to render mImageForHorz for vertical blur pass
105 mActorForHorz = ImageActor::New( mImageForHorz );
106 mActorForHorz.SetParentOrigin( ParentOrigin::CENTER );
107 mActorForHorz.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
108 mActorForHorz.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
110 mRootActor.Add( mActorForInput );
111 mRootActor.Add( mActorForHorz );
112 mRootActor.Add( mCameraActor );
114 std::ostringstream fragmentSource;
117 fragmentSource << "#define DEBUG_RENDER\n";
119 fragmentSource << SPREAD_FRAGMENT_SOURCE;
121 mShaderForHorz = ShaderEffect::New( "", fragmentSource.str() );
122 mActorForInput.SetShaderEffect( mShaderForHorz );
123 mShaderForHorz.SetUniform( "uSpread", mSpread );
124 mShaderForHorz.SetUniform( "uTexScale", Vector2( 1.0f / mTargetSize.width, 0.0f ) );
126 mShaderForVert = ShaderEffect::New( "", fragmentSource.str() );
127 mActorForHorz.SetShaderEffect( mShaderForVert );
128 mShaderForVert.SetUniform( "uSpread", mSpread );
129 mShaderForVert.SetUniform( "uTexScale", Vector2( 0.0f, 1.0f / mTargetSize.height ) );
135 void SpreadFilter::Disable()
141 mRootActor.Remove( mCameraActor );
142 mCameraActor.Reset();
147 mRootActor.Remove( mActorForInput );
148 mActorForInput.Reset();
153 mRootActor.Remove( mActorForHorz );
154 mActorForHorz.Reset();
157 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
159 if( mRenderTaskForHorz )
161 taskList.RemoveTask(mRenderTaskForHorz);
163 if( mRenderTaskForVert )
165 taskList.RemoveTask(mRenderTaskForVert);
172 void SpreadFilter::Refresh()
174 if( mRenderTaskForHorz )
176 mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
179 if( mRenderTaskForVert )
181 mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
185 void SpreadFilter::SetupCamera()
187 // Create and place a camera for the embossing render, corresponding to its render target size
188 mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
189 mCameraActor.SetNearClippingPlane(1.0f);
190 mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height);
191 mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
192 mCameraActor.SetRotation(Quaternion(M_PI, Vector3::YAXIS));
193 mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
196 void SpreadFilter::CreateRenderTasks()
198 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
200 // perform a horizontal blur targeting the internal buffer
201 mRenderTaskForHorz = taskList.CreateTask();
202 mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
203 mRenderTaskForHorz.SetSourceActor( mActorForInput );
204 mRenderTaskForHorz.SetExclusive(true);
205 mRenderTaskForHorz.SetInputEnabled( false );
206 mRenderTaskForHorz.SetClearEnabled( true );
207 mRenderTaskForHorz.SetClearColor( mBackgroundColor );
208 mRenderTaskForHorz.SetTargetFrameBuffer( mImageForHorz );
209 mRenderTaskForHorz.SetCameraActor( mCameraActor );
211 // use the internal buffer and perform a horizontal blur targeting the output buffer
212 mRenderTaskForVert = taskList.CreateTask();
213 mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
214 mRenderTaskForVert.SetSourceActor( mActorForHorz );
215 mRenderTaskForVert.SetExclusive(true);
216 mRenderTaskForVert.SetInputEnabled( false );
217 mRenderTaskForVert.SetClearEnabled( true );
218 mRenderTaskForVert.SetClearColor( mBackgroundColor );
219 mRenderTaskForVert.SetTargetFrameBuffer( mOutputImage );
220 mRenderTaskForVert.SetCameraActor( mCameraActor );
223 } // namespace Internal
225 } // namespace Toolkit