? DDSD_BACKBUFFERCOUNT 表示您想要建立一个后缓冲区。
? DDSCAPS_PRIMARYSURFACE 表示主绘图页的型态描述。
? DDSCAPS_3DDEVICE 这个绘图页可用在3d成像中。
? DDSCAPS_FLIP 表示该绘图页是一个切页结构的一部分。
? DDSCAPS_COMPLEX 表示某个复合绘图页正在描述中。一个复合绘图页意谓着建
立一个以上的绘图页,而另外增加的绘图页则是附加在根绘图页下。
如果您是在立体视讯模式(stereo video mode)下执行,您还需要指定二个旗标: ? DDSCAPS_VIDEOMEMORY 绘图页存在显示记忆中。
? DDSCAPS2_STEREOSURFACELEFT 该绘图页是立体模式切换页连结(stereo
flipping chain)的一部分。当呼叫IDirectDraw7::CreateSurface过程中设定本旗标值时,在主切页连结中的每个缓冲区中都会建立一对立体模式绘图页。您必须建立一个复合切换页连结(利用后缓冲区)。您不能建立单一的立体模式绘图页。IDirectDrawSurface7::Flip方法需要有后缓冲区,因此您必须建立四个以上的绘图页。如果因为呼叫IDirectDraw7::EnumDisplayModes或
IDirectDraw7::GetDisplayMode的结果而导致DDSURFACEDESC2中设定这个值,意谓着在该模式下也支持立体模式。
因为我们早就说过我们需要复合切换页绘图页,我们也要指定需要的后缓冲区数量。因此,我们将dwBackBufferCount成员设为1来表示我们只要一个后缓冲区。
步骤4中,我们利用IDirectDraw7::CreateSurface方法来建立前缓冲区,使用在ddsd结构里设定的旗标值,将新的绘图页存入m_pddsFrontBuffer变数中。
步骤5中,我们呼叫IDirectDraw7::GetAttachedSurface方法来取得前缓冲区。这个方法会取得具有需求功能(在本例中,是指后缓冲区)的附加绘图页。方法的定义如下:
HRESULT GetAttachedSurface (
LPDDSCAPS2 lpDDSCaps,
LPDIRECTDRAWSURFACE7 FAR *lplpDDAttachedSurface
); 参数 lpDDSCaps lplpDDAttachedSurface 说明 DDSCAPS2结构的地址。该结构中包含了绘图页的硬件 特性。 储存了指到取得绘图页的IDirectDrawSurface7接口指 标的变量的地址。所谓取得绘图页是指符合 lpDDSCaps参数的描述。 最后的步骤6中,如果您是在立体视讯模式下执行的话,您会有一个指标指向第二个后缓冲区。如果您想要这个模式,请以第二个后缓冲区来呼叫
IDirectDraw7::GetAttachedSurface。(主要针对左边的图,因为我们会用第一个后缓冲区来处理右边的图)。
到此,我们已可在全屏幕模式下执行绘图页的成像作业。
窗口模式的缓冲区
如果您希望在窗口模式而非全屏幕模式下执行程序,您需要去修改一些设定值。以下是在窗口模式下执行时的相关原始程序代码:
//-------------------------------------------------------------------
//名称:CreateWindowedBuffers
//说明:建立绘制时的主绘图页和(选择性的)后缓冲区。 // //
//-------------------------------------------------------------------
HRESULT CD3DFramework7::CreateWindowedBuffers() {
HRESULT hr; //步骤1-窗口模式
//取得检视端口和屏幕边界的尺寸。
GetClientRect(m_hWnd,&m_rcScreenRect);
ClientToScreen(m_hWnd,(POINT*)&m_rcScreenRect.left); ClientToScreen(m_hWnd,(POINT*)&m_rcScreenRect.right); m_dwRenderWidth =m_rcScreenRect.right -m_rcScreenRect.left; m_dwRenderHeight =m_rcScreenRect.bottom -m_rcScreenRect.top; 窗口模式和全屏幕模式的处理方式不同。
//步骤2-窗口模式 //建立主绘图页 DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd,sizeof(ddsd)); ddsd.dwSize ddsd.dwFlags
=sizeof(ddsd); =DDSD_CAPS;
ddsd.ddsCaps.dwCaps =DDSCAPS_PRIMARYSURFACE; //步骤3-窗口模式
if(FAILED(hr =m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL))) { }
//步骤4-窗口模式
//如果在窗口模式下时,会建立裁切对象。 LPDIRECTDRAWCLIPPER pcClipper;
if(FAILED(hr =m_pDD->CreateClipper(0,&pcClipper,NULL))) { }
//步骤5-窗口模式
//加上裁切和窗口间的关联性 pcClipper->SetHWnd(0,m_hWnd);
m_pddsFrontBuffer->SetClipper(pcClipper); SAFE_RELEASE(pcClipper); //步骤6-窗口模式 //建立后缓冲区
DEBUG_MSG(_T(\)); return D3DFWERR_NOCLIPPER;
DEBUG_MSG(_T(\if(hr !=DDERR_OUTOFVIDEOMEMORY) return D3DFWERR_NOPRIMARY;
DEBUG_MSG(_T(\)); return DDERR_OUTOFVIDEOMEMORY;
surface\));
}
ddsd.dwFlags ddsd.dwWidth ddsd.dwHeight ddsd.ddsCaps.dwCaps
=DDSD_WIDTH |DDSD_HEIGHT =m_dwRenderWidth;
|DDSD_CAPS;
=m_dwRenderHeight; =DDSCAPS_OFFSCREENPLAIN
|DDSCAPS_3DDEVICE;
if(FAILED(hr =m_pDD->CreateSurface(&ddsd, NULL))) { }
ZeroMemory(&m_ddpfBackBufferPixelFormat,sizeof
m_ddpfBackBufferPixelFormat.dwSize =sizeof(DDPIXELFORMAT); hr =m_pddsBackBuffer-> GetPixelFormat
hr =m_pddsBackBuffer->GetSurfaceDesc(&ddsd); return S_OK;
DEBUG_ERR(hr,_T(\if(hr!=DDERR_OUTOFVIDEOMEMORY) return DDERR_OUTOFVIDEOMEMORY;
backbuffer\));
DEBUG_MSG(_T(\));
(DDPIXELFORMAT));
(&m_ddpfBackBufferPixelFormat);
步骤1中,我们用窗口的GetClientRect程序来取得窗口的边界区。这个程序会透过参数m_rcScreenRect传回窗口的边界区数据。我们则可用ClientToScreen程序来将左方和右方的后缓冲区显示坐标转换成屏幕坐标。这个程序会用相等的屏幕坐标去取代
m_rcScreenRect结构中的请求端坐标。这些新计算出来的屏幕坐标则是对应到系统显示屏的左上角。在程序的最后两行,屏幕的宽度和高度会重新计算。
步骤2中,会建立一个DDSURFACEDESC2结构,而DDSCAPS_PRIMARYSURFACE旗标则是被设定成我们想要建立主绘图页。
步骤3中,我们会呼叫IDirectDraw7::CreateSurface方法来在视讯内存中建立前缓冲区,并存入变量m_pddsFrontBuffer中。
步骤4中,我们建立一个裁切对象。虽然当程序在全屏幕模式下执行时不需要裁切,窗口模式下却是必须的,因为如此才能处理当某窗口被其它窗口部分遮蔽时,或是有部分跑出显示
区域时的状况。这种裁切可以避免非预期的窗口外成像,或是跑到其它窗口或桌面上的情形。
在步骤5中,我们呼叫了IDirectDrawClipper::SetHWnd来设定裁切对象可用的窗口代码,以取得裁切信息。这个方法的定义如下:
HRESULT SetHWnd( DWORD dwFlags, HWND hWnd ); 参数 说明 dwFlags 目前本参数没有作用,必须设为0。 hWnd 取得裁切信息的窗口代码。 我们会再呼叫IDirectDrawSurface7::SetClipper来将裁切对象加入绘图页上。这个方法的定义如下:
HRESULT SetClipper ( );
IDirectDrawSurface7::SetClipper只有一个参数lpDDClipper,它是用来记住
DirectDrawClipper对象的IDirectDrawClipper接口的地址,而DirectDrawClipper对象则是会附属在DirectDrawSurface对象下,如果这个参数是NULL值时,目前的DirectDrawClipper对象会被拆开。
最后在步骤6中,我们用IDirectDraw7::CreateSurface来建立实际的后缓冲区。到此,整个程序已经准备好要在全屏幕或窗口模式下执行了。
LPDIRECTDRAWCLIPPER lpDDClipper
切换绘图页
切换绘图页(Page flipping)是一个很重要的功能,可以提高程序图形的可看度。所谓后缓冲区是指发生写入动作的隐藏绘图页。将检视内容从目前的显示缓冲区(屏幕上所见)切换到后缓冲区计算(绘)出的内容的过程称为切换绘图页。切换绘图页使用了多个绘图页,可以在显示一个绘图页的同时计算另一个。一旦运用这种技巧使用多个缓冲区,您可以想见这种画面间的转换一定很平顺,亳无画面切割。画面切割多会发生在一个动态图像被绘出时就有改变的时候。
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库设定Direct 3D应用程序中的DirectDraw(8)在线全文阅读。
相关推荐: