OpenGL texture upload: UNSIGNED_BYTE vs UNSIGNED_INT_8_8_8_8
I'm calling glTexSubImage2D. If my pixel format is GL_RGBA
, then are the pixel types GL_UNSIGNED_BYTE
and GL_UNSIGNED_INT_8_8_8_8
fully equivalent?
Also, are these two pairs equivalent?
开发者_如何学CFormat = GL_RGBA, Type = GL_UNSIGNED_INT_8_8_8_8
Format = GL_BGRA, Type = GL_UNSIGNED_INT_8_8_8_8_REV
I've tried reading the OpenGL spec and the GL_EXT_packed_pixels spec, but honestly I can't make head or tail of them.
The answers are No and No. You have to think about the byte order in your computer. If you have GL_RGBA
and GL_UNSIGNED_INT_8_8_8_8
, that means that pixels are stored in 32-bit integers, and the colors are in the logical order RGBA in such an integer, e.g. the red is in the high-order byte and the alpha is in the low-order byte. But if the machine is little-endian (as with Intel CPUs), it follows that the actual order in memory is ABGR. Whereas, GL_RGBA
with GL_UNSIGNED_BYTE
will store the bytes in RGBA order regardless whether the computer is little-endian or big-endian.
GL_BGRA
with GL_UNSIGNED_INT_8_8_8_8_REV
would store colors in an integer in the logical order ARGB, but then on a little-endian machine, you get BGRA order in memory.
See JWWalker's answer first. This answer is a supplement to it. A quick illustration.
GL_RGBA
stored in GL_UNSIGNED_INT_8_8_8_8
:
0xrrggbbaa
GL_RGBA' stored in
GL_UNSIGNED_BYTE`:
[0xrr, 0xgg, 0xbb, 0xaa]
In both cases, RGBA is in the logical order r, g, b, a, but on a little endian machine (this is the normal architecture), 0xrrggbbaa
has the little byte (least-significant) stored first. If you read the uint32_t
one byte at a time, you'll get 0xaa
first! A C++ example:
uint32_t color{0x11223344};
uint8_t first_byte{reinterpret_cast<uint8_t*>(color)[0]};
first_byte
will equal 0x44
.
One thing that's confusing is the word "first". It can mean "appearing first when written" as in "The red byte is first in 0xrrggbbaa". This is different from "having the lowest memory/pointer address" as in "The alpha byte is first in 0xrrggbbaa when encoded using little-endian"! When you use GL_RGBA
, it sure looks like red will be first, but when encoded in a 4-byte integer little endian, it is only that way in the hex representation.
精彩评论