Can't get particle system to display

Started by
28 comments, last by rahulpawar 13 years, 8 months ago
For some reason I can't get my particle system to work. I followed a tutorial in a Directx9 book, but made some mods. Can someone else test it to see if it works at all? If you do get it to work, can you post the source?

ParticleSystem.h
#ifndef _PARTICLE_#define _PARTICLE_#include <d3d9.h>#include <d3dx9.h>#include <math.h>#include <vector>using namespace std;#define FVF_CUSTOM (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)struct POINT_SPRITE{	float x, y, z;	DWORD PSIZE;	DWORD Diffuse;};class particle{private:protected:public:	D3DXVECTOR3 m_pos;	float m_direction;	DWORD m_size;	DWORD m_color;	DWORD m_duration;	DWORD m_life; // age	DWORD m_start_time;	DWORD m_speed;	particle()	{				m_pos = D3DXVECTOR3( 0, 0 ,0);		m_color = D3DCOLOR_XRGB( 0, 0 ,0);		m_size=m_duration=m_life=m_speed=m_start_time =0;	}	void update()	{		float x = cos(m_direction * 3.14f /180.0f) * m_speed;		float y = sin(m_direction * 3.14f /180.0f) * m_speed;		m_life = timeGetTime() - m_start_time;		m_pos += D3DXVECTOR3( x, y, 0);	}};class emitter{public:	emitter( LPDIRECT3DDEVICE9 dev, const char *fname);	~emitter();	 void Release();	 void update( float x, float y, float direction, float speed, int life);private:	LPDIRECT3DDEVICE9 lpDirect3dDevice9;	LPDIRECT3DVERTEXBUFFER9 lpVertexBuffer9;	LPDIRECT3DTEXTURE9 texture;	D3DXVECTOR3 xyz;	int max_particles;	particle *pParticles;};struct emitter_type{	const char* fname;	float m_direction;	DWORD m_size;	//DWORD m_color;	DWORD m_duration;	int m_life;	DWORD m_speed;};class particle_system{public:	particle_system( LPDIRECT3DDEVICE9 dev);	~particle_system();	int create_emitter( emitter_type &type);	void destroy_emitter( int index);	void update();private:	LPDIRECT3DDEVICE9 pDevice;	vector<emitter> emitter_list;	vector<emitter_type> type_list;};#endif


ParticleSystem.cpp
#include "particleSystem.h"//-------------------------------------------------------------------------//Particle System//-------------------------------------------------------------------------POINT_SPRITE pVertices[] ={	{0.0f, 0.0f, 0.0f, 10, 0xffff0000}, 	{1.0f, 1.0f, 0.0f, 10, 0xff00ff00},	{0.0f, 1.0f, 0.0f, 10, 0x0000ffff},		{1.0f, 0.0f, 0.0f, 10, 0x0000ffff}};particle_system::particle_system( LPDIRECT3DDEVICE9 dev):		pDevice( dev){}particle_system::~particle_system(){	for (vector<emitter>::iterator i = emitter_list.begin(); i != emitter_list.end(); ++i)	{		i->Release();	}	delete &emitter_list;	delete &type_list;}int particle_system::create_emitter( emitter_type &type){	emitter *temp = new emitter( pDevice, type.fname);	return emitter_list.size();	emitter_list.push_back( *temp);	type_list.push_back( type);}void particle_system::destroy_emitter( int index){	emitter_list.erase( emitter_list.begin() + index);}void particle_system::update(){	for (vector<emitter>::iterator i = emitter_list.begin(); i != emitter_list.end(); ++i){	for (vector<emitter_type>::iterator o = type_list.begin(); o != type_list.end(); ++o)	{		i->update( 320, 240, o->m_direction, o->m_speed, o->m_life);	}	}}//-------------------------------------------------------------------------//Emitter//-------------------------------------------------------------------------emitter::emitter( LPDIRECT3DDEVICE9 dev, const char *fname):	lpDirect3dDevice9( dev){		max_particles = 256;	pParticles = new particle[max_particles];	lpDirect3dDevice9->CreateVertexBuffer( max_particles*sizeof(POINT_SPRITE), 0, 	FVF_CUSTOM, D3DPOOL_DEFAULT, &lpVertexBuffer9, NULL);	VOID* vertices;	lpVertexBuffer9->Lock(128*sizeof(pVertices), 0, (void**)&vertices, NULL);	memcpy( pVertices, &vertices, sizeof(pVertices));	lpVertexBuffer9->Unlock();	D3DXCreateTextureFromFile( lpDirect3dDevice9,								fname,								&texture);}emitter::~emitter(){}void emitter::Release(){	if (lpVertexBuffer9) {lpVertexBuffer9->Release();}	if (texture) {texture->Release();}	if (pParticles) {delete [] pParticles;}}void emitter::update(float x, float y, float direction, float speed, int life){	DWORD time = timeGetTime();	POINT_SPRITE *POINT_SPRITEs = new POINT_SPRITE[max_particles];	xyz = D3DXVECTOR3(x,y,0);	for (DWORD counter = 0; counter < max_particles; ++counter)	{		if (pParticles[counter].m_life >= pParticles[counter].m_duration)		{			pParticles[counter].m_start_time = timeGetTime();			pParticles[counter].m_pos = xyz;			pParticles[counter].m_direction = direction;			pParticles[counter].m_speed = speed;			pParticles[counter].m_duration = life;		}		pParticles[counter].update();		POINT_SPRITEs[counter].x=pParticles[counter].m_pos.x;		POINT_SPRITEs[counter].y=pParticles[counter].m_pos.y;		POINT_SPRITEs[counter].z=0;	}	VOID* vertices;	lpVertexBuffer9->Lock(0 ,128*sizeof(pVertices), (void**)&vertices, NULL);	memcpy( vertices, POINT_SPRITEs, sizeof(POINT_SPRITEs));	lpVertexBuffer9->Unlock();	float MinSize=0.5f;	float Scale=1;	lpDirect3dDevice9->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);	lpDirect3dDevice9->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);	lpDirect3dDevice9->SetRenderState(D3DRS_POINTSIZE_MIN,*((DWORD*)&MinSize));	lpDirect3dDevice9->SetRenderState(D3DRS_POINTSCALE_A, *((DWORD*)&Scale));	lpDirect3dDevice9->SetRenderState(D3DRS_POINTSCALE_B, *((DWORD*)&Scale));	lpDirect3dDevice9->SetRenderState(D3DRS_POINTSCALE_C, *((DWORD*)&Scale));	lpDirect3dDevice9->SetStreamSource(0, lpVertexBuffer9, 0, sizeof(POINT_SPRITE));	lpDirect3dDevice9->SetFVF(FVF_CUSTOM);	lpDirect3dDevice9->SetTexture(0, texture);	lpDirect3dDevice9->DrawPrimitive(D3DPT_POINTLIST, 0, max_particles);}


