Performance issues with glDrawArrays

Started by newera31, March 14, 2009, 17:34:16

Previous topic - Next topic

newera31

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:

/**
	 * 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();*/
	}

newera31

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

ndhb

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.

newera31

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?

ndhb

Quote from: newera31 on March 14, 2009, 19:26:39
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".