Question

I am working on a part of a program where given a collection of xyz-coordinates, a 3D model is made. I have all of the functionality needed for this picture done (i.e. panning, rotating, scaling) however the more xyz-coordinates given, the slower my program runs. My program runs pretty smooth when processing 29,000 coordinates, but I when I have 300,000 points, my program slows down. I am using SharpGL in order to use OpenGL in WPF. The code for inserting all these points looks as follows:

gl.Begin(OpenGL.GL_LINES);

        for (int i = 0; i < (parser.dataSet.Count - 1); i++)
        {

            gl.Color(1.0f, 0.0f, 0.0f);
            gl.Vertex(parser.dataSet[i].X / parser.xDiv, parser.dataSet[i].Y / parser.yDiv, parser.dataSet[i].Z);
            gl.Vertex(parser.dataSet[i + 1].X / parser.xDiv, parser.dataSet[i + 1].Y / parser.yDiv, parser.dataSet[i + 1].Z);
        }

        gl.End();
        gl.Flush();

Am I doing something noobish (im not familiar with OpenGL) that I can fix? Some people have mentioned scaling my data down, which I am not totally opposed to, but is there a way to 'scale back up' as I "zoom"(rescale) in on the picture?

Was it helpful?

Solution

The immediate-mode (glBegin()/glEnd()) function-call overhead for 300,000 points is massive.

Batch up your geometry submission using vertex arrays or vertex buffer objects. That way you can draw all your points in 10-20 calls instead of nearly a million.

OTHER TIPS

To add just a grain of salt, you can optimize divisions out:

divParserDotxDiv=1.0f/parser.xDiv;
divParserDotyDiv=1.0f/parser.yDiv;
gl.Color(1.0f, 0.0f, 0.0f);
for (int i = 0; i < (parser.dataSet.Count - 1); i++)
        {


            gl.Vertex(parser.dataSet[i].X * divParserDotxDiv, 
                      parser.dataSet[i].Y * divParserDotyDiv, 
                      parser.dataSet[i].Z);
            gl.Vertex(parser.dataSet[i + 1].X  * divParserDotxDiv,
                      parser.dataSet[i + 1].Y * divParserDotyDiv, 
                      parser.dataSet[i + 1].Z);
        }

which should be at least %1 to %3 faster :)

genpfault's answer of 'Use vertex buffers' is the correct answer, but it's worth noting that if you're constrained on your target environment and/or can't tackle a port away from the OpenGL 1.x API, there is an alternative in display lists.

With a display list you create and activate a list object (using glGenLists and glNewList) which essentially acts as a recorder for your vertex calls. After you've activated the list you then call your rendering calls (glBegin, glEnd, glVertex, etc) as you normally would. When you're done with the geometry, you call glEndList, which completes the recording. In future when you want to render the same geometry you can simply call glCallList as a shortcut. Because the list data can be captured by the driver and stored on the video card, the overhead is much less.

However, the use of display lists has caveats. There's a whole set of OpenGL functions that can't be called from within a list, and they're only applicable for static geometry. Also, there's no guarantee that the driver will actually store the information on the video card, meaning that there's not necessarily a great performance boost. Your best bet is to migrates away from immediate mode and the fixed function pipeline.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top