Advertisement

Loading a bitmap into a direct draw 7 surface

Started by February 17, 2000 01:30 AM
6 comments, last by Asdas 25 years ago
I have been trying to do this for a couple of weeks now with little success. I was using the bitmap loading technique from the ddutil.cpp file, however it is too limited for what i''m trying to do. All of my bitmaps are 16bit, and stored in a single file, where the dimensions and pixels for each bitmap are stored. I can get the bitmaps bits out of the file easy, and the width height, but I am having a lot of problems converting the image from 24bit to 16bit then copying it into a dd surface. Does anyone have any code to copy a bitmaps bits into a direct draw surface that i can use? my surfaces come out with green dots, pink lines, sometimes the computer resets and sometimes I dont get any image at all! Thanks for reading!
Hi. Here''s a quick function to load a bitmap from a file to a surface. It could be easily modified to get the bitmap from a resource, but I wouldn''t know what to do with bitmaps that you have in memory as a collection of bits. Frankly, I hate all these bitmap formats and long for the old days where I had to write my own editors AND sprite formats.

Anyway-- this function: pass it a filename and a directdraw pointer, and it''ll you a surface back. (Note that on these forums, pipes (logical ''or'') becomes a ''/'' because of the HTML. Example: 2/1=3, but 2/1=2


LPDIRECTDRAWSURFACE BitmapToSurface(LPDIRECTDRAW lpdd, char *filename) {

LPDIRECTDRAWSURFACE newsurface;
DDSURFACEDESC ddsd;
HRESULT hRes;
HBITMAP hBM;
BITMAP BM;
HDC hDCImage;
HDC hDC;

hBM=(HBITMAP)LoadImage(NULL,filename,IMAGE_BITMAP,0,0,LP_LOADFROMFILE/LR_CREATEDIBSECTION);

if (hBM==NULL) {
// Could not find the file, or something else blew up
}

GetObject(hBM,sizeof(BM),&BM);
hDCImage=CreateCompatibleDC(NULL);
SelectObject(hdcImage,hBM);

ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS/DDSD_WIDTH/DDSD_HEIGHT;
ddsd.dwWidth=BM.bmWidth;
ddsd.dwHeight=BM.bmHeight;
ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;

hRes=lpdd->lpVtbl->CreateSurface(lpdd,&ddsd,&newsurface,NULL);

hRes=newsurface->lpVtbl->GetDC(newsurface,&hDC);
BitBlt(hDC,0,0,BM.bmWidth,BM.bmHeight,hDCImage,0,0,SRCCOPY);
newsurface->lpVtbl->ReleaseDC(newsurface,hDC);
DeleteDC(hDCImage);
DeleteObject(hBM);

return newsurface;
}

This does the trick, and the nice part is, it''ll dither the bitmap if you''re bringing it down to a lower color mode. All in all, very nice.

At some point, you''ll want to set the color key of the new surface, etc.

Also, there''s a DXUTIL function to load in a bitmap, but unless you''re using C++, it won''t help you.


-- Goodlife-----------------------------Those whom the gods would destroy, they first drive mad.--DirectX design team official motto
Advertisement
this method is prolly nice and short, but a lot slower than writing your own image loading code
(not that i''d do that)
What .h and .lib files are needed to do the function?
Sorry, I should have made it more clear, i CANT use this function (which is almost identical to my old one) because i dont have any single bitmap file for each image. All of the images are stored in one .set file, and although i can get the width/height/data for any image in the file, i cant use LoadImage to create a HBITMAP from it! I need code to copy the bits (UCHAR *, not a HBITMAP) into a ddsurface.

Thanks,
Michael Cleaver
I happen to do the same thing. In fact I just finished writing my own resource file to hold a bunch of bitmaps that I can load easily into surfaces later. I''ll send you the code or post it up here when I get back to my room (I''m on the school''s computers now).
Working on: DoP
Advertisement
Ok, here it is


DWORD width; // width of bitmap
DWORD height; // height of bitmap
BYTE *bitmap24;
BYTE *bitmap16;

// Allocate memory
bitmap24 = (BYTE*)malloc(width*height*3);
bitmap16 = (BYTE*)malloc(width*height*2);

// Read bitmap into bitmap24
// Then flip it or flip it when you read it in

// Next convert the bitmap to 16 bits
for(x=0; x{
WORD color;

BYTE blue = (bitmap24[x*3+0] >> 3);
BYTE green = (bitmap24[x*3+1] >> 2);
BYTE red = (bitmap24[x*3+2] >> 3);

color = ((blue&31) + ((green&63)<<5) + ((red&31)<<11));

((WORD*)bitmap16)[x] = color;
}
free(bitmap24);

// Create a DirectDraw surface the size of width and height

WORD *src; // pointer to source (bitmap)
WORD *dest; // pointer to destination (DD surface)

// Lock the surface and then write the data to it
for(i=0; i{
memcpy(dest, src, width*2);

dest += width;
src += width;
}
// Now unlock the surface and you're done
free(bitmap16);


Note: This code isn't complete by itself, but rather just a framework with some code here and there. I just thought I'd put the code up for the harder functions.

If you need any more help I'll be glad to help out. Hoped this helped.

Edited by - lshadow on 2/20/00 8:56:24 PM
Working on: DoP
Wow, thanks, thats exactly what i was after, I havnt tried it yet, Ill try it when i get home from work.

Thanks for the help!

This topic is closed to new replies.

Advertisement