简单瀑布核心代码

一、程序的效果图:


二、程序源代码位置:http://download.csdn.net/detail/sh15285118586/8570989

三、核心代码提炼:

1、单个粒子的代码:

Particle.h内容:(BMPLoader相关文件请参考我的博客“加载bmp文件方法二”)

#include "BMPLoader.h"


/** 粒子结构 */
struct Particle
{
	float x,y,z;		    /**< 粒子的位置 */
	unsigned int  r,g,b;	/**< 粒子的颜色 */
	float vx,vy,vz;         /**< 粒子的速度(x,y,z方向) */
	float ax,ay,az;         /**< 粒子在x,y,z上的加速度 */
	float lifetime;	        /**< 粒子生命值 */
	float size;		        /**< 粒子尺寸 */
	float dec;		        /**< 粒子消失的速度 */
};

/** 粒子类 */
class CParticle
{
private:
	CBMPLoader  texture[2];         /**< 载入位图 */
	Particle*   data;				/**< 粒子指针 */
	int         numparticle;	    /**< 粒子数目 */
	

public:

	CParticle();          /**< 构造函数 */

	~CParticle();         /**< 析构函数 */
	
	/** 创建粒子数组 */
	int Create(long num);
	
	/** 设置和获取颜色属性 */
	int SetColor(GLint r,GLint g,GLint b);
	int SetColor(GLint index,GLint r,GLint g,GLint b);
	int GetColor(GLint index,GLint &r,GLint &g,GLint &b);
	
	/** 设置和获取速度属性 */
	int SetVelocity(GLfloat vx,GLfloat vy,GLfloat vz);
	int SetVelocity(GLint index,GLfloat vx,GLfloat vy,GLfloat vz);
	int GetVelocity(GLint index,GLfloat &vx,GLfloat &vy,GLfloat &vz);
	
	/** 设置和获取位置属性 */	
	int SetPosition(GLfloat x,GLfloat y,GLfloat z);
	int SetPosition(GLint index,GLfloat x,GLfloat y,GLfloat z);
	int GetPosition(GLint index,GLfloat &x,GLfloat &y,GLfloat &z);
	
	/** 设置和获取加速度属性 */
	int SetAcceleration(GLfloat ax,GLfloat ay,GLfloat az);
	int SetAcceleration(GLint index,GLfloat ax,GLfloat ay,GLfloat az);
	int GetAcceletation(GLint index,GLfloat &ax,GLfloat &ay,GLfloat &az);

	/** 设置和获取尺寸属性 */
	int SetSize(GLfloat size);
	int SetSize(GLint index,GLfloat size);
	int GetSize(GLint index,GLfloat &size);

	/** 设置和获取消失速度属性 */
	int SetDec(GLfloat dec);
	int SetDec(GLint index,GLfloat dec);
	int GetDec(GLint index,GLfloat &dec);
	
	/** 设置和获取生命值属性 */
	int SetLifeTime(GLfloat lifetime);
	int SetLifeTime(GLint index,GLfloat lifetime);
	int GetLifeTime(GLint index,GLfloat &lifetime);

	/** 载入和获取纹理 */
	bool LoadTextures();
	unsigned int GetTexture(int index);

	/** 获取粒子数组地址 */
	Particle *GetParticle()	{	return data;		}
	
	/** 获得粒子的数目 */
	int GetNumOfParticle()	{	return numparticle;	}

	/** 获得粒子所有的属性 */
	int GetAll(int index,								/**< 索引 */
				GLint &r,GLint &g,GLint &b,				/**< 粒子的颜色 */
				GLfloat &x,GLfloat &y,GLfloat &z,		/**< 位置 */
				GLfloat &vx,GLfloat &vy,GLfloat &vz,	/**< 速度 */
				GLfloat &ax,GLfloat &ay,GLfloat &az,	/**< 加速度 */
				GLfloat &size,							/**< 大小 */
				GLfloat &lifetime,						/**< 生命时间 */
				GLfloat &dec							/**< 消失速度 */
				);

	/** 设置粒子的所有属性 */
	int SetAll(int index,							/**< 索引 */
				GLint r,GLint g,GLint b,			/**< 粒子的颜色 */
				GLfloat x,GLfloat y,GLfloat z,		/**< 位置 */	
				GLfloat vx,GLfloat vy,GLfloat vz,	/**< 速度 */
				GLfloat ax,GLfloat ay,GLfloat az,	/**< 加速度 */
				GLfloat size,						/**< 大小 */
				GLfloat lifetime,					/**< 生命时间 */
				GLfloat dec						    /**< 消失速度 */
				);


};


Particle.cpp内容:

#include "Particle.h"

/** 构造函数 */
CParticle::CParticle()
{
	data = NULL;
	numparticle = 0;
	
}

