合并多条线段

发布于 2024-08-16 04:41:19 字数 282 浏览 2 评论 0原文

我的程序使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

救赎№ 2024-08-23 04:41:19

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

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

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 of GL_LINES instead so they can be rendered in one go.

Use glDrawArrays instead of immediate mode rendering:

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

(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.

我的奇迹 2024-08-23 04:41:19

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 issue glCallList() to render it with a single command.

妖妓 2024-08-23 04:41:19

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

一个例子是这样的算法:

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

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

编辑 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:

  1. Construct a new line segment X from the two points farthest away from each other in the two line segments A and B.
  2. Find the minimum distance to X for all points in A and B.
  3. Assign the error as the maximum of those minimum distances.
  4. Replace A and B with X if the error is below your threshold.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文