Directx9: сброс устройства после Ctrl + Alt + Del

Я использую окно без рамки и скопировал код сброса устройства из видео на 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();
}

0

Решение

В приведенном вами примере, который работает, ошибка на 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 Вызываются из того же потока, который использовался для создания устройства.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector