合并多个线段

1 投票
3 回答
2497 浏览
提问于 2025-04-15 17:14

我的程序使用的是PyOpenGL(也就是Python)和psyco。

我需要在每一帧中渲染大约21,000条线段(除非用户放大,这种情况下会把一些线段去掉,不发送到显卡)。现在每帧的渲染时间大约是1.5秒,这实在是太慢了,所以我在想办法减少不同线段的数量。

我想可能有些线段可以合并成一条大线,但我其实不知道从哪里开始。每条线的起点和终点我都有存储,这可能会有帮助。值得注意的是,我在启动时可以花很多时间,内存使用也不是太大的问题。

如果有任何想法,我会非常感激。

3 个回答

0

2万段其实并不算多。而且,你能在每一帧中合并10到100行代码就已经很不错了,所以通过这个优化来提高速度的效果可能微乎其微。渲染过程之所以慢,可能是因为你一直在重复创建模型。你可以使用 glNewList() 来把所有的渲染指令保存在显卡上的一个GL渲染列表里,然后只需要用 glCallList() 这个命令就能一次性渲染出来。

0

你可以为将两条线段合并成一条线段定义一个错误度量,然后测试所有线段的组合,如果误差低于某个阈值,就进行合并。

这里有一个算法的例子:

  1. 从线段A和B中最远的两个点构造一条新的线段X。
  2. 找出线段A和B中所有点到线段X的最小距离。
  3. 将这些最小距离中的最大值作为误差。
  4. 如果这个误差低于你的阈值,就用X替换掉A和B。

这个算法虽然不是最好的,但实现起来很简单。

编辑 1

在实现这个之前,最好先尝试一下显示列表或顶点缓冲对象的渲染。

4

你的性能问题很可能是因为每次调用即时模式的函数时产生的额外开销。我建议你这样做。

不要使用 GL_LINE_STRIPS,而是用一整条 GL_LINES 的列表,这样可以一次性渲染。

使用 glDrawArrays 来替代即时模式渲染:

float* coordinates = {....}; //x and y coordinate pairs for all line segments
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 2 * sizeof(float), coordinates);
glDrawArrays(GL_LINES, 0, 2 * linecount);
glDisableClientState(GL_VERTEX_ARRAY);

(如果你想要更好的性能,可以把顶点缓冲区存储在一个叫做顶点缓冲对象的东西里,但一开始这样做就可以了)

最后,如果你是按每条线进行剔除,可能直接跳过这个步骤,把所有的线都发送给GPU会更快。

撰写回答