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

📄 snowstorm.cpp

📁 一本关于OPenGL的很好的电子书
💻 CPP
字号:
/****************************************************************************
 Particles.h  Particle and particle system base classes.
 
 Author   :   Dave Astle
 Date     :   2/1/2001

 Written for OpenGL Game Programming
*****************************************************************************/


/********************************* Includes *********************************/
#include "snowstorm.h"
#include "bitmap.h"


/*****************************************************************************
 CSnowstorm::Constructor

 Nothing to do
*****************************************************************************/
CSnowstorm::CSnowstorm(int numParticles, vector3_t origin, float height, float width, float depth)
  : m_height(height), m_width(width), m_depth(depth), CParticleSystem(numParticles, origin)
{
} // end CSnowstorm::Constructor


/*****************************************************************************
 CSnowstorm::InitializeParticle()

 Sets the initial particle properties for the snowstorm
*****************************************************************************/
void CSnowstorm::InitializeParticle(int index)
{
  // start the particle at the sky at a random location in the emission zone
  m_particleList[index].m_pos.y = m_height;
  m_particleList[index].m_pos.x = m_origin.x + FRAND * m_width;
  m_particleList[index].m_pos.z = m_origin.z + FRAND * m_depth;

  // set the size of the particle
  m_particleList[index].m_size = SNOWFLAKE_SIZE;

  // give the particle a random velocity
  m_particleList[index].m_velocity.x = SNOWFLAKE_VELOCITY.x + FRAND * VELOCITY_VARIATION.x;
  m_particleList[index].m_velocity.y = SNOWFLAKE_VELOCITY.y + FRAND * VELOCITY_VARIATION.y;
  m_particleList[index].m_velocity.z = SNOWFLAKE_VELOCITY.z + FRAND * VELOCITY_VARIATION.z;
} // end CSnowstorm::InitializeParticle


/*****************************************************************************
 CSnowstorm::Update

 Update the existing particles, killing them and creating new ones as needed
*****************************************************************************/
void CSnowstorm::Update(float elapsedTime)
{
  for (int i = 0; i < m_numParticles; )
  {
    // update the particle's position based on the elapsed time and velocity
    m_particleList[i].m_pos = m_particleList[i].m_pos + m_particleList[i].m_velocity * elapsedTime;

    // if the particle has hit the ground plane, kill it
    if (m_particleList[i].m_pos.y <= m_origin.y)
    {
      // move the last particle to the current positon, and decrease the count
      m_particleList[i] = m_particleList[--m_numParticles];
    }
    else
    {
      ++i;
    }
  }

  // store the accumulated time
  m_accumulatedTime += elapsedTime;

  // determine how many new particles are needed
  int newParticles = SNOWFLAKES_PER_SEC * m_accumulatedTime;

  // save the remaining time for after the new particles are released.
  m_accumulatedTime -= 1.0f/(float)SNOWFLAKES_PER_SEC * newParticles;

  Emit(newParticles);
} // end CSnowstorm::Update()


/*****************************************************************************
 CSnowstorm::Render()

 Draw the snowflake particles as textured quads
*****************************************************************************/
void CSnowstorm::Render()
{
  // enable alpha blending and texturing
  glEnable(GL_BLEND);
  glEnable(GL_TEXTURE_2D);

  // set the blend mode
  glBlendFunc(GL_SRC_ALPHA, GL_ONE);

  // select the snow texture
  glBindTexture(GL_TEXTURE_2D, m_texture);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  // to avoid constant dereferencing...
  vector3_t partPos;
  float size;

  // draw the quads
  glBegin(GL_QUADS);
  for (int i = 0; i < m_numParticles; ++i)
  {
    partPos = m_particleList[i].m_pos;
    size = m_particleList[i].m_size;
    glTexCoord2f(0.0, 1.0);
    glVertex3f(partPos.x, partPos.y, partPos.z);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(partPos.x + size, partPos.y, partPos.z);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(partPos.x + size, partPos.y - size, partPos.z);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(partPos.x, partPos.y - size, partPos.z);
  }
  glEnd();

  glDisable(GL_BLEND);
  glDisable(GL_TEXTURE_2D);
} // end CSnowstorm::Update


/*****************************************************************************
 CSnowstorm::InitializeSystem

 Load the snow texture
*****************************************************************************/
void CSnowstorm::InitializeSystem()
{
  // get a texture object
  glGenTextures(1, &m_texture);
  glBindTexture(GL_TEXTURE_2D, m_texture);

  // load the bitmap
  BITMAPINFOHEADER bitmapInfoHeader;
  unsigned char *buffer = LoadBitmapFileWithAlpha("snowstorm.bmp", &bitmapInfoHeader);

  // set up the texture
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  glTexImage2D(GL_TEXTURE_2D, 0, 4, bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  gluBuild2DMipmaps(GL_TEXTURE_2D, 4, bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

  // we're done with the bitmap data
  free(buffer);

  // let parent do remaining initialization
  CParticleSystem::InitializeSystem();
} // end CSnowstorm::InitializeSystem


/*****************************************************************************
 CSnowstorm::KillSystem

 Free the texture
*****************************************************************************/
void CSnowstorm::KillSystem()
{
  // if we have a valid texture object, free it
  if (glIsTexture(m_texture))
  {
    glDeleteTextures(1, &m_texture);
  }

  // let parent do remaining shutdown
  CParticleSystem::KillSystem();
} // end CSnowstorm::KillSystem

⌨️ 快捷键说明

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