16-bit RGB macro...

Started by
6 comments, last by BeanDog 24 years ago
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 );
Advertisement
The value you pass in to a Blt via the dwFillColor must be
of the same pixelformat as the pixelformat of the destination surface. The RGB_MAKE macro creates RGB-values in 24 bit format (8-bit per channel).
OK thanks... but... How is it you do what I asked?
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))

-Vissing-
-Vissing-
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:

DDPIXELFORMAT pf;

DD_INIT_STRUCT(pf);
lpdds->GetPixelFormat(&pf);

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.

PreManDrake
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
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

Chip

Check out the GPI project today!
Hello,

Use this for detect the pixel format:

lpdd->GetDisplayMode(&ddsd);
ddpixf=ddsd.ddpfPixelFormat;
boolmode555=(ddpixf.dwGBitMask==0x3E0);
if(boolmode555) TRANS_COLOR=_RVB555(255,0,255);
else TRANS_COLOR=_RVB565(255,0,255);

with:
boolmode555 <- boolean
TRANS_COLOR <- unsigned short
ddpixf <- DDPIXELFORMAT



OOO O O O O OOO OOO OO OOO O O OO OO O O O O 0 0 0OOO O O O O O O O O OO OO O O O O O OOOO O O O

This topic is closed to new replies.

Advertisement