Make ItemView::ActivateLayout do what it says on the tin
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / filters / emboss-filter.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://floralicense.org/license/
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 // CLASS HEADER
18 #include "emboss-filter.h"
19
20 // EXTERNAL INCLUDES
21 #include <sstream>
22
23 // INTERNAL INCLUDES
24
25 namespace Dali
26 {
27
28 namespace Toolkit
29 {
30
31 namespace Internal
32 {
33
34 namespace
35 {
36
37 const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
38
39 const char* EMBOSS_FRAGMENT_SOURCE1 =
40 {
41  "uniform vec2 uTexScale;\n"
42  "\n"
43  "void main()\n"
44  "{\n"
45  "  vec4 color;\n"
46  "# ifdef DEBUG_RENDER\n"
47  "  if( vTexCoord.s < 0.495 )\n"
48  "  {\n"
49  "# endif //def DEBUG_RENDER\n"
50  "    color  =  2.0 * texture2D( sTexture, vTexCoord + vec2(0.0, -uTexScale.y) );\n"
51  "    color += -1.0 * texture2D( sTexture, vTexCoord );\n"
52  "    color += -1.0 * texture2D( sTexture, vTexCoord + vec2(0.0, uTexScale.y) );\n"
53  "# ifdef DEBUG_RENDER\n"
54  "  }\n"
55  "  else if( vTexCoord.s > 0.505 )\n"
56  "  {\n"
57  "    color = texture2D( sTexture, vTexCoord );\n"
58  "  }\n"
59  "  else\n"
60  "  {\n"
61  "    color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
62  "  }\n"
63  "# endif //def DEBUG_RENDER\n"
64  "  gl_FragColor = uColor * color;\n"
65  "}\n"
66 };
67
68 const char* EMBOSS_FRAGMENT_SOURCE2 =
69 {
70  "uniform vec2 uTexScale;\n"
71  "\n"
72  "void main()\n"
73  "{\n"
74  "  vec4 color;\n"
75  "# ifdef DEBUG_RENDER\n"
76  "  if( vTexCoord.s < 0.495 )\n"
77  "  {\n"
78  "# endif //def DEBUG_RENDER\n"
79  "    color  = -1.0 * texture2D( sTexture, vTexCoord + vec2(0.0, -uTexScale.y) );\n"
80  "    color += -1.0 * texture2D( sTexture, vTexCoord );\n"
81  "    color +=  2.0 * texture2D( sTexture, vTexCoord + vec2(0.0, uTexScale.y) );\n"
82  "# ifdef DEBUG_RENDER\n"
83  "  }\n"
84  "  else if( vTexCoord.s > 0.505 )\n"
85  "  {\n"
86  "    color = texture2D( sTexture, vTexCoord );\n"
87  "  }\n"
88  "  else\n"
89  "  {\n"
90  "    color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
91  "  }\n"
92  "# endif //def DEBUG_RENDER\n"
93  "  gl_FragColor = uColor * color;\n"
94  "}\n"
95 };
96
97 const char* const COMPOSITE_FRAGMENT_SOURCE =
98     "void main()\n"
99     "{\n"
100     "  gl_FragColor = uColor;\n"
101     "  gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n"
102     "}\n";
103
104 } // namespace
105
106 EmbossFilter::EmbossFilter()
107 : ImageFilter()
108 {
109 }
110
111 EmbossFilter::~EmbossFilter()
112 {
113 }
114
115 void EmbossFilter::Enable()
116 {
117   // Create camera
118   mCameraActor = CameraActor::New();
119   mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
120
121   mImageForEmboss1 = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::Unused );
122   mImageForEmboss2 = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::Unused );
123
124   // create actor to render input with applied emboss effect
125   mActorForInput1 = ImageActor::New( mInputImage );
126   mActorForInput1.SetParentOrigin( ParentOrigin::CENTER );
127   mActorForInput1.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
128   mActorForInput1.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
129   mActorForInput1.SetColor( Color::WHITE );
130
131   mActorForInput2 = ImageActor::New( mInputImage );
132   mActorForInput2.SetParentOrigin( ParentOrigin::CENTER );
133   mActorForInput2.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
134   mActorForInput2.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
135   mActorForInput2.SetColor( Color::WHITE );
136
137   mActorForEmboss1 = ImageActor::New( mImageForEmboss1 );
138   mActorForEmboss1.SetParentOrigin( ParentOrigin::CENTER );
139   mActorForEmboss1.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
140   mActorForEmboss1.SetColor( Color::BLACK );
141   mActorForEmboss1.SetShaderEffect( ShaderEffect::New( "", COMPOSITE_FRAGMENT_SOURCE ) );
142
143   mActorForEmboss2 = ImageActor::New( mImageForEmboss2 );
144   mActorForEmboss2.SetParentOrigin( ParentOrigin::CENTER );
145   mActorForEmboss2.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
146   mActorForEmboss2.SetColor( Color::WHITE );
147   mActorForEmboss2.SetShaderEffect( ShaderEffect::New( "", COMPOSITE_FRAGMENT_SOURCE ) );
148
149   mActorForComposite = Actor::New();
150   mActorForComposite.SetParentOrigin( ParentOrigin::CENTER );
151   mActorForComposite.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
152   mActorForComposite.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
153
154   // create custom shader effect
155   std::ostringstream embossFragmentSource1;
156   if( mDebugRender )
157   {
158     embossFragmentSource1 << "#define DEBUG_RENDER\n";
159   }
160   embossFragmentSource1 << EMBOSS_FRAGMENT_SOURCE1;
161   ShaderEffect effect1 = ShaderEffect::New( "", embossFragmentSource1.str() );
162   mActorForInput1.SetShaderEffect( effect1 );
163   effect1.SetUniform( "uTexScale", Vector2( 1.0f/mTargetSize.width, 1.0f/mTargetSize.height) * 1.5f );
164
165   std::ostringstream embossFragmentSource2;
166   if( mDebugRender )
167   {
168     embossFragmentSource2 << "#define DEBUG_RENDER\n";
169   }
170   embossFragmentSource2 << EMBOSS_FRAGMENT_SOURCE2;
171   ShaderEffect effect2 = ShaderEffect::New( "", embossFragmentSource2.str() );
172   mActorForInput2.SetShaderEffect( effect2 );
173   effect2.SetUniform( "uTexScale", Vector2( 1.0f/mTargetSize.width, 1.0f/mTargetSize.height) * 1.5f );
174
175   SetupCamera();
176   CreateRenderTasks();
177
178   mRootActor.Add( mActorForInput1 );
179   mRootActor.Add( mActorForInput2 );
180   mRootActor.Add( mActorForComposite );
181   mActorForComposite.Add( mActorForEmboss1 );
182   mActorForComposite.Add( mActorForEmboss2 );
183   mRootActor.Add( mCameraActor );
184 }
185
186 void EmbossFilter::Disable()
187 {
188   if( mRootActor )
189   {
190     if( mCameraActor )
191     {
192       mRootActor.Remove( mCameraActor );
193       mCameraActor.Reset();
194     }
195
196     if( mActorForInput1 )
197     {
198       mRootActor.Remove( mActorForInput1 );
199       mActorForInput1.Reset();
200     }
201
202     if( mActorForInput2 )
203     {
204       mRootActor.Remove( mActorForInput2 );
205       mActorForInput2.Reset();
206     }
207
208     if( mActorForComposite )
209     {
210       mRootActor.Remove( mActorForComposite );
211       mActorForComposite.Reset();
212       mActorForEmboss1.Reset();
213       mActorForEmboss2.Reset();
214     }
215
216     RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
217     if( mRenderTaskForEmboss1 )
218     {
219       taskList.RemoveTask(mRenderTaskForEmboss1);
220     }
221
222     if( mRenderTaskForEmboss2 )
223     {
224       taskList.RemoveTask(mRenderTaskForEmboss2);
225     }
226
227     mRootActor.Reset();
228   }
229 }
230
231 void EmbossFilter::Refresh()
232 {
233   if( mRenderTaskForEmboss1 )
234   {
235     mRenderTaskForEmboss1.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
236   }
237   if( mRenderTaskForEmboss2 )
238   {
239     mRenderTaskForEmboss2.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
240   }
241 }
242
243 void EmbossFilter::SetupCamera()
244 {
245   // Create and place a camera for the embossing render, corresponding to its render target size
246   mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
247   mCameraActor.SetNearClippingPlane(1.0f);
248   mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height);
249   mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
250   mCameraActor.SetRotation(Quaternion(M_PI, Vector3::YAXIS));
251   mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
252 }
253
254 void EmbossFilter::CreateRenderTasks()
255 {
256   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
257
258   mRenderTaskForEmboss1 = taskList.CreateTask();
259   mRenderTaskForEmboss1.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
260   mRenderTaskForEmboss1.SetSourceActor( mActorForInput1 );
261   mRenderTaskForEmboss1.SetExclusive(true);
262   mRenderTaskForEmboss1.SetInputEnabled( false );
263   mRenderTaskForEmboss1.SetClearColor( Vector4( 0.0f, 0.0f, 0.0f, 0.0f ) );
264   mRenderTaskForEmboss1.SetClearEnabled( true );
265   mRenderTaskForEmboss1.SetTargetFrameBuffer( mImageForEmboss1 );
266   mRenderTaskForEmboss1.SetCameraActor( mCameraActor );
267
268   mRenderTaskForEmboss2 = taskList.CreateTask();
269   mRenderTaskForEmboss2.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
270   mRenderTaskForEmboss2.SetSourceActor( mActorForInput2 );
271   mRenderTaskForEmboss2.SetExclusive(true);
272   mRenderTaskForEmboss2.SetInputEnabled( false );
273   mRenderTaskForEmboss2.SetClearColor( Vector4( 1.0f, 1.0f, 1.0f, 0.0f ) );
274   mRenderTaskForEmboss2.SetClearEnabled( true );
275   mRenderTaskForEmboss2.SetTargetFrameBuffer( mImageForEmboss2 );
276   mRenderTaskForEmboss2.SetCameraActor( mCameraActor );
277
278   mRenderTaskForOutput = taskList.CreateTask();
279   mRenderTaskForOutput.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
280   mRenderTaskForOutput.SetSourceActor( mActorForComposite );
281   mRenderTaskForOutput.SetExclusive(true);
282   mRenderTaskForOutput.SetInputEnabled( false );
283   mRenderTaskForOutput.SetClearColor( Vector4( 0.5f, 0.5f, 0.5f, 0.0f ) );
284   mRenderTaskForOutput.SetClearEnabled( true );
285   mRenderTaskForOutput.SetTargetFrameBuffer( mOutputImage );
286   mRenderTaskForOutput.SetCameraActor( mCameraActor );
287 }
288
289 } // namespace Internal
290
291 } // namespace Toolkit
292
293 } // namespace Dali