2012-05-29 2 views
1

Я работаю над переносом существующего редактора tilemap на основе XNA/WinForms в WPF. Я довольно новичок в WPF, но большинство концепций не так сложно понять. У меня есть Boxbox, встроенный в ScrollViewer, с использованием метода DrawImage из DrawingContext, предоставленного методом OnRender (Viewbox) для рисования карты. Проблема в том, что я не могу достичь почти той же производительности, что и с версией XNA/WinForm, когда на экране отображается довольно большое количество фрагментов (> 1000 на моей машине). Я реализовал масштабирование и панорамирование, но когда я уменьшаю масштаб слишком далеко или панорамирую, когда на экране появляется большое количество фрагментов, происходит значительное отставание, которое разрушает пользовательский интерфейс. Я предпринял несколько очевидных мер оптимизации (замораживание исходного растрового изображения, отбраковка фрагментов, которые невозможно увидеть, установка режима масштабирования растровых изображений на LowQuality, предоставление подсказки кэширования кэша), но они, похоже, не устраняют проблему. Проблема, очевидно, в том, как WPF обрабатывает рисование текстурированных квадрациклов с помощью DrawingContext.WPF Slow Tilemap Rendering Performance

Я предоставил пример приложение со всем кодом, необходимого для воспроизведения проблемы: SampleGridDrawingExample

Удерживайте среднюю кнопку мыши и переместите мышь к лотку. Он становится все более заметным по мере увеличения размера окна (очевидно, потому что больше фрагментов визуализируется).

Есть ли более быстрый метод, чем DrawingContext в WPF для рисования больших объемов текстурированных квадрациклов с разумной производительностью ?. Используя XNA/WinForms, я могу нарисовать ~ 50000 фрагментов в нескольких слоях с разумным запаздыванием, тогда как в WPF, используя мой текущий подход, который превышает 1000, вызывает заметное отставание (> 10000 приводит приложение к обходу).

ответ

0

Похоже, что только с WPF в настоящее время невозможно достичь производительности XNA. Однако, взглянув на Nick Gravelyns post на интеграцию XNA, я решил использовать метод, указанный здесь, так как производительность приемлема для приложения, которое я разрабатываю.После небольшого изменения образца и последующего стресс-тестирования мне удалось сделать его достаточно стабильным для производственного кода. Я настоятельно рекомендую всем, кто интересуется интеграцией XNA-> WPF, взглянуть на этот пост.

0

Я скачал ваш образец, и он работает хорошо для меня, и не имеет больших отставаний в производительности. Однако, если я контролирую свою производительность, у вас, похоже, есть какое-то узкое место в любом вычислении, которое вы выполняете всякий раз, когда мышь перемещается. См. Прилагаемый скриншот, который иллюстрирует использование ЦП при многократном перемещении мыши (левая половина изображения) и перемещение его нечасто (правая половина).

CPU usage

Я предполагаю, что визуализация не то, что замедляет работу, но другой код в обработчиках событий. Чтобы убедиться, я установил RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;, который ведет себя точно так же на моей машине (хороший процессор, средний графический процессор). Я также проверял это на вопросы Memleak, но в отношении этого он выглядит нормально - в моих 64-битных окнах использование памяти никогда не превышает 64 мегабайта, а сбор мусора эффективно освобождает ресурсы сейчас и потом.

Вы упомянули свое предыдущее решение. Какая часть вашего решения была основана на XNA? XNA полагается на аппаратное ускорение (как и для WPF по умолчанию), WinForms, с другой стороны, просто ускоряется с CPU. Кто управляет вашей старой магией, вашим процессором или вашим GPU?

+0

Расчет во время перемещения мыши - это просто вычислить дельту мыши и прокрутить карту на ее основе. Я бы подумал, что это не проблема (но, очевидно, она часто вычисляет это при перемещении мыши, поэтому я понимаю прыжок в CPU). Старый редактор использует XNA для преобразования загруженных растровых изображений в Texture2Ds и для рендеринга (используя SpriteBatch). Цикл, который рисует карту, такой же, как в образце. Таким образом, по сути, GPU обрабатывает его, но есть некоторый процессор, участвующий в вычислении видимой области для отбраковки и реагирования на вход для масштабирования/панорамирования. – batchprogram

+0

Предполагая, что WPF использует аппаратное ускорение в моем примере, единственное отличие, которое я знаю в рендеринге между ним и моим старым редактором, состоит в том, что у моего старого редактора есть цикл, который связан с событием Idle приложения, которое перерисовывает карту со скоростью 60Гц. – batchprogram

1

WPF действительно использует аппаратное ускорение, но очень неэффективно - он делает слишком много призывов к призыву ко всему. Его возможности 3D-рендеринга предназначены для улучшения пользовательских интерфейсов, а не для сверхпрочного рендеринга (например, для создания десятков тысяч отдельных элементов). Возможно, ваш код может быть оптимизирован, но, конечно, нигде рядом с уровнем производительности, который дает XNA.

Лучшим вариантом для вас будет создание редактора в WPF, но держите рендерер в XNA и размещайте его внутри редактора.