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 If anyone has any ideas or suggestions on how I could boost my performance, I’d love to hear them!
Thanks!