Original Post
I’m having a really annoying problem. I have searched and searched for an answer, but haven’t found anything. I am trying to add handling lost devices into an engine that I’m writing, but am not getting anywhere. This is my situation at the moment: My code runs fine (in fullscreen), I can alt-tab out of the app and alt-tab back in, and it doesn’t crash (yay), but nothing draws. The only thing that seems to work is the call to clear the screen. None of my drawing code works. When I close the app and look in visual studio’s output window, I get a whole bunch of notifications about “first chance exceptions”. I eventually tracked it down to any call to DrawPrimitiveUP (or any primitive drawing for that matter). I have taken my drawing code and pasted it into an example dealing with lost devices I found on Drunken Hyena, and it works fine, so I’m guessing that it’s not the drawing code at fault. It must be something to do with how I’m recovering from the lost devices, but I can’t figure out what I’m doing differently from the example that works. Thus the reason for my question. ;o) This is the code in question: bool D3DVideoDriver::BeginScene(bool ClearTarget, bool ClearDepth, bool ClearStencil) { if (!m_pDevice) return false; if (m_DeviceLost) { OutputDebugString("device is lost\n"); if (FAILED(hr = m_pDevice->TestCooperativeLevel())) { if (hr == D3DERR_DEVICELOST) { // Device lost but cannot be reset ReleaseDeviceObjects(); Sleep(250); return true; } if (hr == D3DERR_DEVICENOTRESET) { // Device lost but can be reset hr = m_pDevice->Reset(&m_D3Dpp); if (FAILED(hr)) { // failed to reset device OutputDebugString("Failed to reset device\n"); return true; } Log_Event("Lost device reset.",""); OutputDebugString("device is being reset\n"); RestoreDeviceObjects(); } return true; }// failed to test device cooperative level m_DeviceLost = false; OutputDebugString("device is reset\n"); } if (m_bIsSceneRunning) return true; OutputDebugString("Begin scene\n"); DWORD dw = 0; // Is anything going to be cleared? if (ClearTarget || ClearDepth || ClearStencil) { if (ClearTarget) dw |= D3DCLEAR_TARGET; if (ClearDepth) dw |= D3DCLEAR_ZBUFFER; if (ClearStencil && m_bStencil) { dw |= D3DCLEAR_STENCIL; } if (FAILED(m_pDevice->Clear(0, NULL, dw, m_ClearColour, 1.0f, 0))) { return false; } } if (FAILED(m_pDevice->BeginScene())) { return false; } m_bIsSceneRunning = true; m_Timer.Update(); MOUSE.Refresh(); KEYBOARD.Refresh(); return true; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool D3DVideoDriver::EndScene() { if (!m_pDevice) return false; if (!m_bIsSceneRunning) return true; int width = (int)((float)m_nWidth * 0.1375f); int height = (int)((float)m_nHeight * 0.1833f); OutputDebugString("Before draw\n"); Draw2DRectangle(Core::Rect(m_nWidth - width - 2, m_nHeight - height - 2, m_nWidth - 2, m_nHeight - 2), SColour(255,255,255,255), 0); OutputDebugString("End scene\n"); hr = m_pDevice->EndScene(); if (FAILED(hr)) { return false; } if (!m_bWindowed || (m_nNumChildWnds <= 0)) { hr = m_pDevice->Present(NULL, NULL, NULL, NULL); } else { hr = m_pChain[m_nActiveWnd]->Present(NULL, NULL, NULL, NULL, 0); } if (hr == D3DERR_DEVICELOST) { if (!m_DeviceLost) Log_Warning("Rendering device lost.",""); m_DeviceLost = true; } m_bIsSceneRunning = false; return true; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool D3DVideoDriver::Draw2DRectangle(const Core::Rect &position, SColour colTopLeft, SColour colTopRight, SColour colBottomRight, SColour colBottomLeft, float rotate) { if (!m_pDevice) return false; if (!m_bIsSceneRunning) return true; OutputDebugString("start of 2d draw\n"); float xTrans = - (float)(m_nWidth>>1); float yTrans = (float)(m_nHeight>>1); D3DXMATRIX world, trans, scale; D3DXMatrixScaling(&scale, (float)(position.BottomRight.x - position.TopLeft.x), (float)(position.BottomRight.y - position.TopLeft.y), 1.0f); D3DXMatrixTranslation(&trans, position.TopLeft.x + xTrans, -position.TopLeft.y + yTrans, 0); world = scale * trans; if (rotate) { D3DXMATRIX rot; D3DXMatrixRotationZ(&rot, rotate); world = scale * rot * trans; } m_pDevice->SetTransform(D3DTS_WORLD, &world); S2DVertex verts[4]; verts[0] = S2DVertex(Core::Vector3df(0,0,1), colTopLeft, Core::Vector2df(0,0)); verts[1] = S2DVertex(Core::Vector3df(1,0,1), colTopRight, Core::Vector2df(0,0)); verts[2] = S2DVertex(Core::Vector3df(1,-1,1), colBottomRight, Core::Vector2df(0,0)); verts[3] = S2DVertex(Core::Vector3df(0,-1,1), colBottomLeft, Core::Vector2df(0,0)); short indices[6] = {0,1,2,0,2,3}; m_pDevice->SetTexture(0,NULL); setRenderMode2D( ((colTopLeft.GetAlpha() < 255) || (colTopRight.GetAlpha() < 255) || (colBottomLeft.GetAlpha() < 255) || (colBottomRight.GetAlpha() < 255)), false, false); setVertexType(OVT_2DVERTEX); OutputDebugString("just before 2d draw\n"); if (FAILED(m_pDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], D3DFMT_INDEX16, &verts[0], sizeof(S2DVertex)))) { OutputDebugString("draw failed!\n"); return false; } OutputDebugString("end of 2d draw\n"); return true; } // bool Draw2DRectangle() The calls to ReleaseDeviceObjects(); and RestoreDeviceObjects(); in the BeginScene() function are basically meaningless, since the functions are empty. I’m not loading any device dependant resources (that I know of). In the drawing function, The setRenderMode2D() call sets all the renderstates that I need to do the 2d drawing, and setVertexType() basically just sets the correct FVF. When I run this is a program that is just calling BeginScene() and then EndScene() in it’s main loop, I get the following output: Begin scene Before draw start of 2d draw just before 2d draw end of 2d draw End scene Begin scene Before draw start of 2d draw just before 2d draw end of 2d draw End scene device is lost device is lost device is lost device is lost device is lost device is lost device is lost device is lost device is lost device is lost device is lost device is lost device is lost device is lost device is being reset device is lost device is reset Begin scene Before draw start of 2d draw just before 2d draw First-chance exception at 0x7c57e592 in OrangeGUIEditor.exe: Microsoft C++ exception: long @ 0x0012f61c. draw failed! End scene Begin scene Before draw start of 2d draw just before 2d draw First-chance exception at 0x7c57e592 in OrangeGUIEditor.exe: Microsoft C++ exception: long @ 0x0012f61c. draw failed! End scene Begin scene Before draw start of 2d draw just before 2d draw First-chance exception at 0x7c57e592 in OrangeGUIEditor.exe: Microsoft C++ exception: long @ 0x0012f61c. draw failed! End scene Begin scene Before draw start of 2d draw just before 2d draw First-chance exception at 0x7c57e592 in OrangeGUIEditor.exe: Microsoft C++ exception: long @ 0x0012f61c. draw failed! End scene Can anybody see what I’m doing wrong? As far as I can see, I’m doing everything that needs to be done, but I’ve never done this before, so I can’t be sure. Please help me, cause this is really starting to annoy me. Thanks in advance