Преобразование байтового массива в texture2D XNA

У меня есть байтовый массив, представляющий изображение.

Каждый байт представляет значение интенсивности (0-255) R, G или B конкретного пикселя. Таким образом, для изображения 640x480 байтовый массив имеет размер 640 * 480 * 3 (каждый пиксель имеет 3 байта, представляющих его).

Байты отсортированы по пикселям. Например:

image[0] = the R value of x=0 y=0 
image[1] = the G value of x=0 y=0
image[2] = the B value of x=0 y=0
image[3] = the R value of x=1 y=0

и так далее.

Мне интересно, какой самый эффективный способ отобразить это на экране в XNA?

Я думаю о следующем.

  1. Создайте новый объект Texture2d
  2. Во время метода draw () выполните цикл по массиву байтов и установите значения в объекте Texture2D.
  3. Нарисуйте этот залитый объект на экране.

Это самый быстрый способ сделать это? Я также могу хранить массив байтов в другом порядке / формате, если он более эффективен. Есть ли какие-либо недостатки в выполнении цикла во время метода draw ()? Было бы лучше сделать это во время update ()?

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

Я попытался использовать setData () в Texture2D для создания новой текстуры каждый раз, когда мой байтовый массив обновляется (обычно один раз в кадре). Теперь частота кадров ниже 15, тогда как раньше была 60. Код выглядит следующим образом:

    public static Texture2D getImageFrame(GraphicsDevice gd)
    {
        if (cameraTex == null)
        {
            cameraTex = new Texture2D(gd, 640, 480, false, SurfaceFormat.Color);
        }
        cameraTex.SetData(imageFrame);
        return cameraTex;
    }

Это называется каждым циклом draw ().

Неужто должен быть более эффективный способ сделать это?


person Jkh2    schedule 19.03.2012    source источник
comment
Я настоятельно рекомендую изучить использование шаблона Flyweight в качестве шаблона проектирования, который следует учитывать при разработке этого приложения. Я думаю, что одной из ваших самых больших проблем будет общий поиск / хранение этих данных с учетом времени на каждой итерации вашего рисования / обновления. en.wikipedia.org/wiki/Flyweight_pattern   -  person George Johnston    schedule 19.03.2012
comment
Что касается хранения байтового массива, я не передаю его как объект. Он обновляется каждый кадр из другого процесса, и я ищу способ преобразовать эти данные в drawable texture2d каждый кадр.   -  person Jkh2    schedule 19.03.2012
comment
Вероятно, вы захотите что-то сделать с помощью SetData, тогда.   -  person thedaian    schedule 19.03.2012
comment
Я попытался использовать setdata, передаваемый в моем byte [] в качестве входных данных. Вылетает за исключением того, что размер данных слишком велик или слишком велик. Размер байтового массива 640 * 480 * 3. Кто-нибудь знает, какой размер setData ожидается для изображения размером 640x480?   -  person Jkh2    schedule 20.03.2012
comment
РЕДАКТИРОВАТЬ: разобрал, забыл альфа-канал ... Теперь новая проблема в том, что это очень медленно. Моя частота кадров сейчас ниже 15, тогда как раньше она была стабильной и составляла 60.   -  person Jkh2    schedule 20.03.2012


Ответы (1)


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

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

public void SetData (данные T [], int startIndex, int elementCount)

public void SetData (int level, Nullable rect, T [] data, int startIndex, int elementCount)

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.texture2d.setdata.aspx

person kallotec    schedule 19.03.2012
comment
Поскольку код вызывается каждый раз, когда вы Draw (), вы также можете создать флаг, сообщающий, действительно ли байтовый массив обновлен, поэтому if (bytesUpdated) - person kallotec; 20.03.2012