I'm currently developing a visualization tool that draws WPF shapes such as paths, ellipses etc. on a Canvas. I've already implemented a virtualized approach where Shapes are being destroyed and created on the fly depending on their visibility. However, even with only like 600 ellipses visible, the application seems to struggle.
What are my options to speed things up? I'm thinking rendering grouped Shapes (let's say 500 at a time) as transparent bitmaps and only painting these on the Canvas. But I don't know whether that's a good idea... From what I gather this requires some sort of hack, if transformations were applied:
VisualBrush shapeBrush = new VisualBrush(shape);
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
using (drawingContext)
{
drawingContext.DrawRectangle(shapeBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
}
renderTarget.Render(drawingVisual);
What about using a big WritableBitmap? Would that be another approach?
WPF under the covers works with drawings and geometries - when you say you're working with shapes, are these actual UIElements? Such elements are quite a bit more heavy-weight. If you use just basic (preferably stream-) geometries to draw drawings, you'll get the best performance in my experience.
I managed to get up to around 10000 dots with a reasonable framerate with that approach, but anything more complex than a dot starts slowing things down (say, round dots or even just rectangles). Still, basic geometries and basic drawings are the way to go if you want to avoid as much WPF overhead as possible.
A Writeable bitmap is clearly eventually faster, but that means rending all those shapes yourself, or, caching the result bitmap if it's mostly static. Also, you'll generally want to apply transformations before rendering to bitmap rather than applying them to the rendered bitmap itself.
I'm aware this is an old question, I'm just answering in the interest of the community.
I researched the topic a bit, and the best I've found is to manually create DrawingVisuals like you say. It saves a lot of internal work to WPF, so it ends up being a lot faster. I used the technique to create a lightweight chart that can have couple hundred points. Here's the article I inspired myself from, you might already know about it.
http://blogs.microsoft.co.il/blogs/tamir/archive/2008/03/02/how-to-high-performance-graphics-in-wpf.aspx
EDIT: New URL http://khason.net/blog/how-to-high-performance-graphics-in-wpf/
EDIT: Newer URL: http://dedjo.blogspot.com/2008/03/how-to-high-performance-graphics-in-wpf.html
Good luck.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With