/** 析构函数 */
CParticle::~CParticle()
{
	delete []data;
	data = NULL;
}

/** 创建一个包含num个元素的粒子数组 */
int CParticle::Create(long num)
{
	/** 删除粒子数组 */
	if (data) 
		delete []data;

	/** 创建数组 */
	if(data = new Particle[num])
	{
		numparticle = num;
		memset(data,0,sizeof(Particle)*numparticle);
				
		/** 返回粒子个数 */
		return numparticle;      
	}
	return 0;
}



/** 载入纹理 */
bool CParticle::LoadTextures()
{
	
	char* fileName[] = {"Data/wall.bmp","Data/flare.bmp" };
	
	for(int i=0; i<2; i++)
	{
		if(!texture[i].LoadBitmap(fileName[i]))
		{
			MessageBox(NULL,"载入纹理失败!","错误",MB_OK);
			exit(-1);
		}

		glGenTextures(1,&texture[i].ID);         
		
		/** 创建纹理对象 */
		glBindTexture(GL_TEXTURE_2D, texture[i].ID);

		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

		gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texture[i].imageWidth,texture[i].imageHeight, GL_RGB, GL_UNSIGNED_BYTE,texture[i].image);
	}
	return true;
		
}

/** 返回纹理ID */
unsigned int CParticle::GetTexture(int index)
{
	if(index == 0 || index == 1)
		
		return texture[index].ID; 
}

/** 设置和获取颜色Color的函数实现 */
int CParticle::SetColor(GLint r,GLint g,GLint b)
{
	for (int index=0;index<numparticle;++index)
	{
		data[index].r=r;
		data[index].g=g;
		data[index].b=b;
	}
	return TRUE;
}

int CParticle::SetColor(GLint index,GLint r,GLint g,GLint b)
{
	if(index>=0 && index<numparticle)
	{
		data[index].r=r;
		data[index].g=g;
		data[index].b=b;
		return TRUE;
	}
	return FALSE;
}

int CParticle::GetColor(GLint index,GLint &r,GLint &g,GLint &b)
{
	if(index>=0 && index<numparticle)
	{
		r=data[index].r;
		g=data[index].g;
		b=data[index].b;
		return TRUE;
	}
	return FALSE;
}

/** 设置和获取位置Position的函数实现 */
int CParticle::SetPosition(GLfloat x,GLfloat y,GLfloat z)
{
	for(int index=0;index<numparticle;++index)
	{
		data[index].x=x;
		data[index].y=y;
		data[index].z=z;
	}
	return TRUE;
}

int CParticle::SetPosition(GLint index,GLfloat x,GLfloat y,GLfloat z)
{
	if(index>=0 && index<numparticle)
	{
		data[index].x=x;
		data[index].y=y;
		data[index].z=z;
		return TRUE;
	}
	return FALSE;
}

int CParticle::GetPosition(GLint index,GLfloat &x,GLfloat &y,GLfloat &z)
{
	if(index>=0 && index<numparticle)
	{
		x=data[index].x;
		y=data[index].y;
		z=data[index].z;
		return TRUE;
	}
	return FALSE;
}
/** 设置和获取加速度Acceleration的函数实现 */
int CParticle::SetAcceleration(GLfloat ax,GLfloat ay,GLfloat az)
{
	for (int index=0;index<numparticle;++index)
	{
		data[index].ax=ax;
		data[index].ay=ay;
		data[index].az=az;
	}
	return TRUE;
}

int CParticle::SetAcceleration(GLint index,GLfloat ax,GLfloat ay,GLfloat az)
{
	if(index>=0 && index<numparticle)
	{
		data[index].ax=ax;
		data[index].ay=ay;
		data[index].az=az;
		return TRUE;
	}
	return FALSE;
}


int CParticle::GetAcceletation(GLint index,GLfloat &ax,GLfloat &ay,GLfloat &az)
{
	if(index>=0 && index<numparticle)
	{
		ax=data[index].ax;
		ay=data[index].ay;
		az=data[index].az;
		return TRUE;
	}
	return FALSE;
}



/** Velocity函数的实现 */
int CParticle::SetVelocity(GLfloat vx,GLfloat vy,GLfloat vz)
{
	for (int index=0;index<numparticle;++index)
	{
		data[index].vx=vx;
		data[index].vy=vy;
		data[index].vz=vz;
	}
	return TRUE;
}

int CParticle::SetVelocity(GLint index,GLfloat vx,GLfloat vy,GLfloat vz)
{
	if(index>=0 && index<numparticle)
	{
		data[index].vx=vx;
		data[index].vy=vy;
		data[index].vz=vz;
		return TRUE;
	}
	return FALSE;
}

