DirectDraw 常用功能代码记录
记录一些常用的代码功能段便于自己以后查找使用:
1.常用宏和函数
#define SafeRelease(lpx) if(lpx!=NULL){lpx->Release();lpx=NULL;}//释放COM #define DD_Call(callcode) if(FAILED(callcode))return DD_FALSE //安全创建 #define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); } //初始化结构体 #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) //按键判断 #define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) #define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))//颜色设置 #define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10)) #define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24)) /*每个像素16位,用此函数前先锁住表面。*/ inline void Plot_Pixel_Faster16(int x, int y,int red, int green, int blue,USHORT *video_buffer, int lpitch16) { USHORT pixel = _RGB16BIT565(red,green,blue); video_buffer[x + y*lpitch16] = pixel; } inline void Plot_Pixel_32(int x, int y,int alpha,int red, int green, int blue,UINT *video_buffer, int lpitch32) { UINT pixel = _RGB32BIT(alpha,red,green,blue); video_buffer[x + y*lpitch32] = pixel; }
2.初始化Device
bool graphicApp::initDevice(HWND hwnd,D3DDEVTYPE dType,bool windowed,int _width,int _height) { width=_width; height=_height; IDirect3D9* _direct=0; HRESULT result=0; D3DCAPS9 caps; _direct=Direct3DCreate9(D3D_SDK_VERSION); if (!_direct) { MessageBoxA(0,"create Directx filed!","create error",MB_OK); return false; } _direct->GetDeviceCaps(D3DADAPTER_DEFAULT,dType,&caps); int vp=0; if (caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT) { vp=D3DCREATE_HARDWARE_VERTEXPROCESSING; }else { vp=D3DCREATE_SOFTWARE_VERTEXPROCESSING; } D3DPRESENT_PARAMETERS d3pp; d3pp.BackBufferWidth=width; d3pp.BackBufferHeight=height; d3pp.BackBufferFormat=D3DFMT_A8R8G8B8; d3pp.BackBufferCount=1; d3pp.MultiSampleType=D3DMULTISAMPLE_NONE; d3pp.MultiSampleQuality=0; d3pp.SwapEffect=D3DSWAPEFFECT_DISCARD; d3pp.hDeviceWindow=hwnd; d3pp.Windowed=windowed; d3pp.EnableAutoDepthStencil=true; d3pp.AutoDepthStencilFormat=D3DFMT_D24S8; d3pp.Flags=0; d3pp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT; d3pp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE; result=_direct->CreateDevice(D3DADAPTER_DEFAULT,dType,hwnd,vp,&d3pp,&pDevice); if (FAILED(result)) { MessageBoxA(0,"create Device filed!","create error",MB_OK); } _direct->Release(); return true; }
3.设置协作等级
//窗口模式 if (FAILED(m_pDD->SetCooperativeLevel(m_hwnd, DDSCL_NORMAL))) return false; //全屏模式 if (FAILED(m_pDD->SetCooperativeLevel(m_hwnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) return false;
4.设置模式
if (FAILED(m_pDD->SetDisplayMode(m_iWidth,m_iHeight,m_iBpp,0,0))) return false;
5.创建主页面
DDSURFACEDESC2 ddsd; //页面描述 memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize=sizeof(ddsd); ddsd.dwFlags=DDSD_CAPS; ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE; hresult=m_pDD->CreateSurface(&ddsd,&lpDDSPrimary,NULL); if (hresult!=DD_OK) return false;
6.创建离屏页面
//创建离屏表面
DDSURFACEDESC2 ddsd; //页面描述
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS; ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth=m_iWidth; ddsd.dwHeight=m_iHeight; if(m_pDD->CreateSurface(&ddsd,&lpDDSTempBuffer,NULL)!=DD_OK) return false;
7.创建后背缓冲(只有在全屏模式下才可以)
DD_INIT_STRUCT(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // 增加DDSD_BACKBUFFERCOUNT 表明dwBackBufferCount有效 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; // 多了 DDSCAPS_COMPLEX | DDSCAPS_FLIP ddsd.dwBackBufferCount = 1; // 后备缓冲的个数 if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL))) return 0; ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; // 请求一个后备缓冲 if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback))) // 得到后备缓冲 return 0;
8.创建裁剪器
//裁剪器 LPDIRECTDRAWCLIPPER lpDDClipper=NULL; if (FAILED(m_pDD->CreateClipper(0,&lpDDClipper,NULL))) return false; if (FAILED(lpDDClipper->SetHWnd(0,m_hwnd))) return false; if (FAILED(lpDDSPrimary->SetClipper(lpDDClipper))) return false; LPRGNDATA region_data;
9.创建调色板
LPDIRECTDRAWPALETTE lpPalette; //调色板 PALETTEENTRY palette[256]; for(int i=1;i<255;i++) { palette[i].peRed=rand()%256; palette[i].peGreen=rand()%256; palette[i].peBlue=rand()%256; palette[i].peFlags=PC_NOCOLLAPSE; } palette[0].peRed=0; palette[0].peGreen=0; palette[0].peBlue=0; palette[0].peFlags=PC_NOCOLLAPSE; palette[255].peRed=255; palette[255].peGreen=255; palette[255].peBlue=255; palette[255].peFlags=PC_NOCOLLAPSE; if (m_pDD->CreatePalette(DDPCAPS_8BIT|DDPCAPS_ALLOW256|DDPCAPS_INITIALIZE,palette,&lpPalette,NULL)!=DD_OK) return false; if (FAILED(lpDDSPrimary->SetPalette(lpPalette)))
10.用DDBLTFX的color填充表面
DDBLTFX ddfx; DD_INIT_STRUCT(ddfx); int red=rand()%256; int green=rand()%256; int blue=rand()%256; ddfx.dwFillColor=_RGB32BIT(0,red,green,blue); RECT dest_rect; dest_rect.left=rand()%m_iWidth; dest_rect.right=rand()%m_iWidth; dest_rect.top=rand()%m_iHeight; dest_rect.bottom=rand()%m_iHeight; dest_rect.left=250; dest_rect.right=400; dest_rect.top=250; dest_rect.bottom=400; hret=lpDDSPrimary->Blt(&dest_rect,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&ddfx); if (hret!=DD_OK) { char temp[512]; //memset(temp,sizeof(temp)); sprintf_s(temp,"Blt Error:%s",DXGetErrorString(hret)); MessageBox(NULL,temp,"ERROR",0); return false; }return false;
11.用另一个表面填充表面
RECT src_rect; src_rect.left=0; src_rect.top=0; src_rect.right=m_iWidth; src_rect.bottom=m_iHeight; //用客户端位置进行blt RECT m_x2d_ClientRect; GetClientRect(m_hwnd, &m_x2d_ClientRect); ClientToScreen(m_hwnd, (LPPOINT)&m_x2d_ClientRect); ClientToScreen(m_hwnd, (LPPOINT)&m_x2d_ClientRect+1); hret=lpDDSPrimary->Blt(&m_x2d_ClientRect,lpBackBuffer,&src_rect,DDBLT_WAIT,NULL); if (hret!=DD_OK) { char temp[512]; sprintf_s(temp,"Blt Error:%s",DXGetErrorString(hret)); MessageBox(NULL,temp,"ERROR",0); return false; }
12.随机设置32位色深表面
DD_INIT_STRUCT(ddsd); if(FAILED(lpDDSPrimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL))) return false; int memPitch=(int)(ddsd.lPitch>>2); UNINT *video_buffer=(UNINT *)ddsd.lpSurface; for (int i=0;i<1000;i++) { int x=rand()%m_iWidth; int y=rand()%m_iHeight; int red=rand()%256; int green=rand()%256; int blue=rand()%256; Plot_Pixel_32(x,y,0,red,green,blue,video_buffer,memPitch); } if(FAILED(lpDDSPrimary->Unlock(NULL))) return false;
13.HDC载入位图到表面
HBITMAP hBitmap; hBitmap = (HBITMAP)LoadImage(NULL, "test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); HDC hdcImage; HDC hdc; BITMAP bm; lpBackBuffer->Restore(); hdcImage = CreateCompatibleDC(NULL); SelectObject(hdcImage, hBitmap); GetObject(hBitmap, sizeof(bm), &bm); lpBackBuffer->GetDC(&hdc); BitBlt(hdc, 0, 0, 800, 600, hdcImage, 0, 0, SRCCOPY); lpBackBuffer->ReleaseDC(hdc); DeleteDC(hdcImage);
14.清空一个页面
DDBLTFX ddBltFx; ddBltFx.dwSize=sizeof(DDBLTFX); ddBltFx.dwFillPixel=0; DDS[SBuffer]->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);