另外也可以对比一下我实现下雨效果的粒子类:
#include<stdlib.h>
#include<GL\glut.h>
#include<time.h>
class rain
{
private:
GLfloat position[3];//粒子的位置
GLfloat v0;//粒子的初速度
GLfloat g;//重力加速度
GLfloat size;//雨滴的大小
GLfloat sizeSet[4];
GLfloat gSet[4];
GLuint display_list;
public:
rain()
{
sizeSet[0] = 0.40;
sizeSet[1] = 0.45;
sizeSet[2] = 0.50;
sizeSet[3] = 0.55;
gSet[0] = 0.5;
gSet[1] = 0.52;
gSet[2] = 0.54;
gSet[3] = 0.56;
}
GLuint createDL()
{
GLuint DL;
DL = glGenLists(1);
glNewList(DL,GL_COMPILE);
GLUquadricObj *qobj = gluNewQuadric();
gluQuadricTexture(qobj,GL_TRUE);
gluSphere(qobj, size, 20, 20);//画一个小球
glEndList();
return DL;
}
void init()//粒子初始化
{
display_list = createDL();
position[0] = rand() % 181 - 90;
position[1] = 50;
position[2] = rand() % 181 - 90;
int sizeIndex = rand() % 4;
size = sizeSet[sizeIndex];
g = gSet[sizeIndex];//随机加速度
v0 = (float)(rand() % 6) / (float)20;//随机初始化初速度
}
void draw()
{
GLfloat diffuse[3] = {1.0, 1.0, 1.0};
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, diffuse);
glPushMatrix();
glTranslatef(position[0], position[1], position[2]);
glCallList(display_list);
glPopMatrix();
}
void move()
{
position[1] -= v0;
v0 += g;
if(position[1] <= 0)
die();
}
void die()
{
init();
}
};
雨水粒子我设计得比较简单,初始化的时候分配它随机一个初速度、一个初位置、加速度、大小等,每次显示过后根据速度和加速度改变位置以实现“加速落下”的效果,还有渲染的时候需要用到雨水的纹理图。
设计好了粒子类之后,就可以再写一个类实现对粒子数的控制,以及对所有粒子进行初始化和显示。
反复调用的实现
通过理解粒子系统,我知道它是反复地调用显示所有粒子的函数,因为每次粒子的位置都会改变,所以就形成了粒子的运动。那怎么反复调用显示函数呢?看一下glut库里的函数(当然如果用windows库的话也能实现反复调用,这里只是glut库的):
glutDisplayFunc(renderScene);每次窗口重绘时指定调用函数
glutReshapeFunc(changeSize); 每次窗口大小改变时制定调用函数
一开始想通过这两个函数想反复调用renderScene函数,但是没办法,它们指定的函数只能在特定情况下被调用;
然后我就找到了glutIdleFunc(renderScene)函数,作用是设置全局的默认调用函数。当函数glutMainLoop()进行了无限等待时间循环时,如果没有窗口事件发生,就默认调用glutIdelFunc指定的函数,这样就可以反复调用renderScene函数了。
五角星粒子系统效果:
雪粒子效果