荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Peter (小飞侠), 信区: Program
标  题: DirectX5.0游戏编程指南(二)
发信站: BBS 荔园晨风站 (Thu Jan 21 22:33:46 1999), 转信


DirectX5.0最新游戏编程指南
DirectDraw篇

    DirectDraw是DirectX SDK的主要部分之一,它允许你直接对显示内存操作,
支持硬件位块传输、硬件覆盖、表面翻转,并且保持同目前的基于Windows的应用
程序和驱动程序兼容。
    DirectDraw是一种软件接口,它除了能直接对显示设备存取外,还保持同
Windows图形设备接口GDI(Graphics Device Interface)兼容。对于图形来说,
它并不是一种高级应用程序接口。DirectDraw提供了一种设备无关性的方法,使
得基于Windows的应用软件和游戏(例如三维图形软件包和数字视频游戏)能直
接获取显示设备的特性。
    DirectDraw能工作于各种各样的显示设备,从简单的SVGA显示器到能够提供
剪切、拉伸和非RGB格式支持的高级显示设备。DirectDraw接口使得你的应用程序
能仿真基本硬件的性能并使用硬件加速特性;硬件不提供的特性将由DirectX来仿
真。DirectDraw提供的对显示内存的设备无关性的访问能使你很容易地管理显示
内存。你的应用程序只需要识别一些基本的设备属性,它们都是标准的硬件应用,
例如RGB和YUV格式的颜色。你不需要调用特殊的过程来使用位块传输或操纵调色
板寄存器。使用DirectDraw,你可以很容易地操作显示内存,充分利用不同类型
显示设备的位块传输和颜色解压功能,而不需要依赖于特定的硬件。DirectDraw
可以运行在Windows95/NT4.0和以后的版本中。
    DirectDraw的硬件抽象层HAL(Hardware Abstraction Layer)提供了统一
的接口,通过该接口,程序可以直接在显示内存或视频内存中工作,获取硬件的
最佳性能。
    DirectDraw对视频硬件的性能进行估计,只要可能就会使用硬件提供的特定
性能。例如,如果视频卡支持位块传输,DirectDraw就会把位块传输委托给视频
卡,CPU不参与位块传输的处理,这就大大提高了程序运行的性能。另外,
DirectDraw提供了硬件仿真层HEL(Hardware Emulation Layer ),使得在某些硬
件不存在时可以用软件仿真来支持本应该由这些硬件提供的特性。
    DirectDraw运行在Windows 95上,能够利用32位内存的优越性和操作系统提
供的“平坦”内存模型。DirectDraw将系统内存和视频内存作为大块存储而不是
一小段一小段地使用。另外,DirectDraw还为 Windows图形程序员带来了许多强
大的功能:
  .DirectDraw使得在全屏模式下的应用多个后台缓冲区的页翻转变得容易
  .支持窗口模式和全屏模式下的剪切功能
  .支持三维 Z缓冲区
  .支持Z方向的硬件辅助覆盖
  .提供对图象拉伸的硬件的存取
  .同时访问标准的和增强的显示设备内存区域
  .动态调色板、独占式的硬件访问、分辨率切换等
将这些特性结合在一起,你就可以较容易地编制出性能超过基于GDI的标准Windows
游戏甚至是MS-DOS下的游戏。

一、DirectDraw的基本图象概念
    DirectDraw提供了一组不同于GDI的图形术语,因此,要用好DirectDraw,
首先应该了解其中的有关概念。下面就对DirectDraw中重要的概念作一介绍。
1.1设备无关性位图DIB(Device-Independent Bitmap)
     DirectX使用设备无关性位图DIB作为主要的图形文件格式。一个DIB文件主要
保护了如下信息:图象的维数、使用的颜色数、描述颜色的值及描述每一个像素的
数据。DIB文件还保护了较少用到的参数,象有关文件压缩的信息和图象的物理维
数。DIB文件的扩展名一般是“.BMP”,有时也可能是“.DIB”。
    因为DIB在Windows编程中的应用极其广泛,DirectX SDK已经包含了许多相关的
