Can't Get Particle System to work - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Can't Get Particle System to work

I can't get directx9 to render the point sprites. Right now ?I', trying to render all the particles at (320,240) before I add physics to them.

ParticleSystem.h
[code]
#ifndef _PARTICLE_
#define _PARTICLE_

#include
#include
#include
#include
#include "gfx_dx9.h"

using namespace std;

#define FVF_CUSTOM (D3DFVF_XYZ | D3DFVF_DIFFUSE)

enum ParticleState
{
PSTATE_ACTIVE,
PSTATE_DEAD
};

struct Vertex
{
D3DXVECTOR3 pos;
DWORD color;

Vertex()
{
pos=D3DXVECTOR3(0.0f,0.0f,0.0f);
color=D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);
}
};

inline DWORD FtoDW( FLOAT f ) { return *((DWORD*)&f); }

struct Particle
{
D3DXVECTOR3 position;
D3DCOLOR color;
float speed;
float friction;
float gravity;
float direction;

int life;

ParticleState state;

Particle()
{
position=D3DXVECTOR3( 0,0,0);
color=D3DXCOLOR( 1, 1, 1, 1);
speed=friction=gravity=direction=0;
state=PSTATE_ACTIVE;
}
Particle( D3DXVECTOR3 pos, float dir)
{
position=pos;
direction=dir;
color=D3DXCOLOR( 1, 1, 1, 1);
speed=friction=gravity=direction=0;
state=PSTATE_ACTIVE;
life=100;
}

void update()
{
life -=1;
if (life < 0){state=PSTATE_DEAD;}

float x_speed=cos( (D3DX_PI/ 180) * direction)*speed-friction;
float y_speed=sin( (D3DX_PI/ 180) * direction)*speed-gravity;
position+=D3DXVECTOR3( 320, 240, 0);
}
};

class emitter
{
public:
emitter( LPDIRECT3DDEVICE9 device, const char *tex, D3DXVECTOR3 pos,float spd, float frict, float grav, int lif);
~emitter();

inline float getRandomMinMax( float fMin, float fMax )
{
float fRandNum = (float)rand () / RAND_MAX;
return fMin + (fMax - fMin) * fRandNum;
}

void emit_stream( int count, D3DXVECTOR3 pos, float direction);
void emit_burst( int count, D3DXVECTOR3 pos, float min_direction, float max_direction);

void update();

private:
LPDIRECT3DDEVICE9 pDevice;
LPDIRECT3DVERTEXBUFFER9 pVertexBuffer;
LPDIRECT3DTEXTURE9 texture;

unsigned long MaxParticles;
int ParticleCount;
DWORD RenderCount;

D3DXVECTOR3 xyz;

float speed, friction, gravity;
int life;

vector ParticleArray;
};

#endif
[/code]

ParticleSystem.cpp
[code]

#include "particleSystem.h"

emitter::emitter( LPDIRECT3DDEVICE9 device, const char *tex, D3DXVECTOR3 pos,float spd, float frict, float grav, int lif):
pDevice( device),
xyz(pos)
{
MaxParticles = 256;
ParticleCount=0;

speed=spd;
friction=frict;
gravity=grav;
life=lif;

if (FAILED(pDevice->CreateVertexBuffer(
MaxParticles * sizeof(Vertex),
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY | D3DUSAGE_POINTS,
FVF_CUSTOM, // Our custom FVF
D3DPOOL_DEFAULT,
&pVertexBuffer, NULL )))
{
MessageBox( NULL, "Failed To Create Vertex Buffer", "Error", MB_OK);
}

if(FAILED(D3DXCreateTextureFromFile( pDevice, tex, &texture)))
{
MessageBox(NULL, "Could Not Load Particle Texture", "Error", MB_OK);
}

}

emitter::~emitter()
{
if (texture){texture->Release();}
if (pVertexBuffer){pVertexBuffer->Release();}

for (int i = 0; i < ParticleArray.size();++i)
{
if (ParticleArray[i])
{
delete ParticleArray[i];
ParticleArray[i] = NULL;
}
}

ParticleArray.clear();
}

void emitter::emit_stream( int count, D3DXVECTOR3 pos, float direction)
{
for (int i = 0; i < count; ++i)
{
if (ParticleArray.size() <= MaxParticles)
{
ParticleArray.push_back(new Particle( pos, direction));
}
}
}

void emitter::emit_burst( int count, D3DXVECTOR3 pos, float min_direction, float max_direction)
{
for (int i = 0; i < count;++i)
{
if (ParticleArray.size() <= MaxParticles)
{
float direction = getRandomMinMax( min_direction, max_direction);
ParticleArray.push_back(new Particle( pos, direction));
}
}
}

void emitter::update()
{
RenderCount=0;

pDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE ); // Turn on point sprites
pDevice->SetRenderState( D3DRS_POINTSCALEENABLE, TRUE ); // Allow sprites to be scaled with distance
pDevice->SetRenderState( D3DRS_POINTSIZE, FtoDW(0.8f) ); // Float value that specifies the size to use for point size computation in cases where point size is not specified for each vertex.
pDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(1.0f) ); // Float value that specifies the minimum size of point primitives. Point primitives are clamped to this size during rendering.
pDevice->SetRenderState( D3DRS_POINTSCALE_A, FtoDW(1.0f) );
pDevice->SetRenderState( D3DRS_POINTSCALE_B, FtoDW(1.0f) );
pDevice->SetRenderState( D3DRS_POINTSCALE_C, FtoDW(0.0f) );

pDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); // fountain particles
pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

pDevice->SetTexture( 0,texture);

Vertex *pVertices;
HRESULT hr;
hr=pVertexBuffer->Lock(0, ParticleArray.size()*sizeof(Vertex), (void**)&pVertices, D3DLOCK_DISCARD);

for (UINT i = 0; i < ParticleArray.size(); ++i)
{
if (ParticleArray[i]->state != PSTATE_DEAD && !FAILED(hr))
{
ParticleArray[i]->update();
pVertices->pos=ParticleArray[i]->position;
pVertices->color=ParticleArray[i]->color;
if (ParticleArray[i]->state != PSTATE_ACTIVE){ ParticleArray[i]->state=PSTATE_ACTIVE;}
++pVertices;
RenderCount++;
}
else
{
delete ParticleArray[i];
ParticleArray.erase(ParticleArray.begin()+i);
}
}

pVertexBuffer->Unlock();

if (RenderCount)
{
pDevice->SetStreamSource( 0, pVertexBuffer, 0, sizeof(Vertex));
pDevice->SetFVF(FVF_CUSTOM);
pDevice->DrawPrimitive(D3DPT_POINTLIST, 0, RenderCount);
}

pDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );
pDevice->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE );

pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
}
[/code]

Help will be appreciated.
Sign In or Register to comment.