X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fbloom-view%2Fbloom-view-impl.cpp;h=c5dfaf80956fbfa6c6225151eaf360ed72cdf604;hb=70fdb1a1e8e2660c383079ae49bc94fbe14943d1;hp=ac562247617172404dc99ecfa045f8cedda72f13;hpb=030e7c680a6eb0e8d87bfdb8ec359a0267ef7db2;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp index ac56224..5ed17c8 100644 --- a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp +++ b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,32 +19,33 @@ #include "bloom-view-impl.h" // EXTERNAL INCLUDES -#include -#include +#include #include #include -#include -#include +#include #include +#include #include +#include +#include +#include // INTERNAL INCLUDES -#include -#include -#include "../gaussian-blur-view/gaussian-blur-view-impl.h" +#include +#include +#include +#include +#include +#include namespace Dali { - namespace Toolkit { - namespace Internal { - namespace { - using namespace Dali; BaseHandle Create() @@ -52,119 +53,80 @@ BaseHandle Create() return Toolkit::BloomView::New(); } -DALI_TYPE_REGISTRATION_BEGIN( Toolkit::BloomView, Toolkit::Control, Create ) +DALI_TYPE_REGISTRATION_BEGIN(Toolkit::BloomView, Toolkit::Control, Create) DALI_TYPE_REGISTRATION_END() // default parameters -const float BLOOM_THRESHOLD_DEFAULT = 0.25f; +const float BLOOM_THRESHOLD_DEFAULT = 0.25f; const float BLOOM_BLUR_STRENGTH_DEFAULT = 1.0f; -const float BLOOM_INTENSITY_DEFAULT = 1.0f; -const float IMAGE_INTENSITY_DEFAULT = 1.0f; -const float BLOOM_SATURATION_DEFAULT = 1.0f; -const float IMAGE_SATURATION_DEFAULT = 1.0f; +const float BLOOM_INTENSITY_DEFAULT = 1.0f; +const float IMAGE_INTENSITY_DEFAULT = 1.0f; +const float BLOOM_SATURATION_DEFAULT = 1.0f; +const float IMAGE_SATURATION_DEFAULT = 1.0f; // gaussian blur -const unsigned int BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_NUM_SAMPLES = 5; -const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_BELL_CURVE_WIDTH = 1.5f; +const unsigned int BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_NUM_SAMPLES = 5; +const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_BELL_CURVE_WIDTH = 1.5f; const Pixel::Format BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_RENDER_TARGET_PIXEL_FORMAT = Pixel::RGBA8888; -const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_FADE_IN = 1.0f; // default, fully blurred -const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_WIDTH_SCALE = 0.5f; -const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_HEIGHT_SCALE = 0.5f; +const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_FADE_IN = 1.0f; // default, fully blurred +const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_WIDTH_SCALE = 0.5f; +const float BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_HEIGHT_SCALE = 0.5f; const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f; -const char* const BLOOM_BLUR_STRENGTH_PROPERTY_NAME = "BlurStrengthProperty"; -const char* const BLOOM_THRESHOLD_PROPERTY_NAME = "uBloomThreshold"; +const char* const BLOOM_BLUR_STRENGTH_PROPERTY_NAME = "BlurStrengthProperty"; +const char* const BLOOM_THRESHOLD_PROPERTY_NAME = "uBloomThreshold"; const char* const RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME = "uRecipOneMinusBloomThreshold"; -const char* const BLOOM_INTENSITY_PROPERTY_NAME = "uBloomIntensity"; -const char* const BLOOM_SATURATION_PROPERTY_NAME = "uBloomSaturation"; -const char* const IMAGE_INTENSITY_PROPERTY_NAME = "uImageIntensity"; -const char* const IMAGE_SATURATION_PROPERTY_NAME = "uImageSaturation"; - -/////////////////////////////////////////////////////// -// -// Bloom shaders -// - -const char* const BLOOM_EXTRACT_FRAGMENT_SOURCE = - "uniform float uBloomThreshold;\n" - "uniform float uRecipOneMinusBloomThreshold;\n" - "void main()\n" - "{\n" - " mediump vec4 col;\n" - " col = texture2D(sTexture, vec2(vTexCoord.x, vTexCoord.y));\n" - " col = (col - uBloomThreshold) * uRecipOneMinusBloomThreshold;\n" // remove intensities lower than the thresold and remap intensities above the threshold to [0..1] - " gl_FragColor = clamp(col, 0.0, 1.0);\n" - "}\n"; - -const char* const COMPOSITE_FRAGMENT_SOURCE = - "uniform float uBloomIntensity;\n" - "uniform float uImageIntensity;\n" - "uniform float uBloomSaturation;\n" - "uniform float uImageSaturation;\n" - - "vec4 ChangeSaturation(vec4 col, float sat)\n" - "{\n" - " float grey = dot(col.rgb, vec3(0.3, 0.6, 0.1));\n" - " return mix(vec4(grey, grey, grey, 1.0), col, sat);\n" - "}\n" - - "void main()\n" - "{\n" - " mediump vec4 image;\n" - " mediump vec4 bloom;\n" - " image = texture2D(sTexture, vec2(vTexCoord.x, vTexCoord.y));\n" - " bloom = texture2D(sEffect, vec2(vTexCoord.x, vTexCoord.y));\n" - " image = ChangeSaturation(image, uImageSaturation) * uImageIntensity;\n" - " bloom = ChangeSaturation(bloom, uBloomSaturation) * uBloomIntensity;\n" - " image *= 1.0 - clamp(bloom, 0.0, 1.0);\n" // darken base where bloom is strong, to prevent excessive burn-out of result - " gl_FragColor = image + bloom;\n" - "}\n"; +const char* const BLOOM_INTENSITY_PROPERTY_NAME = "uBloomIntensity"; +const char* const BLOOM_SATURATION_PROPERTY_NAME = "uBloomSaturation"; +const char* const IMAGE_INTENSITY_PROPERTY_NAME = "uImageIntensity"; +const char* const IMAGE_SATURATION_PROPERTY_NAME = "uImageSaturation"; } // namespace - - BloomView::BloomView() - : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ) - , mBlurNumSamples(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_NUM_SAMPLES) - , mBlurBellCurveWidth(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_BELL_CURVE_WIDTH) - , mPixelFormat(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_RENDER_TARGET_PIXEL_FORMAT) - , mDownsampleWidthScale(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_WIDTH_SCALE) - , mDownsampleHeightScale(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_HEIGHT_SCALE) - , mDownsampledWidth( 0.0f ) - , mDownsampledHeight( 0.0f ) - , mTargetSize(Vector2::ZERO) - , mLastSize(Vector2::ZERO) - , mChildrenRoot(Actor::New()) - , mBloomThresholdPropertyIndex(Property::INVALID_INDEX) - , mBlurStrengthPropertyIndex(Property::INVALID_INDEX) - , mBloomIntensityPropertyIndex(Property::INVALID_INDEX) - , mBloomSaturationPropertyIndex(Property::INVALID_INDEX) - , mImageIntensityPropertyIndex(Property::INVALID_INDEX) - , mImageSaturationPropertyIndex(Property::INVALID_INDEX) +: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)), + mBlurNumSamples(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_NUM_SAMPLES), + mBlurBellCurveWidth(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_BLUR_BELL_CURVE_WIDTH), + mPixelFormat(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_RENDER_TARGET_PIXEL_FORMAT), + mDownsampleWidthScale(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_WIDTH_SCALE), + mDownsampleHeightScale(BLOOM_GAUSSIAN_BLUR_VIEW_DEFAULT_DOWNSAMPLE_HEIGHT_SCALE), + mDownsampledWidth(0.0f), + mDownsampledHeight(0.0f), + mTargetSize(Vector2::ZERO), + mLastSize(Vector2::ZERO), + mChildrenRoot(Actor::New()), + mInternalRoot(Actor::New()), + mBloomThresholdPropertyIndex(Property::INVALID_INDEX), + mBlurStrengthPropertyIndex(Property::INVALID_INDEX), + mBloomIntensityPropertyIndex(Property::INVALID_INDEX), + mBloomSaturationPropertyIndex(Property::INVALID_INDEX), + mImageIntensityPropertyIndex(Property::INVALID_INDEX), + mImageSaturationPropertyIndex(Property::INVALID_INDEX), + mActivated(false) { } -BloomView::BloomView( const unsigned int blurNumSamples, const float blurBellCurveWidth, const Pixel::Format renderTargetPixelFormat, - const float downsampleWidthScale, const float downsampleHeightScale) - : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ) - , mBlurNumSamples(blurNumSamples) - , mBlurBellCurveWidth(blurBellCurveWidth) - , mPixelFormat(renderTargetPixelFormat) - , mDownsampleWidthScale(downsampleWidthScale) - , mDownsampleHeightScale(downsampleHeightScale) - , mDownsampledWidth( 0.0f ) - , mDownsampledHeight( 0.0f ) - , mTargetSize(Vector2::ZERO) - , mLastSize(Vector2::ZERO) - , mChildrenRoot(Actor::New()) - , mBloomThresholdPropertyIndex(Property::INVALID_INDEX) - , mBlurStrengthPropertyIndex(Property::INVALID_INDEX) - , mBloomIntensityPropertyIndex(Property::INVALID_INDEX) - , mBloomSaturationPropertyIndex(Property::INVALID_INDEX) - , mImageIntensityPropertyIndex(Property::INVALID_INDEX) - , mImageSaturationPropertyIndex(Property::INVALID_INDEX) +BloomView::BloomView(const unsigned int blurNumSamples, const float blurBellCurveWidth, const Pixel::Format renderTargetPixelFormat, const float downsampleWidthScale, const float downsampleHeightScale) +: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)), + mBlurNumSamples(blurNumSamples), + mBlurBellCurveWidth(blurBellCurveWidth), + mPixelFormat(renderTargetPixelFormat), + mDownsampleWidthScale(downsampleWidthScale), + mDownsampleHeightScale(downsampleHeightScale), + mDownsampledWidth(0.0f), + mDownsampledHeight(0.0f), + mTargetSize(Vector2::ZERO), + mLastSize(Vector2::ZERO), + mChildrenRoot(Actor::New()), + mInternalRoot(Actor::New()), + mBloomThresholdPropertyIndex(Property::INVALID_INDEX), + mBlurStrengthPropertyIndex(Property::INVALID_INDEX), + mBloomIntensityPropertyIndex(Property::INVALID_INDEX), + mBloomSaturationPropertyIndex(Property::INVALID_INDEX), + mImageIntensityPropertyIndex(Property::INVALID_INDEX), + mImageSaturationPropertyIndex(Property::INVALID_INDEX), + mActivated(false) { } @@ -176,7 +138,7 @@ Toolkit::BloomView BloomView::New() { BloomView* impl = new BloomView(); - Dali::Toolkit::BloomView handle = Dali::Toolkit::BloomView( *impl ); + Dali::Toolkit::BloomView handle = Dali::Toolkit::BloomView(*impl); // Second-phase init of the implementation // This can only be done after the CustomActor connection has been made... @@ -185,12 +147,11 @@ Toolkit::BloomView BloomView::New() return handle; } -Toolkit::BloomView BloomView::New(const unsigned int blurNumSamples, const float blurBellCurveWidth, const Pixel::Format renderTargetPixelFormat, - const float downsampleWidthScale, const float downsampleHeightScale) +Toolkit::BloomView BloomView::New(const unsigned int blurNumSamples, const float blurBellCurveWidth, const Pixel::Format renderTargetPixelFormat, const float downsampleWidthScale, const float downsampleHeightScale) { - BloomView* impl = new BloomView( blurNumSamples, blurBellCurveWidth, renderTargetPixelFormat, downsampleWidthScale, downsampleHeightScale); + BloomView* impl = new BloomView(blurNumSamples, blurBellCurveWidth, renderTargetPixelFormat, downsampleWidthScale, downsampleHeightScale); - Dali::Toolkit::BloomView handle = Dali::Toolkit::BloomView( *impl ); + Dali::Toolkit::BloomView handle = Dali::Toolkit::BloomView(*impl); // Second-phase init of the implementation // This can only be done after the CustomActor connection has been made... @@ -199,24 +160,6 @@ Toolkit::BloomView BloomView::New(const unsigned int blurNumSamples, const float return handle; } -///////////////////////////////////////////////////////////// -// for creating a subtree for all user added child actors, so that we can have them exclusive to the mRenderChildrenTask and our other actors exclusive to our other tasks -// TODO: overloading Actor::Add()/Remove() not nice since breaks polymorphism. Need another method to pass ownership of added child actors to our internal actor root. -void BloomView::Add(Actor child) -{ - mChildrenRoot.Add(child); -} - -void BloomView::Remove(Actor child) -{ - mChildrenRoot.Remove(child); -} - - - - - - /////////////////////////////////////////////////////////// // // Private methods @@ -225,76 +168,67 @@ void BloomView::Remove(Actor child) void BloomView::OnInitialize() { // root actor to parent all user added actors, needed to allow us to set that subtree as exclusive for our child render task - mChildrenRoot.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); - - ////////////////////////////////////////////////////// - // Create shaders - - // Create shader used for extracting the bright parts of an image - mBloomExtractShader = ShaderEffect::New( "", BLOOM_EXTRACT_FRAGMENT_SOURCE ); - - // Create shader used to composite bloom and original image to output render target - mCompositeShader = ShaderEffect::New( "", COMPOSITE_FRAGMENT_SOURCE ); - + mChildrenRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + mInternalRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); ////////////////////////////////////////////////////// // Create actors - // Create an ImageActor for rendering from the scene texture to the bloom texture - mBloomExtractImageActor = ImageActor::New(); - mBloomExtractImageActor.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); - mBloomExtractImageActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME - mBloomExtractImageActor.SetShaderEffect( mBloomExtractShader ); - - // Create an ImageActor for compositing the result (scene and bloom textures) to output - mCompositeImageActor = ImageActor::New(); - mCompositeImageActor.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); - mCompositeImageActor.SetShaderEffect( mCompositeShader ); - mCompositeImageActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME + // Create an image view for rendering from the scene texture to the bloom texture + mBloomExtractActor = Actor::New(); + mBloomExtractActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - // Create an ImageActor for holding final result, i.e. the blurred image. This will get rendered to screen later, via default / user render task - mTargetImageActor = ImageActor::New(); - mTargetImageActor.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); - mTargetImageActor.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) ); // FIXME + // Create an image view for compositing the result (scene and bloom textures) to output + mCompositeActor = Actor::New(); + mCompositeActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + // Create an image view for holding final result, i.e. the blurred image. This will get rendered to screen later, via default / user render task + mTargetActor = Actor::New(); + mTargetActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); // Create the Gaussian Blur object + render tasks // Note that we use mBloomExtractTarget as the source image and also re-use this as the gaussian blur final render target. This saves the gaussian blur code from creating it // render targets etc internally, so we make better use of resources // Note, this also internally creates the render tasks used by the Gaussian blur, this must occur after the bloom extraction and before the compositing mGaussianBlurView = Dali::Toolkit::GaussianBlurView::New(mBlurNumSamples, mBlurBellCurveWidth, mPixelFormat, mDownsampleWidthScale, mDownsampleHeightScale, true); - mGaussianBlurView.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); - + mGaussianBlurView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); ////////////////////////////////////////////////////// // Create cameras for the renders corresponding to the (potentially downsampled) render targets' size mRenderDownsampledCamera = CameraActor::New(); - mRenderDownsampledCamera.SetParentOrigin(ParentOrigin::CENTER); + mRenderDownsampledCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + mRenderDownsampledCamera.SetInvertYAxis(true); mRenderFullSizeCamera = CameraActor::New(); - mRenderFullSizeCamera.SetParentOrigin(ParentOrigin::CENTER); - + mRenderFullSizeCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + mRenderFullSizeCamera.SetInvertYAxis(true); //////////////////////////////// // Connect to actor tree - Self().Add( mChildrenRoot ); - Self().Add( mBloomExtractImageActor ); - Self().Add( mGaussianBlurView ); - Self().Add( mCompositeImageActor ); - Self().Add( mTargetImageActor ); - Self().Add( mRenderDownsampledCamera ); - Self().Add( mRenderFullSizeCamera ); + Self().Add(mChildrenRoot); + Self().Add(mInternalRoot); + mInternalRoot.Add(mBloomExtractActor); + mInternalRoot.Add(mGaussianBlurView); + mInternalRoot.Add(mCompositeActor); + mInternalRoot.Add(mTargetActor); + mInternalRoot.Add(mRenderDownsampledCamera); + mInternalRoot.Add(mRenderFullSizeCamera); // bind properties for / set shader constants to defaults SetupProperties(); + + DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) { + return std::unique_ptr( + new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::ANIMATION)); + }); } -void BloomView::OnControlSizeSet(const Vector3& targetSize) +void BloomView::OnSizeSet(const Vector3& targetSize) { mTargetSize = Vector2(targetSize); - mChildrenRoot.SetSize(targetSize); - mCompositeImageActor.SetSize(targetSize); - mTargetImageActor.SetSize(targetSize); + mChildrenRoot.SetProperty(Actor::Property::SIZE, targetSize); + mCompositeActor.SetProperty(Actor::Property::SIZE, targetSize); + mTargetActor.SetProperty(Actor::Property::SIZE, targetSize); // Children render camera must move when GaussianBlurView object is // resized. This is since we cannot change render target size - so we need @@ -304,79 +238,116 @@ void BloomView::OnControlSizeSet(const Vector3& targetSize) // this is the trade off for not being able to modify render target size // Change camera z position based on GaussianBlurView actor height float cameraPosConstraintScale = 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f); - mRenderFullSizeCamera.SetZ( mTargetSize.height * cameraPosConstraintScale); + mRenderFullSizeCamera.SetProperty(Actor::Property::POSITION_Z, mTargetSize.height * cameraPosConstraintScale); + + // if we have already activated the blur, need to update render target sizes now to reflect the new size of this actor + if(mActivated) + { + Deactivate(); + Activate(); + } - // if we are already on stage, need to update render target sizes now to reflect the new size of this actor - if(Self().OnStage()) + Control::OnSizeSet(targetSize); +} + +void BloomView::OnChildAdd(Actor& child) +{ + if(child != mChildrenRoot && child != mInternalRoot) { - AllocateResources(); + mChildrenRoot.Add(child); } + + Control::OnChildAdd(child); +} + +void BloomView::OnChildRemove(Actor& child) +{ + mChildrenRoot.Remove(child); + + Control::OnChildRemove(child); } void BloomView::AllocateResources() { // size of render targets etc is based on the size of this actor, ignoring z - if(mTargetSize != mLastSize) + if(mTargetSize != mLastSize || !mActivated) { mLastSize = mTargetSize; // get size of downsampled render targets - mDownsampledWidth = mTargetSize.width * mDownsampleWidthScale; + mDownsampledWidth = mTargetSize.width * mDownsampleWidthScale; mDownsampledHeight = mTargetSize.height * mDownsampleHeightScale; - ////////////////////////////////////////////////////// // Create cameras // Create and place a camera for the renders corresponding to the (potentially downsampled) render targets' size mRenderDownsampledCamera.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW); - // TODO: how do we pick a reasonable value for near clip? Needs to relate to normal camera the user renders with, but we don't have a handle on it mRenderDownsampledCamera.SetNearClippingPlane(1.0f); mRenderDownsampledCamera.SetAspectRatio(mDownsampledWidth / mDownsampledHeight); mRenderDownsampledCamera.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor - mRenderDownsampledCamera.SetPosition(0.0f, 0.0f, ((mDownsampledHeight * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f))); + mRenderDownsampledCamera.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, ((mDownsampledHeight * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)))); // Create and place a camera for the children render, corresponding to its render target size mRenderFullSizeCamera.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW); - // TODO: how do we pick a reasonable value for near clip? Needs to relate to normal camera the user renders with, but we don't have a handle on it mRenderFullSizeCamera.SetNearClippingPlane(1.0f); mRenderFullSizeCamera.SetAspectRatio(mTargetSize.width / mTargetSize.height); mRenderFullSizeCamera.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor float cameraPosConstraintScale = 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f); - mRenderFullSizeCamera.SetPosition(0.0f, 0.0f, mTargetSize.height * cameraPosConstraintScale); + mRenderFullSizeCamera.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, mTargetSize.height * cameraPosConstraintScale)); ////////////////////////////////////////////////////// // Pass size change onto GaussianBlurView, so it matches - mGaussianBlurView.SetSize(mTargetSize); + mGaussianBlurView.SetProperty(Actor::Property::SIZE, mTargetSize); GetImpl(mGaussianBlurView).AllocateResources(); + mGaussianBlurView.SetProperty(Actor::Property::VISIBLE, true); ////////////////////////////////////////////////////// // Create render targets // create off screen buffer of new size to render our child actors to - mRenderTargetForRenderingChildren = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED ); - mBloomExtractTarget = FrameBufferImage::New( mDownsampledWidth, mDownsampledHeight, mPixelFormat, Dali::Image::UNUSED ); - mOutputRenderTarget = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED); + mRenderTargetForRenderingChildren = FrameBuffer::New(mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE); + Texture textureForChildren = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height)); + mRenderTargetForRenderingChildren.AttachColorTexture(textureForChildren); + + mBloomExtractTarget = FrameBuffer::New(mDownsampledWidth, mDownsampledHeight, FrameBuffer::Attachment::NONE); + Texture texture = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mDownsampledWidth), unsigned(mDownsampledHeight)); + mBloomExtractTarget.AttachColorTexture(texture); + FrameBuffer blurExtractTarget = FrameBuffer::New(mDownsampledWidth, mDownsampledHeight, FrameBuffer::Attachment::NONE); + texture = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mDownsampledWidth), unsigned(mDownsampledHeight)); + blurExtractTarget.AttachColorTexture(texture); + + mOutputRenderTarget = FrameBuffer::New(mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE); + Texture outputTexture = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height)); + mOutputRenderTarget.AttachColorTexture(outputTexture); ////////////////////////////////////////////////////// // Point actors and render tasks at new render targets - mBloomExtractImageActor.SetImage( mRenderTargetForRenderingChildren ); - mBloomExtractImageActor.SetSize(mDownsampledWidth, mDownsampledHeight); // size needs to match render target + Renderer bloomRenderer = CreateRenderer(BASIC_VERTEX_SOURCE, SHADER_BLOOM_VIEW_EXTRACT_SHADER_FRAG); + SetRendererTexture(bloomRenderer, mRenderTargetForRenderingChildren); + mBloomExtractActor.AddRenderer(bloomRenderer); + mBloomExtractActor.SetProperty(Actor::Property::SIZE, Vector2(mDownsampledWidth, mDownsampledHeight)); // size needs to match render target // set GaussianBlurView to blur our extracted bloom - mGaussianBlurView.SetUserImageAndOutputRenderTarget(mBloomExtractTarget, mBloomExtractTarget); + mGaussianBlurView.SetUserImageAndOutputRenderTarget(mBloomExtractTarget.GetColorTexture(), blurExtractTarget); // use the completed blur in the first buffer and composite with the original child actors render - mCompositeImageActor.SetImage( mRenderTargetForRenderingChildren ); - mCompositeShader.SetEffectImage( mBloomExtractTarget ); + Renderer compositeRenderer = CreateRenderer(BASIC_VERTEX_SOURCE, SHADER_BLOOM_VIEW_COMPOSITE_SHADER_FRAG); + SetRendererTexture(compositeRenderer, mRenderTargetForRenderingChildren); + TextureSet textureSet = compositeRenderer.GetTextures(); + textureSet.SetTexture(0u, mRenderTargetForRenderingChildren.GetColorTexture()); + textureSet.SetTexture(1u, blurExtractTarget.GetColorTexture()); + mCompositeActor.AddRenderer(compositeRenderer); // set up target actor for rendering result, i.e. the blurred image - mTargetImageActor.SetImage(mOutputRenderTarget); + Renderer targetRenderer = CreateRenderer(BASIC_VERTEX_SOURCE, BASIC_FRAGMENT_SOURCE); + SetRendererTexture(targetRenderer, mOutputRenderTarget); + mTargetActor.AddRenderer(targetRenderer); } } @@ -386,35 +357,33 @@ void BloomView::CreateRenderTasks() // create render task to render our child actors to offscreen buffer mRenderChildrenTask = taskList.CreateTask(); - mRenderChildrenTask.SetSourceActor( mChildrenRoot ); + mRenderChildrenTask.SetSourceActor(mChildrenRoot); mRenderChildrenTask.SetExclusive(true); - mRenderChildrenTask.SetInputEnabled( false ); - mRenderChildrenTask.SetClearEnabled( true ); + mRenderChildrenTask.SetInputEnabled(false); + mRenderChildrenTask.SetClearEnabled(true); + mRenderChildrenTask.SetCameraActor(mRenderFullSizeCamera); // use camera that covers render target exactly + mRenderChildrenTask.SetFrameBuffer(mRenderTargetForRenderingChildren); // Extract the bright part of the image and render to a new buffer. Downsampling also occurs at this stage to save pixel fill, if it is set up. mBloomExtractTask = taskList.CreateTask(); - mBloomExtractTask.SetSourceActor( mBloomExtractImageActor ); + mBloomExtractTask.SetSourceActor(mBloomExtractActor); mBloomExtractTask.SetExclusive(true); - mBloomExtractTask.SetInputEnabled( false ); - mBloomExtractTask.SetClearEnabled( true ); + mBloomExtractTask.SetInputEnabled(false); + mBloomExtractTask.SetClearEnabled(true); + mBloomExtractTask.SetCameraActor(mRenderDownsampledCamera); + mBloomExtractTask.SetFrameBuffer(mBloomExtractTarget); // GaussianBlurView tasks must be created here, so they are executed in the correct order with respect to BloomView tasks GetImpl(mGaussianBlurView).CreateRenderTasks(); - // Use an image actor displaying the children render and composite it with the blurred bloom buffer, targeting the output + // Use an image view displaying the children render and composite it with the blurred bloom buffer, targeting the output mCompositeTask = taskList.CreateTask(); - mCompositeTask.SetSourceActor( mCompositeImageActor ); + mCompositeTask.SetSourceActor(mCompositeActor); mCompositeTask.SetExclusive(true); - mCompositeTask.SetInputEnabled( false ); - mCompositeTask.SetClearEnabled( true ); - - mRenderChildrenTask.SetCameraActor(mRenderFullSizeCamera); // use camera that covers render target exactly - mBloomExtractTask.SetCameraActor(mRenderDownsampledCamera); + mCompositeTask.SetInputEnabled(false); + mCompositeTask.SetClearEnabled(true); mCompositeTask.SetCameraActor(mRenderFullSizeCamera); - - mRenderChildrenTask.SetTargetFrameBuffer( mRenderTargetForRenderingChildren ); - mBloomExtractTask.SetTargetFrameBuffer( mBloomExtractTarget ); - mCompositeTask.SetTargetFrameBuffer( mOutputRenderTarget ); + mCompositeTask.SetFrameBuffer(mOutputRenderTarget); } void BloomView::RemoveRenderTasks() @@ -429,25 +398,12 @@ void BloomView::RemoveRenderTasks() taskList.RemoveTask(mCompositeTask); } -void BloomView::OnStageDisconnection() -{ - // TODO: can't call this here, since SetImage() calls fails similarly to above - // Need to fix the stage connection so this callback can be used arbitrarily. At that point we can simplify the API by removing the need for Activate() / Deactivate() - //Deactivate(); -} - -void BloomView::OnControlStageConnection() -{ - // TODO: can't call this here, since SetImage() calls fail to connect images to stage, since parent chain not fully on stage yet - // Need to fix the stage connection so this callback can be used arbitrarily. At that point we can simplify the API by removing the need for Activate() / Deactivate() - //Activate(); -} - void BloomView::Activate() { // make sure resources are allocated and start the render tasks processing AllocateResources(); CreateRenderTasks(); + mActivated = true; } void BloomView::Deactivate() @@ -455,6 +411,19 @@ void BloomView::Deactivate() // stop render tasks processing // Note: render target resources are automatically freed since we set the Image::Unused flag RemoveRenderTasks(); + + mRenderTargetForRenderingChildren.Reset(); + mBloomExtractTarget.Reset(); + mOutputRenderTarget.Reset(); + + // Reset children + mBloomExtractActor.RemoveRenderer(0u); + mTargetActor.RemoveRenderer(0u); + mCompositeActor.RemoveRenderer(0u); + + mGaussianBlurView.SetProperty(Actor::Property::VISIBLE, false); + + mActivated = false; } /** @@ -464,11 +433,13 @@ void BloomView::Deactivate() */ struct RecipOneMinusConstraint { - RecipOneMinusConstraint(){} + RecipOneMinusConstraint() + { + } - void operator()( float& current, const PropertyInputContainer& inputs ) + void operator()(float& current, const PropertyInputContainer& inputs) { - current = 1.0f / ( 1.0f - inputs[0]->GetFloat() ); + current = 1.0f / (1.0f - inputs[0]->GetFloat()); } }; @@ -478,83 +449,77 @@ void BloomView::SetupProperties() { CustomActor self = Self(); - /////////////////////////////////////////// // bloom threshold // set defaults, makes sure properties are registered with shader - mBloomExtractShader.SetUniform( BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT ); - mBloomExtractShader.SetUniform( RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME, 1.0f / (1.0f - BLOOM_THRESHOLD_DEFAULT) ); + mBloomExtractActor.RegisterProperty(BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT); + mBloomExtractActor.RegisterProperty(RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME, 1.0f / (1.0f - BLOOM_THRESHOLD_DEFAULT)); // Register a property that the user can control to change the bloom threshold - mBloomThresholdPropertyIndex = self.RegisterProperty(BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT); - Property::Index shaderBloomThresholdPropertyIndex = mBloomExtractShader.GetPropertyIndex(BLOOM_THRESHOLD_PROPERTY_NAME); - Constraint bloomThresholdConstraint = Constraint::New( mBloomExtractShader, shaderBloomThresholdPropertyIndex, EqualToConstraint()); - bloomThresholdConstraint.AddSource( Source(self, mBloomThresholdPropertyIndex) ); + mBloomThresholdPropertyIndex = self.RegisterProperty(BLOOM_THRESHOLD_PROPERTY_NAME, BLOOM_THRESHOLD_DEFAULT); + Property::Index shaderBloomThresholdPropertyIndex = mBloomExtractActor.GetPropertyIndex(BLOOM_THRESHOLD_PROPERTY_NAME); + Constraint bloomThresholdConstraint = Constraint::New(mBloomExtractActor, shaderBloomThresholdPropertyIndex, EqualToConstraint()); + bloomThresholdConstraint.AddSource(Source(self, mBloomThresholdPropertyIndex)); bloomThresholdConstraint.Apply(); // precalc 1.0 / (1.0 - threshold) on CPU to save shader insns, using constraint to tie to the normal threshold property - Property::Index shaderRecipOneMinusBloomThresholdPropertyIndex = mBloomExtractShader.GetPropertyIndex(RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME); - Constraint thresholdConstraint = Constraint::New( mBloomExtractShader, shaderRecipOneMinusBloomThresholdPropertyIndex, RecipOneMinusConstraint()); - thresholdConstraint.AddSource( LocalSource(shaderBloomThresholdPropertyIndex) ); + Property::Index shaderRecipOneMinusBloomThresholdPropertyIndex = mBloomExtractActor.GetPropertyIndex(RECIP_ONE_MINUS_BLOOM_THRESHOLD_PROPERTY_NAME); + Constraint thresholdConstraint = Constraint::New(mBloomExtractActor, shaderRecipOneMinusBloomThresholdPropertyIndex, RecipOneMinusConstraint()); + thresholdConstraint.AddSource(LocalSource(shaderBloomThresholdPropertyIndex)); thresholdConstraint.Apply(); - //////////////////////////////////////////// // bloom strength // Register a property that the user can control to fade the blur in / out via internal GaussianBlurView object - mBlurStrengthPropertyIndex = self.RegisterProperty(BLOOM_BLUR_STRENGTH_PROPERTY_NAME, BLOOM_BLUR_STRENGTH_DEFAULT); - Constraint blurStrengthConstraint = Constraint::New( mGaussianBlurView, mGaussianBlurView.GetBlurStrengthPropertyIndex(), EqualToConstraint()); - blurStrengthConstraint.AddSource( Source(self, mBlurStrengthPropertyIndex) ); + mBlurStrengthPropertyIndex = self.RegisterProperty(BLOOM_BLUR_STRENGTH_PROPERTY_NAME, BLOOM_BLUR_STRENGTH_DEFAULT); + Constraint blurStrengthConstraint = Constraint::New(mGaussianBlurView, mGaussianBlurView.GetBlurStrengthPropertyIndex(), EqualToConstraint()); + blurStrengthConstraint.AddSource(Source(self, mBlurStrengthPropertyIndex)); blurStrengthConstraint.Apply(); - //////////////////////////////////////////// // bloom intensity // Register a property that the user can control to fade the bloom intensity via internally hidden shader mBloomIntensityPropertyIndex = self.RegisterProperty(BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT); - mCompositeShader.SetUniform( BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT ); - Property::Index shaderBloomIntensityPropertyIndex = mCompositeShader.GetPropertyIndex(BLOOM_INTENSITY_PROPERTY_NAME); - Constraint bloomIntensityConstraint = Constraint::New( mCompositeShader, shaderBloomIntensityPropertyIndex, EqualToConstraint()); - bloomIntensityConstraint.AddSource( Source(self, mBloomIntensityPropertyIndex) ); + mCompositeActor.RegisterProperty(BLOOM_INTENSITY_PROPERTY_NAME, BLOOM_INTENSITY_DEFAULT); + Property::Index shaderBloomIntensityPropertyIndex = mCompositeActor.GetPropertyIndex(BLOOM_INTENSITY_PROPERTY_NAME); + Constraint bloomIntensityConstraint = Constraint::New(mCompositeActor, shaderBloomIntensityPropertyIndex, EqualToConstraint()); + bloomIntensityConstraint.AddSource(Source(self, mBloomIntensityPropertyIndex)); bloomIntensityConstraint.Apply(); - //////////////////////////////////////////// // bloom saturation // Register a property that the user can control to fade the bloom saturation via internally hidden shader mBloomSaturationPropertyIndex = self.RegisterProperty(BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT); - mCompositeShader.SetUniform( BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT ); - Property::Index shaderBloomSaturationPropertyIndex = mCompositeShader.GetPropertyIndex(BLOOM_SATURATION_PROPERTY_NAME); - Constraint bloomSaturationConstraint = Constraint::New( mCompositeShader, shaderBloomSaturationPropertyIndex, EqualToConstraint()); - bloomSaturationConstraint.AddSource( Source(self, mBloomSaturationPropertyIndex) ); + mCompositeActor.RegisterProperty(BLOOM_SATURATION_PROPERTY_NAME, BLOOM_SATURATION_DEFAULT); + Property::Index shaderBloomSaturationPropertyIndex = mCompositeActor.GetPropertyIndex(BLOOM_SATURATION_PROPERTY_NAME); + Constraint bloomSaturationConstraint = Constraint::New(mCompositeActor, shaderBloomSaturationPropertyIndex, EqualToConstraint()); + bloomSaturationConstraint.AddSource(Source(self, mBloomSaturationPropertyIndex)); bloomSaturationConstraint.Apply(); - //////////////////////////////////////////// // image intensity // Register a property that the user can control to fade the image intensity via internally hidden shader mImageIntensityPropertyIndex = self.RegisterProperty(IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT); - mCompositeShader.SetUniform( IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT ); - Property::Index shaderImageIntensityPropertyIndex = mCompositeShader.GetPropertyIndex(IMAGE_INTENSITY_PROPERTY_NAME); - Constraint imageIntensityConstraint = Constraint::New( mCompositeShader, shaderImageIntensityPropertyIndex, EqualToConstraint()); - imageIntensityConstraint.AddSource( Source(self, mImageIntensityPropertyIndex) ); + mCompositeActor.RegisterProperty(IMAGE_INTENSITY_PROPERTY_NAME, IMAGE_INTENSITY_DEFAULT); + Property::Index shaderImageIntensityPropertyIndex = mCompositeActor.GetPropertyIndex(IMAGE_INTENSITY_PROPERTY_NAME); + Constraint imageIntensityConstraint = Constraint::New(mCompositeActor, shaderImageIntensityPropertyIndex, EqualToConstraint()); + imageIntensityConstraint.AddSource(Source(self, mImageIntensityPropertyIndex)); imageIntensityConstraint.Apply(); - //////////////////////////////////////////// // image saturation // Register a property that the user can control to fade the image saturation via internally hidden shader mImageSaturationPropertyIndex = self.RegisterProperty(IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT); - mCompositeShader.SetUniform( IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT ); - Property::Index shaderImageSaturationPropertyIndex = mCompositeShader.GetPropertyIndex(IMAGE_SATURATION_PROPERTY_NAME); - Constraint imageSaturationConstraint = Constraint::New( mCompositeShader, shaderImageSaturationPropertyIndex, EqualToConstraint()); - imageSaturationConstraint.AddSource( Source(self, mImageSaturationPropertyIndex) ); + mCompositeActor.RegisterProperty(IMAGE_SATURATION_PROPERTY_NAME, IMAGE_SATURATION_DEFAULT); + Property::Index shaderImageSaturationPropertyIndex = mCompositeActor.GetPropertyIndex(IMAGE_SATURATION_PROPERTY_NAME); + Constraint imageSaturationConstraint = Constraint::New(mCompositeActor, shaderImageSaturationPropertyIndex, EqualToConstraint()); + imageSaturationConstraint.AddSource(Source(self, mImageSaturationPropertyIndex)); imageSaturationConstraint.Apply(); }