Browse Source

fix problems opening an OpenGL window on some drivers

David Rose 16 years ago
parent
commit
b9f19d6663

+ 38 - 0
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);

+ 8 - 0
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;

+ 32 - 5
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) 

+ 1 - 1
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