全部博文(47)
分类: WINDOWS
2009-04-01 16:33:46
一个比较规范的代码段对directdraw进行初始化。
.h文件
#include <ddraw.h>
DIRECTDRAW dd ;
DDRAWCLIPPER dcClipper ;
DDRAWSURFACE dsFront, dsBack ;
DDSURFACEDESC ddsd ;
HWND m_hArea ;
.cpp文件
#define RGBFMT
BOOL CreateObject()
{
//创建DirectDraw对像
HRESULT hr ;
hr = DirectDrawCreate(NULL, &dd, NULL) ;
if(FAILED(hr)) return FALSE ;
hr = dd->SetCooperativeLevel(m_hArea, DDSCL_NORMAL) ;
if(FAILED(hr)) return FALSE;
ZeroMemory(&ddsd, sizeof(ddsd)) ;
ddsd.dwSize = sizeof(ddsd) ;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN ;
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT ;
ddsd.dwWidth = 352 ;
ddsd.dwHeight = 288 ;
#ifdef RGBFMT //显示RGB
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT) ;
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB ;
ddsd.ddpfPixelFormat.dwRGBBitCount = 16 ;
#else //显示YUV
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_YUV ;
ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y', 'V', '1', '2') ;
ddsd.ddpfPixelFormat.dwYUVBitCount = 8 ;
#endif
hr = dd->CreateSurface(&ddsd, &dsBack, NULL) ; //创建离屏表面
if(hr != DD_OK)
{
dd.Release() ;
return FALSE ;
}
ZeroMemory(&ddsd, sizeof(ddsd)) ;
ddsd.dwSize = sizeof(ddsd) ;
ddsd.dwFlags = DDSD_CAPS ;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE ;
hr = dd->CreateSurface(&ddsd, &dsFront, NULL) ; //创建主表面
if(FAILED(hr))
{
dsBack.Release() ;
dd.Release() ;
return FALSE ;
}
hr = dd->CreateClipper(0, &dcClipper, NULL) ; //创建裁剪区
if(FAILED(hr))
{
dsBack.Release() ;
dsFront.Release() ;
dd.Release() ;
return FALSE ;
}
dcClipper->SetHWnd(0, m_hArea) ; //设置裁剪区区域
hr = dsFront->SetClipper(dcClipper) ;
return TRUE ;
}
void Draw(FrameStruct struFrame)
{
if(CreateObject())
{
DDSURFACEDESC ddsd ;
HRESULT ddRval ;
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC)) ;
ddsd.dwSize = sizeof(DDSURFACEDESC) ;
ddRval = dsBack->Lock(NULL, &ddsd, DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_NOSYSLOCK, NULL);
if( ddRval == DDERR_SURFACELOST )
{
ddRval = dsFront->Restore();
ddRval = dsBack->Restore();
ddRval = dsBack->Lock(NULL, &ddsd, DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_NOSYSLOCK, NULL);
}
if(ddRval != DD_OK)
{
return ;
}
LPBYTE lpSurf = (LPBYTE)ddsd.lpSurface;
LPBYTE PtrY = struFrame.pY ;
LPBYTE PtrU = struFrame.pU ;
LPBYTE PtrV = struFrame.pV ;
#ifdef RGBFMT
//RGB填充方式
memcpy(lpSurf, PtrY, struFrame.iWidth * struFrame.iHeight * 2) ;
#else
//YUV420填充方式
long lSize = 0 ;
if(lpSurf != NULL)
{
for (int i=0; i<struFrame.iHeight; i++)
{
memcpy(lpSurf, PtrY, struFrame.iYStride );
PtrY +=struFrame.iYStride ;
lpSurf += ddsd.lPitch;
}
for (int i=0;i<struFrame.iHeight/2;i++)
{
memcpy(lpSurf, PtrV, ddsd.dwWidth/2);
PtrV += struFrame.iUVStride ;
lpSurf += ddsd.lPitch/2;
}
for (int i=0;i<struFrame.iHeight/2;i++)
{
memcpy(lpSurf, PtrU, ddsd.dwWidth/2);
PtrU += struFrame.iUVStride ;
lpSurf += ddsd.lPitch/2;
lSize += ddsd.lPitch / 2 ;
}
#endif
dsBack->Unlock(NULL);
CRect rcDest, rcSource ;
rcSource.left = 0 ;
rcSource.top = 0 ;
rcSource.right = ddsd.dwWidth ;
rcSource.bottom = ddsd.dwHeight ;
GetDlgItem(IDC_SHOWAREA)->GetWindowRect(&rcDest) ;
ddRval = dsFront->Blt(rcDest, dsBack, NULL, DDBLT_WAIT, NULL) ;
while(ddRval == DDERR_WASSTILLDRAWING) ;
}
}