Delphi中使用DirectDraw技术进行图形处理.doc_第1页
Delphi中使用DirectDraw技术进行图形处理.doc_第2页
Delphi中使用DirectDraw技术进行图形处理.doc_第3页
Delphi中使用DirectDraw技术进行图形处理.doc_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Delphi中使用DirectDraw技术进行图形处理DirectDraw是一套名为DirectX复杂工具的一部分,DirectX是由许多不同的技术组成,比如:DirectDraw、Direct3D、DirectSound、DirectPlay、DirectInput和DirectSetup等。其中的每一种技术都是集中了几种处多媒体的技术或游戏的技术,像声音播放、3D图形、网络播放、硬件设备如鼠标和强制反馈等等。不过,在本章中将只介绍DirectDraw,并且这个主题很容易就会占用一章或更多的章节关于DirectX的其他技术内容,读者可以去参阅其他关于DirectX的书籍。 DirectDraw程序要求用户的系统必须有DirectDraw运行时的DLL,这些运行时文件(实际只是DLL的集合,可能许多机器已经安装了),还可以从Micorsoft的Web站点获取;该站点有各种各样的产品,包括游戏、Windows 98、将来的操作系统Windows NT 5等。如果读者正在使用的是Windows NT 4,那么至少要用Service Pack 3(SP3)去升级,之后才能够访问作为SP3一部分的DirectDraw 3。不要试图直接在Windows NT系统下安装运行时的DirectDraw,而应该安装最新的补丁(Service Pack),直接安装运行时的DirectDraw是针对Windows 95/98系统而言的。确定一个系统是否安装了DirectDraw的一个方法是查看Windows/System或Winnt/System32目录是否存在DDRAW.DLL和DSOUND.DLL,如果有,则说明系统已经安装了DirectDraw。 在可能的情况下,读者应该从Microsoft获取DirectDraw SDK,通常它可以从Microsoft的Web站点下载得到,不过请注意,它至少有30M。安装了SDK后,它在硬盘上创建一个名为DXSDK的目录,在这个目录之下是SDK目录,其中包含有各种各样的文档、用C/C+编写的示例文件和帮助文件。另外,还可以直接从Microsoft得到SDK,在有些特殊情况下,SDK可能是作为MSDN的一个部分而打包发行的;Microsoft出版的Inside DirectX一书也有DirectX SDK。 ssDirectDraw是一套名为DirectX复杂工具的一部分,DirectX是由许多不同的技术组成,比如:DirectDraw、Direct3D、DirectSound、DirectPlay、DirectInput和DirectSetup等等。这其中的每一种技术都是集中了几种处多媒体的技术或游戏的技术,像声音播放、3D图形、网络播放、硬件设备如鼠标和强制反馈等等。不过,在本章中将只介绍DirectDraw,并且这个主题很容易就会占用一章或更多的章节关于DirectX的其他技术内容,读者可以去参阅其他关于DirectX的书籍。 DirectDraw程序要求用户的系统必须有DirectDraw运行时的DLL,这些运行时文件(实际只是DLL的集合,可能许多机器已经安装了),还可以从Micorsoft的Web站点获取;该站 点有各种各样的产品,包括游戏、Windows 98、将来的操作系统Windows NT 5等。如果读者正在使用的是Windows NT 4,那么至少要用Service Pack 3(SP3)去升级,之后才能够访问作为SP3一部分的DirectDraw 3。不要试图直接在Windows NT系统下安装运行时的DirectDraw,而应该安装最新的补丁(Service Pack),直接安装运行时的DirectDraw是针对Windows 95/98系统而言的。确定一个系统是否安装了DirectDraw的一个方法是查看Windows/System或Winnt/System32目录是否存在DDRAW.DLL和DSOUND.DLL,如果有,则说明系统已经安装了DirectDraw。 在可能的情况下,读者应该从Microsoft获取DirectDraw SDK,通常它可以从Microsoft的Web站点下载得到,不过请注意,它至少有30M。安装了SDK后,它在硬盘上创建一个名为DXSDK的目录,在这个目录之下是SDK目录,其中包含有各种各样的文档、用C/C+编写的示例文件和帮助文件。另外,还可以直接从Microsoft得到SDK,在有些特殊情况下,SDK可能是作为MSDN的一个部分而打包发行的;Microsoft出版的Inside DirectX一书也有DirectX SDK。 在介绍代码的运作方式之前,我们将花一点时间说说双缓冲的有关内容。这项技术的思路是尽可能模仿胶片电影的基于帧的技术,即双缓冲只是以足够快的速度将一系列的静 止画面显示出来从而使用户产生流畅动画的感觉。 说得详细点儿,程序员所做的是先在屏幕偏移缓冲区中构造一幅图,然后把它显示在观 众面前;当观众全神贯注于当前这幅图时,程序员接着构造另外一幅场景图,然后用这 幅场景图取代先前的那幅图显示到屏幕上。比如,开始用第一帧在屏幕的最左端显示一 个球;然后,只要把球从左到右每一帧移动几个像素就可以产生运动的效果,位置上的 每一个小的改变,只需要用一幅新图去更新屏幕;程序员实际只是显示球的一些的静止 图片,但观众却得到“受骗”后的感觉:看到了动画。 刷新屏幕的平均速度是每秒大约25帧,这个速率已经足够快,以至人眼根本感觉不到单 独一帧的存在,相反地,只是觉得看到的是真正的动画。如果以25帧/秒的速率从屏幕左 边移动球到屏幕右边,观众就会认为它们看到的不是球的一系列静止画面,而是球真正地在空间运动。根据程序员编写的代码的质量的好坏,DirectX是能够实现高于25帧/秒 的速率的。 我们也许该说这么件事:当我们最初开始创建动画时认为,建立一个完全的缓冲区然后 再把缓冲区的内容显示到屏幕上是愚蠢的作法,这完全是不必要的操作;我们那时决定 想办法直接写屏,修改前后两帧不同的地方,避免资源的无谓开销。 后来证明,我们的方法不一定完全行得通,尤其是在想创建出相对复杂一点的效果时。 很多情况下,直接写屏所作的修改很难瞒过用户的眼光;剔除屏幕上的某一块区域、然 后绘制上下一帧的显示内容,这个操作产生的是显而易见的蹩脚的拼凑效果,即使使用 了尽可能有效的作法,效果也得不到改善。这样的操作应该使用用户看不见的后台缓冲 区(back buffer),然后用整个缓冲区的内容取代原来屏幕的显示,这时,用户看到的 是就是一幅完整的构图而不会是拼凑的效果。 DirectDraw子系统会确保在屏幕刷新时同步执行页面交换操作。我们还从来没碰上谁真 正看到了72MHz的屏幕刷新率。如果一幅画以那种速率刷新的话,那么在向屏幕刷新显示 时,用户根本不能觉察到两次刷新的片刻闪烁。 我们还有些担心:不管我们说什么,一些读者还是想尝试在用户的目光注视下直接写屏 修改屏幕上的某些区域。尽管在某些情况下这可能行得通,但是,更多的时候还只能先 在缓冲区里构图,然后直接“贴”到屏幕显示给用户,这样才能够获得好的效果。如果 读者真要尝试直接写屏,尽管去尝试;不过,到走进死胡同时,不妨回过头来尝试双缓 冲,你会惊喜地发现它在解决看似棘手问题的快速性和有效性。 DirectDraw允许程序员创建一个后台缓冲区(back buffer),向缓冲区绘制图形,然后 把它交换到可见视频内存,再由可见视频内存显示到屏幕上。假定是在独占模式下,拥 有足够的视频内存来把主表面(primary surface)和后台表面(back surface)都装入 视频RAM,那么页面交换操作就不再是一个复制的过程;相反的,它只要简单地改变一下 被视频卡可见内存引用的内存块的地址就可以了。也就是说,当执行页面交换操作时, 内存中只有四个字节的内容需要改变,而其它内容都不变;这唯一需要做的改变就是: 改变指向当前活动视频页的指针,该指针存放在内存的四个字节中。因此,该操作速度 很快;另外,它还能保证与显示器的刷新操作同步发生。这样,使用DirectDraw就可以 实现非常平滑的动画。 DirectDraw和别的DirectX技术尽最大的努力为程序员提供一套高级的、完善的视频例 程;比如3D例程尽可能利用硬件来实现超快速的操作。然而,许多视频卡或别的硬件设 备并不能提供程序员所希望的全部功能,在这种情况下,DirectX将试图从软件上仿真硬 件缺少的功能。 到底软件能提供何种功能、硬件又能提供何种功能,这整个的问题是一个相当技术化的主题,大大超出了本书的范围。但是,可以在特定的系统上运行Microsoft SDK所带的D irectX Viewer(DirectX浏览器)来查看DirectDraw的状态,该浏览器通过执行一系列的DirectX的功能例程来报告特定系统上各种各样多媒体硬件的状态;还可以在运行时刻亲自查询这些子系统,不过这个内容在本书中我们只是稍微介绍一点儿。 到现在为止,所应清楚的一点是:DirectX的一些功能在硬件中执行,而其余部分由软件仿真完成。仿真功能是由一个名称看起来有些奇怪的子系统来处理的,它就是HEL,即Hardware Emulation Layer (硬件仿真层);而程序中非仿真的部分由另一个名称看起来更奇怪的子系统处理:HAL,即Hardware Abstraction Layer(硬件抽象层)。HEL和HAL处理所有DirectDraw的各种操作;它们的驱动程序使得DirectDraw成为可能。 可以应用HEL和HAL中的任意一个来初始化DirectDraw;不过,这是一个非常高级的功能 ,即使在以后的课程中用到很苛刻的性能测试时都可能用不着调用它。 在初始化DirectDraw的实例后,下一步就是设置合作层次(cooperative level): hr : = FDirectDraw.SetCooperativeLevel(Handle, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN); 这些代码把CooperativeLevel设置成全屏独占模式,这样,编写的程序将占据整个屏幕 ,不许别的窗口覆盖它,除非通过按Ctrl+Alt+Tab组合键从程序中显式地把该窗口从视 频缓冲区移走。也可以把合作层次初始化成DDSCL_NORMAL,它是一个窗口模式。我们现 时将略过该模式,因为它在某些方面比独占模式复杂得多。 在独占模式下,应用程序可以选择分辨率及色深,像下面这样: hr : = FDirectDraw.SetDisplayMode(640, 480, 8); 这行代码把屏幕的分辨率设置为640480,8位色深(就是说至多可以显示256色)。 直到最近,选择比这更高的分辨率和色深还是没有结果的。要保持一幅640480的屏幕 的单个拷贝需要大约300KB的空间,也就是说,需要600KB的空间来保持一个屏幕拷贝及 其后台缓冲区;这是期望从大多数系统得到的最大空间了,所以要获取更高分辨率通常 是不可行的。现在,事实上有些视频卡在更高的分辨率下能够提供相当好的性能,但对 大多数人来说,还得指望一阵子。正因为这样,所以我们一直使用这相对简单的分辨率 ,尽管它意味着要学会使用调色板。 设置了合作层次和屏幕分辨率后,下一步是获取两个表面,以便在表面之间进行页面交 换。换句话说,要创建一个指针指向用户注视的视频内存,也指向后台缓冲区(以便为 双缓冲或者说页面交换使用)。可以如下进行:SurfaceDesc.dwSize := sizeof(SurfaceDesc); SurfaceDesc.dwFlags := DDSD_CAPS or DDSD_BACKBUFFERCOUNT; SurfaceDesc.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or DDSCAPS_COMPLEX; SurfaceDesc.dwBackBufferCount := 1; hr := FDirectDraw.CreateSurface(SurfaceDesc, FPrimarySurface, nil); if (hr = DD_OK) then begin / Get a pointer to the back buffer ddscaps.dwCaps := DDSCAPS_BACKBUFFER; hr := FPrimarySurface.GetAttachedSurface(ddscaps, FBackSurface); if (hr = DD_OK) then begin PaintSurfaces; Exit; end; end; 这段显然非常不直接的代码创建了主表面和后台表面,主表面存放显示给用户看的内容,后台表面存放的是当调用DirectDraw的Flip函数来实现双缓冲时要通过页面交换操作显示到主表面的内容。 下面是DDSCaps的结构: TDDSCaps = record dwCaps: DWORD;/需要的表面功能 end; 这个结构初看起来相当简单,但稍微观察一下就会发现它实际上很复杂。事实上,DDSCaps和SurfaceDesc结构都有几乎令人绝望的复杂的结构,这些结构来处理一大堆常量。 为了避免在描述它们时让我们和读者发疯,我们提示只要用DirectX SDK的在线帮助查看一下这些常量参数即可。比如,DDSCaps结构的一个名为dwCaps的字段就有30来个可能的常量,其中的很多解释起来都很复杂。 下面是TDDSurfaceDesc结构的定义: TDDSurfaceDesc = record dwSize: DWORD; / size of the DDSURFACEDESC structure dwFlags: DWORD; / determines what fields are valid dwHeight: DWORD; / height of surface to be created dwWidth: DWORD; / width of input surface lPitch: Longint; / distance to start of next line (retu rn value only) dwBackBufferCount: DWORD; / number of back buffers requested case Integer of 0: (dwMipMapCount: DWORD; / number of mip-map levels requested dwAlphaBitDepth: DWORD; / depth of alpha buffer requested dwReserved: DWORD; / reserved lpSurface: Pointer; / pointer to the associated surfacememory ddckCKDestOverlay: TDDColorKey; / color key for destination overlay use ddckCKDestBlt: TDDColorKey; / color key for destination blt use ddckCKSrcOverlay: TDDColorKey;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论