int CParticle::GetVelocity(GLint index,GLfloat &vx,GLfloat &vy,GLfloat &vz)
{
	if(index>=0 && index<numparticle)
	{
		vx=data[index].vx;
		vy=data[index].vy;
		vz=data[index].vz;
		return TRUE;
	}
	return FALSE;
}


/** Size函数的实现 */
int CParticle::SetSize(GLfloat size)
{
	for (int index=0;index<numparticle;++index)
	{
		data[index].size=size;
	}
	return TRUE;
}

int CParticle::SetSize(GLint index,GLfloat size)
{
	if (index>=0 && index<numparticle)
	{
		data[index].size=size;
		return TRUE;
	}
	return FALSE;
}

int CParticle::GetSize(GLint index,GLfloat &size)
{
	if(index >= 0 && index < numparticle)
	{
		size=data[index].size;
		return TRUE;
	}
	return FALSE;
}

/** 消失速度Dec函数 */
int CParticle::SetDec(GLfloat dec)
{
	for (int index=0;index<numparticle;++index)
	{
		data[index].dec=dec;
	}
	return TRUE;
}
int CParticle::SetDec(GLint index,GLfloat dec)
{
	if(index >= 0 && index < numparticle)
	{
		data[index].dec=dec;
		return TRUE;
	}
	return FALSE;
}
int CParticle::GetDec(GLint index,GLfloat &dec)
{
	if(index >= 0 && index < numparticle)
	{
		dec=data[index].dec;
		return TRUE;
	}
	return FALSE;
}

/** 设置粒子的lifetime 属性 */
int CParticle::SetLifeTime(GLfloat lifetime)
{
	for (int index=0;index<numparticle;++index)
	{
		data[index].lifetime=lifetime;
	}
	return TRUE;
}
int CParticle::SetLifeTime(GLint index,GLfloat lifetime)
{
	if(index >= 0 && index < numparticle)
	{
		data[index].lifetime=lifetime;
		return TRUE;
	}
	return FALSE;
}

/** 获得粒子的lifetime属性 */
int CParticle::GetLifeTime(GLint index,GLfloat &lifetime)
{
	if(index >= 0 && index < numparticle)
	{
		lifetime=data[index].lifetime;
		return TRUE;
	}
	return FALSE;
}

/** 获取粒子的所有属性 */
int CParticle::GetAll(int index,GLint &r,GLint &g,GLint &b,         /**< 粒子的颜色 */
							GLfloat &x,GLfloat &y,GLfloat &z,		/**< 位置 */
							GLfloat &vx,GLfloat &vy,GLfloat &vz,	/**< 速度 */
							GLfloat &ax,GLfloat &ay,GLfloat &az,	/**< 加速度 */
							GLfloat &size,						    /**< 大小 */
							GLfloat &lifetime,					    /**< 生命时间 */
							GLfloat &dec					        /**< 消失速度 */
							)
{
	if (index>=0 && index<numparticle)
	{
		r=data[index].r;
		g=data[index].g;
		b=data[index].b;
		x=data[index].x;
		y=data[index].y;
		z=data[index].z;
		vx=data[index].vx;
		vy=data[index].vy;
		vz=data[index].vz;
		ax=data[index].ax;
		ay=data[index].ay;
		az=data[index].az;
		lifetime=data[index].lifetime;
		size=data[index].size;
		dec=data[index].dec;
    	return TRUE;
	}
	return FALSE;
}

/** 设置粒子的所有属性 */
int CParticle::SetAll(int index,GLint r,GLint g,GLint b,        /**< 粒子的颜色 */
							GLfloat x,GLfloat y,GLfloat z,		/**< 位置 */
							GLfloat vx,GLfloat vy,GLfloat vz,	/**< 速度 */
							GLfloat ax,GLfloat ay,GLfloat az,	/**< 加速度 */
							GLfloat size,						/**< 大小 */
							GLfloat lifetime,					/**< 生命时间 */
							GLfloat dec						    /**< 消失速度 */
							)
{
	if(index>=0 && index<numparticle)
	{
		data[index].r=r;
		data[index].g=g;
		data[index].b=b;
		data[index].x=x;
		data[index].y=y;
		data[index].z=z;
		data[index].vx=vx;
		data[index].vy=vy;
		data[index].vz=vz;
		data[index].ax=ax;
		data[index].ay=ay;
		data[index].az=az;
		data[index].lifetime=lifetime;
		data[index].size=size;
		data[index].dec=dec;
		return TRUE;
	}
	return FALSE;
}

2、WaterFall的代码:

WaterFall.h内容:

#include "BMPLoader.h"
#include "Particle.h"


/** 从GL_Application派生出一个子类 */
class Test : GLApplication								
{
public:
	bool<span style="white-space:pre">	</span>Init();<span style="white-space:pre">	</span>
	void	Draw();							
	void    DrawParticle();                 
	bool    InitWaterfall();                
	void    UpdateWaterfall();             
	
private:
	friend class GLApplication;				   
	Test(const char * class_name);	          /**< 构造函数 */

