Как выбрать формат пикселей при создании нового Texture2D?

Я использую SharpDX Toolkit и пытаюсь программно создать Texture2D, поэтому я могу вручную указать все значения пикселей. И я не уверен, в каком формате пикселей его создавать.

SharpDX даже не документирует тип PixelFormat инструментария (у них есть документация для другого класса PixelFormat но это для WIC, а не для инструментария). Я нашел перечисление DirectX, которое оно обертывает, DXGI_FORMAT, но его документация не дает никаких полезных указаний о том, как выбрать формат.

Я привык к старым 32-битным форматам растровых изображений с 8 битами на цветовой канал плюс 8-битный альфа-канал, что для меня вполне достаточно. Поэтому я предполагаю, что самым простым выбором будет R8G8B8A8 или B8G8R8A8. Имеет значение, что я выберу? Будут ли они оба полностью поддерживаться на всем оборудовании?

И даже после того, как я выбрал один из них, мне нужно дополнительно указать, является ли он SInt, SNorm, Typeless, UInt, UNorm или UNormSRgb. Мне не нужно цветовое пространство sRGB. Я не понимаю, для чего должен быть Typeless. UInt кажется самым простым - просто старый беззнаковый байт, но оказывается, что он не работает; Я не получаю сообщения об ошибке, но моя текстура ничего не выводит на экран. UNorm работает, но в документации нет ничего, что объясняло бы, почему UInt не работает. Так что теперь я параноик, что UNorm может не работать на какой-то другой видеокарте.

Вот код, который у меня есть, если кто-то хочет его увидеть. Загрузите полный пакет SharpDX, откройте проект SharpDXToolkitSamples, перейдите в проект SpriteBatchAndFont.WinRTXaml, откройте класс SpriteBatchAndFontGame и добавьте указанный код:

// Add new field to the class:
private Texture2D _newTexture;

// Add at the end of the LoadContent method:
_newTexture = Texture2D.New(GraphicsDevice, 8, 8, PixelFormat.R8G8B8A8.UNorm);
var colorData = new Color[_newTexture.Width*_newTexture.Height];
_newTexture.GetData(colorData);
for (var i = 0; i < colorData.Length; ++i)
    colorData[i] = (i%3 == 0) ? Color.Red : Color.Transparent;
_newTexture.SetData(colorData);

// Add inside the Draw method, just before the call to spriteBatch.End():
spriteBatch.Draw(_newTexture, new Vector2(0, 0), Color.White);

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

Какой формат пикселей мне следует использовать, чтобы убедиться, что мое приложение будет работать на любом оборудовании и обеспечить максимальную производительность?


person Joe White    schedule 20.11.2012    source источник
comment
Часть вопроса - uint будет возвращать значения как целое число в вашем шейдере, unorm возвращает их как числа с плавающей запятой в диапазоне 0,0..1,0, что обычно ожидается в шейдере для цветов, и что вам обычно нужно возвращать из пиксельный шейдер. Если вы выбрали текстуру int и преобразовали значения в шейдере, это, вероятно, сработает.   -  person jcoder    schedule 23.11.2012
comment
@ J99: Насколько мне известно, на картинке нет шейдера. Я просто пытаюсь использовать SpriteBatch для размещения растрового изображения на экране, и, насколько я могу судить, DirectX вызывает текстуры растровых изображений. Есть ли важные детали, которые мне не хватает?   -  person Joe White    schedule 23.11.2012
comment
Хорошо, внутри библиотеки, которую я исключаю, будет использоваться шейдер, но если у вас нет к нему доступа, это не сработает. Прости   -  person jcoder    schedule 23.11.2012


Ответы (1)


Форматы в SharpDX Toolkit соответствуют базовым форматам DirectX / DXGI, поэтому вы можете, как обычно с продуктами Microsoft, получать информацию из MSDN:

Перечисление DXGI_FORMAT (Windows)

32-битные текстуры являются обычным выбором для большинства сценариев текстур и имеют хорошую производительность на старом оборудовании. UNorm означает, как уже было сказано в комментариях, «в диапазоне 0,0 .. 1,0» и, опять же, это распространенный способ доступа к данным цвета в текстурах.

Если вы посмотрите на аппаратную поддержку, для Direct3D 10Level9 Formats (Windows) вы увидите, что DXGI_FORMAT_R8G8B8A8_UNORM, а также DXGI_FORMAT_B8G8R8A8_UNORM поддерживаются на оборудовании DirectX 9. Вы не столкнетесь с проблемами совместимости с ними обоими.

Производительность зависит от того, как инициализируется ваше устройство (RGBA / BGRA?) И какое оборудование (= поддерживаемый уровень функций DX) и ОС, на которых вы запускаете свое программное обеспечение. Вам нужно будет запустить свои собственные тесты, чтобы выяснить это (хотя в случае этих общих и похожих форматов разница должна составлять максимум однозначный процент).

person Jens Nolte    schedule 25.11.2012
comment
Да, но я предположил, что UNorm был плохим выбором потому что он (некоторые) вещи выполняет как плавающие, а цвета в современных (24- или 32-битных) видеорежимах обычно представлены в виде байта для каждый канал - все целые числа, без чисел с плавающей запятой; поплавки медленные по сравнению с целыми числами. Значит, DirectX действительно представляет цвета как плавающие? Похоже, это требует много дополнительной работы с оборудованием. - person Joe White; 25.11.2012
comment
@JoeWhite: нет плавающей точки из-за нормализации: 0x00 представляет 0/255 = 0, 0x01 представляет 1/255, а 0xFF представляет 255/255 = 1. (Они хотя и будут разрешать в шейдере числа с плавающей запятой, но именно так они и нужны для умножения с другими цветами в любом случае). Это также не специальная вещь DirectX, но распространенная среди графических библиотек, как вы можете увидеть в Формат изображения - OpenGL-Wiki - person Jens Nolte; 26.11.2012