wpf(太多的绘图视觉效果)导致抖动平移和缩放

时间:2010-07-13 14:21:16

标签: c# .net wpf performance drawing

在画布中,我有大约2000个框架元素派生项目。其中包含大约12000个绘图视觉效果。此画布表示复杂机器的二维视图。这个画布有平移和缩放逻辑 这幅画很快...... 但是当机器/绘图装满时..然后平移和缩放非常紧张..

我可以在.net4中应用bitmapcache功能来快速实现它。 然后问题是,当画布放大时看到细节..可以看到像素块..这非常难看..

有没有办法加快这个。?


我没有找到任何合理的答案..

我试过这样的..首先我有10000个框架元素,它代表了简单的形状,如矩形和圆形......它很慢......

然后我尝试了一个框架元素,它拥有10000个绘图视觉效果..但它仍然很慢..

然后我尝试了一个框架元素,其中包含一个包含10000个绘图的绘图视图..仍然很慢......

7 个答案:

答案 0 :(得分:2)

你是如何进行平移和缩放的?如果它们以一种使Canvas布局无效的方式完成,那么你可能会在每一帧上进行一次完整的测量和排列传递(或者只是排列),这会很快地减慢很多元素的速度。如果你可以使用Canvas的RenderTransform进行操作,则不需要在每次移动时重新计算布局。

尝试的另一件事是尝试尽可能地减少FrameworkElements的数量,可能是让一个中间人占用你当前的一堆对象并吐出一个Visual来表示所有这些对象这个观点。显然,这样做不会有相同的交互功能,但我再也不确定你的具体需求。

答案 1 :(得分:2)

我会开始赏金,我不能一直设置bitmapcache,因为图形太可怕了。

所以我现在正在做的是,在我右键单击进行平移时,我使用bitmapcache转换所有控件,当我释放按钮时,我删除了bitmapcache。像这样,当我平移时它只是可怕,但它非常流畅。

问题是当我用bitmapcache转换所有内容时(或当我删除它时),当我完全缩小时需要大约1秒或2秒......等待那段时间是不可接受的......

对于表演,是的,我们冻结了我们所能做的一切。

编辑:

我刚试过一台野兽电脑:双四核3.6ghz,6GB显卡,16GB内存,SSD,一切....并且需要1秒才能将所有控制转换为缓存...如果我不喜欢不要缓存它滞后很多

答案 2 :(得分:2)

尝试使用以两倍的分辨率创建缓存的位图,以便在放大其像素化较少时。甚至可能尝试3倍的分辨率......显然在某些时候会有记忆权交换。请注意,bitmapcache大小限制为2048x2048。


否则你可以实现自己的位图缓存策略 - 也许实现你自己的ScrollViewer和IScrollInfo,并使用RenderTargetBitmap创建你自己的缓存位图,并将你的位图叠加到你的画布上(并分离/隐藏另一组视觉效果)正在平移和缩放。为了避免在缩放/平移启动时创建位图(即渲染所有这些视觉效果)的延迟,您可以渲染"机器"每当图纸被修改后,在背景中的高分辨率图像,所以它可以立即使用。

http://www.codeproject.com/Articles/97871/WPF-simple-zoom-and-drag-support-in-a-ScrollViewer


如果您的复杂机器的2d视图是只读/不编辑的,那么您可以使用Deep Zoom。棘手的一点是生成高分辨率图像并创建.dzi文件。您必须在网络服务器上托管.dzi。

http://www.codeproject.com/Articles/128695/Deep-Zoom-for-WPF

如果您可以以不同的分辨率生成一组图像,以下是将它们组合在一起构建.dzi的方法。

http://jimlynn.wordpress.com/2008/11/28/programmatically-create-deep-zoom-collections/

允许分析.dzi文件。

http://www.deepzoompublisher.com/Viewer/


或者您可以尝试ZoomableApplication2,它声称能够虚拟化一百万个项目......当您放大以减少正在处理的元素时,这将有所帮助...但是当您处于正常的1:1视图时则不会。 http://blogs.msdn.com/b/kaelr/archive/2010/08/11/zoomableapplication2-a-million-items.aspx

答案 3 :(得分:1)

使用Quadtree怎么样?

对于(2d)具有巨大水平的游戏,显然你永远不会画出整个世界,只有可以看到的东西。

使用Quadtree将允许您非常便宜地跟踪对象位置,稍后在绘制时只绘制在屏幕上可见的(四叉树)节点上看到的对象。但这需要你自己的绘图程序。

以下是我如何找到要绘制内容的一些代码, https://gamedev.stackexchange.com/questions/29121/organize-a-game-set

此外,

绘制10K FrameworkElement,12K DrawingVisual是一个或两个数量级太高的订单。如果你必须保留这些类型的IMO,每个容器应该有更多的图纸,这样你就可以减少一些开销。

您可能会对此感兴趣(虚拟化WPF画布): http://blogs.msdn.com/b/kaelr/archive/2009/05/21/priorityquadtree.aspx

就个人而言,我切换到OpenGL以获得高性能,但我认为这是一个极端的解决方案: - )))

答案 4 :(得分:1)

请参阅此处了解具有平移和缩放的WPF VirtualCanvas 实现,该实现可显示一百万个项目:ZoomableApplication2: A Million Items

答案 5 :(得分:0)

不确定它是否适用于您的代码,但您可以在视觉元素上使用“冻结”来提高性能。

答案 6 :(得分:0)

您可以将.NET 4.0与新的CacheMode API一起使用,它将极大地提升性能