Joined: February 28th, 2013, 3:23 amPosts: 2844Location: Oklahoma, United States

You know, sometimes the simplest solutions are the best.

Just spent the last couple days on the particle stuff ( since the 4th ) and have gone through about 4-5 rewrites and the final solution was much cleaner, easier to understand and easier to work with.

Just because it's easier, doesn't mean there isn't some work to be had to get the results you expect.

I have uploaded what I have so far. The demo this time is Fireworks. It's all in the master branch. I have two out of four particle emitters made. The first is a single emitter, it fires a single particle or single stream of particles depending on the delay, if any, between launches. The second is a radial emitter. It emits particles in a radius and random speeds. I played with this one the most. I probably need to make that a ranged variable, but for now you just enter a speed and it randomly chooses a value between 0 and speed.

The other two I haven't done yet, are going to be single stream and conical. The first I'm planning will hopefully be something like fire and the second would be water from a faucet or afterburners from a jet or ship. Just have to throw something together and see what comes out.

At present, and hopefully there won't be many changes, the way you create an emitter is:

For the Fireworks demo, I have the radial emitters spawn particles at the locations of the dead particles that were fired from the single emitter. Each group of particles that gets spawn from the radial emitter gets their own color. Those colors are stored in an array and randomly selected.

Right now, particles are dynamically allocated both using std::unique_ptr and std::vector, or more precisely, a std::vector<std::unique_ptr<Particle>>. My original idea was to pass around the dead particles in a messaging system, but that got complicated and messy. I think I will try having a vector for each emitter that is sized for what the user passes in, and just reuse those slots, moving the dead ones to the end or just finding a dead one and replacing it with a new one. This should cut down on dynamic allocations/reallocations and deallocations. Hopefully, this won't affect the interface too much.

Right now in Release I only use about 8% cpu and 6.3 MB of memory when spawning in 500 particles. I didn't setup a fps text on screen so I'm not sure if there was any frame rate issues, probably not with only 8% usage. In debug mode, you will notice a performance hit and is to be expected. I'll share results when I change from using vector of unique_ptrs to vector of Particles. Also, I'll put up a fps counter before and after.

_________________If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Joined: February 28th, 2013, 3:23 amPosts: 2844Location: Oklahoma, United States

Using a vector of smart pointers

Using a vector of objects

Well, after changing some things, CPU usage went up to 30%, but I still got a pretty descent framerate with vsync disabled...still gets 60 enabled.

Even though the fps is higher in the vector of smart pointers, it's not that big a difference and honestly after awhile of sitting there, they both reach about the same fps. The allocations are only 32 bytes per particle. At max, there are about 500 * 32 = 16,000 bytes being allocated/reallocated/deallocated so memory isn't the bottleneck. If there was one, it'd be all the alpha blending calculations done on the particles.

I think I'll keep the vector of objects though. Later if I decide to use SSE/AVX and or GPU, I'll want a vector of object. The GPU can't handle pointers and SIMD likes solid data as well.

Just did some more runs, increasing the particle counts. I can get between 3500 and 4000 particles on screen before I drop below 60 fps with vsync on. That should be plenty for most 2D games. That doesn't mean you'll get that if you start adding physics calculations and collision, not to mention all the other stuff that make up a game.

Now all I need to do is finish the other particle classes and I still want to have the particles use sprites to draw as well, instead of my colored balls.

_________________If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Joined: February 28th, 2013, 3:23 amPosts: 2844Location: Oklahoma, United States

Fun with particles:

Used an image to create a mask of just the top of her head, white pixels were spawn points for the particles.

I pretty much have the StreamEmitter finished. On to the Conical emitter. Changes not uploaded to GitHub as of yet. When I do, I'll go over the changes then, cause there are quite a few I think. The biggest reason for not uploading yet is the extra code for using std::async and the irrisponsible addition of some SIMD alpha blending code. I say irresponsible because I don't handle cases where the particles are less than 4 pixels wide...check out SSE if you want to know what that's about.

I've copied over a SIMD library that I've created on another project. I want to clean it up before really implementing it.

Cheers.

_________________If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum