Skip to main content
GameDev.net gamedev.net
🔒 Locked

Loading Bitmaps ( again! )

Started by ACAC May 26, 2002 at 12:49 PM 5 replies 250+ views
Original Post
ACAC
ACAC
Ok i solved my bitmap loading problem the other day... now im trying to only load part of the bitmap onto the surface.. so i can have templated bitmaps.The bitmap appears fuzzy, you can tell that the image is correct... but one of the values isnt... so it looks all skewed.. heres the code
    
void CPlayer::Create(char *filename, int numcells, int cellw, int cellh)
{
	this->cellw = cellw; this->cellh = cellh;

	int num_bytes; // needed to store the amount of bytes

	
	ifstream filestream;

	filestream.open(filename, ios::in | ios::binary); // open the file ! :)

	
	if(filestream.is_open())
	{
		//first read in some usefull info

		filestream.seekg(0, ios::beg); // make sure were reading from the beggining

		filestream.read((char*)&this->bitmapfile.bmfh, sizeof(BITMAPFILEHEADER)); 
		filestream.read((char*)&this->bitmapfile.bmih, sizeof(BITMAPINFOHEADER)); 

		// we have info LETS READ IN THE PIXELS BABY YEAH!


		num_bytes = this->bitmapfile.bmih.biWidth * bitmapfile.bmih.biHeight;
		num_bytes *= (this->bitmapfile.bmih.biBitCount/8);

		this->bitmapfile.ByteAmount = num_bytes;

		this->bitmapfile.BitmapBits = new BYTE[num_bytes]; // we have our byte array! :)

		
		filestream.read((char*)&this->bitmapfile.BitmapBits[0], num_bytes);

		// that was SO EASY DUDE!

		filestream.close();
	}
	else
	{
		MessageBox(g_hWnd, "Could Not open bitmapfile!!", filename, MB_OK);
		return;
	}

	//now we need to write it to a surface :S here goes!

	DDSURFACEDESC2 ddsd;
	DDCOLORKEY ck;

	ck.dwColorSpaceHighValue = _16BIT(255,0,255); //pink is transparent

	ck.dwColorSpaceLowValue = _16BIT(255,0,255);//pink is transparent


	ZeroMemory(&ddsd, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);

	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
	ddsd.dwWidth = cellw;
	ddsd.dwHeight = cellh;

	DebugOut("The bitmap width is %d the height is %d", cellw,
														cellh);

for(int index = 0; index < numcells; index++)
{
	ErrorCheck(DDraw->GetInterface()->CreateSurface(&ddsd, &this->lpDDAnims[index], NULL), "Creating Surface");
	ErrorCheck(this->lpDDAnims[index]->SetColorKey(DDCKEY_SRCBLT, &ck), "Colorkey");
}


for(int cell = 0; cell < numcells; cell++)
{
	//now get the bitmap onto the surface

	ZeroMemory(&ddsd, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);

	ErrorCheck(this->lpDDAnims[cell]->Lock(NULL,&ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL),"lock Surface");

	USHORT *vid_buf = (USHORT*)ddsd.lpSurface;
	int lPitch = (ddsd.lPitch>>1);

	int curbit = 0;
	int cury = cellh;
	int curx = 0;
	int bytes = (cellw * cellh) * 3;

	while(curbit < bytes)
	{			
			vid_buf[(curx) + cury*lPitch] = _16BIT(this->bitmapfile.BitmapBits[curbit+2],this->bitmapfile.BitmapBits[curbit+1],this->bitmapfile.BitmapBits[curbit+0]);
			
			curx++;	
			if(curx >= cellw)
			{
				
				DebugOut("Y is :%d",cury);
				cury--;
				curx = 0;
			}

			curbit+=3;
	}

	ErrorCheck(this->lpDDAnims[cell]->Unlock(NULL), "Unlock Surface");	
	
}
    
I know i dont use cell yet, i want to get the first surface right. then i will advance along each cell thanks for your help in advance. btw - the bitmap im trying to load is 64x64 [edited by - ACAC on May 26, 2002 1:54:15 PM]
Jason Zelos
Jason Zelos
Don''t forget that rows are dword alined, zero padded on disk.

,Jay
ACAC
ACAC
I dont think thats the problem but how do I solve it if so?

any other ideas anyone??
Quanta85
Quanta85
i had a similar problem while trying to load bitmaps. my problem was that i was accessing the bitmap image pixel bits assuming the pixel bits buffer was the same width as the bitmap, but its not. The width of the pixel bits buffer can be calculated as:

RowLength = 4 * ((bitmap_width * bitmap_bitcount + 31) /32)

you should copy the bitmap from the file to your offscreen buffer one row at a time, something like this:
for(int i=0;i (is less than) bitmap_height;i++)
{
memcpy(offscreen_buffer+(bitmap_width*i),file_buffer+(RowLength*i),bitmap_width*bits_per_pixel);
}

hope this helps

[edited by - Quanta85 on May 26, 2002 2:51:30 PM]

[edited by - Quanta85 on May 26, 2002 2:52:49 PM]

[edited by - Quanta85 on May 26, 2002 2:57:31 PM]
declspec
declspec
careful of this pattern. just mentioning it to head it off. not so bad with CPlayer though cause there doesnt tend to be alot of instances of CPlayer. if every instance of a game object keeps its own bitmap youll run out of memory fast. different instances that share the same bitmap should point to the same bitmap.

ACAC
ACAC
Hey,

Heres the code... the full project if anyone has time to take a look.

[link]www.btinternet.com/~ashley.canning/zip.zip[/link]

I dont understand what your doing quanta..





[edited by - ACAC on May 26, 2002 3:09:53 PM]
Jason Zelos
Jason Zelos
On disk the pixel data is stored by rows upside-down (high row to low row). Each row is comprised of (width*BytesPerPixel) plus an Offset. The offset can be calculated by

    
Pitch = biWidth * (biBitCount/8); // In case of different bit depths for 1/4 bit round up to nearest byte

RowOffset = 4 - Pitch % 4; // get remainder, take from 4 (bytes)

if (RowOffset==4) RowOffset=0; //4-0 gives 4 rather than 0


The complete row on disk is Pitch+RowOffset, so when you load height*width bytes into memory even using 8 bit colour, you are going to get the rows skewing across the screen incrementaly as you increase the height. You need to either strip out the offset when you load the bitmap or take account of the offset when blitting rows/pixels to screen.

,Jay

Edit: Looks nicer in a source box. How dooo you spell comprised ?


Edit: Really should mention for this kind of application, you only load once but you blit many times. So stripping out padding when loading is best (negligible overhead).

[edited by - Jason Zelos on May 27, 2002 2:47:44 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.