粒子系统的简单实现
来源:互联网 发布:联通网络模式选哪个 编辑:程序博客网 时间:2024/04/30 07:02
粒子系统说起来高深摸测,其实就是许多许多许多许多许多许多的点图象,然后对其进行运行速度,方向,衰减的处理。
本文粒子系统的实现是基于图形API,OPenGL。语言是:C++。
不可少的,先定义一些全局变量。
const int MaxPoint=1000; //粒子的个数;
float slowdown=2.0f;
float xspeed; //粒子的速度,这里没有给出。可以自己加
float yspeed;
float yspeed;
GLuintloop; //循环变量
GLuintcol; //颜色变量。注意:再循环之中必须加上一个判断语句。因为我们的颜色只有12种!
GLuintcol; //颜色变量。注意:再循环之中必须加上一个判断语句。因为我们的颜色只有12种!
既然是对N多数据操作的系统,首先我们需要拥有一个数据结构。
typedef struct
{
{
思考一下。粒子系统需要些什么?
①方位数据。
②颜色数据。
③移动方向与速度。
④是否活动等衰减数据。
就是这些。
bool active; //该粒子是否活动;
float life; //该粒子生命值^@^
float fade; //该粒子衰减速度
float x; //坐标数据
float y;
float z;
float r; //颜色数据
float g;
float b;
float xi; //运动方向及速度
float yi;
float zi;
float xg; // 重力加速度
float yg;
float zg;
}SPoint;
float life; //该粒子生命值^@^
float fade; //该粒子衰减速度
float x; //坐标数据
float y;
float z;
float r; //颜色数据
float g;
float b;
float xi; //运动方向及速度
float yi;
float zi;
float xg; // 重力加速度
float yg;
float zg;
}SPoint;
插入一个颜色的定义(这里面定义了12种颜色。估计没问题):
static GLfloat colors[12][3]= // 颜色
{
{1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f},
{0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f},
{0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}
};
{
{1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f},
{0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f},
{0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}
};
然后显示是初始化粒子,自然大部分的数据必须依靠计算机随机产生(除非你认为自己以人力可以将1000个粒子编排得飘飘亮亮而完全不做作);
其实就是对上面结构的简单赋值;
SPoint sp;
for (loop=0;loop<MaxPoint;loop++) //初始化粒子
{
sp[loop].active=true; //活动中
sp[loop].life=1.0f; //生命值为满
sp[loop].fade=float(rand()%100)/1000.0f+0.003f; //随机衰减率
sp[loop].r=colors[loop*(12/MaxPoint)][0]; // 粒子的红色颜色
sp[loop].g=colors[loop*(MaxPoint)][1]; // 粒子的绿色颜色
sp[loop].b=colors[loop*(MaxPoint)][2]; // 粒子的蓝色颜色
sp[loop].xi=float((rand()%50)-26.0f)*10.0f; // 随机生成X轴方向速度
sp[loop].yi=float((rand()%50)-25.0f)*10.0f; // 随机生成Y轴方向速度
sp[loop].zi=float((rand()%50)-25.0f)*10.0f; // 随机生成Z轴方向速度
sp[loop].xg=0.0f; // 设置X轴方向加速度为0
sp[loop].yg=-0.8f; // 设置Y轴方向加速度为-0.8
sp[loop].zg=0.0f; // 设置Z轴方向加速度为0
}
for (loop=0;loop<MaxPoint;loop++) //初始化粒子
{
sp[loop].active=true; //活动中
sp[loop].life=1.0f; //生命值为满
sp[loop].fade=float(rand()%100)/1000.0f+0.003f; //随机衰减率
sp[loop].r=colors[loop*(12/MaxPoint)][0]; // 粒子的红色颜色
sp[loop].g=colors[loop*(MaxPoint)][1]; // 粒子的绿色颜色
sp[loop].b=colors[loop*(MaxPoint)][2]; // 粒子的蓝色颜色
sp[loop].xi=float((rand()%50)-26.0f)*10.0f; // 随机生成X轴方向速度
sp[loop].yi=float((rand()%50)-25.0f)*10.0f; // 随机生成Y轴方向速度
sp[loop].zi=float((rand()%50)-25.0f)*10.0f; // 随机生成Z轴方向速度
sp[loop].xg=0.0f; // 设置X轴方向加速度为0
sp[loop].yg=-0.8f; // 设置Y轴方向加速度为-0.8
sp[loop].zg=0.0f; // 设置Z轴方向加速度为0
}
最后是显示粒子:
for (loop=0;loop<MaxPoint;loop++) // 循环所有的粒子
...{
if(sp[loop].active) //粒子是否处于激活状态
...{
float x=sp[loop].x // 返回X轴的位置
float y=sp[loop].y; // 返回Y轴的位置
float z=sp[loop].z+35.0f; // 返回Z轴的位置,加的35.0F是Z轴上面的缩放数据
glColor4f(sp[loop].r,sp[loop].g,sp[loop].b,sp[loop].life); //sp[loop].life处于的位置是混合透明参数
glBegin(GL_TRIANGLE_STRIP); // 绘制三角形带
glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z);
glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z);
glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z);
glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z);
glEnd(); //完成绘制
sp[loop].x+=sp[loop].xi/(slowdown*1000); // 更新X坐标的位置
sp[loop].y+=sp[loop].yi/(slowdown*1000); // 更新Y坐标的位置
sp[loop].z+=sp[loop].zi/(slowdown*1000); // 更新Z坐标的位置
sp[loop].xi+=sp[loop].xg; // 更新X轴方向速度大小
sp[loop].yi+=sp[loop].yg; // 更新Y轴方向速度大小
sp[loop].zi+=sp[loop].zg; // 更新Z轴方向速度大小
sp[loop].life-=sp[loop].fade; // 减少粒子的生命值
if (sp[loop].life<0.0f) // 如果粒子生命值小于0
...{
sp[loop].life=1.0f; // 产生一个新的粒子
sp[loop].fade=float(rand()%100)/1000.0f+0.003f; // 随机生成衰减速率
sp[loop].x=0.0f; // 新粒子出现在屏幕的中央
sp[loop].y=0.0f;
sp[loop].z=0.0f;
sp[loop].xi=xspeed+float((rand()%60)-32.0f);// 随机生成粒子速度
sp[loop].yi=yspeed+float((rand()%60)-30.0f);
sp[loop].zi=float((rand()%60)-30.0f);
sp[loop].r=colors[col][0]; // 设置粒子颜色
sp[loop].g=colors[col][1];
sp[loop].b=colors[col][2];
}
}
}
...{
if(sp[loop].active) //粒子是否处于激活状态
...{
float x=sp[loop].x // 返回X轴的位置
float y=sp[loop].y; // 返回Y轴的位置
float z=sp[loop].z+35.0f; // 返回Z轴的位置,加的35.0F是Z轴上面的缩放数据
glColor4f(sp[loop].r,sp[loop].g,sp[loop].b,sp[loop].life); //sp[loop].life处于的位置是混合透明参数
glBegin(GL_TRIANGLE_STRIP); // 绘制三角形带
glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z);
glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z);
glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z);
glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z);
glEnd(); //完成绘制
sp[loop].x+=sp[loop].xi/(slowdown*1000); // 更新X坐标的位置
sp[loop].y+=sp[loop].yi/(slowdown*1000); // 更新Y坐标的位置
sp[loop].z+=sp[loop].zi/(slowdown*1000); // 更新Z坐标的位置
sp[loop].xi+=sp[loop].xg; // 更新X轴方向速度大小
sp[loop].yi+=sp[loop].yg; // 更新Y轴方向速度大小
sp[loop].zi+=sp[loop].zg; // 更新Z轴方向速度大小
sp[loop].life-=sp[loop].fade; // 减少粒子的生命值
if (sp[loop].life<0.0f) // 如果粒子生命值小于0
...{
sp[loop].life=1.0f; // 产生一个新的粒子
sp[loop].fade=float(rand()%100)/1000.0f+0.003f; // 随机生成衰减速率
sp[loop].x=0.0f; // 新粒子出现在屏幕的中央
sp[loop].y=0.0f;
sp[loop].z=0.0f;
sp[loop].xi=xspeed+float((rand()%60)-32.0f);// 随机生成粒子速度
sp[loop].yi=yspeed+float((rand()%60)-30.0f);
sp[loop].zi=float((rand()%60)-30.0f);
sp[loop].r=colors[col][0]; // 设置粒子颜色
sp[loop].g=colors[col][1];
sp[loop].b=colors[col][2];
}
}
}
循环中加上延迟是必不可少的,这里也就不列举了。
OK了。看看生成的图象是否让你惊喜?
这只是一个简单的教程,而且是根据NEHE的教程(这一章似乎没有中文版)改编的,希望看了后能够对粒子系统有一个较为直观的了解。
- 粒子系统的简单实现
- 一个简单的粒子系统的实现
- 基于Direct3D实现简单的粒子系统
- 基于Direct3D实现简单的粒子系统
- opengles实现简单的粒子系统
- 简单的粒子系统~~
- 粒子系统的实现
- Unity3D 粒子系统实现一个简单的爆炸效果
- 一个简单的粒子系统
- 简单BitmapData粒子的实现
- 粒子效果的简单实现
- IOS粒子系统的实现
- canvas简单的粒子效果的实现
- 基于GPU的粒子系统实现概要
- OpenGL实现的烟花粒子系统
- Cocos2d-x—粒子系统的实现
- unity总结--粒子系统的实现
- 移动平台粒子系统的实现原理
- C# 编码规则
- 基于ASP.NET实现全球化
- 个人对联集
- 系统编程部分技巧
- 收藏地址
- 粒子系统的简单实现
- 请教两个进程操作的一个疑惑
- ASP.NET2.0中用Gridview控件操作数据
- 得到真实IP
- 前途一片光明
- 陕西人在美国开面
- POP3协议命令原始码及工作原理
- 使用Apache 反向代理功能连接 Tomcat
- 经典正则表达式