Overlay Surfaces (覆盖表面)
覆盖表面(Overlay Surfaces)
覆盖表面是具有特殊硬件支持能力的表面,通常用于显示活动视频、录制视频或静止位图而不需要位块传输到主表面或改变主表面的内容。对覆盖表面的字此完全由硬件提供,DirectDraw支持显示设备驱动程序所支持的特性,DirectDraw不仿真覆盖表面。可以将覆盖表面想象为一片塑料纸,我们可以在这片塑料上画图并可将其放置在显示器前面。塑料纸覆盖在显示器前面时,你可以看到覆盖和主表面,移去塑
料纸后,主表面并没有改变。覆盖表面的工作原理同透明塑料纸覆盖的原理很相似。的显示一个覆盖表面时,就是告诉设备驱动程序在哪里怎样使覆盖表面可见。当显示设备扫描线重画到显示器上时,它检查主表面上的每一个像素,看是否被覆盖所代替。如果是,显示设备就从覆盖表面中抽取相关像素的数据替代。
使用这种方法,显示适配卡在显示器上生成主表面和覆盖表面的合成表面,产生透明和拉伸效果而不需要改变每个表面的内容。合成表面被送入视频数据流直接送到显示器。因为这种处理和像素替代是硬件级的操作,所以不存在明显的性能损失。另外,这种方法还使得能够用不同的像素格式无缝地合成主表面和覆盖表面。创建覆盖表面需要在DDSCAPS结构中指定DDSCAPS_OVERLAY标志,然后调用IDirectDraw2::CreateSurface方法覆盖表面只能在支配内存中创建,因此还必须包含DDSCAPS_VIDEOMEMORY标志。同其他类型的表面一样,通过包含合适的标志,可以创建单一的覆盖表面也可以创建由多个覆盖组成的翻转链。
你可以调用IDirectDraw2::GetCaps方法来获取有关支持的覆盖特性的信息。该方法用描述所有的特性信息填充一个DDCAPS结构。在报告硬件特性时,设备驱动程序设置dwCaps成员的标志来指明何时强制执行硬件提供的某种类型的约束。获得的驱动程序的能力后,通过检查dwCaps成员的标志可知道提供的约束的信息。DDCAPS结构包含了9个成员,这9个成员描述了覆盖表面的约束信息。下标列出了同覆盖相关的成员既它们的标志。
成员 标志
dwMaxVisibleOverlays 该成员始终有效
dwCurrVisibleOverlays 该成员始终有效
dwAlignBoundarySrc DDCAPS_ALIGNBOUNDARYSRC
dwAlignSizeSrc DDCAPS_ALIGNSIZESRC
dwAlignBoundaryDest DDCAPS_ALIGNBOUNDARYDES
dwAlignSizeDest DDCAPS_ALIGNSIZEDEST
dwMinOverlayStretch DDCAPS_OVERLAYSTRETCH
dwMaxOverlayStretch DDCAPS_OVERLAYSTRETCH
dwMaxVisibleOverlays和dwCurrVisibleOverlays成员指明了硬件可以显示的覆盖的最大数目,以及当前有多少个可见。dwAlignBoundarySrc、dwAlignSizeSrc、dwAlignBoundaryDest、dwAlignSizeDest和dwAlignStrideAlign成员是硬件报告的矩形的位置和大小的约束。这些成员的值指明了在显示覆盖表面时如何确定源矩形和目的矩形的大小和位置。dwMinOverlayStretch和dwMaxOverlayStretch是有关拉伸因子的信息。
a、源矩形和目的矩形(Source and Destination Rectangles)要显示一个覆盖表面,需调用IDirectDrawSurface3::UpdateOverlay方法,在dwFlags参数中指定DDOVER_SHOW标志。该方法要求你在lpSrcRect和lpDestRect参数中指定一个源矩形和目的矩形。若使用整个表面,将lpSrcRect参数设为NULL即可。目的矩形是在主表面上产生覆盖表面的位置。
源、目的矩形不必大小相同。一般让目的矩形必源矩形大一些或小一些都可以,硬件在显示时会自动地压缩或拉伸。要想成功地显示一个覆盖表面,可能需要调整源、目的矩形的大小和位置,这一过程是否必要依赖于设备驱动程序的限制。
b、边界和大小调整(Boundary and Size Alignment)
由于不同硬件的限制,一些设备驱动程序对用于显示覆盖表面的源矩形和目的矩形的大小和位置做了约束。要找出设备应用的约束,可调用IDirectDraw2::GetCaps方法,然后检查DDCAPS结构中同覆盖相关的dwCaps成员的标志。下标列出了指定边界和大小调整约束的成员和标志。
类别
标志
成员
边界约束
DDCAPS_ALIGNBOUNDARYSRC
dwAlignBoundarySrc
DDCAPS_ALIGNBOUNDARYDEST
dwAlignBoundaryDest
大小约束
DDCAPS_ALIGNSIZESRC
dwAlignSizeSrc
DDCAPS_ALIGNSIZEDEST
dwAlignSizeDest
约束有两种,边界约束和大小约束。两种约束都以像素的方式表示,并且能够用于源矩形和目的矩形。当然,由于覆盖表面和主表面的像素格式的不同,这些约束也可以不一样。
边界约束影响源矩形和目的矩形放置的位置。dwAlignBoundarySrc和dwAlignBoundaryDest成员的值告诉你如何调整相关矩形的左上角。
矩形左上角的X坐标(RECT结构中的left成员)必须是报告出的值的整数倍。
大小约束影响源矩形和目的矩形的有效宽度。dwAlignSizeSrc和dwAlignSizeDest成员的值以像素的格式指出怎样调整相关矩形的宽。如果按照一个最小拉伸因子拉伸矩形,应确保拉伸后的矩形仍然是大小调整过的。拉伸矩形之后,通过向上圆整来调整宽度,就可以保持最小的拉伸因子。
c、最大和最小拉伸因子(Minimum and Maximum Stretch Factors)
由于硬件的局限性,一些设备限制了目的矩形同相关的源矩形宽度的比较。DirectDraw将这些约束作为拉伸因子。一个拉伸因子就是源矩形同目的矩形的宽度之间的比率。若驱动程序提供有关拉伸因子的信息,在调用IDirectDraw2::GetCaps方法时后,它将在DDCAPS结构中设置DDCAPS_OVERLAYSTRETCH标志。注意,拉伸因子都已经乘以1000,所以值为1300的拉伸因子实际上是1.3。
不压缩和拉伸覆盖目的矩形的设备所报告出的最大最小拉伸因子通常是0。
最小拉伸因子指出目的矩形比源矩形宽多少或窄多少。如果最小拉伸因子大于1000,就必须增加目的矩形的宽度。例如,若拉伸因子为1300,则目的矩形的宽度应该至少是源矩形宽度的1.3倍。如果拉伸因子小于1000,目的矩形就比源矩形的宽度要小。最大拉伸因子是目的矩形能够拉伸的最大倍数。例如,若最大拉伸因子是2000,则目的矩形的宽度最多可以是源矩形宽度的2倍。若最大拉伸因子小于1000,
目的矩形就需要压缩。经过拉伸之后,目的矩形必须遵守设备要求的任何大小调整约束。因此,最后在大小调整之前拉伸目的矩形。硬件并不要求调整目的矩形的高度。你可以增加矩形的高度来保持方向比率的不变。
d、覆盖Color Key
象其它类型的表面一样,覆盖表面也使用源、目的Color Key来控制表面之间的透明位块传输操作。因为覆盖表面的显示不是通过位块传输完成的,所以在调用IDirectDrawSurface3::UpdateOverlay方法时就需要采取不同的办法来控制覆盖表面显示在主表面上的方式。答案就是覆盖Color Key。同位块传输相关的Color Key相似,覆盖Color Key也有源Color Key和目的Color Key,可通过调用方法
IDirectDrawSurface3::SetColorKey并利用DDCKEY_DESTOVERLAY标志来设置源Color Key和目的Color Key。覆盖表面能够将位块传输和覆盖Color Key结合在一起来控制位块传输操作和覆盖显示操作,两种不同类型的Color Key并不互相冲突。
IDirectDrawSurface3::UpdateOverlay方法用源Color Key检查覆盖表面中哪个像素应该是透明的,允许主表面透过覆盖表面显示。同样,该方法使用目的覆盖Color Key来确定主表面显示时哪部分允许倍覆盖表面所覆盖,其显示效果同位块传输Color Key相同。
e、 定位覆盖表面(Positioning Overlay Surfaces)
在最先调用IDirectDrawSurface3::UpdateOverlay方法显示一个覆盖时,可以用方法 IDirectDrawSurface3::SetOverlayPosition来更新目的矩形。必须确保你指定的目的矩形的位置遵守边界对齐约束, IDirectDraw2::SetOverlayPosition方法并不执行剪切工作,使用了可能引起覆盖越界的坐标会使调用该方法失败,并返回DDERR_INVALIDPOSITION。
f、创建覆盖表面(Creating Overlay Surfaces)
象所有的表面一样,你可以调用IDirectDraw2::CreateSurface方法来创建一个覆盖表面。创建覆盖表面还需要在相关的结构DDSCAPS中包含DDSCAPS_OVERLAY标志。覆盖支持许多显示设备,因此不能判断一个给定的像素格式是否被大多数的驱动程序所支持,必须做好准备使之能工作于多种像素格式。你可以调用IDirectDraw2::GetFourCCCodes方法来获得驱动程序支持的有关非RGB格式的信息。要创建一个覆盖表面,最好使用最常用的像素格式,若给定的像素格式不被支持,DirectDraw会使用显示设备所支持的其他像素格式。创建覆盖表面翻转链也是允许的。
g、翻转覆盖表面(Flipping Overlay Surfaces)
同其他类型的表面一样,你可以创建覆盖表面翻转链。一旦创建了覆盖的翻转链,就可以调用方法IDirectDrawSurface3::Flip来翻转这些覆盖。软件解压在调用Flip方法显示覆盖表面时可使用DDFLIP_ODD和 DDFLIP_EVEN标志以减少运动赝象。如果驱动程序支持奇──偶翻转,在获得了驱动程序的能力后,DDCAPS2_CANFLIPODDEVEN标志将会在DDCAPS结构中设定。一旦设定了DDCAPS2_CANFLIPODDEVEN,就可在调用IDirectDrawSurface3::UpdateOverlay方法时包含DDOVER_BOB标志以通知驱动程序使用“Bob”
算法最小化运动赝象。此后,用DDFLIP_ODD或 DDFLIP_EVEN标志调用Flip时,驱动程序将会自动调整覆盖的源矩形来弥补抖动赝象。
如果获取硬件的能力后没有设置DDCAPS2_CANFLIPODDEVEN标志,但在调用UpdateOverlay时又使用了
DDOVER_BOB标志,那么该调用将会失败。