XNA Texture2D GetData


Это мой код для создания Texture2D из depthFrame Kinect:

private short[] depthData;
private Texture2D depthTexture;
Color[] depthTextureData;

if (null == this.depthData || this.depthData.Length != frame.PixelDataLength)
{
    this.depthData = new short[frame.PixelDataLength];

    this.depthTexture = new Texture2D(
        this.GraphicsDevice,
        frame.Width,
        frame.Height,
        false,
        SurfaceFormat.Bgra4444);


    this.backBuffer = new RenderTarget2D(
        this.GraphicsDevice,
        frame.Width,
        frame.Height,
        false,
        SurfaceFormat.Color,
        DepthFormat.None,
        this.GraphicsDevice.PresentationParameters.MultiSampleCount,
        RenderTargetUsage.PreserveContents);
}

frame.CopyPixelDataTo(this.depthData);

depthTextureData = new Color[frame.Width * frame.Height];
depthTexture.GetData(depthTextureData);

Я получаю ошибку на depthTexture.GetData(depthTextureData);, и она говорит:

Необработанное исключение типа 'System.ArgumentException ' произошло в Microsoft.Хна.Рамки.Графика.dll дополнительная информация: тип, который вы используете для T в этом методе, является недопустимым размером для этого ресурс.

Кто-нибудь знает, в чем проблема ?

2 2

2 ответа:

В основном методGetData запрашивает массив для получения данных.

Согласно MSDN, этот метод может выдавать два различных исключения: ArgumentNullException и/илиInvalidOperationException .

Если вы получаете первый, это, вероятно, потому, что значение depthTextureData равно нулю к тому времени, когда вы используете его с GetData.

Если это не так, вы пытались указать тип T при вызове метода, как показано на рисунке на документации microsoft ?

backBufferData.GetData<Color>(...);

В этом вызове вы указываете, что тип T будет Color, а затем передаете его экземпляр, используя любую перегрузку, которая вам больше всего нравится.

Если вы все еще не можете решить проблему, вы можете взглянуть на тип формата (полное объяснение проблемы ответ можно найти здесь ):

Здесь возможные типы форматов.

Вам придется проверить texture.Format и используйте правильную структуру данных для его SurfaceFormat.

Например.

var b = new Bgr565[result.Width * result.Height];
tex.SetData(b);

Приведенные ниже SurfaceFormat имеют соответствующие типы значений, которые могут быть использованы.

Color
Bgr565
Bgra5551
Bgra4444
NormalizedByte2
NormalizedByte4
Rgba1010102
Rg32
Rgba64
Alpha8
Single
Vector2
Vector4
HalfSingle
HalfVector2
HalfVector4
Формат

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

Вы можете найти библиотеку декомпрессии DXT1 и DXT5 где-нибудь. К сожалению, я не могу найти ничего управляемого настолько небезопасного кода C# вероятно, это лучший вариант для его преобразования. Согласно Википедии, 16 пикселей хранятся в 8 байтах, что делает иметь байт на пиксель, так что теоретически byte[] data = new byte[(Width * Height) / 2] должен работать для извлечения данных.

Dxt1
Dxt3
Dxt5

Это частный случай, просто используйте HalfVector4 для типа, и вы в порядке. HdrBlendable

На самом деле мой тип данных был Color, но я должен использовать Bgra4444. чтобы использовать этот тип данных, я должен использовать пространство имен Microsoft.Хна.Рамки.Графика.PackedVector, а затем сделать массив Bgra4444 и использовать ToVector4 (), чтобы преобразовать поплавковый вектор (р, г, Б, а) использовать поплавковый вектор массива.