Smooth Rendering

Started by
5 comments, last by demonkoryu 14 years ago
I'm making particle systems and even a small amount of particles ( 50 - 100 ) causes the frame rate to drop dramatically, I'm using a method that finds the time taken for each frame to render and multiply the velocity of the particles by the frame rate but it still shows huge lag! Could someone point me in the direction of an example on how to render things more smoothly or show me how? :) Thanks, Malb.
Never refuse a cup of tea, that's how wars are started.
Advertisement
How are you drawing your particles?
More details pls. Are u using vertex/pixel shader? Are u using point sprites?
My dev blog: gameluna.blogspot.com
Not sure :D

#define MAXNUM_PARTICLES 100typedef struct{	// the current position of the particle	D3DXVECTOR3 m_vCurPos;	// the movement vector	D3DXVECTOR3 m_vCurVel;	// the color of the particle	D3DCOLOR m_vColor;	float life;} particles;void initFire ( void ) {	for (int i = 0 ; i < MAXNUM_PARTICLES ; i++ )	{		fireParticles.m_vCurPos = D3DXVECTOR3(0.0f,0.0f,0.0f);		float vecX = ((float)rand() / RAND_MAX);		float vecY = ((float)rand() / RAND_MAX);		float vecZ = ((float)rand() / RAND_MAX);		//make random directions		float randX = ((float)(rand()% 100) / 100) - ((float)(rand()% 100) / 100);		float randY = ((float)(rand()% 100) / 100) - ((float)(rand()% 100) / 100);		float randZ = ((float)(rand()% 100) / 100) - ((float)(rand()% 100) / 100);		vecX *= randX; 		vecY *= randY; 		vecZ *= randZ;		// Using the random values generated above, set the movement vector		// for this particle		fireParticles.m_vCurVel = D3DXVECTOR3 (vecX, vecY, vecZ) / syncRate;		// Each particle is green and has full alpha		fireParticles.m_vColor = D3DCOLOR_RGBA (255, 255, 255, 255);		fireParticles.life = (float)(rand()% 1000) + 500;	}	D3DXCreateTextureFromFile ( pd3dDevice, L"test.bmp", &pParticleTexture);	return;}void updateParticles( ){		for( int i = 0; i < MAXNUM_PARTICLES; ++i )	{		fireParticles.m_vCurPos += fireParticles.m_vCurVel * animRate;		fireParticles.life--;		if ( fireParticles.life < 1 )		{			fireParticles.m_vCurPos = D3DXVECTOR3( 0.0f, 0.0f, 0.0f);			fireParticles.life = (float)(rand()% 1000) + 500;		}	}	}


And rendering them like this:

void renderParticles( void ){	pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );    pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );    pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );	// enable pointsprite render states	// turn on pointsprites    pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );	// enable scaling    pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  TRUE );	// the point size to use when the vertex does not include this information    pd3dDevice->SetRenderState( D3DRS_POINTSIZE,     FLOAT_TO_DWORD(1.0f) );	// the minimum size of the points    pd3dDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FLOAT_TO_DWORD(1.0f) );	// these three renderstates control the scaling of the pointsprite    pd3dDevice->SetRenderState( D3DRS_POINTSCALE_A,  FLOAT_TO_DWORD(0.0f) );    pd3dDevice->SetRenderState( D3DRS_POINTSCALE_B,  FLOAT_TO_DWORD(0.0f) );    pd3dDevice->SetRenderState( D3DRS_POINTSCALE_C,  FLOAT_TO_DWORD(1.0f) );	// Lock the vertex buffer, and set up our point sprites in accordance with 	// our particles that we're keeping track of in our application.	CUSTOMVERTEX *pPointVertices;	g_pVertexBuffer->Lock( 0, MAXNUM_PARTICLES * sizeof(CUSTOMVERTEX),		                   (void**)&pPointVertices, D3DLOCK_DISCARD );	for( int i = 0; i < MAXNUM_PARTICLES; ++i )    {        pPointVertices->psPosition = fireParticles.m_vCurPos;        pPointVertices->color = fireParticles.m_vColor;        pPointVertices++;    }    g_pVertexBuffer->Unlock();		//	// Render point sprites...	//	pd3dDevice->SetTexture( 0, pParticleTexture );    pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX) );	pd3dDevice->SetFVF( CUSTOMFVF );	pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, 0, MAXNUM_PARTICLES );    // Reset render states...    pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );    pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  FALSE );    pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );    pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );}


Since adding a frameRate variable it works better but is still very sticky to start and smooths out as some of the particles move off the screen so it could just be a consequence of having a rubbish graphics card :)
Never refuse a cup of tea, that's how wars are started.
What card do you have?
It's an on board one :( keep thinking of buying a proper one but always forget, shall get one soon. Thing is what if someone with a rubbish GC where to play my game, I'd still like them to have a good experience.
Never refuse a cup of tea, that's how wars are started.
A cheap optimization I see is to use array indexing while accessing pPointVertices; in the same way you're indexing into fireParticles.
This can improve the quality of the compilers code optimizer, because then it doesn't need to assume pointer aliasing.

It won't make much difference, but sometimes every bit helps.

This topic is closed to new replies.

Advertisement