Help will be much appreciated.

Thanks,
~Justin12343
Advertisement
Quote:POINT_SPRITE *POINT_SPRITEs = new POINT_SPRITE[max_particles];
memcpy( vertices, POINT_SPRITEs, sizeof(POINT_SPRITEs));

First: it doesn't appear that you check any function calls for indications of success or failure. You should make liberal use of the FAILED and SUCCEEDED macros.

Second: I don't know if this is the only problem, but POINT_SPRITEs is a pointer, not an array. So sizeof(POINT_SPRITEs)==sizeof(POINT_SPRITE*), not the size of the array in bytes. You're only copying the first few bytes of the array into the vertexbuffer.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I believe I have a simple fire particle engine demo code on my drive if you would like to use that as a reference?
Quote:Original post by Buckeye
Quote:POINT_SPRITE *POINT_SPRITEs = new POINT_SPRITE[max_particles];
memcpy( vertices, POINT_SPRITEs, sizeof(POINT_SPRITEs));

First: it doesn't appear that you check any function calls for indications of success or failure. You should make liberal use of the FAILED and SUCCEEDED macros.

Second: I don't know if this is the only problem, but POINT_SPRITEs is a pointer, not an array. So sizeof(POINT_SPRITEs)==sizeof(POINT_SPRITE*), not the size of the array in bytes. You're only copying the first few bytes of the array into the vertexbuffer.


Ok, I changed that part to this:

VOID* vertices = NULL;
lpVertexBuffer9->Lock(0 ,max_particles*sizeof(POINT_SPRITE), (void**)&vertices, NULL);
memcpy( vertices, pVertices, sizeof(POINT_SPRITE));
lpVertexBuffer9->Unlock();

But now I finding that the particle system class is not calling the update function in the for statement. It seems like the temp emitter is not being pushed back in the vector. The debugger says its size is still zero.
1: what's the point of having emitter type? you should put that information in the emitter... atleast put the struct there.

2: can you post the code were you use this particle system...

also your error about the vector being size 0 all the time is in this bit of code.

int particle_system::create_emitter( emitter_type &type){	emitter *temp = new emitter( pDevice, type.fname);	return emitter_list.size(); /** functions exits too early */	emitter_list.push_back( *temp);	type_list.push_back( type);}
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
Not sure if it helps but this is how the vertex buffer calls go in code I'm using (not mine):

v_buffer->Lock(0, 0, (void**)&pVoid, 0);memcpy(pVoid, stickManArm.vertices, sizeof(stickManArm.vertices));v_buffer->Unlock();


vbuffer is naturally the pointer to the buffer. pVoid is defined as:

VOID* pVoid

stickManArm is a struct containing the relevant vertices. I don't know enough to really help you. I tried to compile your code it seemed as though there's another file missing. Looks (to me) like these are just reference files storing data I couldn't find a main loop anywhere. It bounced when it hit the function timeGetTime().

If you include a bit more I might be able to help. Unlikely tho but the thought is there ;o) Good luck friend.
Quote:memcpy( vertices, pVertices, sizeof(POINT_SPRITE));

This is incorrect, also.

sizeof(POINT_SPRITE) is the size of a single POINT_SPRITE structure, not the size of the array pointed to by pVertices. pVertices holds 4 POINT_SPRITE structures, so you want 4*sizeof(POINT_SPRITE), or just sizeof(pVertices).

Think about the size of the pVertices array in bytes. That's the size you want to copy.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This was starting to get too complicated and disorganized, so I restarted on this from scratch.
Ok, My latest error:

Vertex *pVertices;	pVertexBuffer->Lock(0, ParticleArray.size()*sizeof(Vertex), (void**)&pVertices, D3DLOCK_DISCARD);	for (UINT i = 0; i < ParticleArray.size(); ++i)	{		if (ParticleArray->state != PSTATE_DEAD)		{		pVertices->pos=ParticleArray->position;		pVertices->color=ParticleArray->color;		++pVertices;		RenderCount++;		}	}


I get a Access Violation on the lock function. pVertices is not initialized, but this is how it was used in another tutorial.
Quote:pVertexBuffer->Lock(0, ParticleArray.size()*sizeof(Vertex), (void**)&pVertices, D3DLOCK_DISCARD);

Just try:

Lock(0,0,(void**)&pVertices,0);

D3DLOCK_DISCARD is for dynamic vertex buffers (and other things). If you don't know what that means, don't use it! [wink]

EDIT: Don't forget vertexBuffer->Unlock() when you're done.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement