diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx index 1b5f1733da..b15c467420 100755 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx @@ -64,6 +64,36 @@ wglGraphicsStateGuardian:: } } +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsStateGuardian::fail_pfnum +// Access: Public +// Description: This is called by wglGraphicsWindow when it finds it +// cannot use the pfnum determined by the GSG. Assuming +// this pfnum corresponds to an "advanced" frame buffer +// determined by wglChoosePixelFormatARB, this asks the +// GSG to swap out that pfnum for the earlier, +// "preliminary" pfnum determined via +// DescribePixelFormat(). +// +// This is a one-way operation. Once called, you can +// never go back to the advanced pfnum. +// +// This method returns true if a change was successfully +// made, or false if there was no second tier to fall +// back to. +//////////////////////////////////////////////////////////////////// +bool wglGraphicsStateGuardian:: +fail_pfnum() { + if (_pfnum == _pre_pfnum) { + return false; + } + + _pfnum = _pre_pfnum; + _pfnum_supports_pbuffer = false; + _pfnum_properties = _pre_pfnum_properties; + return true; +} + //////////////////////////////////////////////////////////////////// // Function: wglGraphicsStateGuardian::get_properties // Access: Private @@ -267,6 +297,8 @@ choose_pixel_format(const FrameBufferProperties &properties, _pfnum = best_pfnum; _pfnum_supports_pbuffer = false; _pfnum_properties = best_prop; + _pre_pfnum = _pfnum; + _pre_pfnum_properties = _pfnum_properties; if (best_quality == 0) { wgldisplay_cat.error() @@ -400,6 +432,12 @@ choose_pixel_format(const FrameBufferProperties &properties, _pfnum = best_pfnum; _pfnum_supports_pbuffer = need_pbuffer; _pfnum_properties = best_prop; + + if (wgldisplay_cat.is_debug()) { + wgldisplay_cat.debug() + << "Selected advanced pixfmt #" << _pfnum << " = " + << _pfnum_properties << "\n"; + } } wglDeleteContext(twindow_ctx); diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.h b/panda/src/wgldisplay/wglGraphicsStateGuardian.h index b7293c7302..fdd5587e4d 100755 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.h +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.h @@ -37,6 +37,8 @@ public: INLINE int get_pfnum() const; INLINE bool pfnum_supports_pbuffer() const; INLINE const FrameBufferProperties &get_fb_properties() const; + bool fail_pfnum(); + INLINE bool made_context() const; INLINE HGLRC get_context(HDC hdc); void get_properties(FrameBufferProperties &properties, HDC hdc, int pfnum); @@ -76,6 +78,12 @@ private: FrameBufferProperties _pfnum_properties; bool _pfnum_supports_pbuffer; int _pfnum; + + // This pfnum is the pfnum chosen via DescribePixelFormat. It is + // used in case the one returned by wglChoosePixelFormatARB() fails. + FrameBufferProperties _pre_pfnum_properties; + int _pre_pfnum; + bool _made_context; HGLRC _context; diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index 815d095e63..ceeb5d23c2 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -202,13 +202,36 @@ open_window() { DescribePixelFormat(_hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR), &pixelformat); -#ifdef _DEBUG +#ifdef NOTIFY_DEBUG char msg[200]; sprintf(msg, "Selected GL PixelFormat is #%d", pfnum); print_pfd(&pixelformat, msg); #endif - if (!SetPixelFormat(_hdc, pfnum, &pixelformat)) { + BOOL set_pfnum = SetPixelFormat(_hdc, pfnum, &pixelformat); + + if (!set_pfnum) { + if (wglgsg->fail_pfnum()) { + wgldisplay_cat.error() + << "SetPixelFormat(" << pfnum << ") failed; trying " + << wglgsg->get_pfnum() << " instead\n"; + + pfnum = wglgsg->get_pfnum(); + DescribePixelFormat(_hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR), + &pixelformat); + +#ifdef NOTIFY_DEBUG + sprintf(msg, "Selected GL PixelFormat is #%d", pfnum); + print_pfd(&pixelformat, msg); +#endif + + DescribePixelFormat(_hdc, pfnum, sizeof(PIXELFORMATDESCRIPTOR), + &pixelformat); + set_pfnum = SetPixelFormat(_hdc, pfnum, &pixelformat); + } + } + + if (!set_pfnum) { wgldisplay_cat.error() << "SetPixelFormat(" << pfnum << ") failed after window create\n"; close_window(); @@ -297,7 +320,7 @@ setup_colormap(const PIXELFORMATDESCRIPTOR &pixelformat) { RealizePalette(_hdc); } -#ifdef _DEBUG +#ifdef NOTIFY_DEBUG //typedef enum {Software, MCD, ICD} OGLDriverType; static char *OGLDrvStrings[3] = {"Software","MCD","ICD"}; @@ -310,6 +333,10 @@ static char *OGLDrvStrings[3] = {"Software","MCD","ICD"}; //////////////////////////////////////////////////////////////////// void wglGraphicsWindow:: print_pfd(PIXELFORMATDESCRIPTOR *pfd, char *msg) { + if (!wgldisplay_cat.is_debug()) { + return; + } + OGLDriverType drvtype; if ((pfd->dwFlags & PFD_GENERIC_ACCELERATED) && (pfd->dwFlags & PFD_GENERIC_FORMAT)) { @@ -321,10 +348,10 @@ print_pfd(PIXELFORMATDESCRIPTOR *pfd, char *msg) { } #define PRINT_FLAG(FLG) ((pfd->dwFlags & PFD_##FLG) ? (" PFD_" #FLG "|") : "") - wgldisplay_cat.spam() + wgldisplay_cat.debug() << "================================\n"; - wgldisplay_cat.spam() + wgldisplay_cat.debug() << msg << ", " << OGLDrvStrings[drvtype] << " driver\n" << "PFD flags: 0x" << (void*)pfd->dwFlags << " (" << PRINT_FLAG(GENERIC_ACCELERATED) diff --git a/panda/src/wgldisplay/wglGraphicsWindow.h b/panda/src/wgldisplay/wglGraphicsWindow.h index 9c0d526ca5..fe3260edea 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.h +++ b/panda/src/wgldisplay/wglGraphicsWindow.h @@ -46,7 +46,7 @@ protected: private: void setup_colormap(const PIXELFORMATDESCRIPTOR &pixelformat); -#ifdef _DEBUG +#ifdef NOTIFY_DEBUG static void print_pfd(PIXELFORMATDESCRIPTOR *pfd, char *msg); #endif