directdraw:动画程序编写——DirectDraw的旅(1)



DirectDraw——也许大多数人闻所未闻但当提到 DirectX 恐怕每个 游戏爱好者都再熟悉不过了,但是只知道那是个很多游戏都要求必须安装,再多就无从所知了,那么它到底能为我们游戏干什么呢,其实它又叫 Game SDK它最大特点是直接对硬件抽象层(HAL)进行操作利用 此特点可制作出高性能Windows游戏
http://www. microsoft.com/directx/default.asp DirectDraw就是DirectX56个组件的DirectX5其它5个组件分别是:

Direct3D 提供了3D硬件接口
DirectSound 立体声和3D声音效果同时管理声卡内存
DirectPlay 支持开发多人网络游戏并能处理游戏中网络的间通信问题
DirectInput 为大量设备提供输入支持
DirectSetup 自动安装DirectX驱动

而DirectDraw则是DirectX基础DirectX其它组件都是建立在它基础的上DirectDraw使用页面切换思路方法实现动画它不仅可以访问系统内存还可以访问显示内存这是以往Windows员所不能(例如:如果你是用MFC中CDC类进行绘图,那么它是绝对不会让您直接访问显存) 另外我们利用DirectDraw还可以生成、移动、剪切、转换、合成图像数据从而编写出各种“炫丽多彩”图形应用

您先不要急,我们会在后面附上本文介绍动画原代码,只要将其用vc打开,进行工程编译创建后,您就会立刻看到效果并且我们在工程文件中有详细中文注释,力求将理论和实战紧密联系在

首先让我们先了解下DirectDraw 3个重要概念——表面、Bltting、色彩键码

1.表面

在用DirectDraw编写时,我们先要创建若干个图形数据缓冲区并把这些图形数据装入其中再进行转换、拉伸、挎贝等操作并且还可以显示这些缓冲区中图形数据这些缓冲区就称为表面

表面可以分为几类

主表面(primary surface)是用户在屏幕上可以看到它是显示内存部分所有DirectDraw都有主表面而且只有它在DirectDraw表面对象的前就已经存在了因此不能改变它尺寸、格式和位置

主表面有个很重要特性——翻页(flip)页面翻页用于可以产生相当平滑、不闪烁动画个可以翻页主表面实际上是两个表面个是可见个是不可见不可见表面称为后备缓冲区当发生表面翻页时后备缓冲区就成为可见而以前可见主表面则成为后备缓冲区 下面我们用图示来向您解释上面概念:

\" width=468>

当翻页后,将原后备缓冲区页中内容copy入可见主表面页,而同时将原可见主表面页内容copy入后备缓冲区页

显示器屏幕虽然每秒中刷新很多次在此我们假定为85次但每次都是遍地读取可见主表面中存储显示页信息而你对后备缓冲区改动不会显示出来并且也不会影响可见主表面显示而只有当施行翻页操作后两页内容互换而你已经完成了在原后备缓冲区改动才会显示在屏幕上而这个互相拷贝过程几乎是瞬间完成这个时间比起每次刷新所用时间少得多得多两者几乎差了几乎几十万个数量级而人眼是根本察觉不到所以用这种思路方法可以不闪烁平滑优质动画效果

还有种表面叫离屏表面(off_screen surface)它是不能直接见到离屏表面作为存储缓冲区有助于表面的间互相切换大小是可以改变

主表面和离屏表面都分为有调色板和无调色板这两类像素深度为8位(256色)表面称为有调色板表面;而像素深度为16位(64K色)、24位(16M色)像素表面称为无调色板表面它们存储实际色彩值(RGB值)

在本文下面我们先使用256位表面即有调色板表面

2. Bltting

Bltting是用于复制图形语言可以将图像从处拷贝到另例如大家所熟悉CDC类(设备描述表类)BitBlt就是具有这样功能

在DirectDraw中典型blt操作是将离屏表面内容拷贝到个后备缓冲区blt操作个源表面和个目标表面把源表面内容拷贝到目标表面中不仅可以整体拷贝源表面而且还可以拷贝源表面内任何矩形区域到目标表面任何位置blt还支持透明拷贝就是指表面中像素在blt过程中可以不予以拷贝而这个像素值是由色彩键码(DDCOLOR KEY )决定如图:



\" width=430>

DirectDraw中有 3个支持blt它们是

Blt
BltBatch
BltFast



Blt( )用得最多BltFast速度比Blt要快但功能却很有限例如不支持拉伸、剪切等操作

还有BltSurface它是DirectWin类个成员Blt、BltFast更具有适应性并且使用起来更加简单例如当我们把源表面拷贝到目标表面外时需要裁剪而BltFast不支持裁剪这时我们使用BltSurface它在内部使用Blt和 BltSurface并根据情况自动执行裁剪

在此有人会问这种页面切换思路方法到底好在那里?它到底和用绘图思路方法区别在什么地方?而其它绘图思路方法为什么会使屏幕闪动呢?下面我们举 2个例子:(我们仍然用图示思路方法给您个直观解释)

(1) 在些绘图中您会发现其用到了清屏这种方式是使屏幕效果最差这种思路方法使得没有直接从第个画面切换到第 2个画面而是先用黑色将图形数据缓冲区清空并且还显示在屏幕上但这个时间很短如果反复清屏则会产生严重屏幕闪烁如下图:


\" width=532>

(2)在中用异或方式进行绘图即先在屏幕上画出第个图像然后在画第 2个图像的前再在屏幕上画遍第个图像这样起到清除第个图像效果如果您仔细看会发现这样就会比上个思路方法画面效果好得多但这并不是很完美如果反复使用虽然不会产生全屏幕闪动但在所清除图像处会产生闪烁究其根本原因还是因其没能直接从第个画面切换到第 2个画面如下图:

\" width=458>

我想现在您应明白DirectDraw绘图优势了吧其实这就是对上述思路方法中缺点很好解决思路方法

3.色彩键码

DirectDraw 可以把某种颜色或某个范围颜色指定为个颜色值这个颜色值是由DDCOLORKEY结构即色彩键码介绍说明DDCORLORKEY结构介绍说明如下:

typedef struct _DDCOLORKEY
{
  DWORD dwColorSpaceLowValue; //颜色范围低端
  DWORD dwColorSpaceHighValue; //颜色范围高端
} DDCOLORKEY;

当我们对表面进行拷贝操作时,表面中哪些像素不被拷贝是由色彩键码决定例如当DDCOLORKEY结构两个分量都为零时表面内所有置为零像素都不能被拷贝又例如当表面是24位RGB模式时若想指定RGB=(120120120)像素不被拷贝则应该:

DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue=RGB(120,120,120);
ddck.dwColorSpaceHighValue=RGB(120,120,120);
surf→SetColorKey(DDCKEY_SRCBLT,&ddck);

其中SetColorKey是把色彩键码赋给表面surf这样在对表面surf blt操作期间RGB值为(120,120,120)像素不能被拷贝

OK我们现在已经具备基本DirectDraw知识下面我们就来进行实战演练(未完待续......)



Tags:  directdrawerror directdraw不可用 directdraw加速 directdraw

延伸阅读

最新评论

发表评论