ddraw相关

//

使用ddraw将表面刷成单一色,使用ddblttfx的dwFillColor来填充。
  DDBLTFX ddbltfx;
 
    ddbltfx.dwSize = sizeof(ddbltfx);
    ddbltfx.dwFillColor = ddpf.dwBBitMask; // Pure blue 纯蓝
 
    ddrval = lpDDS->Blt(
        NULL,        // Destination is entire surface,目标是整个平面
        NULL,        // No source surface,没有源平面
        NULL,        // No source rectangle  没有源矩形
        DDBLT_COLORFILL, &ddbltfx);

ddraw透明COPY
m_btn_up.SetTransparent( DDBLTFAST_SRCCOLORKEY, m_pParent->m_ctrl[CTRL_DLG_LANGUAGE_3].color );
 void   SetTransparent( DWORD dwTrans, COLORREF rgb ) { m_dwTransparent = dwTrans; DDSetColorKey2( m_pDDSOne, rgb ); }
extern "C" HRESULT
DDSetColorKey2(IDirectDrawSurface4 * pdds, COLORREF rgb)
{
    DDCOLORKEY ddck;

    ddck.dwColorSpaceLowValue = DDColorMatch(pdds, rgb);
    ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
    return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
}
hRet = m_pDDSPri->BltFast( m_rcPri.left, m_rcPri.top, m_pDDSOne, &rect, DDBLTFAST_WAIT | m_dwTransparent );
色键格式

色键是在DDCOLORKEY结构中来描述。如果色键是一个单一的色,这个结构的所有成员都应被设置成同一个值。否则,色键就是一个色彩范围。

色键指定为平面的像素格式。如果是基于调色板格式,色键就是色彩索引或一段索引范围。如果平面格式是指定为FOURCC码并描述为YUV格式,YUV色键应在DDCOLORKEY结构中的 dwColorSpaceLowValue及dwColorSpaceHighValue的成员都设置成三个低顺序字节。最低的字节包含V数据,第二低的字节包含U数据,最高的字节包含Y数据。

一些有效的色键例程:

    8-Bit调色板模式
//调色板通道26是色键
dwColorSpaceLowValue=26;
dwColorSpaceHighValue=26;

    24-Bit真彩色模式
//色 255,128,128是色键
dwColorSpaceLowValue=RGBQUAD(255,128,128);
dwColorSpaceHighValue=RGBQUAD(255,128,128);

    FourCC YUV模式
//任何YUV色,Y是100与110之间,U和V是50与55之间的是透明色
dwColorSpaceLowValue=YUVQUAD(100,50,50);
dwColorSpaceHighValue=YUVQUAD(110,55,55);

支持色键段与单一色键不同需要硬件支持。查看硬件的DDCAPS结构中的dwCKeyCaps成员。HEL不支持色键段。

一些硬件只支持YUV像素数据的色键段,通常用于视频。视频中的透明背景("蓝屏") 可能不是单一的纯色,所以用一个色键段更理想。

设置色键

你可以在创建平面的前后来设置其源及目标色键。

要在创建平面时设置色键,你需要在传递给IDirectDraw4:CreateSurface 的DDSURFACEDESC2结构中的ddckCKSrcBlt及ddckCKDestBlt成员赋于适当的值。要使色键Blit生效,你也需要在dwFlags成员中加上DDSD_CKSRCBLT及DDSD_CKDESTBLT的一个或全部。

要为已创建好的平面设置色键,你要使用IDirectDrawSurface4::SetColorKey宏。你在lpDDColorKey指定一个键并设置dwFlags成员中的DDCKEY_SRCBLT及DDCKEY_DESTBLT 的一个指定你是设置源色键或目标色键。如果DDCOLORKEY结构包含一个色键段,你必须也设置DDCKEY_COLORSPACE标志。如果这个标志未设置,结构中只有dwColorSpaceLowValue成员会被使用。

依靠色键来Blit

如果你要在调用IDirectDrawSurface4::BltFast宏时使用平面色键,你必须设置dwTrans参数中的DDBLTFAST_STCCOLORKEY或DDBLTFAST_DESTCOLORKEY标志的一个或全部。为了要在调用IDirectDrawSurface4::Blt时使用色键,你要传递在dwFlags参数中的 DDBLT_KEYSRC及DDBLT_KEYDEST标志的一个或全部。作为选择,你能为DDBLTFX结构中的 ddckDestColorkey及ddckSrcColorkey成员设置适当的色彩值,并通过lpDDBltFx成员传递给宏。在这中情况下,你必须也设置dwFlags参数中的DBLT_KEYSRCOVERRIDE及DDBLT_KEYDESTOVERRIDE 标志的一个或全部,以便选择的色键能被DDBLTFX带走而不是平面的其他属性。
//

 

