Jump to content
  • Advertisement
Sign in to follow this  
malborojones

Smooth Rendering

This topic is 2991 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
Not sure :D


#define MAXNUM_PARTICLES 100

typedef 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 :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!