2014-01-07 45 views
0

我j使用一个无国界的窗口和复制从YouTube视频设备复位代码,并在那里工作,但我只是从那里得到消息:DIRECTX9:按Ctrl + Alt + Del键后重置设备

if(FAILED(hr)){ 
    MessageBox(0, "Failed to reset device!", 0, 0); 
    return; 
} 

我哪里错了?我忘了InvalidateDeviceObjects()的东西吗?我可以给你更多的代码,但不是全部,因为它太长了。 我真的需要帮助......

重置设备:

void Render(){ 

if(HandleDeviceLost/*VK_F1*/){ 
    if(DeviceLost){ 
     Sleep(100); 
     if(FAILED(hr=d3ddev->TestCooperativeLevel())){ 

      if(hr==D3DERR_DEVICELOST){ 
       return; 
      } 
      if(hr==D3DERR_DEVICENOTRESET){ 

       //clean 
       InvalidateDeviceObjects(); 

       //reset device 
       hr=d3ddev->Reset(&d3dpp); 

       if(FAILED(hr)){ 
        MessageBox(0, "Failed to reset device!", 0, 0); 
        return; 
       } 

       //restore 
       RestoreDeviceObjects(); 
      } 
      return; 
     } 
    } 
} 
DeviceLost=0; 

/* 
    Stuff 
*/ 

hr=d3ddev->Present(NULL, NULL, NULL, NULL); 
if(hr==D3DERR_DEVICELOST){ 
    DeviceLost=1; 
} 
} 


发行对象:

void InvalidateDeviceObjects(){ 

    buffShipMaterial->Release(); 
    Wall_large->Release(); 
    Wall_small->Release(); 
    space_text->Release(); 
    meshWall->Release(); 
    menuText->Release(); 
    menuText2->Release(); 
    menuText3->Release(); 
    text_cpu->Release(); 
    text_player->Release(); 
    text_player2->Release(); 
    number_0->Release(); 
    number_1->Release(); 
    number_2->Release(); 
    number_3->Release(); 
    number_4->Release(); 
    number_5->Release(); 
    number_6->Release(); 
    number_7->Release(); 
    number_8->Release(); 
    number_9->Release(); 
    number_10->Release(); 
} 
+1

我在切换用户或锁定屏幕时遇到过XP - 这似乎是一个驱动程序问题,唯一的解决方法是拆卸并重建整个DX9系统,就像在应用程序启动时一样。具有不同gfx卡的类似系统可以。 –

+0

我想这是在代码中的东西,因为我尝试(下载)一个简单的游戏与设备重置和它的工作。 – Vider7CC

+0

所以你有这个简单的游戏工作的源代码?如果是这样,你可以比较。我唯一能看到的是,如果第一个'Reset'失败,那么对'InvalidateRect'进行另一次重绘是正常的,所以你再试一次。 –

回答

2

在这种工作,你链接的样品,上Reset错误导致returnrender函数再次被调用。这很正常 - 没有理由为什么Reset必须在第一次调用中成功,所以通常会继续重试,而不是像在代码中那样显示错误消息。

如果你在消息循环中进行渲染,就像在那个例子中一样,只要做同样的事情 - 当你遇到错误时不要停下来。

如果你没有在消息循环中渲染,但使用WM_PAINT方法,那么这是我使用的一般模式 - 虽然有时我设置了一个定时器而不是调用InvalidateRect,它取决于应用程序 - 但是这个对于许多应用程序足够强大。您可以看到Reset在失败时会如何重复,而不是在第一次失败时抛出错误消息。这可能是一个想法,通过这种模式:

void CMyClass::DrawScene() 
{ 
    // perform all dx9 scene drawing 
    HRESULT hr; 

    // if device was lost, try to restore it 
    if (m_bDeviceLost) 
    { 
     // is it ok to render again yet? 
     if (FAILED(hr = m_pD3DDevice->TestCooperativeLevel())) 
     { 
      // the device has been lost but cannot be reset at this time 
      if (hr == D3DERR_DEVICELOST) 
      { 
       // request repaint and exit 
       InvalidateRect(NULL); 
       return; 
      } 

      // the device has been lost and can be reset 
      if (hr == D3DERR_DEVICENOTRESET) 
      { 
       // do lost/reset/restore cycle 
       OnLostDevice(); 
       hr = m_pD3DDevice->Reset(&m_pD3Dpp); 
       if (FAILED(hr)) 
       { 
        // reset failed, try again later 
        InvalidateRect(NULL); 
        return; 
       } 
       OnResetDevice(); 
      } 
     } 

     // flag device status ok now 
     m_bDeviceLost = false; 
    } 

    // ... clear to background and do the drawing ... 

    // display scene 
    hr = m_pD3DDevice->Present(NULL, NULL, GetSafeHwnd(), NULL); 
    m_bDeviceLost = (hr == D3DERR_DEVICELOST); 

    // request repaint if device has been lost 
    if (m_bDeviceLost) 
    { 
     InvalidateRect(NULL); 
    } 
} 

此外,还必须确保TestCooperativeLevelReset是从被用来创建设备在同一个线程调用。

+0

谢谢,但我试过了,它失败了重置并崩溃在第二InvalidateDeviceObjects()/ OnLostDevice()。我添加了一些使用InvalidateDeviceObjects()/ OnLostDevice()一次(错误?),但它只是失败了每次重置。我不使用线程。 – Vider7CC

+0

是否有一个列表或什么 - >释放()/删除或 - > onlostdevice()?我不使用纹理,字体或精灵。只是网格和光。 – Vider7CC

+0

@ Vider7CC是的,引用[from here](http://msdn.microsoft.com/en-us/library/windows/desktop/bb174425(v = vs.85).aspx) - *“调用IDirect3DDevice9 :: Reset导致所有纹理内存表面丢失,管理的纹理从视频内存中被刷新,并且所有的状态信息都将丢失。在调用设备的IDirect3DDevice9 :: Reset方法之前,应用程序应释放任何显式的渲染目标,深度模板表面,与设备关联的附加交换链,状态块和D3DPOOL_DEFAULT资源。“*。 –