opengles实现简单的粒子系统

效果图




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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值