OpenGL系统设计-粒子系统(4)

来源:互联网 发布:嵌入式软件开发怎么样 编辑:程序博客网 时间:2024/05/22 04:27

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帧,当然,随着计算机设备的性能的提高,帧速率也会提高。

原创粉丝点击