3.2.1 使用GDI函数向物理屏幕或逻辑屏幕输出
  调用IDirectDrawSurface2::GetDC可得代表某个屏幕的设备描述表的句柄,使用GDI函数输出,最后调用IDirectDrawSurface2::ReleaseDC释放句柄。为防止在对屏幕作图期间其它应用程序争夺显存,IDirectDrawSurface2::GetDC调用IDirectDrawSurface2::Lock得到Winl6 Lock。这意味着其它程序在该程序释放Win16Lock前都不能访问GDI和USER资源。IDirectDrawSurface2::ReleaseDC调用IDirectDrawSurface2::Unlock释放Win16 Lock。于是,在调用IDirectDrawSurface2::GetDC和IDirectDrawSurface2::ReleaseDC期间,Windows将被挂起。因此,应用程序应尽量缩短这一对函数调用之间的间隔时间,而且调试程序也无法跟踪这段时间内执行的操作。
3.2.2 交替切换物理屏幕和逻辑屏幕或执行屏幕内容的映射
  准备好内存中的逻辑屏幕后,可以调用IDirectDrawSurface2::Flip方法切换物理屏幕和逻辑屏幕,也可调用IDirectDrawSurface2::BltFast、IDirectDrawSurface2::Blt等方法执行部分屏幕内容的映射。一般情况下程序采用异步方式,在显示卡硬件执行切换动作的同时准备下一页屏幕,使CPU和显示卡硬件并行,提高整体执行速度。
  使用Flip切换物理屏幕和逻辑屏幕后,原指向物理屏幕的指针仍然指向物理屏幕,原指向逻辑屏幕的指针仍然指向逻辑屏幕,即指针所指内容也被交换了,便于程序操纵各个屏幕而不至于混淆。
3.2.3 释放DirectDraw对象
  程序结束之前要释放所创建的DirectDraw对象。这只要在相应接口上调用Release方法即可。

4 使用DirectDraw的技巧和注意事项

4.1 检查方法的返回值
  正确执行DirectDraw方法时都返回DDOK。且其值是零。返回其它值表明发生了某种错误。一般地,程序应检查这些返回值以决定是否出错。

4.2 检查Flip和Blt的状态
  如果在Flip或Blt操作的返回值是DDERR_WASSTILLDRAWING情况,为提高效率,DirectDraw提供了IDirectDrawSurface2::GetFlipStatus和IDirectDrawSurface2::GetBltStatus方法。它们能立即返回当前的Flip和Blt状态,于是应用程序可以在上一操作完成之前执行某些其他的任务。

4.3 在位图映射中使用ColorKey
  ColorKey是一种或几种颜色的集合,用于在位图映射操作中区分前景色和背景色。ColorKey包括两种:Source color key和Destination color key。前者是指源位图中代表透明色的颜色,在执行映射操作时将不被映射到目标位图上;后者是指目标位图中将被源位图中相应位置颜色取代的颜色,如果目标位图指定了Destination color key,则只有这些指定的颜色被替换。可以在创建DirectDrawSurface对象时指定Color Key;也可使用方法IDirectDrawSurface2::GetColorKey和IDirectDrawSurface2::SetColorKey以获取和设置已有的DirectDrawSurface对象的ColorKey。

4.4 GDI重定向
  由于GDI在Windows系统启动时先于DirectDraw被装入,而DirectDraw工作时又绕过了GDI,因此GDI不知道DirectDraw对物理屏幕所进行的操作。即使DirectDraw调用了Flip方法将先前的物理屏幕切换为逻辑屏幕,如不采取措施,GDI将仍然向切换后的逻辑屏幕上输出。如果DirectDraw程序拥有菜单、滚动条等由GDI负责绘制的元素,那么在Flip完成后这些元素就会成为不可见,而在对应的逻辑屏幕被切换成物理屏幕时又会显示出来。为避免屏幕闪烁,DirectDraw提供了IDirectDraw2::GetGDISurface,用于确定当前被GDI认为是物理屏幕的DirectDrawSurface对象;以及IDirectDraw2::FlipToGDISurface,用于将GDI的输出重新定向到当前的物理屏幕上。如果需要,可以在每次Flip操作后调用它,以保证屏幕正常。

4.5 在显存中存放位图
  由于从显存到显存的映射比从系统内存到显存的映射快,所以经常将需要映射的位图存放在显存中以提高速度。大多数显示卡在存放了物理屏幕和相关逻辑屏幕之外还有足够的内存可以用来存放位图。可以调用IDirectDraw2::GetCaps检查显存;在创建DirectDrawSurface对象时可以通过结构DDSURFACEDESC中的DDSCAPS域指定该对象存在于显存或系统内存中。如果指定在显存中创建对象,而显存又没有地方容纳该对象,IDirectDraw2::CreateSurface会返回错误信息DDERR_OUTOFVIDEOMEMORY。如果没有指定创建的位置,DirectDraw总是尽量利用空闲的显存。

4.6 检查硬件的性能
  虽然DirectDraw通过HAL和HEL屏蔽了硬件的具体特性,但应用程序也需根据硬件的不同性能来改变自身的执行方式。利用IDirectDraw2::GetCaps方法可以得到有关硬件性能的详细信息。

4.7 保持主窗口的消息循环畅通
  在调用SetCooperativeLevel设置DirectDraw的工作模式时,应用程序为DirectDraw指定了主窗口。由于DirectDraw直接操纵硬件可能导致死机,因此DirectDraw在后台监视主窗口的消息循环,当消息循环长时间没有反应时,DirectDraw就释放所有的资源,结束应用程序的执行。所以DirectDraw程s序应该注意避免长时间封锁消息循环。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值