OpenGL pixel formats

OpenGL uses two separate definitions to fully specify a pixel format on the CPU side, the format and the type.

Format

The format specifies the logical order of components in the pixel format. It follows the scheme:

GL_{components-list}

Example: GL_RGBA

The pixel format consists of four components in the logical order R, G, B, A.

Example: GL_BGRA

The pixel format consists of four components in the logical order B, G, R, A.

Example: GL_RED

The pixel format consists of a single component R.

Type

The type specifies the size and memory representation of the components specified in format. It has two forms, one for non-packed and one for packed representations.

Non-packed

The non-packed representation of type follows the scheme:

GL_{data-type}

The data-type specifies the data type of each component. The components are ordered in memory in the order specified by format. How each component is stored in memory depends on system endianness.

Example: GL_UNSIGNED_BYTE

Each component is stored as a byte.

Example: GL_UNSIGNED_INT

Each component is stored as 32-bit native integer, and is therefore affected by system endianness.

Packed

The packed representation of type follows the scheme:

GL_{data-type}_{component-bits}(_REV)

The data-type specifies the data type used to hold the pixel data as a whole. The component-bits specify the number of bits each component occupies in the data type. The leftmost number corresponds to the size of the component which will occupy the most significant bits of the data type. The leftmost number corresponds to the size of the component which will occupy the least significant bits of the data type.

The way in which components will be ordered in the data type bit positions is controlled by the existence or absence of the REV suffix.

If the type doesn’t have the REV suffix, then the first component occupies the most significant bits, and the last component occupies the least significant bits. Visually, the format GL_XYZW will be mapped to the data type as 0xXYZW.

If the type has the REV suffix, then the first component occupies the least significant bits, and the last component occupies the most significant bits. Visually, the format GL_XYZW will be mapped to the data type as 0xWZYX (hence the REV designation).

The memory layout of a packed pixel format depends on system endianness.

Example: GL_UNSIGNED_SHORT_5_6_5

The pixel is represented by a 16-bit value, with the first component in bits 11-15, the second component in bits 5-10 and the third component in bits 0-5.

Example: GL_UNSIGNED_SHORT_5_6_5_REV

The pixel is represented by a 16-bit value, with the third component in bits 11-15, the second component in bits 5-10 and the first component in bits 0-5.

Combining format and type

By combining a format and a type we get a full specification of the pixel format. For packed types the number of components in format and type must match.

Example: GL_RGBA with GL_UNSIGNED_BYTE

This combination specifies a pixel format laid out in memory as the bytes R, G, B, A (R at the lowest address, A at the highest)

Example: GL_RGB with GL_UNSIGNED_SHORT

The memory layout of this combination depends on system endianness. On little-endian systems it is stored as:

R₀, R₁, G₀, G₁, B₀, B₁

On big-endian systems it is stored as:

R₁, R₀, G₁, G₀, B₁, B₀

(R₀, R₁ are the first and second bytes of the R component, respectively)

Example: GL_BGRA with GL_UNSIGNED_INT_10_10_10_2

This combination represents the 32-bit value:

M                                                              L
B₉B₈B₇B₆B₅B₄B₃B₂B₁B₀G₉G₈G₇G₆G₅G₄G₃G₂G₁G₀R₉R₈R₇R₆R₅R₄R₃R₂R₁R₀A₁A₀

The memory layout of this combination depends on system endianness. On little-endian systems it is stored as:

0                1                2                3
M              L M              L M              L M              L
R₅R₄R₃R₂R₁R₀A₁A₀ G₃G₂G₁G₀R₉R₈R₇R₆ B₁B₀G₉G₈G₇G₆G₅G₄ B₉B₈B₇B₆B₅B₄B₃B₂

On big-endian systems it is stored as:

0                1                2                3
M              L M              L M              L M              L
B₉B₈B₇B₆B₅B₄B₃B₂ B₁B₀G₉G₈G₇G₆G₅G₄ G₃G₂G₁G₀R₉R₈R₇R₆ R₅R₄R₃R₂R₁R₀A₁A₀

Example: GL_RGBA with GL_UNSIGNED_INT_2_10_10_10_REV

This combination represents the 32-bit value:

M                                                              L
A₁A₀B₉B₈B₇B₆B₅B₄B₃B₂B₁B₀G₉G₈G₇G₆G₅G₄G₃G₂G₁G₀R₉R₈R₇R₆R₅R₄R₃R₂R₁R₀

The memory layout of this combination depends on system endianness. On little-endian systems it is stored as:

0                1                2                3
M              L M              L M              L M              L
R₇R₆R₅R₄R₃R₂R₁R₀ G₅G₄G₃G₂G₁G₀R₉R₈ B₃B₂B₁B₀G₉G₈G₇G₆ A₁A₀B₉B₈B₇B₆B₅B₄

On big-endian systems it is stored as:

0                1                2                3
M              L M              L M              L M              L
A₁A₀B₉B₈B₇B₆B₅B₄ B₃B₂B₁B₀G₉G₈G₇G₆ G₅G₄G₃G₂G₁G₀R₉R₈ R₇R₆R₅R₄R₃R₂R₁R₀

Example: GL_RGB with GL_UNSIGNED_INT_8_8_8_8

This combination is invalid since GL_RGB is a 3-component format and GL_UNSIGNED_INT_8_8_8_8 is a 4-component packed type.