c++ - Directx9 : Reset Device after Ctrl+Alt+Del

标签 c++ directx device direct3d directx-9

我正在使用无边框窗口并从 Youtube 视频复制设备重置代码,它在那里工作,但我只是从那里收到消息:

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

最佳答案

在您链接的有效示例中,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);
    }
}

此外,您必须确保从用于创 build 备的同一线程调用 TestCooperativeLevelReset

关于c++ - Directx9 : Reset Device after Ctrl+Alt+Del,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20964404/

相关文章:

Android ListView 未在真实设备上显示但在模拟器上显示

ios - 如何在 Xcode 11 上运行不同版本的 iOS 模拟器?

c++ - ifstream getline 问题(它只读取第一行)

c++ - 具有两个不同缓冲区的指针算法

c++ - 'this' cannot be used in a constant expression error (C++)

c++ - 使用opencv将PNG转换为具有透明度的位图

c++ - 从 D3DXIntersectTri 获取世界坐标

Java创建.dll文件

c++ - 我应该在 DirectX 中使用 std::string 还是 Windows 数据类型?

android - 列出连接到作为 WiFi 接入点工作的 Android 手机的设备