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

📄 particlesystem.h

📁 Ion Team Lord Of The Rings Demo 模拟指环王的3D游戏 VS.NET编译 里面提供高级渲染算法
💻 H
字号:
#define PARTICLES_PER_MILLISECOND 0.1f
#define MAX_PARTICLES 2000
#define RANDOM_NUMBER ((static_cast<float>(rand())*2.0f)/(static_cast<float>(RAND_MAX))-1.0f)

float ParticleFraction=1.0f;
struct fRGBColor
  {
    float r, g, b;
  };

struct Particle
  {
    Vector3d Pos, Speed;

    float fAge;
    float fLifetime;
    float fInitialAlpha;
    float fFinalAlpha;
    float fInitialSize;
    float fFinalSize;

    fRGBColor InitialColor;
    fRGBColor FinalColor;


  };

class ParticleSystem
  {
  public:
    bool Solid, Enabled, IndividualAcceleration, BumpAtYPlane, BumpAtXPlane, BumpAtMinusXPlane;
		float YPlane, XPlane, AccelFraction;
    Particle Particles[MAX_PARTICLES];
    Uint16 NumberOfParticles, ParticlesReleased;
    Particle InitialParticle, Chaos; /* the initial particle setings will come from
                                        InitialParticle, and every possible variation
   																			from those are simply Chaos ]:D */
    Vector3d InitialAccel, FinalAccel, aPos; // initial and final grav vectors (no chaos ;=)
																							// also the position vector to move the particles
																							// to when IndividualAcceleration is enabled
    Uint16 Texture; // Texture for the particles
    void AccelerateTo(Vector3d Position)
    {
      aPos=Position;
    }
    ParticleSystem()
    {
      NumberOfParticles = ParticlesReleased = 0;
    }
    ~ParticleSystem()
    {}
  }
;

class ParticleGod // diferent from a particle system: this handles EVERY particle in EVERY system in the scene :)
  {
  public:
    int NewSystem (int NumberOfParticles, string TextureFile, int Threshold, bool Solid, float AccelFraction_ForIndividualAcceleration);
    inline void Update(float MillisecondsEllapsed);
    inline void Draw();
    Uint16 Size()
    {
      return Systems.size();
    }

    ~ParticleGod()
    {
      Systems.clear();
    }

    void Clear ()
    {
      Systems.clear();
    }
    ParticleSystem *operator[](Uint16 Index)
    {
      return &Systems[Index];
    }
  protected:
    vector<ParticleSystem> Systems;

  }
PGod;

int ParticleGod::NewSystem(int NumberOfParticles, string TextureFile, int Threshold, bool Solid, float AccelFraction_ForIndividualAcceleration=0.0f)
{

	if (ParticleFraction==0.0f)
		return -1;
  if ((int)((float)NumberOfParticles*ParticleFraction)<=0 || (int)((float)NumberOfParticles*ParticleFraction)>=MAX_PARTICLES)
    return -1;
  int ret;
  ParticleSystem System;
  Systems.push_back(System);
  ret = Systems.size() - 1;
  Systems[ret].Texture = LoadAlphaBitmap(TextureFile,CT_LINEAR,Threshold);
  Systems[ret].NumberOfParticles = (int)((float)NumberOfParticles*ParticleFraction);
  Systems[ret].ParticlesReleased=0;
  Systems[ret].Solid=Solid;
  Systems[ret].Enabled=true;
	Systems[ret].IndividualAcceleration=false;
	Systems[ret].BumpAtYPlane=false;
	Systems[ret].BumpAtXPlane=false;
	Systems[ret].BumpAtMinusXPlane=false;
	Systems[ret].AccelFraction=AccelFraction_ForIndividualAcceleration;
  return ret;
}

