4

I'm trying to put a particle system together in Android, using OpenGL. I want a few thousand particles, most of which will probably be offscreen at any given time. They're fairly simple particles visually, and my world is 2D, but they will be moving, changing colour (not size - they're 2x2), and I need to be able to add and remove then.

I currently have an array which I iterate through, handling velocity changes, managing lifecyling (killing old ones, adding new ones), and plotting them, using glDrawArrays. What OpenGl is pointing at, though, for this call, is a single vertex; I glTranslatex it to the relevant co-ords for each particle I want to plot, one at a time, set the colour with glColor4x then glDrawArrays it. It works, but it's a bit slow and only works for a few hundred particles. I'm handling the clipping myself.

I've written a system to support static particles which I have loaded into a vertex/colourarray and plot using glDrawArrays, but this approach only seems suitable for particles which will never change relative location (ie I move all of them using glTranslate), colour and where I don't need to add/remove particles. A few tests on my phone (HTC Desire) suggest that trying to alter the contents of those arrays (which are ByteBuffers, pointed to by OpenGL) is extremely slow.

Perhaps there's some way of manually writing the screen myself with the CPU. If I'm just plotting 1x1/2x2 dots on the screen, and I'm purely interested in writing and not doing any blending/antialiasing, is this an option? Would it be quicker than whatever OpenGl is doing?

(200 or so particles on a 1ghz machine with megs of ram. This is way slower than I was getting 20 years ago on a 7mhz machine with <500k of ram! I appreciate I'm using Java here, but surely there must be a better solution. Do I have to use the NDK to get the power of C++, or is what I'm after possible)

1 Answers1

0

I've been hoping somebody might answer this definitively, as I'll be needing particles on Android myself. (I'm working in C++, though -- Currently using glDrawArrays(), but haven't pushed particles to the limit yet.)

I found this thread on gamedev.stackexchange.com (not Android-specific), and nobody can agree on the best approach there, but you might want to try a few things out and see for yourself.

I was going to suggest glDrawArrays(GL_POINTS, ...) with glPointSize(), but the guy asking the question there seemed unhappy with it.

Let us know if you find a good solution!

Community
  • 1
  • 1
Martin Stone
  • 12,682
  • 2
  • 39
  • 53
  • Thanks for the link. glDrawArrays(GL_POINTS) was described above. I just experimented with GL_TRIANGLE_STRIP & 2 triangles and it's a little faster (perhaps 5-10% assuming my timing is accurate). I tried using one triangle (GL_TRIANGLES) but it flickered and didn't seem any faster. GL_LINES didn't help. It's frustrating because I can handle thousands of points in my static array with no slowdown, but a few tens of dynamic points(quads) completely kills it. I doubt I can get away with writing to a bitmap the size of the screen, converting it to a texture each frame and displaying it. –  Feb 21 '11 at 23:21
  • After searching and experimenting it seems I have no choice but to install the NDK and do it in C++. It seems clear that my phone has no problem rendering thousands of pointsprites via a single glDrawArrays call, but that multiple calls to DrawArrays (one call per dot) is just not fast enough for more than 20 or 30 dots. It's also too slow to alter the vertexbuffer from Java, so my first job will be to manipulate that from C++. It's possible that it's faster still using trianglestrips there (2 triangles per dot), as it is when I make the multiple calls currently, so I'll have to time that too. –  Feb 22 '11 at 11:20
  • 1
    Ended up using the NDK, and floats instead of fixed point. This page was helpful ( http://www.badlogicgames.com/wiki/index.php/Direct_Bulk_FloatBuffer.put_is_slow ). They claim that using put with ints is slow because of a bug and that it'll be fixed in Android 3.0, but an alternative of using floats is still loads slower than their native solution (of a single memcpy in C, which is what I do..well, two memcpys...) so who cares if they fix it?! I still use points; the overhead of using individual OpenGL calls to plot a quad is way slower than a single call to plot hundreds of points. –  Feb 27 '11 at 16:37