C++ Directx9:Ctrl+之后重置设备;Alt+;德尔

C++ Directx9:Ctrl+之后重置设备;Alt+;德尔,c++,directx,device,direct3d,directx-9,C++,Directx,Device,Direct3d,Directx 9,我正在使用一个无边界窗口,并从Youtube视频中复制了设备重置代码,它在那里工作,但我只是从那里得到了信息: if(FAILED(hr)){ MessageBox(0, "Failed to reset device!", 0, 0); return; } 我哪里出错了?我是否忘记了InvalidateDeviceObjects()中的某些内容?我可以给你更多的代码,但不是所有的,因为它太长了。 我真的需要帮助。。。 复位装置: 释放对象: 在您链接的有效示例中,Rese

我正在使用一个无边界窗口,并从Youtube视频中复制了设备重置代码,它在那里工作,但我只是从那里得到了信息:

if(FAILED(hr)){
    MessageBox(0, "Failed to reset device!", 0, 0);
    return;
}
我哪里出错了?我是否忘记了
InvalidateDeviceObjects()
中的某些内容?我可以给你更多的代码,但不是所有的,因为它太长了。 我真的需要帮助。。。

复位装置:


释放对象:


在您链接的有效示例中,
Reset
上的错误将导致
return
,而
render
函数将再次被调用。这是正常的-没有理由在第一次调用时
Reset
必须成功,因此通常会继续重试,而不是像代码中那样显示错误消息

如果要在消息循环中进行渲染(如该示例中所示),只需执行相同的操作—当出现错误时不要停止

如果您不在消息循环中进行渲染,而是使用
WM_PAINT
方法,那么这就是我使用的一般模式-尽管有时我会设置一个计时器而不是调用
invalidate
,这取决于应用程序-但这对于许多应用程序来说已经足够健壮。您可以看到如何在出现故障时重复执行
重置
,而不是在第一次出现故障时抛出错误消息。采用这种模式可能是个好主意:

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
是从用于创建设备的同一线程调用的。

我在XP上切换用户或锁定屏幕时遇到过这种情况-这似乎是驱动程序问题,唯一的解决办法是在应用程序启动时拆除并重建整个DX9系统。类似的系统和不同的gfx卡是可以的。我想这是代码中的一些东西,因为我尝试(下载)了一个简单的游戏和设备重置,它工作了。那么你有这个简单游戏的源代码工作了吗?如果是这样,你可以比较一下。我能看到的唯一一件事是,如果第一次
重置
失败,则正常情况下,
重置
以获得另一次重新绘制,因此您可以重试。我对其进行了比较,没有发现任何差异。这是第三个:谢谢,但我试过了,重置失败,在第二个InvalidateDeviceObjects()/OnLostDevice()处崩溃。我添加了一些东西来使用InvalidateDeviceObjects()/OnLostDevice(),只使用了一次(错误?),但每次重置都失败了。我不使用线程。是否有一个列表或什么东西可以->释放()/删除或->联机设备()?我不使用纹理、字体或精灵。只有网格和灯光。@Vider7CC是的,引用-调用IDirect3DDevice9::Reset会导致所有纹理内存表面丢失、托管纹理从视频内存刷新以及所有状态信息丢失。在为设备调用IDirect3DDevice9::Reset方法之前,应用程序应释放与设备关联的所有显式渲染目标、深度模具曲面、附加交换链、状态块和D3DPOOL_默认资源。“。现在我正在重新创建设备,而不是重置它,它可以工作。这个方法有什么不好的地方吗?@Vider7CC好吧,现在我们回到我对你问题的第一个评论。这听起来和我不得不做的事情很相似,
Reset
呼叫开始返回
DRIVER\u INTERNAL\u ERROR
,除了重新创建设备外,没有其他方法返回。这感觉有些过分,但它确实有效。您可以尝试更新驱动程序,看看这是否会影响任何内容。
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();
}
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);
    }
}