Merge "Make Dali::Vector movable & add use Modern C++ semantics on public & devel...
[platform/core/uifw/dali-core.git] / automated-tests / src / dali-internal / utc-Dali-Internal-FrustumCulling.cpp
1 /*
2  * Copyright (c) 2020 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 // EXTERNAL INCLUDES
19 #include <dali/public-api/dali-core.h>
20 #include <dali/integration-api/bitmap.h>
21 #include <iostream>
22 #include <algorithm>
23 #include <stdlib.h>
24
25 // INTERNAL INCLUDES
26 #include <dali-test-suite-utils.h>
27 #include <mesh-builder.h>
28
29 using namespace Dali;
30
31 #define MAKE_SHADER(A)#A
32
33 const char* VERTEX_SHADER = MAKE_SHADER(
34 attribute mediump vec2    aPosition;
35 attribute mediump vec2    aTexCoord;
36 uniform   mediump mat4    uMvpMatrix;
37 uniform   mediump vec3    uSize;
38 varying   mediump vec2    vTexCoord;
39
40 void main()
41 {
42   mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);
43   vertexPosition.xyz *= uSize;
44   vertexPosition = uMvpMatrix * vertexPosition;
45   vTexCoord = aTexCoord;
46   gl_Position = vertexPosition;
47 }
48 );
49
50 const char* FRAGMENT_SHADER = MAKE_SHADER(
51 uniform Sampler2D sTexture;
52 varying mediump vec2 vTexCoord;
53 void main()
54 {
55   gl_FragColor = texture2D( sTexture, vTexCoord );
56 }
57 );
58
59 Actor CreateMeshActorToScene( TestApplication& application, Vector3 parentOrigin = ParentOrigin::CENTER, Vector3 anchorPoint = AnchorPoint::CENTER, Shader::Hint::Value shaderHints = Shader::Hint::NONE )
60 {
61   Integration::PixelBuffer* pixelBuffer = new Integration::PixelBuffer[ 4 ];
62   PixelData pixelData = PixelData::New(pixelBuffer, 4, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY);
63   Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
64   image.Upload(pixelData);
65
66   Geometry geometry = CreateQuadGeometry();
67   Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER, shaderHints );
68   TextureSet textureSet = TextureSet::New();
69   textureSet.SetTexture(0u, image);
70   Renderer renderer = Renderer::New( geometry, shader );
71   renderer.SetTextures( textureSet );
72
73   Actor meshActor = Actor::New();
74   meshActor.AddRenderer( renderer );
75   meshActor.SetProperty( Actor::Property::SIZE, Vector3( 400.0f, 400.0f, 0.1f ) );
76   meshActor.SetProperty( Actor::Property::PARENT_ORIGIN, parentOrigin );
77   meshActor.SetProperty( Actor::Property::ANCHOR_POINT, anchorPoint );
78   application.GetScene().Add( meshActor );
79
80   application.SendNotification();
81   application.Render( 16 );
82
83   return meshActor;
84 }
85
86 bool GetCameraDepths( TestApplication& application, float& nearPlane, float& farPlane, float& cameraDepth )
87 {
88   RenderTaskList renderTasks = application.GetScene().GetRenderTaskList();
89   CameraActor cameraActor;
90   for( unsigned int i = 0; i < renderTasks.GetTaskCount(); ++i )
91   {
92     RenderTask task = renderTasks.GetTask( i );
93     cameraActor = task.GetCameraActor();
94     if( cameraActor )
95     {
96       break;
97     }
98   }
99   if( cameraActor )
100   {
101     application.SendNotification();
102     application.Render( 16 );
103
104     nearPlane = cameraActor.GetNearClippingPlane();
105     farPlane = cameraActor.GetFarClippingPlane();
106     cameraDepth = cameraActor.GetCurrentProperty< Vector3 >( Actor::Property::POSITION ).z;
107   }
108
109   return !!cameraActor;
110 }
111
112 int UtcFrustumCullN(void)
113 {
114   TestApplication application;
115   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
116   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
117   drawTrace.Enable( true );
118
119   CreateMeshActorToScene( application );
120
121   drawTrace.Reset();
122   application.SendNotification();
123   application.Render( 16 );
124
125   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
126
127   END_TEST;
128 }
129
130 int UtcFrustumLeftCullP(void)
131 {
132   TestApplication application;
133   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
134   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
135   drawTrace.Enable( true );
136
137   float offset = -0.01f;
138   Actor meshActor = CreateMeshActorToScene( application, Vector3( offset, 0.5f, 0.5f ), AnchorPoint::CENTER_RIGHT );
139
140   float radius = meshActor.GetTargetSize().Length() * 0.5f;
141   Vector2 sceneSize = application.GetScene().GetSize();
142   meshActor.SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( -radius / sceneSize.width + offset, 0.5f, 0.5f ) );
143   meshActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
144
145   drawTrace.Reset();
146   application.SendNotification();
147   application.Render( 16 );
148
149   // This will be sphere culled
150   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
151
152   END_TEST;
153 }
154
155 int UtcFrustumLeftCullN(void)
156 {
157   TestApplication application;
158   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
159   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
160   drawTrace.Enable( true );
161
162   float offset = 0.01f;
163   Actor meshActor = CreateMeshActorToScene( application, Vector3( offset, 0.5f, 0.5f ), AnchorPoint::CENTER_RIGHT );
164
165   drawTrace.Reset();
166   application.SendNotification();
167   application.Render( 16 );
168
169   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
170
171   END_TEST;
172 }
173
174 int UtcFrustumRightCullP(void)
175 {
176   TestApplication application;
177   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
178   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
179   drawTrace.Enable( true );
180
181   float offset = 1.01f;
182   Actor meshActor = CreateMeshActorToScene( application, Vector3( offset, 0.5f, 0.5f ), AnchorPoint::CENTER_LEFT );
183
184   float radius = meshActor.GetTargetSize().Length() * 0.5f;
185   Vector2 sceneSize = application.GetScene().GetSize();
186
187   meshActor.SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( radius / sceneSize.width + offset, 0.5f, 0.5f ) );
188   meshActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
189
190   drawTrace.Reset();
191   application.SendNotification();
192   application.Render( 16 );
193
194   // This will be sphere culled
195   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
196
197   END_TEST;
198 }
199
200 int UtcFrustumRightCullN(void)
201 {
202   TestApplication application;
203   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
204   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
205   drawTrace.Enable( true );
206
207   float offset = 0.99f;
208   Actor meshActor = CreateMeshActorToScene( application, Vector3( offset, 0.5f, 0.5f ), AnchorPoint::CENTER_LEFT );
209
210   drawTrace.Reset();
211   application.SendNotification();
212   application.Render( 16 );
213
214   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
215
216   END_TEST;
217 }
218
219 int UtcFrustumTopCullP(void)
220 {
221   TestApplication application;
222   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
223   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
224   drawTrace.Enable( true );
225
226   float offset = -0.01f;
227   Actor meshActor = CreateMeshActorToScene( application, Vector3( 0.5f, offset, 0.5f ), AnchorPoint::BOTTOM_CENTER );
228
229   float radius = meshActor.GetTargetSize().Length() * 0.5f;
230   Vector2 sceneSize = application.GetScene().GetSize();
231
232   meshActor.SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 0.5f, -radius / sceneSize.width + offset, 0.5f ) );
233   meshActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
234
235   drawTrace.Reset();
236   application.SendNotification();
237   application.Render( 16 );
238
239   // This will be sphere culled
240   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
241
242   END_TEST;
243 }
244
245 int UtcFrustumTopCullN(void)
246 {
247   TestApplication application;
248   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
249   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
250   drawTrace.Enable( true );
251
252   float offset = 0.01f;
253   Actor meshActor = CreateMeshActorToScene( application, Vector3( 0.5f, offset, 0.5f ), AnchorPoint::BOTTOM_CENTER );
254
255   drawTrace.Reset();
256   application.SendNotification();
257   application.Render( 16 );
258
259   // This will be box culled
260   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
261
262   END_TEST;
263 }
264
265 int UtcFrustumBottomCullP(void)
266 {
267   TestApplication application;
268   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
269   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
270   drawTrace.Enable( true );
271
272   float offset = 1.01f;
273   Actor meshActor = CreateMeshActorToScene( application, Vector3( 0.5f, offset, 0.5f ), AnchorPoint::TOP_CENTER );
274
275   float radius = meshActor.GetTargetSize().Length() * 0.5f;
276   Vector2 sceneSize = application.GetScene().GetSize();
277
278   meshActor.SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 0.5f, radius / sceneSize.width + offset, 0.5f ) );
279   meshActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
280
281   drawTrace.Reset();
282   application.SendNotification();
283   application.Render( 16 );
284
285   // This will be sphere culled
286   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
287
288   END_TEST;
289 }
290
291 int UtcFrustumBottomCullN(void)
292 {
293   TestApplication application;
294   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
295   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
296   drawTrace.Enable( true );
297
298   float offset = 0.99f;
299   Actor meshActor = CreateMeshActorToScene( application, Vector3( 0.5f, offset, 0.5f ), AnchorPoint::TOP_CENTER );
300
301   drawTrace.Reset();
302   application.SendNotification();
303   application.Render( 16 );
304
305   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
306
307   END_TEST;
308 }
309
310 int UtcFrustumNearCullP(void)
311 {
312   TestApplication application;
313   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
314   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
315   drawTrace.Enable( true );
316
317   float nearPlane, farPlane, cameraDepth;
318   DALI_TEST_CHECK( GetCameraDepths( application, nearPlane, farPlane, cameraDepth ) );
319
320   Actor meshActor = CreateMeshActorToScene( application );
321   Vector3 meshPosition = meshActor.GetCurrentProperty< Vector3 >( Actor::Property::POSITION );
322
323   float radius = meshActor.GetTargetSize().Length() * 0.5f;
324   float offset = radius + 0.1f;
325   meshPosition.z = cameraDepth - nearPlane + offset;
326   meshActor.SetProperty( Actor::Property::POSITION, meshPosition );
327
328   drawTrace.Reset();
329   application.SendNotification();
330   application.Render( 16 );
331
332   // This will be sphere culled
333   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
334
335   END_TEST;
336 }
337
338 int UtcFrustumNearCullN(void)
339 {
340   TestApplication application;
341   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
342   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
343   drawTrace.Enable( true );
344
345   float nearPlane, farPlane, cameraDepth;
346   DALI_TEST_CHECK( GetCameraDepths( application, nearPlane, farPlane, cameraDepth ) );
347
348   Actor meshActor = CreateMeshActorToScene( application );
349   Vector3 meshPosition = meshActor.GetCurrentProperty< Vector3 >( Actor::Property::POSITION );
350
351   float offset = meshActor.GetTargetSize().z - 0.1f;
352   meshPosition.z = cameraDepth - nearPlane + offset;
353   meshActor.SetProperty( Actor::Property::POSITION, meshPosition );
354
355   drawTrace.Reset();
356   application.SendNotification();
357   application.Render( 16 );
358
359   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
360
361   END_TEST;
362 }
363
364 int UtcFrustumFarCullP(void)
365 {
366   TestApplication application;
367   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
368   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
369   drawTrace.Enable( true );
370
371   float nearPlane, farPlane, cameraDepth;
372   DALI_TEST_CHECK( GetCameraDepths( application, nearPlane, farPlane, cameraDepth ) );
373
374   Actor meshActor = CreateMeshActorToScene( application );
375   Vector3 meshPosition = meshActor.GetCurrentProperty< Vector3 >( Actor::Property::POSITION );
376
377   float radius = meshActor.GetTargetSize().Length() * 0.5f;
378   float offset = radius + 0.1f;
379   meshPosition.z = cameraDepth - farPlane - offset;
380   meshActor.SetProperty( Actor::Property::POSITION, meshPosition );
381
382   drawTrace.Reset();
383   application.SendNotification();
384   application.Render( 16 );
385
386   // This will be sphere culled
387   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
388
389   END_TEST;
390 }
391
392 int UtcFrustumFarCullN(void)
393 {
394   TestApplication application;
395   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
396   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
397   drawTrace.Enable( true );
398
399   float nearPlane, farPlane, cameraDepth;
400   DALI_TEST_CHECK( GetCameraDepths( application, nearPlane, farPlane, cameraDepth ) );
401
402   Actor meshActor = CreateMeshActorToScene( application );
403   Vector3 meshPosition = meshActor.GetCurrentProperty< Vector3 >( Actor::Property::POSITION );
404
405   float offset = meshActor.GetTargetSize().z - 0.1f;
406   meshPosition.z = cameraDepth - farPlane - offset;
407   meshActor.SetProperty( Actor::Property::POSITION, meshPosition );
408
409   drawTrace.Reset();
410   application.SendNotification();
411   application.Render( 16 );
412
413   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
414
415   END_TEST;
416 }
417
418 int UtcFrustumCullDisabledP(void)
419 {
420   TestApplication application;
421   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
422   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
423   drawTrace.Enable( true );
424
425   CreateMeshActorToScene( application, Vector3( 7.0f, 0.5f, 0.5f ), AnchorPoint::CENTER, Shader::Hint::MODIFIES_GEOMETRY );
426
427   drawTrace.Reset();
428   application.SendNotification();
429   application.Render( 16 );
430
431   // This should not be culled
432   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
433
434   END_TEST;
435 }