Cocos2d-x集成LiquidFun及Liquid Shader流体纹理贴图

http://blog.csdn.net/final5788/article/details/49281961博文地址:Cocos集成LiquidFun——流体shader 纹理贴图http://blog.csdn.net/final5788/article/details/49281961
b2_waterParticle:

b2_elasticParticle:

http://blog.csdn.net/final5788/article/details/49200947 参考

创建b2ParticleSystem
b2ParticleSystemDef particleSystemDef; particleSystemDef.dampingStrength = 0.2f;//阻尼 particleSystemDef.radius = 0.1f;//每个粒子的半径,半径越小模拟程度越高,但同时对硬件性能要求更高 _particleSystem = _world->CreateParticleSystem(&particleSystemDef);//创建b2ParticleSystem _particleSystem->SetGravityScale(0.4f);//重力比例 _particleSystem->SetDensity(0.8f);//粒子的密度 b2ParticleGroupDef pd;//粒子组 pd.position.Set(s.width / 2 / PTM_RATIO, s.height / 2 / PTM_RATIO); pd.flags = b2ParticleFlag::b2_waterParticle; //pd.groupFlags = b2ParticleGroupFlag::b2_rigidParticleGroup; //粒子组的形状,如下粒子组形状为5*6的box(盒子),通俗讲,即创建出一盒子的粒子 b2PolygonShape shape2; shape2.SetAsBox(5.0f, 6.0f, b2Vec2(0.0f, 0.0f), 0.0); pd.shape = &shape2; _particleSystem->CreateParticleGroup(pd); //LiquidSprite是自定义类,用于绘制贴图 auto ls = LiquidSprite::create(_particleSystem, PTM_RATIO);
this->addChild(ls);

LiquidSprite类的实现:

LiquidSprite::create(_particleSystem, PTM_RATIO);
要传入两个参数,_particleSystem是粒子系统,可用其获取所有粒子的位置、颜色等信息,然后传入Shader作为坐标顶点(a_position)、纹理坐标(a_texCoord)进行着色。
PTM_RATIO是物理坐标与像素坐标的比例关系。

Shader:
vs部分:liquid.vert
attribute vec4 a_position;//需传入所有粒子的坐标 attribute vec2 a_texCoord;//纹理贴图的纹理坐标 uniform vec4 u_color;//颜色混合 uniform
float u_pointSize;//传入粒子的大小 uniform vec2 u_texSize; #ifdef GL_ES varying lowp vec4 v_fragmentColor; varying lowp vec2 v_texCoord; #else varying vec4 v_fragmentColor; varying vec2 v_texCoord; #endif
void main() { gl_Position = CC_MVPMatrix * a_position; gl_PointSize = u_pointSize; v_fragmentColor = u_color; //vec2 newCoord = vec2(clamp(a_texCoord.x, 0.0, 1.0), clamp(a_texCoord.y, 0.0, 1.0)); v_texCoord = a_texCoord;//vec2(a_position.x / u_texSize.x, 1 - a_position.y / u_texSize.y); }

PS部分:liquid.frag
#ifdef GL_ES varying lowp vec4 v_fragmentColor; varying lowp vec2 v_texCoord; #else varying vec4 v_fragmentColor; varying vec2 v_texCoord; #endif uniform sampler2D u_texture;//传入Texture2D 纹理贴图
void main() { gl_FragColor = texture2D(u_texture, v_texCoord)*v_fragmentColor;//将纹理采样颜色与v_fragmentColor混合,然后输出 }

创建并应用shader:
auto uTexture = Director::getInstance()->getTextureCache()->addImage(“HelloWorld.png”); auto texSize = uTexture->getContentSize(); auto program = GLProgram::createWithFilenames(“shader/liquid.vert”, “shader/liquid.frag”); auto pState = GLProgramState::getOrCreateWithGLProgram(program); pState->setUniformTexture(“u_texture”, uTexture);//纹理贴图传入shader //pState->setUniformVec2(“u_texSize”, texSize);//纹理的大小 pState->setUniformVec4(“u_color”, Vec4(1, 1, 1, 0.7)); //要进行混合的颜色 pState->setUniformFloat(“u_pointSize”, _pSystem->GetRadius()_ratio2);//绘制点的大小,粒子半径比例2即粒子直径
this->setGLProgramState(pState);//应用Shader

将顶点位置传入Shader:
auto vertsCount = _pSystem->GetParticleCount();//b2ParticleSystem函数,获取粒子数量 auto verts = _pSystem->GetPositionBuffer();//b2ParticleSystem函数,获取粒子位置数组 //顶点转换
for (
int i = 0; i < vertsCount; i++) { b2Vec2 vec = verts*; ** posVerts.push_back(Vec2(
int*(vec.x * _ratio),
int(vec.y*_ratio))); texCoords.push_back(Vec2(
int(vec.x * _ratio) / texSize.width, 1 -
int(vec.y * _ratio) / texSize.height)); } pState->setVertexAttribPointer(“a_position”, 2, GL_FLOAT, GL_FALSE,
sizeof(Vec2), &posVerts);//传入shader pState->setVertexAttribPointer(“a_texCoord”, 2, GL_FLOAT, GL_FALSE,
sizeof(Vec2), &texCoords);//传入shader scheduleUpdate();//update()函数用于实时获取粒子位置数组并更新顶点位置
*update函数

void
LiquidSprite::update(
float dt) {
if (!posVerts.empty()) { posVerts.clear();//先清空posVerts } auto vertsCount = _pSystem->GetParticleCount(); auto verts = _pSystem->GetPositionBuffer();//实时获取粒子位置数组
for (
int i = 0; i < vertsCount; i++) { b2Vec2 vec = verts*; ** posVerts.push_back(Vec2(
int*(vec.x * _ratio),
int(vec.y*_ratio)));//更新顶点 } } ***
使用GL_POINTS模式进行绘制:***glDrawArrays(GL_POINTS, 0, posVerts.size());

源码下载:http://yun.baidu.com/s/1pJEdz8B***