Textured Quads Particle System

Started by
16 comments, last by belfegor 13 years, 6 months ago
I'm trying to implement a Textured Quads Particle System and I've read a lot about billboarding and there's something I can't yet figure out,
In my implementation I have this structure as the Particle structure
struct ParticleVertex{	D3DXVECTOR3 initialpos;	float U,V;	D3DXVECTOR3 initialVelocity;	float initialSize;	float initialTime;	float lifeTime;	float mass;	D3DCOLOR beginColor;};

Where initalpos is supposed to be the center of the quad and my VertexBuffer is Created once as a dynamic one with size equal numberofParticles* 4 (as each particle has 4 vertices). and pass the system to the VS to do the integration on the position.
What I'm missing is how I can update the buffer afterwards based on the new position (I mean updating the 4 vertices of each quad, based on the new center resulting from the integration)
Advertisement
You're going to need each quad to be made of 6 vertices, because the system is going to need to be drawn as a triangle list.

If I were you, I wouldn't update the list in real time at all...let the shader move the points around it. Build the vertices with information that is velocity etc, then just pass down delta time, an origin etc. to the shader once for each system.
Yeah they are 6 vertices sorry :), but I can't get what u mean by letting the shader move them??, I can't understand that
Its better to use 4 vertices for each particle drawed as indexed triangle list.
You can try this:
http://www.codesampler.com/dx9src/dx9src_7.htm#dx9_particle_system
its for point sprites but you can rewrite it to use with billboarded quads.
I have already done a particle system framework for Point Sprites and used it to build a fog system.my problem is how it can be transformed to use billboards and that's what I'm working on and can't figure it exactly how to handle the 4 or 6 vertices that will represent the particle
...float f = 0.5f * (float)ParticleSize;Vector3 horizontal(viewMat.M00 * f, viewMat.M10 * f, viewMat.M20 * f);f = -0.5f * (float)ParticleSize;Vector3 vertical(viewMat.M01 * f, viewMat.M11 * f, viewMat.M21 * f);Vector3 view(-viewMat.M02, -viewMat.M12 , -viewMat.M22);D3D9Device->SetVertexDeclaration(...);D3D9Device->SetIndices(...);D3D9Device->SetStreamSource(...);UINT numVert    = 0;UINT numTri     = 0;Vertex3D_PNCT1* pVertices = 0;VBuffer->Lock((LPVOID*)&pVertices, D3DLOCK_DISCARD);for(DWORD i = 0; i < (DWORD)AParticles.Size(); i++){    const Particle& particle                   = AParticles;    Vector3 shorizontal = horizontal * particle.Scale;    Vector3 svertical   = vertical * particle.Scale;    pVertices[0 + numVert].Position         = particle.Position + shorizontal + svertical;        pVertices[0 + numVert].Normal           = view;        pVertices[0 + numVert].TexCoord0        = Vector2(0.0f, 0.0f);        pVertices[0 + numVert].Color            = particle.Color;        pVertices[1 + numVert].Position         = particle.Position + shorizontal - svertical;        pVertices[1 + numVert].Normal           = view;        pVertices[1 + numVert].TexCoord0        = Vector2(0.0f, 1.0f);        pVertices[1 + numVert].Color            = particle.Color;        pVertices[2 + numVert].Position         = particle.Position - shorizontal - svertical;        pVertices[2 + numVert].Normal           = view;        pVertices[2 + numVert].TexCoord0        = Vector2(1.0f, 1.0f);        pVertices[2 + numVert].Color            = particle.Color;        pVertices[3 + numVert].Position         = particle.Position - shorizontal + svertical;        pVertices[3 + numVert].Normal           = view;        pVertices[3 + numVert].TexCoord0        = Vector2(1.0f, 0.0f);        pVertices[3 + numVert].Color            = particle.Color;        if(particle.Rotation)        {            Vector2 centerCoord(0.5f, 0.5f);            pVertices[0 + numVert].TexCoord0.RotateBy(particle.Rotation, centerCoord);            pVertices[1 + numVert].TexCoord0.RotateBy(particle.Rotation, centerCoord);            pVertices[2 + numVert].TexCoord0.RotateBy(particle.Rotation, centerCoord);            pVertices[3 + numVert].TexCoord0.RotateBy(particle.Rotation, centerCoord);        }        numVert    += 4;        numTri     += 2;        if(numVert > (VBuffer->GetNumVertices() - 4))        {            VBuffer->Unlock();            D3D9Device->DrawIndexedPrimitive(                D3DPT_TRIANGLELIST, 0, 0, numVert, 0, numTri);            pVertices = 0;            numVert   = 0;            numTri    = 0;            VBuffer->Lock((LPVOID*)&pVertices, D3DLOCK_DISCARD);        }}VBuffer->Unlock();if(numVert > 0){	D3D9Device->DrawIndexedPrimitive(			D3DPT_TRIANGLELIST, 0, 0, numVert, 0, numTri);}...
I forget to add code for indices:
UINT numIndices = numParticles * 6;USHORT* pIndices = 0;IBuffer->Lock((LPVOID*)&pIndices);USHORT j = 0;for(USHORT i = 0; i < numIndices; i += 6){	pIndices[0+i] = 0+j;	pIndices[1+i] = 2+j;	pIndices[2+i] = 1+j;	pIndices[3+i] = 0+j;	pIndices[4+i] = 3+j;	pIndices[5+i] = 2+j;	j += 4;}IBuffer->Unlock();


any progress?
Thanks for your help and code :), Sorry I had some connection problems so couldn't be online, I'll work on your code tomorrow as it is late here to start today :).
Thanks again :)
What I do for my particles is something like this:

ever frame:
update every particle position, check for deaths, etc.
lock vertex buffer
fill it up with particle positions, colours, etc.
unlock buffer
then a single DrawPrimitive() call renders them all

If you aren't sure how to billboard check out this post (Lord Evil), it helped me a lot:

http://www.gamedev.net/community/forums/topic.asp?topic_id=415727

Good luck.
There's something I don't understand in the code. May you please explain this part
float f = 0.5f * (float)ParticleSize;Vector3 horizontal(viewMat.M00 * f, viewMat.M10 * f, viewMat.M20 * f);f = -0.5f * (float)ParticleSize;Vector3 vertical(viewMat.M01 * f, viewMat.M11 * f, viewMat.M21 * f);Vector3 view(-viewMat.M02, -viewMat.M12 , -viewMat.M22);


Thanks

This topic is closed to new replies.

Advertisement