⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 particles.cpp

📁 wince 3d tutorial, it has various examples
💻 CPP
字号:
#include "particles.h"

ParticleSystem::ParticleSystem(const char *textureFilename, int numberOfParticles, GLfixed x, GLfixed y, GLfixed z)
{
  srand(GetTickCount());  //set the random number generator seed
  
  //set the emmiter position
  m_emmiter[0] = x;
  m_emmiter[1] = y;
  m_emmiter[2] = z;

  //Create the particles texture: if it is a .raw texture, it must be 16x16 with two channels (16 bits)
  m_texture = new Texture(textureFilename, GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE,GL_CLAMP_TO_EDGE,64,64,16);
    
  m_numberOfParticles = numberOfParticles;

  m_totalLifeTime = new GLfixed[m_numberOfParticles];
  m_lifeTime      = new GLfixed[m_numberOfParticles];
  m_startSpeed    = new GLfixed[m_numberOfParticles];
  m_startAngle    = new int[m_numberOfParticles];
  m_color         = new GLubyte[m_numberOfParticles * 4]; //RGBA
  m_position      = new GLfixed[m_numberOfParticles * 3]; //XYZ


  //Initialize all particles
  for(int i=0;i< m_numberOfParticles;++i)
    ResetParticle(i);  

  //Initialize trigonometric tables
  for(i=0;i<360;++i)
  {
    m_sin[i] = FixedFromFloat((float)sin(DEGTORAD(i)));
    m_cos[i] = FixedFromFloat((float)cos(DEGTORAD(i)));
  }

}
//----------------------------------------------------------------------------
ParticleSystem::~ParticleSystem()
{  
  delete [] m_totalLifeTime;
  delete [] m_lifeTime;
  delete [] m_startSpeed;
  delete [] m_startAngle; 
  delete [] m_color;   
  delete [] m_position;
  delete m_texture;
}
//----------------------------------------------------------------------------
void ParticleSystem::ResetParticle(int index)
{
  m_totalLifeTime[index] = FixedFromInt(2 + rand()%1);//random number between 2 and 3 (seconds)  
  m_lifeTime[index] = m_totalLifeTime[index];
  m_startSpeed[index] = FixedFromInt(5 + rand()%3); //random number between 5 and 8 (m/s)  

  //Random number between 0 and 360 degrees
  m_startAngle[index] = rand() % 360; 

  //random number between 0 and 255 (color is in GLubyte format: 0-255)
  int colorIndex = index * 4;
  m_color[colorIndex] = rand()%255;
  m_color[colorIndex + 1] = rand()%255;
  m_color[colorIndex + 2] = rand()%255;
  m_color[colorIndex + 3] = 255;

  //set starting position at emmiter
  int positionIndex = index * 3;
  m_position[positionIndex]     = m_emmiter[0]; 
  m_position[positionIndex + 1] = m_emmiter[1]; 
  m_position[positionIndex + 2] = m_emmiter[2];

}
//----------------------------------------------------------------------------
void ParticleSystem::UpdateParticles(unsigned int elapsedTime)
{    
  //convert elapsed time from milliseconds to seconds
  GLfixed felapsed = DivideFixed(FixedFromInt(elapsedTime), FixedFromInt(1000));
  
  //iterate throught all particles
  for(int i=0;i< m_numberOfParticles;++i)
  {
    m_lifeTime[i] -= felapsed; //reduce the particle's lifetime
    if((m_lifeTime[i] <= 0)||(m_position[i * 3 + 1] < 0))
      ResetParticle(i); //reset the partice if has died or of touched the floor(y < 0)
    else
    {       
      GLfixed flife = m_totalLifeTime[i] - m_lifeTime[i]; //current life time
      //we will set an alpha transparency based on the particle's life time: (lifetime/totaltime)*255
      GLfixed aux = DivideFixed(m_lifeTime[i],m_totalLifeTime[i]);
      m_color[i * 4 + 3] = (GLubyte)IntFromFixed(MultiplyFixed(aux,FixedFromInt(255)));
      
      /*Compute the particle's position. for the vertical axis, we will use the vertical axis 
        ecuation of the parabolic shot(-0.5*g*t*t)+(V0*t)      
        For the horizontal ones, we will use the horizontal component, in a radial direction given by
        m_startAngle: (1/8)*(V0*sin(angle)) (the 1/8 factor is handcoded, to simulate an high elevation angle
        of the parabolic shot*/
      GLfixed temp1, temp2;
      temp1 = MultiplyFixed(flife,flife);
      temp1 = MultiplyFixed(GRAVITY, temp1);
      temp2 = MultiplyFixed(m_startSpeed[i],flife);
      
      GLfixed fHorizontalFactor = MultiplyFixed(FixedFromFloat(0.125f), flife);
      int positionIndex = i * 3;
      m_position[positionIndex]     += MultiplyFixed(MultiplyFixed(m_startSpeed[i], m_sin[m_startAngle[i]]), fHorizontalFactor);
      m_position[positionIndex + 1] += temp1 + temp2;
      m_position[positionIndex + 2] += MultiplyFixed(MultiplyFixed(m_startSpeed[i], m_cos[m_startAngle[i]]), fHorizontalFactor);
    }
  }  
}
//----------------------------------------------------------------------------
void ParticleSystem::DrawParticles(unsigned int elapsedTime)
{
  //Update all particles before drawing
  UpdateParticles(elapsedTime);

  //Enable blending and disable the alpha test.
  glEnable(GL_BLEND);
  glDisable(GL_DEPTH_TEST);  
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_TEXTURE_2D);
  //Setup point sprites coordinate generation
  glEnable(GL_POINT_SPRITE_OES);
  glTexEnvx(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
  glPointSize(15);
  m_texture->BindTexture();

  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_COLOR_ARRAY);
  glVertexPointer(3, GL_FIXED, 0, m_position);
  glColorPointer(4, GL_UNSIGNED_BYTE, 0, m_color);
  
  glDrawArrays(GL_POINTS,0,m_numberOfParticles);
  
  //restore all states
  glDisableClientState(GL_VERTEX_ARRAY);
  glDisableClientState(GL_COLOR_ARRAY);
  
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_BLEND);
  glTexEnvx(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_FALSE);
  glDisable(GL_TEXTURE_2D);
  glDisable(GL_POINT_SPRITE_OES);

}
















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -