Advertisement

16 Bit Color Question

Started by March 14, 2000 09:12 AM
3 comments, last by Qoy 24 years, 9 months ago
I am converting my game from 32 bit to 16 bit color, and I am having problems detecting the pixel format. I used the code from Tricks of the Windows Game Programming Gurus, but not only did the macros in the book not work, but that code doesn't seem to work either.. It calls GetPixelFormat and then checks if dwRGBBitCount comes to 15 or 16, but looking in the DXSDK it doesn't look like it would ever come to 15 (which I what my card happens to be, 5.5.5 format). I have my own macros (inline functions) that work to build RGB values, but I just can't detect the pixel format correctly... How would I do this? Thanks! ------------------------------ Jonathan Little invader@hushmail.com http://www.crosswinds.net/~uselessknowledge Edited by - Qoy on 3/14/00 4:41:04 PM
This site has an article about doing 16-bit programming, in one of the programming sections. I think it tells how to do everything you want, but here''s something the author e-mailed me:

usually, you''ll be starting with a COLORREF containing a 24bpp RGB pixel
color.

grab the surfaces pixelformat by calling its GetPixelFormat() member function.

the three fields you are interested in are dwRBitMask, dwGBitMask, and
dwBBitMask.

next, grab each of the r,g, and b components from the COLORREF(cr)

//these are DWORDs for an important reason
DWORD r=GetRValue(cr);
DWORD g=GetGValue(cr);
DWORD b=GetBValue(cr);

next, multiply each by the appropriate mask

//ddpf contains the pixel format
r*=ddpf.dwRBitMask;
g*=ddpf.dwGBitMask;
b*=ddpf.dwBBitMask;

now, divide each by 256 (because each component in a colorref has 8 bits,
and 2^8=256)

r/=256;
g/=256;
b/=256;

now, to make sure that there arent any extra bits anywhere, do a bitwise
AND with each of the appropriate masks

r&=ddpf.dwRBitMask;
g&=ddpf.dwGBitMask;
b&=ddpf.dwBBitMask;

now, you can combine the r,g, and b into a single color value...

DWORD color=r / g / b;
Advertisement
I found a way to do it. This is what I have:

Set up:
// get the pixel format	unsigned long redMask = 0, greenMask = 0, blueMask = 0;	DDPIXELFORMAT pixelFormat;	pixelFormat.dwSize = sizeof(DDPIXELFORMAT);	primaryBuffer->GetPixelFormat(&pixelFormat);	// get the bit shifts for each color in a pixel	// get red mask	redMask = pixelFormat.dwRBitMask;	while(!(redMask & 0x01))	{		redMask >>= 1;		rShift++;	}	// get green mask	greenMask = pixelFormat.dwGBitMask;	while(!(greenMask & 0x01))	{		greenMask >>= 1;		gShift++;	}	// get blue mask	blueMask = pixelFormat.dwBBitMask;	while(!(blueMask & 0x01))	{		blueMask >>= 1;		bShift++;	}	// test for 555 or 565 mode	switch(rShift)	{	case 10:		{			gScale = 8;			OutputDebugString("-InitDirectDraw: gScale set for 555 mode\n");		} break;	case 11:		{			gScale = 4;			OutputDebugString("-InitDirectDraw: gScale set for 565 mode\n");		} break;	default:		{			char buffer[70];			wsprintf(buffer,"-InitDirectDraw: Error setting gScale: rShift = %d",rShift);			OutputDebugString(buffer);		} break;	} // end switch(rShift) 


and here''s my RGB function:
inline short RGBValue(int r, int g, int b){	return (((r / 8) << rShift) / ((g / gScale) << gShift) / ((b / 8) << bShift));} 


(Sorry about the tabs, I just copied and pasted...)

Hope this helps somebody out there sometime
Sorry. That anonymous poster was me!
I was wondering how to use those bit masks to get the correct color, so thanks for the post. Correct me if I''m wrong, but I think there is a slight flaw in your algorithm. I belive that you should div by 255 and not 256 (since the color range is from 0-255 and not 256.) If 256 is used on, say, the first 5 bits of a 16bit color (the blue bits) then the maximum color you can obtain is 31*255/256 = 30 instead of 31.

Also, are the bitwise ANDs really needed? It seems that, as long as the color values are in the range 0-255, then the result will come out in the right bit positions with nothing left over.

This topic is closed to new replies.

Advertisement