c++ - DXGI_FORMAT_ 代码如何与字节顺序相关?

标签 c++ direct3d endianness dxgi

我一直在研究 Frank D. Luna 的书“Introduction to 3D programming with DirectX 10”,其中一个问题是从使用

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

大概要使用的格式代码是:DXGI_FORMAT_R8G8B8A8_UNORM。

在我看来,这意味着您有一个变量,该变量在字节级别上以确切的顺序包含有关 channel 的信息:RGBA(这是正确的解释吗?-问是因为我确定我已经读过当您想要 RGBA,您确实需要这样的代码:A#R#G#B#,其中首先指定了 alpha channel 。

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

UINT color = (UINT)WHITE; 

定义白色的地方:const D3DXCOLOR WHITE(1.0f, 1.0f, 1.0f, 1.0f); 此转换在 D3DXCOLOR 的扩展中定义。

但是,当 DXGI_FORMAT_R8G8B8A8_UNORM 与 UINT 颜色变量一起使用时,您会得到错误的结果。 Luna 将此归因于字节顺序。

这是因为 D3DXCOLOR 的转换产生了 RGBA 形式的 UINT 但因为英特尔 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);
}

由于原始 Direct3D 10 版本的 DXGI (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”。

关于c++ - DXGI_FORMAT_ 代码如何与字节顺序相关?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12877399/

相关文章:

c++ - 如何检测边界点

C++:除了虚函数之外,[类名 "undefined reference to '的]' "类型信息的原因是什么

buffer - 动态缓冲区行为

directx - 有没有办法将元数据附加到 HLSL 全局(统一/常量)变量?

c++ - 为什么在将 short[] 转换为 char* 时数组会反转?

c++ - 模板重载数组类型 : Force char array to use string_view

c++ - 将迭代器作为函数参数传递

c++ - Direct2D 深度缓冲区

将大端字节序的有符号整数数组转换为C中小端字节序的十六进制16位

python - ctypes bigendianstruct Littlendianstruct 对单字节返回不同的结果