Sign in to follow this  
daviddoria

glCallList very slow

Recommended Posts

daviddoria    154
I have a model with about 10,000 triangles. I put it into a display list and then display it 100 times, each time with a different translation. The problem is, this takes about 7 seconds!! It is horribly slow. This seems like a super small model (as things are usually measured in million of polygons / second, right?), so I don't know what the problem is. I measured the time with a timer class and everything was super fast except the glCallList calls. Any thoughts? Thanks, Dave

Share this post


Link to post
Share on other sites
swiftcoder    18437
Quote:
Original post by daviddoria
I have a model with about 10,000 triangles. I put it into a display list and then display it 100 times, each time with a different translation. The problem is, this takes about 7 seconds!! It is horribly slow. This seems like a super small model (as things are usually measured in million of polygons / second, right?), so I don't know what the problem is. I measured the time with a timer class and everything was super fast except the glCallList calls.
100 * 10,000 is 1,000,000 triangles. My machine achieves ~30 fps when rendering 1,000,000 triangles per frame, with texturing and a single light source.

However, my 1,000,000 triangles are sourced from VBOs, are rendered as indexed triangle lists, are in batches of 10,000 triangles, and each batch is cache optimised. Display lists are ancient technology, soon to be deprecated, and are typically far slower than rendering with a properly optimised VBO. You may see a decent performance improvement by moving to a more modern rendering setup.

Share this post


Link to post
Share on other sites
Kambiz    758
The triangle count is not the only important factor, you should also consider the amount of per pixel operations, if each of those rendered objects fills a big portion of the frame buffer you are rewriting the whole frame buffer many times per frame. Drawing some full-screen quads can be slower than rendering a small high-poly model.

Share this post


Link to post
Share on other sites
Yann L    1802
Quote:
Original post by daviddoria
Any thoughts?

I have no idea. You don't even say what graphics card you have. How are we supposed to give any performance advice ? There's a slight difference in interpreting these figures based on whether you have an Intel integrated chipset or a Quadro FX 5800, you know...

Share this post


Link to post
Share on other sites
daviddoria    154
swiftcoder - so without switching to VBOs there's no way to make it faster?

kambiz - I don't understand, what is a "per pixel operation"? I don't understand why it would draw the frame buffer more than once per frame?

Yann L - I have a professional series 9000 (or 9x00) GeForce 4 card. That should be capable of going as fast as I need it to. Is there some standard speed test that I can run? As swiftcoder says - he's getting 30,000,000 triangles per second, and I'm getting 1,000,000 triangles in 7 seconds!

Dave

Share this post


Link to post
Share on other sites
Yann L    1802
Quote:
Original post by daviddoria
Yann L - I have a professional series 9000 (or 9x00) GeForce 4 card.

There is no such thing in Nvidia's product line. It is still not clear to me on what hardware you are working. Do you have a 9x00 series GeForce ? This should indeed be able to handle the load easily. Or do you have a GeForce 4 ? This will definitely choke on 1 million triangles, although not as bad as the result you got - unless you have a GeForce 4 MX series, which was essentially a renamed GeForce 3. Or do you mean a 9x00 series ATI Radeon ? These had horrific OpenGL drivers, which might explain the problem as well.

Anyway, it actually sounds like you're running in software mode. While display lists are in fact obsolete technology, and VBOs will indeed be faster, the difference is usually in the 10-20% range. Nothing as extreme as you mentioned. So the problem is somewhere else.

1) Check exactly on what 3D chipset you are running and post it here.
2) Check the GL_VENDOR string, so to make sure you are running in hardware.
3) Make sure you have up-to-date drivers installed.

If nothing of that helps, then I'm afraid you need to post some code.

Share this post


Link to post
Share on other sites
Kambiz    758
Quote:
Original post by daviddoria
kambiz - I don't understand, what is a "per pixel operation"? I don't understand why it would draw the frame buffer more than once per frame?


Let's say you are rendering something like this:

If you render the yellow object first, opengl will render the whole yellow object (even the pixel behind the red object), then when you render the red object it will overwrite a lot of the previously rendered (yellow) pixels. Each of those per-pixel operations take some time.

Share this post


Link to post
Share on other sites
daviddoria    154
here are some outputs:

Vendor: NVIDIA Corporation
Renderer: Quadro FX 3450/4000 SDI/PCI/SSE2
Version: 2.1.2 NVIDIA 173.14.12

Does that shed any light on the situation?

Thanks,

Dave

Share this post


Link to post
Share on other sites
Yann L    1802
Quote:
Original post by daviddoria
here are some outputs:

Vendor: NVIDIA Corporation
Renderer: Quadro FX 3450/4000 SDI/PCI/SSE2
Version: 2.1.2 NVIDIA 173.14.12

Does that shed any light on the situation?

Partially. Your graphics card uses an NV42 GPU. Your Quadro FX is the equivalent of a GeForce 6800. While obviously a bit dated, it's still a decent card. It should have no problems displaying 1 million triangles at a decent framerate.

So in conclusion, you are doing something wrong somewhere in your code. As I said, it looks like you are falling back to software mode. Tell us exactly what you are doing, and we can investigate further.

Share this post


Link to post
Share on other sites
daviddoria    154
Here is my drawing function:

	
void ModelFile::DrawTriangles(const bool Normals, const bool Named) const
{
bool HasColors = false;
if(NumColors() > 0)
HasColors = true;
else
glColor3ub(100, 100, 100);

if(Named)
glPushName(1);

if(NumTriangles() > 0)
{
//cout << "Drawing " << NumTriangles() << "Triangles with " << NumColors() << " colors." << endl;

for(int i = 0; i < NumTriangles(); i++)
{
if(Named)
glLoadName(i);

if(HasColors) //color!
{
geom_Color<unsigned char> cu = Colors_[i];
glColor3ub(cu.getR(), cu.getG(), cu.getB());
}

Triangles_[i].Draw(Normals);
}
}
else
{
DrawPoints();
}
}


I make the display list with :



int list;
list = glGenLists(1);
glNewList(list,GL_COMPILE);
Scene.DrawTriangles(true, true);
glEndList();


and then I call it like this


glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective(50, 1, 1, 100); //field of view angle, aspect ratio, znear, zfar

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
//gluLookAt(2, 2, 10, 0, 0, 0, 0, 1, 0);
gluLookAt(Location_.getX(), Location_.getY(), Location_.getZ(), P.getX(), P.getY(), P.getZ(), 0, 1, 0);

//display(Model);
display(list);




I just didn't see how anything could be "wrong" with the code since it works as expected (just slow), that's why I didn't post it from the get go.

See anything wrong?

Thanks,

Dave

Share this post


Link to post
Share on other sites
swiftcoder    18437
Quote:
Original post by daviddoria
I just didn't see how anything could be "wrong" with the code since it works as expected (just slow), that's why I didn't post it from the get go.
You appear to be rendering in immediate mode. The display list may help somewhat, but unless you are very careful about the specification of vertex elements it won't help much, and will be orders of magnitude slower than vertex buffers or even arrays.

Share this post


Link to post
Share on other sites
daviddoria    154
What do you mean "immediate mode"? I am putting them in a display list, so that's not immediate, right? Also, what do you mean by "be very careful"? What can I do to make the display list help? It seemed pretty complicated to switch to VBO, is there an easy way to convert this code to arrays?

Thanks,
Dave

Share this post


Link to post
Share on other sites
swiftcoder    18437
Quote:
Original post by daviddoria
What do you mean "immediate mode"?
Immediate mode is using glVertex*f() [between glBegin() and glEnd()] to send each vertex to the GPU. This usage is deprecated, and extremely slow, as the graphics card must wait for each vertex to arrive.
Quote:
I am putting them in a display list, so that's not immediate, right? Also, what do you mean by "be very careful"? What can I do to make the display list help?
Display lists were designed to help with the performance problems of immediate mode, and as such are similarly deprecated. However, if you must stick to immediate mode, some drivers are able to optimise display lists, provide that each vertex specified has identical elements (i.e. exactly one normal, texture coordinate and colour per vertex).
Quote:
It seemed pretty complicated to switch to VBO, is there an easy way to convert this code to arrays?
VBOs are a very simple extension to arrays - they basically move the arrays into GPU memory. As for converting to arrays, as long as you have an array of vertices, it should be as simple as setting the relevant glVertexPointer, glNormalPointer, glColorPointer, and calling glDrawArrays.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this