DirectDraw中的基本图形概念   作者:阮象华

类别:VC语言 点击:0 评论:0 推荐:
DirectDraw中的基本图形概念   作者:阮象华   发布时间:2001/06/06   文章摘要:   本文简介了DirectDraw下的图形程序。所有的介绍都是非技术性的深入浅出的,以DirectDraw如何支持的部分特性为向导。         正文:   DirectDraw中的基本图形概念

   如果你熟悉Windows下C及C++编程,那你就不难消化这部分内容。当你阅读完这部分内容,你就有了一个坚实的DirectDraw基本图形概念。共分以下几部分:
  o 与设备无关位图 (Device-Independent Bitmaps)DIB
  o 绘制平面
  o 块图形移动
  o 交换页和屏后缓冲
  o 矩形


1 设备无关位图

  Windows及DirectX都使用与设备无关位图(DIB)作为其原始图形格式。本质上,一个DIB文件就是包含描述图象的尺寸,使用多少色彩,描述这些色彩的参数,每一像素的描述数据。另外,一个DIB还包含一些基本参数如:压缩信息,有效色(如果没有使用),及物理尺寸(如打印输出到尾部)。DIB通常以BMP为扩展名,有时也使用DIB为扩展名。
  因为DIB在Windows程序中应用广泛,操作系统SDK已经包含许多函数操作DIB你可与DirectX一起使用。例如:以下例程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;
//
// 这是Win32部分
// 试图读取一个Bitmap(位图)
// 如果失败,用文件代替
//
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;
//
// 获取位图的尺寸
//
GetObject(hbm, sizeof(bm), &bm);
//
// 现在回到DirectX函数调用
// 为该位图创建一个DirectDrawSurface(平面)
//
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;
}
要获得DIB的详细内容参见WIN32SDK。
2 绘制平面
  绘制平面接收数据将图象显示到屏幕(位图)。在大多数Windows程序中都要通过Win32函数来创建绘制平面例如GetDC,用来获取设备句柄(DC)。当你获得设备句柄后,你就可向屏幕输出。不管怎样,Win32的图形函数是系统另一部分提供的,图形设备接口(GDI)。GDI是为Windows应用程序提供一个图形输出的抽象层。
  对GDI来说最不利的就是对于多媒体来说它不是高度优化的。它是用来制作商用程序如WORD或电子表格。GDI能操作系统内存,而不是显存,也无法发挥硬件所提供的特性。简言之,GDI对大多数商业软件已足够,但性能太差无法满足多媒体及游戏软件。
  另一方面,DirectDraw能让你绘制平面来显示显存中的内容。这意味着当你使用DirectDraw,你能直接操作显示卡的显存,使图形操作非常快。这些平面能反映对应的显存块,使寻址更容易。
详见平面。
3 块图形移动
  Blit术语是块移动(Bit Block Transfer),就是将一内存块从原地整块移动到其他地方。图形程序用Blit将图形从一内存块移动到其他地方。Blit通常用于小物体精灵(Sprite)的移动,将在以后讨论。详见DirectDraw的Blit和平面(Surface)的Blit。
4 交换页和屏后缓冲
  页交换是多媒体,动画,及游戏的关键。软件上的页交换就象画卡通的一叠纸。艺术家只要在每张纸上稍加修改,当你快速翻动时,它就动起来了。
软件页交换过程与此很象,当你设置许多DirectDraw平面,就象艺术家的纸一张一张的层叠,第一个平面称为主平面,而后面的平面称为屏后缓冲。你的程序事先修改屏后缓冲的图象,然后翻开主平面,屏后缓冲便显示出来了。当系统显示图象,你的程序继续写屏后缓冲。就这样不停继续,使你能高速高效显示动画。DirectDraw能使你简单实现使用页交换,如简单双缓冲(一个主平面一个屏后缓冲)或更多更复杂的多屏后缓冲。详见DirectDraw教程及平面交换。
5 矩形
  通过DirectDraw及Windows程序,屏幕上的对象都归于一个叫绑定矩形(Bounding Rectangles)的术语。在绑定矩形通常与屏幕平行,因此绑定矩形由两点决定,左上角及右下角。多数程序在Blit时使用RECT结构来设置绑定矩形的信息。RECT结构如下:
typedef struct tagRECT {
LONG left; // 这是左上角的X坐标。
LONG top; // 这是左上角的Y坐标。
LONG right; // 这是右下角的X坐标。
LONG bottom; // 这是右下角的Y坐标。
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;

  在上面的结构中,左面及上面的X,Y坐标是绑定矩形的左上角。同样,右面及下面的数是绑定矩形的右下角。下面的图片直观显示了该结构:

  出于效率,兼容,易用性,所有的DirectDraw的Blit函数都以绑定矩形来工作。不管怎样,你可使用自由Blit自行定义Blit。详见自由Blit。

本文地址:http://com.8s8s.com/it/it3429.htm