Question

I'm jusing a borderless Window and copied the device reset code from a Youtube video and it worked there but I just get the message from there:

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

Where did I something wrong? Did I forget something at InvalidateDeviceObjects()? I can give you more code but not everything because it's just too long. I really need help...

Reset Device:

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;
}
}


Release Objects:

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();
}
Était-ce utile?

La solution

In the sample you linked that works, an error on Reset results in return and the render function just gets called again. This is normal - there is no reason why Reset must succeed on the first call, so it's usual to keep retrying rather than showing an error message like in your code.

If you're rendering in the message loop, like in that example, just do the same thing - don't stop when you get an error.

If you don't render in the message loop, but use the WM_PAINT method, then this is the general pattern that I use - although sometimes I set a timer rather than calling InvalidateRect, it depends on the app - but this has been robust enough for many applications. You can see how the Reset will get repeated on failure, rather than throwing an error message on the first fail. It might be an idea to adopt this pattern:

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);
    }
}

Also, you must ensure that TestCooperativeLevel and Reset are called from the same thread that was used to create the device.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top