boosting performance drawing lots of textures

Hi all,

I’m working on an app where I generate fuzzy looking creatures by drawing a texture multiple times over itself. For example, the following image:

is generated by drawing the following texture 180 times around a circle, and scaled up 6x:

The problem is that these creatures totally kill my framerate. Drawing one brings it down to ~52fps, two down to ~28fps, three to ~18fps, and so on. I am looking for help figuring out the best way to draw a bunch of textures. It seems that this is definitely possible, as 180 textures is really not that much…

I am now using vertex arrays:

  
  
tex.bind();  
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);  
glEnableClientState(GL_VERTEX_ARRAY);  
glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
{  
    glVertexPointer(2, GL_FLOAT, 0, texVerts);  
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);  
    glDrawArrays(GL_QUADS, 0, numTexSlices * 4 * 2);  
}  
glDisableClientState(GL_VERTEX_ARRAY);   
glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
tex.unbind();  
  

texCoords are only calculated once in the constructor, since they never change:

  
  
texCoords = new GLfloat[180  * 4 * 2];  
  
for (int i=0; i < 180; i++) {  
    texCoords[i*4*2 + 0*2 + 0] = 0;  
    texCoords[i*4*2 + 0*2 + 1] = 0;  
      
    texCoords[i*4*2 + 1*2 + 0] = 64;  
    texCoords[i*4*2 + 1*2 + 1] = 0;  
      
    texCoords[i*4*2 + 2*2 + 0] = 64;  
    texCoords[i*4*2 + 2*2 + 1] = 64;  
      
    texCoords[i*4*2 + 3*2 + 0] = 0;  
    texCoords[i*4*2 + 3*2 + 1] = 64;  
}  
  

texVerts are calculated every frame because the textures rotate:

  
  
for (int i=0; i < 180; i++) {  
    float x = radius * cosf(DEG_TO_RAD * (i * 360/180));  
    float y = radius * sinf(DEG_TO_RAD * (i * 360/180));  
    int   j = ofRandom(0, 360);  
    float a;  
      
    float texRadius = (64 * 6) / 2.0f;  
  
    // top-left  
    a = DEG_TO_RAD * (225 + j);  
    texVerts[i*4*2 + 0*2 + 0] = x + texRadius * cosf(a);  
    texVerts[i*4*2 + 0*2 + 1] = y + texRadius * sinf(a);  
      
    // top-right  
    a = DEG_TO_RAD * (315 + j);  
    texVerts[i*4*2 + 1*2 + 0] = x + texRadius * cosf(a);  
    texVerts[i*4*2 + 1*2 + 1] = y + texRadius * sinf(a);  
      
    // bottom-right  
    a = DEG_TO_RAD * ( 45 + j);  
    texVerts[i*4*2 + 2*2 + 0] = x + texRadius * cosf(a);  
    texVerts[i*4*2 + 2*2 + 1] = y + texRadius * sinf(a);  
      
    // bottom-left  
    a = DEG_TO_RAD * (135 + j);  
    texVerts[i*4*2 + 3*2 + 0] = x + texRadius * cosf(a);  
    texVerts[i*4*2 + 3*2 + 1] = y + texRadius * sinf(a);  
}  
  

Some ideas I’ve had so far:

  • Since I’m drawing the texture 180 times, texVerts and texCoords each hold 180 * 4 vertices * 2 coords = 1440 values. These are all different for texVerts and changing every frame (because the 180 textures rotate over time), but they are the same set of 4 * 2 vertices repeated over and over in texCoords: (0, 0), (0, 64), (64, 64), (64, 0). Is there a way to only put in those 4 vertices in the tex coord pointer?

  • I tried using a bigger texture instead of scaling this small one, but that gave me worse performance (less than 50%). I even tried using mipmaps and the new ARB compression, but that did not make any difference.

  • I tried using a smaller texture (32x32) and doubling the scale but that also had no effect.

  • I tried using VBOs instead of vertex arrays but it had no noticeable effect.

  • I thought of using point sprites instead of quads, but the Internet’s been telling me that you can’t rotate point sprites.

And I’m out of ideas :slight_smile: If anyone has any ideas or suggestions on how I could boost my performance, I’d love to hear them!

Thanks!