我正在尝试实现类似于以下两个屏幕截图(gnome-system-monitor)的数据可视化工具:
正如您所看到的,这是一些网络流量的简单线图,每秒都会更新一次。但不是每秒更新一次,我想每10ms左右绘制一次“实时”数据。因为我最终会绘制很多数据点,所以我决定使用顶点缓冲对象(VBO),这样只需要将数据上传到GPU一次。 但即使使用VBO,性能也会有很大差异,因此我想知道实现这一点的最佳方法是什么。到目前为止,我提出了以下方案:
glTranslatef
移动'相机',最后重新渲染场景因为浏览大量的VBO并呈现内容需要很长时间(很多gl*
次调用),所以我也在考虑以下两种方法:
glMapBuffer
访问GPU上的数据。然后我将旋转数据,以便前几个点结束。然后我会在新传入数据的末尾覆盖这些点是否有更好的方法来实施我打算做的事情?如何最大限度地减少gl*
次呼叫的数量,以便获得类似100FP的信息?这是否真实(让我们说300000分)?
修改 据我所知,我无法真正渲染300000个数据点。但是,这不是我的问题。我的问题是如何最有效地更新这么多数据。对于方法一和二,我得到的东西就像10FPS,这是一个非常低的数字。
答案 0 :(得分:4)
您的屏幕可能水平约有2000像素。因此,您的绘图在任何给定时间内屏幕上最多只能有2000个可区分的数据点。这不是一个庞大的数据量。您是否尝试过将这一切都转移到每一帧的天真方法,并且在尝试对VBO的复杂管理变得聪明之前,确定这种方法表现不佳?
答案 1 :(得分:4)
将图形拆分为多个段,以便将每个段映射到单个VBO。收到一些新数据后,我将删除第一个VOB(将向左移出图表的VOB),创建一个新的VBO并上传新数据。然后我将用glTranslatef移动'相机',最后重新渲染场景
不,将数据保存在一个VBO中,但不要尝试一次绘制整个事物。您可以很好地绘制数据子集。 VBO娱乐也是一项昂贵的操作。只需更新它。
和以前一样,但是我将绑定旧的并将新数据上传到其中,而不是删除VBO并创建一个新的
更好,但请确保只使用glBufferSubData并且只更新已更改的数据点,而不是更新。
为图中的所有数据点创建一个VBO。获得新数据后,我可以使用glMapBuffer访问GPU上的数据。然后我将旋转数据,以便前几个点结束。然后我会在新传入数据的末尾覆盖这些点
为什么这么复杂?只需将基本索引偏移到VBO中并从那里绘制。
创建例如5个VBO:一个用于保存大部分屏幕数据的VBO。剩下的四个用于保存最后四个输入数据包的数据。通过这种方式,我可以始终只旋转最后4个VBO并使用新数据更新最后一个VBO。但我还必须在大型VBO中旋转数据。
你可以用一个VBO完美地做到这一点。试着将VBO视为一些只使用切片的内存。