函数。例如,DirectX SDK提供的ddutil.cpp文件中有一个函数,它将Win32和DirectX
函数结合在一起,概念是把一个DIB文件装入DirectX表面,代码如下:
extern "C" IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd,
    LPCSTR szBitmap, int dx, int dy)
{
    HBITMAP             hbm;
    BITMAP              bm;
    DDSURFACEDESC       ddsd;
    IDirectDrawSurface *pdds;
    //  This is the Win32 part.
    //   Try to load the bitmap as a resource, if that fails, try it as a file.
    hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap,
                             IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION);
    if (hbm == NULL)
        hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy,
                                 LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    if (hbm == NULL)
        return NULL;
    // Get the size of the bitmap.
    GetObject(hbm, sizeof(bm), &bm);
    // Now, return to DirectX function calls.
    // Create a DirectDrawSurface for this bitmap.
    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    ddsd.dwWidth = bm.bmWidth;
    ddsd.dwHeight = bm.bmHeight;
    if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
        return NULL;
    DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
    DeleteObject(hbm);
    return pdds;
}

1.2、绘图表面(Drawing Surface)
    绘图表面接受视频数据并将其作为图象显示出来。在大多数的Windows应用程序中,
你可以使用Win32的函数如GetDC来访问绘图表面。GetDC获取设备上下文DC(Device
Context),
获得了设备上下文后,就可以重画表面了。然而,Win32的图象函数是由GDI提供的。
GDI是系统的一部分,它提供了抽象层,使得标准的Windows程序向表面绘图。
    GDI的缺点是它并不是为高性能的多媒体软件设计的,它主要用于商业软件如
字处理和电子表格软件。GDI提供了对系统内存中的视频缓冲区的访问,但不提供
对视频内存的访问。尽管GDI对于大多数的商业软件非常合适,但对于多媒体应用
程序和游戏软件则显得太慢了。
    另一方面,DirectDraw 能提供表征真实视频内存的绘图表面,这就意味着当你
使用DirectDraw 时,你能够直接向视频内存写数据,使得图象的显示速度足够快。
这些表面表征为连续的内存块,使得寻址时更加容易。

1.3、位块传输Blit
   Blit是“Bit Block Transfer”的简写,表示位块传输。它是将内存中一个地址
的一块数据传送到另一个地址的一种方法。位块传输经常用于精灵动画中。你可以
使用IDirectDrawSurface3::Blt 方法和IDirectDrawSurface3::BltFast方法来执行
位块传输。

1.4、页翻转(Page Flipping)和后台缓冲(Back Buffering)
    页翻转是多媒体、动画、游戏软件中的关键。软件页翻转是对卡通画家使图象
运动的过程的模拟。例如,画家在一张纸上画了一个人物,然后将其置于下一帧的
工作状态,对于每一帧,只很少地改变人物图象。当你快速翻转纸片时,连续的人
物图象看起来就成了动画。
    软件中的页翻转类似于上述的过程。首先,你建立了一系列DirectDraw表面,
这些设计好的表面准备“翻转”到屏幕。第一个表面被看作是主表面(Primary Surface)

在主表面后的所有表面都称为后台缓冲区。应用程序将数据写向后台缓冲区,然后
翻转主表面,于是后台缓冲区就显示在片面上了。当系统正在显示图象时,程序就
可以向后台缓冲区写数据,这个过程一直持续到动画的结束,它使你快速而高效地
将离散的图象变成动画。 DirectDraw可以利用相对简单一些的双缓冲区(一个主表
面和一个后台缓冲区),也可以使用较复杂的技术,加入其它的后台缓冲区。使得你
能够容易地建立页翻转的程序。

1.5、矩形(Rectangle)
    贯穿DirectDraw和Windows编程的一个最重要的概念是表面上的对象──有界矩形。
