📄 chapter5.txt
字号:
●SetClipper()
●SetColorKey()
●SetOverlayPosition()
●SetPalette()
●SetSurfaceDesc()
●Unlock()
●UpdateOverlay()
●UpdateOverlayDisplay()
●UpdateOverlayZOrder()
1. 表面描述函数
我们首先讨论的个可用于检索表面自身信息的函数,它们是:
●GetCaps()
●GetPixelFormat()
●GetSurfaceDesc()
●SetSurfaceDesc()
同DirectDraw接口提供的GetCaps()函数一样,DirectDrawSurface接口提供的GetCaps()函数用于输出表征哪些特征可被表面支持的数据。该信息包括:表面是主表面还是离屏表面;表面使用的存储器定位于显示RAM还是系统RAM。
GetPixelFormat()函数在用于高彩和真彩表面时是非常重要的,这是由于像素格式因显示卡的不同而不同。该函数返回表征码,这些表征码表明每一种颜色部件是如何存储的。
GetSurfaceDesc()函数返回一个表面描述。该信息包括表面的宽度、高度和深度。表面像素格式(同样被GetPixelFormat()函数检索)也包含在其中。
SetSurfaceDesc()函数(对于DirectX5)来讲是新增的,只由DirectDrawSurface3接口提供)允许设定某些表面属性。该函数可用于指定表面使用的内存。这一点在设计定制表面存储器管理器策略时非常有用。
2。 表面Blt函数
DirectDrawSurface接口提供3个支持blt操作的函数:
●Blt()
●BltBatch()
●BltFast()
Blt()函数是一个主要函数。Blt()函数能够进行常规的blting(无特殊影响的简单的表面到表面的blt),同时支持延伸、旋转、镜像和颜色填充的操作。当用于同剪裁器关联的表面时,Blt()可进行剪裁blt操作。
BltBatch()函数不是在DirectX3下实现的(你可以调用该函数,但什么也不会发生)。执行BltBatch()函数时,如果可能,它可同时进行多blt操作。
BltFast()函数是Blt()函数的优化版本。BltFast()函数的效率提高了,但性能却下降了。BltFast()函数不能进行一些特殊的blt操作,而Blt()函数可以。而且,BltFast()函数不能用于剪裁。但是BltFast()函数支持源和目标色彩键码blt的操作。在遵循定制剪裁例程的情况下,BltFast()函数可进行DirectDraw能够提供的最快捷、灵活的blt操作。在下章中我们将执行一个定制剪裁例程。
以上3个blt函数均将源表面和目标表面作为变量。其他的数据,例如blt在目标表面上的理想定位,是通过指定理想blt操作的确切属性来提供的。一旦可能,这3个函数将进行硬件加速blt。
3. Flip()函数
Flip()函数用于页面翻转操作。调用Flip()函数可隐藏屏幕上先前可见的表面,并使一个后备缓冲区显现。只有被明确地创建为翻转表面的表面,才响应该函数的调用。
必须牢记,真正的翻转操作不可能总是成功。页面翻转要求有足够的显示RAM容纳两整屏有效数据。如果满足不了这一要求,系统RAM中将创建一个后备缓冲区。这时调用Flip()函数进行的是blt操作而不是页面翻转。基于系统RAM的后备缓冲区中的内容被拷贝到主表面上。这样会严重影响性能,但是,在真正的页面翻转中如果没有足够的显示RAM,又不退出程序,也只能如此了。如果你的应用程序要求最佳性能,就得设法避免激活不能进行真正页面翻转的显示模式。
4. 表面状态函数
下面讨论两个能检索有关操作和翻转操作信息的函数,它们是:
●GetBltStatus()
●GetFlipStatus()
GetBltStatus()函数用于确定当前是否进行blt操作。这一点很重要,因为正被blt的表面不能进行其他操作。该函数表明,给定的表面是否正是一个进行blt操作的源表面或目标表面。
同样地,GetBltStatus()函数表明是否正在进行翻转操作。即使DirectDraw通过blt操作仿真页面翻转,该函数而不GetBltStatus()也必须用于由Flip()函数初始化的监视器页面翻转。
5. 色彩键码函数
DirectDrawSurface接口提供了以下两个函数,来设置和检查表面色彩键码或色彩键码的范围,它们是:
●GetColorKey()
●SetColoKey()
默认状态下,表面没有色彩键码。一个色彩键码只对应一种颜色,但某些硬件支持色彩键码范围。色彩键码和色彩键码范围是DDCOLORKEY结构定义的。GetColorKey()和SetColoKey()函数都将该结构的指针作为变量。在要求表面的一部分透明时或需要进行目标色彩键码操作时,可以使用这两个函数。
6. Lock和Unlock()函数
DirectDraw的一个主要特点,就是能够提供对图像数据的直接存取。直接存取可以提供最佳性能和更好的灵活性,因为没有中间API影响运行速度,并且开发人员呆任意使用图像数据。对表面存储器的中间存取通过以下出众个函数实现:
●Unlock()
●Lock()
Lock()函数向组成表面的存储器返回一个指针,不管表面存储器位于显示RAM还是系统RAM。存储器一般按线性风格排列,以便能简单地进行图像 数据存取。Unolock()函数在完成表面存储器的存取之后指定给DirectDraw。
对图像数据的直接存取必须付出代价。为了支持这种存取方式,DirectDraw在表面锁定的时候必须关闭基本的Windows机构。在Windows95状态下,如果忘记解锁表面,必定会损坏机器。
因此,表面锁定的时间应尽量缩短。测试前应仔细检查Lock()和Unlock()函数之间的程序调用。因为这一程序无法用传统的调试程序进行调试。
锁定表面不能被blt和翻转,因此试图保持表面处于锁定状态没有任何有益之处。而且,一旦表面解锁,由Lock()函数检索的指针就失效了。
表面锁定后不能再次被锁定。在表面锁定时也就无法调用Lock()函数。
7. GetDC()ReleaseDC()函数
对表面的直接存取占用很大内存,有时候把表面作为一个常规的Windows设备会更好。在此,DirectDrawSurface接口提供以下两个函数:
●GetDC()
●ReleaseDC()
GetDC()函数提供了一个DC(设备环境),可以用常规的Win32函数写到表面上。例如,DC可以用Win32的TextOut()函数在表面上绘制文本。用完DC后必须马上调用ReleaseDC()函数。
同Lock()和Unlock()函数使用一样,在调用完GetDC()函数后必须马上调用ReleaseDC()函数。这是因为GetDC()函数内部调用Lock函数,而ReleaseDC()函数内部调用Unlock()函数。
8. PageLock()和PageUnlock()函数
接下来,我们讨论另外两个与Lock()函数和Unlock()函数看上去非常相像的函数:
●PageLock()
●PageUnlock()
尽管这两个函数看上去很像Lock()和Unlock()函数,但它们却有完全不同的作用。PageLock()和PageUnlock()函数用于控制Windows对基于系统RAM的表面的处理方式。这两个函数由DirectDrawSurface2接口提供,而不是由DirectDrawSurface接口提供。
当Windows认为当前正在运行的其他应用程序或进程更适于使用内存时,Windows会向硬盘释放部分内存。这种缓冲对于整个系统内存都起作用,因此驻留在系统内存中的DirectDraw表面有可能被存到硬盘上。如果要用到这样的表面,Windows需要花费一定的时间从硬盘上读取表面数据。
PageLock()函数提示Windows哪些给定的表面不应该释放到硬盘上。这样,在使用表面时就不用耗费时间进行硬盘存取了。相反地,PageUnlock()函数用于告知Windows哪些表面内存可被释放。
过程调用PageLock()函数会减少缓冲内存的总量,从而导致Windows的速度大大降低。至于这种情况何时发生,取决于页面锁定系统内存量及机器提供的系统内存量。
PageLock()和PageUnlock()函数主要是由DirectDraw提供而非DirectDraw应用程序。举个例子来说,DirectDraw自动使用PageLock()函数,以确保运行blt操作时,基于系统RAM的表面不被释放到硬盘。
PageLock()函数可以被同一个表面多次调用。DirectDraw用参考计数法记录PageLock()函数被调用的次数,因此多次调用PageUnlock()函数就必须避免多次调用PageLock()函数。
PageLock()和PageUnlock()函数对于驻留在显示RAM中的表面不起作用。
9. IsLost()的Restore()函数
现在讨论两个与使用驻留在显示RAM中的表面有关的函数:
●IsLost()
●Restore()
让我们来看一看下面这种情况。应用程序正在运行时,尽量把表面分配到显示RAM中,剩下的创建到系统RAM中。应用程序在运行一段时间之后,用户执行或切换到另一个应用程序。该应用程序是任意的,可以是一个常规的Windows程序,如Windows开发程序或记事本。它也可以是另外的DirectDraw应用程序,该程序也试图将尽可能多地分配显示RAM。如果DirectDraw不接受显示RAM,那么新的应用程序就很可能根本运行不了。相反的情况就意味着,应用程序不允许分配到任何显示RAM中。
因此,DirectDraw可以随意将任何一个或者所有的基于显示RAM的表面从非激活应用程序中移走。这种情况就是所谓的表面丢失。从技术上讲,程序仍具有表面,但它们不再同任何内存相关。要使用丢失的表面会导致DDERR-SURFACELOST错误。IsLost()函数可用于确定一个表面是否丢失了内存。
表面内存丢失后可通过Restore()函数恢复,但只能在应用程序被重新激活之后才可恢复。这会导致应用程序无法将处于最小化状态的所有表面复原。
Restore()函数可恢复附属于表面的任一内存,但并不恢复内存的内容。表面被复原后,应用程序就可以恢复表面内容了。
注意,这种用法不适合利用系统RAM创建的表面。如果需要用到基于系统RAM的表面所占内存,那么Windows会立即将这些表面释放到硬盘上。Windows自动地处理存储和恢复,包括恢复表面的内容。
10. GetDDInterface()函数
GetDDInterface()函数可检索用于创建给定表面的DirectDraw接口的指针。由于程序中大多数情况下只有一个DirectDraw接口实例,所以GetDDInterface()函数并不常用。但是一个应用程序中有可能使用多个DirectDraw接口,在这种情况下,GetDDInterface()函数会起到重要作用。
11. 表面连接函数
DirectDrawSurface接口提供以下4个函数,用来维持表面间的连接:
●AddAttachedSurface()
●DeleteAttachedSurface()
●EnumAttachedSurfaces()
●GetAttachedSurface()
DirectDraw支持大量的用于表面间的连接情况。最常见的情况就是页面翻转。进行页面翻转时,两个或两个以上的表面连接成环状,每次调用Flip()函数时,都会使连成环状的表面中的下一个表面显现。
表面连接函数用于创建、检查或消除表面间的连接,但这些函数并非必不可少的。DirectDraw往往是自动创建连接表面。比如,当创建一个主翻转表面时,可以指定用于连接表面的后备缓冲区的数量。DirectDraw就会创建这些表面,并将它们连接起来。
12. 重叠函数
DirectDrawSurface接口用于支持重叠的函数如下:
●AddOverlayDirtyRect()
●EnumOverlayZOrders()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -