DirectDraw
一、DirectDraw接口
DirectDraw接口图如下:
1、IUnknown:所有COM对象都必须从这个基本接口派生
2、IDirectDraw:这是开始使用DirectDraw时必须创建的主接口对象
3、IDirectDrawSurface:这表示你用DirectDraw创建、控制和显示的实际显示表面。分两种:主显示表面(Primary Surface)和从显示表面(Secondary Surface)
4、IDirectDrawPalette:使用256或更少的颜色在视频模式下处理调色板,用于创建、加载和控制调色板,以及将调色板关联到显示表面
5、IDirectDrawClipper:用于帮助剪切DirectDraw光栅和位图操作到一些可见显示表面的子集
二、创建DirectDraw对象
HRESULT WINAPI DirectDrawCreateEx(GUID FAR *lpGUID, //全局唯一标识符,为NULL时表示系统缺省配置
LPVOID *lplpDD, //指向IDirectDraw接口的指针
REFIID iid, //请求的接口的ID
IUnknown FAR *pUnkOuter //总是为NULL
);
对DirectDraw进行错误处理:FAILED()——检测是否失败,SUCCEEDED()——检测是否成功
例子:LPDIRECTDRAW7 lpdd7=null;
if(FAILED(DirectDrawCreateEx(NULL,(void**)&lpdd7,IID_IDirectDraw7,NULL))){
//错误处理
}
三、与Windows协作
对于DirectDraw来说,视频显示设备有两种模式:全屏模式(Full-screen Mode)和窗口模式(Windows Mode),在窗口模式下,DirectDraw必须更多的与Windows协作,因为其他应用程序可能更新它们各自的客户窗口区域。
要设置DirectDraw的协作级别,需要调用IDirectDraw7的一个方法:IDirectDraw7::SetCooperativeLevel()函数。
HRESULT SetCooperativeLevel(HWND hwnd,DWORD dwFlags);
控制标记dwFlags常用的值有:
DDSCL_ALLOWMODEX:允许使用Mode X(320*200、240、400)显示模式,仅当设置DDSCL_EXCLUSIVE和DDSCL_FULLSCREEN时生效
DDSCL_ALLOWREBOOT:允许在排除(全屏)模式下检测到Ctrl+Alt+Del
DDSCL_EXCLUSIVE:请求排他级别,需要与DDSCL_FULLSCREEN标记同时使用
DDSCL_FULLSCREEN:使用全屏模式
DDSCL_NORMAL:表示应用程序是一个通常的Windows应用程序
例:
if(FAILED(lpdd7->SetCooperativeLevel(hwnd,DDSCL_FULLSCREEN|DDSCL_ALLOWMODEX|DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT))){
//错误处理
}
四、设置模式
设置模式的函数叫做SetDisplayMode()
HRESULT SetDisplayMode(DWORD dwWidth, //显示的屏幕宽度
DWORD dwHeight, //显示的屏幕高度
DWORD dwBPP, //每像素是8位还是16、24、32位
DWORD dwRefreshRate, //刷新频率,模式为0
DWORD dwFlags //默认为0
);
例:
lpdd->SetDisplayMode(800,600,16,0,0); //设置16位增强色的800*600模式
五、创建显示表面
1、显示在屏幕上的图形只不过是以某种格式存储在内存中的有色像素组成的矩阵,或是调色板的或是RGB模式的。有两种显示表面:主表面和从表面。
主表面:表示直接相当于被显卡光栅化的实际显存,且任何时候都是可见的,只能有一个主表面,它直接指向屏幕图像并常驻于VRAM。
从表面:总是和主显示面有同样的色彩深度和几何分布,可以驻留在VRAM或是系统内存中。
2、创建任何显示表面的步骤:
A、填充一个DDSURFACEDESC2数据结构,描述你所希望创建的显示表面。
B、调用IDirectDraw7::CreateSurface()来创建显示表面。
HRESULT CreateSurface(LPDDSURFACEDESC2 lpDDSurfaceDesc2, //显示表面的描述
LPDIRECTDRAWSURFACE4 FAR *lplpDDSurface, //指向新的显示表面接口
IUnknown FAR *pUnkOuter //默认为NULL
);
DDSURFACEDESC2的主要成员有:
dwsize:值设置为sizeof(DDSURFACEDESC2)
dwFlags:用来指示DirectDraw会把有效数据填充到哪个域中。
dwWidth:显示表面以像素计的宽度
dwHeight:显示表面以像素计的高度
IPitch:是该显示模式中每行上的字节数,也被称为步幅或内存宽度
lpSurface:用来获取指向你所创建的显示表面所驻留的实际内存的指针
dwBackBufferCount:如果只使用一个后备缓冲称为双缓冲,使用两个后备缓冲的技术称为三重缓冲
ddckCKDestBlt:控制目标色键,在位块传输操作中控制可以写入的色彩的部件
ddckCKSrcBlt:指示源色键
ddpfPixelFormat:获取显示表面的像素格式
ddsCaps:用来返回你所请求的显示表面的一些未在别处定义的属性。
3、关联调色板
HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette); //这个参数是你希望关联的调色板的指针
4、绘制像素
所有的DirectDraw显示模式和显示表面都是线性的,这意味着当你从一行移到另一行时,内存从左到右,从顶到下的增长。
5、锁内存
HRESULT Lock(LPRECT lpDestRect, //需要加锁的矩形区域,为NULL时表示整个表面
LPDDSURFACEDESC2 lpDDSurfaceDesc, //你请求的显示表面的信息
DWORD dwFlags, //告诉Lock()你想做什么,常用DDLOCK_SURFACEMEMORYPTR,DDLOCK_WAIT
HANDLE hEvent //协助一个Win32支持的高级特性——事件
);
例:
DDSURFACEDESC2 ddsd;
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
if(FAILED(lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT))){
//error
}
解锁用Unlock,将lock命令使用的RECT传给Unlock()
例:lpddsprimary->Unlock(NULL);