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