inline void ParticleGod::Update (float MillisecondsEllapsed)
{
  Uint16 ParticlesAfterRelease,t;
  float fLifeFraction;
  for (Uint16 i=0;i<Systems.size();i++)
    {
      if (Systems[i].Enabled)
        {
          t=Systems[i].ParticlesReleased;
          t=Systems[i].NumberOfParticles;
          if (Systems[i].ParticlesReleased<Systems[i].NumberOfParticles)
            {
              ParticlesAfterRelease = Systems[i].ParticlesReleased+(PARTICLES_PER_MILLISECOND * MillisecondsEllapsed);
              if (ParticlesAfterRelease>Systems[i].NumberOfParticles)
                ParticlesAfterRelease=Systems[i].NumberOfParticles;
              if (ParticlesAfterRelease<Systems[i].NumberOfParticles)
                {
                  for (Uint16 j=Systems[i].ParticlesReleased+1;j<=ParticlesAfterRelease;j++)
                    {
                      Systems[i].Particles[j].Pos.Coords[0] = Systems[i].InitialParticle.Pos.Coords[0]+(RANDOM_NUMBER * Systems[i].Chaos.Pos.Coords[0]);
                      Systems[i].Particles[j].Pos.Coords[1] = Systems[i].InitialParticle.Pos.Coords[1]+(RANDOM_NUMBER * Systems[i].Chaos.Pos.Coords[1]);
                      Systems[i].Particles[j].Pos.Coords[2] = Systems[i].InitialParticle.Pos.Coords[2]+(RANDOM_NUMBER * Systems[i].Chaos.Pos.Coords[2]);

                      Systems[i].Particles[j].Speed.Coords[0] = Systems[i].InitialParticle.Speed.Coords[0]+(RANDOM_NUMBER * Systems[i].Chaos.Speed.Coords[0]);
                      Systems[i].Particles[j].Speed.Coords[1] = Systems[i].InitialParticle.Speed.Coords[1]+(RANDOM_NUMBER * Systems[i].Chaos.Speed.Coords[1]);
                      Systems[i].Particles[j].Speed.Coords[2] = Systems[i].InitialParticle.Speed.Coords[2]+(RANDOM_NUMBER * Systems[i].Chaos.Speed.Coords[2]);

                      Systems[i].Particles[j].fAge = 0.0f;
                      Systems[i].Particles[j].fLifetime = Systems[i].InitialParticle.fLifetime+(RANDOM_NUMBER * Systems[i].Chaos.fLifetime);
                      Systems[i].Particles[j].fInitialAlpha = Systems[i].InitialParticle.fInitialAlpha+(RANDOM_NUMBER * Systems[i].Chaos.fInitialAlpha);
                      Systems[i].Particles[j].fFinalAlpha = Systems[i].InitialParticle.fFinalAlpha+(RANDOM_NUMBER * Systems[i].Chaos.fFinalAlpha);
                      Systems[i].Particles[j].fInitialSize = Systems[i].InitialParticle.fInitialSize+(RANDOM_NUMBER * Systems[i].Chaos.fInitialSize);
                      Systems[i].Particles[j].fFinalSize = Systems[i].InitialParticle.fFinalSize+(RANDOM_NUMBER * Systems[i].Chaos.fFinalSize);

                      Systems[i].Particles[j].InitialColor.r = Systems[i].InitialParticle.InitialColor.r+(RANDOM_NUMBER * Systems[i].Chaos.InitialColor.r);
                      Systems[i].Particles[j].InitialColor.g = Systems[i].InitialParticle.InitialColor.g+(RANDOM_NUMBER * Systems[i].Chaos.InitialColor.g);
                      Systems[i].Particles[j].InitialColor.b = Systems[i].InitialParticle.InitialColor.b+(RANDOM_NUMBER * Systems[i].Chaos.InitialColor.b);

                      Systems[i].Particles[j].FinalColor.r = Systems[i].InitialParticle.FinalColor.r+(RANDOM_NUMBER * Systems[i].Chaos.FinalColor.r);
                      Systems[i].Particles[j].FinalColor.g = Systems[i].InitialParticle.FinalColor.g+(RANDOM_NUMBER * Systems[i].Chaos.FinalColor.g);
                      Systems[i].Particles[j].FinalColor.b = Systems[i].InitialParticle.FinalColor.b+(RANDOM_NUMBER * Systems[i].Chaos.FinalColor.b);
                    }
                  Systems[i].ParticlesReleased=ParticlesAfterRelease;

                }
              else
                {
                  Systems[i].ParticlesReleased=Systems[i].NumberOfParticles;
                }
            }
          for (Uint16 j=0;j<=Systems[i].ParticlesReleased;j++)
            {
              Systems[i].Particles[j].fAge += MillisecondsEllapsed;
              if (Systems[i].Particles[j].fAge>=Systems[i].Particles[j].fLifetime)
                {
                  Systems[i].Particles[j].Pos.Coords[0] = Systems[i].InitialParticle.Pos.Coords[0]+(RANDOM_NUMBER * Systems[i].Chaos.Pos.Coords[0]);
                  Systems[i].Particles[j].Pos.Coords[1] = Systems[i].InitialParticle.Pos.Coords[1]+(RANDOM_NUMBER * Systems[i].Chaos.Pos.Coords[1]);
                  Systems[i].Particles[j].Pos.Coords[2] = Systems[i].InitialParticle.Pos.Coords[2]+(RANDOM_NUMBER * Systems[i].Chaos.Pos.Coords[2]);

                  Systems[i].Particles[j].Speed.Coords[0] = Systems[i].InitialParticle.Speed.Coords[0]+(RANDOM_NUMBER * Systems[i].Chaos.Speed.Coords[0]);
                  Systems[i].Particles[j].Speed.Coords[1] = Systems[i].InitialParticle.Speed.Coords[1]+(RANDOM_NUMBER * Systems[i].Chaos.Speed.Coords[1]);
                  Systems[i].Particles[j].Speed.Coords[2] = Systems[i].InitialParticle.Speed.Coords[2]+(RANDOM_NUMBER * Systems[i].Chaos.Speed.Coords[2]);
                  Systems[i].Particles[j].fAge = 0.0f;
                  Systems[i].Particles[j].fLifetime = Systems[i].InitialParticle.fLifetime+(RANDOM_NUMBER * Systems[i].Chaos.fLifetime);
                  Systems[i].Particles[j].fInitialAlpha = Systems[i].InitialParticle.fInitialAlpha+(RANDOM_NUMBER * Systems[i].Chaos.fInitialAlpha);
                  Systems[i].Particles[j].fFinalAlpha = Systems[i].InitialParticle.fFinalAlpha+(RANDOM_NUMBER * Systems[i].Chaos.fFinalAlpha);
                  Systems[i].Particles[j].fInitialSize = Systems[i].InitialParticle.fInitialSize+(RANDOM_NUMBER * Systems[i].Chaos.fInitialSize);
                  Systems[i].Particles[j].fFinalSize = Systems[i].InitialParticle.fFinalSize+(RANDOM_NUMBER * Systems[i].Chaos.fFinalSize);

                  Systems[i].Particles[j].InitialColor.r = Systems[i].InitialParticle.InitialColor.r+(RANDOM_NUMBER * Systems[i].Chaos.InitialColor.r);
                  Systems[i].Particles[j].InitialColor.g = Systems[i].InitialParticle.InitialColor.g+(RANDOM_NUMBER * Systems[i].Chaos.InitialColor.g);
                  Systems[i].Particles[j].InitialColor.b = Systems[i].InitialParticle.InitialColor.b+(RANDOM_NUMBER * Systems[i].Chaos.InitialColor.b);

                  Systems[i].Particles[j].FinalColor.r = Systems[i].InitialParticle.FinalColor.r+(RANDOM_NUMBER * Systems[i].Chaos.FinalColor.r);
                  Systems[i].Particles[j].FinalColor.g = Systems[i].InitialParticle.FinalColor.g+(RANDOM_NUMBER * Systems[i].Chaos.FinalColor.g);
                  Systems[i].Particles[j].FinalColor.b = Systems[i].InitialParticle.FinalColor.b+(RANDOM_NUMBER * Systems[i].Chaos.FinalColor.b);

                }
              fLifeFraction = Systems[i].Particles[j].fAge / Systems[i].Particles[j].fLifetime;
              Systems[i].Particles[j].Pos += Systems[i].Particles[j].Speed*MillisecondsEllapsed;
							if (Systems[i].BumpAtYPlane)
								if (Systems[i].Particles[j].Pos.Coords[1]<Systems[i].YPlane)
								{
									Systems[i].Particles[j].Speed.Coords[1]=-Systems[i].Particles[j].Speed.Coords[1];
									Systems[i].Particles[j].Pos.Coords[1] +=Systems[i].Particles[j].Speed.Coords[1] * MillisecondsEllapsed * 2.0f;
								}
							if (Systems[i].BumpAtXPlane)
								if (Systems[i].Particles[j].Pos.Coords[0]<Systems[i].XPlane)
								{
									Systems[i].Particles[j].Speed.Coords[0]=-Systems[i].Particles[j].Speed.Coords[0];
									Systems[i].Particles[j].Pos.Coords[0] +=Systems[i].Particles[j].Speed.Coords[0] * MillisecondsEllapsed * 2.0f;
								}

							if (Systems[i].BumpAtMinusXPlane)
								if (Systems[i].Particles[j].Pos.Coords[0]>Systems[i].XPlane)
								{
									Systems[i].Particles[j].Speed.Coords[0]=-Systems[i].Particles[j].Speed.Coords[0];
									Systems[i].Particles[j].Pos.Coords[0] +=Systems[i].Particles[j].Speed.Coords[0] * MillisecondsEllapsed * 2.0f;
								}
              if (Systems[i].IndividualAcceleration)
              {
								Systems[i].Particles[j].Speed += (Systems[i].aPos-Systems[i].Particles[j].Pos)*Systems[i].AccelFraction;
								Systems[i].Particles[j].Pos += (Systems[i].aPos-Systems[i].Particles[j].Pos)*Systems[i].AccelFraction;
							}
              else
                {
                  if (Systems[i].InitialAccel!=Systems[i].FinalAccel)
                    Systems[i].Particles[j].Speed += (Systems[i].InitialAccel + ((Systems[i].FinalAccel-Systems[i].InitialAccel)*fLifeFraction))*MillisecondsEllapsed;
                  else
                    Systems[i].Particles[j].Speed +=Systems[i].InitialAccel*MillisecondsEllapsed;

                }


            }
        }
    }
}


