基于NeHe第十九课做的粒子系统

    可以实现各种喷射状的运动状态,按上下左右键分别移动粒子,按y键切换颜色,按7、8、9、0切换不同的纹理,按1、2改变粒子速度、按3、4改变粒子大小
ParticleSys.h
// ParticleSys.h: interface for the CParticleSys class.
//
//
 
#if !defined(AFX_PARTICLESYS_H__F9DB0BB6_E352_488D_A578_09D57EEE6F42__INCLUDED_)
#define AFX_PARTICLESYS_H__F9DB0BB6_E352_488D_A578_09D57EEE6F42__INCLUDED_
 
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define     MAX_PARTICLES 1000              // 定义最大的粒子数
typedef struct                                     // 创建粒子数据结构
{
       bool active;                                 // 是否激活
       float life;                              // 粒子生命
       float fade;                                   // 衰减速度
       float r;                                 // 红色值
       float g;                                // 绿色值
       float b;                                // 蓝色值
       float x;                                // X 位置
       float y;                                // Y 位置
       float z;                                 // Z 位置
       float xi;                                // X 方向移动
       float yi;                                // Y 方向
       float zi;                                // Z 方向
       float xg;                               // X 方向重力加速度
       float yg;                               // Y 方向重力加速度
       float zg;                               // Z 方向重力加速度
 
}particles;
class CParticleSys 
{
public:
       CParticleSys();
       virtual ~CParticleSys();
public:
       void InitParticles();
       int DrawParticles();
       void ChangeColor();
       void ChangeXSpeed(float fOff);
       void ChangeYSpeed(float fOff);
       void ResetPos();
       void ChangeDelay(float fOff);
       void ChangeSlow(float fOff);
       void ChangeZoom(float fOff);
       void SetTexList(GLuint iTexList);
       void SetZoom(float fZoom);
       void SetXSpeed(float fXSpeed);
       void SetYSpeed(float fYSpeed);
       void SetSlow(float fSlow);
public:
       bool m_rainbow;                  // 是否为彩虹模式
       float m_slowdown;               // 减速粒子
       float m_xspeed;                           // X方向的速度
       float m_yspeed;                           // Y方向的速度
       float m_zoom;                      // 沿Z轴缩放
       GLuint    m_loop;                        // 循环变量
       GLuint    m_col;                         // 当前的颜色
       GLuint    m_delay;                      // 彩虹效果延迟
       bool    m_bXG;
       bool    m_bYG;
       bool    m_bXGJ;
       bool    m_bYGJ;
       bool    m_bOrg;
private:
       particles particle[MAX_PARTICLES];                       // 保存1000个粒子的数组
       GLuint    m_iTexList;
 
};
 
#endif // !defined(AFX_PARTICLESYS_H__F9DB0BB6_E352_488D_A578_09D57EEE6F42__INCLUDED_)
 
Particles.cpp
// ParticleSys.cpp: implementation of the CParticleSys class.
//
//
 
#include "stdafx.h"
#include "MySDOpenGL.h"
#include "ParticleSys.h"
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
 
//
// Construction/Destruction
//
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}
};
 
 
CParticleSys::CParticleSys()
{
       m_rainbow = true;
       m_slowdown = 2.0f;                   // 减速粒子
       m_xspeed = 0;                            // X方向的速度
       m_yspeed = 0;                            // Y方向的速度
       m_zoom = -40.0f;                // 沿Z轴缩放
       m_loop = 0;   
       m_col = 0;
       m_delay = 0;
 
       m_bOrg = false;
       m_bXGJ = false;
       m_bYGJ = false;
       m_bXG = false;
       m_bYG = false;
       m_iTexList = 0;
      
}
CParticleSys::~CParticleSys()
{
 
}
 
void CParticleSys::SetXSpeed(float fXSpeed)
{
       m_xspeed = fXSpeed;
}
 
void CParticleSys::SetYSpeed(float fYSpeed)
{
       m_yspeed = fYSpeed;
}
 
void CParticleSys::SetSlow(float fSlow)
{
       m_slowdown = fSlow;
}
 
