Ok, maybe someone new looking at this problem can help me out. I'm loading a bitmap with the following code, and then transfering it to a DDraw surface, and blitting it. The only problem is, there are blank lines on the image blted to the screen. I've narrowed it down to either the bitmap loader or the bitmap to surface function. The bitmap does not have any padding issues(its DWORD aligned) and I am converting to the right 16-bit mode. Heres the coder for the loader:
for(iHeight = spBitmap->infoheader.biHeight - 1; iHeight >=0; iHeight --){
for(iWidth = 0; iWidth < spBitmap->infoheader.biWidth*2; iWidth += 2){
//read in one pixel, converting it to either RGB 565 or 555
//and switching it from BGR to RGB
file.get((char&)sTemp.blue);
file.get((char&)sTemp.green);
file.get((char&)sTemp.red);
//convert the pixel to 16 bit
wColor = Convert16(sTemp.red, sTemp.green, sTemp.blue);//Converts it to a 16-bit WORD value
//store low-end of WORD
spBitmap->buffer[iHeight*spBitmap->infoheader.biWidth+iWidth] = wColor & 0xFF;
//The buffer is a BYTE buffer that IS big enough to hold everything
//store high-end of WORD
spBitmap->buffer[iHeight*spBitmap->infoheader.biWidth+iWidth + 1] = wColor>>8;
}
}
And now heres the part that copies the bitmap from buffer to a surface.
wBitmap_Buffer = (WORD*)spBitmap->buffer;//Again, BUFFER points to a BYTE buffer
wScreen_Buffer = (WORD*)SurfaceDesc.lpSurface; //make the buffer valid
//Now copy the bitmap to the newly locked surface
for(y = 0; y < spBitmap->infoheader.biHeight; y++)
{
//copy the bitmap one line at a time
memcpy((void*)wScreen_Buffer,
(void*)wBitmap_Buffer,
spBitmap->infoheader.biWidth*2);
//advance pointers
wScreen_Buffer += SurfaceDesc.lPitch;
wBitmap_Buffer += spBitmap->infoheader.biWidth;
}
Any ideas at this point would be MUCH appreciated. I'm sick of staring at my screen trying to figure out whats wrong.
-Chris
EDIT: Fixed the formatting
Edited by - Turtlebread on August 5, 2001 6:48:46 PM
I''ve found that the easiest thing to do is to use the loader that comes with the DirectX SDK. There is a function called DDLoadBitmap() in ddutil.h and .cpp that does just what you need. The ddutil files are in some of the sample directories. Just do a search for them and you should find them. Here''s the prototype:
IDirectDrawSurface7 *DDLoadBitmap(IDirectDraw7 *pdd, LPCSTR szBitmap, int dx, int dy);
If I remember correctly dx and dy are used to specify where the bitmap is to be put on the surface. So I put 0,0 it indicate the top left corner. It loads a bitmap from a file specified by szBitmap and puts it onto a surface, and returns a pointer to that surface. Once you have that pointer, you can use it to blt the bitmap to your backbuffer or whatever. Here''s how I used it in my code:
It seems like instead of blank space, its printing garabage values, like the surface is not getting totally written too. And I don't want to use a function to load a bitmap, I'm trying to create one myself, so I have some control over how it is loaded.
Thanks, -Chris
EDIT: Link didn't work
Edited by - Turtlebread on August 5, 2001 8:35:03 PM
I don''t know what your exact problem is, but there is a differenct way that you could copy the bitmap. I have it in Object Pascal right now, and could convert it to C++, but the functions are windows functions, so you should get it. Oh yeah, and // denotes a comment, nil is null, := assigns variables, assigning Result to something is the same as returning something, and just ask if anything else baffles you.
function DXLoadBitmap(FDirectDraw: IDirectDraw7; const BitmapName: string; Width, Height: integer): IDirectDrawSurface7; var Bitmap: HBitmap; //this is equal to a long int BM: Windows.TBitmap; //this is equal to a TagBitmap, which is just the bitmap header info SrfDC, SrcDC: HDC; //handles to device contexts DDSurface: TDDSurfaceDesc2;//surface description FSurface: IDirectDrawSurface7;//your surface begin // try to load the bitmap as a resource, if that fails, try it as a file Bitmap:= LoadImage(GetModuleHandle(NIL), PChar(BitmapName), IMAGE_BITMAP, Width, Height, LR_CREATEDIBSECTION); try if Bitmap = 0 then Bitmap:= LoadImage(0, PChar(BitmapName), IMAGE_BITMAP, Width, Height, LR_LOADFROMFILE or LR_CREATEDIBSECTION); // get size of the bitmap GetObject(Bitmap, SizeOf(BM), @BM); SrcDC:= CreateCompatibleDC(0); SelectObject(SrcDC, Bitmap); FillChar(DDSurface, SizeOf(TDDSurfaceDesc2), 0); DDSurface.dwSize := SizeOf(TDDSurfaceDesc2); DDSurface.dwFlags := DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH; DDSurface.dwWidth := Width; DDSurface.dwHeight := Height; DDSurface.ddsCaps.dwCaps := DDSCAPS_OFFSCREENPLAIN; FDirectDraw.CreateSurface(DDSurface, FSurface, nil); FSurface.GetDC(SrfDC); try BitBlt(SrfDC, 0, 0, Width, Height, SrcDC, 0, 0, SRCCOPY); finally FSurface.ReleaseDC(SrfDC); end; finally DeleteDC(SrcDC); Result := FSurface; if Bitmap <> 0 then DeleteObject(Bitmap); end; end;
It sounds to me like you are may be using an integer is being used somewhere where it shouldn''t. That''s just a guess though. Hope this helps.
Hmm...it seems another little problem has entered the game. Since I''m in 16-bit mode, I''m casting the lpSurface pointer to a WORD. To advance it, I''m adding lPitch to it. However, lPitch is the number of BYTES, and I''m using a WORD pointer. AHA! I thought, now I have it. I''ll just divide lPitch by 2 (16/8) However, it didn''t work. It is STILL showing up wrong, but this leads me to another question. What happens if lPitch is say, 41 bytes. 41/2 = 21.5. This would be very bad, as the WORD pointer couldn''t advance to the right spot. What happens in this situation? Is lPitch ALWAYS going to be even? If not, what happens if yer using a WORD pointer to the surface?
Well I can''t really tell without a little more code, but one thing that seems off is your for statement. If you''re reading in a 24-bit bitmap (which it appears you are and then converting it to 16-bit), then the for statement would be...
I''m reading in a pixel at a time though, so I should just run through the entire bitmap once. The only reason I''m adding two at a time is because of my BYTE buffer. Anyway, I''ve been running some test, and found out that it reads the first row of pixels fine, and then only the second half. For example, take a 4x4 bitmap X X X X 0 0 X X 0 0 X X 0 0 X X
The X''s represent the pixels that appear on the screen of a 4x4 bitmap. The problem seems to be somewhere in the bitmap reading loop...Let me know if anyone sees a problem.
Aha! It finally works. It was a combination of problems, including the fact I wasn''t taking into account the BYTE buffer addressing. Thanks to all who helped