WinCe下使用DirectDraw绘制覆盖表面方式

WinCe下使用DirectDraw绘制覆盖表面方式
2010-03-10 09:17

之前一直苦于不知道如何实现覆盖表面的的关键色和透明同时使用,以为只支持其中的一种。后来在放弃之后,在无意中发现实现的方法,天意啊。
以下为窗口的一个函数,用来初始化我的directdraw离屏表面,表面同时支持支持关键色和透明:
所有以“m_”开头的都为类的成员变量
BOOL MyMainWin::MyInitDD()
{
HRESULT ret = DirectDrawCreate(NULL, &m_pDD, NULL);
if (ret != DD_OK)
{
printf("获取directdraw实例失败!");
return FALSE;
}

ret = m_pDD->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL);
if (ret != DD_OK)
{
printf("设置登记失败!");
return FALSE;
}

//g_pDD->GetDisplayMode(&ddsd);
//hRet = g_pDD->SetDisplayMode(480, 720, 32, 0, DDSDM_STANDARDVGAMODE);

DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd));

ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
ret = m_pDD->CreateSurface(&ddsd, &m_pDDSPrimary, NULL);
if (ret != DD_OK)
{
printf("创建主表面失败!");
return FALSE;
}

DDCAPS ddcaps;

// 申请离屏表面
memset(&ddcaps, 0, sizeof(ddcaps));
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
ddsd.dwHeight = 720;
ddsd.dwWidth = 480;
ret = m_pDD->CreateSurface( &ddsd, &m_pDDSOffScreenOne, NULL);
if( ret != DD_OK )
{
printf("创建离屏表面失败");
return FALSE;
}

memset(&ddcaps, 0, sizeof(ddcaps));
ddcaps.dwSize = sizeof(ddcaps);
ret = m_pDD->GetCaps(&ddcaps, NULL);
if (ret != DD_OK)
{
printf("获取caps描述失败!");
return FALSE;
}

if (ddcaps.dwOverlayCaps == 0)
{
printf("不支持覆盖表面");
return FALSE;
}

RECT rs;
rs.left = 0;
rs.top = 0;
       
        // 我要创建的表面的大小(此处为全屏幕),如果表面非全屏,需要判断设备支持的表面大小以及坐标开始值,请参考网上资料
rs.right = PIC_SIZE_WIDTH;
rs.bottom = PIC_SIZE_HEIGHT;

memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP ;
//ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT;
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT;

ddsd.dwWidth = rs.right;
ddsd.dwHeight = rs.bottom;
//ddsd.dwBackBufferCount = 2;
ddsd.dwBackBufferCount = 1;

ret = m_pDD->CreateSurface(&ddsd, &m_pDDSOverlay, NULL);

if (ret != DD_OK)
{
printf("创建覆盖表面失败!");
return FALSE;
}

// 获取缓冲表面(MyGetSurfaceCallback为回调函数,在后面给出,作用是获取后备缓冲表面的指针)
ret = m_pDDSOverlay->EnumAttachedSurfaces(this, MyGetSurfaceCallback);
if (FAILED(ret))
{
printf("获取缓冲表面失败!");
return FALSE;
}

// 覆盖表面的标志
//DWORD dwUpdateFlags = DDOVER_SHOW;
DWORD dwUpdateFlags = 0;

// 检查是否支持关键色(透明色)
//DDOVERLAYFX ovfx;
memset(&m_ovfx, 0, sizeof(m_ovfx));
m_ovfx.dwSize = sizeof(m_ovfx);

        // 这个判断是我自己加的,无特别意义,可去掉
if(IF_PAINT_COLORKEY)
{
//if (ddcaps.dwOverlayCaps & DDOVERLAYCAPS_ALPHAANDKEYDEST)
{
   if (ddcaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYSRC)
   {
    dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE;

    // 设置透明色
    m_ovfx.dckSrcColorkey.dwColorSpaceLowValue = BG_COLORKEY; // black as the color key
    m_ovfx.dckSrcColorkey.dwColorSpaceHighValue = BG_COLORKEY;
   }
}
}

// 更新覆盖表面的值

ret = m_pDDSOverlay->UpdateOverlay(&rs, m_pDDSPrimary, &rs, dwUpdateFlags, &m_ovfx);
if (ret != DD_OK)
{
printf("更新覆盖表面初始信息失败!");
return FALSE;
}
        // BG_TRANS_VALUE为背景色透明度(即关键色的透明度),FG_TARANS_VALUE为前景色透明度(即关键色外的所有颜色)
        // 两个值的范围都是 0~15,0表示完全透明,15表示完全不透
m_ovfx.dwAlphaConst = ((BG_TRANS_VALUE&0xF) << 4 ) | (FG_TARNS_VALUE & 0xF);

ret = m_pDDSOverlay->UpdateOverlay(&rs, m_pDDSPrimary, &rs, 0, &m_ovfx);
if (ret != DD_OK)
{
printf("更新覆盖表面初始信息失败!");
return FALSE;
}

        // 此处给表面填充关键色(可不做),以免显示时出现黑色的闪烁(因为表面的初始颜色为黑色)
HDC hdc = NULL;
if (FAILED(m_pDDSOverlay->GetDC(&hdc)))
{
return FALSE;
}
FillRect(hdc, &rs, m_hb);
m_pDDSOverlay->ReleaseDC(hdc);

// 显示

ret = m_pDDSOverlay->UpdateOverlay(&rs, m_pDDSPrimary, &rs, DDOVER_SHOW, &m_ovfx);
if (ret != DD_OK)
{
   printf("更新覆盖表面初始信息失败!");
   return FALSE;
}

return TRUE;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值