Hello Guest

Performance issues with glDrawArrays

  • 5 Replies
  • 14475 Views
Performance issues with glDrawArrays
« on: March 14, 2009, 17:34:16 »
Hello,

I apologize if this is a repeated post, I searched the net and the forums and found no one asking a similar question.

I am receiving poor performance when using glDrawArrays.  All my drawing is for 2D.  When I use immediate mode I receive approximately 90 FPS.  When using glDrawArrays I receive < 15 FPS.

What I'm I doing wrong?

This code is invoked for each texture I want to draw:

Code: [Select]
/**
* Draws an Image.
*
* @param image
* @param x
* @param y
* @param width
* @param height
*/
private void drawImage0(LWJGLImage texture, float x, float y, int width, int height) {
glBindTexture(GL_TEXTURE_2D, texture.getTextureId());

                // makes no gl calls
Rectangle bounds = applyFilters(texture, 0, 0, width, height);
    if ( texture.isRepeating() ) {
GLState.textureRepeat();
}
else {
GLState.textureClamp();
}

    FloatBuffer tex = BufferUtils.createFloatBuffer(4 * 2);
    tex.put(texture.getTexX()).put(texture.getTexY()).
    put(texture.getTexX()).put(texture.getHeight()).
        put(texture.getWidth()).put(texture.getHeight()).
    put(texture.getWidth()).put(texture.getTexY());
    tex.flip();
   
    FloatBuffer vertex = BufferUtils.createFloatBuffer(4 * 2);
    vertex.put(x + bounds.getX()).put(y + bounds.getY()).
       put(x + bounds.getX()).put(y + bounds.getHeight()).
           put(x + bounds.getWidth()).put(y + bounds.getHeight()).
       put(x + bounds.getWidth()).put(y + bounds.getY());
    vertex.flip();
   
//     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//     glEnableClientState(GL_VERTEX_ARRAY);
   
   
    glTexCoordPointer(2, 0, tex);
    glVertexPointer(2, 0, vertex);
   
    glDrawArrays(GL_QUADS, 0, 4);
   
//     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//     glDisableClientState(GL_VERTEX_ARRAY);
   
// draw a quad textured to match the sprite
/*glBegin(GL_QUADS);
glTexCoord2f(texture.getTexX(), texture.getTexY());
glVertex2f(x + bounds.getX(), y + bounds.getY());

glTexCoord2f(texture.getTexX(), texture.getHeight());
glVertex2f(x + bounds.getX(), y + bounds.getHeight());

glTexCoord2f(texture.getWidth(), texture.getHeight());
glVertex2f(x + bounds.getWidth(), y + bounds.getHeight());

glTexCoord2f(texture.getWidth(), texture.getTexY());
glVertex2f(x + bounds.getWidth(), y + bounds.getY());
glEnd();*/
}

Re: Performance issues with glDrawArrays
« Reply #1 on: March 14, 2009, 17:52:49 »
I moved the creation of the buffers to data members which increased performance to 80 FPS.  This is still slower than the 90 FPS in immediate mode though.

Any suggestions?


Thanks

*

Offline ndhb

  • **
  • 70
Re: Performance issues with glDrawArrays
« Reply #2 on: March 14, 2009, 18:40:34 »
You need to submit a lot more primitives than 4 to benefit from DrawArrays. Each GL function call takes time. The less function calls you make, the better. DrawArrays is better for performance because you can draw a whole array with few function calls, instead of immediate mode that requires function calls for each vertex, texture coordinate etc. Group all the vertices together in one array, then submit the whole array.

Re: Performance issues with glDrawArrays
« Reply #3 on: March 14, 2009, 19:26:39 »
Thanks for the reply!

If I batch the vertex and texCoords how do I tell the glDrawArrays which texture to bind for each entry in the batch?

*

Offline ndhb

  • **
  • 70
Re: Performance issues with glDrawArrays
« Reply #4 on: March 15, 2009, 11:52:47 »
If I batch the vertex and texCoords how do I tell the glDrawArrays which texture to bind for each entry in the batch?

You don't. There's no way to do that. All the primitives rendered with a single glDrawArrays will use the same texture(s), it will use what the texture(s) that is bind when you issue the draw call. What you can do then, is to put all your small texture images into one large texture (a so called texture atlas). Then adjust/change the texture coordinates for each primitives you render with a different texture. Besides making it possible to render many primitives fast, with this technique, you only have to bind a few large texture atlas instead of many small textures. This in itself is much better for performance. The keywords you want to search for is "texture atlas".

Re: Performance issues with glDrawArrays
« Reply #5 on: March 16, 2009, 01:33:47 »
Thanks all!