#include "partical.h"
#include <TCHAR.H>
using namespace psys;
const DWORD RippleVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL| D3DFVF_DIFFUSE | D3DFVF_TEX1;
const DWORD RainVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
/*****************************对PSystem函数的定义**********************/
template<class Attribute>
PSystem<Attribute>::PSystem()
{
_device = 0;
_vb = 0;
_tex = 0;
}
template<class Attribute>
PSystem<Attribute>::~PSystem()
{
d3d::Release<IDirect3DVertexBuffer9*>(_vb);
d3d::Release<IDirect3DTexture9*>(_tex);
}
template<class Attribute>
bool PSystem<Attribute>::init(IDirect3DDevice9* &device, TCHAR* texFileName)
{
// vertex buffer's size does not equal the number of particles in our system. We
// use the vertex buffer to draw a portion of our particles at a time. The arbitrary
// size we choose for the vertex buffer is specified by the _vbSize variable.
//无论什么系统,都使用同一设备
_device = device;
HRESULT hr = 0;
hr = device->CreateVertexBuffer(
_vbSize * sizeof(Attribute),
D3DUSAGE_DYNAMIC | D3DUSAGE_POINTS | D3DUSAGE_WRITEONLY,
Attribute::FVF,
D3DPOOL_DEFAULT, // D3DPOOL_MANAGED can't be used with D3DUSAGE_DYNAMIC
&_vb,
0);
if(FAILED(hr))
{
::MessageBox(0, _T("CreateVertexBuffer() - FAILED"), _T("PSystem"), 0);
return false;
}
hr = D3DXCreateTextureFromFile(
device,
texFileName,
&_tex);
if(FAILED(hr))
{
::MessageBox(0, _T("D3DXCreateTextureFromFile() - FAILED"), _T("PSystem"), 0);
return false;
}
return true;
}
template<class Attribute>
void PSystem<Attribute>::reset()
{
std::list<Attribute>::iterator i;
for(i = _particles.begin(); i != _particles.end(); i++)
{
resetParticle( &(*i) );
}
}
template<class Attribute>
void PSystem<Attribute>::addParticle()
{
Attribute attribute;
resetParticle(&attribute);
_particles.push_back(attribute);
}
template<class Attribute>
bool PSystem<Attribute>::isEmpty()
{
return _particles.empty();
}
template<class Attribute>
bool PSystem<Attribute>::isDead()
{
std::list<Attribute>::iterator i;
for(i = _particles.begin(); i != _particles.end(); i++)
{
// is there at least one living particle? If yes,
// the system is not dead.
if( i->_isAlive )
return false;
}
// no living particles found, the system must be dead.
return true;
}
/*****************************对RippleSystem函数定义****************************/
/* */
/* 中心,半径,生命时间,这些数是随机生成的,不随时间改变 */
/* 随时间改变的当前半径,当前年龄,alpha,这些数是随着时间演变的 */
/* alpha随着时间变化,_alphaFade=1.0/_lifeTime,生成粒子和重置的时候就给定 */
/* */
/*******************************************************************************/
template<class Attribute>
RippleSystem<Attribute>::RippleSystem(BoundingBox* boundingBox, int numParticles)
{
//每个正方形需要六个顶点,一批有50个正方形,一共50*6=300个顶点
_boundingbox = *boundingbox;
_vbSize = 300;
_vbOffset = 0;
_vbBatchSize = 50;
_maxParticles = numParticles;
for(int i = 0; i < numParticles; i++)
addParticle();
}
template<class Attribute>
void RippleSystem<Attribute>::update(float timeDelta)
{
std::list<Attribute1>::iterator i;
for(i = _particles.begin(); i != _particles.end(); i++)
{
if(i->_age > i->_lifeTime){
resetParticle( &(*i) );
}
i->_alpha -= i->_alphaFade*timeDelta;
if(i->_alpha<0)
{
i->_alpha=0.0f;
}
i->_age += timeDelta;
i->_curradius += i->_radius/i->_lifeTime*timeDelta;
i->_vertices[0]._x = i->_center.x - i->_curradius;
i->_vertices[0]._z = i->_center.y + i->_curradius;
i->_vertices[1]._x = i->_center.x + i->_curradius;
i->_vertices[1]._z = i->_center.y + i->_curradius;
i->_vertices[2]._x = i->_center.x - i->_curradius;
i->_vertices[2]._z = i->_center.y - i->_curradius;
i->_vertices[3]._x = i->_center.x - i->_curradius;
i->_vertices[3]._z = i->_center.y - i->_curradius;
i->_vertices[4]._x = i->_center.x + i->_curradius;
i->_vertices[4]._z = i->_center.y + i->_curradius;
i->_vertices[5]._x = i->_center.x + i->_curradius;
i->_vertices[5]._z = i->_center.y - i->_curradius;
for(int j=0;j<6;++j){
i->_vertices[j]._diffuse=D3DCOLOR_ARGB(int(255*i->_alpha),255,255,255);
}
}
}
template<class Attribute>
void RippleSystem<Attribute>::resetParticle(Attribute *attribute)
{
d3d::GetRandomVector(&attribute->_center,&_boundingPlane._min,&_boundingPlane._max);
attribute->_lifeTime = d3d::GetRandomFloat(0.7f, 1.0f)*3.0f;
attribute->_radius = d3d::GetRandomFloat(0.5f, 1.0f)*2.5f;
attribute->_alphaFade = 1.0f/attribute->_lifeTime;
attribute->_alpha = 1.0f;
attribute->_isAlive = true;
attribute->_age = 0.0f;
attribute->_curradius = 0.0f;
for(int i=0;i<6;++i){
attribute->_vertices[i]._y = attribute->_center.y;
attribute->_vertices[i]._nx = 0.0f;
attribute->_vertices[i]._ny = 1.0f;
attribute->_vertices[i]._nz = 0.0f;
attribute->_vertices[i]._diffuse=0xffffffff;
}
attribute->_vertices[0]._u=0.0f;
attribute->_vertices[0]._v=0.0f;
attribute->_vertices[1]._u=1.0f;
attribute->_vertices[1]._v=0.0f;
attribute->_vertices[2]._u=0.0f;
attribute->_vertices[2]._v=1.0f;
attribute->_vertices[3]._u=0.0f;
attribute->_vertices[3]._v=1.0f;
attribute->_vertices[4]._u=1.0f;
attribute->_vertices[4]._v=0.0f;
attribute->_vertices[5]._u=1.0f;
attribute->_vertices[5]._v=1.0f;
}
template<class Attribute>
void RippleSystem<Attribute>::preRender()
{
_device->SetTexture(0,_tex);
_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
_device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
_device->SetRenderState(D3DRS_LIGHTING, false);
_device->SetRenderState(D3DRS_ALPHATESTENABLE,true);
_device->SetRenderState(D3DRS_ALPHAREF,0x00000000);
_device->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATER);
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
_device->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_MODULATE);
_device->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
_device->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
}
template<class Attribute>
void RippleSystem<Attribute>::postRender()
{
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
_device->SetRenderState(D3DRS_ALPHATESTENABLE,false);
}
template<class Attribute>
void RippleSystem<Attribute>::render()
{
if( !_particles.empty() )
{
//
// set render states
//
preRender();
_device->SetTexture(0, _tex);
_device->SetFVF(RippleVertex::FVF);
_device->SetStreamSource(0, _vb, 0, sizeof(RippleVertex));
//
// render batches one by one
//
// start at beginning if we're at the end of the vb
if(_vbOffset >= _vbSize)
_vbOffset = 0;
RippleVertex* v = 0;
_vb->Lock(
_vbOffset * sizeof( RippleVertex ),
6*_vbBatchSize * sizeof( RippleVertex ),
(void**)&v,
_vbOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);
DWORD numParticlesInBatch = 0;
//
// Until all particles have been rendered.
//
std::list<Attribute>::iterator i;
for(i = _particles.begin(); i != _particles.end(); i++)
{
if( i->_isAlive )
{
//
// Copy a batch of the living particles to the
// next vertex buffer segment
//
for(int j=0;j<6;++j){
v->_diffuse = i->_vertices[j]._diffuse;
v->_x = i->_vertices[j]._x;
v->_y =
池塘夜雨 用directx做的
4星 · 超过85%的资源 需积分: 9 73 浏览量
2009-05-21
20:33:25
上传
评论 1
收藏 933KB RAR 举报
ghostwasd
- 粉丝: 0
- 资源: 2
最新资源
- 电力场景安全帽检测数据集VOC+YOLO格式295张2类别.7z
- MISC图片隐写MISC图片隐写MISC图片隐写MISC图片隐写MISC图片隐写.txt
- 七维大脑原理:探索人类心智的多元维度.txt
- 电力场景设备漏油检测数据集VOC+YOLO格式338张1类别.7z
- 基于yolov8+pyqt5实现精美界面支持图片视频和摄像检测源码.zip
- 用C语言为母亲节献上一份特别的祝福.zip
- LCD1602液晶显示屏的深入探索与实用指南.zip
- 基于Matlab人脸肤色定理的教师人数统计+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab霍夫曼变换的表盘读数识别+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab火灾烟雾检测源码带GUI界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