Dark Bit Factory & Gravity
PROGRAMMING => C / C++ /C# => Topic started by: Pixel_Outlaw on November 24, 2010
-
I'm currently up and running through the examples over at LazoFoo's site (which seems to be the defacto place to learn SDL) and I have realized that often the library wants an unsigned int value to assign color. I'm very used to working in RGB triplets I understand how they are stored in an int but I'm confused on how to manipulate the bits for converting between four bytes (for ABGR) and a single unsigned int.
I'm looking to write the 4 byte values to an int, and later to extract them from an unsigned int.
Alpha Blue Green Red
00000000 00000000 00000000 00000000
Thanks again folks. Still getting my feet wet with this stuff. Bit level operators are not something I'm totally comfortable with yet. ::)
-
Hey,
It looks that the website is a place to learn SDL, all my classmates learnt there ...
I didn't go through :p but I know what you need. I think you should like to the documentation of SDL_MapRGB or SDL_MapRGBA :)
Otherwise:
unsigned int colour = 0xFF00FF00;
unsigned char a = colour >> 24 & 0xFF;
unsigned char r = colour >> 16 & 0xFF;
unsigned char g = colour >> 8 & 0xFF;
unsigned char b = colour & 0xFF;
Here we are :)
For putting all together, nearly the same:
unsigned char a = 0xFF;
unsigned char r =0xFF;
unsigned char g =0xFF;
unsigned char b = 0x00;
unsigned int colour = (a << 24) & 0xFF000000) + (r << 16) & 0x00FF0000) + ((g << 8) & 0x0000FF00) + (b & 0x000000FF)
Far to be optimised ... I am doing certainly some useless masking.
If you don't get the lines ... it's just moving bits (>> and <<) and masking (& -> AND)
Warning: Be careful with the endianness, because bits order will change ... so you should really use this SDL_MapRGB() :)
-
Thank you.
This is pretty common in many of the graphics programming applications so this will be useful beyond SDL.
-
There's a small problem with Littlewhite's codes as they stand - you need brackets around the shifts, because & has a higher precedence than >>
unsigned int colour = 0xFF00FF00;
unsigned char a = (colour >> 24) & 0xFF;
unsigned char r = (colour >> 16) & 0xFF;
unsigned char g = (colour >> 8) & 0xFF;
unsigned char b = colour & 0xFF;
Jim
-
Oops!
Jim is totally right of course :)
-
I think you can write more compact code to get r,g,b,a back to one uint value...
unsigned int colour = (a << 24 | (r << 16) | (g << 8) | b);
-
You could also do it with macros:
#ifdef _ARGB
#define ARGB_A(u) (((u) >> 24) & 0x000000FF)
#define ARGB_R(u) (((u) >> 16) & 0x000000FF)
#define ARGB_G(u) (((u) >> 8) & 0x000000FF)
#define ARGB_B(u) (((u) >> 0) & 0x000000FF)
#define ARGB( r, g, b, a ) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#else //RGBA
// reverse the process
#endif
-
Perhaps working with pointers without shfting and bitmasking:
Its Masm but i think it can be done in inline asm for c++
.data
color dd 0ffeeddcch
.data?
r db ?
g db ?
b db ?
a db ?
.code
main:
invoke GetModuleHandle,NULL
xor eax,eax
;Extracting RGBA bytes from DWORD
lea edi,r
lea esi,color
mov ecx,4
rep movsb
mov color,0 ;Clear color
;Writing RGBA bytes to DWORD
lea edi,color
lea esi,r
mov ecx,4
rep movsb
-
Real coders don't separate their RGBs ;)
-
Yeah, real coders only use toggle switches for their Altairs too.
I'm really going to have to study more at the bit level. :crutches:
-
Alternatively you can avoid most of that bit-fiddling by using unions:
struct Color
{
union
{
struct
{
unsigned char b,g,r,a;
};
unsigned int argb;
};
Color()
{
}
Color(unsigned int col)
{
argb= col;
}
};
This way the for bytes r,g,b,a occupy the same space as the integer argb.
Color col;
col= 0xffeeddcc;
printf("Color: %d,%d,%d,%d \n", col.a, col.r, col.g, col.b);
-
OT: Hellfire: "Can you see it?"
(http://rel.betterwebber.com/images/screenies/BF_EXscreenshot.png)