Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm benchmarking some simple code for drawing using OpenGL.

In the following code, the number of indices being drawn is 4,644 (or 1,548 triangles per frame = @60fps 92,880 Triangles per second).

glMatrixMode(GL_PROJECTION);                        
glLoadIdentity();                                   
glOrtho(0, screenSize.width, screenSize.height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);                         
glLoadIdentity();                                   
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);

glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(venomGLAttribute), ,drawingTexturedList.attrib[0].color);
glVertexPointer(2, GL_SHORT, sizeof(venomGLAttribute), &drawingTexturedList.attrib[0].pos[0]);
glTexCoordPointer(2, GL_FLOAT, sizeof(venomGLAttribute), &drawingTexturedList.attrib[0].UV[0]);
glDrawElements(GL_TRIANGLES, drawingTexturedList[cnt].currentIndice /*4644*/, GL_UNSIGNED_INT, drawingTexturedList[cnt].Indices);

This takes 100% of one of my CPU's. If I take out the call to glDrawElements but still perform all the other steps (geometry preperation, gl*Pointer setup) I see my CPU stay at ~3%.

Is this expected behaviour? The machine I'm running on has a GeForce 8800GTX and a Dual Core @ 2.66Ghz.

Using fps as a measurement (which isn't perfect I realise) and using gDEBugger to confirm my findings, rendering 27,904 triangles a frame in a single call to glDrawElements brings my frame rate down to ~35fps (or 977,640 triangles a second).

Is there a better way to pack my data than I'm doing or perhaps a better way to send the data than glDrawElements? I don't think using a VBO will help as the data being sent changes every frame.

Any idea's would be appreciated!

share|improve this question

2 Answers 2

up vote 2 down vote accepted

Yes, it's somewhat to be expected (although your throughput is really low).

You're using about the worst method of drawing with vertex arrays: drawing indexed with client-side vertex data requires the GL implementation to:

  • parse all the indices to find the min/max on each draw
  • transfer all the vertex data from min to max on each draw.

Note that if you remove the draw, the GL will not do any of it, and it will be real fast.

if you don't want to use VBOs (they still help in that the GL can figure out easier how much to transfer), you can use glDrawRangeElements, which specifies the range of indices that the GL will transfer (ie the first of the 2 bullets).

Also, are the indices changing each frame too ? If they don't, you can store them in an index buffer. (but be careful: at that point, if you don't use glDrawRangeElements, the GL usually has to bring the index buffer back from the device, find min/max, and transfer vertex data. That's even worse than your current state)

share|improve this answer
    
Moving over to glDrawRangeElements didn't seem to make a difference. However moving to VBO's did actually speed it up considerably even though the data is being changed every frame. I'm seeing a throughput of about 15 million triangles / second now and a much lower CPU cost. Cheers! –  Olly Aug 6 '10 at 13:12
    
@Olly: good to know you solved it. Whether the GL implements the optimizations I talked about really depends on each implementation you use, sadly. –  Bahbar Aug 7 '10 at 12:11

Have you tried simply reducing the size of the array, and seeing if it makes a difference? I have a feeling you are getting a false positive; by taking out the ONLY draw call, I think you are affecting OpenGL more significantly and I'm pretty sure if you replace it with an easier call you'll still see 100% CPU.

If that is the case, then you need to make sure you are sleeping in each iteration of the game loop, or enable vsync. If you don't sleep and just have a tight draw loop then you will naturally take up 100% of one CPU, but if you just add a sleep(0) call it should reduce to ~0% CPU.

Or I could be totally wrong; if that's the case, I apologize in advance.

share|improve this answer
1  
I have VSync enabled. Plus I'm seeing the higher CPU when the draw call is in. If I take the draw call out I idle at ~3%. In fact if I do everything apart from the call to glDrawElements, it is steady at 3%. With the one call in, 100% on one CPU. –  Olly Aug 4 '10 at 18:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.