合并多条线段
我的程序使用 PyOpenGL(所以它是 Python)和 psyco。
我需要在渲染的每一帧中渲染大约 21,000 个线段(除非用户放大,在这种情况下线段将被剔除并且根本不会发送到卡)。目前每帧大约需要 1.5 秒才能完成。这还不够好,所以我正在寻找减少不同线段数量的方法。
我想在某些情况下,多个线段可以合并成一条大线,但老实说,我什至不知道从哪里开始。我确实存储了每条线的起点和终点,因此这可能会有所帮助。请注意,我可以在启动时花费所需的时间,并且内存使用量并不是太重要。
任何想法将不胜感激。
My program uses PyOpenGL (so it's Python) with psyco.
I have around 21,000 line segments which I need to render in each frame of my render (unless the user zooms in, in which case line segments are culled and not sent to the card at all). This is currently taking around 1.5 seconds each frame to complete. That's just not good enough, so I'm looking at ways to reduce the number of distinct line segments.
I imagine there would be cases where multiple line segments can be merged into one big line, but I honestly do not even know where to begin with this. I do have the start point and end point of each line stored, so that might help things. Note that I am able to take as long as I need to at startup, and memory usage isn't too much of a concern.
Any ideas would be much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
几乎可以肯定,所有立即模式函数调用的开销都会影响您的性能。我会做以下事情。
不要使用
GL_LINE_STRIPS
,而是使用单个GL_LINES
列表,以便可以一次性渲染它们。使用
glDrawArrays
而不是立即模式渲染:(为了获得更好的性能,您可以将顶点缓冲区存储在称为顶点缓冲区对象的东西中,但这应该可以开始)
最后一件事,如果您'在逐行进行剔除时,跳过它并将所有行发送到 GPU 可能会更快。
It's almost certainly the overhead of all the immediate mode function calls that's killing your performance. I would do the following.
Don't use
GL_LINE_STRIPS
, use a single list ofGL_LINES
instead so they can be rendered in one go.Use
glDrawArrays
instead of immediate mode rendering:(For even better performance you can store the vertex buffer in something called a vertex buffer object, but this should be fine to begin with)
One final thing, if you're do culling on a per line basis it's probably faster to just skip it and send all the lines to the GPU.
20K 段并不算多。另外,当您每帧可以合并 10-100 行时,您就会很幸运,因此这种优化带来的加速将可以忽略不计。渲染过程可能很慢,因为您一次又一次地创建模型。使用
glNewList()
将所有渲染命令保存在卡上的GL渲染列表中,然后只需发出glCallList()
即可使用单个命令进行渲染。20K segments isn't that much. Also, you'll be lucky when you can merge 10-100 lines per frame, so the speedup by this optimization will be neglectable. The rendering process is probably slow because you create the model again and again. Use
glNewList()
to save all the rendering commands in an GL render list on the card and then just issueglCallList()
to render it with a single command.您可以定义一个错误度量,用于将两个线段合并为一个,然后测试所有线段对,如果误差低于某个阈值,则将它们合并。
一个例子是这样的算法:
这不是最好的算法,但很容易实现。
编辑 1
在实现此操作之前,一定要尝试执行显示列表或顶点缓冲区对象渲染。
You can define an error metric for merging two line segments into one and then testing all pairs of segments and then merging them if the error is below a certain threshold.
One example is this algorithm:
This isn't the best algorithm, but it is easy to implement.
Edit 1
Definitely try doing display lists or vertex buffer object rendering before implementing this.