简体   繁体   English

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

[英]wpf (too many drawing visuals) cause jittery pan and zoom

in a canvas, i have around 2000 framework element derived items.. which inturn consist of around a total of 12000 drawing visuals. 在画布中,我有大约2000个框架元素派生项目。其中包含大约12000个绘图视觉效果。 This canvas represents a 2d view of a complex machine. 此画布表示复杂机器的二维视图。 And this canvas has pan and zoom logic. 这个画布有平移和缩放逻辑。
The drawing comes in a jiffy.. but when the machine/drawing is fully loaded.. then the pan and zoom is very jittery.. 画面很快......但是当机器/绘图完全装满时......然后平移和缩放非常紧张..

I could apply bitmapcache feature in .net4 to make it blazing fast. 我可以在.net4中应用bitmapcache功能,使其快速发展。 Then the problem is, when the canvas is zoomed into see the details.. pixel blocks can be seen.. which is very ugly.. 然后问题是,当画布放大时看到细节..可以看到像素块..这是非常难看的..

Is there any way to speed up this.? 有没有办法加快这个。


I dont find any reasonable answer for this.. 我没有找到任何合理的答案..

I tried like this.. first i had 10000 framework eleements which represents simple shapes like rectangles and circles.. It was damn slow.. 我试过这样的..首先我有10000个框架元素,它代表了简单的形状,如矩形和圆形......它很慢......

Then i tried one framework element which holds 10000 drawing visuals.. still it was slow.. 然后我尝试了一个框架元素,其中包含10000个绘图视觉效果..仍然很慢..

Then i tried one framework element which contain one drawing visual which contains 10000 drawings.. still it is slow... 然后我尝试了一个框架元素,其中包含一个包含10000个绘图的绘图视图..仍然很慢......

I'll start a bounty, I cannot set a bitmapcache all the time, cause the graphic is horrible. 我会开始赏金,我不能一直设置bitmapcache,因为图形太可怕了。

So what I'm doing right now is, at the moment of I right click to do my panning, I convert all my controls with bitmapcache, and when I release the button, I remove the bitmapcache. 所以我现在正在做的是,在我右键单击进行平移时,我使用bitmapcache转换所有控件,当我释放按钮时,我删除了bitmapcache。 Like this, it's only hideous when I'm panning, but it's very smooth. 像这样,当我平移时它只是可怕的,但它非常流畅。

The problem is when I convert everything with bitmapcache (or when I remove it), it takes about 1 second or 2 when I'm completely zoomed out... it's not acceptable to wait that time... 问题是当我用bitmapcache转换所有东西时(或当我删除它时),当我完全缩小时需要大约1秒或2秒......等待那段时间是不可接受的......

And for the performance, yes we freeze everything we can. 对于表演,是的,我们冻结了我们所能做的一切。

EDIT: 编辑:

I just tried on a beast computer : dual quad core 3.6ghz, 6GB video card, 16 gb ram, SSD, everything.... and it takes 1 second to convert all the control to cache... if I don't cache it lag a lot 我刚尝试了一台野兽电脑:双四核3.6ghz,6GB显卡,16GB RAM,SSD,一切....而且需要1秒才能将所有控制转换为缓存...如果我不缓存它落后很多

Try using to get the cached bitmap to be created at twice the resolution, so that when you zoom in its less pixelated. 尝试使用以两倍的分辨率创建缓存的位图,以便在放大其较少的像素化时。 Maybe even try 3 times resolution...obviously there will be a memory trade off at some point. 甚至可能尝试3倍的分辨率......显然在某些时候会有记忆权交换。 Note there is a bitmapcache size limit of 2048x2048. 请注意,bitmapcache大小限制为2048x2048。


Otherwise you could implement your own bitmap caching strategy - perhaps implement your own ScrollViewer and IScrollInfo, and create your own cached bitmaps using RenderTargetBitmap, and overlay that bitmap onto your canvas (and detach/hide the other set of visuals) while you are panning and zooming. 否则,您可以实现自己的位图缓存策略 - 也许实现您自己的ScrollViewer和IScrollInfo,并使用RenderTargetBitmap创建您自己的缓存位图,并在您平移时将该位图覆盖到画布上(并分离/隐藏另一组视觉效果)缩放。 To avoid the lag of creating the Bitmap (ie rendering all those visuals) when the zoom/pan is started, you could render the "machine" to aa high-resolution image in the background whenever the drawing has been modified, so it is ready to be used immediately. 为了避免在缩放/平移开始时创建位图(即渲染所有这些视觉效果)的延迟,只要图形被修改,就可以将“机器”渲染为背景中的高分辨率图像,因此它已准备就绪立即使用。

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


