【问题标题】:An efficient way to draw many OpenGL points in individual Begin-End blocks?在单个 Begin-End 块中绘制许多 OpenGL 点的有效方法?
【发布时间】:2012-06-15 22:01:28
【问题描述】:

如果您开始渲染点,渲染大量顶点,然后结束,您获得的性能明显优于开始点、渲染顶点、结束并重复大量次(例如,在平移和例如,200,000 点的缩放动作要平滑得多)。

我想这可能是有道理的,但令人失望。有没有办法恢复性能,同时仍然在自己的开始-结束块中渲染每个点?

背景:

我想设计一个控件,它可以包含大量(在极端情况下超过一百万)“对象”,每个对象都进行自己的渲染。其中许多对象将自己表示为点。

如果我让十万个点分别在它们自己的开始端块中呈现自己,我会受到重大的性能影响(而不是在单个开始端块中呈现它们)。因此,似乎我可能必须让容器知道对象呈现自己的方式(例如,开始点,告诉所有需要呈现点的东西,然后结束)。

这弄乱了我想要的显示-对象关系的独立性。它还会通过选择来搞乱命中测试,因为我认为您不能将名称添加到 inside 起始点块的顶点,对吧?

仅供参考(以防万一)我的项目将显示 2D 场景(使用正射投影)并需要点击测试以确定用户可能单击的相关对象。通常,对象将表示“轨迹”,其中包含用线连接的各个点。位置数据通常是静态的,但点和轨迹颜色以及显示表示可能会因用户设置和选择信息而改变。一个例外——“回放”模式可能允许用户一次只能看到一个轨迹点(回放中的“当前”点),并从一个点到下一个点逐步进行时间。但是,即使在那种情况下,我也假设我会根据播放中的当前时间简单地更改每个轨道上实际显示的点(在其“静态”位置)。如果其中任何一个让我想起对 OpenGL 新手的进一步建议,那么非常感谢!

【问题讨论】:

  • 如果您想要真正好的性能,就没有办法绕过巧妙的数据组织和批处理。它不必变成一团糟,但它确实需要思考。除此之外,如果可以的话,你应该真正使用 VBO(我怀疑你不能),不仅仅是为了性能,还因为它更好,未来,并且可以很好地扩展到更复杂的东西。
  • 感谢您的评论。我已经开始研究 VBO(目前我的原型使用显示列表)并且仍然需要阅读以完全了解它们。我不认为他们一定会把我带到我想去的地方(我假设一堆顶点在它自己的 VBO 中不会像一个带有一堆顶点的单个 VBO 那样有效)但我试图学习我能做的,以确保我不会走上错误的设计道路,只是后来发现“哦,你可以那样做吗?”我将在有关我的情况的问题中添加更多信息,以防提供建议。

标签: opengl rendering points


【解决方案1】:

为了解决这个问题,我首先使用 VBO(它确实加快了速度)。然后,我允许我的“轨道”对象分别绘制自己的一组点以及连接这些点的线(每个轨道使用两个 DrawArray:一个用于线带,一个用于点)。每个点不必独立于其他点来绘制自身——这是主要的性能改进。

但是,我仍然需要针对这些点进行命中测试,所以..

最后,我需要允许每个显示的对象(在本例中为轨道)执行自己的选择例程,以便每个对象都可以执行有效选择所需的操作。对于轨道,他们采取了两个步骤。首先,轨道用一个名称 (0) 为其整个线带命名并执行选择。如果导致命中,则轨道执行第二次渲染传递,命名每个单独的点和线段以针对轨道的每个部分进行命中测试。这使得对每个点的命中测试非常快。

顺便说一句,我正在使用 .Net (C#) 进行编程。有了它,我创建了一个派生自 EventArgs 的类 (SelectEventArgs) 来描述正在显示的对象的选择标准。我的SelectEventArgs 类包括一个旨在填充选定对象的列表。然后显示类有一个EventHandler<SelectEventArgs> 事件。将对象添加到显示时,它会订阅该事件。当事件触发时,每个对象确定它是否被选中,并用其信息填充所选对象的列表(在事件中传递的 SelectEventArgs 中)。事件触发后,我可以访问SelectEventArgs 实例中返回的对象列表来处理用户交互。我发现这是创建灵活的显示对象和选择工具的一个很好的模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    相关资源
    最近更新 更多