|
|
发表于 2005-2-7 11:06:00
|
显示全部楼层
Re:求助:为什么我载入位图后显示不出来??
也不知道你用的是什么方法,干脆给你几个完整的函数吧,该函数可以将8位、16位或24位的BMP位图装入离屏表面,使用方法如下:
例如:将C:\1.bmp中保存的位图装入到离屏表面surf中。
LPDIRECTDRAWSURFACE7 surf=0;
surf=CreateSurface("C:\\1,bmp");
然后将surf表面Blt到主表面即可显示出来。
------------------------源程序--------------------------
LPDIRECTDRAWSURFACE7 CreateSurface(LPCTSTR filename)
{
int imagew, imageh;
GetBmpDimensions( filename, imagew, imageh );
LPDIRECTDRAWSURFACE7 surf=CreateSurface( imagew, imageh );
if (surf==0)
return 0;
ifstream bmp( filename, ios::binary | ios::nocreate );
if (!bmp.is_open())
return 0;
BITMAPFILEHEADER bmpfilehdr;
bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );
char* ptr=(char*)&bmpfilehdr.bfType;
if (*ptr!='B' || *++ptr!='M')
return 0;
BITMAPINFOHEADER bmpinfohdr;
bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );
bmp.seekg( sizeof(bmpfilehdr)+bmpinfohdr.biSize, ios::beg );
int imagebitdepth=bmpinfohdr.biBitCount;
int imagesize=bmpinfohdr.biSizeImage;
if (imagesize==0)
imagesize=((imagew*(imagebitdepth/8)+3) & ~3)*imageh;
if (bmpinfohdr.biCompression!=BI_RGB)
return 0;
BYTE* buf=new BYTE[imagesize];
bmp.read( buf, imagesize );
if (!Copy_Bmp_Surface( surf, &bmpinfohdr, buf ))
{
delete [] buf;
surf->Release();
return 0;
}
delete [] buf;
return surf;
}
---------------------------以下是辅助函数----------------------------------
BOOL GetBmpDimensions( LPCTSTR filename, int& w, int& h)
{
ifstream bmp( filename, ios::binary | ios::nocreate );
if (!bmp.is_open())
{
TRACE("GetBmpDimensions: cannot open file\n");
return FALSE;
}
BITMAPFILEHEADER bmpfilehdr;
bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );
char* ptr=(char*)&bmpfilehdr.bfType;
if (*ptr!='B' || *++ptr!='M')
{
TRACE("GetBmpDimensions: invalid bitmap\n");
return FALSE;
}
BITMAPINFOHEADER bmpinfohdr;
bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );
w=bmpinfohdr.biWidth;
h=bmpinfohdr.biHeight;
return TRUE;
}
LPDIRECTDRAWSURFACE7 CreateSurface( DWORD w, DWORD h )
{
DWORD bytes=w*h*(displaydepth/8);
DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
desc.dwWidth = w;
desc.dwHeight = h;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
LPDIRECTDRAWSURFACE7 surf;
HRESULT r=ddraw7->CreateSurface( &desc, &surf, 0 );
if (r==DD_OK)
return surf;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
r=ddraw7->CreateSurface( &desc, &surf, 0 );
if (r==DD_OK)
return surf;
return 0;
}
BOOL Copy_Bmp_Surface( LPDIRECTDRAWSURFACE7 surf, BITMAPINFOHEADER* bmphdr, BYTE* buf)
{
if (surf==0 || bmphdr==0 || buf==0)
return FALSE;
int imagew=bmphdr->biWidth;
int imageh=bmphdr->biHeight;
int imagebitdepth=bmphdr->biBitCount;
BOOL ret=FALSE;
if (imagebitdepth==8)
{
if (displaydepth==8)
ret=Copy_Bmp08_Surface08( surf, buf, imagew, imageh );
}
else if (imagebitdepth==24)
{
if (displaydepth==16)
ret=Copy_Bmp24_Surface16( surf, buf, imagew, imageh );
else if (displaydepth==24)
ret=Copy_Bmp24_Surface24( surf, buf, imagew, imageh );
else if (displaydepth==32)
ret=Copy_Bmp24_Surface32( surf, buf, imagew, imageh );
}
return ret;
}
BOOL Copy_Bmp08_Surface08( LPDIRECTDRAWSURFACE7 surf, BYTE* bmpbuf, int w, int h )
{
if (surf==0 || bmpbuf==0)
return FALSE;
DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );
if (r!=DD_OK)
{
TRACE("ShowBmp: Lock() failed\n");
return FALSE;
}
int bytesgiven=(w+3) & ~3;
BYTE* surfbits = (BYTE*)desc.lpSurface;
BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);
for( int i=0; i<h; i++ )
{
memcpy( surfbits, imagebits, w );
surfbits += desc.lPitch;
imagebits -= bytesgiven;
}
surf->Unlock( 0 );
return TRUE;
}
BOOL Copy_Bmp24_Surface16( LPDIRECTDRAWSURFACE7 surf, BYTE* bmpbuf, int w, int h )
{
if (surf==0 || bmpbuf==0)
return FALSE;
DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );
if (r!=DD_OK)
{
TRACE("Copy_Bmp24_Surface16: Lock() failed\n");
return FALSE;
}
int bytesrequired=w*3;
int bytesgiven=(bytesrequired+3) & ~3;
BYTE* surfbits = (BYTE*)desc.lpSurface;
BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);
float REDdiv=(float)256/(float)pow( 2, numREDbits );
float GREENdiv=(float)256/(float)pow( 2, numGREENbits );
float BLUEdiv=(float)256/(float)pow(2, numBLUEbits );
for( int i=0; i<h; i++ )
{
USHORT* pixptr=(unsigned short*)surfbits;
RGBTRIPLE* triple=(RGBTRIPLE*)imagebits;
for (int p=0;p<w;p++)
{
float rf=(float)triple->rgbtRed/REDdiv;
float gf=(float)triple->rgbtGreen/GREENdiv;
float bf=(float)triple->rgbtBlue/BLUEdiv;
WORD r=(WORD)((WORD)rf<<loREDbit);
WORD g=(WORD)((WORD)gf<<loGREENbit);
WORD b=(WORD)((WORD)bf<<loBLUEbit);
*pixptr = (WORD)(r|g|b);
triple++;
pixptr++;
}
surfbits += desc.lPitch;
imagebits -= bytesgiven;
}
surf->Unlock( 0 );
return TRUE;
}
BOOL Copy_Bmp24_Surface24( LPDIRECTDRAWSURFACE7 surf, BYTE* bmpbuf, int w, int h )
{
if (surf==0 || bmpbuf==0)
return FALSE;
DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );
if (r!=DD_OK)
{
TRACE("Copy_Bmp24_Surface24: Lock() failed\n");
return FALSE;
}
int bytesrequired=w*3;
int bytesgiven=(bytesrequired+3) & ~3;
BYTE* surfbits = (BYTE*)desc.lpSurface;
BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);
// check if file and surface format are identical
// if so, use memcpy() to speed things up
if (loREDbit==16 && loGREENbit==8 && loBLUEbit==0)
{
TRACE("using optimized code...\n");
for (int i=0;i<h;i++)
{
memcpy( surfbits, imagebits, bytesrequired );
surfbits += desc.lPitch;
imagebits -= bytesgiven;
}
}
else
{
TRACE("not using optimated code...\n");
for(int i=0; i<h; i++ )
{
RGBTRIPLE* surf=(RGBTRIPLE*)surfbits;
RGBTRIPLE* image=(RGBTRIPLE*)imagebits;
for (int p=0;p<w;p++)
{
DWORD r=image->rgbtRed << loREDbit;
DWORD g=image->rgbtGreen << loGREENbit;
DWORD b=image->rgbtBlue << loBLUEbit;
DWORD* data=(DWORD*)surf;
*data = r|g|b;
surf++;
image++;
}
surfbits += desc.lPitch;
imagebits -= bytesgiven;
}
}
surf->Unlock( 0 );
return TRUE;
}
BOOL Copy_Bmp24_Surface32( LPDIRECTDRAWSURFACE7 surf, BYTE* bmpbuf, int w, int h )
{
if (surf==0 || bmpbuf==0)
return FALSE;
DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );
if (r!=DD_OK)
{
TRACE("Copy_Bmp24_Surface32: Lock() failed\n");
return FALSE;
}
int bytesrequired=w*3;
int bytesgiven=(bytesrequired+3) & ~3;
BYTE* surfbits = (BYTE*)desc.lpSurface;
BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);
for(int i=0; i<h; i++ )
{
DWORD* surf=(DWORD*)surfbits;
RGBTRIPLE* image=(RGBTRIPLE*)imagebits;
for (int p=0;p<w;p++)
{
DWORD r=image->rgbtRed << loREDbit;
DWORD g=image->rgbtGreen << loGREENbit;
DWORD b=image->rgbtBlue << loBLUEbit;
DWORD* data=(DWORD*)surf;
*data = r|g|b;
surf++;
image++;
}
surfbits += desc.lPitch;
imagebits -= bytesgiven;
}
surf->Unlock( 0 );
return TRUE;
}
|
|