#### Archived

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

# 16 bit color

This topic is 6930 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Everybody new to DirectX seems to have this problem, here is what I use to extract or create the rgb values. Basicly, just add it at the top of your code and your good to go.

#define RED(p) ( p >> pRed ) // Extracts Red Component
#define GREEN(p) ((p & mGreen) >> pGreen) // Extracts Green Component
#define BLUE(p) ( p & mBlue ) // Extracts Blue Component
#define RGB16(r, g, b) ((r << pRed ) | (g << pGreen) | b) // create RGB value

##### Share on other sites
Thanks, but do you have any nice values for
masks and shift, or do you get them from DX?

##### Share on other sites
can buildup a macro that will work great with everything.

But what GetPixelFormat does not explicitly return is the number of
bits you need to shift each RGB component to make your 16-bit value.

Well, the DD docs has a neat function that does this for you:

code:
WORD GetNumberOfBits(DWORD dwMask) { WORD wBits = 0;     while(dwMask) {    dwMask = dwMask & (dwMask - 1);    wBits++;     } return wBits;}

What this does is count the number of '1' bits in a mask. So,
a blue mask of 0x001F will return a value of 5 (only 5 bits are set)

Save these mask bit counts in variables too. These are needed to
finally determine how many bits you need to shift each RGB component.

It'll look something like this:
------
DDPIXELFORMAT ddpf;
ZeroMemory( &ddpf, sizeof(DDPIXELFORMAT) );
ddpf.dwSize = sizeof(DDPIXELFORMAT);

surface->GetPixelFormat(&ddpf);

blue_shift = 0;
green_shift = blue_bits;
red_shift = blue_bits + green_bits;

------

That's all you need to do! Now you can reference these variables in
a 16bit macro or function and you are good to go. So use the masks
to extract RGB components, and use the shifts to make a 16-bit color
value.

Don't use constant values directly, it will only make your code less
compatible.

Reaver

[This message has been edited by Reaver (edited November 01, 1999).]

##### Share on other sites
To answer your second quesion, Ake, you need to scale R, G and B to get them in the 0-255 range. The simplest thing is to do another shift:

B = (col & 0x1F) << 3;
G = ((col >> 5) & 0x3F) << 2;
R = ((col >> 11) & 0x1F) << 3;

This doesn't quite work though! It results in these ranges.

R = 0-248
G = 0-252
B = 0-248

Close enough!

##### Share on other sites
Thanks a bunch, guys...

##### Share on other sites
OK, I'm not really happy yet. I'll give you the code first:
USHORT GetColor16()
{
return (USHORT) (( m_iR << m_wRShift ) | ( m_iG << m_wGShift ) | m_iB );
}

void GetRGB()
{
m_iB = ( col & m_dwBMask ) << 3;
m_iG = ( (col & m_dwGMask ) >> m_wGShift ) << 2;
m_iR = ( (col & m_dwRMask ) >> m_wRShift ) << 3;
}

void SetPixelFormat( LPDIRECTSURFACE4 bla )
{

WORD wRBits = GetNumberOfBits( m_dwRMask );
WORD wGBits = GetNumberOfBits( m_dwGMask );
WORD wBBits = GetNumberOfBits( m_dwBMask );

m_wRShift = wBBits + wGBits;
m_wGShift = wBBits;
m_wBShift = 0;
}

Not this looks ok to everyone, then let's try it.
wSurf2[ y * 256 + x] = GetColor16( 255, 0, 255 );
GetRGB( wSurf2[ y * 256 + x] );
Now it should be, R = 248, G = 0, B = 248. But it's not.
It's R = 248, G = 28, B = 248. Hmmmm. I remove the << 2
and I found that G gets the value 7 when it should be 0.
Pretty much the same thing happened when I wrote (0,255,255)
it read (56,124,248). (124 can be fixed by shifting the G by
3 instead). Any ideas why this happens.

And Reaver, would the Mask and shift be correct in 24 or 32
bpp mode too, using the GetNumberOfBits thingie?

##### Share on other sites
If you are passing 24-bit values (0 to 255), You need to convert them to
16-bit values (0 to 31) before you combine them together. Try this for

code:
 WORD  GetColor16(BYTE r, BYTE g, BYTE b) {    return (WORD)( (((r>>(8-wRBits))&31) << m_wRShift) | (((g>>(8-wGBits))&31) << m_wGShift) | ((b>>(8-wBBits))&31) ); }

I hope that came out right.

Hmmm, or try this:

code:
 WORD  GetColor16(BYTE r, BYTE g, BYTE b) {    return (WORD)( ((r>>(8-wRBits)) << m_wRShift) | ((g>>(8-wGBits)) << m_wGShift) | (b>>(8-wBBits)) ); }

I don't know if that will do much visually, but I just remembered I put in
the &31 part because I want all color to clamp to 555, even though it might be 565.
Or you could try substituting &63 for the &31 part in the green component.
I never tried this, it might not work right.

If that doesn't work, make sure you have everything setup correctly, write
out your masks values, shift values, and bit count values. Make sure it is
all correct for 16-bit 565.

And, I think you don't need to use GetNumberOfBits or figure out
how bits to shift with 24-bit, because it usually only has one format.
At least I hope so. Always 888 for 24-bit. I think 32-bit can be
2-10-10-10 or 8-8-8-8. I never tested it with anything else than 16-bit,
but I would guess it would still give you the same results.

Reaver

[This message has been edited by Reaver (edited November 01, 1999).]

##### Share on other sites
The thing is though, if you want to make a 16bit engine you have to have RGB color ranges from 0-31. You can't have 0-255.

For 555 format
Total 32768 colors

For 565 format
Total 65536 colors

I dont think that our eyes can even notice all thoses shades.

#define RGB16(r, g, b) ((r << RedPos) | (g << GreenPos) | b)
When you call this macro with 255,255,255 it truncates them down to 31,31,31

So then when you plot lets say a pure red pixel with 255 and you call this macro to extract the red color
#define RED(p)(p >> RedPos)

The value you will get is 31.

So if you make a 16 bit engine you have to stick with 31 shades. Ifnot you will have to go up to 24bit mode or 32 bit mode but those are still to frigin slow.

##### Share on other sites
You'd be surprised what the eye can distinguish. It can reliably discern all the 16M colors of 24bit color modes, because all it really does it discern the 256 levels of each RGB. Even more impressive is that it can distinguish about 50M colors on a reflective surface such as paper!

Rock

##### Share on other sites
Hi everybody,

How do I extract each color components of a 16bit 565 color?
I tried this:
B = col & 0x1F;
G = (col >> 5) & 0x3F;
R = (col >> 11) & 0x1F;
But it didn't work very well, color values are just between 0-31, I want them 0-255.

TIA, Tobias

1. 1
Rutin
44
2. 2
3. 3
4. 4
5. 5
JoeJ
19

• 11
• 15
• 9
• 10
• 13
• ### Forum Statistics

• Total Topics
633004
• Total Posts
3009841
• ### Who's Online (See full list)

There are no registered users currently online

×