Optimising particle array of sorts

Hi all,

I am hitting my first ever performance limitation of OF (guess it was bound to happen eventually!). I have built an app to function as a simulator for 3D LED screens. I have a 3D Model of an environment, with some video planes positioned inside it, and my LED simulation which the user can move the camera through.

I am trying to optimise the LEDs so that I can have a higher framerate. At the moment color values of the LEDs are being pulled from a video frame, which I load into a texture. I then iterate through each pixel and draw an ellipse to screen using the following function for billboarding from [www.lighthouse3d.com/opengl/billboarding/billboardingtut.pdf] as I had no luck using shaders for this:

void testApp::billboardCheatSphericalBegin() {
float modelview[16];
int i,j;

// save the current modelview matrix
glPushMatrix();

// get the current modelview matrix
glGetFloatv(GL_MODELVIEW_MATRIX , modelview);

// undo all rotations
// beware all scaling is lost as well
for( i=0; i<3; i++ ) {
for( j=0; j<3; j++ ) {
if ( i==j )
modelview[i\*4+j] = 1.0;
else
modelview[i\*4+j] = 0.0;
}
}

//set the modelview with no rotations
glLoadMatrixf(modelview);

}

I have tried drawing all the LEDs into an ofFBOTexture and then drawing to screen but this doesn’t help. At the moment I have 10 layers of LEDs, that are 100 square, which I realise is a whopping 100,000. This runs at 9fps on my 2.66 GHz Dual Core Mac Pro with 512 mb graphics card. If I halve the number of LEDs I get 13 fps which looks passable.

If I take out all the billboarding and video texture stuff, and just draw this many ellipses all the same colour it still chokes so this is definitely where the bottleneck is. Does anyone have any tips or is this just not possible? Would love to get 25 fps.

Cheers,
nay.

each circle is about 22 triangles (it’s built out of triangles). you can try changing the circle resolution, or even, using a texture of a circle (which is two triangles) and this can help with speed a great deal (as it cuts down on triangles to draw).

are you doing : billboardCheatSphericalBegin() per particle? seems that that would be quite slow.

finally, you should look at point sprites, which are billboarded points that can have a circle texture…

http://www.codesampler.com/oglsrc/oglsrc-6.htm
http://www.informit.com/articles/articl-…-9&seqNum=7

hope that helps !
zach

instead of drawing circles you could try drawing single points by setting their size with glPointSize(…) and enabling glEnable(GL_POINT_SMOOTH).
then you could also draw the points using vertex arrays and color arrays to speed things up.
have a look in this topic http://forum.openframeworks.cc/t/very-simple-example-of-vertex-arrays,-vbo’s,-point-sprites/1349/0 maybe it will help.

Rui

[quote author=“pelintra”]instead of drawing circles you could try drawing single points by setting their size with glPointSize(…) and enabling glEnable(GL_POINT_SMOOTH).
then you could also draw the points using vertex arrays and color arrays to speed things up.
have a look in this topic http://forum.openframeworks.cc/t/very-simple-example-of-vertex-arrays,-vbo’s,-point-sprites/1349/0 maybe it will help.

Rui[/quote]

the downside of that is that points are really limited in terms of size (maximum size and also distance attenuation is another bottleneck)

I’ve got some sample openframeworks code at
http://www.memo.tv/vertex-arrays-vbos-a-…-frameworks

which renders a particle system using point sprites and vbo (or vertex array). You may need to modify the sample a bit to work with ofw006.

awesome. thanks all for the great feedback. I should be able to spend all tomorrow on this. will post back.

another opengl optimisation technique is to use opengl display lists.

so you draw your shape once and add it to a display list.

glNewList( intergerID, GL.GL_COMPILE );
glBegin( GL.GL_QUADS );
gl.glVertex3f( 1, 1, 0 );


glEnd();
glEndList();

then to draw it again, you simply call it from the display list.
this speeds things up a lot…

beginGL();
glCallList( intergerID );
endGL();

guess the tricky part of this approach is that you have to draw your cicrle using opengl commands but that shouldn’t be too complicated.

L.

hi all,

have only had time for a preliminary tinker but point sprites look great for this. they alone have made my framerate passable, but i will definitely implement the array stuff too. from playing/googling it looks like i need to use a shader if i want to vary point size according to depth (hopefully this won’t be a big hit in to performance), don’t suppose anyone has done this before?

keen to go the point sprite route as using a transparent png for the texture will give me better looking results than drawing a circle (feathered edges etc)

and memo, thanks heaps for the code. just had to change variables in ofFBOTexture.cpp, textureName became texData.textureName etc.

[quote author=“nay”]hi all,

have only had time for a preliminary tinker but point sprites look great for this. they alone have made my framerate passable, but i will definitely implement the array stuff too. from playing/googling it looks like i need to use a shader if i want to vary point size according to depth (hopefully this won’t be a big hit in to performance), don’t suppose anyone has done this before?

keen to go the point sprite route as using a transparent png for the texture will give me better looking results than drawing a circle (feathered edges etc)

and memo, thanks heaps for the code. just had to change variables in ofFBOTexture.cpp, textureName became texData.textureName etc.[/quote]

No, you actually don’t need a shader for distance attenuation on point sprites, you would need something like this:

  
  
	float att[3] = {1.0f, -0.01f, -0.00001f};   
	glPointSize(100);  
	glPointParameterf(GL_POINT_SIZE_MIN, 1.0f);  
	glPointParameterf(GL_POINT_SIZE_MAX, 256.0f);  
	glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, att);  
  

what values give you the correct results here depends alot on your openGL “camera” setup

thanks moka - that works! getting the attenuation right is tricky but doable and performance is good. will hopefully be great by the time i work in the array stuff!

thanks again everyone!