📄 snowstorm.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 + -