如何在画布上使用大量多边形来提高性能和内存使用率?

时间:2008-09-29 19:03:21

标签: wpf performance

我正在研究的项目需要渲染一个ESRI形状文件,该文件可以包含大量多边形/形状。当我将所有这些多边形,线条,点等添加到我正在使用的画布时,它变得非常慢。

要在地图上绘制形状,我正在创建一个Path对象,并将其Data属性设置为StreamGeometry。我最初使用的是Polygon,但根据MSDN,StreamGeometry的重量要轻得多。

如何改善表现?将成品转换为Bitmap,还是VisualBrush帮助?有没有更有效的方法将所有这些形状渲染到画布上?

编辑:我忘了提到这需要能够在部分信任XBAP中工作。

8 个答案:

答案 0 :(得分:7)

无需诉诸GDI,您只需在WPF API中向下移动一层,并将几何图形组合成更少的视觉效果。 Pablo Fermicola根据您的表现需求提供了一些有关picking which layer的有用信息。

我使用DrawingVisualDrawingContext类设法获得了出色的效果。

答案 1 :(得分:2)

您可以尝试使用GDI +或直接x而不是WPF。

我做了一个类似的项目(通过WPF渲染地图数据),这是我一年前写的一篇MSDN杂志文章。

这只是我写得相当快的东西(文章+应用程序花了大约1周),并且只是为了“这是你可以做的事情”,所以我没有太注重性能。无论如何,我遇到了同样的问题。一旦画布上的多边形数量变大,渲染性能就开始下降。例如,调整窗口大小将导致大约1/2秒的延迟。

这很大程度上与WPF的开销有关。它主要设计为GUI工具包,而不是高性能图形引擎。这意味着它专注于功能丰富而不是高效渲染。使用较少数量的对象(在大多数GUI应用程序中可能会发现),性能非常好,数据绑定,动画和声明式样式功能(以及所有事件路由和其他需要的东西)都可以派上用场

然而,在绘制地图时,如你所知,大量的数据会导致所有这些整洁的数据绑定功能导致性能问题。

如果你不需要声明式样式和动画,那么我只需要消除WPF,并使用GDI +绘制你自己的地图。它基本上涉及设置正确的变换矩阵以使地图绘制到控制表面上,然后遍历所有多边形并调用一堆DrawPolygon方法。

要启用交互,您必须编写自己的命中测试代码,并且必须在调整窗体大小时重新绘制地图。您还必须手动编写任何动画或样式更改或您想要做的事情(例如,当鼠标悬停在区域上时突出显示区域)。但是,编写代码并不困难。我会想象你可以在大约1.5周内完成它。

但是,这样做可以提高性能,因为它只能做大约20-30K的矢量转换,这在大多数现代CPU上都不需要太多的处理器能力。您还可以考虑使用Direct X,它可以让您利用GPU,这可以提供更大的性能提升。

答案 2 :(得分:1)

您可能会受到画布小部件性能的限制。如果您可以选择使用第三方工具包,请查看QT.它具有高性能canvas widget,旨在快速呈现复杂形状。这已用于at least one GIS application,因此它在此空间中有一些记录。

您可以wrap QT as an ActiveX control或使用Qyoto/Kimono .Net绑定来连接.Net应用程序。 Troll Tech刚刚修改了他们的网站,我找不到他们曾经拥有的可下载演示,但它显示了QGraphicsView小部件渲染了一个非常大的矢量绘图并实时缩小。

答案 3 :(得分:0)

您即将发现GPU背后的动机以及疯狂超频和冷却的显卡。并且双缓冲。

并且:将事物转换为位图:渲染它的区别是什么?

毕竟你有n个/某种/必须要渲染的对象(除非你可以弄清楚哪些对象隐藏在其他对象后面但是这对你没什么帮助,因为你必须看看n!对象关系)。

此外:也许离开正统的OOP方法并转而采用程序化是值得的。

答案 4 :(得分:0)

@xmjx

  

并且:将事物转换为位图:渲染它的区别是什么?

我的想法是,我的减速可能是由于画布上有n个对象而不是1个位图造成的。也就是说,我不知道性能,或者在将具有n个对象的画布转换为Bitmap时在后台发生的情况。

我不想使用Bitmap,因此我可以允许用户与形状/多边形进行交互(修改/删除)。

答案 5 :(得分:0)

如果性能是个问题,那么您需要避免使用Visual Brushes。这些画笔最适合用于将屏幕的某些可见部分投影到屏幕上的另一个位置。它们会导致性能大幅下降,因为这些画笔会在画笔内容发生变化时自动更新。

此画笔的任何使用都将通过软件呈现,并且无法利用图形卡的硬件功能。

More info from MSDN on VisualBrush

答案 6 :(得分:0)

使用DrawingGroup并添加/删除Drawing对象来解决此问题。有关answer的类似问题,请参阅我的DrawingVisual performance with Opacity=0。我认为我的答案实际上更适合这个问题。

答案 7 :(得分:0)

如果您不必一次显示所有多边形(例如由于缩放,平移等),请查看虚拟化画布样本here