游戏编程一:位图的处理

本文详细介绍了在游戏编程中处理位图的方法,包括如何使用双缓存策略,创建DIBSection,以及位图头文件结构的定义。通过LoadImage和CreateDIBSection函数来加载和创建位图,接着展示了如何进行位图复制、重叠等图像处理,以及处理透明度的方法。代码示例中展示了如何进行图像的复制、混合操作,为游戏场景添加角色和地图。
摘要由CSDN通过智能技术生成

 在游戏编程中,位图的处理是一个重要的环节,我将结合这几天我们小组制作游戏的具体情况,简单介绍一下我们小组对位图的处理方法。
    首先我们采用的当然是双缓存策略,就是在缓存里面画好图后在用bitblt映射到client上,我们用的图片是bmp文件,采用的是设备无关位图,所以首先创建一个class DIBSection,用来操纵DIB,这里我们参考的是坂本千寻所写的一个类库。
    我们定义一个位图头文件结构
    struct {
  BITMAPINFOHEADER Info;
  DWORD    BitField[3];
 } Header;                              //位图头文件结构
    然后进行DIBSection的创建,使用函数如下:
BOOL CDibSection::Create(int width, int height, int depth)
{

 bytes_per_line = ScanBytes(width, depth);
 bytes_per_pixel = PixelBytes(depth);

 Header.Info.biSize   = sizeof(BITMAPINFOHEADER);
 Header.Info.biWidth   = width;
 Header.Info.biHeight  = height;
 Header.Info.biBitCount  = depth;
 Header.Info.biPlanes  = 1;
 Header.Info.biXPelsPerMeter = 0;
 Header.Info.biYPelsPerMeter = 0;
 Header.Info.biClrUsed  = 0;
 Header.Info.biClrImportant = 0;
 Header.Info.biCompression = depth == 24? BI_RGB: BI_BITFIELDS;
 Header.Info.biSizeImage  = bytes_per_line * height;

 switch (depth) {
   case 16:
  Header.BitField[0] = 0x7c00;
  Header.BitField[1] = 0x03e0;
  Header.BitField[2] = 0x001f;
  break;

   case 32:
  Header.BitField[0] = 0xff0000;
  Header.BitField[1] = 0x00ff00;
  Header.BitField[2] = 0x0000ff;
  break;     

   default:
  Header.BitField[0] = 0;
  Header.BitField[1] = 0;
  Header.BitField[2] = 0;
  break;
 }

 HDC dc = ::GetDC(0);
 hBitmap = CreateDIBSection(dc, (BITMAPINFO *)&Header, DIB_RGB_COLORS, &Bits, NULL, 0);
 ::ReleaseDC(0, dc);

 return hBitmap != 0;
}

    在这个函数中,其实就是调用了CreateDIBSection的API来创建了一个DIBSection,该函数需要有一个BITMAPINFO结构体,具体的请自行参照MSDN。在这个函数中,可以实现16,24,以及32位位图的创建,在创建24为位图时biCompression需要设置成BI_RGB,且紧跟在BITMAPINFO后的色盘位字段为0。

    然后就是显示BMP文件,Windows有一个自带的函数LoadImage,可是他的功能太过于强大,不能知道很多位图文件的内部信息,但只是可以使用GetObject,就可以从读入的图片中取得想要的信息,同时我们用GetModuleHandle取得调用LoadImage的实体代号,故函数如下:

//位图资源加载

BOOL CDibSection::LoadBmp(const char *path)
{
 Destroy();

 hBitmap = (HBITMAP)::LoadImage(::GetModuleHandle(0), path, IMAGE_BITMAP, 0, 0,
  LR_CREATEDIBSECTION | LR_LOADFROMFILE);
 if (!hBitmap)
  return FALSE;

 DIBSECTION dib;
 if (::GetObject(hBitmap, sizeof(DIBSECTION), &dib) != sizeof(DIBSECTION)) {
  ::DeleteObject(hBitmap);
  hBitmap = 0;
  return FALSE;
 }
 Header.Info = dib.dsBmih;
 for (int i=0; i<3; i++)
  Header.BitField[i] = dib.dsBitfields[i];

 bytes_per_pixel = PixelBytes(dib.dsBmih.biBitCount);
 bytes_per_line = ScanBytes(dib.dsBmih.biWidth, dib.dsBmih.biBitCount);
 Bits = dib.dsBm.bmBits;

 return TRUE;
}

    在我们通过一个bitblt函数,就可以把图像画到client上,Draw函数如下,

//图像绘制
inline void CDibSection::Draw(HDC dc, int x, int y, int w, int h, int ox, int oy)
{
 BitBlt(dc, x, y, w, h, CDibDC(*this, dc), ox, oy, SRCCOPY);
}

inline void CDibSection::Draw(HDC dc, const CRect &rect, CPoint point)
{
 Draw(dc, rect.left, rect.top, re

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值