If the 2d view of your complex machine is readonly/not edited, then you could maybe use Deep Zoom. 如果您的复杂机器的2d视图是只读/不编辑的,那么您可以使用深度缩放。 The tricky bit would be in generating the high resolution images and creating the .dzi file. 棘手的一点是生成高分辨率图像并创建.dzi文件。 You'd have to host the .dzi on a webserver though. 你必须在网络服务器上托管.dzi。

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

Provided you can generate a set of images at the different resolutions, here is how you can join them together to build the .dzi. 如果您可以生成不同分辨率的图像集,则可以通过以下方式将它们组合在一起构建.dzi。

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

Allows analysis of .dzi file. 允许分析.dzi文件。

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


Or you could try ZoomableApplication2 which claims to be able to virtualize a million items...this would help when you are zoomed-in to reduce the elements being processed...but not when you are at normal 1:1 view. 或者您可以尝试ZoomableApplication2,它声称能够虚拟化一百万个项目......当您放大以减少正在处理的元素时,这将有所帮助......但是当您处于正常的1:1视图时则不会。 http://blogs.msdn.com/b/kaelr/archive/2010/08/11/zoomableapplication2-a-million-items.aspx http://blogs.msdn.com/b/kaelr/archive/2010/08/11/zoomableapplication2-a-million-items.aspx

How are you doing your pan and zoom? 你是如何进行平移和缩放的? If they're being done in a way that invalidates the Canvas's layout then it's possible that you're doing a full Measure and Arrange pass (or just Arrange) on every frame, which slows down very quickly with that many elements. 如果它们以一种使Canvas布局无效的方式完成,那么你可能会在每一帧上进行一次完整的测量和排列传递(或者只是排列),这会很快地减慢很多元素的速度。 If you can do the manipulations using the Canvas's RenderTransform the layout won't need to be recalculated on every movement. 如果您可以使用Canvas的RenderTransform进行操作,则不需要在每次移动时重新计算布局。

The other thing to try would be to try to reduce the number of FrameworkElements as much as possible, maybe by having a middle-man that takes a bunch of your current objects and spits out a single Visual to represent all of them in this view. 尝试的另一件事是尝试尽可能地减少FrameworkElements的数量,可能是让一个中间人占用你当前的一堆对象并吐出一个Visual来代表这个视图中的所有对象。 Obviously there won't be the same interaction capabilities doing this, but again I'm not sure of your specific needs. 显然,这样做不会有相同的交互功能,但我再也不确定您的具体需求。

What about using a Quadtree ? 使用四叉树怎么样?

For (2d) games with huge levels obviously you never draw the whole world, only what can be seen. 对于(2d)具有巨大水平的游戏,显然你永远不会画出整个世界,只有可以看到的东西。

Using a Quadtree will allow you to track objects location quite cheaply, later when drawing you only draw objects seen on (Quadtree) nodes visible on your screen. 使用四叉树将允许您非常便宜地跟踪对象位置,稍后绘制时只绘制在屏幕上可见的(四叉树)节点上看到的对象。 But this needs your own drawing routine. 但这需要你自己的绘图程序。

Here is some code I did of how to find what to draw, https://gamedev.stackexchange.com/questions/29121/organize-a-game-set 以下是我如何找到绘制内容的一些代码, https://gamedev.stackexchange.com/questions/29121/organize-a-game-set

Additionally, 另外,

Drawing 10K FrameworkElement, 12K DrawingVisual is an order or perhaps two of magnitude too high. 绘制10K FrameworkElement,12K DrawingVisual是一个或者两个数量级太高的订单。 If you have to keep these types IMO there should be more drawings per container, this way you will reduce some overhead. 如果你必须保留这些类型IMO,每个容器应该有更多的图纸,这样你将减少一些开销。

This might interest you (Virtualized WPF Canvas) : http://blogs.msdn.com/b/kaelr/archive/2009/05/21/priorityquadtree.aspx 您可能会对此感兴趣(Virtualized WPF Canvas): http //blogs.msdn.com/b/kaelr/archive/2009/05/21/priorityquadtree.aspx

Personally I switched to OpenGL for high-performance but I reckon this is an extreme solution :-))) 我个人转而使用OpenGL来获得高性能,但我认为这是一个极端的解决方案:-)))

请参阅此处获取具有Pan和Zoom的WPF VirtualCanvas实现,该实现可显示一百万个项目: ZoomableApplication2:百万项

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM