OpenGL: More vertices, slower performance

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-11 02:48:26

问题


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?


回答1:


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.




回答2:


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 :)




回答3:


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.



来源:https://stackoverflow.com/questions/22209166/opengl-more-vertices-slower-performance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!