DirectDraw 对象
DirectDraw 对象是 DirectDraw 应用程序的核心 . 它是你在建立 DirectDraw 应用程序时所要创建的第一个对象 , 再用它来 创建所有其它相关的对象 . 通 过调用 DirectDrawCreate 函数可以 创建一个 DirectDraw 对象 . DirectDraw 对象通过 IDirectDraw ( 移 动 版本 仅 支持 这 个 ) , IDirectDraw2 , 和 IDirectDraw4 接口 为开发者提供其函数性 .
DirectDrawSurface 对象
DirectDrawSurface 对象 , 通常 简称为 " 页面 (Surface)", 代表了内存中的一 块区域 , 它存 储了可以显示在显示器上的图象数据 . 通 过调用 DirectDraw 对象的 IDirectDraw4::CreateSurface 函数可以 创建一个与该 DirectDraw 对象相关联的页面 . DirectDrawSurface 对象通过 IDirectDrawSurface( 移 动 版本 仅 支持 这 个 ) , IDirectDrawSurface2 , IDirectDrawSurface3 , 和 IDirectDrawSurface4 接口 为开发者提供其函数性 .
DirectDrawSurface对象和DirectDraw对象什么区别?DirectDraw对象,我们知道是表示整个显示系统,也就是你的 显卡和显屏构成的那个系统,你能在显示器屏幕上直接画点东西吗?不行,显屏上的东西是通过显存和内存操作把里面的东西显示出来,那么相对应于显屏,内存中 就应该有一张矩形白纸供你作画,然后才能把它在显屏上显示。那张白纸就是DirectDrawSurface对象,代表了显存或内存里的一个连续的线性的 数据区。这个数据区可以被代表显示硬件的DirectDraw对象所识别和确认。一般,可以创建的页面有4种,我们常用的有主页面 (primary surface)和离屏页面(offscreen plain)先说主页面,就是一块显存,在主页面中的图形会显示到屏幕中,直接在主 页面上操作会有个问题,数据一多,图象就会不连续,为此可以采用缓冲技术,即建立一个Back buffer(后台缓冲),说白了,就是在内存中再开辟一 块区域,和主页面的区域对应,这样就可以不直接操作主页面,先把数据写入到这里,然后通过换页成为可见。离屏页面不同了,它是和主页面一模一样的画面,但 是它永远不在屏幕上表现出来,通常被用来存储位图,用于将后来的位图图象Blit到主页面或后台缓冲上。
DirectDrawPalette 对象
DirectDrawPalette 对象 , 通常 简称为 " 调色板 (Palette)", 代表了一个可以 为页面所使用的 16 或 256 色的 调色板 . 它包含了一 组 RGB 值的索引 , 用来描述 页面上的像素所使用的颜色值 . 对于像素位深度大于 8 的 页面 , 不需要使用 调色板 . 通 过调用 IDirectDraw4::CreatePalette 函数 , 可以 创建一个 DirectDrawPalette 对象 . DirectDrawPalette 对象通过 IDirectDrawPalette 接口 为开发者提供其函数性 .
DirectDrawClipper 对象
DirectDrawClipper 对象,通常简称为 " 裁剪器 (Clipper)", 帮助开 发者使 Blit( 位 块传送 ) 操作限定在 页面的某一区域内 , 或不超出 页面的边界范围 . 通 过调用 IDirectDraw4::CreateClipper 函数可以 创建一个 DirectDrawClipper 对象 . DirectDrawClipper 对象通过 IDirectDrawClipper 接口 为开发者提供其函数性 .
当 硬件抽象 层 (HAL) 不支持某种特性 时 , DirectDraw 会 试图进行软件仿真 . 仿真的函数是由 硬件仿真 层 (HEL) 提供的 . HEL 与 HAL 一 样 , 代表了 DirectDraw 的特性 . 很 显然 , 软件仿真不能与硬件所提供的特性等效 . 可以 调用 IDirectDraw4::GetCaps 函数以 查询硬件支持什么特性 . 在 应用程序初始化的时候检查这些特性 , 你可以 调整应用程序的参数以提供优化的性能 .
下 图展示了 DirectDraw, 图形设备接口 (GDI), 硬件抽象 层 (HAL) 和硬件仿真 层 (HEL) 四者之 间的关系 .
DirectDraw 核心
这一部分讨论 DirectDraw 的主要核心内容 . 相关信息被 组织为如下几组 :
DirectDraw 对象 (The DirectDraw Object)
1. 控制 级描述了 DirectDraw 是怎 样与显示设备相互作用的 , 它如何 对系统事件产生反应 . 使用 IDirectDraw4::SetCooperativeLevel 函数可以 设置 DirectDraw 的控制 级 . 最主要的是 , 你使用 DirectDraw 控制 级来决定你的应用程序是运行于全屏模式 ( 具有独占的 访问视频内存的特性 ), 还是运行于窗口模式 . 任何存在的 页面都应该通过调用 IDirectDrawSurface4::Restore 或 IDirectDraw4::RestoreAllSurfaces 来恢复 , 这样它们的内容将在显示之前被重新装载 .
2. 有两种 显示模式 : 调色板式和非调色板式 . 对于调色板式显示模式来说 , 每一个像素的 颜色值是以一个相关调色板的索引值来代表 . 显示模式的位深度决定了调色板中可容纳的颜色数量 . 举例来说 , 在 8 位的 调色板显示模式中 , 每一个像素的 值从 0 到 255, 该调色板可容纳 256 个 颜色入口 . 非 调色板式显示模式 , 就象它的名称所表示的那 样 , 不需要使用 调色板 . 在 这种显示模式下 , 像素的位深度 为 16,24 或 32, 每个像素分别占用 2 字 节 ,3 字 节或 4 字 节 , 用来描述像素的真 实颜色 .
3. DirectDraw 允 许一个进程在需要的时候 , 可以任意多次的 调用 DirectDrawCreate 函数 . 每次 调用后 , 返回一个唯一的与 设备无关的接口 . 每一个 DirectDraw 对象可以随心所欲的使用 , 在 对象与对象之间没有相互依赖的关系 . 每个 对象的行为就象它是由一个唯一的进程创建的 . 因 为 DirectDraw 对象之间是不相互依赖的 , 由一个特定的 DirectDraw 对象创建的 DirectDrawSurface, DirectDrawPalette 和 DirectDrawClipper 对象不应该与其它的 DirectDraw 对象一起使用 , 因 为这些对象会在它的 DirectDraw 对象销毁时而自动被释放 . 如果它 们与其它的 DirectDraw 对象一起使用 , 调用它们的函数将在它们被销毁时退出 .
4. DirectDrawSurface 对象 , 代表了内存里的一个 连续的线性的数据区 . 这个数据区可以被代表显示硬件的 DirectDraw 对象所识别和确认 . DirectDrawSurface 对象代表了一个通常是驻留在显存内的页面 , 如果 显存被用完或被明确地指定它也可以存在于系统内存里 . 调用 IDirectDraw::CreateSurface 函数可以 创建若干类型的 DirectDrawSurface 对象 , 包括 单页面对象 , 复杂页面 (complex surface) - 换页链 , 或三 维页面 . CreateSurface 函数 创建我们所请求的页面或换页链 , 并且返回指向 主页面 (primary surface) 的 IDirectDrawSurface 接口的指 针 .
主 页面 代表的是在 显示器的当前可见屏幕 , 它在 页面描述中具有 DDSCAPS_PRIMARYSURFACE 标志符 . 对于每一个 DirectDraw 对象来说 , 你只可能 拥有一个主页面 . 在移 动 版本中, 仅 支持一个后台 缓 冲 页 面,复 杂页 面 ( 含有多个后台 缓 冲 页 面 链 ) 的形式是不被支持的。 实现 方式是 这样 的,先 创 建一个主 页 面,然后在 该 主 页 面 对 象上 调 用 EnumAttachedSurfaces() 来 绑 定一个后台 缓 冲 页 面用于将来的 flip 操作。离屏 页面 (DDSCAPS_OFFSCREENPLAIN) 通常被用来存储位图 , 用于以后将位 图图象 Blit 到主 页面或后台缓存上 . ( 移 动 版本不支持 )
DirectDraw 里的任何 页面都可以构造为换页页面 (flipping surfaces) . 一个 换页页面是位于内存里的任何一个可以在 前台缓存 (front buffer) 和 后台缓存 (back buffer) 之 间交换的页面 , 这个换页环境就是我们所称的 换页链 (flipping chain) . 在移 动版本 中, 实际 上只存在两个 页 面用于 flipping 操作。当你 调用 IDirectDrawSurface::Flip 函数以 请求一次换页操作 , 指向主 页面和后台缓存的 指针相互交换 ( 只改 变了页面的指针 , 数据并未 实际移动 ). 这就是说 , 换页的操作 , 是通 过交换显示设备用来代表页面内存的指针 , 而不是通 过相互复制页面的实际内存来完成的 .( 当 显 存不足 时 情况就不同了 ) 实际上 每 经历 一次 flip 操作以后主 页 面与后台 缓 存的 页 面指 针 都会互 换 ,上一次刷新前的后台 页 面 变 成了新的主 页 面。只要在每次 update frame( 用 Timer 实现 ) 的循 环调用中进行如下操作: 1) 后台页面对象 ->GetDC(&hdc) 并更新内容 2) 主页面调用 flip() 来显示后台页面的更新结果,并把当前主页面变成后台页面等待下一次的更新操作。
附 录
常用 DirectDraw 接口
在通过 DirectDrawCreate 创建好 DirectDraw 对象实例以后,就可以通过调用合适的接口函数来管理他们,以下是一些主要的接口。
1. IDirectDraw
应用程序使用 IDirectDraw 接口的方法来 创建 DirectDraw 的各种 对象,并且与系统层变量一起工作。以下是一些该接口的常用函数参考。
控制 级 | |
| |
创建对象 | |
| |
| |
设备特性 |
2. IDirectDrawClipper
应用程序使用 IDirectDrawClipper 接口的函数来管理 裁剪表 (clip list) 。 以下是该接口的函数参考。
分配内存 | |
裁剪表 | |
| |
| |
| |
窗口句柄 |
|
3. IDirectDrawPalette
应用程序使用 IDirectDrawPalette 接口的方法来 创建 DirectDrawPalette 对象,并使其与系统层变量协同工作。以下是该接口的函数参考。
分配内存 | |
调色板特性 | |
调色板入口 | |
|
|
4. IDirectDrawSurface
应用程序使用 IDirectDrawSurface 接口的方法来 创建 DirectDrawSurface 对象,并且与系统层变量一起工作。这部分是关于该接口方法的参考。
分配内存 | |
| |
| |
隶属 页面 | |
| |
| |
| |
位 块传送 | AlphaBlt |
| BltBatch ( 移 动 版本没有 ) |
| BltFast ( 移 动 版本没有 ) |
| |
关 键色 | |
| |
设备环境 | GetDC --> 得到 GDI 设备环境句柄 (HDC) |
| |
换页 | |
| |
页面性能 | |
页面裁剪 | |
| |
页面描述 | |
| |
| |
| |
| |
页面调色板 | |
|
常用 DirectDraw 对象结构
1. The DDCAPS structure represents the capabilities of the hardware exposed through the DirectDraw object. This structure contains a DDSCAPS structure used in this context to describe what kinds of DirectDrawSurface objects can be created.
2. The DDSCAPS structure defines the capabilities of a DirectDrawSurface object. This structure is part of the DDCAPS and DDSURFACEDESC structures.
3. The DDSURFACEDESC structure contains a description of a surface. This structure is passed to the IDirectDraw::CreateSurface method.