void CParticleSys::SetZoom(float fZoom)
{
       m_zoom = fZoom;
}
 
void CParticleSys::InitParticles()
{
       glDisable(GL_DEPTH_TEST);
 
       glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
       for(m_loop = 0; m_loop < MAX_PARTICLES; m_loop++)
       {
              particle[m_loop].active = true;
              particle[m_loop].life = 1.0f;
              particle[m_loop].fade = float(rand() % 100)/1000.0f + 0.003f; // 随机生成衰减速率
             
              particle[m_loop].r = colors[m_loop*(12/MAX_PARTICLES)][0];
              particle[m_loop].g = colors[m_loop*(12/MAX_PARTICLES)][1];
              particle[m_loop].b = colors[m_loop*(12/MAX_PARTICLES)][2];
 
              particle[m_loop].xi = float((rand() % 50) - 26.0f)*10.0f;
              particle[m_loop].yi = float((rand() % 50) - 25.0f)*10.0f;
              particle[m_loop].zi = float((rand() % 50) - 25.0f)*10.0f;
             
              particle[m_loop].xg = 0.0f;
              particle[m_loop].yg = -0.8f;
              particle[m_loop].zg = 0.0f;
 
              particle[m_loop].x = 0.0f;
              particle[m_loop].y = 0.0f;
              particle[m_loop].z = 0.0f;
       }
}
 