一个有界矩形由两个点来确定,即左上角和右下角。当以位块传输的方式向屏幕写数据时,
大多数的应用程序都使用RECT结构来传送有关有界矩形的信息。RECT结构的定义如下:
typedef struct tagRECT {
    LONG    left;    // This is the top-left corner's X-coordinate.
    LONG    top;     // The top-left corner's Y-coordinate.
    LONG    right;   // The bottom-right corner's X-coordinate.
    LONG    bottom;  // The bottom-right corner's Y-coordinate.
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;

    其中left和top成员变量是矩形左上角的X、Y坐标的值,right和bottom是右下角
的X、Y的坐标值。

1.6、精灵(Sprite )
    许多视频游戏都使用了精灵。从最基本的意义上来讲,一个精灵就是在屏幕上
移动的图象。精灵画在一个表面上,覆盖在已有的背景上,合成后的图象被送到屏
幕上显示出来。

1.6.1、透明位块传输(Transparent Blitting)和Color Key
    精灵动画中的难点在于对非标准矩形的精灵的处理。因为位块传输函数是工作在
矩形方式下,你的精灵也必须放在一个矩形之中,而不管它在屏幕上是否矩形。
    精灵图象本身不是矩形的,但却包含在矩形区域中。当用位块传输将图象移动到
目的地时,矩形区域中不属于精灵的像素就被“透明”处理。程序员选择任意一种颜
色来创建精灵,这种颜色就被用来作为透明度“Color Key”。它是一种不常用的颜色,
程序员仅仅用于表示透明度或特定的颜色范围。
    使用IDirectDrawSurface3::SetColorKey方法,你可以为一个表面设定Color Key。
设置了Color Key后,调用 IDirectDrawSurface3::BltFast方法来使用已设好的
Color Key,而不管像素是否同该Color Key匹配。这种类型的Color Key是源 Color Key。
源Color Key禁止“透明”的像素写到目的地,这样,原来的背景像素就保留下来了,
使得精灵看起来就是非矩形的了并且精灵还可以在背景上移动。
    另外,你还可以使用一个Color Key来影响目的表面(目的Color Key)。目的
Color Key也是表面上的一种颜色,它用于指明像素是否可以被精灵所覆盖。

1.6.2、精灵和修补矩形(Sprite and Patch Rectangle)
    为了产生精灵运动的效果,你在将精灵画到新的位置之前还必须从背景上擦除旧的
位置上的精灵图象。当然,也可以重新调入整个背景再重画精灵,但这会大大降低动画
的质量。事实上,你可以保留精灵矩形的上一次的轨迹,仅对该位置重画。这种方法称
为“修补”(Patching)。为了修补精灵旧的位置,可以利用原始背景图象(已经调入
到一个屏外表面)的一个拷贝来重画这一位置。在这个过程中使用的是位块传输方法,
在整个表面的循环中进行,需要耗用的处理时间很少。下面是这一过程的简单步骤:
(1). 设置精灵上一次位置的修补矩形
(2). 使用位块传输将屏外表面中的背景图象的主拷贝补到该位置
(3). 更新精灵是目的矩形,它反映了精灵新的位置
(4). 将精灵位块传输到背景上最新更新的矩形位置
(5).重复
    将DirectDraw提供的强大的图象功能同直线式的C/C++程序结合起来,利用上面的步
骤,马上就可以创建一个简单的精灵动画。

1.6.3、边界检查和碰撞检测(Bounds Checking and Hit Detection)
    在精灵动画中,边界检查和碰撞检测是两个非常车间而又相当重要的任务。边界是限
制精灵活动的范围,边界检查就是通过RECT结构来检查精灵的位置,判断精灵是否超出
了限定的范围。碰撞检测就是检查多个精灵是否占用了同一个位置。大部分的碰撞检测是
检查各个精灵的矩形之间是否有所覆盖。

--
※ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.1.3]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店