Transparency Color Key in 16bit.

Started by
2 comments, last by pimstead 22 years, 8 months ago
If you have a bmp that was created in full color and you are going to use it in your game in 16bit color mode how do you make sure you are using the right 16bit transparency color key? Does someone here have an easy solution for this problem, also is 555 and 565 16bit differences something you have to consider? Also for 16bit games is all the art usually developed in full color (24 or 32bit)? Thanks in advance.
Advertisement
I'm Working with directdraw in visual basic in 16bit and reciently found some code (After about 3 hours searching) that can convert rgb888(24bit) colours to rgb555(16bit) colours. (Although It's curriently burried somewhere in my program.)

Here are a few conversions:

RGB888 - RGB555 - colour
255,255,255 - 65535 - White
000,000,000 - 0 - Black
255,000,255 - 63519 - Magenta (Pink/Red/Purple)

I have normal 24bit color images and use Magenta for transparies as it's rarely used.

If anyone needs any other colors converted Just e-mail me!
Mew1984au@softhome.net

Edited by - Mew1984au on August 6, 2001 4:21:11 AM
If I understand your question right use this:
#define RGB16(r,g,b) ((r << 11) + (g << 5) + b)

I would recommend pink. it''s:
RGB(255,0,255) or RGB16(31,0,31)

Remember that RGB16''s max values are 31,63,31

/MindWipe


"If it doesn''t fit, force it; if it breaks, it needed replacement anyway."
"To some its a six-pack, to me it's a support group."
Both of the above poster''s suggestions will break if run on a videocard with the "wrong" pixel format. If you use a 16-bit mode, your code must adapt to the current format.

I forget the specific function name, and it might have changed slightly in DX8, but in DX7 the IDirectDrawSurface interface had a function which would return a DDPIXELFORMAT structure which held info about the surface''s format. This included mask values which could be used in color conversion code.

...
shuffle shuffle
...

I just searched through my source code, and found the function that stores the format data in my game. The lo___bit and num___bits variables are globals which I''ve defined here so you know what they are.

	WORD loREDbit, numREDbits;	WORD loGREENbit, numGREENbits;	WORD loBLUEbit, numBLUEbits; 


In addition, the code uses these helper functions.

  WORD HighBitPos( DWORD dword ){	DWORD test=1;	test<<=31;	for (WORD i=0;i<32;i++)	{		if ( dword & test )			return (WORD)(31-i);		test>>=1;	}	return 0;}WORD LowBitPos( DWORD dword ){	DWORD test=1;	for (WORD i=0;i<32;i++)	{		if ( dword & test )			return i;		test<<=1;	}	return 0;}  


Here''s the function:
  BOOL StorePixelFormatData(){	DDPIXELFORMAT format;	ZeroMemory( &format, sizeof(format) );	format.dwSize=sizeof(format);	if (primsurf->GetPixelFormat( &format )!=DD_OK)	{		TRACE("StorePixelFormatData() failed\n");		return FALSE;	}	loREDbit = LowBitPos( format.dwRBitMask );	WORD hiREDbit = HighBitPos( format.dwRBitMask );	numREDbits=(WORD)(hiREDbit-loREDbit+1);	loGREENbit = LowBitPos( format.dwGBitMask );	WORD hiGREENbit = HighBitPos( format.dwGBitMask );	numGREENbits=(WORD)(hiGREENbit-loGREENbit+1);	loBLUEbit  = LowBitPos( format.dwBBitMask );	WORD hiBLUEbit  = HighBitPos( format.dwBBitMask );	numBLUEbits=(WORD)(hiBLUEbit-loBLUEbit+1);	return TRUE;}  


The StorePixelFormatData function is called after creating the flipping surfaces. To see how this data is used, here is my function that copies a bitmap into a 16-bit surface. (The bmpbuf parameter is a pointer to the bitmap''s bits.)
  BOOL Copy_Bmp24_Surface16( LPDIRECTDRAWSURFACE7 surf, 										 BYTE* bmpbuf, int w, int h ){	if (surf==0 || bmpbuf==0)		return FALSE;		DDSURFACEDESC2 desc;	ZeroMemory( &desc, sizeof(desc) );	desc.dwSize = sizeof(desc);	HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );	if (r!=DD_OK)	{		TRACE("Copy_Bmp24_Surface16: Lock() failed\n");		return FALSE;	}	int bytesrequired=w*3;	int bytesgiven=(bytesrequired+3) & ~3;	BYTE* surfbits = (BYTE*)desc.lpSurface;	BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);	float REDdiv=(float)256/(float)pow( 2, numREDbits );	float GREENdiv=(float)256/(float)pow( 2, numGREENbits );	float BLUEdiv=(float)256/(float)pow(2, numBLUEbits );	for( int i=0; i<h; i++ )	{		USHORT* pixptr=(unsigned short*)surfbits;		RGBTRIPLE* triple=(RGBTRIPLE*)imagebits;		for (int p=0;p<w;p++)		{			float rf=(float)triple->rgbtRed/REDdiv;			float gf=(float)triple->rgbtGreen/GREENdiv;			float bf=(float)triple->rgbtBlue/BLUEdiv;			WORD r=(WORD)((WORD)rf<<loREDbit);			WORD g=(WORD)((WORD)gf<<loGREENbit);			WORD b=(WORD)((WORD)bf<<loBLUEbit);			*pixptr = (WORD)(r|g|b);			triple++;			pixptr++;		}		surfbits += desc.lPitch;		imagebits -= bytesgiven;	}	surf->Unlock( 0 );	return TRUE;}  



One thing to note about this method is that it will work with any format that could ever possibly exist. Even if run on some non-standard videocard, it would still display colors properly.

Anyway, I hope this helps you.
"It tastes like burning..."

This topic is closed to new replies.

Advertisement