2009-09-29 9 views
13

Actualmente estoy desarrollando una herramienta de visualización que dibuja formas de WPF como caminos, elipses, etc. en un lienzo. Ya implementé un enfoque virtualizado donde las formas se destruyen y se crean sobre la marcha en función de su visibilidad. Sin embargo, incluso con solo 600 elipses visibles, la aplicación parece tener dificultades.Desempeño de WPF: mostrar miles de rutas/formas en un lienzo

¿Cuáles son mis opciones para acelerar las cosas? Estoy pensando en representar formas agrupadas (digamos 500 a la vez) como bitmaps transparentes y solo pintarlas en el lienzo. Pero no sé si eso es una buena idea ... Por lo que sé esto requiere algún tipo de corte, si se aplican las transformaciones:

 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); 

¿Qué pasa con el uso de una gran WritableBitmap? ¿Ese sería otro enfoque?

Respuesta

6

WPF debajo de las cubiertas funciona con dibujos y geometrías: cuando dices que estás trabajando con formas, ¿son estos UIElements reales? Tales elementos son un poco más pesados. Si usa geometrías básicas (preferiblemente de flujo) para dibujar dibujos, obtendrá el mejor rendimiento en mi experiencia.

Me las arreglé para obtener hasta 10000 puntos con un framerate razonable con ese enfoque, pero cualquier cosa más compleja que un punto comienza a desacelerar cosas (por ejemplo, puntos redondos o incluso solo rectángulos). Aún así, las geometrías básicas y los dibujos básicos son el camino a seguir si se quiere evitar la mayor cantidad de sobrecarga de WPF posible.

Un mapa de bits escribible es claramente más rápido, pero eso significa rasgar todas esas formas usted mismo, o almacenar en caché el mapa de bits resultante si es mayormente estático. Además, generalmente querrá aplicar transformaciones antes de renderizar en mapas de bits en lugar de aplicarlos al mapa de bits renderizado.

+0

Actualmente estoy utilizando este enfoque: una clase VirtualPath que almacena los datos de ruta y devuelve un WPF System.Windows.Shapes.Path tan pronto como sus límites son visibles. – kitsune

+0

Gracias por indicarme StreamGeometry, todavía no conocía esta clase – kitsune

+1

@kitsune, ¿alguna vez completó su truco "virtualpath que devuelve una ruta tan pronto como sea visible"? Creo que podría beneficiarme de esto en uno de mis proyectos –

-1

Un enfoque de fuerza bruta podría ser implementar un control ActiveX y representar los gráficos directamente utilizando Win32. Sin embargo, esto será un poco complicado. El control del lienzo de QT podría ser un enfoque más cálido y esponjoso para el mismo fin y se destaca por representar este tipo de cosas con bastante rapidez. Troll proporciona un contenedor ActiveX para las versiones comerciales de QT, por lo que podría ser más fácil integrarlo.

+1

¿Cómo es relevante esto para una pregunta etiquetada 'WPF'? – stakx

2

Soy consciente de que esta es una vieja pregunta, solo estoy respondiendo en interés de la comunidad.

Investigué el tema un poco, y lo mejor que he encontrado es crear manualmente DrawingVisuals como dices. Se ahorra mucho trabajo interno a WPF, por lo que termina siendo mucho más rápido. Usé la técnica para crear un gráfico ligero que puede tener un par de cientos de puntos. Aquí está el artículo del que me inspiré, es posible que ya lo sepas.

http://blogs.microsoft.co.il/blogs/tamir/archive/2008/03/02/how-to-high-performance-graphics-in-wpf.aspx

EDIT: Nueva URL http://khason.net/blog/how-to-high-performance-graphics-in-wpf/
EDIT: reciente URL: http://dedjo.blogspot.com/2008/03/how-to-high-performance-graphics-in-wpf.html

Buena suerte.