Actor rootActor, // Reset default render task to point at this actor
Actor secondRootActor, // Source actor
unsigned int refreshRate,
- bool glSync)
+ bool glSync,
+ uint32_t frameBufferWidth = 10,
+ uint32_t frameBufferHeight = 10)
{
// Change main render task to use a different root
RenderTaskList taskList = application.GetScene().GetRenderTaskList();
taskList.GetTask(0u).SetSourceActor(rootActor);
- FrameBuffer frameBuffer = FrameBuffer::New(10, 10);
+ FrameBuffer frameBuffer = FrameBuffer::New(frameBufferWidth, frameBufferHeight);
if(glSync)
{
- NativeImageInterfacePtr testNativeImagePtr = TestNativeImage::New(10, 10);
+ NativeImageInterfacePtr testNativeImagePtr = TestNativeImage::New(frameBufferWidth, frameBufferHeight);
Texture texture = Texture::New(*testNativeImagePtr);
frameBuffer.AttachColorTexture(texture);
}
}
END_TEST;
}
+
+int UtcDaliRenderTaskClippingMode01(void)
+{
+ TestApplication application;
+
+ tet_infoline("Testing clipping mode: CLIP_TO_BOUNDING_BOX.\n");
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+ TraceCallStack& scissorTrace = glAbstraction.GetScissorTrace();
+
+ enabledDisableTrace.Enable(true);
+ scissorTrace.Enable(true);
+
+ // SETUP AN OFFSCREEN RENDER TASK
+ Actor rootActor = Actor::New();
+ application.GetScene().Add(rootActor);
+
+ CameraActor offscreenCameraActor = CameraActor::New(Size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT));
+ offscreenCameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ offscreenCameraActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ application.GetScene().Add(offscreenCameraActor);
+
+ Shader shader = CreateShader();
+ Texture image = CreateTexture();
+ TextureSet textureSet = CreateTextureSet(image);
+
+ Geometry geometry = CreateQuadGeometry();
+ Renderer renderer = Renderer::New(geometry, shader);
+ renderer.SetTextures(textureSet);
+
+ Vector2 position(100.0f, 100.0f);
+ Vector2 size(200.0f, 200.0f);
+ Actor secondRootActor = Actor::New();
+ secondRootActor.AddRenderer(renderer);
+ secondRootActor.SetProperty(Actor::Property::POSITION, position);
+ secondRootActor.SetProperty(Actor::Property::SIZE, size);
+ secondRootActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ secondRootActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ secondRootActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
+ application.GetScene().Add(secondRootActor);
+
+ RenderTask newTask = CreateRenderTask(application, offscreenCameraActor, rootActor, secondRootActor, RenderTask::REFRESH_ONCE, true, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(enabledDisableTrace.FindMethodAndParams("Enable", "3089")); // 3089 = 0xC11 (GL_SCISSOR_TEST)
+
+ // Check the scissor was set, and the coordinates are correct.
+ Vector4 expectResults(position.x, TestApplication::DEFAULT_SURFACE_HEIGHT - size.height - position.y, size.width, size.height); // (100, 500, 200, 200)
+ std::stringstream compareParametersString;
+ compareParametersString << expectResults.x << ", " << expectResults.y << ", " << expectResults.z << ", " << expectResults.w;
+ DALI_TEST_CHECK(scissorTrace.FindMethodAndParams("Scissor", compareParametersString.str())); // Compare with the expected result
+
+ END_TEST;
+}
+
+int UtcDaliRenderTaskClippingMode02(void)
+{
+ TestApplication application;
+
+ tet_infoline("Testing clipping mode with the inverted camera: CLIP_TO_BOUNDING_BOX.\n");
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+ TraceCallStack& scissorTrace = glAbstraction.GetScissorTrace();
+
+ enabledDisableTrace.Enable(true);
+ scissorTrace.Enable(true);
+
+ // SETUP AN OFFSCREEN RENDER TASK
+ Actor rootActor = Actor::New();
+ application.GetScene().Add(rootActor);
+
+ CameraActor offscreenCameraActor = CameraActor::New(Size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT));
+ offscreenCameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ offscreenCameraActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ offscreenCameraActor.SetInvertYAxis(true);
+ application.GetScene().Add(offscreenCameraActor);
+
+ Shader shader = CreateShader();
+ Texture image = CreateTexture();
+ TextureSet textureSet = CreateTextureSet(image);
+
+ Geometry geometry = CreateQuadGeometry();
+ Renderer renderer = Renderer::New(geometry, shader);
+ renderer.SetTextures(textureSet);
+
+ Vector2 position(100.0f, 100.0f);
+ Vector2 size(200.0f, 200.0f);
+ Actor secondRootActor = Actor::New();
+ secondRootActor.AddRenderer(renderer);
+ secondRootActor.SetProperty(Actor::Property::POSITION, position);
+ secondRootActor.SetProperty(Actor::Property::SIZE, size);
+ secondRootActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ secondRootActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ secondRootActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
+ application.GetScene().Add(secondRootActor);
+
+ RenderTask newTask = CreateRenderTask(application, offscreenCameraActor, rootActor, secondRootActor, RenderTask::REFRESH_ONCE, true, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(enabledDisableTrace.FindMethodAndParams("Enable", "3089")); // 3089 = 0xC11 (GL_SCISSOR_TEST)
+
+ // Check the scissor was set, and the coordinates are correct.
+ Vector4 expectResults(position.x, position.y, size.width, size.height); // (100, 100, 200, 200)
+ std::stringstream compareParametersString;
+ compareParametersString << expectResults.x << ", " << expectResults.y << ", " << expectResults.z << ", " << expectResults.w;
+ DALI_TEST_CHECK(scissorTrace.FindMethodAndParams("Scissor", compareParametersString.str())); // Compare with the expected result
+
+ END_TEST;
+}
} // Unnamed namespace
-
/**
* @brief This method is responsible for making decisions on when to apply and unapply scissor clipping, and what rectangular dimensions should be used.
* A stack of scissor clips at each depth of clipping is maintained, so it can be applied and unapplied.
* As the clips are hierarchical, this RenderItems AABB is clipped against the current "active" scissor bounds via an intersection operation.
* @param[in] item The current RenderItem about to be rendered
* @param[in] context The context
+ * @param[in] instruction The render-instruction to process.
*/
-inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Context& context )
+inline void RenderAlgorithms::SetupScissorClipping(const RenderItem& item, Context& context, const RenderInstruction& instruction)
{
// Get the number of child scissors in the stack (do not include layer or root box).
size_t childStackDepth = mScissorStack.size() - 1u;
if( scissorEnabled )
{
ClippingBox useScissorBox( mScissorStack.back() );
+
+ if(instruction.mFrameBuffer && instruction.GetCamera()->IsYAxisInverted())
+ {
+ useScissorBox.y = (instruction.mFrameBuffer->GetHeight() - useScissorBox.height) - useScissorBox.y;
+ }
context.Scissor( useScissorBox.x, useScissorBox.y, useScissorBox.width, useScissorBox.height );
}
}
}
-inline void RenderAlgorithms::SetupClipping( const RenderItem& item,
- Context& context,
- bool& usedStencilBuffer,
- uint32_t& lastClippingDepth,
- uint32_t& lastClippingId,
- Integration::StencilBufferAvailable stencilBufferAvailable )
+inline void RenderAlgorithms::SetupClipping(const RenderItem& item,
+ Context& context,
+ bool& usedStencilBuffer,
+ uint32_t& lastClippingDepth,
+ uint32_t& lastClippingId,
+ Integration::StencilBufferAvailable stencilBufferAvailable,
+ const RenderInstruction& instruction)
{
RenderMode::Type renderMode = RenderMode::AUTO;
const Renderer *renderer = item.mRenderer;
// As both scissor and stencil clips can be nested, we may be simultaneously traversing up the scissor tree, requiring a scissor to be un-done. Whilst simultaneously adding a new stencil clip.
// We process both based on our current and old clipping depths for each mode.
// Both methods with return rapidly if there is nothing to be done for that type of clipping.
- SetupScissorClipping( item, context );
+ SetupScissorClipping(item, context, instruction);
if( stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE )
{
// Set up clipping based on both the Renderer and Actor APIs.
// The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used.
- SetupClipping( item, context, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable );
+ SetupClipping(item, context, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction);
if( DALI_LIKELY( item.mRenderer ) )
{
* - If the node is a clipping node, apply the nodes clip intersected with the current/parent scissor clip.
* - If we have gone up the scissor hierarchy, and need to un-apply a scissor clip.
* - Disable scissor clipping completely if it is not needed
- * @param[in] item The current RenderItem (about to be rendered)
- * @param[in] context The current Context
+ * @param[in] item The current RenderItem (about to be rendered)
+ * @param[in] context The current Context
+ * @param[in] instruction The render-instruction to process.
*/
- inline void SetupScissorClipping( const Dali::Internal::SceneGraph::RenderItem& item, Context& context );
+ inline void SetupScissorClipping(const Dali::Internal::SceneGraph::RenderItem& item, Context& context, const Dali::Internal::SceneGraph::RenderInstruction& instruction);
/**
* @brief Set up the clipping based on the specified clipping settings.
* @param[in/out] lastClippingDepth The stencil depth of the last renderer drawn. Used by the clipping feature.
* @param[in/out] lastClippingId The clipping ID of the last renderer drawn. Used by the clipping feature.
* @param[in] stencilBufferAvailable Whether the stencil buffer is available
+ * @param[in] instruction The render-instruction to process.
*/
- inline void SetupClipping( const Dali::Internal::SceneGraph::RenderItem& item,
- Context& context,
- bool& usedStencilBuffer,
- uint32_t& lastClippingDepth,
- uint32_t& lastClippingId,
- Integration::StencilBufferAvailable stencilBufferAvailable );
+ inline void SetupClipping(const Dali::Internal::SceneGraph::RenderItem& item,
+ Context& context,
+ bool& usedStencilBuffer,
+ uint32_t& lastClippingDepth,
+ uint32_t& lastClippingId,
+ Integration::StencilBufferAvailable stencilBufferAvailable,
+ const Dali::Internal::SceneGraph::RenderInstruction& instruction);
/**
* @brief Process a render-list.