Я работал над книгой Фрэнка Д. Луны «Введение в 3D-программирование с DirectX 10», и одна из проблем заключается в том, чтобы отказаться от использования
Цвет D3DXCOLOR (128 бит)
в
Цвет UINT (32 бита)
Предположительно используемый код формата: DXGI_FORMAT_R8G8B8A8_UNORM.
На мой взгляд, это означает, что у вас есть переменная, которая на уровне байтов содержит информацию о каналах в точном порядке: RGBA (Это правильная интерпретация? — Спрашиваю, потому что я уверен, что я прочитал, когда вы хотите RGBA, вы действительно нужен код как: A # R # G # B # где альфа-канал указан первым.
Во всяком случае, я решил (возможно, есть лучший способ) сделать:
UINT color = (UINT)WHITE;
где БЕЛЫЙ определяется: const D3DXCOLOR WHITE(1.0f, 1.0f, 1.0f, 1.0f);
Это приведение определено в расширении до D3DXCOLOR.
Однако, когда DXGI_FORMAT_R8G8B8A8_UNORM используется с цветовой переменной UINT, вы получите неправильные результаты. Луна связывает это с порядком байтов.
Это потому, что приведение из D3DXCOLOR создает UINT в форме RGBA, а потому что intel x86 использует немного endiann, тогда на уровне байтов вы действительно получаете ‘ABGR’ ?? Итак, когда эта переменная действительно интерпретируется, шейдер видит ABGR вместо RGBA? Разве он не должен просто знать при интерпретации байтов, что биты более высокого порядка находятся по меньшему адресу?
И последний вопрос: поскольку код указан как DXGI_FORMAT_R8G8B8A8_UNORM, означает ли это, что R должен быть наименьшим адресом, а A должен быть самым большим? Я уверен, что у меня куча заблуждений, поэтому, пожалуйста, не стесняйтесь их развеять.
Когда вы используете оператор «UINT color = (UINT) WHITE», он вызывает преобразование оператора DWORD () D3DXCOLOR. Поскольку устаревшая версия D3DX9Math была разработана для Direct3D 9, это цвет BGRA (эквивалент DXGI_FORMAT_B8G8R8A8_UNORM от DXGI). Из d3dx9math.inl:
D3DXINLINE
D3DXCOLOR::D3DXCOLOR( DWORD dw )
{
CONST FLOAT f = 1.0f / 255.0f;
r = f * (FLOAT) (unsigned char) (dw >> 16);
g = f * (FLOAT) (unsigned char) (dw >> 8);
b = f * (FLOAT) (unsigned char) (dw >> 0);
a = f * (FLOAT) (unsigned char) (dw >> 24);
}
Поскольку исходная версия DXGI (v1.0) для Direct3D 10 не определяла DXGI_FORMAT_B8G8R8A8_UNORM (она была добавлена в DXGI 1.1), цвет по умолчанию для Direct3D 10+ — RGBA.
Все форматы DXGI имеют формат Little-Endian, поскольку это справедливо для всех платформ Direct3D 10+ Microsoft. Для Xbox 360 были представлены некоторые специальные Big-Endian версии Direct3D 9 D3DFORMAT, но это не совсем то, что здесь работает. Проблема более простая: BGRA и RGBA являются допустимыми вариантами, но Direct3D 9 предпочитает BGRA, а Direct3D 10+ предпочитает RGBA.
Чтобы немного запутать, соглашение об именах цветов Direct3D 9 D3DFMT для DXGI полностью изменено. «D3DFMT_A8R8G8B8» — это то же самое, что и «DXGI_FORMAT_B8G8R8A8_UNORM». Смотрите эту тему на MSDN. Исторически графика Windows называла бы это «32-битным ARGB» форматом, но более естественный способ описать это «BGRA».
Других решений пока нет …