【问题标题】:Merging multiple line segments合并多个线段
【发布时间】:2010-12-28 16:07:26
【问题描述】:

我的程序使用 PyOpenGL(所以它是 Python)和 psyco。

我需要在渲染的每一帧中渲染大约 21,000 条线段(除非用户放大,在这种情况下线段被剔除并且根本不发送到卡)。目前每帧大约需要 1.5 秒才能完成。这还不够好,所以我正在寻找减少不同线段数量的方法。

我想会有多条线段可以合并成一条大线的情况,但老实说,我什至不知道从哪里开始。我确实存储了每条线的起点和终点,所以这可能会有所帮助。请注意,我可以在启动时花费我需要的时间,而且内存使用不是什么大问题。

任何想法都将不胜感激。

【问题讨论】:

  • GPU 是如何发送线段的? glBegin(GL_LINES) 或某种glDrawElements() 电话? (对不起 C 语法,不知道这些在 python 中的样子)
  • 我正在使用 glBegin(GL_LINE_STRIP); ;结束()。我想过多的 glBegin/glEnd 调用也可能会影响性能,但我不确定如何删除它们。并非我正在使用的所有线段都必须相互接触。

标签: python opengl merge pyopengl line-segment


【解决方案1】:

几乎可以肯定的是,所有立即模式函数调用的开销都会影响您的性能。我会做以下事情。

不要使用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 可能会更快。

【讨论】:

  • 使用 glDrawArrays 将线集的渲染时间减半,但每帧仍需要 0.7 秒。我会看看 VBO,看看他们是否可以进一步降低这个数字。
  • 我改用 VBO 并看到 即时 速度提升:从每帧 0.7 秒到微秒。谢谢! :)
【解决方案2】:

20K 段并不多。此外,当您每帧可以合并 10-100 行时,您会很幸运,因此这种优化带来的加速可以忽略不计。渲染过程可能很慢,因为您一次又一次地创建模型。使用 glNewList() 将所有渲染命令保存在卡上的 GL 渲染列表中,然后只需发出 glCallList() 即可使用单个命令进行渲染。

【讨论】:

    【解决方案3】:

    您可以定义一个错误度量,将两个线段合并为一个,然后测试所有线段对,然后在错误低于某个阈值时合并它们。

    一个例子是这个算法:

    1. 从两条线段 A 和 B 中相距最远的两点构造一条新线段 X。
    2. 求 A 和 B 中所有点到 X 的最小距离。
    3. 将误差指定为这些最小距离中的最大值。
    4. 如果错误低于您的阈值,请将 A 和 B 替换为 X。

    这不是最好的算法,但很容易实现。

    编辑 1

    在实现之前,一定要尝试做显示列表或顶点缓冲区对象渲染。

    【讨论】:

      猜你喜欢
      • 2018-05-06
      • 1970-01-01
      • 1970-01-01
      • 2019-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-19
      相关资源
      最近更新 更多