wpf (слишком много графических изображений) вызывает резкое панорамирование и масштабирование - PullRequest
3 голосов
/ 13 июля 2010

на холсте у меня есть около 2000 элементов, производных от элемента каркаса, которые включают в себя около 12000 графических визуальных элементов.Этот холст представляет 2d вид сложной машины.И у этого холста есть логика панорамирования и масштабирования.
Рисунок приходит в один миг ... но когда машина / чертеж полностью загружен ... тогда панорамирование и масштабирование очень нервные ..

Я мог бы применитьФункция bitmapcache в .net4, чтобы сделать его быстрым.Тогда проблема в том, что когда холст увеличен, чтобы увидеть детали ... можно увидеть пиксельные блоки ... что очень уродливо ..

Есть ли способ ускорить это ??


Я не могу найти никакого разумного ответа на это ..

Я пытался вот так ... сначала у меня было 10000 каркасных элементов, представляющих простые формы, такие как прямоугольники и круги ... Это было чертовски медленно ..

Затем я попробовал один элемент каркаса, который содержит 10000 графических изображений ... все еще он был медленным ..

Затем я попробовал один элемент каркаса, который содержит один визуальный объект чертежа, который содержит 10000 рисунков ... все еще он медленный...

Ответы [ 7 ]

2 голосов
/ 14 июля 2012

Попробуйте использовать, чтобы получить кэшированное растровое изображение, созданное с удвоенным разрешением, чтобы при увеличении его было меньше пикселей.Может быть, даже попробуйте разрешение в 3 раза ... очевидно, в какой-то момент произойдет обмен памяти.Обратите внимание, что ограничение размера растрового кэша составляет 2048x2048.


В противном случае вы можете реализовать свою собственную стратегию кэширования растрового изображения - возможно, реализовать собственный ScrollViewer и IScrollInfo, а также создать собственные кэшированные растровые изображения с помощью RenderTargetBitmap и наложить это растровое изображениена ваш холст (и отсоединить / скрыть другой набор визуальных эффектов) во время панорамирования и масштабирования.Чтобы избежать отставания в создании растрового изображения (т. Е. Рендеринга всех этих визуальных элементов) при запуске масштабирования / панорамирования, вы можете визуализировать «машину» в виде изображения с высоким разрешением в фоновом режиме всякий раз, когда чертеж был изменен, поэтому он готовдля немедленного использования.

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


Если 2-мерный вид вашей сложной машины доступен только для чтения / не редактируется, возможно, вы можете использовать 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

2 голосов
/ 10 июля 2012

Я начну щедрость, я не могу установить битовый кэш все время, потому что графика ужасна.

То, что я сейчас делаю, в тот момент, когда я щелкаю правой кнопкой мыши, чтобы сделатьпанорамирование, я преобразовываю все свои элементы управления с помощью bitmapcache, и когда я отпускаю кнопку, я удаляю bitmapcache.Как это, это только отвратительно, когда я панорамирую, но это очень гладко.

Проблема в том, что когда я конвертирую все с помощью bitmapcache (или когда я его удаляю), это занимает около 1 секунды или 2, когда я 'я полностью уменьшен ... недопустимо ждать этого времени ...

И для исполнения, да, мы замораживаем все, что можем.

РЕДАКТИРОВАТЬ:

Iтолько что попробовал на чудовищном компьютере: двухъядерный процессор 3,6 ГГц, видеокарта 6 ГБ, 16 ГБ ОЗУ, SSD, все ... и требуется 1 секунда, чтобы преобразовать все элементы управления в кэш ... если я не кеширую егомного отстает

2 голосов
/ 14 июля 2010

Как у вас дела с панорамированием и масштабированием?Если они выполняются способом, который делает недействительным макет Canvas, возможно, вы выполняете полный проход «Измерить и расположить» (или просто расположить) в каждом кадре, который очень быстро замедляется с таким количеством элементов.Если вы можете выполнять манипуляции с помощью Canvas RenderTransform, вам не нужно будет пересчитывать макет при каждом движении.

Другая вещь, которую стоит попробовать, - попытаться максимально уменьшить количество FrameworkElements, возможно.имея посредника, который берет кучу ваших текущих объектов и выплевывает один визуал для представления всех их в этом представлении.Очевидно, что при этом не будет таких возможностей взаимодействия, но, опять же, я не уверен в ваших конкретных потребностях.

1 голос
/ 15 июля 2012

См. Здесь реализацию WPF VirtualCanvas с панорамированием и масштабированием, которая может отображать миллион элементов: ZoomableApplication2: миллион элементов

1 голос
/ 11 июля 2012

Как насчет использования Quadtree ?

Для (2d) игр с огромными уровнями очевидно, что вы никогда не рисуете весь мир, только то, что видите.

Использование Quadtree позволит вам довольно дешево отслеживать местоположение объектов, позже при рисовании вы рисуете только объекты, видимые на (Quadtree) узлах, видимых на вашем экране. Но для этого нужна собственная рутина рисования.

Вот код, который я сделал, чтобы найти, что рисовать, https://gamedev.stackexchange.com/questions/29121/organize-a-game-set

Кроме того,

Drawing 10K FrameworkElement, 12K DrawingVisual - это порядок или, возможно, на два порядка больше. Если вам нужно сохранить эти типы IMO, в одном контейнере должно быть больше чертежей, таким образом вы уменьшите некоторые накладные расходы.

Это может вас заинтересовать (виртуализированный холст WPF): http://blogs.msdn.com/b/kaelr/archive/2009/05/21/priorityquadtree.aspx

Лично я перешел на OpenGL для высокой производительности, но считаю, что это экстремальное решение: -)))

0 голосов
/ 20 июня 2011

Вы можете использовать .NET 4.0 с новыми API-интерфейсами CacheMode, это значительно повысит производительность

0 голосов
/ 20 апреля 2011

Не уверен, применимо ли это к вашему коду, но вы можете использовать «Freeze» для визуального элемента для повышения производительности.

...