2014-01-07 3 views
0

Я jusing без полого окна и скопировал код сброса устройства из видео 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

Итак, у вас есть исходный код для этой простой игры, которая сработала? Если это так, вы можете сравнить. Единственное, что я вижу, это то, что если первый «Сброс» терпит неудачу, для 'InvalidateRect' это нормально, чтобы получить еще одну перерисовку, чтобы повторить попытку. –

ответ

2

В образце вы связаны, что работает, ошибка на Reset результаты в return и функция render снова вызывается. Это нормально - нет причин, по которым 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); 
    } 
} 

Кроме того, вы должны убедиться, что TestCooperativeLevel и Reset вызываются из той же нити, которая была использована для создания устройства.

+0

Спасибо, но я попробовал, и он не смог сбросить и разбился на 2-й InvalidateDeviceObjects()/OnLostDevice(). Я добавил что-то, чтобы использовать InvalidateDeviceObjects()/OnLostDevice() только один раз (неправильно?), Но затем он просто терпит неудачу при каждом Сбросе. Я не использую Threads. – Vider7CC

+0

Есть ли список или что-то в том, что делать -> release()/delete или -> onlostdevice()? Я не использую текстуры, шрифты или спрайты. Только Меши и Свет. – Vider7CC

+0

@ Vider7CC Да, цитируя [отсюда] (http://msdn.microsoft.com/en-us/library/windows/desktop/bb174425 (v = vs.85) .aspx) - * «Вызов IDirect3DDevice9 :: Сброс заставляет все поверхности текстурной памяти потеряться, управляемые текстуры, которые должны быть сброшены из видеопамяти, и вся информация о состоянии, которая должна быть потеряна. Перед вызовом метода IDirect3DDevice9 :: Reset для устройства приложение должно освободить любые явные цели рендеринга, глубинные трафаретные поверхности , дополнительные цепи подкачки, государственные блоки и ресурсы D3DPOOL_DEFAULT, связанные с устройством. * *. –

Смежные вопросы