ddraw小結

ddraw 小結

WINCE應用程序開 2010-08-04 10:02:33 閱讀136 評論0   字號: 訂閱

1.鏈接庫

動態裝載
typedef HRESULT (* DIRECTDRAWCREATE)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
m_hModule=::LoadLibrary(_T("ddraw.dll"));
m_pDirectDrawCreate= (DIRECTDRAWCREATE)::GetProcAddress(m_hModule,L"DirectDrawCreate");

靜態鏈接
#pragma comment(lib, "ddraw.lib") 調用DirectDrawCreate


2.GUID的使用

直接定義
const GUID g_IID_IDirectDraw ={0x9c59509a,0x39bd,0x11d1,
0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5};

鏈接#pragma comment(lib, "dxguid.lib")
QueryInterface IID_IDirectDraw4

3.創建主頁面

// Create the main DirectDraw object
LPDIRECTDRAW g_pDD;
hRet = DirectDrawCreate(NULL, &g_pDD, NULL);
hRet = g_pDD->QueryInterface(g_IID_IDirectDraw, (LPVOID *)&g_pDD);
// Get normal mode
hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);

memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
// creates a DirectDrawSurface object for this DirectDraw object.
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
創建主頁面無須指定像素格式和頁面大小

4.頁面的像素格式

//YUV4:1:1
DDPIXELFORMAT pixel_format=
{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','V','1','2'),0,0,0,0,0};

//RGB565
DDPIXELFORMAT ddpfOverlayFormats =
{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0xF800, 0x07e0, 0x001F, 0};

5.創建OverLay頁面

memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP | DDSCAPS_VIDEOMEMORY;
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT;
ddsd.dwWidth = DDRAW_X;
ddsd.dwHeight = DDRAW_Y;
ddsd.dwBackBufferCount = 1;//有個後臺頁面
ddsd.ddpfPixelFormat = pixel_format;

hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);
創建OverLay頁面應該指定頁面的大小(可以全屏),像素格式。

6.OverLay頁面的顯示與隱藏
void ShowOverLay()
{
DDOVERLAYFX ovfx = {0};
ovfx.dwSize = sizeof(DDOVERLAYFX);
ovfx.dckSrcColorkey.dwColorSpaceLowValue = COLOR_KEY;//指定頁面的透明色
ovfx.dckSrcColorkey.dwColorSpaceHighValue = COLOR_KEY;
ovfx.dwAlphaConstBitDepth = 8;//指明alpha位寬度
ovfx.dwAlphaConst = 0x50;//alpha透明值 指明頁面的透明度.16級.

RECT rs;
rs.left = 0;
rs.top = 0;
rs.right = DDRAW_X;
rs.bottom = DDRAW_Y;

DWORD dwUpdateFlags = DDOVER_KEYSRCOVERRIDE | DDOVER_SHOW;
if(g_pDDSOverlay != NULL && g_pDDSOverlay->IsLost() == DD_OK)
{
HRESULT hret = g_pDDSOverlay->UpdateOverlay(&rs,g_pDDSPrimary,&rs,dwUpdateFlags,&ovfx);
//將主頁面和OverLay頁面關聯起來
if(hret != DD_OK)
{
printf("Update OverLay errorrn");
if(hret == DDERR_SURFACELOST)
{
g_pDDSOverlay->Restore();
}
}
}
}

dwUpdateFlags = DDOVER_HIDE即隱藏頁面。
UpdateOverlay這個接口一般是在頁面初始化後,顯示,隱藏這三種狀況下調用,
每次在頁面上繪圖後不必要調用UpdateOverlay,否則就會造成畫面顯示卡動,不連續。

7.在頁面上繪圖

在頁面上繪圖有兩種方法
一是獲取頁面DC後,以GDI方式繪圖
if( g_pDDSOverlay->GetDC(&hDC) == DD_OK)
//進行DC繪圖
g_pDDSOverlay->ReleaseDC(hDC);
第二種狀況當知道頁面的像素格式,Lock頁面獲取頁面指針,直接操作頁面存儲區。
g_pDDSOverlay->Lock(NULL,&ddsd,0,NULL);
BYTE *pFramePhyPtr = (LPBYTE)ddsd.lpSurface;
int framesize = DDRAW_X * DDRAW_Y;
memcpy(pFramePhyPtr,src[0],framesize);
memcpy(pFramePhyPtr + framesize,src[2],framesize / 4);
memcpy(pFramePhyPtr + framesize + framesize / 4,src[1], framesize / 4);
g_pDDSOverlay->Unlock(NULL);//YUV4:1:1

8.遍歷後臺頁面

EnumAttachedSurfaces
enumerates all the surfaces attached to a given primary surface.
可以先到後臺頁面上繪製,然後Flip操作.

9.注意要點
不要頻繁調用UpdateOverLay。
注意頁面的像素格式與圖像幀的像素格式的匹配,
爲了加快顯示速度,最好與顯示驅動所支持的像素格式相同。
可以用後臺頁面和Flip操作,加快頁面顯示。

轉自:http://blog.163.com/penjiang_1652/blog/static/16558440620107410233749/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章