2013年6月4日星期二(使用位图)

这一节是个大餐,加上了位图。最主要的一点,是我知道了,不一定要按照字符串读取的方法,而是根据标识去做,

定义了位图标识

#define  BITMAP_ID     0x4D42

 

位图(.BMP文件),分为几部分,位图文件头

 

typedef struct BITMAP_FILE_TAG

{

     BITMAPFILEHEADER       bitmapfileheader;  //位图文件头

     BITMAPINFOHEADER       bitmapinfoheader;//位图信息头

     PALETTEENTRY           palette[256]; //调色板

     UCHAR    *                  buffer;  //位图实际数据缓冲

}BITMAP_FILE, * BITMAP_FILE_PTR;

 

加了4个函数

 

int      Flip_Bitmap( UCHAR * image,int bytes_per_line, int height );

int      Load_Bitmap_File( BITMAP_FILE_PTR bitmap,char * filename );

int      Unload_Bitmap_File( BITMAP_FILE_PTR bitmap );

int      DDraw_Fill_Surface( LPDIRECTDRAWSURFACE7 lpdds,int color );

位图句柄

BITMAP_FILE              bitmap;

 

 

加载位图过程,首先打开文件,读取位图文件头,如果是位图标识,则继续读取位图信息头。如果有调色板,则加载,并将调色板中的RB颜色互换,最后加载位图数据。在函数中,是适合于8,16,24位位图,方法是按照字节分配内存,并读进位图文件。然后关闭文件句柄,逐行读入位图。

 

加载位图代码如下:

int Load_Bitmap_File( BITMAP_FILE_PTR bitmap,char * filename )

{

     int                file_handle, index;

     UCHAR *            temp_buffer            = NULL;       //用来将位位图转为位

     OFSTRUCT      file_data;                           //文件数据信息

 

     if( ( file_handle = OpenFile( filename, & file_data, OF_READ ) ) == -1 )      //打开文件

         return ( 0 );

     //读取位图文件头

     _lread( file_handle, & bitmap->bitmapfileheader, sizeof( BITMAPFILEHEADER ) );

    

     if( bitmap->bitmapfileheader.bfType != BITMAP_ID )

     {

         _lclose( file_handle );

         return ( 0 );

     }

 

     _lread( file_handle, & bitmap->bitmapinfoheader, sizeof( BITMAPINFOHEADER ) );

     //如果有颜色调色板,则加载

     if( bitmap->bitmapinfoheader.biBitCount == 8 )

     {

         _lread( file_handle, & bitmap->palette, MAX_COLORS_PALETTE *sizeof( PALETTEENTRY ) );

         //将调色板RB颜色互换

         for( index = 0;  index < MAX_COLORS_PALETTE; index ++ )

         {

              int      temp_color                           = bitmap->palette[index].peRed;

              bitmap->palette[index].peRed              = bitmap->palette[index].peBlue;

              bitmap->palette[index].peBlue             = temp_color;

              bitmap->palette[index].peFlags            = PC_NOCOLLAPSE;

         }

     }

     //最后加载位图数据

     _lseek( file_handle, - ( int ) ( bitmap->bitmapinfoheader.biSizeImage ), SEEK_END );

 

     //在这里以指针形式可以读取,16,24位位图

 

     if( bitmap->bitmapinfoheader.biBitCount == 8 || bitmap->bitmapinfoheader.biBitCount == 16 || bitmap->bitmapinfoheader.biBitCount == 24 )

     {

         if( bitmap->buffer )

              free( bitmap->buffer );

 

         //按照字节为位图分配内存

         if( ! ( bitmap->buffer = ( UCHAR * ) malloc( bitmap->bitmapinfoheader.biSizeImage ) ) )

         {

              _lclose( file_handle );

              return ( 0 );

         }

         //现在读进位图

         _lread( file_handle, bitmap->buffer, bitmap->bitmapinfoheader.biSizeImage );

     }

 

     else

     {

         return ( 0 );

     }

     _lclose( file_handle );

     Flip_Bitmap( bitmap->buffer, bitmap->bitmapinfoheader.biWidth * ( bitmap->bitmapinfoheader.biBitCount / 8 ), bitmap->bitmapinfoheader.biHeight );

     return ( 1 );

}

在这里,疑问其实很多,

第一,      位图文件头有哪些?

Typedef struct tagBITMAPFILEHEADER

{

     WORD bfType;       //文件类型,.bmp必须是0x4D42

     DWORD bfSize;      //指定位图文件字节数

     WORD bfReserved1;  //保留字段,必须为0

     WORD bfReserved2;  //保留字段,必须为0

     DWORD bfOffBits;   //指定从文件头结构到 位图位数的偏移量

} BITMAPFILEHEADER;

第二,      位图信息段有哪些

Typedef struct tagBITMAPINFO

{

     BITMAPINFOHEADER   bmiHeader;         //位图信息头

     RGBQUAD            bmiColors[1];      //调色板(如果有的话)

} BITMAPINFO;

 

位图信息头的结构

Typedef struct tagBITMAPINFOHEADER

{

     WORD          biSize;                //指定位图信息头的结构字节数

     LONG          biWidth;               //指定位图宽度像素数

     LONG          biHeight;              //指定位图高度像素数,如果为正,则位图是自下到上,起点在左下角;如果为负,则位图是自上到下,起点在左上角。

     WORD          biPlanes;              //指定颜色板数,必须为1

     WORD          biBitCount;            //指定每像素的位数,必须是1,4,8,16,24,或者32

     DWORD         biCompression;         //指定位图压缩类型,必须是BI_RGB

     DWORD         biSizeImage;           //位图字节数

     DWORD         biXPelsPerMeter;       //指定X轴的每米像素数

     DWORD         biYPelsPerMeter;       //指定Y轴的每米像素数

     DWORD         biClrUsed ;             //指定位图使用的颜色数

     DWORD         biClrImportant;        //指定重要的颜色数

} BITMAPINFOHEADER;

 

 

第三,加载位图时为何RB互换?

因为位图调色板项RGBQUAD,是正常的PALETTEENTRYS的倒序

Typedef struct tagRGBQUAD

{

     BYTE          rgbBlue;

     BYTE          rgbGreen;

     BYTE          rgbRed;

     BYTE          rgbReserved;           //未用

} RGBQUAD;

 

下面进行

//处理上下颠倒的位图

int Flip_Bitmap( UCHAR * image, int bytes_per_line, int height )

{

     UCHAR * buffer;

     int      index;

     if( ! ( buffer = ( UCHAR * ) malloc( bytes_per_line * height ) ) )

         return ( 0 );

     memcpy( buffer, image, bytes_per_line * height );

 

     for( index = 0; index < height; index ++ )

         memcpy( & image[  ( ( height - 1 ) - index ) * bytes_per_line], & buffer[index * bytes_per_line], bytes_per_line );

     free( buffer );

 

     return ( 1 );

}

 

下面是清屏函数

 

int DDraw_Fill_Surface( LPDIRECTDRAWSURFACE7 lpdds,int color )

{

     DDBLTFX       ddbltfx;

     DDRAW_INIT_STRUCT( ddbltfx );

     ddbltfx.dwFillColor                       = color;

     lpdds->Blt( NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, & ddbltfx );

 

     return ( 1 );

}

Game_main()是逐行读取像素,

 

 

在设置DDRAW的调色板时,用到自己的调色板图像,用setentries().

 

但是,运行后代码不对。7-11,7-12代码复制过来也有问题。回来再在网上查下。注释掉下句OK

//   _lseek( file_handle, - ( int ) ( bitmap->bitmapinfoheader.biSizeImage ), SEEK_END );

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值