Archived

This topic is now archived and is closed to further replies.

Igrum

AARRGGHH!! HELP!!

Recommended Posts

OK, I've been working on this code for a while now, and I still can't get it to work. It's just supposed to be a demo sprite animator that I can give to my artist so he can test the artwork he makes. The problem is I can't get a bitmap loaded correctly to save my life. I've done it a couple different ways, but the result is the same: the image is stretched to roughly twice its normal size. Here's the code I originally used:
      
	_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
	_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));

	bitmap->lpddsbuffer = CreateOffscreenSurface(bitmap->bitmapinfoheader.biWidth, 
												 bitmap->bitmapinfoheader.biHeight);
	
	UCHAR *temp_buffer = new UCHAR[bitmap->bitmapinfoheader.biWidth * bitmap->bitmapinfoheader.biHeight];

	if ((hr = bitmap->lpddsbuffer->Lock(NULL, &ddsd, 
										 DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 
										 NULL)) != DD_OK)
	{
		Log_File((char *)DXGetErrorDescription8(hr));
		return(0);
	}
	
	UINT *surface_buffer = (UINT *)ddsd.lpSurface;

	_lread(file_handle, surface_buffer, bitmap->bitmapinfoheader.biSizeImage);

	bitmap->lpddsbuffer->Unlock(NULL);
  
  
And here's the code I tried when that stretched the image:
       
	HBITMAP hbitmap;
	HDC hSrcDC;
	HDC hDestDC;


	if ((hbitmap = (HBITMAP) LoadImage(NULL, filename, 
									   IMAGE_BITMAP, bitmap->bitmapinfoheader.biWidth, 
									   bitmap->bitmapinfoheader.biHeight,
									   LR_LOADFROMFILE | LR_CREATEDIBSECTION)) == NULL)
	{
		Log_File("Couldn't load bitmap.");
		return(0);
	}

	if ((hSrcDC = CreateCompatibleDC(NULL)) == NULL)
	{
		Log_File("Couldn't create compatible DC.");
		return(0);
	}

	if (SelectObject(hSrcDC, hbitmap) == NULL)
	{
		DeleteDC(hSrcDC);
		Log_File("Couldn't select object into DC.");
		return(0);
	}

	if (GetObject(hbitmap, sizeof(BITMAP), &bitmap->bmp) == 0)
	{
		DeleteDC(hSrcDC);
		Log_File("Couldn't get object.");
		return(0);
	}

	if ((hr = bitmap->lpddsbuffer->GetDC(&hDestDC)) != DD_OK)
	{
		DeleteDC(hSrcDC);
		Log_File("Couldn't get buffer's DC.");
		Log_File((char *)DXGetErrorDescription8(hr));
		return(0);
	}

	if (BitBlt(hDestDC, 0, 0, 
			   bitmap->bmp.bmWidth, bitmap->bmp.bmHeight, 
			   hSrcDC, 0, 0, SRCCOPY) == NULL)
	{
		DeleteDC(hSrcDC);
		bitmap->lpddsbuffer->ReleaseDC(hDestDC);
		Log_File("Couldn't blt bitmap to surface.");
		return(0);
	}


	DeleteDC(hSrcDC);
	bitmap->lpddsbuffer->ReleaseDC(hDestDC);
  
That produced an enlarged image too. When I drew both of these surfaces, I just used a blt to do it. There was one time when I managed to get the image to draw correctly, when I used the following code to draw it:
  
	DDSURFACEDESC2 ddsd;

	DDRAW_INIT_STRUCT(ddsd);

	if (FAILED(lpdds->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL)))
	{
		Log_File("Draw24Bit: Lock failed.");
		return(0);
	}
	

	DWORD *primary_buffer = (DWORD *)ddsd.lpSurface;       

	// process each line and copy it into the primary buffer

	for (int index_y = 0; index_y < bitmap->bitmapinfoheader.biHeight; index_y++)
	{
		for (int index_x = 0; index_x < bitmap->bitmapinfoheader.biWidth; index_x++)
		{
			// get BGR values

			UCHAR blue  = (bitmap->buffer[index_y*bitmap->bitmapinfoheader.biWidth*3 + index_x*3 + 0]),
				  green = (bitmap->buffer[index_y*bitmap->bitmapinfoheader.biWidth*3 + index_x*3 + 1]),
				  red   = (bitmap->buffer[index_y*bitmap->bitmapinfoheader.biWidth*3 + index_x*3 + 2]);

						
DWORD pixel = _RGB32BIT(0,red,green,blue);


						primary_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;

		} 

	} 

	lpdds->Unlock(NULL); 
      
I tried altering this code to work when I loaded the bitmap, which should have been trivial. Unfortunately, this didn't work. It'd go partway through the loop before failing somewhere and exiting the program. I'm not sure what to do from here. Loading a bitmap into memory is supposed to be one of the easier parts of this whole process, and I can't do it. Please help! [edited by - Igrum on March 18, 2003 4:11:58 PM] [edited by - Igrum on March 18, 2003 4:12:50 PM]

Share this post


Link to post
Share on other sites
There don't seem to be many references to the pitch/stride there. That's the number of bytes per line width, that can be greater than x.

Remember the surface you create could be in any format. If its 32 bit then 4 bytes per pixel, 8-bit then one.

The best option is to parse for each format.

For example:

case D3DFMT_A8R8G8B8:
index=x*4+y*pitch;
surface[index+3]=alpha;
surface[index+2]=(byte)(color&0x000000ff);
surface[index+1]=(byte)((color&0x0000ff00)>>8);
surface[index+0]=(byte)((color&0x00ff0000)>>16);
break;

Mark

[edited by - Mark Sheeky on March 22, 2003 9:06:05 AM]

[edited by - Mark Sheeky on March 22, 2003 9:06:55 AM]

Share this post


Link to post
Share on other sites