我一直在研究Frank D. Luna的书“使用DirectX 10进行3D编程简介”,其中的问题之一是从使用
D3DXCOLOR颜色(128位)
至
UINT颜色(32位)
大概使用的格式代码是:DXGI_FORMAT_R8G8B8A8_UNORM。
在我看来,这意味着您有一个变量,该变量在字节级别上具有与通道有关的信息的确切顺序:RGBA(这是正确的解释吗?-问,因为我确定当您需要RGBA时我已经读过它确实需要这样的代码:A#R#G#B#首先指定Alpha通道。
无论如何,我选择了(可能有更好的方法):
UINT color = (UINT)WHITE;
定义了WHITE的位置:
const D3DXCOLOR WHITE(1.0f, 1.0f, 1.0f, 1.0f);
此强制转换在D3DXCOLOR的扩展中定义。但是,当DXGI_FORMAT_R8G8B8A8_UNORM与UINT颜色变量一起使用时,您将得到错误的结果。 Luna将其归因于字节顺序。
这是因为从D3DXCOLOR进行的强制转换会生成RGBA形式的UINT,但是由于Intel x86使用的字节序很少,因此在字节级别上您确实得到了“ABGR”?因此,当实际解释此变量时,着色器看到的是ABGR而不是RGBA?在解释字节时,难道不只知道高阶位在较小的地址上吗?
最后一个问题:由于代码指定为DXGI_FORMAT_R8G8B8A8_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(v1.0)的原始Direct3D 10版本未定义DXGI_FORMAT_B8G8R8A8_UNORM(它与DXGI 1.1一起添加),因此Direct3D 10+使用的“默认”颜色为RGBA。
所有DXGI格式都是Little-Endian,因为所有Direct3D 10+ Microsoft平台都是如此。对于Xbox 360,引入了Direct3D 9 D3DFORMAT的一些特殊的Big-Endian版本,但这并不是这里真正起作用的。问题是更基本的:BGRA和RGBA都是有效的选项,但是Direct3D 9首选BGRA,而Direct3D 10+则首选RGBA。
为了使事情更加困惑,DXGI颠倒了Direct3D 9 D3DFMT颜色的命名约定。 “D3DFMT_A8R8G8B8”与“DXGI_FORMAT_B8G8R8A8_UNORM”相同。请参阅MSDN上的该主题。历史上Windows图形将其称为“32位ARGB”格式,但更自然的描述方式是“BGRA”。
关于c++ - DXGI_FORMAT_代码相对于字节顺序如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12877399/