(AutomatedTests) Ensure warnings are shown as errors
[platform/core/uifw/dali-core.git] / automated-tests / src / dali-internal / utc-Dali-Internal-FrustumCulling.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 #include <iostream>
19 #include <algorithm>
20 #include <stdlib.h>
21 #include <dali/public-api/dali-core.h>
22 #include <dali-test-suite-utils.h>
23 #include <dali/devel-api/object/property-buffer.h>
24 #include <dali/devel-api/rendering/geometry.h>
25 #include <dali/devel-api/rendering/material.h>
26 #include <dali/devel-api/rendering/renderer.h>
27 #include <dali/devel-api/rendering/sampler.h>
28 #include <dali/devel-api/rendering/shader.h>
29
30 using namespace Dali;
31
32 #define MAKE_SHADER(A)#A
33
34 const char* VERTEX_SHADER = MAKE_SHADER(
35 attribute mediump vec2    aPosition;
36 attribute mediump vec2    aTexCoord;
37 uniform   mediump mat4    uMvpMatrix;
38 uniform   mediump vec3    uSize;
39 varying   mediump vec2    vTexCoord;
40
41 void main()
42 {
43   mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);
44   vertexPosition.xyz *= uSize;
45   vertexPosition = uMvpMatrix * vertexPosition;
46   vTexCoord = aTexCoord;
47   gl_Position = vertexPosition;
48 }
49 );
50
51 const char* FRAGMENT_SHADER = MAKE_SHADER(
52 uniform Sampler2D sTexture;
53 varying mediump vec2 vTexCoord;
54 void main()
55 {
56   gl_FragColor = texture2D( sTexture, vTexCoord );
57 }
58 );
59
60 Geometry CreateGeometry()
61 {
62   const float halfQuadSize = .5f;
63   struct TexturedQuadVertex { Vector2 position; Vector2 textureCoordinates; };
64   TexturedQuadVertex texturedQuadVertexData[4] = {
65     { Vector2(-halfQuadSize, -halfQuadSize), Vector2(0.f, 0.f) },
66     { Vector2( halfQuadSize, -halfQuadSize), Vector2(1.f, 0.f) },
67     { Vector2(-halfQuadSize,  halfQuadSize), Vector2(0.f, 1.f) },
68     { Vector2( halfQuadSize,  halfQuadSize), Vector2(1.f, 1.f) } };
69
70   Property::Map texturedQuadVertexFormat;
71   texturedQuadVertexFormat["aPosition"] = Property::VECTOR2;
72   texturedQuadVertexFormat["aTexCoord"] = Property::VECTOR2;
73   PropertyBuffer texturedQuadVertices = PropertyBuffer::New( texturedQuadVertexFormat, 4 );
74   texturedQuadVertices.SetData(texturedQuadVertexData);
75
76   // Create indices
77   unsigned int indexData[6] = { 0, 3, 1, 0, 2, 3 };
78   Property::Map indexFormat;
79   indexFormat["indices"] = Property::INTEGER;
80   PropertyBuffer indices = PropertyBuffer::New( indexFormat, sizeof(indexData)/sizeof(indexData[0]) );
81   indices.SetData(indexData);
82
83   // Create the geometry object
84   Geometry texturedQuadGeometry = Geometry::New();
85   texturedQuadGeometry.AddVertexBuffer( texturedQuadVertices );
86   texturedQuadGeometry.SetIndexBuffer( indices );
87
88   return texturedQuadGeometry;
89 }
90
91 Actor CreateMeshActorToStage( TestApplication& application, Vector3 parentOrigin = ParentOrigin::CENTER, Vector3 anchorPoint = AnchorPoint::CENTER, Shader::ShaderHints shaderHints = Shader::HINT_NONE )
92 {
93   PixelBuffer* pixelBuffer = new PixelBuffer[ 4 ];
94   BufferImage image = BufferImage::New( pixelBuffer, 1, 1 );
95
96   Geometry geometry = CreateGeometry();
97   Material material = Material::New( Shader::New( VERTEX_SHADER, FRAGMENT_SHADER, shaderHints ) );
98   material.AddTexture( image, "sTexture" );
99   Renderer renderer = Renderer::New( geometry, material );
100
101   Actor meshActor = Actor::New();
102   meshActor.AddRenderer( renderer );
103   meshActor.SetSize( Vector3( 400.0f, 400.0f, 0.1f ) );
104   meshActor.SetParentOrigin( parentOrigin );
105   meshActor.SetAnchorPoint( anchorPoint );
106   Stage::GetCurrent().Add( meshActor );
107
108   application.SendNotification();
109   application.Render( 16 );
110
111   return meshActor;
112 }
113
114 bool GetCameraDepths( TestApplication& application, float& nearPlane, float& farPlane, float& cameraDepth )
115 {
116   RenderTaskList renderTasks = Stage::GetCurrent().GetRenderTaskList();
117   CameraActor cameraActor;
118   for( unsigned int i = 0; i < renderTasks.GetTaskCount(); ++i )
119   {
120     RenderTask task = renderTasks.GetTask( i );
121     cameraActor = task.GetCameraActor();
122     if( cameraActor )
123     {
124       break;
125     }
126   }
127   if( cameraActor )
128   {
129     application.SendNotification();
130     application.Render( 16 );
131
132     nearPlane = cameraActor.GetNearClippingPlane();
133     farPlane = cameraActor.GetFarClippingPlane();
134     cameraDepth = cameraActor.GetCurrentPosition().z;
135   }
136
137   return !!cameraActor;
138 }
139
140 int UtcFrustumCullN(void)
141 {
142   TestApplication application;
143   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
144   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
145   drawTrace.Enable( true );
146
147   CreateMeshActorToStage( application );
148
149   drawTrace.Reset();
150   application.SendNotification();
151   application.Render( 16 );
152
153   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
154
155   END_TEST;
156 }
157
158 int UtcFrustumLeftCullP(void)
159 {
160   TestApplication application;
161   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
162   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
163   drawTrace.Enable( true );
164
165   float offset = -0.01f;
166   Actor meshActor = CreateMeshActorToStage( application, Vector3( offset, 0.5f, 0.5f ), AnchorPoint::CENTER_RIGHT );
167
168   drawTrace.Reset();
169   application.SendNotification();
170   application.Render( 16 );
171
172   // This will be box culled
173   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
174
175   float radius = meshActor.GetTargetSize().Length() * 0.5f;
176   Vector2 stageSize = Stage::GetCurrent().GetSize();
177
178   meshActor.SetParentOrigin( Vector3( -radius / stageSize.width + offset, 0.5f, 0.5f ) );
179   meshActor.SetAnchorPoint( AnchorPoint::CENTER );
180
181   drawTrace.Reset();
182   application.SendNotification();
183   application.Render( 16 );
184
185   // This will be sphere culled
186   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
187
188   END_TEST;
189 }
190
191 int UtcFrustumLeftCullN(void)
192 {
193   TestApplication application;
194   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
195   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
196   drawTrace.Enable( true );
197
198   float offset = 0.01f;
199   Actor meshActor = CreateMeshActorToStage( application, Vector3( offset, 0.5f, 0.5f ), AnchorPoint::CENTER_RIGHT );
200
201   drawTrace.Reset();
202   application.SendNotification();
203   application.Render( 16 );
204
205   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
206
207   END_TEST;
208 }
209
210 int UtcFrustumRightCullP(void)
211 {
212   TestApplication application;
213   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
214   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
215   drawTrace.Enable( true );
216
217   float offset = 1.01f;
218   Actor meshActor = CreateMeshActorToStage( application, Vector3( offset, 0.5f, 0.5f ), AnchorPoint::CENTER_LEFT );
219
220   drawTrace.Reset();
221   application.SendNotification();
222   application.Render( 16 );
223
224   // This will be box culled
225   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
226
227   float radius = meshActor.GetTargetSize().Length() * 0.5f;
228   Vector2 stageSize = Stage::GetCurrent().GetSize();
229
230   meshActor.SetParentOrigin( Vector3( radius / stageSize.width + offset, 0.5f, 0.5f ) );
231   meshActor.SetAnchorPoint( AnchorPoint::CENTER );
232
233   drawTrace.Reset();
234   application.SendNotification();
235   application.Render( 16 );
236
237   // This will be sphere culled
238   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
239
240   END_TEST;
241 }
242
243 int UtcFrustumRightCullN(void)
244 {
245   TestApplication application;
246   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
247   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
248   drawTrace.Enable( true );
249
250   float offset = 0.99f;
251   Actor meshActor = CreateMeshActorToStage( application, Vector3( offset, 0.5f, 0.5f ), AnchorPoint::CENTER_LEFT );
252
253   drawTrace.Reset();
254   application.SendNotification();
255   application.Render( 16 );
256
257   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
258
259   END_TEST;
260 }
261
262 int UtcFrustumTopCullP(void)
263 {
264   TestApplication application;
265   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
266   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
267   drawTrace.Enable( true );
268
269   float offset = -0.01f;
270   Actor meshActor = CreateMeshActorToStage( application, Vector3( 0.5f, offset, 0.5f ), AnchorPoint::BOTTOM_CENTER );
271
272   drawTrace.Reset();
273   application.SendNotification();
274   application.Render( 16 );
275
276   // This will be box culled
277   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
278
279   float radius = meshActor.GetTargetSize().Length() * 0.5f;
280   Vector2 stageSize = Stage::GetCurrent().GetSize();
281
282   meshActor.SetParentOrigin( Vector3( 0.5f, -radius / stageSize.width + offset, 0.5f ) );
283   meshActor.SetAnchorPoint( AnchorPoint::CENTER );
284
285   drawTrace.Reset();
286   application.SendNotification();
287   application.Render( 16 );
288
289   // This will be sphere culled
290   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
291
292   END_TEST;
293 }
294
295 int UtcFrustumTopCullN(void)
296 {
297   TestApplication application;
298   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
299   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
300   drawTrace.Enable( true );
301
302   float offset = 0.01f;
303   Actor meshActor = CreateMeshActorToStage( application, Vector3( 0.5f, offset, 0.5f ), AnchorPoint::BOTTOM_CENTER );
304
305   drawTrace.Reset();
306   application.SendNotification();
307   application.Render( 16 );
308
309   // This will be box culled
310   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
311
312   END_TEST;
313 }
314
315 int UtcFrustumBottomCullP(void)
316 {
317   TestApplication application;
318   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
319   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
320   drawTrace.Enable( true );
321
322   float offset = 1.01f;
323   Actor meshActor = CreateMeshActorToStage( application, Vector3( 0.5f, offset, 0.5f ), AnchorPoint::TOP_CENTER );
324
325   drawTrace.Reset();
326   application.SendNotification();
327   application.Render( 16 );
328
329   // This will be box culled
330   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
331
332   float radius = meshActor.GetTargetSize().Length() * 0.5f;
333   Vector2 stageSize = Stage::GetCurrent().GetSize();
334
335   meshActor.SetParentOrigin( Vector3( 0.5f, radius / stageSize.width + offset, 0.5f ) );
336   meshActor.SetAnchorPoint( AnchorPoint::CENTER );
337
338   drawTrace.Reset();
339   application.SendNotification();
340   application.Render( 16 );
341
342   // This will be sphere culled
343   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
344
345   END_TEST;
346 }
347
348 int UtcFrustumBottomCullN(void)
349 {
350   TestApplication application;
351   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
352   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
353   drawTrace.Enable( true );
354
355   float offset = 0.99f;
356   Actor meshActor = CreateMeshActorToStage( application, Vector3( 0.5f, offset, 0.5f ), AnchorPoint::TOP_CENTER );
357
358   drawTrace.Reset();
359   application.SendNotification();
360   application.Render( 16 );
361
362   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
363
364   END_TEST;
365 }
366
367 int UtcFrustumNearCullP(void)
368 {
369   TestApplication application;
370   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
371   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
372   drawTrace.Enable( true );
373
374   float nearPlane, farPlane, cameraDepth;
375   DALI_TEST_CHECK( GetCameraDepths( application, nearPlane, farPlane, cameraDepth ) );
376
377   Actor meshActor = CreateMeshActorToStage( application );
378   Vector3 meshPosition = meshActor.GetCurrentPosition();
379
380   float radius = meshActor.GetTargetSize().Length() * 0.5f;
381   float offset = ( meshActor.GetTargetSize().z + radius ) * 0.5f; //midpoint between AABB and sphere
382   meshPosition.z = cameraDepth - nearPlane +  offset;
383   meshActor.SetPosition( meshPosition );
384
385   drawTrace.Reset();
386   application.SendNotification();
387   application.Render( 16 );
388
389   // This will be box culled
390   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
391
392   offset = radius + 0.1f;
393   meshPosition.z = cameraDepth - nearPlane + offset;
394   meshActor.SetPosition( meshPosition );
395
396   drawTrace.Reset();
397   application.SendNotification();
398   application.Render( 16 );
399
400   // This will be sphere culled
401   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
402
403   END_TEST;
404 }
405
406 int UtcFrustumNearCullN(void)
407 {
408   TestApplication application;
409   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
410   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
411   drawTrace.Enable( true );
412
413   float nearPlane, farPlane, cameraDepth;
414   DALI_TEST_CHECK( GetCameraDepths( application, nearPlane, farPlane, cameraDepth ) );
415
416   Actor meshActor = CreateMeshActorToStage( application );
417   Vector3 meshPosition = meshActor.GetCurrentPosition();
418
419   float offset = meshActor.GetTargetSize().z - 0.1f;
420   meshPosition.z = cameraDepth - nearPlane + offset;
421   meshActor.SetPosition( meshPosition );
422
423   drawTrace.Reset();
424   application.SendNotification();
425   application.Render( 16 );
426
427   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
428
429   END_TEST;
430 }
431
432 int UtcFrustumFarCullP(void)
433 {
434   TestApplication application;
435   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
436   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
437   drawTrace.Enable( true );
438
439   float nearPlane, farPlane, cameraDepth;
440   DALI_TEST_CHECK( GetCameraDepths( application, nearPlane, farPlane, cameraDepth ) );
441
442   Actor meshActor = CreateMeshActorToStage( application );
443   Vector3 meshPosition = meshActor.GetCurrentPosition();
444
445   float radius = meshActor.GetTargetSize().Length() * 0.5f;
446   float offset = ( meshActor.GetTargetSize().z + radius ) * 0.5f; //midpoint between AABB and sphere
447
448   meshPosition.z = cameraDepth - farPlane - offset;
449   meshActor.SetPosition( meshPosition );
450
451   drawTrace.Reset();
452   application.SendNotification();
453   application.Render( 16 );
454
455   // This will be box culled
456   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
457
458   offset = radius + 0.1f;
459   meshPosition.z = cameraDepth - farPlane - offset;
460   meshActor.SetPosition( meshPosition );
461
462   drawTrace.Reset();
463   application.SendNotification();
464   application.Render( 16 );
465
466   // This will be sphere culled
467   DALI_TEST_CHECK( !drawTrace.FindMethod( "DrawElements" ) );
468
469   END_TEST;
470 }
471
472 int UtcFrustumFarCullN(void)
473 {
474   TestApplication application;
475   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
476   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
477   drawTrace.Enable( true );
478
479   float nearPlane, farPlane, cameraDepth;
480   DALI_TEST_CHECK( GetCameraDepths( application, nearPlane, farPlane, cameraDepth ) );
481
482   Actor meshActor = CreateMeshActorToStage( application );
483   Vector3 meshPosition = meshActor.GetCurrentPosition();
484
485   float offset = meshActor.GetTargetSize().z - 0.1f;
486   meshPosition.z = cameraDepth - farPlane - offset;
487   meshActor.SetPosition( meshPosition );
488
489   drawTrace.Reset();
490   application.SendNotification();
491   application.Render( 16 );
492
493   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
494
495   END_TEST;
496 }
497
498 int UtcFrustumCullDisabledP(void)
499 {
500   TestApplication application;
501   TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
502   TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
503   drawTrace.Enable( true );
504
505   CreateMeshActorToStage( application, Vector3( 7.0f, 0.5f, 0.5f ), AnchorPoint::CENTER, Shader::HINT_MODIFIES_GEOMETRY );
506
507   drawTrace.Reset();
508   application.SendNotification();
509   application.Render( 16 );
510
511   // This should not be culled
512   DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) );
513
514   END_TEST;
515 }