This topic is now archived and is closed to further replies.


16-bit RGB macro...

Recommended Posts

When I pass in a value returned from the default RGB macro to a 16-bit DDrawSurface color block blit, the colors are wierd. Is this because RGB returns a 24-bit value? How would I make this work right? Can''t be that hard. Thanks, ~BenDilts( void );

Share this post

Link to post
Share on other sites
This is the MACRO i allways use for 16bpp:-)

#define RGB16BIT555(r,g,b) ((r&31) + ((g&31) << 5) ((b&31) << 10))
#define RGB16BIT565(r,g,b) (r / (g << 6) / (b << 11))


Share this post

Link to post
Share on other sites
Actually, it can be quite hard to get 24-bit information compressed down into 16 bit. Your surface probably has 5 bits of red info, 6 bits of green, then 5 bits of blue info. Normal RGB surfaces have 8 bits of each. So either you have to start doing some bit packing, or use a surface conversion library like hermes in which you can draw in 8,16,24 or 32 bit and then convert that surface into 8,16,24 or 32 bit using hermes.

Personally, I used hermes because I could draw in 32 bit color really easily and have it copied down to 16 bit color with very little speed loss.

If you really wanted to do bit packing though, you first need to figure out the format that you are working with like follows:



bpp = pf.dwRGBBitCount;
redMask = pf.dwRBitMask;
greenMask = pf.dwGBitMask;
blueMask = pf.dwBBitMask;

which assumes lpdds is a LPDIRECTDRAWSURFACE variable. After you have this information you can make a look up table that allows you to convert from 24 to 16 bit. That will take longer to explain though, post again if you need more help.


Share this post

Link to post
Share on other sites
Vissing has it right, however i think he missed out a couple symbols.

#define RGB16BIT555(r,g,b) (((r&31) << 10 ) / ((g&31) << 5) / (b&31) )
#define RGB16BIT565(r,g,b) (((r&31) << 11 ) / ((g&63) << 6) / (b&31) )

There are some things you have to remember with useing these, the 555 will need rgb values below 32 and the 565 will need a green value below 64, the problem is that you will need to pass it 63 if you want full green and 31 for full red.
One more thing to point out, vissing's formula will give you BGR order, I have not come across video cards that use BGR order.

OneEyeLessThanNone - it flickers

Oups, forgot that this forum likes to change or to divide. Just use the or operator where there is a back slash.

OneEyeLessThanNone - it burns, IT BURNS!!

Edited by - OneEyeLessThanNone on 3/29/00 4:11:27 PM

Share this post

Link to post
Share on other sites
There is an easier way to define the macros so that you don''t neen to limit your colors to the 31 or 63 value ranges. If you want to pass in normal 8 bit color values for the RGB components you can to this:

#define RGB555(r,g,b) ((r>>3)<<10) + ((g>>3)<<5) + (b>>3)
#define RGB565(r,g,b) ((r>>3)<<11) + ((g>>2)<<5) + (b>>3)

The added right shifting will extract the most significant color bits from the full 8bit value (ie, the ones that you really care about) You could also include some &''s to make sure the input colors are strictly less than 256, but this may not be necessary and really depends on your code.

Hope that helps


Check out the GPI project today!

Share this post

Link to post
Share on other sites

Use this for detect the pixel format:

if(boolmode555) TRANS_COLOR=_RVB555(255,0,255);
else TRANS_COLOR=_RVB565(255,0,255);

boolmode555 <- boolean
TRANS_COLOR <- unsigned short

Share this post

Link to post
Share on other sites