inline TraceCallStack& GetDrawTrace() { return mDrawTrace; }
template <typename T>
+ inline bool GetUniformValue( const char* name, T& value ) const
+ {
+ for( ProgramUniformMap::const_iterator program_it = mUniforms.begin();
+ program_it != mUniforms.end();
+ ++program_it )
+ {
+ const UniformIDMap &uniformIDs = program_it->second;
+
+ UniformIDMap::const_iterator uniform_it = uniformIDs.find( name );
+ if( uniform_it != uniformIDs.end() )
+ {
+ // found one matching uniform name, lets check the value...
+ GLuint programId = program_it->first;
+ GLint uniformId = uniform_it->second;
+
+ const ProgramUniformValue<T> &mProgramUniforms = GetProgramUniformsForType( value );
+ return mProgramUniforms.GetUniformValue( programId, uniformId, value );
+ }
+ }
+ return false;
+ }
+
+
+ template <typename T>
inline bool CheckUniformValue( const char* name, const T& value ) const
{
for( ProgramUniformMap::const_iterator program_it = mUniforms.begin();
#include <dali.h>
#include <dali-toolkit/dali-toolkit.h>
-#include <dali/devel-api/actors/mesh-actor.h>
-#include <dali/devel-api/modeling/material.h>
using namespace Dali;
using namespace Dali::Toolkit;
END_TEST;
}
+int UtcDaliBubbleEmitterDownCast01(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline(" UtcDaliBubbleEmitterDownCast01 ");
+
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
+
+ BaseHandle handle(emitter);
+ BubbleEmitter emitter2 = BubbleEmitter::DownCast(handle);
+ DALI_TEST_EQUALS( (bool)emitter2, true, TEST_LOCATION );
+ END_TEST;
+}
+
+int UtcDaliBubbleEmitterDownCast02(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline(" UtcDaliBubbleEmitterDownCast02 ");
+
+ Handle handle = Handle::New(); // Create a custom object
+ BubbleEmitter emitter = BubbleEmitter::DownCast(handle);
+ DALI_TEST_EQUALS( (bool)emitter, false, TEST_LOCATION );
+ END_TEST;
+}
+
int UtcDaliBubbleEmitterGetRootActor(void)
{
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterGetRootActor " );
Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 270, Vector2( 5.f, 10.f ));
Actor root = emitter.GetRootActor();
DALI_TEST_CHECK( root );
END_TEST;
}
-int UtcDaliBubbleEmitterSetShapeImage(void)
+//TODO: test case for BubbleEmitter::SetShapeImage(Image)
+// To test that the bubble-shape image is successfully switched in the sampler
+/*int UtcDaliBubbleEmitterSetShapeImage(void)
{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliBubbleEmitterSetShapeImage " );
-
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-
- Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- Material material = bubbleMesh.GetMaterial();
-
- DALI_TEST_CHECK( material.GetDiffuseTexture() == shapeImage1 );
-
- Image shapeImage2 = CreateSolidColorImage( application, Color::RED, 8, 8 );
- emitter.SetShapeImage( shapeImage2 );
-
- DALI_TEST_CHECK( material.GetDiffuseTexture() == shapeImage2 );
- END_TEST;
-}
+}*/
int UtcDaliBubbleEmitterSetBubbleScale(void)
{
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterSetBubbleScale " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 150, Vector2( 5.f, 10.f ));
Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- ShaderEffect effect = bubbleMesh.GetShaderEffect();
- DALI_TEST_CHECK( effect );
+ Stage::GetCurrent().Add( root );
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ Wait(application);
- Property::Index scalePropertyIndex = effect.GetPropertyIndex( "uDynamicScale" );
float scaleValue;
- (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
- DALI_TEST_EQUALS(scaleValue, 1.f, TEST_LOCATION );
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
+ DALI_TEST_EQUALS( scaleValue, 1.f, TEST_LOCATION );
emitter.SetBubbleScale( 2.f );
- application.SendNotification();
- application.Render();
- (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
- DALI_TEST_EQUALS(scaleValue, 2.f, TEST_LOCATION );
+ Wait(application);
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
+ DALI_TEST_EQUALS( scaleValue, 2.f, TEST_LOCATION );
emitter.SetBubbleScale( 0.5f );
- application.SendNotification();
- application.Render();
- (effect.GetProperty(scalePropertyIndex)).Get( scaleValue );
- DALI_TEST_EQUALS(scaleValue, 0.5f, TEST_LOCATION );
+ Wait(application);
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uDynamicScale", scaleValue ) );
+ DALI_TEST_EQUALS( scaleValue, 0.5f, TEST_LOCATION );
END_TEST;
}
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterSetBubbleDensity " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
try
{
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterSetBubbleDensity " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 200, Vector2( 5.f, 10.f ));
try
{
ToolkitTestApplication application;
tet_infoline( " UtcDaliBubbleEmitterSetBlendMode " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
-
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 150, Vector2( 5.f, 10.f ));
Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
+ Stage::GetCurrent().Add( root );
- BlendingFactor::Type srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha;
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ Wait(application);
+ DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
emitter.SetBlendMode( true );
- bubbleMesh.GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
- DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE );
- DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ZERO );
- DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE );
+ Wait(application);
+ DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ZERO, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
emitter.SetBlendMode( false );
- bubbleMesh.GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
- DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE_MINUS_SRC_ALPHA );
- DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ONE );
- DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE_MINUS_SRC_ALPHA );
+ Wait(application);
+ DALI_TEST_EQUALS( (GLenum)GL_SRC_ALPHA, glAbstraction.GetLastBlendFuncSrcRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstRgb(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE, glAbstraction.GetLastBlendFuncSrcAlpha(), TEST_LOCATION );
+ DALI_TEST_EQUALS( (GLenum)GL_ONE_MINUS_SRC_ALPHA, glAbstraction.GetLastBlendFuncDstAlpha(), TEST_LOCATION );
+
END_TEST;
}
BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- ShaderEffect effect = bubbleMesh.GetShaderEffect();
- DALI_TEST_CHECK( effect );
+ Actor bubbleMesh = root.GetChildAt( 0 );
+ Stage::GetCurrent().Add( root );
+ DALI_TEST_CHECK( bubbleMesh );
- Property::Index propertyIndex0 = effect.GetPropertyIndex( "uPercentage[0]" );
- Property::Index propertyIndex1 = effect.GetPropertyIndex( "uPercentage[1]" );
+ Property::Index propertyIndex0 = bubbleMesh.GetPropertyIndex( "percentage-0" );
+ Property::Index propertyIndex1 = bubbleMesh.GetPropertyIndex( "percentage-1" );
float value0, value1;
Animation animation = Animation::New( 0.5f );
emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
emitter.EmitBubble( animation, Vector2(10.f,10.f), Vector2(5.f,5.f), Vector2(30.f,30.f) );
- (effect.GetProperty(propertyIndex0)).Get( value0 );
- (effect.GetProperty(propertyIndex1)).Get( value1 );
+ (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
+ (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
DALI_TEST_EQUALS(value0, 0.f, TEST_LOCATION );
DALI_TEST_EQUALS(value1, 0.f, TEST_LOCATION );
animation.Play();
Wait(application, 300);
- (effect.GetProperty(propertyIndex0)).Get( value0 );
- (effect.GetProperty(propertyIndex1)).Get( value1 );
+ propertyIndex0 = bubbleMesh.GetPropertyIndex( "percentage-0" );
+ propertyIndex1 = bubbleMesh.GetPropertyIndex( "percentage-1" );
+ (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
+ (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
DALI_TEST_CHECK( value0 >= 0.6f );
DALI_TEST_CHECK( value1 >= 0.6f );
- Wait(application, 600);
- (effect.GetProperty(propertyIndex0)).Get( value0 );
- (effect.GetProperty(propertyIndex1)).Get( value1 );
+ Wait(application,500);
+ (bubbleMesh.GetProperty(propertyIndex0)).Get( value0 );
+ (bubbleMesh.GetProperty(propertyIndex1)).Get( value1 );
DALI_TEST_EQUALS(value0, 1.f, TEST_LOCATION );
DALI_TEST_EQUALS(value1, 1.f, TEST_LOCATION );
END_TEST;
}
-int UtcDaliBubbleEmitterStartExplosion(void)
+int UtcDaliBubbleEmitterRestore(void)
{
ToolkitTestApplication application;
- tet_infoline( " UtcDaliBubbleEmitterStartExplosion " );
+ tet_infoline( " UtcDaliBubbleEmitterRestore " );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
+ Image shapeImage = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
+ BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage, 90, Vector2( 5.f, 10.f ));
Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- ShaderEffect effect = bubbleMesh.GetShaderEffect();
- DALI_TEST_CHECK( effect );
-
- Property::Index propertyIndex = effect.GetPropertyIndex( "uMagnification" );
- float value;
- (effect.GetProperty(propertyIndex)).Get( value );
- DALI_TEST_EQUALS(value, 1.f, TEST_LOCATION );
-
- emitter.StartExplosion( 0.4, 4.f );
+ Stage::GetCurrent().Add( root );
- Wait(application, 200); // 0.2s
- (effect.GetProperty(propertyIndex)).Get( value );
- DALI_TEST_CHECK( value >= 2.f );
+ Actor bubbleMesh = root.GetChildAt( 0 );
+ Renderer renderer = bubbleMesh.GetRendererAt( 0 );
+ DALI_TEST_CHECK( renderer );
- Wait(application, 100); // 0.3s
- (effect.GetProperty(propertyIndex)).Get( value );
- DALI_TEST_CHECK( value >= 3.f );
+ TestGlAbstraction& gl = application.GetGlAbstraction();
- Wait(application, 100); // 0.4s
- (effect.GetProperty(propertyIndex)).Get( value );
- DALI_TEST_EQUALS(value, 1.f, TEST_LOCATION );
- END_TEST;
-}
+ float percentageValue;
+ Vector4 startEndPosValue;
-int UtcDaliBubbleEmitterRestore(void)
-{
- ToolkitTestApplication application;
- tet_infoline( " UtcDaliBubbleEmitterRestore " );
+ Animation animation = Animation::New( 0.5f );
+ emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
- Image shapeImage1 = CreateSolidColorImage( application, Color::GREEN, 5, 5 );
- BubbleEmitter emitter = BubbleEmitter::New( Vector2(50.f,50.f),shapeImage1, 200, Vector2( 5.f, 10.f ));
- Actor root = emitter.GetRootActor();
- MeshActor bubbleMesh = MeshActor::DownCast( root.GetChildAt( 0 ) );
- ShaderEffect effect = bubbleMesh.GetShaderEffect();
- DALI_TEST_CHECK( effect );
+ Wait(application);
- Property::Index percentagePropertyIndex = effect.GetPropertyIndex( "uPercentage[0]" );
- float percentage;
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
+ DALI_TEST_EQUALS( percentageValue, 0.f, TEST_LOCATION );
- Animation animation = Animation::New( 0.5f );
- emitter.EmitBubble( animation, Vector2(40.f,40.f), Vector2(-5.f,-5.f), Vector2(30.f,30.f) );
- (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
- DALI_TEST_EQUALS(percentage, 0.f, TEST_LOCATION );
+ DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartAndEndPos[0]", startEndPosValue ) );
+ DALI_TEST_EQUALS( startEndPosValue.x, 40.f, TEST_LOCATION );
+ DALI_TEST_EQUALS( startEndPosValue.y, 40.f, TEST_LOCATION );
animation.Play();
Wait(application, 200);
animation.Clear();
- (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
- DALI_TEST_CHECK( percentage < 0.5f && percentage >= 0.4);
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
+ DALI_TEST_CHECK( percentageValue < 0.5f && percentageValue >= 0.4);
+
+ DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartAndEndPos[0]", startEndPosValue ) );
+ DALI_TEST_EQUALS( startEndPosValue.x, 40.f, TEST_LOCATION );
+ DALI_TEST_EQUALS( startEndPosValue.y, 40.f, TEST_LOCATION );
emitter.Restore();
application.SendNotification();
application.Render();
- (effect.GetProperty(percentagePropertyIndex)).Get( percentage );
- DALI_TEST_EQUALS(percentage, 1.f, TEST_LOCATION );
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uPercentage[0]", percentageValue ) );
+ DALI_TEST_EQUALS( percentageValue, 0.f, TEST_LOCATION );
+
+ DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uStartAndEndPos[0]", startEndPosValue ) );
+ DALI_TEST_EQUALS( startEndPosValue, Vector4::ZERO, TEST_LOCATION );
END_TEST;
}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "bubble-actor.h"
+
+// EXTERNAL INCLUDES
+#include <cmath>
+#include <sstream>
+
+// INTERNAL INCLUDES
+
+namespace
+{
+
+/**
+ * Register a property and map it as uniform.
+ * @param[in] handle The handle to register new property.
+ * @param[in] propertyName The name of the property.
+ * @param[in] unifoemName The name of the uniform.
+ * @param[in] value The initial value of the property.
+ * @return The index of theproperty
+ */
+Dali::Property::Index RegisterUniform( Dali::Handle& handle,
+ const std::string& propertyName,
+ const std::string& uniformName,
+ Dali::Property::Value value)
+{
+ Dali::Property::Index propertyIndex = handle.RegisterProperty( propertyName, value );
+ handle.AddUniformMapping( propertyIndex, uniformName );
+
+ return propertyIndex;
+}
+
+}// end LOCAL_STUFF
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+BubbleActor::BubbleActor( unsigned int numberOfBubble,
+ const Vector2& movementArea)
+: mMovementArea( movementArea ),
+ mNumBubble( numberOfBubble )
+{
+ mActor = Actor::New();
+}
+
+void BubbleActor::MakeRenderable( Geometry geometry, Material material )
+{
+ if( mRenderer )
+ {
+ // This function is supposed to be called once
+ return;
+ }
+
+ mRenderer = Renderer::New( geometry, material );
+
+ mActor.AddRenderer( mRenderer );
+ mActor.SetSize( mMovementArea );
+ mActor.SetParentOrigin(ParentOrigin::TOP_LEFT);
+
+ // register uniforms
+ mIndexGravity = RegisterUniform( mActor, "gravity", "uGravity", 50.f );
+ mIndexDynamicScale = RegisterUniform( mActor, "dynamic-scale", "uDynamicScale", 1.f );
+
+ mIndexInvertedMovementArea = RegisterUniform( mActor, "inverted-movement-area", "uInvertedMovementArea", Vector2(1.f,1.f) / mMovementArea );
+
+ srand(time(NULL));
+ mIndicesOffset.resize(9);
+ int offset = mMovementArea.Length() / 10.f;
+ mIndicesOffset[0] = RegisterUniform(mActor, "offset-0", "offset[0]", Vector2(0.f,0.f));
+ mIndicesOffset[1] = RegisterUniform(mActor, "offset-1", "offset[1]", Vector2(rand()%offset,rand()%offset) );
+ mIndicesOffset[2] = RegisterUniform(mActor, "offset-2", "offset[2]", Vector2(rand()%offset,-rand()%offset) );
+ mIndicesOffset[3] = RegisterUniform(mActor, "offset-3", "offset[3]", Vector2(-rand()%offset,rand()%offset) );
+ mIndicesOffset[4] = RegisterUniform(mActor, "offset-4", "offset[4]", Vector2(-rand()%offset,-rand()%offset) );
+ mIndicesOffset[5] = RegisterUniform(mActor, "offset-5", "offset[5]", Vector2(rand()%offset,0.f));
+ mIndicesOffset[6] = RegisterUniform(mActor, "offset-6", "offset[6]", Vector2(-rand()%offset,0.f));
+ mIndicesOffset[7] = RegisterUniform(mActor, "offset-7", "offset[7]", Vector2(0.f,rand()%offset));
+ mIndicesOffset[8] = RegisterUniform(mActor, "offset-8", "offset[8]", Vector2(0.f,-rand()%offset));
+
+ Vector4 zeroVector;
+ mIndiceStartEndPos.resize( mNumBubble );
+ mIndicesPercentage.resize( mNumBubble );
+ for( unsigned int i=0; i<mNumBubble; i++ )
+ {
+ std::ostringstream ossProperty;
+ ossProperty<< "start-end-position-"<< i;
+
+ std::ostringstream ossUniform;
+ ossUniform<< "uStartAndEndPos["<< i << "]";
+ mIndiceStartEndPos[i] = RegisterUniform( mActor, ossProperty.str(), ossUniform.str(), zeroVector );
+
+ ossProperty.str("");
+ ossProperty<< "percentage-"<< i;
+
+ ossUniform.str("");
+ ossUniform<< "uPercentage["<< i << "]";
+ mIndicesPercentage[i] = RegisterUniform( mActor, ossProperty.str(), ossUniform.str(), 0.f );
+ }
+}
+
+Actor BubbleActor::GetMeshActor()
+{
+ return mActor;
+}
+
+void BubbleActor::SetGeometry( Geometry geometry )
+{
+ mRenderer.SetGeometry( geometry );
+}
+
+void BubbleActor::SetMovementArea( const Vector2& movementArea )
+{
+ if( movementArea == mMovementArea)
+ {
+ return;
+ }
+
+ mMovementArea = movementArea;
+ mActor.SetSize( mMovementArea );
+ mActor.SetProperty( mIndexInvertedMovementArea, Vector2(1.f,1.f) / mMovementArea );
+
+ int offset = mMovementArea.Length() / 10.f;
+ mActor.SetProperty( mIndicesOffset[1], Vector2(rand()%offset,rand()%offset) );
+ mActor.SetProperty( mIndicesOffset[2], Vector2(rand()%offset,-rand()%offset) );
+ mActor.SetProperty( mIndicesOffset[3], Vector2(-rand()%offset,rand()%offset) );
+ mActor.SetProperty( mIndicesOffset[4], Vector2(-rand()%offset,-rand()%offset) );
+ mActor.SetProperty( mIndicesOffset[5], Vector2(rand()%offset,0.f));
+ mActor.SetProperty( mIndicesOffset[6], Vector2(-rand()%offset,0.f));
+ mActor.SetProperty( mIndicesOffset[7], Vector2(0.f,rand()%offset));
+ mActor.SetProperty( mIndicesOffset[8], Vector2(0.f,-rand()%offset));
+}
+
+void BubbleActor::SetStartAndEndPosition( unsigned int index, const Vector4& startAndEndPosition )
+{
+ mActor.SetProperty( mIndiceStartEndPos[index], startAndEndPosition );
+}
+
+void BubbleActor::SetPercentage( unsigned int index, float percentage )
+{
+ mActor.SetProperty( mIndicesPercentage[index], percentage );
+}
+
+void BubbleActor::SetGravity( float gravity )
+{
+ mActor.SetProperty( mIndexGravity, gravity );
+}
+
+void BubbleActor::SetDynamicScale( float scale )
+{
+ mActor.SetProperty( mIndexDynamicScale, scale );
+}
+
+Property BubbleActor::GetPercentageProperty( unsigned int index )
+{
+ return Property( mActor, mIndicesPercentage[index] );
+}
+
+void BubbleActor::ResetProperties()
+{
+ Vector4 zeroVector;
+ for( unsigned int i=0; i<mNumBubble; i++ )
+ {
+ SetPercentage( i, 0.f);
+ SetStartAndEndPosition( i, zeroVector );
+ }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H_
+#define __DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H_
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/actors/renderer.h>
+#include <dali/public-api/object/property-buffer.h>
+#include <dali/public-api/object/property-map.h>
+#include <dali/public-api/shader-effects/material.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * BubbleActor is a group of bubbles.Each bubble can be moved separately.
+ * Its custom shader achieves similar effect of particle system by applying on a specially created mesh
+ * Each bubble is rendered on a patch with two triangles; and each mesh can contain multiple such patches, thus a group.
+ */
+class BubbleActor : public RefObject
+{
+public:
+
+ /**
+ * Constructor
+ * @param[in] numberOfBubble How many groups of uniforms are used to control the bubble movement.
+ * Note: Limited by the maximum available uniforms, this parameter cannot be bigger than 100.
+ * Ideally use one group of uniform to control one bubble.
+ * If the num of patches in the MeshActor is more than groups of uniforms,
+ * the uniform values will be shared by multiple bubbles. Allow up to 9 times.
+ * @param[in] movementArea The size of the bubble moving area, usually the same size as the background image actor.
+ * @return A newly allocated object.
+ */
+ BubbleActor( unsigned int numberOfBubble,
+ const Vector2& movementArea);
+
+ /**
+ * @brief Destructor
+ */
+ ~BubbleActor(){}
+
+ /**
+ * Prepare for the rendering: create and add renderer, and register properties
+ * @param[in] geometry The geometry to be used by the renderer
+ * @param[in] material The material to be used by the renderer
+ */
+ void MakeRenderable( Geometry geometry, Material material );
+
+ /**
+ * Return the mesh actor which is used to display the bubbles
+ */
+ Actor GetMeshActor();
+
+ /**
+ * Sets the geometry to be used by the renderer
+ * @param[in] geometry The geometry to be used by the renderer
+ */
+ void SetGeometry( Geometry geometry );
+
+ /**
+ * Set the bubble movement area for the BubbleEffect
+ * @param[in] movementArea The size of bubble movement area; by default, it is the stage size
+ */
+ void SetMovementArea( const Vector2& movementArea );
+
+ /**
+ * Set the start and end positions of the index-th bubble's movement.
+ * @param[in] index Indicate which bubble these properties are applied on.
+ * @param[in] startAndEndPosition The start and the end position of movement.
+ */
+ void SetStartAndEndPosition( unsigned int index, const Vector4& startAndEndPosition );
+
+ /**
+ * Set the movement completed percentage of the index-th bubble.
+ * The bubble will appear at start position when percentage equals to zero,
+ * and disappear near end position (affected by gravity) when percentage equals to one.
+ * This percentage property is used to animate the bubble movement.
+ * @param[in] index Indicate which bubble this property is applied on.
+ * @param[in] percentage Set the percentage property value ( between zero and one ).
+ */
+ void SetPercentage( unsigned int index, float percentage );
+
+ /**
+ * Set the gravity applied to the y direction, which makes the bubbles no longer moving on a straight line.
+ * @param[in] gravity The gravity on the y direction.
+ */
+ void SetGravity( float gravity );
+
+ /**
+ * Set the scale factor applied to the bubbles
+ * @param[in] scale The scale factor applied on all bubbles.
+ */
+ void SetDynamicScale( float scale );
+
+ /**
+ * Get the idx-th percentage property.
+ * @param[in] idx The percentage property index.
+ * @return the idx-th percentage property.
+ */
+ Property GetPercentageProperty( unsigned int idx );
+
+ /**
+ * Reset the uniform values to default.
+ */
+ void ResetProperties();
+
+private:
+
+ Actor mActor;
+ Renderer mRenderer;
+
+ Vector2 mMovementArea; ///< The size of the bubble moving area, usually the same size as the background image actor.
+
+ //properties mapped as uniforms
+ std::vector<Property::Index> mIndicesOffset; ///< Indices of the properties mapping to uniform array 'uOffset'
+ std::vector<Property::Index> mIndiceStartEndPos; ///< Indices of the properties mapping to uniform array 'uStartAndEndPos'
+ std::vector<Property::Index> mIndicesPercentage; ///< Indices of the properties mapping to uniform array 'uPercentage'
+ Property::Index mIndexGravity; ///< Index of the property mapping to uniform 'uGravity'
+ Property::Index mIndexDynamicScale; ///< Index of the property mapping to uniform 'uDynamicScale'
+ Property::Index mIndexInvertedMovementArea; ///< Index of the property mapping to uniform 'uInvertedMovementArea'
+
+ unsigned int mNumBubble; ///< How many groups of uniforms are used to control the bubble movement.
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H_ */
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H_
+#define __DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H_
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <sstream>
+#include <dali/public-api/shader-effects/shader.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * Create the shader to be used by the material
+ * @param[in] numberOfBubble How many groups of uniforms are used to control the bubble movement.
+ * @return A handle to the newly created shader.
+ */
+inline Shader CreateBubbleShader( unsigned int numBubble )
+{
+ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+ attribute mediump float aIndex;\n
+ attribute mediump vec2 aPosition;\n
+ attribute highp vec2 aTexCoord;\n
+ varying mediump vec2 vTexCoord;\n
+ uniform mediump mat4 uMvpMatrix;\n
+ // the gravity applied to the y direction
+ uniform mediump float uGravity;\n
+ // xy: the emit position of the bubble; zw: the destination of the bubble.
+ // The bubble is moving from (xy) to (zw plus the y drop influenced by gravity).
+ uniform vec4 uStartAndEndPos[NUMBER_OF_BUBBLE];\n
+ // The undergoing percentage of the bubble movement. 0.0: start from emit position, 1.0: reach the destination
+ uniform float uPercentage[NUMBER_OF_BUBBLE];\n
+ uniform vec2 uInvertedMovementArea;\n
+ // The bubble number is restricted by the available uniform num.
+ // To increase the displayed bubble, every uStartAndEndPos and uPercentage uniform is applied to a small bunch of bubbles (9 here)
+ // The offset defines the random offset between bubbles within the bunch.
+ uniform vec2 offset[9];\n
+ // This uniform is used to change the bubble size during running time
+ uniform float uDynamicScale;\n
+ varying float vPercentage;\n
+ varying vec2 vEffectTexCoord;\n
+ void main()\n
+ {\n
+ vec4 position = vec4( aPosition, 0.0, 1.0 );\n
+ // The Z coordinate is used to record the bubble index within current mesh actor
+ int index = int(aIndex); \n
+ //for some i between 0 ~ NUMBER_OF_BUBBLE-1: i,i+NUMBER_OF_BUBBLE, i+NUMBER_OF_BUBBLE*2, ... (up to i+NUMBER_OF_BUBBLE*8) belongs to the same bunch.
+ int groupIdx = index / NUMBER_OF_BUBBLE;\n
+ // The bubbles within the same bunch applies the same uniforms uStartAndEndPos[idx] & uPercentage[idx]
+ int idx = index - groupIdx*NUMBER_OF_BUBBLE;\n
+ float percentage = uPercentage[idx];
+ // early out if uPercentage is (zero || one) setting position to zero (zero sized triangles)
+ if( percentage <= 0.0 || percentage >= 1.0 )\n
+ {\n
+ gl_Position = vec4(0.0);\n
+ return;\n
+ }\n
+ vec4 startAndEnd = uStartAndEndPos[idx];\n
+ // The final position is added up different offset for bubbles
+ startAndEnd.zw += offset[groupIdx];\n
+ \n
+ // increase the bubble size from 0% to 100% during the first 1/5 of movement & apply the dynamic scale
+ // the new xy value containes both the new scale and new bubble position
+ position.xy *= uDynamicScale*min(percentage*5.0, 1.0);\n
+ position.xy += mix(startAndEnd.xy, startAndEnd.zw, percentage);\n
+ // The gravity is g*t*t on the y direction
+ position.y += uGravity * pow(percentage, 2.0);\n
+ gl_Position = uMvpMatrix * position;\n
+ \n
+ // Add multiple bubble shapes in the effect
+ vTexCoord = aTexCoord;\n
+ vPercentage = percentage;\n
+ // Use the emit position color for the bubble
+ vEffectTexCoord = startAndEnd.xy * uInvertedMovementArea;\n
+ }\n
+ );
+
+ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+ varying mediump vec2 vTexCoord;\n
+ uniform lowp vec4 uColor;\n
+ uniform sampler2D sBackground;\n
+ uniform sampler2D sBubbleShape;\n
+ varying mediump float vPercentage;\n
+ varying mediump vec2 vEffectTexCoord;\n
+ \n
+ void main()\n
+ {\n
+ // Get the emit pisition color, and Mix with the actor color
+ mediump vec4 fragColor = texture2D(sBackground, vEffectTexCoord)*uColor;\n
+ // Apply the shape defined by the texture contained in the material
+ // And make the opacity being 0.7, and animate from 0.7 to 0 during the last 1/3 of movement
+ fragColor.a *= texture2D(sBubbleShape, vTexCoord).a * ( 2.1 - max( vPercentage*2.1, 1.4 ) );\n
+ gl_FragColor = fragColor;\n
+ }\n
+ );
+
+ std::ostringstream vertexShaderStringStream;
+ vertexShaderStringStream << "#define NUMBER_OF_BUBBLE "<< numBubble << "\n"
+ << VERTEX_SHADER;
+ Shader shader = Shader::New( vertexShaderStringStream.str(), FRAGMENT_SHADER );
+
+ return shader;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+#endif /* __DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H_ */
#include "bubble-emitter-impl.h"
// EXTERNAL INCLUDES
-#include <cmath>
#include <dali/public-api/animation/animation.h>
#include <dali/public-api/render-tasks/render-task-list.h>
#include <dali/public-api/images/resource-image.h>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/shader-effects/bubble-effect/color-adjuster.h>
+#include <dali-toolkit/internal/controls/bubble-effect/bubble-actor.h>
+#include <dali-toolkit/internal/controls/bubble-effect/color-adjuster.h>
+#include <dali-toolkit/internal/controls/bubble-effect/bubble-effect.h>
+
+namespace
+{
+struct Vertex
+{
+ float index;
+ Dali::Vector2 position;
+ Dali::Vector2 textureCoord;
+
+ Vertex()
+ {}
+
+ Vertex( float index, const Dali::Vector2& position, const Dali::Vector2& textureCoord )
+ : index( index ), position( position ), textureCoord( textureCoord )
+ {}
+};
+
+/**
+ * Return a random value between the given interval.
+ * @param[in] f0 The low bound
+ * @param[in] f1 The up bound
+ * @return A random value between the given interval
+ */
+float RandomRange(float f0, float f1)
+{
+ return f0 + (rand() & 0xfff) * (f1-f0) * (1.0f/4095.0f);
+}
+
+}
namespace Dali
{
unsigned int maximumNumberOfBubble,
const Vector2& bubbleSizeRange )
: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
- mMovementArea( movementArea ),
mShapeImage( shapeImage ),
- mTotalNumOfBubble( maximumNumberOfBubble ),
- mRenderTaskRunning(false),
+ mMovementArea( movementArea ),
mBubbleSizeRange( bubbleSizeRange ),
- mCurrentUniform( 0 ),
- mDensity( 5 )
+ mDensity( 5 ),
+ mTotalNumOfBubble( maximumNumberOfBubble ),
+ mCurrentBubble( 0 ),
+ mRenderTaskRunning(false)
{
- // Calculate how many BubbleEffect shaders are required
+ // Calculate how many shaders are required
if( mTotalNumOfBubble>100 )
{
- mNumBubblePerShader = 100;
- mNumShader = mTotalNumOfBubble / 100;
+ mNumBubblePerActor = 100;
+ mNumActor = mTotalNumOfBubble / 100;
+ if( mNumActor*mNumBubblePerActor < mTotalNumOfBubble )
+ {
+ mNumActor++;
+ mNumBubblePerActor = mTotalNumOfBubble / mNumActor+1;
+ mTotalNumOfBubble = mNumActor * mNumBubblePerActor;
+ }
}
else
{
- mNumBubblePerShader = mTotalNumOfBubble;
- mNumShader = 1;
+ mNumBubblePerActor = mTotalNumOfBubble;
+ mNumActor = 1;
}
}
// Prepare the frame buffer to store the color adjusted background image
mEffectImage = FrameBufferImage::New( mMovementArea.width/4.f, mMovementArea.height/4.f, Pixel::RGBA8888, Dali::Image::UNUSED );
- // Generate the material object, which is used by all meshActors
- GenMaterial();
+ // Generate the samplers and geometry, which is used by all bubbleActors
+ mSamplerBackground = Sampler::New( mEffectImage, "sBackground" );
+ mSamplerBubbleShape = Sampler::New( mShapeImage, "sBubbleShape" );
+ mMeshGeometry = CreateGeometry( mNumBubblePerActor*mDensity );
- mMesh.resize( mNumShader );
- mMeshActor.resize( mNumShader );
- mEffect.resize( mNumShader );
+ Shader bubbleShader = CreateBubbleShader (mNumBubblePerActor );
+
+ mMaterial = Material::New( bubbleShader );
+ mMaterial.AddSampler( mSamplerBackground );
+ mMaterial.AddSampler( mSamplerBubbleShape );
+
+ mBubbleActors.resize( mNumActor );
// Create the meshActor group and bubbleEffect group to emit bubbles following the given track, such as finger touch track.
- MeshData meshData;
- ConstructBubbleMesh( meshData, mNumBubblePerShader*mDensity);
- for(unsigned int i=0; i < mNumShader; i++ )
+ for(unsigned int i=0; i < mNumActor; i++ )
{
- mMesh[i] = Mesh::New( meshData );
- mMeshActor[i] = MeshActor::New( mMesh[i] );
- mMeshActor[i].SetParentOrigin(ParentOrigin::TOP_LEFT);
- mEffect[i] = BubbleEffect::New( mNumBubblePerShader );
- mEffect[i].SetEffectImage( mEffectImage );
- mEffect[i].SetMovementArea( mMovementArea );
- mMeshActor[i].SetShaderEffect( mEffect[i] );
- mBubbleRoot.Add( mMeshActor[i] );
+ mBubbleActors[i] = new BubbleActor( mNumBubblePerActor, mMovementArea );
+ (mBubbleActors[i])->MakeRenderable( mMeshGeometry, mMaterial );
+ mBubbleRoot.Add( (mBubbleActors[i])->GetMeshActor() );
}
- // Create the extra meshActor and bubbleEffect to emit bubbles in totally random angle.
- MeshData meshDataForNoise;
- ConstructBubbleMesh( meshDataForNoise, mNumBubblePerShader);
- mMeshActorForNoise = MeshActor::New( Mesh::New(meshDataForNoise) );
- mMeshActorForNoise.SetParentOrigin(ParentOrigin::TOP_LEFT);
- mEffectForNoise = BubbleEffect::New( mNumBubblePerShader );
- mEffectForNoise.SetMovementArea( mMovementArea );
- mEffectForNoise.SetEffectImage( mEffectImage );
- mMeshActorForNoise.SetShaderEffect( mEffectForNoise );
- mBubbleRoot.Add( mMeshActorForNoise );
-
// Create a cameraActor for the off screen render task.
mCameraActor = CameraActor::New(mMovementArea);
mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
sourceActor.SetParentOrigin(ParentOrigin::CENTER);
Stage::GetCurrent().Add( sourceActor );
- ColorAdjuster colorAdjuster = ColorAdjuster::New( hsvDelta, true /*ignore alpha to make bubble color always*/ );
+ ShaderEffect colorAdjuster = CreateColorAdjuster( hsvDelta, true /*ignore alpha to make bubble color always*/ );
sourceActor.SetShaderEffect( colorAdjuster );
RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
void BubbleEmitter::SetShapeImage( Image shapeImage )
{
- mCustomMaterial.SetDiffuseTexture( shapeImage );
+ mSamplerBubbleShape.SetImage( shapeImage );
}
void BubbleEmitter::SetBubbleScale( float scale )
{
- for(unsigned int i=0; i < mNumShader; i++ )
+ for(unsigned int i=0; i < mNumActor; i++ )
{
- mEffect[i].SetDynamicScale( scale );
+ (mBubbleActors[i])->SetDynamicScale( scale );
}
- mEffectForNoise.SetDynamicScale( scale );
}
void BubbleEmitter::SetBubbleDensity( unsigned int density )
else
{
mDensity = density;
- MeshData meshData;
- ConstructBubbleMesh( meshData, mNumBubblePerShader*mDensity);
- for(unsigned int i=0; i < mNumShader; i++ )
+ mMeshGeometry = CreateGeometry( mNumBubblePerActor*mDensity );
+ for(unsigned int i=0; i < mNumActor; i++ )
{
- mMesh[i].UpdateMeshData(meshData);
+ (mBubbleActors[i])->SetGeometry( mMeshGeometry );
}
}
}
+void BubbleEmitter::SetBlendMode( bool enable )
+{
+ if(enable)
+ {
+ // linear overlay
+ mMaterial.SetBlendFunc(BlendingFactor::SRC_ALPHA, BlendingFactor::ONE,
+ BlendingFactor::ZERO, BlendingFactor::ONE);
+ }
+ else
+ {
+ // using default blend func
+ mMaterial.SetBlendFunc( BlendingFactor::SRC_ALPHA, BlendingFactor::ONE_MINUS_SRC_ALPHA,
+ BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA );
+ }
+}
+
// clear the resources created for the off screen rendering
void BubbleEmitter::OnRenderFinished(RenderTask& source)
{
Actor sourceActor = source.GetSourceActor();
if( sourceActor )
{
- RenderableActor renderable = RenderableActor::DownCast( sourceActor );
+ ImageActor renderable = ImageActor::DownCast( sourceActor );
if( renderable )
{
renderable.RemoveShaderEffect();
}
}
-void BubbleEmitter::SetBlendMode( bool enable )
-{
- if(enable)
- {
- for(unsigned int i=0; i < mNumShader; i++ )
- {
- // linear overlay
- // TODO: if BlendColor would be public api from renderable actor, then can optimize the constant color
- mMeshActor[i].SetBlendFunc(BlendingFactor::SRC_ALPHA, BlendingFactor::ONE,
- BlendingFactor::ZERO, BlendingFactor::ONE);
- }
- mMeshActorForNoise.SetBlendFunc(BlendingFactor::SRC_ALPHA, BlendingFactor::ONE,
- BlendingFactor::ZERO, BlendingFactor::ONE);
- }
- else
- {
- for(unsigned int i=0; i < mNumShader; i++ )
- {
- // using default blend func
- mMeshActor[i].SetBlendFunc( BlendingFactor::SRC_ALPHA, BlendingFactor::ONE_MINUS_SRC_ALPHA,
- BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA );
- }
- mMeshActorForNoise.SetBlendFunc( BlendingFactor::SRC_ALPHA, BlendingFactor::ONE_MINUS_SRC_ALPHA,
- BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA );
- }
-}
-
void BubbleEmitter::EmitBubble( Animation& animation, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement )
{
- unsigned int curUniform = mCurrentUniform % mNumBubblePerShader;
- unsigned int groupIdx = mCurrentUniform / mNumBubblePerShader;
- SetBubbleParameter( mEffect[groupIdx], curUniform, emitPosition, direction, displacement);
- animation.AnimateTo( Property( mEffect[groupIdx], mEffect[groupIdx].GetPercentagePropertyName(curUniform) ),
+ unsigned int curUniform = mCurrentBubble % mNumBubblePerActor;
+ unsigned int groupIdx = mCurrentBubble / mNumBubblePerActor;
+ SetBubbleParameter( mBubbleActors[groupIdx], curUniform, emitPosition, direction, displacement);
+ animation.AnimateTo( (mBubbleActors[groupIdx])->GetPercentageProperty(curUniform),
1.f, AlphaFunction::LINEAR );
- if( mCurrentUniform % mNumShader == 0 )
- {
- unsigned int uniform = mCurrentUniform / mNumShader;
- SetBubbleParameter(mEffectForNoise, uniform, emitPosition, displacement);
- animation.AnimateTo( Property( mEffectForNoise, mEffectForNoise.GetPercentagePropertyName(uniform) ),
- 1.f, AlphaFunction::LINEAR );
- }
-
- mCurrentUniform = (mCurrentUniform + 1) % mTotalNumOfBubble;
-}
-
-void BubbleEmitter::StartExplosion( float duration, float multiple )
-{
- Animation animation = Animation::New( duration );
- for(unsigned int i=0; i < mNumShader; i++ )
- {
- animation.AnimateTo( Property( mEffect[i], mEffect[i].GetMagnificationPropertyName() ),
- multiple, AlphaFunction::EASE_OUT);
- }
- animation.AnimateTo( Property( mEffectForNoise, mEffectForNoise.GetMagnificationPropertyName() ),
- multiple, AlphaFunction::EASE_OUT);
- animation.Play();
-
- animation.FinishedSignal().Connect(this, &BubbleEmitter::OnExplosionFinished);
+ mCurrentBubble = (mCurrentBubble + 1) % mTotalNumOfBubble;
}
void BubbleEmitter::Restore()
{
- for(unsigned int i=0; i < mNumShader; i++ )
+ for(unsigned int i=0; i < mNumActor; i++ )
{
- mEffect[i].ResetParameters();
+ (mBubbleActors[i])->ResetProperties();
}
- mEffectForNoise.ResetParameters();
-}
-
-void BubbleEmitter::GenMaterial()
-{
- mCustomMaterial = Material::New("CustomMaterial");
- mCustomMaterial.SetOpacity(1.0f);
- mCustomMaterial.SetDiffuseColor(Color::WHITE);
- mCustomMaterial.SetAmbientColor(Vector4(0.0, 0.1, 0.1, 1.0));
- mCustomMaterial.SetMapU( Material::MAPPING_MODE_WRAP );
- mCustomMaterial.SetMapV( Material::MAPPING_MODE_WRAP );
- mCustomMaterial.SetDiffuseTexture( mShapeImage );
}
-void BubbleEmitter::AddVertex(MeshData::VertexContainer& vertices, Vector3 XYZ, Vector2 UV)
+Geometry BubbleEmitter::CreateGeometry( unsigned int numOfPatch )
{
- MeshData::Vertex meshVertex;
- meshVertex.x = XYZ.x;
- meshVertex.y = XYZ.y;
- meshVertex.z = XYZ.z;
- meshVertex.u = UV.x;
- meshVertex.v = UV.y;
- vertices.push_back(meshVertex);
-}
-
-void BubbleEmitter::AddTriangle(MeshData::FaceIndices& faces,
-size_t v0, size_t v1, size_t v2)
-{
- faces.push_back(v0);
- faces.push_back(v1);
- faces.push_back(v2);
-}
+ unsigned int numVertex = numOfPatch*4u;
+ std::vector<Vertex> vertexData;
+ vertexData.reserve( numVertex );
-void BubbleEmitter::ConstructBubbleMesh( MeshData& meshData, unsigned int numOfBubble)
-{
- MeshData::VertexContainer vertices;
- MeshData::FaceIndices faces;
- BoneContainer bones(0);
+ unsigned int numIndex = numOfPatch*6u;
+ Vector<unsigned int> indexData;
+ indexData.Reserve( numIndex );
- for(unsigned int index = 0; index < numOfBubble; index ++)
+ for(unsigned int i = 0; i < numOfPatch; i++)
{
float curSize = RandomRange(mBubbleSizeRange.x, mBubbleSizeRange.y);
- if(rand()%100 < 1)
- {
- curSize *= 2.f;
- }
- float depth = static_cast<float>( index );
- AddVertex( vertices, Vector3(0.f,0.f,depth), Vector2(0.f,0.f) );
- AddVertex( vertices, Vector3(0.f,curSize,depth), Vector2( 0.f,1.f ));
- AddVertex( vertices, Vector3(curSize,curSize,depth), Vector2(1.f,1.f) );
- AddVertex( vertices, Vector3(curSize,0.f,depth), Vector2(1.f,0.f) );
+
+ float index = static_cast<float>( i );
+ vertexData.push_back( Vertex( index, Vector2(0.f,0.f), Vector2(0.f,0.f) ) );
+ vertexData.push_back( Vertex( index, Vector2(0.f,curSize), Vector2(0.f,1.f) ) );
+ vertexData.push_back( Vertex( index, Vector2(curSize,curSize), Vector2(1.f,1.f) ) );
+ vertexData.push_back( Vertex( index, Vector2(curSize,0.f), Vector2(1.f,0.f) ) );
unsigned int idx = index * 4;
- AddTriangle( faces, idx, idx+1, idx+2);
- AddTriangle( faces, idx, idx+2, idx+3);
+ indexData.PushBack( idx );
+ indexData.PushBack( idx+1 );
+ indexData.PushBack( idx+2 );
+ indexData.PushBack( idx );
+ indexData.PushBack( idx+2 );
+ indexData.PushBack( idx+3 );
}
- meshData.SetData(vertices, faces, bones, mCustomMaterial);
- meshData.SetHasColor(false);
- meshData.SetHasTextureCoords(true);
-}
+ Property::Map vertexFormat;
+ vertexFormat["aIndex"] = Property::FLOAT;
+ vertexFormat["aPosition"] = Property::VECTOR2;
+ vertexFormat["aTexCoord"] = Property::VECTOR2;
+ PropertyBuffer vertices = PropertyBuffer::New( PropertyBuffer::STATIC, vertexFormat, numVertex );
+ vertices.SetData( &vertexData[0] );
-void BubbleEmitter::SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform,
- const Vector2& emitPosition, const Vector2& displacement )
-{
- int halfRange = displacement.x / 2;
- Vector2 randomVec(rand()%static_cast<int>(displacement.x) - halfRange, rand()%static_cast<int>(displacement.y) - halfRange);
- if(randomVec.y > 0.0f)
- {
- randomVec.y *= 0.33f;
- }
+ Property::Map indexFormat;
+ indexFormat["indices"] = Property::UNSIGNED_INTEGER;
+ PropertyBuffer indices = PropertyBuffer::New( PropertyBuffer::STATIC, indexFormat, numIndex );
+ indices.SetData( &indexData[0] );
- Vector4 startAndEndPos( emitPosition.x, emitPosition.y, emitPosition.x+randomVec.x, emitPosition.y+randomVec.y );
- effect.SetStartAndEndPosition( curUniform, startAndEndPos );
+ Geometry geometry = Geometry::New();
+ geometry.AddVertexBuffer( vertices );
+ geometry.SetIndexBuffer( indices );
- effect.SetPercentage( curUniform, 0.f);
+ return geometry;
}
-void BubbleEmitter::SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform,
+void BubbleEmitter::SetBubbleParameter( BubbleActorPtr bubbleActor, unsigned int curUniform,
const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement )
{
Vector2 dir(direction);
randomVec.y *= 0.33f;
}
Vector4 startAndEndPos( emitPosition.x, emitPosition.y, emitPosition.x+randomVec.x, emitPosition.y+randomVec.y );
- effect.SetStartAndEndPosition( curUniform, startAndEndPos );
+ bubbleActor->SetStartAndEndPosition( curUniform, startAndEndPos );
- effect.SetPercentage( curUniform, 0.f);
-}
-
-void BubbleEmitter::OnExplosionFinished( Animation& source )
-{
- Restore();
-}
-
-float BubbleEmitter::RandomRange(float f0, float f1)
-{
- return f0 + (rand() & 0xfff) * (f1-f0) * (1.0f/4095.0f);
+ bubbleActor->SetPercentage( curUniform, 0.f);
}
} // namespace Internal
#define __DALI_TOOLKIT_INTERNAL_BUBBLE_EMITTER_IMPL_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 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.
#include <dali/public-api/actors/camera-actor.h>
#include <dali/public-api/actors/image-actor.h>
#include <dali/public-api/common/stage.h>
+#include <dali/public-api/geometry/geometry.h>
#include <dali/public-api/images/frame-buffer-image.h>
#include <dali/public-api/render-tasks/render-task.h>
+#include <dali/public-api/shader-effects/sampler.h>
+#include <dali/public-api/shader-effects/material.h>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/bubble-effect/bubble-emitter.h>
-#include <dali-toolkit/public-api/shader-effects/bubble-effect/bubble-effect.h>
namespace Dali
{
namespace Internal
{
+class BubbleActor;
+typedef IntrusivePtr<BubbleActor> BubbleActorPtr;
+
/**
* BubbleEmitter implementation class.
*/
void EmitBubble( Animation& animation, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement );
/**
- * @copydoc Toolkit::BubbleEmitter::StartExplosion
- */
- void StartExplosion( float duration, float multiple );
-
- /**
* @copydoc Toolkit::BubbleEmitter::Restore
*/
void Restore();
void OnInitialize();
/**
+ * Create the geometry of a mesh.
+ * @param[in] numOfPatch The triangle number in the mesh is 2*numOfPatch; two triangles for each bubble.
+ * @return The mesh geometry.
+ */
+ Geometry CreateGeometry( unsigned int numOfPatch );
+
+ /**
* Callback function of the finished signal of off-screen render task.
* @param[in] source The render task used to create the color adjusted background image.
*/
void OnContextRegained();
/**
- * Generate the material object which is attached to the meshActor to describe its color, texture, texture mapping mode etc.
- */
- void GenMaterial();
-
- /**
- * Add a vertex to the mesh data.
- * @param[in] vertices The collection of vertices.
- * @param[in] XYZ The vertex position coordinates.
- * @param[in] UV The vertex texture coordinate.
- */
- void AddVertex(MeshData::VertexContainer& vertices, Vector3 XYZ, Vector2 UV);
-
- /**
- * Add a triangle to the mesh data.
- * @param[in] faces The collection od FaceIndex items.
- * @param[in] v0 The index of the first point of the triangle.
- * @param[in] v1 The index of the second point of the triangle.
- * @param[in] v3 The index of the first point of the triangle.
- */
- void AddTriangle(MeshData::FaceIndices& faces,size_t v0, size_t v1, size_t v2);
-
- /**
- * Create a new mesh.
- * @param[in] meshData The MeshData object which encompasses all the data required to describe and render the 3D mesh.
- * @param[in] numberOfBubble The triangle number in the meshData is 2*numOfBubble; two triangles for each bubble
- */
- void ConstructBubbleMesh( MeshData& meshData, unsigned int numOfBubble);
-
- /**
- * Set the uniform values to the shader effect to emit a bubble
- * @param[in] effect The BubbleEffect to render the current bubble
- * @param[in] curUniform The index of the uniform array in the shader
- * @param[in] emitPosition The start position of the bubble movement.
- * @param[in] displacement The displacement used to bound the moving distance of the bubble.
- */
- void SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform,
- const Vector2& emitPosition, const Vector2& displacement );
-
- /**
* Set the uniform values to the shader effect to emit a bubble
- * @param[in] effect The BubbleEffect to render the current bubble
+ * @param[in] bubbleActor The BubbleActor to render the current bubble
* @param[in] curUniform The index of the uniform array in the shader
* @param[in] emitPosition The start position of the bubble movement.
* @param[in] direction The direction used to constrain the bubble to move in an adjacent direction around it.
* @param[in] displacement The displacement used to bound the moving distance of the bubble.
*/
- void SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform,
+ void SetBubbleParameter( BubbleActorPtr bubbleActor, unsigned int curUniform,
const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement );
- /**
- * Callback function of the explosion animation finished signal to reset the shader parameters
- * @param[in] source The explosion animation.
- */
- void OnExplosionFinished( Animation& source );
-
- /**
- * Return a random value between the given interval.
- * @param[in] f0 The low bound
- * @param[in] f1 The up bound
- * @return A random value between the given interval
- */
- float RandomRange(float f0, float f1);
-
private:
- Vector2 mMovementArea; ///< The size of the bubble moving area, usually the same size as the background image actor.
- Image mShapeImage; ///< The alpha channnel of this texture defines the bubble shape.
Actor mBubbleRoot; ///<The bubble root actor. Need to add it to stage to get the bubbles rendered.
-
- unsigned int mNumBubblePerShader; ///< How many bubbles for each BubbleEffect shader.
- unsigned int mNumShader; ///< How many BubbleEffect shaders are used.
- unsigned int mTotalNumOfBubble; ///< mNumBubblePerShader*mNumShader.
- bool mRenderTaskRunning; ///< If the background render task is currently running
-
- Vector2 mBubbleSizeRange; ///< The bubble size range.
-
- std::vector<Mesh> mMesh; ///< The mesh vector, each mesh is used to create a meshActor which applies a BubbleEffect.
- std::vector<MeshActor> mMeshActor; ///< The meshActor vector, its size is mNumShader.
- MeshActor mMeshActorForNoise; ///< An Extra mesh data to emit bubbles which emit bubble in totally random angle.
- Material mCustomMaterial; ///< The material object which is attached to the meshActor to describe its color, texture, texture mapping mode etc.
-
- std::vector<BubbleEffect> mEffect; ///< The bubbleEffect vector, corresponding to the mMeshActoe vector.
- BubbleEffect mEffectForNoise; ///< The extra bubbleEffect, corresponding to the mMeshActorForNoise.
-
- unsigned int mCurrentUniform; ///< Keep track of the uniform index for the newly emitted bubble
-
- Vector3 mHSVDelta; ///< The HSV difference used to adjust the background image color.
+ Image mShapeImage; ///< The alpha channnel of this texture defines the bubble shape.
Image mBackgroundImage; ///< The original background image
FrameBufferImage mEffectImage; ///< The image stores the adjusted color of the background image.The bubbles pick color from this image.
CameraActor mCameraActor; ///< The render task views the scene from the perspective of this actor.
+ Sampler mSamplerBackground; ///< The sampler which provides the background image to material
+ Sampler mSamplerBubbleShape; ///< The sampler which provides the bubble shape image to material
+ Geometry mMeshGeometry; ///< The mesh geometry which contains the vertices and indices data
+ Material mMaterial; ///< The material which controls the bubble display
+ std::vector<BubbleActorPtr> mBubbleActors; ///< The meshActor vector, its size is mNumShader.
+
+ Vector2 mMovementArea; ///< The size of the bubble moving area, usually the same size as the background image actor.
+ Vector2 mBubbleSizeRange; ///< The size range of the bubbles; x component is the low bound, and y component is the up bound.
+ Vector3 mHSVDelta; ///< The HSV difference used to adjust the background image color.
+
+ unsigned int mNumBubblePerActor; ///< How many bubbles for each BubbleActor.
+ unsigned int mNumActor; ///< How many BubbleActors are used.
unsigned int mDensity; ///< How many bubbles will emit at each time, they are controlled by same uniforms in the shader.
+ unsigned int mTotalNumOfBubble; ///< mNumBubblePerShader*mNumShader.
+ unsigned int mCurrentBubble; ///< Keep track of the index for the newly emitted bubble
+
+ bool mRenderTaskRunning; ///< If the background render task is currently running
};
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_COLOR_ADJUSTER_H_
+#define __DALI_TOOLKIT_INTERNAL_COLOR_ADJUSTER_H_
+
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <dali/public-api/math/vector3.h>
+#include <dali/public-api/shader-effects/shader-effect.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+* Creates a new ColorAdjuster effect.
+* ColorAdjuster is a custom shader effect to adjust the image color in HSV space.
+* @param[in] hsvDelta The color difference to apply to the HSV channel.
+* @param[in] ignoreAlpha If true, the result color will be opaque even though source has alpha value
+* @return A handle to a newly allocated Dali resource.
+*/
+inline ShaderEffect CreateColorAdjuster( const Vector3& hsvDelta, bool ignoreAlpha = false )
+{
+ std::string fragmentShader = DALI_COMPOSE_SHADER(
+ precision highp float;\n
+ uniform vec3 uHSVDelta;\n
+ uniform float uIgnoreAlpha;\n
+ float rand(vec2 co) \n
+ {\n
+ return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); \n}
+ \n
+ vec3 rgb2hsv(vec3 c)\n
+ {\n
+ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n
+ \n
+ float d = q.x - min(q.w, q.y);\n
+ float e = 1.0e-10;\n
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n
+ }\n
+ vec3 hsv2rgb(vec3 c)\n
+ {\n
+ vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n
+ }\n
+ void main() {\n
+ vec4 color = texture2D(sTexture, vTexCoord); \n
+ vec3 hsvColor = rgb2hsv( color.rgb );\n
+ // modify the hsv Value
+ hsvColor += uHSVDelta * rand(vTexCoord); \n
+ // if the new vale exceeds one, then decrease it
+ hsvColor -= max(hsvColor*2.0 - vec3(2.0), 0.0);\n
+ // if the new vale drops below zero, then increase it
+ hsvColor -= min(hsvColor*2.0, 0.0);\n
+ color.rgb = hsv2rgb( hsvColor ); \n
+ // uIgnoreAlpha decide the result alpha will be 1.0 or source's alpha
+ color.a += uIgnoreAlpha;\n
+ gl_FragColor = color; \n
+ }\n
+ );
+
+ ShaderEffect shaderEffect = ShaderEffect::New("", fragmentShader);
+ shaderEffect.SetUniform( "uHSVDelta", hsvDelta );
+ shaderEffect.SetUniform( "uIgnoreAlpha", ignoreAlpha?1.0f:0.0f );
+
+ return shaderEffect;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* __DALI_TOOLKIT_INTERNAL_COLOR_ADJUSTER_H_ */
$(toolkit_src_dir)/builder/replacement.cpp \
$(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \
$(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \
+ $(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \
+ $(toolkit_src_dir)/controls/bubble-effect/bubble-actor.cpp \
$(toolkit_src_dir)/controls/buttons/button-impl.cpp \
$(toolkit_src_dir)/controls/buttons/check-box-button-impl.cpp \
$(toolkit_src_dir)/controls/buttons/push-button-impl.cpp \
GetImpl(*this).EmitBubble( animation, emitPosition, direction, displacement );
}
-void BubbleEmitter::StartExplosion( float duration, float multiple )
-{
- GetImpl(*this).StartExplosion( duration, multiple );
-}
-
void BubbleEmitter::Restore()
{
GetImpl(*this).Restore();
/**
* @brief Set the density of the bubble.
*
- * Ideally every bubble's moving track is controlled by different uniforms in BubbleEffect shaders.
+ * Ideally every bubble's moving track is controlled by different uniforms in shader.
* To increase the density, 'density' number of bubbles are sharing one group of uniforms, but with random offsets between these bubbles.
- * The available density is one to nine. The default density is five.
+ * The available densities are one to nine only. The default value is five.
* By set the density bigger than one, instead of emit one bubble each time, a 'density' number of bubbles are emitted.
* @param[in] density The density of the bubble.
*/
void EmitBubble( Animation& animation, const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement );
/**
- * @brief Start an animation to enlarge every activated bubble's size and moving speed.
- *
- * @param[in] duration The duration of the animation
- * @param[in] multiple The bubble size and moving speed will be increased gradually to multiple speed during the animation.
- */
- void StartExplosion( float duration, float multiple );
-
- /**
* @brief Reset all the parameters controlling the bubbles after animation.
*/
void Restore();
$(public_api_src_dir)/controls/control-impl.cpp \
$(public_api_src_dir)/controls/control.cpp \
$(public_api_src_dir)/controls/alignment/alignment.cpp \
+ $(public_api_src_dir)/controls/bubble-effect/bubble-emitter.cpp \
$(public_api_src_dir)/controls/buttons/button.cpp \
$(public_api_src_dir)/controls/buttons/check-box-button.cpp \
$(public_api_src_dir)/controls/buttons/push-button.cpp \