Since I usually recode a system someone has donated for public consumption (As they never quite fit my style or project to the Tee), here is a quick run down on how the system functions.:
A. Create a mesh, parent it to the camera (this mesh will hold all the cloud puffs, and it will keep them relative to the camera, so that's nice). Paint the mesh with the cloud template (alpha mapped of course).
B. Create a linked list called cloud or something. In this list, you need to know:
1. A Pivot (This tells us where the cloud particle is in the world)
2. A Mesh (Mesh we are drawing to, this is mostly for speed and expandability)
3. A Surface (the mesh surface, we keep this in the list for speed reasons)
4. Width and Height (of the cloud particle)
5. U and V offset and UV width and height (For the offset of the texture to use)
6. Camera (for speed, we can translate to this camera)
7. X, Y, Z (local coordinates used to draw sprite)
The reason we keep such info in the linked list is because leaving a function when your updating 8,000 some odd particles can cost you dearly! Might as well have the info at hand.
So when we create a cloud particle, we tell it what camera, what mesh (And surface of course), its width, height, and UV offsets (what area of the texture we are needing). Along with a camera of course.
Some of this could be global as well I guess, but for expandability, its smart just to keep it in the list and supply the info as needed.
So, we position the list\pivot where we want the cloud particle to appear. The width and height are set to our width and height needed for the particle. Now lets update the particles:
Now lets create 2 arrays to store the sorting information.
Array1.CLOUD(10000) ;This is for storing our cloud particle refference
Array2#(10000) ;Stores the Z value after the transformation
You could put some of these in their own function, however leaving a function in a loop of 8-10000 gets cpu expensive. just stay in the loop with your calculations if possible:
---update loop:
Transform the pivot x,y,z to the local coordinates of the camera.
If it has a new Z > 0 then it's in front of the camera (< 0 and its behind, and ignore it).
Save the transformed coordinates in our Z,Y,Z of this list
If we can see the particle, add it to the array
CloudCount = CloudCount + 1
Array1.CLOUD(CloudCount) = This.Cloud
Array2#(CloudCount) = NewZ
---End Update looop
K, now lets clear the surface(mesh) of all triangles and verticies. It's easier just to draw new ones than re-use the old ones (specially with alpha sorting involved).
Now use quicksort and sort the arrays. Just sort based on Array2, and when it does a swap of locations, swap Array1 as well (so the refference follows the Z location).
Now loop through the array, smalles to biggest, and draw the particle on the mesh. (remember to stay in the loop, dont call other functions if you can help it).
For ThisCloud = 1 to CloudCount
ThisWidth# =Array1(ThisCloud)\Width * .5
ThisHeight# =Array1(ThisCloud)\Height * .5
ThisUWidth# =Array1(ThisCloud)\UWidth * .5
ThisVWidth# =Array1(ThisCloud)\VWidth * .5
V1 =addvertex(Array1(ThisCloud)\Surface, Array1(ThisCloud)\X - ThisWidth#, Array1(ThisCloud)\Y + ThisHeight#,Array1(ThisCloud)\Z, Array1(ThisCloud)\U,Array1(ThisCloud)\V)
V1 =addvertex(Array1(ThisCloud)\Surface, Array1(ThisCloud)\X + ThisWidth#, Array1(ThisCloud)\Y + ThisHeight#,Array1(ThisCloud)\Z, Array1(ThisCloud)\U+ThisUWidth#,Array1(ThisCloud)\V)
V1 =addvertex(Array1(ThisCloud)\Surface, Array1(ThisCloud)\X + ThisWidth#, Array1(ThisCloud)\Y - ThisHeight#,Array1(ThisCloud)\Z, Array1(ThisCloud)\U+ThisUWidth#,Array1(ThisCloud)\V+ThisVWidth#)
V1 =addvertex(Array1(ThisCloud)\Surface, Array1(ThisCloud)\X - ThisWidth#, Array1(ThisCloud)\Y - ThisHeight#,Array1(ThisCloud)\Z, Array1(ThisCloud)\U,Array1(ThisCloud)\V+ThisVWidth#)
AddTriangle(Array1(ThisCloud)\Surface, V1, V2, V3)
AddTriangle(Array1(ThisCloud)\Surface, V3, V4, V1)
Next
And there you have it (pretty much). It's a bit long winded of how simple it really is. You can also add stuff like vertex coloring and alpha to each cloud as well. This is all off the top of my head, so take it for face value.
[/book]