#include "EpParticleSystem.h"
#include <stdlib.h>
#include <time.h>
#include "EpLuaScriptEngine.h"
EpParticleSystem::EpParticleSystem( D3DVECTOR position, D3DVECTOR range,
D3DVECTOR acceleration, D3DVECTOR emitterPositionMin, D3DVECTOR emitterPositionMax,
D3DVECTOR velocityMin, D3DVECTOR velocityMax, D3DCOLORVALUE colorMin,
D3DCOLORVALUE colorMax, float psizeMin, float psizeMax,
int maxCount, int emitCount, float emitInterval,
LPDIRECT3DDEVICE9 device, const char *textureFileName )
{
m_Pos = position;
m_Range = range;
m_Accel = acceleration;
m_EmiPosMin = emitterPositionMin;
m_EmiPosMax = emitterPositionMax;
m_VeloMin = velocityMin;
m_VeloMax = velocityMax;
m_ColorMin = colorMin;
m_ColorMax = colorMax;
m_PSizeMin = psizeMin;
m_PSizeMax = psizeMax;
m_Count = 0;
m_MaxCount = maxCount;
m_EmiCount = emitCount;
m_EmiInterval = emitInterval;
m_Interval = 0.0f;
m_pDevice = device;
m_TexFileName = NULL;
if (textureFileName)
{
int length = strlen(textureFileName) + 1;
m_TexFileName = new char[length];
strcpy_s(m_TexFileName, length,textureFileName);
}
m_pTexture = NULL;
m_Particles = NULL;
m_pVB = NULL;
//随机数种子
srand( (unsigned)time( NULL ) );
//计算世界矩阵
D3DXMatrixTranslation(&m_WorldMat, m_Pos.x, m_Pos.y, m_Pos.z);
}
bool EpParticleSystem::Initialize()
{
if (m_pDevice == NULL)
{
return false;
}
//构建粒子池
m_Particles = new EpParticle[m_MaxCount];
if (m_Particles == NULL)
{
return false;
}
//创建顶点缓冲区
if(FAILED(m_pDevice->CreateVertexBuffer(sizeof(stParticleVertex) * m_MaxCount,
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY | D3DUSAGE_POINTS,
D3DFVF_PARTICLE, D3DPOOL_DEFAULT, &m_pVB, NULL)))
return false;
//创建纹理
if (m_TexFileName != NULL)
{
D3DXCreateTextureFromFile(m_pDevice, m_TexFileName,&m_pTexture);
}
return true;
}
void EpParticleSystem::Update( float delta )
{
EpParticle *p = NULL;
for (int i = 0; i < m_Count; i++)
{
//改变粒子的速度与位置
p = &m_Particles[i];
p->pos += p->velo;
p->velo += m_Accel;
//检查粒子是否超出边界
if (!(p->pos.x <= m_Range.x/2 && p->pos.x >= -m_Range.x/2 &&
p->pos.y <= m_Range.y/2 && p->pos.y >= -m_Range.y/2 &&
p->pos.z <= m_Range.z/2 && p->pos.z >= -m_Range.z/2 ))
{
//将最后一个粒子移到该位置
m_Particles[i] = m_Particles[m_Count-1];
m_Count--; //抛弃最后一个粒子
i--; //重新检查该粒子
}
}
//发射粒子
m_Interval += delta;
if (m_Interval >= m_EmiInterval)
{
emit(m_EmiCount);
m_Interval -= m_EmiInterval;
}
}
//生成随机数
float rangeRand( float min, float max )
{
return (float)rand() / RAND_MAX * (max - min) + min;
}
//发射一定数量的粒子
void EpParticleSystem::emit( int emitCount )
{
EpParticle *p = NULL;
for (int i = 0; i < emitCount; i++)
{
if (m_Count == m_MaxCount) break;
p = &m_Particles[m_Count];
p->pos.x = rangeRand(m_EmiPosMin.x, m_EmiPosMax.x);
p->pos.y = rangeRand(m_EmiPosMin.y, m_EmiPosMax.y);
p->pos.z = rangeRand(m_EmiPosMin.z, m_EmiPosMax.z);
p->velo.x = rangeRand(m_VeloMin.x, m_VeloMax.x);
p->velo.y = rangeRand(m_VeloMin.y, m_VeloMax.y);
p->velo.z = rangeRand(m_VeloMin.z, m_VeloMax.z);
p->psize = rangeRand(m_PSizeMin, m_PSizeMax);
p->color.r = rangeRand(m_ColorMin.r, m_ColorMax.r);
p->color.g = rangeRand(m_ColorMin.g, m_ColorMax.g);
p->color.b = rangeRand(m_ColorMin.b, m_ColorMax.b);
p->color.a = rangeRand(m_ColorMin.a, m_ColorMax.a);
m_Count++;
}
}
bool EpParticleSystem::Render()
{
if (m_Count == 0)
{
return true;
}
//将粒子从粒子池转移到顶点缓冲区
stParticleVertex *p;
if(FAILED(m_pVB->Lock(0, sizeof(stParticleVertex) * m_Count, (void**)&p, 0)))
return false;
for (int i = 0; i < m_Count; i++)
{
p[i].pos = m_Particles[i].pos;
p[i].psize = m_Particles[i].psize;
p[i].color = D3DCOLOR_COLORVALUE(m_Particles[i].color.r,
m_Particles[i].color.g, m_Particles[i].color.b, m_Particles[i].color.a);
}
m_pVB->Unlock();
m_pDevice->SetTransform(D3DTS_WORLD, &m_WorldMat);
m_pDevice->SetTexture(0, m_pTexture);
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
m_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_POINTSCALE_A, FtoDW(0.0f));
m_pDevice->SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.0f));
m_pDevice->SetRenderState(D3DRS_POINTSCALE_C, FtoDW(10.0f));
m_pDevice->SetFVF(D3DFVF_PARTICLE);
m_pDevice->SetStreamSource(0, m_pVB, 0, sizeof(stParticleVertex));
m_pDevice->DrawPrimitive(D3DPT_POINTLIST, 0, m_Count);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
return true;
}
EpParticleSystem::~EpParticleSystem()
{
if (m_Particles != NULL)
{
delete[] m_Particles;
m_Particles = NULL;
}
if (m_pVB != NULL)
{
m_pVB->Release();
m_pVB = NULL;
}
if (m_pTexture != NULL)
{
m_pTexture->Release();
m_pTexture = NULL;
}
if (m_TexFileName != NULL)
{
delete[] m_TexFileName;
m_TexFileName = NULL;
}
}
EpParticleSystem * EpParticleSystem::CreateFromFile( LPDIRECT3DDEVICE9 device, const char *fileName )
{
if (!fileName) return NULL;
//初始化lua,加载粒子脚本
EpLuaScriptEngine lua;
lua.LoadScript(fileName);
D3DVECTOR position = {0}; //粒子系统的位置
lua.GetTFloat("position", 1, &position.x);
lua.GetTFloat("position", 2, &position.y);
lua.GetTFloat("position", 3, &position.z);
D3DVECTOR range = {0}; //长宽高范围
lua.GetTFloat("range", 1, &range.x);
lua.GetTFloat("range", 2, &range.y);
lua.GetTFloat("range", 3, &range.z);
D3DVECTOR accel = {0}; //加速度
lua.GetTFloat("accel", 1, &accel.x);
lua.GetTFloat("accel", 2, &accel.y);
lua.GetTFloat("accel", 3, &accel.z);
D3DVECTOR emiPosMin = {0}; //发射位置的范围
lua.GetTFloat("emiPosMin", 1, &emiPosMin.x);
lua.GetTFloat("emiPosMin", 2, &emiPosMin.y);
lua.GetTFloat("emiPosMin", 3, &emiPosMin.z);
D3DVECTOR emiPosMax = {0};
lua.GetTFloat("emiPosMax", 1, &emiPosMax.x);
lua.GetTFloat("emiPosMax", 2, &emiPosMax.y);
lua.GetTFloat("emiPosMax", 3, &emiPosMax.z);
D3DXVECTOR3 veloMin; //粒子初始速度范围
ZeroMemory(&veloMin,sizeof(veloMin));
lua.GetTFloat("veloMin", 1, &veloMin.x);
lua.GetTFloat("veloMin", 2, &veloMin.y);
lua.GetTFloat("veloMin", 3, &veloMin.z);
D3DXVECTOR3 veloMax;
ZeroMemory(&veloMax,sizeof(veloMax));
lua.GetTFloat("veloMax", 1, &veloMax.x);
lua.GetTFloat("veloMax", 2, &veloMax.y);
lua.GetTFloat("veloMax", 3, &veloMax.z);
D3DCOLORVALUE colorMin = {0}; //粒子颜色范围
lua.GetTFloat("colorMin", 1, &colorMin.a);
lua.GetTFloat("colorMin", 2, &colorMin.r);
lua.GetTFloat("colorMin", 3, &colorMin.g);
lua.GetTFloat("colorMin", 4, &colorMin.b);
D3DCOLORVALUE colorMax = {0};
lua.GetTFloat("colorMax", 1, &colorMax.a);
lua.GetTFloat("colorMax", 2, &colorMax.r);
lua.GetTFloat("colorMax", 3, &colorMax.g);
lua.GetTFloat("colorMax", 4, &colorMax.b);
float psizeMin = 0.0f; //粒子大小范围
lua.GetFloat("psizeMin", &psizeMin);
float psizeMax = 0.0f;
lua.GetFloat("psizeMax", &psizeMax);
int maxCount = 0; //最大粒子数量
lua.GetInt("maxCount", &maxCount);
int emiCount = 0; //每次发射数量
lua.GetInt("emiCount", &emiCount);
float emiInterval = 1.0f; //发射间隔时间
lua.GetFloat("emiInterval", &emiInterval);
const char *textureFile = NULL;
lua.GetString("texture", &textureFile);
EpParticleSystem *ps = new EpParticleSystem(position,range,accel,emiPosMin,
emiPosMax,veloMin,veloMax,colorMin,colorMax,psizeMin,psizeMax,maxCount,
emiCount,emiInterval,device,textureFile);
return ps;
}
基于Direct3D的基本粒子系统(支持Lua编写粒子脚本)
4星 · 超过85%的资源 需积分: 10 165 浏览量
2009-09-14
20:56:16
上传
评论
收藏 17KB RAR 举报
ntwilford
- 粉丝: 47
- 资源: 17
最新资源
- 筷手引流工具.apk
- 论文(最终)_20240430235101.pdf
- 基于python编写的Keras深度学习框架开发,利用卷积神经网络CNN,快速识别图片并进行分类
- 最全空间计量实证方法(空间杜宾模型和检验以及结果解释文档).txt
- 5uonly.apk
- 蓝桥杯Python组的历年真题
- 2023-04-06-项目笔记 - 第一百十九阶段 - 4.4.2.117全局变量的作用域-117 -2024.04.30
- 2023-04-06-项目笔记 - 第一百十九阶段 - 4.4.2.117全局变量的作用域-117 -2024.04.30
- 前端开发技术实验报告:内含4四实验&实验报告
- Highlight Plus v20.0.1
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
前往页