OpenGL/DirectX のピクセル並びの順番

OpenGL と DirectX は色の並び順が異なります。

       GL Type   OpenGL          DirectX9
------------------------------------------------------------
8888   BYTE      R8G8B8A8        B8G8R8A8 (A8R8G8B8)
888    BYTE      R8G8B8          B8G8R8   (R8G8B8)
565    SHORT     R5G6B5          R5G6B5
5551   SHORT     R5G5B5A1        A1R5G5B5
4444   SHORT     R4G4B4A4        A4R4G4B4
HALF   HALF      R16G16B16A16F   R16G16B16A16F (A16B16G16R16F)
FLOAT  FLOAT     R32G32B32A32F   R32G32B32A32F (A32B32G32R32F)


      OpenGL(LE)           OpenGL(BE)           DirectX9(LE)
-----------------------------------------------------------------
      1byte目  2byte目     1byte目  2byte目     1byte目  2byte目
      H______L H______L    H______L H______L    H______L H______L
565   gggbbbbb rrrrrggg    rrrrrggg gggbbbbb    gggbbbbb rrrrrggg
5551  ggbbbbba rrrrrggg    rrrrrggg ggbbbbba    gggbbbbb arrrrrgg
4444  bbbbaaaa rrrrgggg    rrrrgggg bbbbaaaa    ggggbbbb aaaarrrr

Alpha 位置の違いなので 565 は OpenGL/DirectX どちらも同じ。

●OpenGL の場合

OpenGL はメモリのアクセス単位が TYPE で決まっています。
例えば GL_UNSIGNED_BYTE の場合バイトオーダーに関係なくメモリの並びは
一定となります。

・OpenGL はメモリ上の配列は R G B A の順。
・short 等パックされた場合は上位 bit から R G B A。アルファが最下位。

メモリの並びとパックされた値は Big endian (BE) の場合に一致します。
R G B A の順番は X Y Z W の対応と等しく、float (fp16/32) 等のフォーマット
時の並びと一致します。

●DirectX の場合

アクセス単位という概念が特に無く 32bit/16bit 共に違いを意識しません。

・int/short 等パックされた場合、最上位がアルファ。上位から A R G B の順。
・メモリ上の配列は 32/24bit を LE で格納するため B G R A の順になる。

Little endian (LE) で格納した場合 24bit color と 32bit color の構造に
互換性があります。(B G R X → B G R A)
GL と D3D の違いはフォーマット作成時の GE と LE の違いかもしれません。

ARGB の順番 (D3DCOLOR) は XYZW と一致しません。
常に XYZW 順である float (fp16/32) フォーマットとも異なっています。
Direct3D10 では RGBA 並びをもとに大きく変更されました。
Direct3D9 以前と Direct3D10 (DXGI) 以降では FORMAT シンボルの表記順も
逆になっています。

Direct3D9              ABGR順    D3DFMT_A16B16G16R16F
Direct3D10/11(DXGI)    RGBA順    DXGI_FORMAT_R16G16B16A16_FLOAT

●相互変換

OpenGL で dds を用いたり、モバイルの OpenGL ES と PC の DirectX で
エンジンを共通化する場合はこれらの画素変換が必要になります。

具体例
OpenGLES2.0 DDS テクスチャを読み込む

モバイル GPU ではバス帯域がボトルネックになりがちです。
出来る限り圧縮テクスチャを用いますが、未対応 GPU の場合は
16bit テクスチャを活用することになります。

関連エントリ
Android OpenGL ES 2.0 の圧縮テクスチャ
OpenGLES2.0 DDS テクスチャを読み込む