2011年3月11日 onedouble.net

 

     原来总发现最小化侯再打开会失去键盘鼠标响应,最近搞明白,原来这就是TMD的设备丢失啊,丢失了该怎么办呢?先试着小心翼翼地问电脑,可以恢复吗(Reset())?带点儿小舌的颤音,非常好,就是这样。如果丫告诉你不行,抽他丫的,然后再问,直到屈打成招表示情绪稳定可以恢复,则销毁所有的显存资源和所有的交换链(swap chains),然后调用Reset()函数恢复设备。创建时使用D3DPOOL_MANAGED标志的资源可以不需要重新载入,但D3DPOOL_DEFAULT加载的资源就需要先释放,后重建。通常需要这样处理的有ID3DXFont和ID3DXSprite,而.X模型什么的就不需要。

如果设备丢失,Present()函数就会“出问题”,返回值是D3DERR_DEVICELOST。所以我会在绘制结束调用present函数之后检查调用结果以判断是否设备丢失.

 1 m_pIDirect3DDevice->EndScene();
2
3 HRESULT hr;
4 hr = m_pIDirect3DDevice->Present(NULL, NULL, NULL, NULL);
5 if(hr == D3DERR_DEVICELOST)
6 {
7 if(m_pIDirect3DDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET)
8 {
9 OnLostDevice();
10 OnResetDevice();
11 }
12 }



TestCooperativeLevel()== D3DERR_DEVICENOTRESET时,就可以恢复设备了。
于是,我们调用OnLostDevice()让D3DPOOL_DEFAULT加载的资源释放掉,之后,调用OnResetDevice()来恢复设备就可以了。

好在ID3DXFont和ID3DXSprite有设备丢失处理函数,直接调用就好了

1 void OnLostDevice(void)
2 {
3 m_sprite->OnLostDevice();
4 m_font->OnLostDevice();
5 }



再 写个恢复函数

 1 void OnResetDevice(void)
2 {
3 if(FAILED(m_pIDirect3DDevice->Reset(&d3dpp)))
4 {
5 return;
6 }
7
8 m_sprite->OnResetDevice();
9 m_font->OnResetDevice();
10
11 InitDevice();
12 }



最后,需要把D3D设备中的状态啊,矩阵变换啊这些重新设置下就完成了,也就是调用InitDevice()。

 1 void InitDevice()
2 {
3 m_pIDirect3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
4
5 m_pIDirect3DDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );
6
7 m_pIDirect3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
8 m_pIDirect3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
9 m_pIDirect3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
10
11 D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f );
12 m_pIDirect3DDevice->SetTransform( D3DTS_PROJECTION, &matProj );
13
14 vEyeVec=D3DXVECTOR3(0.0f,0.0f,-1.0f);
15 vLookatVec=D3DXVECTOR3(0.0f,0.0f,0.0f);
16 vUpVec=D3DXVECTOR3(0.0f,1.0f,0.0f);
17 D3DXMatrixLookAtLH( &matView, &vEyeVec, &vLookatVec, &vUpVec );
18 m_pIDirect3DDevice->SetTransform( D3DTS_VIEW, &matView );
19
20 }