Particle systems not independent.

Started by
4 comments, last by xsirxx 19 years, 7 months ago
Okay I'm sure this is probably a stupid question but all my OOP knowledge is self taught so there's a lot of stuff about classes that's kind of like magic to me. Basically, I've created a class that is a particle system (in this case an explosion), it works great... the only problem is when I create a second one, only one explosion works at a time! Basically, they both work, but if one explosion is active when the other particle system activates, the one that was already going dissappears. I could paste all of my code but since that'd be a bit much I'll just paste the class definition for now. Something obviously is linking the two together but I don't know what. One time I had a bizarre problem where my class used a pointer and whenever I created new objects of that class type it shared the same pointer, so maybe it's something like that. I'm pretty clueless.

class ParticleSys : public CBase
{

private: 
	
	LPDIRECT3DVERTEXBUFFER9 m_particleVertexBuffer;
	Particle g_particles[200];
	double dStartAppTime;

public:
	bool isActive;
	LPDIRECT3DTEXTURE9 m_texParticle;
	void initPointSprites( LPDIRECT3DDEVICE9 m_pD3DDevice);
	void begin(float originX, float originY, float originZ);
	void updatePointSprites( void );
	void renderPointSprites( LPDIRECT3DDEVICE9 m_pD3DDevice );
	D3DXVECTOR3 getRandomVector( void );
	float getRandomMinMax( float fMin, float fMax );

	// Constructor - Sets the default variables for the particle system
	ParticleSys()
	{
		m_particleVertexBuffer = 0;
		m_texParticle = 0;
		dStartAppTime = 0;
		isActive = false;
	}
	// Destructor - cleans up behind itself
	~ParticleSys()
	{
		SafeRelease(m_particleVertexBuffer);
		SafeRelease(m_texParticle);
	}


};

Basically everything is perfect except when one particle system starts the other one disappears. All of the stuff related to the particle systems is in that class. Shouldn't the two objects I created completely seperate? aah!
Advertisement
Well post yer rending function... its probably in there somewhere, either yer vertex buffer or when u change yer matricies for positioning, or could be changing over yer texture? Post that it could help.

EDIT:
void renderPointSprites( LPDIRECT3DDEVICE9 m_pD3DDevice );
Also do a debug to make sure that they arent overwriting each other in yer array or list in a loop. So just step through and check yer positions to make sure they are in the correct units for view.
--X
Here's my rendering function:

void ParticleSys::renderPointSprites( LPDIRECT3DDEVICE9 m_pD3DDevice ){	//	// Setting D3DRS_ZWRITEENABLE to FALSE makes the Z-Buffer read-only, which 	// helps remove graphical artifacts generated from  rendering a list of 	// particles that haven't been sorted by distance to the eye.	//    // Setting D3DRS_ALPHABLENDENABLE to TRUE allows particles, which overlap, 	// to alpha blend with each other correctly.	//		m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);	m_pD3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );	m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );	m_pD3DDevice->SetRenderState( D3DRS_SRCBLEND,D3DBLEND_SRCALPHA );	m_pD3DDevice->SetRenderState( D3DRS_DESTBLEND,D3DBLEND_ONE );	m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );	m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE);	m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );	m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);	//	// Set up the render states for using point sprites...	//    m_pD3DDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );    // Turn on point sprites    m_pD3DDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  TRUE );    // Allow sprites to be scaled with distance    m_pD3DDevice->SetRenderState( D3DRS_POINTSIZE,     FtoDW(1.0) );  // Float value that specifies the size to use for point size computation in cases where point size is not specified for each vertex.    m_pD3DDevice->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.     m_pD3DDevice->SetRenderState( D3DRS_POINTSCALE_A,  FtoDW(0.0f) ); // Default 1.0    m_pD3DDevice->SetRenderState( D3DRS_POINTSCALE_B,  FtoDW(0.0f) ); // Default 0.0    m_pD3DDevice->SetRenderState( D3DRS_POINTSCALE_C,  FtoDW(1.0f) ); // Default 0.0	//	// Lock the vertex buffer, and set up our point sprites in accordance with 	// our particles that we're keeping track of in our application.	//	m_pD3DDevice->SetTexture( 0, m_texParticle);	m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);	Vertex *pPointVertices;	m_particleVertexBuffer->Lock( 0, MAX_PARTICLES * sizeof(Vertex),		                   (void**)&pPointVertices, D3DLOCK_DISCARD );	for( int i = 0; i < MAX_PARTICLES; ++i )    {        pPointVertices->posit = g_particles.m_vCurPos;        pPointVertices->color = g_particles.m_vColor;        pPointVertices++;    }    m_particleVertexBuffer->Unlock();		//	// Render point sprites...	//    m_pD3DDevice->SetStreamSource( 0, m_particleVertexBuffer, 0, sizeof(Vertex) );    m_pD3DDevice->SetFVF( Vertex::FVF_Flags );	m_pD3DDevice->DrawPrimitive( D3DPT_POINTLIST, 0, MAX_PARTICLES );	//    // Reset render states...	//	    m_pD3DDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );    m_pD3DDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  FALSE );    m_pD3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );    m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );	m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);}


I've had a bit of trouble debugging it because it uses timers for the explosion effect and debugging obviously throws that way off.
you should use smth like this:
in your main application class write

CMainClass::CMainClass()
{
...
...
particleSystem1 = new ParticleSys ();
particleSystem2 = new ParticleSys ();
particleSystem3 = new ParticleSys ();
...
}

and later in program use:
particleSystem1->renderPointSprites();
particleSystem2->renderPointSprites();

etc...

Well after looking through, u have
m_pD3DDevice->DrawPrimitive( D3DPT_POINTLIST, 0, MAX_PARTICLES );


shouldnt that be:

m_pD3DDevice->DrawPrimitive( D3DPT_POINTLIST, 0, FILL HERE);

where FILL HERE is the Actual number of particles in the buffer? or is MAX always maxed?

??? Also do you do have to do a transform or do u do it before hand? Obviously yer getting one to the screen but not all? so u prolly have the correct perspective... My idea is that yer only rendering one per frame and not all.. so could be yer size of the vertex buffer? & Dizz is right, are u declaring 2 particle systems? or just one and trying to reuse?
--X
I do something like this:

	DWORD dwNumParticlesToRender = 0;	for(int max = 0; max < MAXTYPES; max++){		if(max == 0){			vbParticles->Lock(0, iVBSize * sizeof(VERTEX_PARTICLE), (BYTE **) &pVertices, D3DLOCK_DISCARD);			for(int i = 0; i < MAXRAIN; i++){				if(partRain.IsAlive() == TRUE){				Particle &part = partRain;  				pVertices->position = part.vPos;				pVertices->pointsize = part.fSize;				pVertices->color = (DWORD)part.cColor;				pVertices++;				++dwNumParticlesToRender;				}				}		vbParticles->Unlock();		pd3dDevice->SetTexture(0, texParticle[max]);		pd3dDevice->DrawPrimitive(D3DPT_POINTLIST, 0, dwNumParticlesToRender);		dwNumParticlesToRender = 0;		}		


dont worry about max, it is just a type for isntance, rain, snow.. if I have more i plug them in... damn old code heh
--X

This topic is closed to new replies.

Advertisement