/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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 "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/rendering/texture.h>
+#include <dali/public-api/rendering/shader.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/shader-effects/bubble-effect/color-adjuster.h>
+#include <dali-toolkit/internal/controls/bubble-effect/bubble-effect.h>
+#include <dali-toolkit/internal/controls/bubble-effect/bubble-renderer.h>
+
+namespace
+{
+struct Vertex
+{
+ Vertex()
+ : index( 0.0f ), position(), textureCoord()
+ {
+ }
+
+ Vertex( float index, const Dali::Vector2& position, const Dali::Vector2& textureCoord )
+ : index( index ), position( position ), textureCoord( textureCoord )
+ {
+ }
+
+ float index;
+ Dali::Vector2 position;
+ Dali::Vector2 textureCoord;
+};
+
+
+/**
+* Return a random value between the given interval.
+* @param[in] f0 The low bound
+* @param[in] f1 The up bound
+* @param[in] seed The seed to genergate random number
+* @return A random value between the given interval
+*/
+float RandomRange(float f0, float f1, unsigned int& seed)
+{
+ return f0 + (rand_r(&seed) & 0xfff) * (f1 - f0) * (1.0f / 4095.0f);
+}
+
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+ attribute mediump vec2 aPosition;\n
+ attribute mediump vec2 aTexCoord;\n
+ uniform mediump vec3 uSize;\n
+ uniform mediump mat4 uMvpMatrix;\n
+ varying mediump vec2 vTexCoord;\n
+ \n
+
+ void main()\n
+ {\n
+ gl_Position = uMvpMatrix * vec4(aPosition*uSize.xy,0.0,1.0);
+ vTexCoord = aTexCoord;\n
+ }\n
+);
+
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+ precision highp float;\n
+ uniform vec3 uHSVDelta;\n
+ varying mediump vec2 vTexCoord;\n
+ uniform sampler2D sTexture;\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 = vec4( hsv2rgb( hsvColor ), 1.0 ); \n
+ gl_FragColor = color; \n
+ }\n
+ );
+
+Dali::Geometry CreateTexturedQuad()
+{
+ struct Vertex
+ {
+ Dali::Vector2 position;
+ Dali::Vector2 texCoord;
+ };
+
+ static const Vertex data[] = {{ Dali::Vector2( -0.5f, -0.5f ), Dali::Vector2( 0.0f, 0.0f ) },
+ { Dali::Vector2( 0.5f, -0.5f ), Dali::Vector2( 1.0f, 0.0f ) },
+ { Dali::Vector2( -0.5f, 0.5f ), Dali::Vector2( 0.0f, 1.0f ) },
+ { Dali::Vector2( 0.5f, 0.5f ), Dali::Vector2( 1.0f, 1.0f ) }};
+
+ //Create a vertex buffer for vertex positions and texture coordinates
+ Dali::PropertyBuffer vertexBuffer = Dali::PropertyBuffer::New( Dali::Property::Map()
+ .Add( "aPosition", Dali::Property::VECTOR2 )
+ .Add( "aTexCoord", Dali::Property::VECTOR2 ) );
+ vertexBuffer.SetData( data, 4u );
+
+ //Create the geometry
+ Dali::Geometry geometry = Dali::Geometry::New();
+ geometry.AddVertexBuffer( vertexBuffer );
+ geometry.SetType(Dali::Geometry::TRIANGLE_STRIP );
+
+ return geometry;
+}
+
+}
namespace Dali
{
namespace Internal
{
BubbleEmitter::BubbleEmitter( const Vector2& movementArea,
- Image shapeImage,
+ Texture shapeTexture,
unsigned int maximumNumberOfBubble,
const Vector2& bubbleSizeRange )
-: Control( REQUIRES_TOUCH_EVENTS ),
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
+ mShapeTexture( shapeTexture ),
mMovementArea( movementArea ),
- mShapeImage( shapeImage ),
- mTotalNumOfBubble( maximumNumberOfBubble ),
- mRenderTaskRunning(false),
mBubbleSizeRange( bubbleSizeRange ),
- mCurrentUniform( 0 ),
- mDensity( 5 )
+ mDensity( 5 ),
+ mTotalNumOfBubble( maximumNumberOfBubble ),
+ mCurrentBubble( 0 ),
+ mRandomSeed( 0 ),
+ mRenderTaskRunning(false)
{
- // Calculate how many BubbleEffect shaders are required
+ // Calculate how many shaders are required
if( mTotalNumOfBubble>100 )
{
- mNumBubblePerShader = 100;
- mNumShader = mTotalNumOfBubble / 100;
+ mNumBubblePerRenderer = 100;
+ mNumRenderer = mTotalNumOfBubble / 100;
+ if( mNumRenderer*mNumBubblePerRenderer < mTotalNumOfBubble )
+ {
+ mNumRenderer++;
+ mNumBubblePerRenderer = mTotalNumOfBubble / mNumRenderer+1;
+ mTotalNumOfBubble = mNumRenderer * mNumBubblePerRenderer;
+ }
}
else
{
- mNumBubblePerShader = mTotalNumOfBubble;
- mNumShader = 1;
+ mNumBubblePerRenderer = mTotalNumOfBubble;
+ mNumRenderer = 1;
}
+
+ mRandomSeed = time(NULL);
}
BubbleEmitter::~BubbleEmitter()
}
Toolkit::BubbleEmitter BubbleEmitter::New( const Vector2& winSize,
- Image shapeImage,
+ Texture shapeTexture,
unsigned int maximumNumberOfBubble,
const Vector2& bubbleSizeRange )
{
// Create the implementation
- IntrusivePtr<BubbleEmitter> internalBubbleEmitter ( new BubbleEmitter( winSize, shapeImage,
+ IntrusivePtr<BubbleEmitter> internalBubbleEmitter ( new BubbleEmitter( winSize, shapeTexture,
maximumNumberOfBubble,bubbleSizeRange ) );
// Pass ownership to Toolkit::BubbleEmitter handle
mBubbleRoot = Actor::New();
mBubbleRoot.SetSize(mMovementArea);
- // 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 );
+ // Prepare the frame buffer to store the color adjusted background texture
+ Vector2 imageSize = Vector2( mMovementArea.width/4.f, mMovementArea.height/4.f );
+ mFrameBuffer = FrameBuffer::New( imageSize.x, imageSize.y, 0 );
+ mEffectTexture = Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, imageSize.x, imageSize.y );
+ mFrameBuffer.AttachColorTexture( mEffectTexture );
- // Generate the material object, which is used by all meshActors
- GenMaterial();
+ // Generate the geometry, which is used by all bubbleActors
+ mMeshGeometry = CreateGeometry( mNumBubblePerRenderer*mDensity );
- mMesh.resize( mNumShader );
- mMeshActor.resize( mNumShader );
- mEffect.resize( mNumShader );
+ Shader bubbleShader = CreateBubbleShader( mNumBubblePerRenderer );
- // 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++ )
+ mTextureSet = TextureSet::New();
+ mTextureSet.SetTexture( 0u, mEffectTexture );
+ mTextureSet.SetTexture( 1u, mShapeTexture );
+
+ // Create the renderers to render the bubbles
+ mBubbleRenderers.resize( mNumRenderer );
+ for(unsigned int i=0; i < mNumRenderer; i++ )
{
- mMesh[i] = Mesh::New( meshData );
- mMeshActor[i] = MeshActor::New( mMesh[i] );
- mMeshActor[i].SetAffectedByLighting( false );
- mMeshActor[i].SetParentOrigin(ParentOrigin::TOP_LEFT);
- mEffect[i] = BubbleEffect::New( mNumBubblePerShader, mShapeImage.GetFilename() );
- mEffect[i].SetEffectImage( mEffectImage );
- mEffect[i].SetMovementArea( mMovementArea );
- mMeshActor[i].SetShaderEffect( mEffect[i] );
- mBubbleRoot.Add( mMeshActor[i] );
+ mBubbleRenderers[i].Initialize( mNumBubblePerRenderer, mMovementArea, mMeshGeometry, mTextureSet, bubbleShader );
+ mBubbleRoot.AddRenderer( mBubbleRenderers[i].GetRenderer() );
}
- // 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.SetAffectedByLighting( false );
- mMeshActorForNoise.SetParentOrigin(ParentOrigin::TOP_LEFT);
- mEffectForNoise = BubbleEffect::New( mNumBubblePerShader, mShapeImage.GetFilename() );
- 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);
return mBubbleRoot;
}
-void BubbleEmitter::SetBackground( Image bgImage, const Vector3& hsvDelta )
+void BubbleEmitter::SetBackground( Texture bgTexture, const Vector3& hsvDelta )
{
- mBackgroundImage = bgImage;
+ mBackgroundTexture = bgTexture;
mHSVDelta = hsvDelta;
- ImageActor sourceActor = ImageActor::New( bgImage );
+ //Create RenderTask source actor
+ Actor sourceActor = Actor::New();
sourceActor.SetSize( mMovementArea );
sourceActor.SetParentOrigin(ParentOrigin::CENTER);
+ sourceActor.RegisterProperty( "uHSVDelta", hsvDelta );
Stage::GetCurrent().Add( sourceActor );
- ColorAdjuster colorAdjuster = ColorAdjuster::New( hsvDelta, true /*ignore alpha to make bubble color always*/ );
- sourceActor.SetShaderEffect( colorAdjuster );
+ //Create renderer
+ Dali::Geometry geometry = CreateTexturedQuad();
+ Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+ Renderer renderer = Renderer::New( geometry, shader );
+ TextureSet textureSet = TextureSet::New();
+ textureSet.SetTexture(0u, bgTexture );
+ renderer.SetTextures( textureSet );
+ sourceActor.AddRenderer( renderer );
RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
RenderTask task = taskList.CreateTask();
task.SetExclusive(true);
task.SetCameraActor(mCameraActor);
task.GetCameraActor().SetInvertYAxis(true);
- task.SetTargetFrameBuffer( mEffectImage );
+ task.SetFrameBuffer( mFrameBuffer );
task.FinishedSignal().Connect(this, &BubbleEmitter::OnRenderFinished);
mRenderTaskRunning = true;
}
-void BubbleEmitter::SetShapeImage( Image shapeImage )
+void BubbleEmitter::SetBubbleShape( Texture shapeTexture )
{
- mCustomMaterial.SetDiffuseTexture( shapeImage );
-
- //Get pixel width of the shape
- float width = Image::GetImageSize(shapeImage.GetFilename()).width;
-
- for(unsigned int i=0; i < mNumShader; i++ )
- {
- mEffect[i].SetShapeImageWidth(width);
- }
- mEffectForNoise.SetShapeImageWidth(width);
+ mTextureSet.SetTexture( 1, shapeTexture );
}
void BubbleEmitter::SetBubbleScale( float scale )
{
- for(unsigned int i=0; i < mNumShader; i++ )
+ for(unsigned int i=0; i < mNumRenderer; i++ )
{
- mEffect[i].SetDynamicScale( scale );
+ mBubbleRenderers[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( mNumBubblePerRenderer*mDensity );
+ for(unsigned int i=0; i < mNumRenderer; i++ )
{
- mMesh[i].UpdateMeshData(meshData);
+ mBubbleRenderers[i].SetGeometry( mMeshGeometry );
}
}
}
{
mRenderTaskRunning = false;
Actor sourceActor = source.GetSourceActor();
- if( sourceActor )
- {
- RenderableActor renderable = RenderableActor::DownCast( sourceActor );
- if( renderable )
- {
- renderable.RemoveShaderEffect();
- }
- }
-
Stage stage = Stage::GetCurrent();
stage.Remove(sourceActor);
stage.GetRenderTaskList().RemoveTask(source);
// and trigger re-draw if not already running
if( ! mRenderTaskRunning )
{
- SetBackground( mBackgroundImage, mHSVDelta );
- }
-}
-
-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 );
+ SetBackground( mBackgroundTexture, mHSVDelta );
}
}
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) ),
- 1.f, AlphaFunctions::Linear );
-
- if( mCurrentUniform % mNumShader == 0 )
- {
- unsigned int uniform = mCurrentUniform / mNumShader;
- SetBubbleParameter(mEffectForNoise, uniform, emitPosition, displacement);
- animation.AnimateTo( Property( mEffectForNoise, mEffectForNoise.GetPercentagePropertyName(uniform) ),
- 1.f, AlphaFunctions::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, AlphaFunctions::EaseOut);
- }
- animation.AnimateTo( Property( mEffectForNoise, mEffectForNoise.GetMagnificationPropertyName() ),
- multiple, AlphaFunctions::EaseOut);
- animation.Play();
+ unsigned int curUniform = mCurrentBubble % mNumBubblePerRenderer;
+ unsigned int groupIdx = mCurrentBubble / mNumBubblePerRenderer;
+ SetBubbleParameter( mBubbleRenderers[groupIdx], curUniform, emitPosition - Vector2(mMovementArea.x*0.5f,mMovementArea.y*0.5f), direction, displacement);
+ animation.AnimateTo( mBubbleRenderers[groupIdx].GetPercentageProperty(curUniform),
+ 1.f, AlphaFunction::LINEAR );
- 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 < mNumRenderer; i++ )
{
- mEffect[i].ResetParameters();
+ mBubbleRenderers[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)
-{
- 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)
+Geometry BubbleEmitter::CreateGeometry( unsigned int numOfPatch )
{
- faces.push_back(v0);
- faces.push_back(v1);
- faces.push_back(v2);
-}
+ unsigned int numVertex = numOfPatch*4u;
+ 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 short> 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) );
-
- unsigned int idx = index * 4;
- AddTriangle( faces, idx, idx+1, idx+2);
- AddTriangle( faces, idx, idx+2, idx+3);
+ float halfSize = RandomRange(mBubbleSizeRange.x, mBubbleSizeRange.y, mRandomSeed) * 0.5f;
+
+ float index = static_cast<float>( i );
+ vertexData.PushBack( Vertex( index, Vector2(-halfSize,-halfSize),Vector2(0.f,0.f) ) );
+ vertexData.PushBack( Vertex( index, Vector2(-halfSize, halfSize), Vector2(0.f,1.f) ) );
+ vertexData.PushBack( Vertex( index, Vector2( halfSize, halfSize), Vector2(1.f,1.f) ) );
+ vertexData.PushBack( Vertex( index, Vector2( halfSize,-halfSize), Vector2(1.f,0.f) ) );
+
+ unsigned short idx = index * 4;
+ 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);
-}
-
-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 vertexFormat;
+ vertexFormat["aIndex"] = Property::FLOAT;
+ vertexFormat["aPosition"] = Property::VECTOR2;
+ vertexFormat["aTexCoord"] = Property::VECTOR2;
+ PropertyBuffer vertices = PropertyBuffer::New( vertexFormat );
+ vertices.SetData( &vertexData[0], numVertex );
- 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( &indexData[0], numIndex );
- effect.SetPercentage( curUniform, 0.f);
+ return geometry;
}
-void BubbleEmitter::SetBubbleParameter( BubbleEffect& effect, unsigned int curUniform,
+void BubbleEmitter::SetBubbleParameter( BubbleRenderer& bubbleRenderer, unsigned int curUniform,
const Vector2& emitPosition, const Vector2& direction, const Vector2& displacement )
{
Vector2 dir(direction);
int halfRange = displacement.x / 2;
// for the y coordinate, always negative, so bubbles always go upwards
- Vector2 randomVec(rand()%static_cast<int>(displacement.x) - halfRange, -rand()%static_cast<int>(displacement.y));
+ Vector2 randomVec(rand_r(&mRandomSeed) % static_cast<int>(displacement.x) - halfRange, -rand_r(&mRandomSeed) % static_cast<int>(displacement.y));
dir.Normalize();
randomVec.x -= dir.x*halfRange;
randomVec.y *= 1.0f - fabsf(dir.x)*0.33f;
randomVec.y *= 0.33f;
}
Vector4 startAndEndPos( emitPosition.x, emitPosition.y, emitPosition.x+randomVec.x, emitPosition.y+randomVec.y );
- effect.SetStartAndEndPosition( curUniform, startAndEndPos );
-
- effect.SetPercentage( curUniform, 0.f);
-}
+ bubbleRenderer.SetStartAndEndPosition( curUniform, startAndEndPos );
-void BubbleEmitter::OnExplosionFinished( Animation& source )
-{
- Restore();
-}
-
-float BubbleEmitter::RandomRange(float f0, float f1)
-{
- return f0 + (rand() & 0xfff) * (f1-f0) * (1.0f/4095.0f);
+ bubbleRenderer.SetPercentage( curUniform, 0.f);
}
} // namespace Internal