Archived

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

Ratman

Im going crazy - can I please just get a straight answer?

Recommended Posts

Ok I've had this problem for about 3 weeks now, and cant take it anymore. I've thought about it, I've expiremented, I've read everything I could - and I still cant get this code to work. So, if you think you can help me work this out, I'd appreicaite it. Please be as descriptive as possible, so I can (hopefully) understand why this isnt working. Heres the scenerio - I was reading Lamothes tricks of the windows game programming gurus (as well as the DX helpfile) to help me learn DirectDraw. Well I wanted to make his code work with 16-bit, as well as put it all into classes. So everything gone good untill I get to bitmaps. And Ive tracked it down to this function - copying the bitmap into a direct draw surface. Heres is the code, with comments- CImage::CopyBmpSurface() { //This will take Buffer which is a USHORT and copy it to the Surface //After this, we can blit! USHORT *source_ptr; USHORT *dest_ptr; //working pointers DDSURFACEDESC2 ddsd; //surface description DDRAW_INIT_STRUCT(ddsd); //lock the surface we're gonna copy Surface->Lock(NULL, &ddsd, DDLOCK_WAIT / DDLOCK_SURFACEMEMORYPTR, NULL); source_ptr = (USHORT *)Bitmap;// this is the buffer we've loaded the picture onto dest_ptr = (USHORT *)ddsd.lpSurface; // this is the surface we're scanning it to. //go thru each line and copy piture for(unsigned int index_y = 0; index_y < ddsd.dwHeight; index_y++) //bitshift here? { memcpy(dest_ptr, source_ptr, (bitmapinfoheader.biWidth)); //bitshift here? //advance pointer dest_ptr += (ddsd.dwWidth); //bitshift here? source_ptr += bitmapinfoheader.biWidth; //bitshift here? } Surface->Unlock(NULL); } And thats it. Im pretty sure it was to do with the bitshifting. Im in 16bit mode, so I want to use USHORT* to hold my data, but "DD uses UCHAR to count". So, for example, if my image is 64 pixels big, its ddsd.dwWidth is going to be 128? When I run the program as it is, the image is 1/4 its size (if the image is 64x64, it will now be 32x32) and will have a grey box, its same size under it. like this: ************* *-----*-----* *--A--*-----* *-----*-----* ******--C--* *-----*-----* *--B--*-----* *-----*-----* ************* A = the visible image, shrunk down to 1/4 its correct size but the entire image is there (its shrunk, not cut off). B = Gray area C = this is how big the image should be, right now, its black. Thank you for any help. This is really, really, frusterating, and I want to move on to programming - games - and am quite sick of fidling with this stuff. Thanks again Dave Ratti Edited by - ratman on 4/1/00 4:49:21 PM

Share this post


Link to post
Share on other sites
Hi

The Problem lies in the fact, that the Function memcpy wan''ts to know how many BYTES you wan''t to copy regardless of the Pointer type.
so you have to multiply the Width by 2, when using 16 Bit.

The other things do not need any shifts (i hope)

Lars

Share this post


Link to post
Share on other sites
you can avoid using bitmap buffers by using some of the already made functions for this and copying the HDC of the bitmap to that of the surface:

//copies the a bitmap to a surface
HRESULT Ddraw::CopyBMPToSurface( LPDIRECTDRAWSURFACE7 pddsSurface, DWORD width, DWORD height, char file[ FILE_LEN ]){
BITMAP bm;
HBITMAP hbm;
HDC hdcBitmap,
hdcTexture;
DDSURFACEDESC2 ddsdesc;

ddsdesc.dwSize = sizeof(ddsdesc);
ddsdesc.dwFlags = DDSD_HEIGHT / DDSD_WIDTH;
pddsSurface->GetSurfaceDesc(&ddsdesc);
// Create a bitmap and load the pddsSurface file into it. Check the
// executable's resource first.
hbm = (HBITMAP)LoadImage( GetModuleHandle(NULL), file,
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
if( NULL == hbm ){
// If not in the resource, try to load the bitmap as a file. Real code
// would try to find the bitmap among many file paths.
hbm = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE/LR_CREATEDIBSECTION );
if( NULL == hbm ) return NULL;
}
// Now, copy the bitmap to the pddsSurface surface. To do this, we are creating
// a DC for the bitmap and a DC for the surface, so we can use the BitBlt()
// call to copy the actual bits.
hdcBitmap = CreateCompatibleDC( NULL );
if( NULL == hdcBitmap ){
pddsSurface->Release();
return NULL;
}
SelectObject( hdcBitmap, hbm );

// Get the bitmap structure (to extract width, height, and bpp)
GetObject( hbm, sizeof(BITMAP), &bm );
//added this so that the bitmap is centered in the surface (useful for d3d)
DWORD x, y;
x = (ddsdesc.dwWidth / 2) - (width / 2);
y = (ddsdesc.dwHeight / 2) - (height / 2);
// Get a DC for the surface
if( SUCCEEDED( pddsSurface->GetDC( &hdcTexture ) ) ){
// Copy the bitmap image to the surface.
StretchBlt( hdcTexture, 0, 0, width, height,
hdcBitmap, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
pddsSurface->ReleaseDC( hdcTexture );
}
DeleteDC( hdcBitmap );
DeleteObject(hbm);
return S_OK;
}


Edited by - iwasbiggs on 4/1/00 9:52:46 PM

Share this post


Link to post
Share on other sites