   d3d9 textures appear to use bgra when created with argb format [SOLVED]
  Hello, recently I have written code that uses libjpeg to load a jpeg file and create a d3d9 texture from it's contents. When forming the image data, specifically the data that is all memcpied to the D3DLOCKED_RECT::pBits given by:IDirect3DTexture9::LockRect(0, &rect, NULL, 0))I found experimentally that the 1st byte in a color is the blue value, not the alpha, because when treating it like the alpha value (and setting all the alpha values to 255) the texture would look very blue. I found out the rest of the bytes were switched as well because I had to swap them to make the textures appear as they actually were.This is a sample of the texture data in memory as argb:http://img3.imageshack.us/img3/1742/texturedata.pngThis is its resulthttp://img341.imageshack.us/img341/1521/screenargb.pngThis is a sample of the texture data in memory as bgra:http://img5.imageshack.us/img5/4675/texturedatabgra.pngThis is its result (what it should look like)http://img36.imageshack.us/img36/7343/screenbgra.pngThis is the code for copying that data (parent->GetImageData()) into the d3d9 texture:D3DLOCKED_RECT rect;if (FAILED(d3d9tex->LockRect(0, &rect, nullptr, 0))) // D3DLOCK_DISCARD?throw Exception(Text("IDirect3DTexture9::LockRect() failed"));memcpy(rect.pBits, parent->GetImageData(),  parent->GetBytesPerPixel() * parent->GetDimensions().x * parent->GetDimensions().y);if (FAILED(d3d9tex->UnlockRect(0)))throw Exception(Text("IDirect3DTexture9::UnlockRect() failed"));This is the code for the creation of the d3d texture:HRESULT hr;if (FAILED(hr = gd->GetIDirect3DDevice9()->CreateTexture(texture->GetDimensions().x,texture->GetDimensions().y,1,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,&d3d9tex,nullptr)))throw Exception(Text("IDirect3DDevice9::CreateTexture() failed"), hr);Any help is greatly appreciated.[Edited by - glass66 on June 28, 2009 2:28:48 PM]
  D3D is just dealing with the data you give it. What is more likely the case here is that libjpeg is giving you BGRA data.I'm not overly familiar with libjpeg, but you could always do an endian swap on every uint32 in the data.   ;  I came across this a while ago, and it appears to be because of x86 being little endian.Basicly d3d define A8R8G8B8 such that:unsigned col = SomeColour();unsigned char a = (col & 0xFF000000) >> 24;unsigned char r = (col & 0x00FF0000) >> 16;unsigned char g = (col & 0x0000FF00) >>  8;unsigned char b = (col & 0x000000FF) ;Now on a big endian computer that is the same as the actual layout of the bits making up the integer however on a little endian computer the bytes are in the other order, ie:bbbbbbbb gggggggg rrrrrrrr aaaaaaaaYou can see this with a unionunion{    unsigned num;    unsigned char bytes[4];}data;data.num = 0xFFAA8844;std::cout << ((data.num & 0xFF000000) >> 24) << std::endl;std::cout << ((data.num & 0x00FF0000) >> 16) << std::endl;std::cout << ((data.num & 0x0000FF00) >>  8) << std::endl;std::cout << ((data.num & 0x000000FF) ) << std::endl;std::cout << std::endl;std::cout << (int)data.bytes[0] << std::endl;std::cout << (int)data.bytes[1] << std::endl;std::cout << (int)data.bytes[2] << std::endl;std::cout << (int)data.bytes[3] << std::endl;On a little endian computer (assuming you told cout to output integers in hex) you will get:FFAA88444488AAFF;Quote:Original post by glass66I found experimentally that the 1st byte in a color is the blue value, not the alpha, ...When you see something like D3DFMT_A8R8G8B8, it means that a pixel takes up a single u32, and the way you interpret the order is that you read from left-to-right the order, which goes from most significant bits to the least significant. That is, 'A8' takes up the 8 most significant bits of the u32, then 'R8' takes the next 8 bits, 'G8' then, and finally 'B8' is stored in the 8 least significant bits.In ascii art, the individual bits of a u32 in binary notation from MSBit to LSBit:31    24 23    16 158 7 0AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB.Now, the abovementioned applies only if you treat the surface memory as a u32 array. Since the x86 platform is little-endian, a u32 is stored in memory from LSB to MSB, so a u32 with the value 0x12345678 is stored in memory in the order '78 56 34 12'. Therefore, if you're accessing the surface memory of a D3DFMT_A8R8G8B8 texture as a u8 array and not a u32 array, you'll see that the color order seems to be swapped and the array contents are like the following: 0  1  2  3  4  5  6  7  8  9  A  BBl Gr Re Al Bl Gr Re Al Bl Gr Re Al--Pixel 0--|--Pixel 1--|--Pixel 2--|So, apparently libjpeg will hand the surface to you with the color channels of the individual pixels in different order. It's alright to just swap them and be done with it..   ;  Yes, D3D9 has the channels reversed compared to other API's. IIRC both D3D10 and XNA use the same order, which is opposite of D3D9.   ;  D3D10 and D3D9 certainly work the same way, since to get d3d10 to work with my existing stuff I just moved the A component to the end (since d3d10 just has a R8G8B8A8 format): ((col & 0xFF000000) >> 24) | (col & 0x00FFFFFF) << 8)I'd assume that XNA works the same as D3D9, D3D10, and I'll assume all the other version before.Personally I think it makes more sense to define the colours this way since in my expirence its more common to work with the whole thing as an integer and use the bitwise operators rather than looking at each byte indivdually. Also reduces the amount of code that needs to change to move to big endian platforms (eg xbox 360) since 0xFF00FF00 still means the same thing on big endian or little endian with the format defined this way, its just the way that integer is stored and some behind the scenes d3d and hardware stuff that changes.   ;  Thank you for all your responses. I did not know that the order of the colors in the enum denoted it's values in order of significance, instead of it's actually order in memory. My system is little endian, so it makes sense that in memory it is layered as bgra. Problem solved!   