Dali 3D User Interface Engine
utc-Dali-Internal-FrustumCulling.cpp
Go to the documentation of this file.
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>
22 #include <dali-test-suite-utils.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 
52 uniform Sampler2D sTexture;
53 varying mediump vec2 vTexCoord;
54 void main()
55 {
56  gl_FragColor = texture2D( sTexture, vTexCoord );
57 }
58 );
59 
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 
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 {
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
499 {
500  TestApplication application;
501  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
502  TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
503  drawTrace.Enable( true );
504 
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 }
Dali Docs Home
Read more about Dali