24-bit -> 16-bit conversion
First, I have never been too fond of GDI.
But more importantly, the bitmap data itself is going to be in memory, and not necessarily from a file. I see no way of using GDI's LoadImage() function to grab the bitmap data from memory, only from a resource or a file.
So, I need a way to convert from 24-bit RGB source images - because I like true color - to a 16-bit format (presumable the primary display adaptor's 16-bit mode) in order to allow 16-bit display modes to be used with my game.
- Splat
quote:Also, is it possible to just drop the source bitmap into a temporary surface at 24-bits, then Blit it to a 16-bit surface, and let DirectDraw handle the conversion?
I have written such a thing down a couple of times, and oh well. Here it comes again.
code:BOOL CopyBMPDataTo1555Surface (BITMAPINFOHEADER *BMPh, unsigned char *pdata, LPDIRECTDRAWSURFACE surface){ DDSURFACEDESC ddsd; //Get a valid pointer to the texture surface. memset (&ddsd, 0, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); if (surface->Lock(NULL, &(ddsd), DDLOCK_WAIT, NULL) == DD_OK) { //Copy 888 .BMP image to 1555 DirectDraw texture surface in video //memory, converting as we go. BMP data is stored bottom to top //(i.e., from left to right along a row, but the rows are //stored bottom to top in memory). For applications that support //multiple texture formats, this code fragment can be broken //out into a separate function, and then copied and modified //for each supported texture format. unsigned char r,g,b; unsigned char *oldpdata; unsigned short color1555; unsigned short *texSurfBase; int x, y; int skip; //actual vs. asked for surface width int imageWidthInBytes; oldpdata = pdata; texSurfBase = (unsigned short *)ddsd.lpSurface; imageWidthInBytes = BMPh->biWidth*IMAGEDEPTH_IN_BYTES; skip = ddsd.lPitch - BMPh->biWidth*COLORDEPTH_IN_BYTES; //start at beginning of last row of image pdata += BMPh->biHeight*imageWidthInBytes - imageWidthInBytes; for (y=0; ybiHeight; y++) { for (x=0; xbiWidth; x++) { b = *pdata++; g = *pdata++; r = *pdata++; color1555 = (unsigned short)( ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) ); *texSurfBase++ = color1555; } //go to next row of texture surface texSurfBase += skip; //go to start of previous row (i.e., go back //two rows worth of bytes, the one just completed, //and the one we want to get to the start of... pdata -= imageWidthInBytes*2; } pdata = oldpdata; //reset pdata's original address surface->Unlock (ddsd.lpSurface); return TRUE; } else { MessageBox(hWnd, "Surface Lock failed", "yeah whatnow?", MB_OK); return FALSE; } }
of course you need a pointer to the place where the bgr stuff begins.....then this'll do the rest
------------------
Dance with me......
Maybe I should rephrase my question. I guess the question now is: if I had unlimited processing time, how can I convert a 24-bit bitmap to 16-bit bitmap that looks as good as 16-bit can get?
- Splat
Anyway, that's for all of your help guys.
- Splat
Also, is it possible to just drop the source bitmap into a temporary surface at 24-bits, then Blit it to a 16-bit surface, and let DirectDraw handle the conversion?
- Splat