DX锁屏后设备的恢复

DX程序,运行时,锁屏后,再进入,就发现画面卡主了。

实际上是设备没有恢复的缘故。

 	HRESULT hr = device->TestCooperativeLevel();
  	if (hr == D3DERR_DEVICELOST)
  	{
  		// 设备丢失
  	}
  	else if (hr == D3DERR_DEVICENOTRESET)
  	{
  
  		// 设备可以恢复
                 // 删除自分配的内存
 				// 在对设备调用 Reset 前,
 				// 应用程序应释放任何与该设备相关联的
 				// 显式呈现目标、深度模具图面、附加交换链、状态块以及默认资源。
 		// d3dpool_managed可以不管
  		g_vb->Release();
  		g_ib->Release();
                 // 恢复设备
  		hr = device->Reset(&g_d3dpp);
         }
  
 设置设备参数:(只是一个例子)
         D3DPRESENT_PARAMETERS g_d3dpp;
  
 	g_d3dpp.BackBufferWidth = 700;
  	g_d3dpp.BackBufferHeight = 700;
  	g_d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
  	g_d3dpp.BackBufferCount = 1;
  	g_d3dpp.hDeviceWindow = 0;//mWindowHandle;
  	g_d3dpp.Windowed = TRUE;
  	g_d3dpp.Flags = 0;
  	g_d3dpp.FullScreen_RefreshRateInHz = 0;
  	g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
  
  	// Request depth and stencil buffers.
  	g_d3dpp.EnableAutoDepthStencil = TRUE;
  	g_d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
  
  	// Request multisampling.
  	g_d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP; 
  	g_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
  	g_d3dpp.MultiSampleQuality = 0;
  
 


如果Reset失败,一般是以下异常

异常 条件
InvalidCallException

方法调用无效。例如,参数可能包含无效值。

DriverInternalErrorException

内部驱动程序错误。当收到此错误时,应用程序通常会关闭。

OutOfMemoryException

Direct3D 无法分配足够的内存来完成调用。


切换到全屏模式时,Direct3D 会尝试找到一种与后台缓冲区格式匹配的桌面格式,以便后台缓冲区格式和前台缓冲区格式相同。这样就无需转换颜色了。

如果对 Reset 的调用失败,除非设备处于“未重置”状态(由从 CheckCooperativeLevel 方法的 hResult 参数返回的 DeviceNotReset 来指示),否则设备会被置于“丢失”状态(由从对CheckCooperativeLevel 的调用返回的值 false 指示)。

调用 Reset 将导致所有纹理内存图面和状态信息丢失,并且还会导致托管纹理在视频内存中被刷新。在对设备调用 Reset 前,应用程序应释放任何与该设备相关联的显式呈现目标、深度模具图面、附加交换链、状态块以及默认资源。

交换链可以是全屏的,也可以是窗口式的。如果新的交换链是全屏的,则会将适配器置于与新大小匹配的显示模式中。

如果调用 Reset 的线程不是用来创建所要重置的设备的线程,则该调用将失败。

调用 DeviceReset 和 SwapChain 时,可以将窗口模式后台缓冲区的格式指定为“未知”。这意味着应用程序在窗口模式下调用 Device 前不必查询当前的桌面格式。对于全屏模式,必须指定后台缓冲区格式。将 BackBufferCount 设置为 0 会创建一个后台缓冲区。

尝试成组重置多个显示适配器时,可传入 PresentParameters 对象数组,该数组中的每个对象都对应于该适配器组中的一个显示适配器。


设备恢复成功了,可以重设各种矩阵以及视点。

// 伪代码

Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_DirectX(90.0f, 1.0f, 0.1f, 100.0f);
  // 设置视角转换矩阵
  device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &projection_matrix);
  // 关闭光照
  device->SetRenderState(D3DRS_LIGHTING, FALSE);
  // 改变三角形正面的法线
  device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
  // `计算出一个可以转换到镜头坐标系的矩阵`
  Matrix4x4 view_matrix = GutMatrixLookAtRH(g_eye, g_lookat, g_up);
  device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix);
 


问题:

还是有不解的地方

1. 多适配器怎么恢复

2. 一直还是恢复失败,究竟要删除哪些东西啊,纹理?顶点?特效?Sprite?,具体有哪些啊?

   对于简单的程序,像上面那么做就可以了,但是复杂的程序要一个个排除啊。。。有没有一个CheckList?

3. SetSourceSream是d3dpool_defaul还是d3dpool_managed


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值