int glInit(GLvoid)
{
//创建粒子系统使用的纹理
ParticleTexture[0] = CreateTexture("particle.bmp");
if(!ParticleTexture[0]) //创建失败则返回
{
return FALSE;
}
glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
//重要,必须使用混合,否则无法产生预期的效果
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
//下面设置爆炸粒子系统的初始化参数
explosive.SetAlpha(1.0f, 0.0f); //从全不透明到全透明
explosive.SetVelocity(1.0f, 1.0f, 1.0f); //各方向的速度相同
explosive.SetTexture(ParticleTexture[0]); //纹理
explosive.SetAngle(360);
explosive.SetAttraction(0); //不具有引力效果
explosive.SetColor(1.0f, 0.0f, 0.0f, 1.0f, 0.55f, 0.1f);//颜色变化的最初值和最终值
explosive.SetGravity(0.0f, 0.0f, 0.0f); //不受重力影响
explosive.SetLife(4); //生命周期为4秒
explosive.SetLocation(0.0f, 0.0f, 0.0f); //初始位置在原点
explosive.SetParticlesPerSec(0); //初始没有粒子产生,后面说明,需要触发
explosive.SetSize(3, 2); //最初的大小为3,最终大小为2
explosive.SetSpeed(10); //速度为10
explosive.SetSpread(-100, 100, 200); //在XYZ方向上的扩散速度
attractor.SetAlpha(1.0f, 0.0f);
attractor.SetVelocity(10.0f, 10.0f, 10.0f);
//设置引力球的初始化属性值
attractor.SetTexture(ParticleTexture[0]);
attractor.SetAngle(180);
attractor.SetAttraction(10);
attractor.SetColor(0.0f, 1.0f, 0.0f, 0.0f, 0.55f, 0.1f);
attractor.SetGravity(0.0f, 0.0f, 0.0f);
attractor.SetLife(3);
attractor.SetLocation(0.0f, 0.0f, -10.0f);
attractor.SetParticlesPerSec(100);
attractor.SetSize(1, 1);
attractor.SetSpeed(2);
attractor.SetSpread(-100, 100, 200);
attractor.SetSystemFlag(ATTRACTION, SK_ON); //引力效果
fire.SetAlpha(1.0f, 0.0f);
fire.SetVelocity(0.0f, 0.0f, 0.0f);
fire.SetTexture(ParticleTexture[0]);
fire.SetAngle(360);
fire.SetAttraction(10);
fire.SetColor(1.0f, 0.0f, 0.0f, 1.0f, 0.55f, 0.1f);
fire.SetGravity(0.0f, 3.0f, 0.0f);
fire.SetLife(2);
fire.SetParticlesPerSec(100);
fire.SetSize(2, 1);
fire.SetSpeed(1.5);
fire.SetSpread(-100, 100, 100);
torch.SetAlpha(1.0f, 0.0f);
torch.SetVelocity(0.0f, 0.0f, 0.0f);
torch.SetTexture(ParticleTexture[0]);
torch.SetAngle(180);
torch.SetColor(1.0f, 0.0f, 0.0f, 1.0f, 0.55f, 0.1f);
torch.SetGravity(0.0f, 3.5f, 0.0f);
torch.SetLife(4);
torch.SetParticlesPerSec(5);
torch.SetSize(6, 1);
torch.SetSpeed(2);
torch.SetSpread(-100, 100, 200);
torch.SetLocation(0, -13.0f, -10.0f);
//建立一种“Times New Roma”字体,用来显示帧速率
glBuildFont(&g_FontBase, 24, ANSI_CHARSET, "Times New Roma");
return TRUE;
}
在glMain中对四个粒子系统进行渲染,然后根据各种条件对粒子系统进行更新,显示当前运行的帧速率。
int glMain(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -23.0f);
if(keys[VK_ESCAPE]) //ESC键退出
return FALSE;
if (keys[VK_F1]) // F1键切换窗口模式和全屏模式
{
keys[VK_F1]=FALSE;
glShutdown();
fullscreen=!fullscreen;
if (!InitInstance(WIDTH, HEIGHT, BITS))
{
return 0;
}
}
//为了显示字符串,先禁用纹理
glDisable(GL_TEXTURE_2D);
CalculateFrameRate();
glColor3f(1.0, 0.0, 0.0);
glRasterPos2f(-12.0f, 8.5f);
glPrint(g_FontBase, szFPS);
//启用纹理
glEnable(GL_TEXTURE_2D);
//将火焰的粒子系统的位置放在一个X方向上随机的位置
fire.SetLocation((float)Random(-15,15), -14, -10.0f);
//右方向键增加火炬粒子系统X方向的重力(加速度)
if(keys[VK_RIGHT])
{
torch.mGravity.vertex[0] += 0.1f;
torch.SetGravity(torch.mGravity.vertex[0], torch.mGravity.vertex[1],
torch.mGravity.vertex[2]);
}
//左方向键增加火炬粒子系统-X方向的重力
if(keys[VK_LEFT])
{
torch.mGravity.vertex[0] -= 0.1f;
torch.SetGravity(torch.mGravity.vertex[0], torch.mGravity.vertex[1],
torch.mGravity.vertex[2]);
}
//向上方向键增加火炬粒子系统Y方向的重力
if(keys[VK_UP])
{
torch.mGravity.vertex[1] += 0.1f;
torch.SetGravity(torch.mGravity.vertex[0], torch.mGravity.vertex[1],
torch.mGravity.vertex[2]);
}
//向下方向键增加火炬粒子系统-Y方向的重力
if(keys[VK_DOWN])
{
torch.mGravity.vertex[1] -= 0.1f;
torch.SetGravity(torch.mGravity.vertex[0], torch.mGravity.vertex[1],
torch.mGravity.vertex[2]);
}
//渲染四个粒子系统
explosive.Render();
attractor.Render();
fire.Render();
torch.Render();
float time = timeGetTime() * 0.001f;
//E键显示爆炸粒子系统
if(keys['E'])
explosive.Update(time, ONLY_CREATE, 500);
//A键显示引力粒子系统
if(keys['A'])
attractor.Update(time, ONLY_CREATE, 500);
//更新各粒子系统
explosive.Update(time, ONLY_UPDATE, 0);
attractor.Update(time, ONLY_UPDATE, 0);
fire.Update(time, UPDATE_AND_CREATE, 50);
torch.Update(time, UPDATE_AND_CREATE, 10);
SwapBuffers(g_hDC);
return TRUE;
}
重新运行后,可以看到,在窗口的下边是一片燃烧的火焰,中间是一火柱。当按下如上所述的各键后,对应的效果就显示出来了,效果如图12-1所示。在PIII 866系统下,帧速率在320X240窗口模式下为每秒23帧,在全屏模式下可以达到每秒27帧,当然,随着计算机设备的性能的提高,帧速率也会提高。