Remove Deprecated APIs
[platform/core/uifw/dali-toolkit.git] / optional / dali-toolkit / internal / filters / spread-filter.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include "spread-filter.h"
20
21 // EXTERNAL INCLUDES
22 #include <sstream>
23
24 // INTERNAL INCLUDES
25
26 namespace Dali
27 {
28
29 namespace Toolkit
30 {
31
32 namespace Internal
33 {
34
35 namespace
36 {
37
38 const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
39
40 const char* const SPREAD_FRAGMENT_SOURCE =
41 {
42  "uniform float uSpread;\n"
43  "uniform vec2 uTexScale;\n"
44  "void main()\n"
45  "{\n"
46  "  vec4 color = texture2D( sTexture, vTexCoord);\n"
47  "# ifdef DEBUG_RENDER\n"
48  "  if( vTexCoord.s < 0.495 )\n"
49  "  {\n"
50  "# endif //def DEBUG_RENDER\n"
51  "    int spread = int(uSpread);\n"
52  "    for( int i = 1; i <= spread; ++i )\n"
53  "    {\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"
57  "    }\n"
58  "# ifdef DEBUG_RENDER\n"
59  "  }\n"
60  "  else if( vTexCoord.s <= 0.505 )\n"
61  "  {\n"
62  "    color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
63  "  }\n"
64  "# endif //def DEBUG_RENDER\n"
65  "  gl_FragColor = color;\n"
66  "}\n"
67 };
68
69 } // namespace
70
71
72 SpreadFilter::SpreadFilter()
73 : ImageFilter(),
74   mSpread(2)
75 {
76 }
77
78 SpreadFilter::~SpreadFilter()
79 {
80 }
81
82 void SpreadFilter::SetSpread( float spread )
83 {
84   mSpread = spread;
85 }
86
87 void SpreadFilter::Enable()
88 {
89   mCameraActor = CameraActor::New();
90   mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
91
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) );
97
98   // create internal offscreen for result of horizontal pass
99   mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::Unused );
100
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) );
106
107   mRootActor.Add( mActorForInput );
108   mRootActor.Add( mActorForHorz );
109   mRootActor.Add( mCameraActor );
110
111   std::ostringstream fragmentSource;
112   if( mDebugRender )
113   {
114     fragmentSource << "#define DEBUG_RENDER\n";
115   }
116   fragmentSource << SPREAD_FRAGMENT_SOURCE;
117
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 ) );
122
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 ) );
127
128   SetupCamera();
129   CreateRenderTasks();
130 }
131
132 void SpreadFilter::Disable()
133 {
134   if( mRootActor )
135   {
136     if( mCameraActor )
137     {
138       mRootActor.Remove( mCameraActor );
139       mCameraActor.Reset();
140     }
141
142     if( mActorForInput )
143     {
144       mRootActor.Remove( mActorForInput );
145       mActorForInput.Reset();
146     }
147
148     if( mActorForHorz )
149     {
150       mRootActor.Remove( mActorForHorz );
151       mActorForHorz.Reset();
152     }
153
154     RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
155
156     if( mRenderTaskForHorz )
157     {
158       taskList.RemoveTask(mRenderTaskForHorz);
159     }
160     if( mRenderTaskForVert )
161     {
162       taskList.RemoveTask(mRenderTaskForVert);
163     }
164
165     mRootActor.Reset();
166   }
167 }
168
169 void SpreadFilter::Refresh()
170 {
171   if( mRenderTaskForHorz )
172   {
173     mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
174   }
175
176   if( mRenderTaskForVert )
177   {
178     mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
179   }
180 }
181
182 void SpreadFilter::SetupCamera()
183 {
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)));
191 }
192
193 void SpreadFilter::CreateRenderTasks()
194 {
195   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
196
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 );
207
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 );
218 }
219
220 } // namespace Internal
221
222 } // namespace Toolkit
223
224 } // namespace Dali