/*
使用了3缓冲,1个主表面 (lpDDSPrimary)2个后台表面lpDDSBuffer,lpDDSBuffer2
在每个垂直同步信号(帧信号)来的时候,使用Flip切换
lpDDSPrimary->Flip(NULL,0);此时完成交换表面指针的操作
然后填充第1个lpDDSBuffer
问题:我是用VForm开发的,系统为WIN7 64位,VS2010,有时候肉眼能看到闪过我的Form控制台窗体,帧频设置为75Hz,退出程序,查看时间,确实也是1000/75=13.3333ms
,一闪而过,下午又突然好了,没闪了 这是为什么了,望高手解答
**/
/*创建Surface表面*/
m_hwnd=(HWND)::GetActiveWindow();
HRESULT ddrval;
DDSURFACEDESC2 ddsd; // DirectDraw的页面描述
ddrval=DirectDrawCreateEx (NULL, (VOID**)&lpDD, IID_IDirectDraw7, NULL);
if(ddrval != DD_OK)
{
//DirectDraw 对象不能被创建"
strTimerIntr+="error:DirectDrawCreateEx\r\n";
//RunningLOG("error:DirectDrawCreateEx\r\n ");
return FALSE;
}
//这里使用了 if ( xxx != DD_OK) 的方法进行错误检测,这是最常用的方法
ddrval=lpDD->SetCooperativeLevel(m_hwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);//DDSCL_NORMAL DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN
if (ddrval != DD_OK)
{
strTimerIntr+="error:SetCooperativeLevel\r\n ";
//RunningLOG("error:SetCooperativeLevel\r\n ");
return FALSE; //设置DirectDraw控制级
}
//if ( lpDD->SetDisplayMode( FullScrenn_Width, FullScrenn_Height, FullScrenn_Bits, 0, DDSDM_STANDARDVGAMODE ) != DD_OK )
//{
// return FALSE; //设置显示模式
//}
//开始创建主页面,先清空页面描述
memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
//填充页面描述
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; //有后台缓存
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP|DDSCAPS_VIDEOMEMORY; //只使用显存来创建
ddsd.dwBackBufferCount = 2; //一个后台缓存
if ( lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL ) != DD_OK )
{
strTimerIntr+="error:SetCooperativeLevel\r\n ";
//RunningLOG("error:CreateSurface lpDDSPrimary\r\n ");
return FALSE; //创建主页面
}
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY; //这是后台缓存
if ( DD_OK != lpDDSPrimary->GetAttachedSurface( &ddsd.ddsCaps, &lpDDSBuffer ))
{
strTimerIntr+="error:GetAttachedSurface lpDDSBuffer\r\n ";
return FALSE; //创建后台缓存
}
/*下面代码为关键测试代码,在一个线程中等待垂直同步信号*/
WaitForVerticalBlank();//等待垂直同步信号过来
{
while (DDERR_WASSTILLDRAWING==lpDDSBuffer->GetFlipStatus(DDGFS_ISFLIPDONE));//等待上一次后台翻面操作完成
HRESULT ddrval;
ddrval=lpDDSPrimary->Flip(NULL,0);//切换前后台
while (1)
{
if (DD_OK==ddrval)
{
break;
}
if (DDERR_SURFACELOST==ddrval)
{
ddrval=lpDDSPrimary->Restore();//尝试恢复页面
if (DD_OK==ddrval)
{
break;
}
}
if (DDERR_WASSTILLDRAWING!=ddrval)
{
break;
}
}
PainSurface(lpDDSBuffer);//填充后台缓冲
}
void PainSurface(LPDIRECTDRAWSURFACE7 LPback)
{
HRESULT hRet;
HDC mydc;
BYTE* pTmpDest = BitmapData;
int add = WIDTHBYTES(PICTURE_WIDTH*24) - PICTURE_WIDTH * 3;
if (add)
{
MessageBox::Show("图像WidthByte不是4的整数倍");
}
//保证surface可用
if(LPback->IsLost()!=DD_OK)
{
hRet = LPback->Restore();
if (hRet != DD_OK)
{
MessageBox::Show(_T("无法Restore surface"));
return;
}
}
//// 取得DC
hRet = LPback->GetDC(&mydc);
if (hRet != DD_OK)
{
MessageBox::Show(_T("无法GetDC"));
return;
}
pin_ptr pinBuff = &arrayFileRGBBuff[0];//获取图像数据地址
if(GDI_ERROR == StretchDIBits(mydc,0,0,PICTURE_WIDTH,PICTURE_HEIGHT,0,0,PICTURE_WIDTH,PICTURE_HEIGHT,
(void *)pinBuff,
&bmi,
DIB_RGB_COLORS,
SRCCOPY))
{
MessageBox::Show(_T("图片生成失败"));
return;
}
lpDDSBuffer->ReleaseDC(mydc);
}