int CParticleSys::DrawParticles()
{
       if(m_iTexList == 0)
       {
              glDisable(GL_TEXTURE_2D);
              glDisable(GL_BLEND);
       }
       else
       {
              glEnable(GL_TEXTURE_2D);
              glCallList(m_iTexList);
              glEnable(GL_BLEND);
       }
       for(m_loop = 0; m_loop < MAX_PARTICLES; m_loop++)
       {
              if(particle[m_loop].active)
              {
                     float x = particle[m_loop].x;
                     float y = particle[m_loop].y;
                     float z = particle[m_loop].z + m_zoom;
                     glColor4f(particle[m_loop].r, particle[m_loop].g, particle[m_loop].b, particle[m_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();
 
                     particle[m_loop].x+=particle[m_loop].xi/(m_slowdown*1000); // 更新X坐标的位置
                     particle[m_loop].y+=particle[m_loop].yi/(m_slowdown*1000); // 更新Y坐标的位置
                     particle[m_loop].z+=particle[m_loop].zi/(m_slowdown*1000); // 更新Z坐标的位置
 
                     particle[m_loop].xi+=particle[m_loop].xg;                  // 更新X轴方向速度大小
                     particle[m_loop].yi+=particle[m_loop].yg;                  // 更新Y轴方向速度大小
                     particle[m_loop].zi+=particle[m_loop].zg;                  // 更新Z轴方向速度大小
                    
                     particle[m_loop].life-=particle[m_loop].fade;              // 减少粒子的生命值
                     if(particle[m_loop].life < 0.0f)
                     {
                            particle[m_loop].life = 1.0f;
                            particle[m_loop].fade = float(rand() % 100)/1000.0f + 0.003f;
                            particle[m_loop].x=0.0f;                                   // 新粒子出现在屏幕的中央
                            particle[m_loop].y=0.0f;                                  
                            particle[m_loop].z=0.0f;       
                           
                            particle[m_loop].xi=m_xspeed+float((rand()%60)-32.0f);   // 随机生成粒子速度
                            particle[m_loop].yi=m_yspeed+float((rand()%60)-30.0f);  
                            particle[m_loop].zi=float((rand()%60)-30.0f);    
                           
                            particle[m_loop].r=colors[m_col][0];                 // 设置粒子颜色
                            particle[m_loop].g=colors[m_col][1];                
                            particle[m_loop].b=colors[m_col][2];  
 
                     }
                     if(m_bYG && particle[m_loop].yg < 1.5f)
                            particle[m_loop].yg += 0.01;
                     if(m_bYGJ && particle[m_loop].yg > -1.5f)
                            particle[m_loop].yg -= 0.01;
                     if(m_bXG && particle[m_loop].xg < 1.5f)
                            particle[m_loop].xg += 0.01;
                     if(m_bXGJ && particle[m_loop].xg > -1.5f)
                            particle[m_loop].xg -= 0.01;
 
                     if(m_bOrg)
                     {
                            particle[m_loop].x=0.0f;                                  
                            particle[m_loop].y=0.0f;                                  
                            particle[m_loop].z=0.0f;                            
                            particle[m_loop].xi=float((rand()%50)-26.0f)*10.0f;   // 随机生成速度
                            particle[m_loop].yi=float((rand()%50)-25.0f)*10.0f;  
                            particle[m_loop].zi=float((rand()%50)-25.0f)*10.0f;
                            m_bOrg = false;
                     }
              }
       }
       ChangeColor();
       return 1;
}
 
void CParticleSys::ChangeColor()
{
       m_delay ++;
       if(m_rainbow && m_delay > 25)
       {
              if(m_col > 11)
                     m_col = 0;
              m_col ++;
       }
}
 
void CParticleSys::ChangeXSpeed(float fOff)
{
       if(fabs(m_xspeed) < 200)
              m_xspeed += fOff;
}
 
void CParticleSys::ChangeYSpeed(float fOff)
{
       if(fabs(m_yspeed) < 200)
              m_yspeed += fOff;
}
 
void CParticleSys::ResetPos()
{
       m_bOrg = false;
       m_bXGJ = false;
       m_bYGJ = false;
       m_bXG = false;
       m_bYG = false;
}
 
void CParticleSys::ChangeDelay(float fOff)
{
       m_delay += fOff;
}
 
void CParticleSys::ChangeSlow(float fOff)
{
       m_slowdown += fOff;
}
 
void CParticleSys::ChangeZoom(float fOff)
{
       m_zoom += fOff;
}
 
void CParticleSys::SetTexList(GLuint iTexList)
{
       m_iTexList = iTexList;
}
应用:
1、粒子和纹理的建立
m_pParticle = new CParticleSys();
       m_pParticle->InitParticles();
       GenTexList("light02.RGB", 101);
       GenTexList("smoke02.RGB", 102);
       GenTexList("fire.RGB", 103);
       GenTexList("waterexp.RGB", 104);
2、粒子绘制
       m_pParticle->DrawParticles();
3、粒子状态改变
       void CMySDOpenGLView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
       m_pParticle->ResetPos();
       switch(nChar)
       {
       case 39:
              m_pParticle->m_bXG = true;
              break;
       case 37:
              m_pParticle->m_bXGJ = true;
              break;
       case 38:
              m_pParticle->m_bYG = true;
              break;
       case 40:
              m_pParticle->m_bYGJ = true;
              break;
       case 67:
              m_pParticle->m_bOrg =true;
              break;
       case 65:
              m_pParticle->ChangeXSpeed(-1.0f);
              break;
       case 68:
              m_pParticle->ChangeXSpeed(1.0f);
              break;
       case 87:
              m_pParticle->ChangeYSpeed(1.0f);
              break;
       case 88:
              m_pParticle->ChangeYSpeed(-1.0f);
              break;
       case 89:
              m_pParticle->m_rainbow = !m_pParticle->m_rainbow;
              break;
       case '1':
              m_pParticle->ChangeSlow(0.01);
              break;
       case '2':
              m_pParticle->ChangeSlow(-0.01);
              break;
       case '3':
              m_pParticle->ChangeZoom(0.1f);
              break;
       case '4':
              m_pParticle->ChangeZoom(-0.1f);
              break;
       case '6':
              m_pParticle->SetTexList(0);
              break;
       case '7':
              m_pParticle->SetTexList(101);
              break;
       case '8':
              m_pParticle->SetTexList(102);
              break;
       case '9':
              m_pParticle->SetTexList(103);
              break;
       case '0':
              m_pParticle->SetTexList(104);
              break;
       }
       CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
4、删除粒子
       if(m_pParticle != NULL)
       {
              delete m_pParticle;
              m_pParticle = NULL;
       }
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值