resizing and cursor fixes

This commit is contained in:
cxgeorge 2002-04-02 23:44:50 +00:00
parent 0a482df28a
commit 4cade76e34
7 changed files with 189 additions and 108 deletions

View File

@ -94,6 +94,10 @@ bool dx_debug_view_mipmaps = config_dxgsg.GetBool("dx-debug-view-mipmaps", false
//int dx_print_texstats = config_dxgsg.GetBool("dx-print-texstats", 0); //int dx_print_texstats = config_dxgsg.GetBool("dx-print-texstats", 0);
#endif #endif
// use dx8 or GDI mouse cursor in fullscreen mode?
// Nvidia dx8 cursor is invisible as of 28.32 drivers, so using GDI in fullscrn by default for now
bool dx_use_dx_cursor = config_dxgsg.GetBool("dx-use-dx-cursor", false);
bool dx_force_anisotropic_filtering = config_dxgsg.GetBool("dx-force-anisotropic-filtering", false); bool dx_force_anisotropic_filtering = config_dxgsg.GetBool("dx-force-anisotropic-filtering", false);
// set 'retained-mode #t' and this to have prepare_geom concatenate all tristrips within a geom // set 'retained-mode #t' and this to have prepare_geom concatenate all tristrips within a geom

View File

@ -39,6 +39,7 @@ extern const bool link_tristrips;
extern DWORD dx_multisample_antialiasing_level; extern DWORD dx_multisample_antialiasing_level;
extern bool dx_use_triangle_mipgen_filter; extern bool dx_use_triangle_mipgen_filter;
extern const char *D3DFormatStr(D3DFORMAT fmt); extern const char *D3DFormatStr(D3DFORMAT fmt);
extern bool dx_use_dx_cursor;
// debug flags we might want to use in full optimized build // debug flags we might want to use in full optimized build
extern bool dx_ignore_mipmaps; extern bool dx_ignore_mipmaps;

View File

@ -399,7 +399,13 @@ HRESULT CD3DFont::RestoreDeviceObjects() {
// Desc: Destroys all device-dependent objects // Desc: Destroys all device-dependent objects
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
HRESULT CD3DFont::InvalidateDeviceObjects() { HRESULT CD3DFont::InvalidateDeviceObjects() {
/*
#ifdef _DEBUG
if(m_pVB) {
cout << "XXXX Releasing Font VertexBuffer\n";
}
#endif
*/
SAFE_RELEASE( m_pVB ); SAFE_RELEASE( m_pVB );

View File

@ -724,7 +724,7 @@ dx_init(HCURSOR hMouseCursor) {
// must check (scrn.d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_BLENDOP) (yes on GF2/Radeon85, no on TNT) // must check (scrn.d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_BLENDOP) (yes on GF2/Radeon85, no on TNT)
scrn.pD3DDevice->SetRenderState(D3DRS_BLENDOP,D3DBLENDOP_ADD); scrn.pD3DDevice->SetRenderState(D3DRS_BLENDOP,D3DBLENDOP_ADD);
if(dx_full_screen) { if((scrn.pProps->_fullscreen) && dx_use_dx_cursor) {
hr = CreateDX8Cursor(scrn.pD3DDevice,hMouseCursor,dx_show_cursor_watermark); hr = CreateDX8Cursor(scrn.pD3DDevice,hMouseCursor,dx_show_cursor_watermark);
if(FAILED(hr)) if(FAILED(hr))
dxgsg_cat.error() << "CreateDX8Cursor failed!\n"; dxgsg_cat.error() << "CreateDX8Cursor failed!\n";
@ -748,10 +748,10 @@ dx_init(HCURSOR hMouseCursor) {
UINT xsize = scrn.pProps->_xsize; UINT xsize = scrn.pProps->_xsize;
UINT ysize = scrn.pProps->_ysize; UINT ysize = scrn.pProps->_ysize;
#define FPS_MSG_FORMAT_STR " %dx%d\n%6.02f fps" #define FPS_MSG_FORMAT_STR " %dx%dx%d\n%6.02f fps"
char fps_msg[50]; char fps_msg[50];
sprintf(fps_msg,FPS_MSG_FORMAT_STR,xsize,ysize,800.00f); // 6 == NUM_FPSMETER_LETTERS sprintf(fps_msg,FPS_MSG_FORMAT_STR,xsize,ysize,32,800.00f); // 6 == NUM_FPSMETER_LETTERS
hr = _pStatMeterFont->GetTextExtent(fps_msg,&TextRectSize); hr = _pStatMeterFont->GetTextExtent(fps_msg,&TextRectSize);
if(SUCCEEDED(hr)) { if(SUCCEEDED(hr)) {
@ -997,8 +997,11 @@ void INLINE TestDrawPrimFailure(DP_Type dptype,HRESULT hr,IDirect3DDevice8 *pD3D
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian:: void DXGraphicsStateGuardian::
render_frame() { render_frame() {
if (!_bDXisReady) if (!_bDXisReady) {
//if(dxgsg_cat.is_spam())
// dxgsg_cat.spam() << "dx is not ready, skipping render_frame()\n";
return; return;
}
_win->begin_frame(); _win->begin_frame();
@ -3567,7 +3570,6 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
state.set_transition(new ColorBlendTransition); state.set_transition(new ColorBlendTransition);
state.set_transition(new StencilTransition); state.set_transition(new StencilTransition);
switch (pb->get_format()) { switch (pb->get_format()) {
case PixelBuffer::F_depth_component: case PixelBuffer::F_depth_component:
{ {
@ -4814,7 +4816,8 @@ end_frame() {
D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,0); // yellow D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,0); // yellow
char fps_msg[50]; char fps_msg[50];
sprintf(fps_msg,FPS_MSG_FORMAT_STR,scrn.pProps->_xsize,scrn.pProps->_ysize,_current_fps); sprintf(fps_msg,FPS_MSG_FORMAT_STR,scrn.pProps->_xsize,scrn.pProps->_ysize,
(IS_16BPP_DISPLAY_FORMAT(scrn.PresParams.BackBufferFormat) ? 16 : 32),_current_fps);
// usually only want to call BeginText() & EndText() once/frame // usually only want to call BeginText() & EndText() once/frame
// to bracket all the text for a given cd3dfont obj // to bracket all the text for a given cd3dfont obj
@ -5758,35 +5761,6 @@ HRESULT DXGraphicsStateGuardian::ReleaseAllDeviceObjects(void) {
return S_OK; return S_OK;
} }
HRESULT DXGraphicsStateGuardian::RestoreAllDeviceObjects(void) {
// BUGBUG: this should also restore vertex buffer contents when they are implemented
// You will need to destroy and recreate
// optimized vertex buffers however, restoring is not enough.
/*
HRESULT hr;
// note: could go through and just restore surfs that return IsLost() true
// apparently that isnt as reliable w/some drivers tho
if (FAILED(hr = scrn.pD3DDevice->RestoreAllSurfaces() )) {
dxgsg_cat.fatal() << "RestoreAllSurfs failed : result = " << D3DERRORSTRING(hr);
exit(1);
}
*/
// DX8 should handle restoring contents of managed textures automatically
// cant access template in libpanda.dll directly due to vc++ limitations, use traverser to get around it
// traverse_prepared_textures(refill_tex_callback,this);
if(IS_VALID_PTR(_pStatMeterFont))
_pStatMeterFont->RestoreDeviceObjects();
if(dxgsg_cat.is_debug())
dxgsg_cat.debug() << "restore and refill of video surfaces complete...\n";
return S_OK;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: show_frame // Function: show_frame
// Access: // Access:
@ -5899,8 +5873,20 @@ void DXGraphicsStateGuardian::show_windowed_frame(void) {
HRESULT DXGraphicsStateGuardian::reset_d3d_device(D3DPRESENT_PARAMETERS *pPresParams) { HRESULT DXGraphicsStateGuardian::reset_d3d_device(D3DPRESENT_PARAMETERS *pPresParams) {
HRESULT hr; HRESULT hr;
assert(IS_VALID_PTR(pPresParams));
assert(IS_VALID_PTR(scrn.pD3D8));
assert(IS_VALID_PTR(scrn.pD3DDevice));
ReleaseAllDeviceObjects(); ReleaseAllDeviceObjects();
if(!dx_full_screen) {
// for windowed make sure out format matches the desktop fmt, in case the
// desktop mode has been changed
scrn.pD3D8->GetAdapterDisplayMode(scrn.CardIDNum, &scrn.DisplayMode);
pPresParams->BackBufferFormat = scrn.DisplayMode.Format;
}
hr=scrn.pD3DDevice->Reset(pPresParams); hr=scrn.pD3DDevice->Reset(pPresParams);
if(SUCCEEDED(hr)) { if(SUCCEEDED(hr)) {
if(pPresParams!=&scrn.PresParams) if(pPresParams!=&scrn.PresParams)
@ -5929,7 +5915,6 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) {
if(bDoReactivateWindow) if(bDoReactivateWindow)
_win->reactivate_window(); //must reactivate window before you can restore surfaces (otherwise you are in WRONGVIDEOMODE, and DDraw RestoreAllSurfaces fails) _win->reactivate_window(); //must reactivate window before you can restore surfaces (otherwise you are in WRONGVIDEOMODE, and DDraw RestoreAllSurfaces fails)
RestoreAllDeviceObjects();
hr = scrn.pD3DDevice->TestCooperativeLevel(); hr = scrn.pD3DDevice->TestCooperativeLevel();
if(FAILED(hr)) { if(FAILED(hr)) {
// internal chk, shouldnt fail // internal chk, shouldnt fail
@ -5937,6 +5922,8 @@ bool DXGraphicsStateGuardian::CheckCooperativeLevel(bool bDoReactivateWindow) {
exit(1); exit(1);
} }
_bDXisReady = TRUE;
break; break;
case D3DERR_DEVICELOST: case D3DERR_DEVICELOST:

View File

@ -234,7 +234,6 @@ protected:
DWORD wNumRings, DWORD wNumSections, float sx, float sy, float sz, DWORD wNumRings, DWORD wNumSections, float sx, float sy, float sz,
DWORD *pNumVertices,DWORD *pNumTris,DWORD fvfFlags,DWORD dwVertSize); DWORD *pNumVertices,DWORD *pNumTris,DWORD fvfFlags,DWORD dwVertSize);
HRESULT ReleaseAllDeviceObjects(void); HRESULT ReleaseAllDeviceObjects(void);
HRESULT RestoreAllDeviceObjects(void);
HRESULT RecreateAllDeviceObjects(void); HRESULT RecreateAllDeviceObjects(void);
HRESULT DeleteAllDeviceObjects(void); HRESULT DeleteAllDeviceObjects(void);

View File

@ -43,6 +43,7 @@ TypeHandle wdxGraphicsWindow::_type_handle;
#define LAST_ERROR 0 #define LAST_ERROR 0
#define ERRORBOX_TITLE "Panda3D Error" #define ERRORBOX_TITLE "Panda3D Error"
#define WDX_WINDOWCLASSNAME "wdxDisplay" #define WDX_WINDOWCLASSNAME "wdxDisplay"
#define WDX_WINDOWCLASSNAME_NOCURSOR "wdxDisplay_NoCursor"
#define DEFAULT_CURSOR IDC_ARROW #define DEFAULT_CURSOR IDC_ARROW
typedef map<HWND,wdxGraphicsWindow *> HWND_PANDAWIN_MAP; typedef map<HWND,wdxGraphicsWindow *> HWND_PANDAWIN_MAP;
@ -67,7 +68,7 @@ wdxGraphicsWindow* global_wdxwinptr = NULL; // need this for temporary windproc
#define MAX_DISPLAYS 20 #define MAX_DISPLAYS 20
#define PAUSED_TIMER_ID 7 // completely arbitrary choice #define PAUSED_TIMER_ID 7 // completely arbitrary choice
#define DXREADY ((_dxgsg!=NULL)&&(_dxgsg->GetDXReady())) #define DX_IS_READY ((_dxgsg!=NULL)&&(_dxgsg->GetDXReady()))
LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam,LPARAM lparam); LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam,LPARAM lparam);
@ -168,6 +169,15 @@ extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *p
} }
#endif #endif
void ClearToBlack(HWND hWnd,GraphicsWindow::Properties &props) {
// clear to black
HDC hDC=GetDC(hWnd); // GetDC is not particularly fast. if this needs to be super-quick, we should cache GetDC's hDC
RECT clrRect={props._xorg,props._yorg,props._xorg+props._xsize,props._yorg+props._ysize};
FillRect(hDC,&clrRect,(HBRUSH)GetStockObject(BLACK_BRUSH));
// PatBlt(hDC,_props._xorg,_props._yorg,_props._xsize,_props._ysize,BLACKNESS);
ReleaseDC(hWnd,hDC);
}
// fn exists so AtExitFn can call it without refcntr blowing up since its !=0 // fn exists so AtExitFn can call it without refcntr blowing up since its !=0
void wdxGraphicsWindow::DestroyMe(bool bAtExitFnCalled) { void wdxGraphicsWindow::DestroyMe(bool bAtExitFnCalled) {
if(wdxdisplay_cat.is_spam()) if(wdxdisplay_cat.is_spam())
@ -275,19 +285,23 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
int x, y, width, height; int x, y, width, height;
switch(msg) { switch(msg) {
case WM_PAINT: { case WM_PAINT: {
if((_WindowAdjustingType != NotAdjusting) || (!DX_IS_READY)) {
// let DefWndProc do WM_ERASEBKGND & just draw black,
// rather than forcing Present to stretchblt the old window contents
// into the new size
break;
}
PAINTSTRUCT ps; PAINTSTRUCT ps;
BeginPaint(hwnd, &ps); BeginPaint(hwnd, &ps);
if(DXREADY)
show_frame(); show_frame();
EndPaint(hwnd, &ps); EndPaint(hwnd, &ps);
return 0; return 0;
} }
case WM_MOUSEMOVE: { case WM_MOUSEMOVE: {
if(!DXREADY) if(!DX_IS_READY)
break; break;
// Win32 doesn't return the same numbers as X does when the mouse // Win32 doesn't return the same numbers as X does when the mouse
@ -310,7 +324,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
SET_MOUSE_COORD(y,newY); SET_MOUSE_COORD(y,newY);
handle_mouse_motion(x, y); handle_mouse_motion(x, y);
if(dx_full_screen && (_dxgsg!=NULL) && (_dxgsg->scrn.pD3DDevice!=NULL)) if(_props._fullscreen && (_dxgsg!=NULL) && (_dxgsg->scrn.pD3DDevice!=NULL))
_dxgsg->scrn.pD3DDevice->SetCursorPosition(newX,newY,D3DCURSOR_IMMEDIATE_UPDATE); _dxgsg->scrn.pD3DDevice->SetCursorPosition(newX,newY,D3DCURSOR_IMMEDIATE_UPDATE);
return 0; return 0;
} }
@ -346,15 +360,9 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
case WM_CREATE: { case WM_CREATE: {
track_mouse_leaving(hwnd); track_mouse_leaving(hwnd);
_cursor_in_windowclientarea=false; _cursor_in_windowclientarea=false;
if(!_props._bCursorIsVisible) ClearToBlack(hwnd,_props);
ShowCursor(false); set_cursor_visibility(true);
HDC hDC=GetDC(hwnd);
PatBlt(hDC,_props._xorg,_props._yorg,_props._xsize,_props._ysize,BLACKNESS);
ReleaseDC(hwnd,hDC);
break; break;
} }
@ -422,7 +430,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
if(button < 0) if(button < 0)
button = 1; button = 1;
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
if(!DXREADY) if(!DX_IS_READY)
break; break;
if(button < 0) if(button < 0)
@ -439,7 +447,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
if(button < 0) if(button < 0)
button = 1; button = 1;
case WM_RBUTTONUP: case WM_RBUTTONUP:
if(!DXREADY) if(!DX_IS_READY)
break; break;
if(button < 0) if(button < 0)
@ -455,15 +463,18 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
case WM_SETCURSOR: case WM_SETCURSOR:
// Turn off any GDI window cursor // Turn off any GDI window cursor
// dx8 cursor not working yet // dx8 cursor not working yet
if(dx_full_screen) {
SetCursor( NULL ); if(_use_dx8_cursor && _props._fullscreen) {
_dxgsg->scrn.pD3DDevice->ShowCursor(true); // SetCursor( NULL );
// _dxgsg->scrn.pD3DDevice->ShowCursor(true);
set_cursor_visibility(true);
return TRUE; // prevent Windows from setting cursor to window class cursor (see docs on WM_SETCURSOR) return TRUE; // prevent Windows from setting cursor to window class cursor (see docs on WM_SETCURSOR)
} }
break; break;
case WM_MOVE: case WM_MOVE:
if(!DXREADY) if(!DX_IS_READY)
break; break;
handle_window_move(LOWORD(lparam), HIWORD(lparam) ); handle_window_move(LOWORD(lparam), HIWORD(lparam) );
return 0; return 0;
@ -516,15 +527,24 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
#endif #endif
if(_WindowAdjustingType==Resizing) { if(_WindowAdjustingType==Resizing) {
handle_windowed_resize(hwnd,true); bool bSucceeded=handle_windowed_resize(hwnd,true);
if(!bSucceeded) {
#if 0
bugbug need to fix this stuff
SetWindowPos(hwnd,NULL,0,0,lastxsize,lastysize,
SWP_NOMOVE |
#endif
}
} }
_WindowAdjustingType = NotAdjusting; _WindowAdjustingType = NotAdjusting;
_dxgsg->SetDXReady(true);
return 0; return 0;
case WM_ENTERSIZEMOVE: { case WM_ENTERSIZEMOVE: {
if(_dxgsg!=NULL) if(_dxgsg!=NULL)
_dxgsg->SetDXReady(true); // dont disable here because I want to see pic as I resize _dxgsg->SetDXReady(false); // dont see pic during resize
_WindowAdjustingType = MovingOrResizing; _WindowAdjustingType = MovingOrResizing;
} }
break; break;
@ -588,7 +608,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
case WM_SETFOCUS: { case WM_SETFOCUS: {
// wdxdisplay_cat.info() << "got WM_SETFOCUS\n"; // wdxdisplay_cat.info() << "got WM_SETFOCUS\n";
if(!DXREADY) { if(!DX_IS_READY) {
break; break;
} }
@ -610,7 +630,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
case WM_KILLFOCUS: { case WM_KILLFOCUS: {
// wdxdisplay_cat.info() << "got WM_KILLFOCUS\n"; // wdxdisplay_cat.info() << "got WM_KILLFOCUS\n";
if(!DXREADY) { if(!DX_IS_READY) {
break; break;
} }
@ -709,8 +729,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
// should be used by both fullscrn and windowed resize // should be used by both fullscrn and windowed resize
bool wdxGraphicsWindow::reset_device_resize_window(UINT new_xsize, UINT new_ysize) { bool wdxGraphicsWindow::reset_device_resize_window(UINT new_xsize, UINT new_ysize) {
DXScreenData *pScrn=&_dxgsg->scrn; DXScreenData *pScrn=&_dxgsg->scrn;
assert((new_xsize>0)&&(new_ysize>0)); assert((new_xsize>0)&&(new_ysize>0));
bool bRetval=true;
D3DPRESENT_PARAMETERS d3dpp; D3DPRESENT_PARAMETERS d3dpp;
memcpy(&d3dpp,&pScrn->PresParams,sizeof(D3DPRESENT_PARAMETERS)); memcpy(&d3dpp,&pScrn->PresParams,sizeof(D3DPRESENT_PARAMETERS));
@ -719,14 +739,25 @@ bool wdxGraphicsWindow::reset_device_resize_window(UINT new_xsize, UINT new_ysiz
HRESULT hr=_dxgsg->reset_d3d_device(&d3dpp); HRESULT hr=_dxgsg->reset_d3d_device(&d3dpp);
if(FAILED(hr)) { if(FAILED(hr)) {
if(hr==D3DERR_OUTOFVIDEOMEMORY) bRetval=false;
return false;
wdxdisplay_cat.error() << "reset_device_resize_window Reset() failed" << D3DERRORSTRING(hr); wdxdisplay_cat.error() << "reset_device_resize_window Reset() failed" << D3DERRORSTRING(hr);
if(hr==D3DERR_OUTOFVIDEOMEMORY) {
hr=_dxgsg->reset_d3d_device(&pScrn->PresParams);
if(FAILED(hr)) {
wdxdisplay_cat.error() << "reset_device_resize_window Reset() failed OutOfVidmem, then failed again doing Reset w/original params:" << D3DERRORSTRING(hr);
exit(1); exit(1);
} else {
if(wdxdisplay_cat.is_info())
wdxdisplay_cat.info() << "reset of original size (" <<pScrn->PresParams.BackBufferWidth << ","
<< pScrn->PresParams.BackBufferHeight << ") succeeded\n";
}
} else {
exit(1);
}
} }
init_resized_window(); init_resized_window();
return true; return bRetval;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -796,7 +827,7 @@ bool wdxGraphicsWindow::handle_windowed_resize(HWND hWnd,bool bDoDxReset) {
bResizeSucceeded=reset_device_resize_window(xsize,ysize); // create the new resized rendertargets bResizeSucceeded=reset_device_resize_window(xsize,ysize); // create the new resized rendertargets
if(!bResizeSucceeded) { if(!bResizeSucceeded) {
if(wdxdisplay_cat.is_debug()) if(wdxdisplay_cat.is_debug())
wdxdisplay_cat.debug() << "windowed_resize to size: (" << xsize << "," << ysize << ") failed due to out-of-memory, retrying w/reduced size\n"; wdxdisplay_cat.debug() << "windowed_resize to size: (" << xsize << "," << ysize << ") failed due to out-of-memory\n";
} else { } else {
if(wdxdisplay_cat.is_debug()) if(wdxdisplay_cat.is_debug())
wdxdisplay_cat.debug() << "windowed_resize to origin: (" << _props._xorg << "," << _props._yorg << "), size: (" << _props._xsize << "," << _props._ysize << ")\n"; wdxdisplay_cat.debug() << "windowed_resize to origin: (" << _props._xorg << "," << _props._yorg << "), size: (" << _props._xsize << "," << _props._ysize << ")\n";
@ -860,38 +891,31 @@ void wdxGraphicsWindow::deactivate_window(void) {
// } // }
} }
// currently this should only be called from CheckCoopLvl to return from Alt-tab
void wdxGraphicsWindow::reactivate_window(void) { void wdxGraphicsWindow::reactivate_window(void) {
if(_window_inactive) { if((_window_inactive)||(_active_minimized_fullscreen)) {
// first see if dx cooperative level is OK for reactivation // first see if dx cooperative level is OK for reactivation
// if(!_dxgsg->CheckCooperativeLevel()) // if(!_dxgsg->CheckCooperativeLevel())
// return; // return;
if(_PandaPausedTimer!=NULL) {
KillTimer(_dxgsg->scrn.hWnd,_PandaPausedTimer);
_PandaPausedTimer = NULL;
}
if(_window_inactive) {
_window_inactive = false;
if(wdxdisplay_cat.is_spam()) if(wdxdisplay_cat.is_spam())
wdxdisplay_cat.spam() << "WDX window re-activated...\n"; wdxdisplay_cat.spam() << "WDX window re-activated...\n";
} else {
_window_inactive = false; _active_minimized_fullscreen = false;
if(_PandaPausedTimer!=NULL) {
KillTimer(_dxgsg->scrn.hWnd,_PandaPausedTimer);
_PandaPausedTimer = NULL;
}
// move window to top of zorder
// if(_props._fullscreen)
// SetWindowPos(_DisplayDataArray[0].hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER);
GdiFlush();
} else if(_active_minimized_fullscreen) {
if(wdxdisplay_cat.is_spam()) if(wdxdisplay_cat.is_spam())
wdxdisplay_cat.spam() << "WDX window unminimized from active-minimized state...\n"; wdxdisplay_cat.spam() << "WDX window unminimized from active-minimized state...\n";
if(_PandaPausedTimer!=NULL) {
KillTimer(_dxgsg->scrn.hWnd,_PandaPausedTimer);
_PandaPausedTimer = NULL;
} }
_active_minimized_fullscreen = false; // need to call dx_init and ResourceManagerDiscardBytes since D3D Reset() was called
init_resized_window();
// move window to top of zorder // move window to top of zorder
// if(_props._fullscreen) // if(_props._fullscreen)
@ -944,6 +968,18 @@ bool supports_color_cursors(D3DADAPTER_IDENTIFIER8 &DevID) {
return false; return false;
} }
HCURSOR CreateNullCursor(HINSTANCE hInst) {
#define CURSORBYTESIZE (32*4)
// 1-bit 32x32
BYTE ANDPlane[CURSORBYTESIZE],XORPlane[CURSORBYTESIZE];
ZeroMemory(XORPlane,CURSORBYTESIZE);
memset(ANDPlane,0xFF,CURSORBYTESIZE);
return CreateCursor(hInst,0,0,32,32,ANDPlane,XORPlane);
}
void wdxGraphicsWindowGroup::CreateWindows(void) { void wdxGraphicsWindowGroup::CreateWindows(void) {
HINSTANCE hProgramInstance = GetModuleHandle(NULL); HINSTANCE hProgramInstance = GetModuleHandle(NULL);
WNDCLASS wc; WNDCLASS wc;
@ -975,6 +1011,7 @@ void wdxGraphicsWindowGroup::CreateWindows(void) {
wc.hIcon = NULL; // use default app icon wc.hIcon = NULL; // use default app icon
} }
#if 0
// Note: dx_init() uses the cursor handle to create the dx cursor surface // Note: dx_init() uses the cursor handle to create the dx cursor surface
string windows_color_cursor_filename = get_color_cursor_filename().to_os_specific(); string windows_color_cursor_filename = get_color_cursor_filename().to_os_specific();
@ -1020,6 +1057,7 @@ void wdxGraphicsWindowGroup::CreateWindows(void) {
} }
try_mono_cursor: try_mono_cursor:
#endif
if(!_bLoadedCustomCursor) { if(!_bLoadedCustomCursor) {
string windows_mono_cursor_filename = get_mono_cursor_filename().to_os_specific(); string windows_mono_cursor_filename = get_mono_cursor_filename().to_os_specific();
@ -1047,18 +1085,33 @@ void wdxGraphicsWindowGroup::CreateWindows(void) {
if(!_bLoadedCustomCursor) if(!_bLoadedCustomCursor)
_hMouseCursor = LoadCursor(NULL, DEFAULT_CURSOR); _hMouseCursor = LoadCursor(NULL, DEFAULT_CURSOR);
// bugbug: probably need to make 2 classes, one w/cursor and one w/NULL cursor for fullscrn to support mixed types // need both a mouse and no-mouse class in case we have mixed fullscrn/windowed
// windowed must use GDI mouse, fullscrn usually wont
if (!wc_registered) { if (!wc_registered) {
// We only need to register the window class once per session. // We only need to register the window class once per session.
wc.hCursor = (dx_full_screen ? NULL : _hMouseCursor); // for windowed mode use the GDI cursor.
wc.hCursor = _hMouseCursor; // for windowed mode use the GDI cursor.
// bugbug: for fullscreen do we need to do a SetWindowLongNULL // bugbug: for fullscreen do we need to do a SetWindowLongNULL
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL; wc.lpszMenuName = NULL;
wc.lpszClassName = WDX_WINDOWCLASSNAME; wc.lpszClassName = WDX_WINDOWCLASSNAME;
if(!RegisterClass(&wc)) { if(!RegisterClass(&wc)) {
wdxdisplay_cat.error() << "could not register window class!" << endl; wdxdisplay_cat.error() << "could not register window class " << WDX_WINDOWCLASSNAME << endl;
} }
if(dx_use_dx_cursor) {
wc.hCursor = CreateNullCursor(hProgramInstance);
if(wc.hCursor==NULL)
wdxdisplay_cat.error() << "failed to create NULL cursor, error=" << GetLastError() << endl;
wc.lpszClassName = WDX_WINDOWCLASSNAME_NOCURSOR;
if(!RegisterClass(&wc)) {
wdxdisplay_cat.error() << "could not register window class " << WDX_WINDOWCLASSNAME_NOCURSOR << endl;
}
}
wc_registered = true; wc_registered = true;
} }
@ -1074,6 +1127,7 @@ void wdxGraphicsWindowGroup::CreateWindows(void) {
DWORD final_window_style; DWORD final_window_style;
final_window_style=base_window_style; final_window_style=base_window_style;
char *pWindowClassName;
if(_windows[devnum]->_props._fullscreen) { if(_windows[devnum]->_props._fullscreen) {
MONITORINFO minfo; MONITORINFO minfo;
@ -1086,6 +1140,8 @@ void wdxGraphicsWindowGroup::CreateWindows(void) {
ytop=minfo.rcMonitor.top; ytop=minfo.rcMonitor.top;
xsize=props->_xsize; xsize=props->_xsize;
ysize=props->_ysize; ysize=props->_ysize;
pWindowClassName= (dx_use_dx_cursor ? WDX_WINDOWCLASSNAME_NOCURSOR : WDX_WINDOWCLASSNAME);
} else { } else {
RECT win_rect; RECT win_rect;
SetRect(&win_rect, props->_xorg, props->_yorg, props->_xorg + props->_xsize, SetRect(&win_rect, props->_xorg, props->_yorg, props->_xorg + props->_xsize,
@ -1108,11 +1164,13 @@ void wdxGraphicsWindowGroup::CreateWindows(void) {
ytop= win_rect.top; ytop= win_rect.top;
xsize=RECT_XSIZE(win_rect); xsize=RECT_XSIZE(win_rect);
ysize=RECT_YSIZE(win_rect); ysize=RECT_YSIZE(win_rect);
pWindowClassName=WDX_WINDOWCLASSNAME;
} }
// BUGBUG: this sets window posns based on desktop arrangement of monitors (that is what GetMonInfo is for). // BUGBUG: this sets window posns based on desktop arrangement of monitors (that is what GetMonInfo is for).
// need to move to chancfg stuff instead (i.e. use the properties x/yorg's) when that is ready // need to move to chancfg stuff instead (i.e. use the properties x/yorg's) when that is ready
HWND hWin = CreateWindow(WDX_WINDOWCLASSNAME, props->_title.c_str(), HWND hWin = CreateWindow(pWindowClassName, props->_title.c_str(),
final_window_style, xleft,ytop,xsize,ysize, final_window_style, xleft,ytop,xsize,ysize,
_hParentWindow, NULL, hProgramInstance, 0); _hParentWindow, NULL, hProgramInstance, 0);
@ -1202,10 +1260,14 @@ void wdxGraphicsWindow::config_window(wdxGraphicsWindowGroup *pParentGroup) {
_return_control_to_app = false; _return_control_to_app = false;
_active_minimized_fullscreen = false; _active_minimized_fullscreen = false;
if(_props._fullscreen || _props._fullscreen) { if(_props._fullscreen || dx_full_screen) {
_props._fullscreen = _props._fullscreen = true; _props._fullscreen = dx_full_screen= true;
} }
_use_dx8_cursor = dx_use_dx_cursor;
if(!_props._fullscreen)
_use_dx8_cursor = false;
_WindowAdjustingType = NotAdjusting; _WindowAdjustingType = NotAdjusting;
_bSizeIsMaximized=FALSE; _bSizeIsMaximized=FALSE;
@ -1448,7 +1510,7 @@ find_all_card_memavails(void) {
HINSTANCE hDDrawDLL = LoadLibrary(DDRAW_NAME); HINSTANCE hDDrawDLL = LoadLibrary(DDRAW_NAME);
if(hDDrawDLL == 0) { if(hDDrawDLL == 0) {
wdxdisplay_cat.fatal() << "can't locate " << DDRAW_NAME <<"!\n"; wdxdisplay_cat.fatal() << "LoadLibrary(" << DDRAW_NAME <<") failed!, error=" << GetLastError() << endl;
exit(1); exit(1);
} }
@ -2322,10 +2384,9 @@ void wdxGraphicsWindow::init_resized_window(void) {
resized(newWidth,newHeight); // update panda channel/display rgn info, _props.xsize, _props.ysize resized(newWidth,newHeight); // update panda channel/display rgn info, _props.xsize, _props.ysize
// clear window to black ASAP // clear window to black ASAP
HDC hDC=GetDC(pDisplay->hWnd); ClearToBlack(pDisplay->hWnd,_props);
PatBlt(hDC,_props._xorg,_props._yorg,_props._xsize,_props._ysize,BLACKNESS);
ReleaseDC(pDisplay->hWnd,hDC);
// clear textures and VB's out of video&AGP mem, so cache is reset
hr = pDisplay->pD3DDevice->ResourceManagerDiscardBytes(0); hr = pDisplay->pD3DDevice->ResourceManagerDiscardBytes(0);
if(FAILED(hr)) { if(FAILED(hr)) {
wdxdisplay_cat.error() << "ResourceManagerDiscardBytes failed for device #" << pDisplay->CardIDNum << D3DERRORSTRING(hr); wdxdisplay_cat.error() << "ResourceManagerDiscardBytes failed for device #" << pDisplay->CardIDNum << D3DERRORSTRING(hr);
@ -2341,6 +2402,30 @@ void wdxGraphicsWindow::init_resized_window(void) {
_dxgsg->dx_init(_pParentWindowGroup->_hMouseCursor); _dxgsg->dx_init(_pParentWindowGroup->_hMouseCursor);
// do not SetDXReady() yet since caller may want to do more work before letting rendering proceed // do not SetDXReady() yet since caller may want to do more work before letting rendering proceed
set_cursor_visibility(true);
}
// does NOT override _props._bCursorIsVisible
INLINE void wdxGraphicsWindow::set_cursor_visibility(bool bVisible) {
bool bValidDXPtrs;
if(_use_dx8_cursor)
bValidDXPtrs = (IS_VALID_PTR(_dxgsg) && IS_VALID_PTR(_dxgsg->scrn.pD3DDevice));
if(_props._bCursorIsVisible) {
if(_use_dx8_cursor) {
ShowCursor(false);
if(bValidDXPtrs)
_dxgsg->scrn.pD3DDevice->ShowCursor(bVisible);
} else {
ShowCursor(bVisible);
}
} else {
ShowCursor(false);
if(_use_dx8_cursor && bValidDXPtrs)
_dxgsg->scrn.pD3DDevice->ShowCursor(false);
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -2404,7 +2489,6 @@ void wdxGraphicsWindow::setup_colormap(void) {
RealizePalette(_hdc); RealizePalette(_hdc);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: begin_frame // Function: begin_frame
// Access: // Access:
@ -2417,8 +2501,6 @@ void wdxGraphicsWindow::show_frame(void) {
_dxgsg->show_frame(); _dxgsg->show_frame();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: end_frame // Function: end_frame
// Access: // Access:

View File

@ -117,6 +117,7 @@ private:
bool _active_minimized_fullscreen; bool _active_minimized_fullscreen;
bool _return_control_to_app; bool _return_control_to_app;
bool _cursor_in_windowclientarea; bool _cursor_in_windowclientarea;
bool _use_dx8_cursor;
bool _tracking_mouse_leaving; bool _tracking_mouse_leaving;
int _depth_buffer_bpp; int _depth_buffer_bpp;
@ -130,6 +131,7 @@ public:
virtual void do_close_window(); virtual void do_close_window();
void deactivate_window(void); void deactivate_window(void);
void reactivate_window(void); void reactivate_window(void);
INLINE void set_cursor_visibility(bool bVisible);
bool handle_windowed_resize(HWND hWnd,bool bDoDXReset); bool handle_windowed_resize(HWND hWnd,bool bDoDXReset);
private: private: