DXGI_FORMAT_代码如何与endianness相关工作

How do the DXGI_FORMAT_ codes work in relation to endianness?

本文关键字:endianness 工作 FORMAT 代码 DXGI      更新时间:2023-10-16

我一直在阅读Frank D.Luna的书《DirectX 10 3D编程简介》,其中一个问题是从使用切换

D3DXCOLOR颜色(128位)
到UINT彩色(32位)

假定要使用的格式代码为:DXGI_format_R8G8B8_UNORM。

在我看来,这意味着你有一个变量,它在字节级别上有关于通道的准确顺序信息:RGBA(这是正确的解释吗?——问,因为我相信我读过,当你想要RGBA时,你真的需要一个代码,比如:a#R#G#B#,其中首先指定了alpha通道。

无论如何,我选择了(可能有更好的方法):

UINT color = (UINT)WHITE; 

其中白色定义为:const D3DXCOLOR WHITE(1.0f, 1.0f, 1.0f, 1.0f);此强制转换是在D3DXCOLOR的扩展中定义的。

但是,当DXGI_FORMAT_R8G8B8_UNORM与UINT颜色变量一起使用时,会得到错误的结果。Luna将此归因于endianness。

这是因为D3DXCOLOR的强制转换生成了RGBA形式的UINT,但因为intelx86使用了小endiann,那么在字节级别上,你真的得到了"ABGR"吗??所以,当这个变量被实际解释时,着色器看到的是ABGR而不是RGBA?难道它不应该在解释字节时知道高阶比特在较小的地址吗?最后一个问题:由于代码被指定为DXGI_FORMAT_R8G8B8_UNORM,这是否意味着R应该是最小的地址,而A应该是最大的地址?我相信我有很多误解,所以请随时消除它们。

当您使用语句"UINT color=(UINT)WHITE"时,它正在调用D3DXCOLOR运算符DWORD()转换。由于传统D3DX9Math是为Direct3D 9设计的,因此它是一种BGRA颜色(相当于DXGI的DXGI_FORMAT_B8G8R8A8_UNORM)。从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的原始Direct3D 10版本(v1.0)没有定义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"。