Loading a bitmap into a direct draw 7 surface
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.
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
this method is prolly nice and short, but a lot slower than writing your own image loading code
(not that i''d do that)
(not that i''d do that)

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
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
Ok, here it is
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
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
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement