Jump to content
  • Advertisement
Sign in to follow this  
billouparis

OpenGL glDrawArrays sometimes fast sometimes slow! [SOLVED] problem is not related to glDrawArrays but to textures size

This topic is 2780 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

I have this weird issue, working with openGL ES 2.0 on iMx51 Freescale board.
My application is drawing around 80 complex 3D objects. based on VBO, and glDrawArrays.

I can easely draw let's say something like 50 objects in a loop, with a very fast glDrawArrays (less than 1 ms each call to glDrawArrays even for object with more than 3000 triangles),
now If I try to draw only one object more, so let's say a 51st object, then some calls to glDrawArrays suddenly require more time (around 30ms for most of these calls).
This 51st object has nothing particular compared to the other, small amount of triangles.

CASE A
unsigned int index = 0;
Foreach (object, in objectGroup)
{
if (index != 3)
{
...
glDrawArrays(GL_TRIANGLES, 0, object->numberOfTriangles * 3);
}
index++
}


CASE B
unsigned int index = 0;
Foreach (object, in objectGroup)
{
if (1)
{
...
glDrawArrays(GL_TRIANGLES, 0, object->numberOfTriangles * 3);
}
index++
}

In CASE A, each call to glDrawArrays require less than 1ms
in CASE B, there are around 10 calls to glDrawArrays that suddenly require around 30ms, when index == 3 the glDrawArrays require less than 1 ms.

There are no gl error after the calls to glDrawArrays.

Any idea what could be the problem here?
I removed all texture drawing, and replace them by unique color drawing, the problem is the same.

Thank you for any hint how I could progress with this issue.
Regards,
Bill

Share this post


Link to post
Share on other sites
Advertisement
Many OpenGL (and Direct3D) calls add actions to the end of a rendering queue and return immediately, allowing the CPU and GPU to work in parallel. If the rendering queue fills up, the call has to wait until the GPU finishes some work before it can add anything new. If your objects contain a lot of triangles and your GPU isn't that powerful, it could end up waiting a fairly long time. :)

If you add a glFinish() call to wait until the GPU finishes its work, I suspect you'll get much more consistent measurements. You wouldn't want to do that in production, of course...

My suggestion is to have to the CPU go do some other work between drawing objects so it doesn't overflow the rendering queue.

Share this post


Link to post
Share on other sites
The article here explains some of this; it's for D3D but much the same concepts apply (especially with VBOs in the equation). Even if there are no extra state changes involved, the paragraph beginning "Just to complicate matters further..." is very relevant.

Share this post


Link to post
Share on other sites

Many OpenGL (and Direct3D) calls add actions to the end of a rendering queue and return immediately, allowing the CPU and GPU to work in parallel. If the rendering queue fills up, the call has to wait until the GPU finishes some work before it can add anything new. If your objects contain a lot of triangles and your GPU isn't that powerful, it could end up waiting a fairly long time. :)

If you add a glFinish() call to wait until the GPU finishes its work, I suspect you'll get much more consistent measurements. You wouldn't want to do that in production, of course...

My suggestion is to have to the CPU go do some other work between drawing objects so it doesn't overflow the rendering queue.


Hello kdmiller3,
thank you for your answer.
Following your comments, I added a call to glFinish() in my code, and tried with only the first 50 objects, but in this case they are rendered very quickly.
So I don't know if my problem is really related to the number of rendering commands in the openGL queue then.

But let's considered this is really the problem, then I am not sure I understood your last suggestion to help get my problem solved? Because to create one frame of my scene I have to have all of my objects drawn.
Let me give you another detail concerning my application: it is drawing a 3D scene with less than 17000 triangles, and some image textures (all stored in unit 0 as far as I understand this, well, at least I don't mention anything in my code for this so I guess it is what is done), and the user can move around the scene (changing the modelview matrix, applying a rotation computation). When the use begins to move the mouse the complete scene must be redrawn according to the new values of my modelview matrix. And the thing is, when drawing only 50 objects, it goes smoothly, but then if I add only one object, the redraw is performed very slowly, like one frame per 500 ms or so.

I wonder how I could determine of the openGL rendering queue reaches its limit at some point, is there a method to test this?
Thank you,
Bill

Share this post


Link to post
Share on other sites

The article here explains some of this; it's for D3D but much the same concepts apply (especially with VBOs in the equation). Even if there are no extra state changes involved, the paragraph beginning "Just to complicate matters further..." is very relevant.


Hello mhagain, the article is indeed very interesting, although I don't know what I could change in my code to try to follow these hints at this moment.
Thank you,
Bill

Share this post


Link to post
Share on other sites
I have done the following test:

paint()
{
glFinish();
startClock();
draw3D();
glFinish()
stopClock();
}

case A -> draw3D draws 50 objects, clock is 40ms
case B-> draw3D draws 51 objects, clock is 500 ms.

The extra object is basically the same type as the others already drawn, no extra number of triangles, no specific texture involved.
I really don't get it then, do you?


[s]Also I tested my application in a very small viewport to be sure the fragment shader was not faulty at any time, when drawing inside a 50*30pxl frame, I get the exact same rendering time measures.[/s] This is apparently not true.

I just re-tested my application with a very simple fragment shader simply displaying the same color for each fragment, and the speed is around 35ms with the whole scene objects. So the issue is maybe located in the textures processing. I am gonna try maybe to sort the objects depending on their textures to see if it can boost the whole rendering.
Also I have some quite large images for the textures, in tiff format, and maybe this can also be the problem. Beside I did not use the texture units, I simply created my textures this way:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glBindTexture( GL_TEXTURE_2D, textures[indexTextureBuffer] );

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexImage2D (GL_TEXTURE_2D, 0,
GL_RGBA, image2.width(), image2.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, image2.bits());

And then I use them this way:
glBindTexture( GL_TEXTURE_2D, texturesArray[group->material].texture /* textures[]*/ );


Bill

Share this post


Link to post
Share on other sites
Ok so apparently my problem is related to the textures, I'm using now a single texture for all objects, and the whole thing is rendering very fast.
I wonder why is there such a gap, when adding only one object with another texture.
Anybody knows?

Thank you,
Bill

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!