2013-04-16 3 views
2

Я работаю над стилем игры «падающий песок».Оптимальный способ установки пиксельных данных?

Я пробовал много способов рисовать песок на экране, однако каждый способ, похоже, создает некоторые проблемы в той или иной форме.

Список вещей, которые я работал через:

  1. рисования каждого пикселя в отдельности, по одному из размера текстуры пикселей. Проблема: Замедление после того, как на обновление было изменено около 100 000 пикселей.

  2. Рисование каждого пикселя в одну большую текстуру2d, рисование текстуры2d, а затем очистку данных. Проблемы: использование texture.SetPixel() выполняется очень медленно, и даже с удалением старой текстуры это приведет к небольшой утечке памяти (около 30 кбит/с, что добавляется быстро) даже после вызова объекта на объект. Я просто не мог понять, как остановить его. В целом, однако, это был лучший метод (до сих пор). Если есть способ остановить эту утечку, я бы хотел ее услышать.

  3. Использование Lockbits из растрового изображения. Это отлично работало с точки зрения растровых изображений, но, к сожалению, мне все равно пришлось преобразовать растровое изображение обратно в texture2d, что приведет к снижению частоты кадров до единицы. Таким образом, это может работать очень хорошо, если я смогу найти способ рисовать растровое изображение в xna, не преобразовывая его (или что-то еще).

  4. Установка каждого пикселя в текстуру2d с установленным пикселем путем замены «старой» позиции пикселей на прозрачные пиксели, а затем установки новой позиции с соответствующим цветом. Это удвоило число наборов пикселей, необходимых для завершения работы, и был гораздо медленнее, чем при использовании номер 2.

Итак, мой вопрос, какие идеи лучше? Или идеи о том, как исправить стили 2 или 3?

+0

В ответ на # 1: Вы пытались дозировать ваши ничьи, а не по одному за раз? – 2013-04-17 05:06:31

+0

Нет, я так не верю, у вас есть ссылка или объяснение? (Если вы имеете в виду рисование похожих текстур вместе, да, это помогло, но это было не очень хорошо.) – Colton

+0

Ну, проще всего начать с того, чтобы просто использовать «SpriteBatch» и «Draw» каждый пиксель с назначением прямоугольник размером '1, 1' и образец из очень маленькой текстуры с нужным цветом. Если это все еще медленно, вы можете сделать все это вручную, а не использовать какие-либо текстуры вообще (нужно немного ускорить его). Это потенциально много полигонов, но это стоит того. – 2013-04-17 05:20:24

ответ

1

Я сразу же подумал, что вы задерживаете контур графического процессора. Графический процессор может иметь конвейер, который отстает от нескольких кадров за командами, которые вы выдаете.

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

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

Также вы можете писать текстуры из потока, отличного от потока рендеринга. Это может пригодиться, особенно для очистки текстур.

Как вы, кажется, обнаружили, что на самом деле это быстрее, чем SetData в больших кусках, а не вызывать много мелких звонков SetData. Определение идеального размера для «куска» различается между графическими процессорами, но оно справедливо немного больше, чем один пиксель.

Кроме того, создание текстуры происходит намного медленнее, чем повторное использование, в условиях сырой производительности (если вы проигнорируете эффект конвейера, который я только что описал); поэтому повторно используйте эту текстуру.

Стоит отметить, что «пиксельный спрайт» требует отправки в GPU в 30 раз больше данных на пиксель, чем текстуры.

См. Также this answer, который содержит несколько подробностей и некоторые углубленные ссылки, если вы хотите углубиться.

+0

Я думаю, что нить может быть моей следующей лучшей ставкой. Спасибо вам за вашу мудрость ... и ваши ссылки. :п – Colton