.bmp help if anyone would be so kind :)

Started by
13 comments, last by Tyranthraxus 23 years, 3 months ago
Ok, just learning directX...I can plot pixels (yahoo!) and use the Blitter (yay!)...and I''m reading Windows Game Programming for Dummies Anyway, there is some error in the code for that book, that tells you how to load a bitmap and display it. Even on the pre-compiled version by the author, it loads the .bmps all funny colored. I tried to reverse the BGR RGB...but it still looked funny (though different), so it''s not that. I tried emailing the author, Andre'' Lamothe, but he never answered. If anyone knows about this specifically, or could just figure it out from the code below, that would be most appreciated. /////////////////////////////////////////////////////////// int CGameShell::Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename) { // this function opens a bitmap file and loads the data into bitmap int file_handle, // the file handle index; // looping index UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit OFSTRUCT file_data; // the file data information // open the file if it exists if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1) return(0); // now load the bitmap file header _lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER)); // test if this is a bitmap file if (bitmap->bitmapfileheader.bfType!=BITMAP_ID) { // close the file _lclose(file_handle); // return error return(0); } // end if // now we know this is a bitmap, so read in all the sections // first the bitmap infoheader // now load the bitmap file header _lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER)); // now load the color palette if there is one if (bitmap->bitmapinfoheader.biBitCount == 8) // || bitmap->bitmapinfoheader.biBitCount == 16) { _lread(file_handle, &bitmap->palette,256*sizeof(PALETTEENTRY)); // now set all the flags in the palette correctly and fix the reversed // BGR RGBQUAD data format for (index=0; index < 256; index++) { // reverse the red and green fields int temp_color = bitmap->palette[index].peRed; bitmap->palette[index].peRed = bitmap->palette[index].peBlue; bitmap->palette[index].peBlue = temp_color; // always set the flags word to this bitmap->palette[index].peFlags = PC_NOCOLLAPSE; } // end for index } // end if // finally the image data itself _lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END); // now read in the image, if the image is 8 or 16 bit then simply read it // but if its 24 bit then read it into a temporary area and then convert // it to a 16 bit image if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16) { // allocate the memory for the image if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage))) { // close the file _lclose(file_handle); // return error return(0); } // end if // now read it in _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage); } // end if else { // this must be a 24 bit image, load it in and convert it to 16 bit // printf("\nconverting 24 bit image..."); // allocate temporary buffer if (!(temp_buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage))) { // close the file _lclose(file_handle); // return error return(0); } // end if // allocate final 16 bit storage buffer if (!(bitmap->buffer=(UCHAR *)malloc(2*bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight))) { // close the file _lclose(file_handle); // release working buffer free(temp_buffer); // return error return(0); } // end if // now read it in _lread(file_handle,temp_buffer,bitmap->bitmapinfoheader.biSizeImage); // now convert each 24 bit RGB value into a 16 bit value for (index=0; indexbitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight; index++) { // extract RGB components (in BGR order), note the scaling UCHAR blue = (temp_buffer[index*3 + 0] >> 3), green = (temp_buffer[index*3 + 1] >> 3), red = (temp_buffer[index*3 + 2] >> 3); // build up 16 bit color word USHORT color = RGB16BIT(red,green,blue); // write color to buffer ((USHORT *)bitmap->buffer)[index] = color; } // end for index // finally write out the correct number of bits bitmap->bitmapinfoheader.biBitCount=16; } // end if #if 0 // write the file info out printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d", filename, bitmap->bitmapinfoheader.biSizeImage, bitmap->bitmapinfoheader.biWidth, bitmap->bitmapinfoheader.biHeight, bitmap->bitmapinfoheader.biBitCount, bitmap->bitmapinfoheader.biClrUsed, bitmap->bitmapinfoheader.biClrImportant); #endif // close the file _lclose(file_handle); // flip the bitmap Flip_Bitmap(bitmap->buffer, bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8), bitmap->bitmapinfoheader.biHeight); // return success return(1); } // end Load_Bitmap_File ///////////////////////////////////////////////////////////////// Thanks, Tyranthraxus
Advertisement
I''m not sure if this is the problem, and it only applies if your using 16 bit graphics but... some computers store a 16bit RGB value as 5,5,5 and ingnore the extra bit, and some give the extra bit to the green channel giving you a 5,6,5 format. I believe you can check the DDSD2 structure to find out which is the case and plan for both accordingly.
A couple things to watch out for:

if you are running the 16-bit color bitmap demos, and have a graphics card that only uses 5 bits for green instead of the more common 6 green bits, you will have graphical problems. Andre fixes this in Tricks of the Windows Game Programming Gurus.

Another thing to watch out for in the future: For some reason, Andre''s bitmap loading code only loads bitmaps whose dimensions are a width (and height, I believe) of 8.


Wes

-Wes
Thanks for the replies Hmm...I wonder if my Graphics card uses the 5 5 5 method for 16-bit graphics... I''m using an STB nVidia TnT card.

Maybe I''ll try the code on my other computer which has a GeForce, and see how that goes. If it''s still messed, I guess I''ll have to try and get it to work for 5 6 5.

Thanks for the help.

Oh, btw, if anyone knows where to find help on .bmp loading for 16 or 24 bit graphics, it would be most appreciated. Most of the tutorials I''ve found thus far, only cover 8-bit graphics. Actually, ALL of the tutorials I''ve found only cover 8-bit. Which is probably because most of them are pretty old.

Thanks,
Tyranthraxus
Actualy, if you look in the DX Documentation, it has a bit about loading bitmaps onto surfaces. There might even be a function in dxutil.h and dxutil.c that does this .
I had the same problem and I fixed it by changing the _RGB16BIT macro in Gpdumb1.h to

#define _RGB16BIT(r,g,b) ((b&31)+((g&63)<<6) + ((r&31)<<11))
Yep, the problem was definately 5 6 5...

However, I needed to use this to fix it:

#define _RGB16BIT(r, g, b) ((b % 32) + ((g % 32) << 6) + ((r % 32) << 11))

GunnarStein had %31 %63 %31, but that gave some distortion still, so I went back to %32 %32 %32, and everything is swell

Thanks for all the help everyone. I''m still learning, so I may not be doing things right, or the best way, but at least I can load a bitmap now (even if I don''t understand everything I''m doing )!

Tyranthraxus
gunnerstein had &31 not %31, big difference
I wrote an article about loading .bmp files!
Don''t know where they hid it...ah, FOUND IT:

http://www.gamedev.net/reference/articles/article1064.asp

*"Loading Bitmap Files into DirectDraw"*

It doesn''t use Andre LaMothe''s limited file parsing routines, instead the Windows API, which even enhances 256-colour files and err..de-hances files with more colours than your screen has.

Glad2Help(tm)

p.s. dont trust that lamothe
quote:Original post by Tyranthraxus

Yep, the problem was definately 5 6 5...

However, I needed to use this to fix it:

#define _RGB16BIT(r, g, b) ((b % 32) + ((g % 32) << 6) + ((r % 32) << 11))

GunnarStein had %31 %63 %31, but that gave some distortion still, so I went back to %32 %32 %32, and everything is swell

Thanks for all the help everyone. I''m still learning, so I may not be doing things right, or the best way, but at least I can load a bitmap now (even if I don''t understand everything I''m doing )!

Tyranthraxus


You might want to check to see if it works on a non 565 graphics card... I had a similar problem a few months ago.


Dave "Dak Lozar" Loeser
Dave Dak Lozar Loeser
"Software Engineering is a race between the programmers, trying to make bigger and better fool-proof software, and the universe trying to make bigger fools. So far the Universe in winning."--anonymous

This topic is closed to new replies.

Advertisement