inline void ParticleGod::Draw()
{
  glDisable(GL_CULL_FACE);
  //glDisable(GL_ALPHA_TEST);
  glDepthMask(false);


  float fLifeFraction, fSize;
  float modelview[16];
  for (Uint16 i=0;i<Systems.size();i++)
    {
      if (Systems[i].Enabled)
        {
          Bind(Systems[i].Texture);
          if (!Systems[i].Solid)
            {
              glDisable(GL_LIGHTING);
              glEnable(GL_BLEND);
            }
          else
            {
              glDisable(GL_BLEND);
              glEnable(GL_LIGHTING);
            }
          for (Uint16 j=0;j<=Systems[i].ParticlesReleased;j++)
            {
              //Calculate The Fraction of life remaining
              fLifeFraction = Systems[i].Particles[j].fAge / Systems[i].Particles[j].fLifetime;
              // Calculate the fraction of Size acoording to inital and final size, and fLifeFraction
              fSize = Systems[i].Particles[j].fInitialSize + ((Systems[i].Particles[j].fFinalSize - Systems[i].Particles[j].fInitialSize)*fLifeFraction);
              // Calculate the color and alpha
              glColor4f(Systems[i].Particles[j].InitialColor.r + ((Systems[i].Particles[j].FinalColor.r - Systems[i].Particles[j].InitialColor.r)*fLifeFraction),
                        Systems[i].Particles[j].InitialColor.g + ((Systems[i].Particles[j].FinalColor.g - Systems[i].Particles[j].InitialColor.g)*fLifeFraction),
                        Systems[i].Particles[j].InitialColor.b + ((Systems[i].Particles[j].FinalColor.b - Systems[i].Particles[j].InitialColor.b)*fLifeFraction),
                        Systems[i].Particles[j].fInitialAlpha + ((Systems[i].Particles[j].fFinalAlpha - Systems[i].Particles[j].fInitialAlpha)*fLifeFraction));

              //save current modelview matrix
              glPushMatrix();
              // Goto the particle position
              glTranslatef(Systems[i].Particles[j].Pos.Coords[0],Systems[i].Particles[j].Pos.Coords[1],Systems[i].Particles[j].Pos.Coords[2]);
              // Get The Matrix!
              glGetFloatv(GL_MODELVIEW_MATRIX , modelview);
              for(int k=0; k<3; k++ ) //Undo all cam rotation, so particle will allways be turned this way
                for(int l=0; l<3; l++ )
                  {
                    if ( k==l )
                      modelview[k*4+l] = 1.0;
                    else
                      modelview[k*4+l] = 0.0;
                  }

              // set the modelview to our own!
              glLoadMatrixf(modelview);

              //draw the quad around the particle pos, considering fSize
              glBegin(GL_TRIANGLE_STRIP);
              glTexCoord2f(0.998f,0.998f);
              glVertex3f (fSize,fSize,0.0f);
              glTexCoord2f(0.0f,0.998f);
              glVertex3f (-fSize,fSize,0.0f);
              glTexCoord2f(0.998f,0.0f);
              glVertex3f (fSize,-fSize,0.0f);
              glTexCoord2f(0.0f,0.0f);
              glVertex3f (-fSize,-fSize,0.0f);
              glEnd();
              // restore the previous matrix
              glPopMatrix();
            }
        }
    }
  //glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
  glEnable(GL_CULL_FACE);
  glEnable(GL_LIGHTING);
  //glEnable(GL_ALPHA_TEST);
  glDisable(GL_BLEND);
  glDepthMask(true);
}

⌨️ 快捷键说明

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