D3D Reset Issue

For help with anything that CEGUI doesn't offer straight out-of-the-box, e.g.:
- Implementation of new features, such as new Core classes, widgets, WindowRenderers, etc. ...
- Modification of any existing features for specific purposes
- Integration of CEGUI in new engines or frameworks and writing of new plugins (Renderer, Parser, ...) or modules

Moderators: CEGUI MVP, CEGUI Team

User avatar
SuperGeek
Just popping in
Just popping in
Posts: 16
Joined: Wed Oct 19, 2005 18:56

D3D Reset Issue

Postby SuperGeek » Sun Sep 24, 2006 04:33

I am running CEGUI and DirectX9 April SDK. I have gotten all the code working to reset the device to a new resolution and so on while in the app.

The trouble is that after the reset, the user must click on the app once to get CEGUI to update, although the CEGUI cursor is working fine, and the app is still the foreground window in Windows.

I have noticed as well that while in windowed mode, the Windows cursor no longer shows in the Windows title bar at the top of the app, or while over the minimize and close buttons. The cursor changes fine from CEGUI to Windows and back other wise.

When you do click on the close button (again, windows titlebar), the window closes, but the app does not quit. This behavior is not noticed prior to the reset. I suspect it has something to do with the SetWindowPos() calls.

I'm not sure what code would be the most helpful (there is alot of it here), but this is the essentials:

The Reset:

Code: Select all

      Win32AppHelper::changeWindow(s_pimpl->d_window, width, height, windowed);

      s_pimpl->d_renderer->preD3DReset();

      HRESULT resetResult = s_pimpl->d_3DDevice->Reset(&s_pimpl->d_ppars);
      if(SUCCEEDED(resetResult))
      {
         s_pimpl->d_renderer->postD3DReset();
         d_winResetting=false;
         executeD3D9App();
         return true;
      }



The Cursor:

Code: Select all

   case WM_MOUSEMOVE:
      CEGUI::System::getSingleton().injectMouseMove((float)(LOWORD(lParam) - old_mouse_x), (float)(HIWORD(lParam) - old_mouse_y));
      old_mouse_x = LOWORD(lParam);
      old_mouse_y = HIWORD(lParam);
      if (d_needsClipping)
         if (!d_isWindowed)
         {
            CEGUI::System::getSingleton().injectMousePosition((float)LOWORD(lParam),(float)HIWORD(lParam));
            releaseCursor();
            captureCursor(hWnd, false);
            CEGUI::MouseCursor::getSingleton().show();
         }
         d_needsClipping=false;
      if (!d_fInWindow)
      {
         d_fInWindow=true;
         if (d_isWindowed)
         {
            CEGUI::System::getSingleton().injectMousePosition((float)LOWORD(lParam),(float)HIWORD(lParam));
            tme.cbSize = sizeof(TRACKMOUSEEVENT);
            tme.dwFlags = TME_LEAVE;
            tme.hwndTrack = hWnd;
            TrackMouseEvent(&tme);
            ShowCursor(false);
            CEGUI::MouseCursor::getSingleton().show();
         }
      }
      if (CEGUI::MouseCursor::getSingleton().isVisible()==false)
         CEGUI::MouseCursor::getSingleton().show();
      break;

   case WM_MOUSELEAVE:
      ShowCursor(true);
      CEGUI::MouseCursor::getSingleton().hide();
      d_fInWindow=false;
      break;



The Window Changer:

Code: Select all

   bool Win32AppHelper::changeWindow(HWND hWnd, int width, int height, bool windowed)
   {
      if (windowed)
      {
         if (d_isWindowed)
         {
            SetWindowPos(hWnd, HWND_TOP, 0, 0, width, height, SWP_NOMOVE);
            d_fInWindow=false;
         }
         else
         {
            d_isWindowed=true;
            SetWindowLong(hWnd, GWL_STYLE, WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_MINIMIZEBOX|WS_SYSMENU|WS_VISIBLE);
            SetWindowPos(hWnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
            Win32AppHelper::releaseCursor();
            d_fInWindow=false;
         }
      }
      else
      {
         if (d_isWindowed)
         {
            d_isWindowed=false;
            SetWindowLong(hWnd, GWL_STYLE, WS_POPUP);
            SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, width, height, SWP_FRAMECHANGED);
            d_needsClipping=true;
         }
         else
         {
            SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOMOVE);
            d_needsClipping=true;
         }
      }
      d_Width = width;
      d_Height = height;
      return true;
   }



Any help is appreciated!

User avatar
SuperGeek
Just popping in
Just popping in
Posts: 16
Joined: Wed Oct 19, 2005 18:56

Postby SuperGeek » Mon Sep 25, 2006 00:15

Just wanted to let who ever reads this know that I found some of the issues and resolved them.

Resolved:
The problem with having to reselect the GUI to get it updated was due to me foolishly not waiting long enough after the reset before presenting again. I resolved this by running a while loop until the device reports available.

The problem with the app not exiting when the Windows close button is clicked was due to me calling executeD3DApp multiple times. You had to exit for each one apparently. I had though that I had told the function to exit when the reset started, but it didn't feel like it. Now I just have the loop skip the render scene code when a reset is in process. That way it can pick up right where it left off when the reset is finished.

Existing Problem:
I am still trying to find a solution to the cursor not showing in the title bar after a reset. I think it is due to the change in window size confusing the nonclient area of the window. Perhaps I should try to add detection of both client and non client areas.....

Any ideas on this problem would be nice.


Return to “Modifications / Integrations / Customisations”

Who is online

Users browsing this forum: No registered users and 10 guests