效果图
shader实现
const char* vs =
{
"uniform float u_time;"
"uniform vec3 u_centerPosition;"
"attribute float _lifetime;"
"attribute vec3 _startPosition;"
"attribute vec3 _endPosition;"
"varying float v_lifetime;"
"void main()"
"{"
" if(u_time<=_lifetime)"
"{"
" gl_Position.xyz=_startPosition+(u_time*_endPosition);"//最终位置=开始位置+位移*时间
" gl_Position.xyz+=u_centerPosition;"//下一波粒子运动的中心点位置
" gl_Position.w=1.0;"
"}"
"else"
" gl_Position=vec4(-1000,-1000,0,0);"
"v_lifetime=1.0-(u_time/_lifetime);"//根据运动时间逐渐减少其生存时间
"v_lifetime=clamp(v_lifetime,0.0,1.0);"//clamp函数原型 clamp(x, min, max) 把输入值限制在[min, max]范围内。
"gl_PointSize=40.0;"//"gl_PointSize=(v_lifetime*v_lifetime)*40.0;" 点精灵的大小不同的系统有不同的规定,要根据函数查询
"}"
};
const char* ps =
{
"precision mediump float;"//指定float的精度
"uniform vec4 _color;"
"varying float v_lifetime;"
"uniform sampler2D _texture;"
"void main()"
"{"
"vec4 texColor;"
"texColor=texture2D(_texture,gl_PointCoord);"
"gl_FragColor=vec4(_color)*texColor;"
"gl_FragColor.a*=v_lifetime;"//通过其生存时间逐渐改变其透明度,直至消失
"}"
};
初始化;
//随机生成每个粒子的存活时间,起始空间坐标
srand(0);
memset(_particleData,0,sizeof(_particleData));
for (int i = 0; i <NUM_PARTICLES; i++)
{
//数组首地址
float *particleData = &_particleData[i*PARTICLE_SIZE];
//每个粒子的存活时间
(*particleData++) = ((float)(rand() % 10000) / 10000.0f);
//每个粒子的结束位置 (x,y,z)
(*particleData++) = ((float)(rand() % 10000) / 5000.0f) - 1.0f;
(*particleData++) = ((float)(rand() % 10000) / 5000.0f) - 1.0f;
(*particleData++) = ((float)(rand() % 10000) / 5000.0f) - 1.0f;
//每个粒子的开始位置(x,y,z)
(*particleData++) = ((float)(rand() % 10000) / 40000.0f) - 0.125f;
(*particleData++) = ((float)(rand() % 10000) / 40000.0f) - 0.125f;
(*particleData++) = ((float)(rand() % 10000) / 40000.0f) - 0.125f;
}
渲染函数:
virtual void render(float deltaTime)
{
glViewport(0,0,_width,_height);
glClear(GL_COLOR_BUFFER_BIT);
_shader.begin();
_shader._timer += deltaTime;
//当运动时间累积大于等于1.0时,随机生成一个中心点坐标和rgba像素点颜色坐标
//时间清零,这样就会产生下一波粒子爆炸效果
if (_shader._timer>=1.0f)
{
float centerPos[3];
float color[4];
_shader._timer = 0.0f;
centerPos[0] = ((float)(rand() % 10000) / 10000.0f) - 0.5f;
centerPos[1] = ((float)(rand() % 10000) / 10000.0f) - 0.5f;
centerPos[2] = ((float)(rand() % 10000) / 10000.0f) - 0.5f;
glUniform3fv(_shader._centerPositionLoc,1,¢erPos[0]);
color[0] = ((float)(rand() % 10000) / 20000.0f) + 0.5f;
color[1] = ((float)(rand() % 10000) / 20000.0f) + 0.5f;
color[2] = ((float)(rand() % 10000) / 20000.0f) + 0.5f;
color[3] = 0.5;
glUniform4fv(_shader._colorLoc,1,&color[0]);
}
glUniform1f(_shader._timeLoc,_shader._timer);
glVertexAttribPointer(_shader._lifetimeLoc,1,GL_FLOAT,GL_FALSE,PARTICLE_SIZE*sizeof(GLfloat),_particleData);
glVertexAttribPointer(_shader._endPositionLoc,3,GL_FLOAT,GL_FALSE,PARTICLE_SIZE*sizeof(GLfloat),&_particleData[1]);
glVertexAttribPointer(_shader._startPositionLoc,3,GL_FLOAT,GL_FALSE,PARTICLE_SIZE*sizeof(GLfloat),&_particleData[4]);
glUniform1i(_shader._samplerLoc,0);
glBindTexture(GL_TEXTURE_2D,_sprit);
glDrawArrays(GL_POINTS,0,NUM_PARTICLES);
_shader.end();
}
完整项目下载地址:http://download.csdn.net/detail/hb707934728/9845935