	/** 用户自定义的程序变量 */ 
	
	CParticle*       Waterfall;            /**< 粒子系统的对象 */
   				
};

WaterFall.cpp内容:

bool Test::Init()									
{
/** 用户自定义的初始化过程 */
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);						
	glClearDepth(1.0f);											
	glDepthFunc(GL_LEQUAL);										
	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);									
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);			
	ResizeDraw(true);	                             
	 
	glEnable(GL_TEXTURE_2D);             /**< 开启纹理映射 */      
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);    /**< 设置混合因子获得半透明效果 */
	glEnable(GL_BLEND);				     /**< 启用混和 */

	
	if(!Waterfall->LoadTextures())
	{
		MessageBox(NULL,"载入纹理失败!","错误",MB_OK);
		exit(-1);
	}
	
	/** 创建5000个粒子 */
	Waterfall->Create(5000);
	
	/** 初始化粒子 */
	InitWaterfall();
	
	return true;                                        /**< 成功返回 */
}
/** 初始化粒子 */
bool Test::InitWaterfall()
{
	for (int i=0; i < Waterfall->GetNumOfParticle(); ++i)
	{
		///初始化颜色
		//r = rand()%255;
		//g = rand()%255;
		//b = rand()%255;
		r = 100;
		g = 100;
		b = 100;

		Waterfall->SetColor(i,r,g,b);

		///初始化坐标
		x = 0.005f * (rand()%9) - 1;
		y = 0.005f * (rand()%9) + 1.6;
		z = 0.0001f * (rand()%15000);
		
		Waterfall->SetPosition(i,x,y,z);

		///初始化速度
		vz = 0;
		vx = 0.000001f*(rand()%9000);
		vy = -rand()%5400 * vx * vx;

		Waterfall->SetVelocity(i,vx,vy,vz);


		///初始化加速度
		ax = 0;
		ay = -0.0001;
		az = 0;
		
		Waterfall->SetAcceleration(i,ax,ay,az);

		///初始化生命周期
		lifetime = 100;
		Waterfall->SetLifeTime(i,lifetime);

		///消失速度
		dec = 0.05 * (rand()%50);
		Waterfall->SetDec(i,dec);

		///初始化大小
		Waterfall->SetSize(i,0.02f);


	}
	return true;
}
/** 绘制粒子 */
void Test::DrawParticle()
{
	/** 绑定纹理 */
	glBindTexture(GL_TEXTURE_2D,Waterfall->GetTexture(1));
	
	for(int i = 0; i<Waterfall->GetNumOfParticle(); ++i)
	{
		/** 获得粒子的所有属性 */
		Waterfall->GetAll(i,r,g,b,x,y,z,vx,vy,vz,ax,ay,az,size,lifetime,dec);
		glLoadIdentity();
		glTranslatef(0.0f,0.0f,-6.0f);
		glColor4ub(r,g,b,255);
		glNormal3f(0.0f,0.0f,1.0f);   /**< 定义法线方向 */
		/** 画出粒子 */
		glBegin(GL_QUADS);
			glTexCoord2f(0.0f,0.0f);glVertex3f(x-size,y-size,z);
			glTexCoord2f(1.0f,0.0f);glVertex3f(x-size,y+size,z);
			glTexCoord2f(1.0f,1.0f);glVertex3f(x+size,y+size,z);
			glTexCoord2f(0.0f,1.0f);glVertex3f(x+size,y-size,z);
		glEnd();
		
		/** 更新粒子属性 */
		UpdateWaterfall();
		Waterfall->SetAll(i,r,g,b,x,y,z,vx,vy,vz,ax,ay,az,size,lifetime,dec);
		
	}
}

/** 更新粒子 */
void Test::UpdateWaterfall()
{
	/** 更新位置 */
	x += vx;
	y += vy;

	/** 更新速度 */
	vy += ay;
	
	/** 更新生存时间 */
	lifetime -= dec;
	
	/** 如果粒子消失或生命结束 */
	if (y <= -1 || lifetime <= 0)
	{
		/** 初始化位置 */
		x = 0.005f * (rand()%9) - 1;
		y = 0.005f * (rand()%9) + 1.6;
		z = 0.0001f * (rand()%15000);
		
		/** 初始化速度 */
		vz = 0;
		vx = 0.000001f * (rand()%9000);
		vy = -rand()%500 * vx * vx;
		
		
		lifetime = 100;
		dec = 0.05 * (rand()%50);
	}
}

/** 绘制函数 */
void Test::Draw()											
{
/** 用户自定义的绘制过程 */
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			
	glLoadIdentity();
	DrawParticle();
	glFlush();	                     /**< 强制执行所有的OpenGL命令 */
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值