Browse Source

Changes moving FrameBufferProperties into GraphicsOutput

Josh Yelon 20 years ago
parent
commit
a8ffec28b6
62 changed files with 674 additions and 306 deletions
  1. 16 10
      doc/makepanda/makepanda.py
  2. 2 1
      panda/src/display/displayRegion.cxx
  3. 187 0
      panda/src/display/frameBufferProperties.I
  4. 64 2
      panda/src/display/frameBufferProperties.cxx
  5. 31 2
      panda/src/display/frameBufferProperties.h
  6. 3 2
      panda/src/display/graphicsBuffer.cxx
  7. 1 0
      panda/src/display/graphicsBuffer.h
  8. 4 4
      panda/src/display/graphicsEngine.I
  9. 9 14
      panda/src/display/graphicsEngine.cxx
  10. 12 2
      panda/src/display/graphicsOutput.I
  11. 8 5
      panda/src/display/graphicsOutput.cxx
  12. 4 0
      panda/src/display/graphicsOutput.h
  13. 2 1
      panda/src/display/graphicsPipe.cxx
  14. 2 25
      panda/src/display/graphicsPipe.h
  15. 23 13
      panda/src/display/graphicsStateGuardian.I
  16. 9 10
      panda/src/display/graphicsStateGuardian.cxx
  17. 11 11
      panda/src/display/graphicsStateGuardian.h
  18. 2 1
      panda/src/display/graphicsWindow.cxx
  19. 1 0
      panda/src/display/graphicsWindow.h
  20. 1 1
      panda/src/display/parasiteBuffer.cxx
  21. 34 12
      panda/src/display/renderBuffer.h
  22. 2 6
      panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx
  23. 2 1
      panda/src/dxgsg8/wdxGraphicsBuffer8.cxx
  24. 1 0
      panda/src/dxgsg8/wdxGraphicsBuffer8.h
  25. 15 15
      panda/src/dxgsg8/wdxGraphicsPipe8.cxx
  26. 8 7
      panda/src/dxgsg8/wdxGraphicsPipe8.h
  27. 13 13
      panda/src/dxgsg8/wdxGraphicsWindow8.cxx
  28. 1 1
      panda/src/dxgsg8/wdxGraphicsWindow8.h
  29. 2 6
      panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx
  30. 3 2
      panda/src/dxgsg9/wdxGraphicsBuffer9.cxx
  31. 1 0
      panda/src/dxgsg9/wdxGraphicsBuffer9.h
  32. 15 16
      panda/src/dxgsg9/wdxGraphicsPipe9.cxx
  33. 2 1
      panda/src/dxgsg9/wdxGraphicsPipe9.h
  34. 13 13
      panda/src/dxgsg9/wdxGraphicsWindow9.cxx
  35. 1 0
      panda/src/dxgsg9/wdxGraphicsWindow9.h
  36. 39 4
      panda/src/glstuff/glGraphicsBuffer_src.cxx
  37. 1 0
      panda/src/glstuff/glGraphicsBuffer_src.h
  38. 36 39
      panda/src/glstuff/glGraphicsStateGuardian_src.cxx
  39. 2 1
      panda/src/glxdisplay/glxGraphicsBuffer.cxx
  40. 1 0
      panda/src/glxdisplay/glxGraphicsBuffer.h
  41. 12 9
      panda/src/glxdisplay/glxGraphicsPipe.cxx
  42. 1 0
      panda/src/glxdisplay/glxGraphicsPipe.h
  43. 1 0
      panda/src/glxdisplay/glxGraphicsWindow.cxx
  44. 1 0
      panda/src/glxdisplay/glxGraphicsWindow.h
  45. 6 5
      panda/src/mesadisplay/osMesaGraphicsBuffer.cxx
  46. 1 0
      panda/src/mesadisplay/osMesaGraphicsBuffer.h
  47. 6 6
      panda/src/mesadisplay/osMesaGraphicsPipe.cxx
  48. 1 0
      panda/src/mesadisplay/osMesaGraphicsPipe.h
  49. 2 1
      panda/src/osxdisplay/osxGraphicsBuffer.cxx
  50. 1 0
      panda/src/osxdisplay/osxGraphicsBuffer.h
  51. 11 12
      panda/src/osxdisplay/osxGraphicsPipe.cxx
  52. 2 1
      panda/src/osxdisplay/osxGraphicsPipe.h
  53. 2 1
      panda/src/osxdisplay/osxGraphicsWindow.cxx
  54. 1 0
      panda/src/osxdisplay/osxGraphicsWindow.h
  55. 6 5
      panda/src/wgldisplay/wglGraphicsBuffer.cxx
  56. 1 0
      panda/src/wgldisplay/wglGraphicsBuffer.h
  57. 27 22
      panda/src/wgldisplay/wglGraphicsPipe.cxx
  58. 2 1
      panda/src/wgldisplay/wglGraphicsPipe.h
  59. 2 1
      panda/src/wgldisplay/wglGraphicsWindow.cxx
  60. 1 0
      panda/src/wgldisplay/wglGraphicsWindow.h
  61. 2 1
      panda/src/windisplay/winGraphicsWindow.cxx
  62. 1 0
      panda/src/windisplay/winGraphicsWindow.h

+ 16 - 10
doc/makepanda/makepanda.py

@@ -375,7 +375,7 @@ def parseopts(args):
     global COMPILER,OPTIMIZE,OMIT,INSTALLER,GENMAN,SLAVEBUILD
     global COMPILER,OPTIMIZE,OMIT,INSTALLER,GENMAN,SLAVEBUILD
     global VERSION,COMPRESSOR,VERBOSE,SLAVEFILE,THREADCOUNT
     global VERSION,COMPRESSOR,VERBOSE,SLAVEFILE,THREADCOUNT
     longopts = [
     longopts = [
-        "help","package-info","compiler=","directx-sdk=","slavebuild=",
+        "help","package-info","compiler=","slavebuild=",
         "optimize=","everything","nothing","installer","quiet","verbose",
         "optimize=","everything","nothing","installer","quiet","verbose",
         "version=","lzma","no-python","slaves=","threads="]
         "version=","lzma","no-python","slaves=","threads="]
     anything = 0
     anything = 0
@@ -447,8 +447,8 @@ os.chdir(PANDASOURCE)
 ########################################################################
 ########################################################################
 
 
 if (os.path.isdir("sdks")):
 if (os.path.isdir("sdks")):
-    DIRECTXSDK["DX8"] = "sdks/directx"
-    DIRECTXSDK["DX9"] = "sdks/directx"
+    DIRECTXSDK["DX8"] = "sdks/directx8"
+    DIRECTXSDK["DX9"] = "sdks/directx9"
     MAXSDKCS["MAX6"] = "sdks/maxsdk6"
     MAXSDKCS["MAX6"] = "sdks/maxsdk6"
     MAXSDKCS["MAX7"] = "sdks/maxsdk7"
     MAXSDKCS["MAX7"] = "sdks/maxsdk7"
     MAXSDKCS["MAX8"] = "sdks/maxsdk8"
     MAXSDKCS["MAX8"] = "sdks/maxsdk8"
@@ -476,13 +476,19 @@ if sys.platform == "win32":
         if (subdir[0]=="{"):
         if (subdir[0]=="{"):
             dir = GetRegistryKey(uninstaller+"\\"+subdir, "InstallLocation")
             dir = GetRegistryKey(uninstaller+"\\"+subdir, "InstallLocation")
             if (dir != 0):
             if (dir != 0):
-                for ver in DXVERSIONS:
-                    if ((DIRECTXSDK.has_key("DX"+ver)==0) and
-                        (os.path.isfile(dir+"\\Include\\d3d"+ver+".h")) and
-                        (os.path.isfile(dir+"\\Include\\d3dx"+ver+".h")) and
-                        (os.path.isfile(dir+"\\Lib\\x86\\d3d"+ver+".lib")) and
-                        (os.path.isfile(dir+"\\Lib\\x86\\d3dx"+ver+".lib"))):
-                        DIRECTXSDK["DX"+ver] = dir.replace("\\", "/").rstrip("/")
+                if ((DIRECTXSDK.has_key("DX8")==0) and
+                    (os.path.isfile(dir+"\\Include\\d3d8.h")) and
+                    (os.path.isfile(dir+"\\Include\\d3dx8.h")) and
+                    (os.path.isfile(dir+"\\Lib\\d3d8.lib")) and
+                    (os.path.isfile(dir+"\\Lib\\d3dx8.lib"))):
+                   DIRECTXSDK["DX8"] = dir.replace("\\", "/").rstrip("/")
+                if ((DIRECTXSDK.has_key("DX9")==0) and
+                    (os.path.isfile(dir+"\\Include\\d3d9.h")) and
+                    (os.path.isfile(dir+"\\Include\\d3dx9.h")) and
+                    (os.path.isfile(dir+"\\Include\\dxsdkver.h")) and
+                    (os.path.isfile(dir+"\\Lib\\x86\\d3d9.lib")) and
+                    (os.path.isfile(dir+"\\Lib\\x86\\d3dx9.lib"))):
+                   DIRECTXSDK["DX9"] = dir.replace("\\", "/").rstrip("/")
     for ver in DXVERSIONS:
     for ver in DXVERSIONS:
         if (OMIT.count("DX"+ver)==0):
         if (OMIT.count("DX"+ver)==0):
             if (DIRECTXSDK.has_key("DX"+ver)==0):
             if (DIRECTXSDK.has_key("DX"+ver)==0):

+ 2 - 1
panda/src/display/displayRegion.cxx

@@ -646,7 +646,8 @@ get_screenshot(PNMImage &image) {
   // Create a temporary texture to receive the framebuffer image.
   // Create a temporary texture to receive the framebuffer image.
   PT(Texture) tex = new Texture;
   PT(Texture) tex = new Texture;
   
   
-  RenderBuffer buffer = gsg->get_render_buffer(get_screenshot_buffer_type());
+  RenderBuffer buffer = gsg->get_render_buffer(get_screenshot_buffer_type(),
+                                               _window->get_fb_properties());
   if (!gsg->framebuffer_copy_to_ram(tex, -1, this, buffer)) {
   if (!gsg->framebuffer_copy_to_ram(tex, -1, this, buffer)) {
     return false;
     return false;
   }
   }

+ 187 - 0
panda/src/display/frameBufferProperties.I

@@ -69,6 +69,7 @@ INLINE void FrameBufferProperties::
 set_frame_buffer_mode(int frameBuffer_mode) {
 set_frame_buffer_mode(int frameBuffer_mode) {
   _frame_buffer_mode = frameBuffer_mode;
   _frame_buffer_mode = frameBuffer_mode;
   _specified |= S_frame_buffer_mode;
   _specified |= S_frame_buffer_mode;
+  recalc_buffer_mask();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -105,6 +106,7 @@ INLINE void FrameBufferProperties::
 clear_frame_buffer_mode() {
 clear_frame_buffer_mode() {
   _specified &= ~S_frame_buffer_mode;
   _specified &= ~S_frame_buffer_mode;
   _frame_buffer_mode = 0;
   _frame_buffer_mode = 0;
+  recalc_buffer_mask();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -367,6 +369,191 @@ clear_multisamples() {
   _multisamples = 1;
   _multisamples = 1;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::set_aux_rgba
+//       Access: Published
+//  Description: Specifies the exact number of auxiliary RGBA
+//               bitplanes that are required.
+////////////////////////////////////////////////////////////////////
+INLINE void FrameBufferProperties::
+set_aux_rgba(int aux_rgba) {
+  _aux_rgba = aux_rgba;
+  _specified |= S_aux_rgba;
+  recalc_buffer_mask();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::get_aux_rgba
+//       Access: Published
+//  Description: Returns the exact number of auxiliary RGBA
+//               bitplanes that are required.
+////////////////////////////////////////////////////////////////////
+INLINE int FrameBufferProperties::
+get_aux_rgba() const {
+  return _aux_rgba;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::has_aux_rgba
+//       Access: Published
+//  Description: Returns true if the number auxiliary RGBA
+//               bitplanes has been specified, false otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool FrameBufferProperties::
+has_aux_rgba() const {
+  return ((_specified & S_aux_rgba) != 0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::clear_aux_rgba
+//       Access: Published
+//  Description: Removes the aux_rgba specification from the
+//               properties.
+////////////////////////////////////////////////////////////////////
+INLINE void FrameBufferProperties::
+clear_aux_rgba() {
+  _specified &= ~S_aux_rgba;
+  _aux_rgba = 0;
+  recalc_buffer_mask();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::set_aux_hrgba
+//       Access: Published
+//  Description: Specifies the exact number of auxiliary half-float
+//               RGBA bitplanes that are required.
+////////////////////////////////////////////////////////////////////
+INLINE void FrameBufferProperties::
+set_aux_hrgba(int aux_hrgba) {
+  _aux_hrgba = aux_hrgba;
+  _specified |= S_aux_hrgba;
+  recalc_buffer_mask();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::get_aux_hrgba
+//       Access: Published
+//  Description: Returns the exact number of auxiliary half-float
+//               RGBA bitplanes that are required.
+////////////////////////////////////////////////////////////////////
+INLINE int FrameBufferProperties::
+get_aux_hrgba() const {
+  return _aux_hrgba;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::has_aux_hrgba
+//       Access: Published
+//  Description: Returns true if the number of auxiliary half-float
+//               RGBA bitplanes has been specified, false otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool FrameBufferProperties::
+has_aux_hrgba() const {
+  return ((_specified & S_aux_hrgba) != 0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::clear_aux_hrgba
+//       Access: Published
+//  Description: Removes the aux_hrgba specification from the
+//               properties.
+////////////////////////////////////////////////////////////////////
+INLINE void FrameBufferProperties::
+clear_aux_hrgba() {
+  _specified &= ~S_aux_hrgba;
+  _aux_hrgba = 0;
+  recalc_buffer_mask();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::set_aux_float
+//       Access: Published
+//  Description: Specifies the exact number of auxiliary float
+//               single-channel bitplanes that are required.
+////////////////////////////////////////////////////////////////////
+INLINE void FrameBufferProperties::
+set_aux_float(int aux_float) {
+  _aux_float = aux_float;
+  _specified |= S_aux_float;
+  recalc_buffer_mask();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::get_aux_float
+//       Access: Published
+//  Description: Returns the exact number of auxiliary float
+//               single-channel bitplanes that are required.
+////////////////////////////////////////////////////////////////////
+INLINE int FrameBufferProperties::
+get_aux_float() const {
+  return _aux_float;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::has_aux_float
+//       Access: Published
+//  Description: Returns true if the number of auxiliary float
+//               single-channel bitplanes has been specified, false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool FrameBufferProperties::
+has_aux_float() const {
+  return ((_specified & S_aux_float) != 0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::clear_aux_float
+//       Access: Published
+//  Description: Removes the aux_float specification from the
+//               properties.
+////////////////////////////////////////////////////////////////////
+INLINE void FrameBufferProperties::
+clear_aux_float() {
+  _specified &= ~S_aux_float;
+  _aux_float = 0;
+  recalc_buffer_mask();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::get_buffer_mask
+//       Access: Public
+//  Description: Returns the buffer mask for the bitplanes
+//               in the frame buffer.
+////////////////////////////////////////////////////////////////////
+INLINE int FrameBufferProperties::
+get_buffer_mask() const {
+  return _buffer_mask;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::buffer_mask_remove
+//       Access: Public
+//  Description: Removes one or more bits from the buffer mask.
+//               This is generally called by the gsg when one of the
+//               bitplanes is failing for some implementation-
+//               dependent reason.  Changing the properties will
+//               cause the _buffer_mask information to be lost.
+////////////////////////////////////////////////////////////////////
+INLINE void FrameBufferProperties::
+buffer_mask_remove(int bits) {
+  _buffer_mask &= (~bits);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::buffer_mask_add
+//       Access: Public
+//  Description: Adds one or more bits to the buffer mask.
+//               This is generally called by the gsg when the
+//               implementation supplies a bitplane that was not
+//               specifically requested (say, a freebie stencil
+//               buffer). Changing the properties will
+//               cause the _buffer_mask information to be lost.
+////////////////////////////////////////////////////////////////////
+INLINE void FrameBufferProperties::
+buffer_mask_add(int bits) {
+  _buffer_mask |= bits;
+}
+
 INLINE ostream &
 INLINE ostream &
 operator << (ostream &out, const FrameBufferProperties &properties) {
 operator << (ostream &out, const FrameBufferProperties &properties) {
   properties.output(out);
   properties.output(out);

+ 64 - 2
panda/src/display/frameBufferProperties.cxx

@@ -18,7 +18,7 @@
 
 
 #include "frameBufferProperties.h"
 #include "frameBufferProperties.h"
 #include "string_utils.h"
 #include "string_utils.h"
-
+#include "renderBuffer.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: FrameBufferProperties::Constructor
 //     Function: FrameBufferProperties::Constructor
@@ -45,6 +45,10 @@ operator = (const FrameBufferProperties &copy) {
   _alpha_bits = copy._alpha_bits;
   _alpha_bits = copy._alpha_bits;
   _stencil_bits = copy._stencil_bits;
   _stencil_bits = copy._stencil_bits;
   _multisamples = copy._multisamples;
   _multisamples = copy._multisamples;
+  _aux_rgba = copy._aux_rgba;
+  _aux_hrgba = copy._aux_hrgba;
+  _aux_float = copy._aux_float;
+  _buffer_mask = copy._buffer_mask;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -139,6 +143,8 @@ get_default() {
   props.set_stencil_bits(stencil_bits);
   props.set_stencil_bits(stencil_bits);
   props.set_multisamples(multisamples);
   props.set_multisamples(multisamples);
 
 
+  props.recalc_buffer_mask();
+
   return props;
   return props;
 }
 }
 
 
@@ -156,7 +162,11 @@ operator == (const FrameBufferProperties &other) const {
           _color_bits == other._color_bits &&
           _color_bits == other._color_bits &&
           _alpha_bits == other._alpha_bits &&
           _alpha_bits == other._alpha_bits &&
           _stencil_bits == other._stencil_bits &&
           _stencil_bits == other._stencil_bits &&
-          _multisamples == other._multisamples);
+          _multisamples == other._multisamples &&
+          _aux_rgba == other._aux_rgba &&
+          _aux_hrgba == other._aux_hrgba &&
+          _aux_float == other._aux_float &&
+          _buffer_mask == other._buffer_mask);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -176,6 +186,10 @@ clear() {
   _alpha_bits = 1;
   _alpha_bits = 1;
   _stencil_bits = 1;
   _stencil_bits = 1;
   _multisamples = 1;
   _multisamples = 1;
+  _aux_rgba = 0;
+  _aux_hrgba = 0;
+  _aux_float = 0;
+  recalc_buffer_mask();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -205,6 +219,15 @@ add_properties(const FrameBufferProperties &other) {
   if (other.has_multisamples()) {
   if (other.has_multisamples()) {
     set_multisamples(other.get_multisamples());
     set_multisamples(other.get_multisamples());
   }
   }
+  if (other.has_aux_rgba()) {
+    set_aux_rgba(other.get_aux_rgba());
+  }
+  if (other.has_aux_hrgba()) {
+    set_aux_hrgba(other.get_aux_hrgba());
+  }
+  if (other.has_aux_float()) {
+    set_aux_float(other.get_aux_float());
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -274,4 +297,43 @@ output(ostream &out) const {
   if (has_multisamples()) {
   if (has_multisamples()) {
     out << "multisamples=" << get_multisamples() << " ";
     out << "multisamples=" << get_multisamples() << " ";
   }
   }
+  if (has_aux_rgba()) {
+    out << "aux_rgba=" << get_aux_rgba() << " ";
+  }
+  if (has_aux_hrgba()) {
+    out << "aux_hrgba=" << get_aux_hrgba() << " ";
+  }
+  if (has_aux_float()) {
+    out << "aux_float=" << get_aux_float() << " ";
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FrameBufferProperties::recalc_buffer_mask
+//       Access: Private
+//  Description: Calculates the buffer mask based on the mode
+//               and aux bitplanes.
+////////////////////////////////////////////////////////////////////
+void FrameBufferProperties::
+recalc_buffer_mask() {
+  if ((_frame_buffer_mode & FM_buffer) == FM_single_buffer) {
+    _buffer_mask = RenderBuffer::T_front;
+  } else {
+    _buffer_mask = RenderBuffer::T_front | RenderBuffer::T_back;
+  }
+  if (_frame_buffer_mode & FM_depth) {
+    _buffer_mask |= RenderBuffer::T_depth;
+  }
+  if (_frame_buffer_mode & FM_stencil) {
+    _buffer_mask |= RenderBuffer::T_stencil;
+  }
+  for (int aux_rgba=0; aux_rgba < _aux_rgba; ++aux_rgba) {
+    _buffer_mask |= (RenderBuffer::T_aux_rgba_0 << aux_rgba);
+  }
+  for (int aux_hrgba=0; aux_hrgba < _aux_hrgba; ++aux_hrgba) {
+    _buffer_mask |= (RenderBuffer::T_aux_hrgba_0 << aux_hrgba);
+  }
+  for (int aux_float=0; aux_float < _aux_float; ++aux_float) {
+    _buffer_mask |= (RenderBuffer::T_aux_float_0 << aux_float);
+  }
 }
 }

+ 31 - 2
panda/src/display/frameBufferProperties.h

@@ -58,6 +58,7 @@ PUBLISHED:
   };
   };
 
 
   void clear();
   void clear();
+  INLINE int get_buffer_mask() const;
   INLINE bool is_any_specified() const;
   INLINE bool is_any_specified() const;
 
 
   INLINE void set_frame_buffer_mode(int frameBuffer_mode);
   INLINE void set_frame_buffer_mode(int frameBuffer_mode);
@@ -92,10 +93,31 @@ PUBLISHED:
   INLINE bool has_multisamples() const;
   INLINE bool has_multisamples() const;
   INLINE void clear_multisamples();
   INLINE void clear_multisamples();
 
 
-  void add_properties(const FrameBufferProperties &other);
+  INLINE void set_aux_rgba(int naux);
+  INLINE int get_aux_rgba() const;
+  INLINE bool has_aux_rgba() const;
+  INLINE void clear_aux_rgba();
+  
+  INLINE void set_aux_hrgba(int naux);
+  INLINE int get_aux_hrgba() const;
+  INLINE bool has_aux_hrgba() const;
+  INLINE void clear_aux_hrgba();
+
+  INLINE void set_aux_float(int naux);
+  INLINE int get_aux_float() const;
+  INLINE bool has_aux_float() const;
+  INLINE void clear_aux_float();
 
 
+  void add_properties(const FrameBufferProperties &other);
   void output(ostream &out) const;
   void output(ostream &out) const;
-  
+
+public:
+  INLINE void buffer_mask_add(int bits);
+  INLINE void buffer_mask_remove(int bits);
+
+private:
+  void recalc_buffer_mask();
+
 private:
 private:
   // This bitmask indicates which of the parameters in the properties
   // This bitmask indicates which of the parameters in the properties
   // structure have been filled in by the user, and which remain
   // structure have been filled in by the user, and which remain
@@ -107,6 +129,9 @@ private:
     S_alpha_bits        = 0x0008,
     S_alpha_bits        = 0x0008,
     S_stencil_bits      = 0x0010,
     S_stencil_bits      = 0x0010,
     S_multisamples      = 0x0020,
     S_multisamples      = 0x0020,
+    S_aux_rgba          = 0x0040,
+    S_aux_hrgba         = 0x0080,
+    S_aux_float         = 0x0100,
   };
   };
 
 
   int _specified;
   int _specified;
@@ -117,6 +142,10 @@ private:
   int _alpha_bits;
   int _alpha_bits;
   int _stencil_bits;
   int _stencil_bits;
   int _multisamples;
   int _multisamples;
+  int _aux_rgba;
+  int _aux_hrgba;
+  int _aux_float;
+  int _buffer_mask;
 };
 };
 
 
 INLINE ostream &operator << (ostream &out, const FrameBufferProperties &properties);
 INLINE ostream &operator << (ostream &out, const FrameBufferProperties &properties);

+ 3 - 2
panda/src/display/graphicsBuffer.cxx

@@ -30,10 +30,11 @@ TypeHandle GraphicsBuffer::_type_handle;
 GraphicsBuffer::
 GraphicsBuffer::
 GraphicsBuffer(GraphicsPipe *pipe,
 GraphicsBuffer(GraphicsPipe *pipe,
                const string &name,
                const string &name,
+               const FrameBufferProperties &properties,
                int x_size, int y_size, int flags,
                int x_size, int y_size, int flags,
                GraphicsStateGuardian *gsg,
                GraphicsStateGuardian *gsg,
                GraphicsOutput *host) :
                GraphicsOutput *host) :
-  GraphicsOutput(pipe, name, x_size, y_size, flags, gsg, host)
+  GraphicsOutput(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
 #ifdef DO_MEMORY_USAGE
 #ifdef DO_MEMORY_USAGE
   MemoryUsage::update_type(this, this);
   MemoryUsage::update_type(this, this);
@@ -69,7 +70,7 @@ void GraphicsBuffer::
 request_open() {
 request_open() {
   _open_request = OR_open;
   _open_request = OR_open;
 }
 }
- 
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsBuffer::request_close
 //     Function: GraphicsBuffer::request_close
 //       Access: Public, Virtual
 //       Access: Public, Virtual

+ 1 - 0
panda/src/display/graphicsBuffer.h

@@ -35,6 +35,7 @@ class EXPCL_PANDA GraphicsBuffer : public GraphicsOutput {
 protected:
 protected:
   GraphicsBuffer(GraphicsPipe *pipe, 
   GraphicsBuffer(GraphicsPipe *pipe, 
                  const string &name,
                  const string &name,
+                 const FrameBufferProperties &properties,
                  int x_size, int y_size, int flags,
                  int x_size, int y_size, int flags,
                  GraphicsStateGuardian *gsg,
                  GraphicsStateGuardian *gsg,
                  GraphicsOutput *host);
                  GraphicsOutput *host);

+ 4 - 4
panda/src/display/graphicsEngine.I

@@ -125,7 +125,7 @@ INLINE GraphicsWindow *GraphicsEngine::
 make_window(GraphicsStateGuardian *gsg, const string &name, int sort) {
 make_window(GraphicsStateGuardian *gsg, const string &name, int sort) {
   // The hardwired size here is never used.
   // The hardwired size here is never used.
   GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort,
   GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort,
-                                       gsg->get_properties(), 50, 50,
+                                       gsg->get_default_properties(), 50, 50,
                                        GraphicsPipe::BF_require_window,
                                        GraphicsPipe::BF_require_window,
                                        gsg, NULL);
                                        gsg, NULL);
   return DCAST(GraphicsWindow, result);
   return DCAST(GraphicsWindow, result);
@@ -140,7 +140,7 @@ INLINE GraphicsOutput *GraphicsEngine::
 make_buffer(GraphicsStateGuardian *gsg, const string &name,
 make_buffer(GraphicsStateGuardian *gsg, const string &name,
             int sort, int x_size, int y_size) {
             int sort, int x_size, int y_size) {
    GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort,
    GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort,
-                                        gsg->get_properties(), x_size, y_size,
+                                        gsg->get_default_properties(), x_size, y_size,
                                         GraphicsPipe::BF_refuse_window,
                                         GraphicsPipe::BF_refuse_window,
                                         gsg, NULL);
                                         gsg, NULL);
    return result;
    return result;
@@ -154,8 +154,8 @@ make_buffer(GraphicsStateGuardian *gsg, const string &name,
 INLINE GraphicsOutput *GraphicsEngine::
 INLINE GraphicsOutput *GraphicsEngine::
 make_parasite(GraphicsOutput *host, const string &name, 
 make_parasite(GraphicsOutput *host, const string &name, 
               int sort, int x_size, int y_size) {
               int sort, int x_size, int y_size) {
-  GraphicsOutput *result = make_output(host->get_gsg()->get_pipe(), name, sort,
-                                       host->get_gsg()->get_properties(), x_size, y_size,
+  GraphicsOutput *result = make_output(host->get_pipe(), name, sort,
+                                       host->get_fb_properties(), x_size, y_size,
                                        GraphicsPipe::BF_require_parasite,
                                        GraphicsPipe::BF_require_parasite,
                                        host->get_gsg(), host);
                                        host->get_gsg(), host);
    return result;
    return result;

+ 9 - 14
panda/src/display/graphicsEngine.cxx

@@ -282,11 +282,11 @@ make_output(GraphicsPipe *pipe,
   //
   //
   //  The only problem with this design is that it requires the
   //  The only problem with this design is that it requires the
   //  engine to call open_windows, which is slow.  To make
   //  engine to call open_windows, which is slow.  To make
-  //  things faster, we can ask pipe::make_output to "precertify"
-  //  its creations.  If we ask it to precertify, then it guarantees
+  //  things faster, the pipe can choose to "precertify"
+  //  its creations.  If it chooses to do so, this is a guarantee
   //  that the windows it returns will not fail in open_windows.
   //  that the windows it returns will not fail in open_windows.
-  //  However, we can only ask for precertification if we are
-  //  passing it an already-initialized gsg.  Long story short,
+  //  However, most graphics pipes will only precertify if you
+  //  pass them an already-initialized gsg.  Long story short,
   //  if you want make_output to be fast, use an
   //  if you want make_output to be fast, use an
   //  already-initialized gsg.
   //  already-initialized gsg.
 
 
@@ -306,7 +306,6 @@ make_output(GraphicsPipe *pipe,
   if (gsg != (GraphicsStateGuardian *)NULL) {
   if (gsg != (GraphicsStateGuardian *)NULL) {
     nassertr(pipe == gsg->get_pipe(), NULL);
     nassertr(pipe == gsg->get_pipe(), NULL);
     nassertr(this == gsg->get_engine(), NULL);
     nassertr(this == gsg->get_engine(), NULL);
-    nassertr(prop == gsg->get_properties(), NULL);
     nassertr(threading_model.get_draw_name() ==
     nassertr(threading_model.get_draw_name() ==
              gsg->get_threading_model().get_draw_name(), NULL);
              gsg->get_threading_model().get_draw_name(), NULL);
   }
   }
@@ -320,20 +319,12 @@ make_output(GraphicsPipe *pipe,
     gsg = make_gsg(pipe, prop);
     gsg = make_gsg(pipe, prop);
   }
   }
   
   
-  // A thread could modify these flags while we create the
-  // buffer.  So we do a single atomic fetch here.
-  
-  bool precertify = gsg->_is_valid && (!gsg->_needs_reset);
-  
   // Determine if a parasite buffer meets the user's specs.
   // Determine if a parasite buffer meets the user's specs.
 
 
   bool can_use_parasite = false;
   bool can_use_parasite = false;
   if ((host != 0)&&
   if ((host != 0)&&
       ((flags&GraphicsPipe::BF_require_window)==0)&&
       ((flags&GraphicsPipe::BF_require_window)==0)&&
       ((flags&GraphicsPipe::BF_refuse_parasite)==0)&&
       ((flags&GraphicsPipe::BF_refuse_parasite)==0)&&
-      ((flags&GraphicsPipe::BF_need_aux_rgba_MASK)==0)&&
-      ((flags&GraphicsPipe::BF_need_aux_hrgba_MASK)==0)&&
-      ((flags&GraphicsPipe::BF_need_aux_float_MASK)==0)&&
       ((flags&GraphicsPipe::BF_can_bind_color)==0)&&
       ((flags&GraphicsPipe::BF_can_bind_color)==0)&&
       ((flags&GraphicsPipe::BF_can_bind_every)==0)) {
       ((flags&GraphicsPipe::BF_can_bind_every)==0)) {
     can_use_parasite = true;
     can_use_parasite = true;
@@ -354,8 +345,9 @@ make_output(GraphicsPipe *pipe,
   // Ask the pipe to create a window.
   // Ask the pipe to create a window.
   
   
   for (int retry=0; retry<10; retry++) {
   for (int retry=0; retry<10; retry++) {
+    bool precertify = false;
     PT(GraphicsOutput) window = 
     PT(GraphicsOutput) window = 
-      pipe->make_output(name, x_size, y_size, flags, gsg, host, retry, precertify);
+      pipe->make_output(name, prop, x_size, y_size, flags, gsg, host, retry, precertify);
     if (window != (GraphicsOutput *)NULL) {
     if (window != (GraphicsOutput *)NULL) {
       window->_sort = sort;
       window->_sort = sort;
       do_add_window(window, gsg, threading_model);
       do_add_window(window, gsg, threading_model);
@@ -923,6 +915,7 @@ cull_and_draw_together(const GraphicsEngine::Windows &wlist) {
   for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
   for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
     GraphicsOutput *win = (*wi);
     GraphicsOutput *win = (*wi);
     if (win->is_active() && win->get_gsg()->is_active()) {
     if (win->is_active() && win->get_gsg()->is_active()) {
+      win->get_gsg()->set_current_properties(&win->get_fb_properties());
       if (win->begin_frame(GraphicsOutput::FM_render)) {
       if (win->begin_frame(GraphicsOutput::FM_render)) {
         win->clear();
         win->clear();
       
       
@@ -1088,6 +1081,7 @@ draw_bins(const GraphicsEngine::Windows &wlist) {
   for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
   for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
     GraphicsOutput *win = (*wi);
     GraphicsOutput *win = (*wi);
     if (win->is_active() && win->get_gsg()->is_active()) {
     if (win->is_active() && win->get_gsg()->is_active()) {
+      win->get_gsg()->set_current_properties(&win->get_fb_properties());
       if (win->begin_frame(GraphicsOutput::FM_render)) {
       if (win->begin_frame(GraphicsOutput::FM_render)) {
         win->clear();
         win->clear();
       
       
@@ -1148,6 +1142,7 @@ make_contexts(const GraphicsEngine::Windows &wlist) {
   Windows::const_iterator wi;
   Windows::const_iterator wi;
   for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
   for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
     GraphicsOutput *win = (*wi);
     GraphicsOutput *win = (*wi);
+    win->get_gsg()->set_current_properties(&win->get_fb_properties());
     if (win->begin_frame(GraphicsOutput::FM_refresh)) {
     if (win->begin_frame(GraphicsOutput::FM_refresh)) {
       win->end_frame(GraphicsOutput::FM_refresh);
       win->end_frame(GraphicsOutput::FM_refresh);
     }
     }

+ 12 - 2
panda/src/display/graphicsOutput.I

@@ -293,6 +293,16 @@ get_right_eye_color_mask() const {
   return _right_eye_color_mask;
   return _right_eye_color_mask;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsOutput::get_fb_properties
+//       Access: Published
+//  Description: Returns the framebuffer properties of the window.
+////////////////////////////////////////////////////////////////////
+INLINE FrameBufferProperties &GraphicsOutput::
+get_fb_properties() {
+  return _fb_properties;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsOutput::is_stereo
 //     Function: GraphicsOutput::is_stereo
 //       Access: Published
 //       Access: Published
@@ -303,7 +313,7 @@ get_right_eye_color_mask() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool GraphicsOutput::
 INLINE bool GraphicsOutput::
 is_stereo() const {
 is_stereo() const {
-  return _red_blue_stereo || _gsg->get_properties().is_stereo();
+  return _red_blue_stereo || _fb_properties.is_stereo();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -547,7 +557,7 @@ clear_cube_map_selection() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void GraphicsOutput::
 INLINE void GraphicsOutput::
 trigger_flip() {
 trigger_flip() {
-  if (!_gsg->get_properties().is_single_buffered()) {
+  if (!_fb_properties.is_single_buffered()) {
     _flip_ready = true;
     _flip_ready = true;
   }
   }
 }
 }

+ 8 - 5
panda/src/display/graphicsOutput.cxx

@@ -71,6 +71,7 @@ static CubeFaceDef cube_faces[6] = {
 GraphicsOutput::
 GraphicsOutput::
 GraphicsOutput(GraphicsPipe *pipe,
 GraphicsOutput(GraphicsPipe *pipe,
                const string &name,
                const string &name,
+               const FrameBufferProperties &properties,
                int x_size, int y_size, int flags,
                int x_size, int y_size, int flags,
                GraphicsStateGuardian *gsg,
                GraphicsStateGuardian *gsg,
                GraphicsOutput *host) {
                GraphicsOutput *host) {
@@ -80,6 +81,7 @@ GraphicsOutput(GraphicsPipe *pipe,
   _pipe = pipe;
   _pipe = pipe;
   _gsg = gsg;
   _gsg = gsg;
   _host = host;
   _host = host;
+  _fb_properties = properties;
   _name = name;
   _name = name;
   _creation_flags = flags;
   _creation_flags = flags;
   _x_size = x_size;
   _x_size = x_size;
@@ -101,8 +103,7 @@ GraphicsOutput(GraphicsPipe *pipe,
   _texture_card = 0;
   _texture_card = 0;
   _trigger_copy = false;
   _trigger_copy = false;
 
 
-  if (gsg->get_properties().is_single_buffered()) {
-    // Single buffered; we must draw into the front buffer.
+  if (_fb_properties.is_single_buffered()) {
     _draw_buffer_type = RenderBuffer::T_front;
     _draw_buffer_type = RenderBuffer::T_front;
   } else {
   } else {
     _draw_buffer_type = RenderBuffer::T_back;
     _draw_buffer_type = RenderBuffer::T_back;
@@ -690,7 +691,7 @@ make_texture_buffer(const string &name, int x_size, int y_size,
   GraphicsOutput *buffer = get_gsg()->get_engine()->
   GraphicsOutput *buffer = get_gsg()->get_engine()->
     make_output(get_gsg()->get_pipe(),
     make_output(get_gsg()->get_pipe(),
                 name, get_sort()-1,
                 name, get_sort()-1,
-                get_gsg()->get_properties(),
+                get_host()->get_fb_properties(),
                 x_size, y_size, GraphicsPipe::BF_refuse_window,
                 x_size, y_size, GraphicsPipe::BF_refuse_window,
                 get_gsg(), get_host());
                 get_gsg(), get_host());
 
 
@@ -992,7 +993,8 @@ copy_to_textures() {
         display_cat.debug()
         display_cat.debug()
           << "cube_map_index = " << _cube_map_index << "\n";
           << "cube_map_index = " << _cube_map_index << "\n";
       }
       }
-      RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());
+      RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type(),
+                                                    get_fb_properties());
       if (_cube_map_dr != (DisplayRegion *)NULL) {
       if (_cube_map_dr != (DisplayRegion *)NULL) {
         if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
         if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
           _gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
           _gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
@@ -1055,7 +1057,8 @@ change_scenes(DisplayRegion *new_dr) {
             display_cat.debug()
             display_cat.debug()
               << "cube_map_index = " << old_cube_map_index << "\n";
               << "cube_map_index = " << old_cube_map_index << "\n";
           }
           }
-          RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());
+          RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type(),
+                                                        get_fb_properties());
           if (rtm_mode == RTM_copy_ram) {
           if (rtm_mode == RTM_copy_ram) {
             _gsg->framebuffer_copy_to_ram(texture, old_cube_map_index,
             _gsg->framebuffer_copy_to_ram(texture, old_cube_map_index,
                                           old_cube_map_dr, buffer);
                                           old_cube_map_dr, buffer);

+ 4 - 0
panda/src/display/graphicsOutput.h

@@ -63,6 +63,7 @@ class EXPCL_PANDA GraphicsOutput : public TypedWritableReferenceCount, public Dr
 protected:
 protected:
   GraphicsOutput(GraphicsPipe *pipe, 
   GraphicsOutput(GraphicsPipe *pipe, 
                  const string &name,
                  const string &name,
+                 const FrameBufferProperties &properties,
                  int x_size, int y_size, int flags,
                  int x_size, int y_size, int flags,
                  GraphicsStateGuardian *gsg,
                  GraphicsStateGuardian *gsg,
                  GraphicsOutput *host);
                  GraphicsOutput *host);
@@ -123,6 +124,7 @@ PUBLISHED:
   INLINE unsigned int get_left_eye_color_mask() const;
   INLINE unsigned int get_left_eye_color_mask() const;
   INLINE unsigned int get_right_eye_color_mask() const;
   INLINE unsigned int get_right_eye_color_mask() const;
 
 
+  INLINE FrameBufferProperties &get_fb_properties();
   INLINE bool is_stereo() const;
   INLINE bool is_stereo() const;
 
 
   INLINE void clear_delete_flag();
   INLINE void clear_delete_flag();
@@ -229,6 +231,8 @@ protected:
   PT(GraphicsStateGuardian) _gsg;
   PT(GraphicsStateGuardian) _gsg;
   PT(GraphicsPipe) _pipe;
   PT(GraphicsPipe) _pipe;
   PT(GraphicsOutput) _host;
   PT(GraphicsOutput) _host;
+  FrameBufferProperties _fb_properties;
+  bool _stereo;
   string _name;
   string _name;
   pvector<RenderTexture> _textures;
   pvector<RenderTexture> _textures;
   bool _flip_ready;
   bool _flip_ready;

+ 2 - 1
panda/src/display/graphicsPipe.cxx

@@ -192,11 +192,12 @@ close_gsg(GraphicsStateGuardian *gsg) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsOutput) GraphicsPipe::
 PT(GraphicsOutput) GraphicsPipe::
 make_output(const string &name,
 make_output(const string &name,
+            const FrameBufferProperties &properties,
             int x_size, int y_size, int flags,
             int x_size, int y_size, int flags,
             GraphicsStateGuardian *gsg,
             GraphicsStateGuardian *gsg,
             GraphicsOutput *host,
             GraphicsOutput *host,
             int retry,
             int retry,
-            bool precertify) {
+            bool &precertify) {
   display_cat.error()
   display_cat.error()
     << get_type() << " cannot create buffers or windows.\n";
     << get_type() << " cannot create buffers or windows.\n";
   return NULL;
   return NULL;

+ 2 - 25
panda/src/display/graphicsPipe.h

@@ -74,30 +74,6 @@ PUBLISHED:
   };
   };
 
 
   enum BufferCreationFlags {
   enum BufferCreationFlags {
-
-    // How many RGBA aux bitplanes do you need?
-    BF_need_aux_rgba_MASK  = 0x00000003,
-    BF_need_0_aux_rgba     = 0x00000000,
-    BF_need_1_aux_rgba     = 0x00000001,
-    BF_need_2_aux_rgba     = 0x00000002,
-    BF_need_3_aux_rgba     = 0x00000003,
-
-    // How many half-float rgba aux bitplanes do you need?
-    // This is not currently implemented.
-    BF_need_aux_hrgba_MASK = 0x0000000C,
-    BF_need_0_aux_hrgba    = 0x00000000,
-    BF_need_1_aux_hrgba    = 0x00000004,
-    BF_need_2_aux_hrgba    = 0x00000008,
-    BF_need_3_aux_hrgba    = 0x0000000C,
-
-    // How many full-float single-channel bitplanes do you need?
-    // This is not currently implemented.
-    BF_need_aux_float_MASK = 0x00000030,
-    BF_need_0_aux_float    = 0x00000000,
-    BF_need_1_aux_float    = 0x00000010,
-    BF_need_2_aux_float    = 0x00000020,
-    BF_need_3_aux_float    = 0x00000040,
-
     // Flags that control what type of output is returned.
     // Flags that control what type of output is returned.
     BF_refuse_parasite     = 0x00000100,
     BF_refuse_parasite     = 0x00000100,
     BF_require_parasite    = 0x00000200,
     BF_require_parasite    = 0x00000200,
@@ -136,11 +112,12 @@ protected:
   virtual void close_gsg(GraphicsStateGuardian *gsg);
   virtual void close_gsg(GraphicsStateGuardian *gsg);
   
   
   virtual PT(GraphicsOutput) make_output(const string &name,
   virtual PT(GraphicsOutput) make_output(const string &name,
+                                         const FrameBufferProperties &properties,
                                          int x_size, int y_size, int flags,
                                          int x_size, int y_size, int flags,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsOutput *host,
                                          GraphicsOutput *host,
                                          int retry,
                                          int retry,
-                                         bool precertify);
+                                         bool &precertify);
   
   
   Mutex _lock;
   Mutex _lock;
 
 

+ 23 - 13
panda/src/display/graphicsStateGuardian.I

@@ -135,13 +135,14 @@ is_valid() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_properties
 //     Function: GraphicsStateGuardian::get_properties
 //       Access: Published
 //       Access: Published
-//  Description: Returns the frame buffer properties requested for
-//               this GSG.  All windows created for this GSG must be
-//               created with the same properties.
+//  Description: Returns the default frame buffer properties for
+//               this GSG.  All windows created for this GSG will be
+//               created with these properties, unless explicitly
+//               overridden.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE const FrameBufferProperties &GraphicsStateGuardian::
 INLINE const FrameBufferProperties &GraphicsStateGuardian::
-get_properties() const {
-  return _properties;
+get_default_properties() const {
+  return _default_properties;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -630,6 +631,17 @@ mark_new() {
   _needs_reset = true;
   _needs_reset = true;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::needs_reset
+//       Access: Public
+//  Description: Returns true if the gsg is marked as needing a
+//               reset.
+////////////////////////////////////////////////////////////////////
+INLINE bool GraphicsStateGuardian::
+needs_reset() const {
+  return _needs_reset;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_transform
 //     Function: GraphicsStateGuardian::get_transform
 //       Access: Public
 //       Access: Public
@@ -729,15 +741,13 @@ get_clip_plane(int plane_id) const {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::set_properties
+//     Function: GraphicsStateGuardian::set_current_properties
 //       Access: Protected
 //       Access: Protected
-//  Description: Changes the frame buffer properties structure
-//               representing this GSG's capabilities.  Normally, this
-//               should only be called by a derived class wishing to
-//               indicate that the originally-requested capabilities
-//               could not be granted.
+//  Description: Notifies the gsg that it is about to render into a
+//               window/buffer with the given FrameBufferProperties
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void GraphicsStateGuardian::
 INLINE void GraphicsStateGuardian::
-set_properties(const FrameBufferProperties &properties) {
-  _properties = properties;
+set_current_properties(FrameBufferProperties *prop) {
+  _current_properties = prop;
 }
 }
+

+ 9 - 10
panda/src/display/graphicsStateGuardian.cxx

@@ -79,7 +79,7 @@ GraphicsStateGuardian::
 GraphicsStateGuardian(const FrameBufferProperties &properties,
 GraphicsStateGuardian(const FrameBufferProperties &properties,
                       CoordinateSystem internal_coordinate_system) :
                       CoordinateSystem internal_coordinate_system) :
   _internal_coordinate_system(internal_coordinate_system),
   _internal_coordinate_system(internal_coordinate_system),
-  _properties(properties)
+  _default_properties(properties)
 {
 {
   _coordinate_system = CS_invalid;
   _coordinate_system = CS_invalid;
   _external_transform = TransformState::make_identity();
   _external_transform = TransformState::make_identity();
@@ -95,9 +95,11 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
   
   
   _needs_reset = true;
   _needs_reset = true;
   _is_valid = false;
   _is_valid = false;
+  _current_properties = NULL;
   _closing_gsg = false;
   _closing_gsg = false;
   _active = true;
   _active = true;
   _prepared_objects = new PreparedGraphicsObjects;
   _prepared_objects = new PreparedGraphicsObjects;
+  _stereo_buffer_mask = ~0;
 
 
   _prefers_triangle_strips = false;
   _prefers_triangle_strips = false;
   _max_vertices_per_array = INT_MAX;
   _max_vertices_per_array = INT_MAX;
@@ -274,16 +276,12 @@ reset() {
   _scene_null = new SceneSetup;
   _scene_null = new SceneSetup;
   _scene_setup = _scene_null;
   _scene_setup = _scene_null;
   
   
-  _buffer_mask = 0;
-  _stereo_buffer_mask = ~0;
   _color_write_mask = ColorWriteAttrib::C_all;
   _color_write_mask = ColorWriteAttrib::C_all;
   _color_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
   _color_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
   _depth_clear_value = 1.0f;
   _depth_clear_value = 1.0f;
   _stencil_clear_value = 0.0f;
   _stencil_clear_value = 0.0f;
   _accum_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
   _accum_clear_value.set(0.0f, 0.0f, 0.0f, 0.0f);
 
 
-  _is_stereo = get_properties().is_stereo();
-
   _has_scene_graph_color = false;
   _has_scene_graph_color = false;
   _transform_stale = true;
   _transform_stale = true;
   _color_blend_involves_color_scale = false;
   _color_blend_involves_color_scale = false;
@@ -336,8 +334,8 @@ set_state_and_transform(const RenderState *state,
 //               union of all the desired RenderBuffer::Type values.
 //               union of all the desired RenderBuffer::Type values.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 RenderBuffer GraphicsStateGuardian::
 RenderBuffer GraphicsStateGuardian::
-get_render_buffer(int buffer_type) {
-  return RenderBuffer(this, buffer_type & _buffer_mask & _stereo_buffer_mask);
+get_render_buffer(int buffer_type, const FrameBufferProperties &prop) {
+  return RenderBuffer(this, buffer_type & prop.get_buffer_mask() & _stereo_buffer_mask);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -647,7 +645,8 @@ clear(DrawableRegion *clearable) {
   }
   }
 
 
   if (clear_buffer_type != 0) {
   if (clear_buffer_type != 0) {
-    do_clear(get_render_buffer(clear_buffer_type));
+    do_clear(get_render_buffer(clear_buffer_type,
+                               *_current_properties));
   }
   }
 }
 }
 
 
@@ -901,14 +900,14 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) {
   switch (stereo_channel) {
   switch (stereo_channel) {
   case Lens::SC_left:
   case Lens::SC_left:
     _color_write_mask = dr->get_window()->get_left_eye_color_mask();
     _color_write_mask = dr->get_window()->get_left_eye_color_mask();
-    if (_is_stereo) {
+    if (_current_properties->is_stereo()) {
       _stereo_buffer_mask = ~(RenderBuffer::T_front_right | RenderBuffer::T_back_right);
       _stereo_buffer_mask = ~(RenderBuffer::T_front_right | RenderBuffer::T_back_right);
     }
     }
     break;
     break;
 
 
   case Lens::SC_right:
   case Lens::SC_right:
     _color_write_mask = dr->get_window()->get_right_eye_color_mask();
     _color_write_mask = dr->get_window()->get_right_eye_color_mask();
-    if (_is_stereo) {
+    if (_current_properties->is_stereo()) {
       _stereo_buffer_mask = ~(RenderBuffer::T_front_left | RenderBuffer::T_back_left);
       _stereo_buffer_mask = ~(RenderBuffer::T_front_left | RenderBuffer::T_back_left);
     }
     }
     break;
     break;

+ 11 - 11
panda/src/display/graphicsStateGuardian.h

@@ -78,8 +78,9 @@ PUBLISHED:
   INLINE void set_active(bool active);
   INLINE void set_active(bool active);
   INLINE bool is_active() const;
   INLINE bool is_active() const;
   INLINE bool is_valid() const;
   INLINE bool is_valid() const;
+  INLINE bool needs_reset() const;
 
 
-  INLINE const FrameBufferProperties &get_properties() const;
+  INLINE const FrameBufferProperties &get_default_properties() const;
   INLINE GraphicsPipe *get_pipe() const;
   INLINE GraphicsPipe *get_pipe() const;
   INLINE GraphicsEngine *get_engine() const;
   INLINE GraphicsEngine *get_engine() const;
   INLINE const GraphicsThreadingModel &get_threading_model() const;
   INLINE const GraphicsThreadingModel &get_threading_model() const;
@@ -202,8 +203,8 @@ public:
 
 
   INLINE CPT(TransformState) get_transform();
   INLINE CPT(TransformState) get_transform();
   
   
-  RenderBuffer get_render_buffer(int buffer_type);
-
+  RenderBuffer get_render_buffer(int buffer_type, const FrameBufferProperties &prop);
+  
   INLINE const DisplayRegion *get_current_display_region() const;
   INLINE const DisplayRegion *get_current_display_region() const;
   INLINE Lens::StereoChannel get_current_stereo_channel() const;
   INLINE Lens::StereoChannel get_current_stereo_channel() const;
   INLINE const Lens *get_current_lens() const;
   INLINE const Lens *get_current_lens() const;
@@ -238,14 +239,14 @@ protected:
   virtual void bind_clip_plane(const NodePath &plane, int plane_id);
   virtual void bind_clip_plane(const NodePath &plane, int plane_id);
   virtual void end_bind_clip_planes();
   virtual void end_bind_clip_planes();
 
 
+  void set_current_properties(FrameBufferProperties *properties);
+  
   virtual void free_pointers();
   virtual void free_pointers();
   virtual void close_gsg();
   virtual void close_gsg();
   void panic_deactivate();
   void panic_deactivate();
 
 
   void determine_light_color_scale();
   void determine_light_color_scale();
 
 
-  INLINE void set_properties(const FrameBufferProperties &properties);
-
 #ifdef DO_PSTATS
 #ifdef DO_PSTATS
   void init_frame_pstats();
   void init_frame_pstats();
 #endif
 #endif
@@ -267,8 +268,6 @@ protected:
   CPT(GeomMunger) _munger;
   CPT(GeomMunger) _munger;
   CPT(GeomVertexData) _vertex_data;
   CPT(GeomVertexData) _vertex_data;
 
 
-  int _buffer_mask;
-  int _stereo_buffer_mask;
   unsigned int _color_write_mask;
   unsigned int _color_write_mask;
   Colorf _color_clear_value;
   Colorf _color_clear_value;
   float _depth_clear_value;
   float _depth_clear_value;
@@ -280,14 +279,13 @@ protected:
   CPT(Lens) _current_lens;
   CPT(Lens) _current_lens;
   CPT(TransformState) _projection_mat;
   CPT(TransformState) _projection_mat;
   CPT(TransformState) _projection_mat_inv;
   CPT(TransformState) _projection_mat_inv;
+  FrameBufferProperties *_current_properties;
   
   
   CoordinateSystem _coordinate_system;
   CoordinateSystem _coordinate_system;
   CoordinateSystem _internal_coordinate_system;
   CoordinateSystem _internal_coordinate_system;
   CPT(TransformState) _cs_transform;
   CPT(TransformState) _cs_transform;
   CPT(TransformState) _inv_cs_transform;
   CPT(TransformState) _inv_cs_transform;
 
 
-  bool _is_stereo;
-
   Colorf _scene_graph_color;
   Colorf _scene_graph_color;
   bool _has_scene_graph_color;
   bool _has_scene_graph_color;
   bool _transform_stale;
   bool _transform_stale;
@@ -349,7 +347,9 @@ protected:
   bool _supports_basic_shaders;
   bool _supports_basic_shaders;
   int _supported_geom_rendering;
   int _supported_geom_rendering;
   bool _color_scale_via_lighting;
   bool _color_scale_via_lighting;
-  
+
+  int _stereo_buffer_mask;
+
 public:
 public:
   // Statistics
   // Statistics
   static PStatCollector _vertex_buffer_switch_pcollector;
   static PStatCollector _vertex_buffer_switch_pcollector;
@@ -402,7 +402,7 @@ private:
   pvector<ClipPlaneInfo> _clip_plane_info;
   pvector<ClipPlaneInfo> _clip_plane_info;
   bool _clip_planes_enabled_this_frame;
   bool _clip_planes_enabled_this_frame;
 
 
-  FrameBufferProperties _properties;
+  FrameBufferProperties _default_properties;
   PT(GraphicsPipe) _pipe;
   PT(GraphicsPipe) _pipe;
   GraphicsEngine *_engine;
   GraphicsEngine *_engine;
   GraphicsThreadingModel _threading_model;
   GraphicsThreadingModel _threading_model;

+ 2 - 1
panda/src/display/graphicsWindow.cxx

@@ -38,10 +38,11 @@ TypeHandle GraphicsWindow::_type_handle;
 GraphicsWindow::
 GraphicsWindow::
 GraphicsWindow(GraphicsPipe *pipe,
 GraphicsWindow(GraphicsPipe *pipe,
                const string &name,
                const string &name,
+               const FrameBufferProperties &properties,
                int x_size, int y_size, int flags,
                int x_size, int y_size, int flags,
                GraphicsStateGuardian *gsg,
                GraphicsStateGuardian *gsg,
                GraphicsOutput *host) :
                GraphicsOutput *host) :
-  GraphicsOutput(pipe, name, x_size, y_size, flags, gsg, host)
+  GraphicsOutput(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
 #ifdef DO_MEMORY_USAGE
 #ifdef DO_MEMORY_USAGE
   MemoryUsage::update_type(this, this);
   MemoryUsage::update_type(this, this);

+ 1 - 0
panda/src/display/graphicsWindow.h

@@ -42,6 +42,7 @@ class EXPCL_PANDA GraphicsWindow : public GraphicsOutput {
 protected:
 protected:
   GraphicsWindow(GraphicsPipe *pipe, 
   GraphicsWindow(GraphicsPipe *pipe, 
                  const string &name,
                  const string &name,
+                 const FrameBufferProperties &properties,
                  int x_size, int y_size, int flags,
                  int x_size, int y_size, int flags,
                  GraphicsStateGuardian *gsg,
                  GraphicsStateGuardian *gsg,
                  GraphicsOutput *host);
                  GraphicsOutput *host);

+ 1 - 1
panda/src/display/parasiteBuffer.cxx

@@ -31,7 +31,7 @@ TypeHandle ParasiteBuffer::_type_handle;
 ParasiteBuffer::
 ParasiteBuffer::
 ParasiteBuffer(GraphicsOutput *host, const string &name,
 ParasiteBuffer(GraphicsOutput *host, const string &name,
                int x_size, int y_size, int flags) :
                int x_size, int y_size, int flags) :
-  GraphicsOutput(host->get_pipe(), name, 
+  GraphicsOutput(host->get_pipe(), name, host->get_fb_properties(),
                  x_size, y_size, flags, host->get_gsg(), host)
                  x_size, y_size, flags, host->get_gsg(), host)
 {
 {
 #ifdef DO_MEMORY_USAGE
 #ifdef DO_MEMORY_USAGE

+ 34 - 12
panda/src/display/renderBuffer.h

@@ -34,21 +34,43 @@ class GraphicsStateGuardian;
 class EXPCL_PANDA RenderBuffer {
 class EXPCL_PANDA RenderBuffer {
 public:
 public:
   enum Type {
   enum Type {
-    T_front_left       = 0x0001,
-    T_back_left        = 0x0002,
-    T_front_right      = 0x0004,
-    T_back_right       = 0x0008,
+    T_aux_rgba_0       = 0x00000001,
+    T_aux_rgba_1       = 0x00000002,
+    T_aux_rgba_2       = 0x00000004,
+    T_aux_rgba_3       = 0x00000008,
 
 
-    T_front            = 0x0005,
-    T_back             = 0x000a,
-    T_left             = 0x0003,
-    T_right            = 0x000c,
+    T_aux_hrgba_0      = 0x00000010,
+    T_aux_hrgba_1      = 0x00000020,
+    T_aux_hrgba_2      = 0x00000040,
+    T_aux_hrgba_3      = 0x00000080,
 
 
-    T_color            = 0x000f,
+    T_aux_float_0      = 0x00000100,
+    T_aux_float_1      = 0x00000200,
+    T_aux_float_2      = 0x00000400,
+    T_aux_float_3      = 0x00000800,
 
 
-    T_depth            = 0x0010,
-    T_stencil          = 0x0020,
-    T_accum            = 0x0040,
+    T_aux_undef_0      = 0x00001000,
+    T_aux_undef_1      = 0x00002000,
+    T_aux_undef_2      = 0x00004000,
+    T_aux_undef_3      = 0x00008000,
+
+    T_aux              = 0x0000FFFF,
+
+    T_front_left       = 0x00010000,
+    T_back_left        = 0x00020000,
+    T_front_right      = 0x00040000,
+    T_back_right       = 0x00080000,
+
+    T_front            = 0x00050000,
+    T_back             = 0x000a0000,
+    T_left             = 0x00030000,
+    T_right            = 0x000c0000,
+    
+    T_color            = 0x000F0000,
+
+    T_depth            = 0x00100000,
+    T_stencil          = 0x00200000,
+    T_accum            = 0x00400000,
   };
   };
 
 
 
 

+ 2 - 6
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -524,7 +524,7 @@ do_clear(const RenderBuffer &buffer) {
           if (FAILED(hr2)) {
           if (FAILED(hr2)) {
             dxgsg8_cat.error()
             dxgsg8_cat.error()
               << "Unable to clear depth buffer; removing.\n";
               << "Unable to clear depth buffer; removing.\n";
-            _buffer_mask &= ~RenderBuffer::T_depth;
+            _current_properties->buffer_mask_remove(RenderBuffer::T_depth);
           }
           }
         }
         }
         if (buffer_type & RenderBuffer::T_stencil) {
         if (buffer_type & RenderBuffer::T_stencil) {
@@ -534,7 +534,7 @@ do_clear(const RenderBuffer &buffer) {
           if (FAILED(hr2)) {
           if (FAILED(hr2)) {
             dxgsg8_cat.error()
             dxgsg8_cat.error()
               << "Unable to clear stencil buffer; removing.\n";
               << "Unable to clear stencil buffer; removing.\n";
-            _buffer_mask &= ~RenderBuffer::T_stencil;
+            _current_properties->buffer_mask_remove(RenderBuffer::T_stencil);
           }
           }
         }
         }
       }
       }
@@ -1605,10 +1605,6 @@ reset() {
 
 
   // overwrite gsg defaults with these values
   // overwrite gsg defaults with these values
 
 
-  // We always have at least a color buffer (the depth and/or stencil
-  // buffer flags will be filled in by the window).
-  _buffer_mask = RenderBuffer::T_color;
-
   HRESULT hr;
   HRESULT hr;
 
 
   // make sure gsg passes all current state down to us
   // make sure gsg passes all current state down to us

+ 2 - 1
panda/src/dxgsg8/wdxGraphicsBuffer8.cxx

@@ -43,10 +43,11 @@ TypeHandle wdxGraphicsBuffer8::_type_handle;
 wdxGraphicsBuffer8::
 wdxGraphicsBuffer8::
 wdxGraphicsBuffer8(GraphicsPipe *pipe,
 wdxGraphicsBuffer8(GraphicsPipe *pipe,
                    const string &name,
                    const string &name,
+                   const FrameBufferProperties &properties,
                    int x_size, int y_size, int flags,
                    int x_size, int y_size, int flags,
                    GraphicsStateGuardian *gsg,
                    GraphicsStateGuardian *gsg,
                    GraphicsOutput *host):
                    GraphicsOutput *host):
-  GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
+  GraphicsBuffer(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
   // initialize all class members
   // initialize all class members
   _cube_map_index = -1;
   _cube_map_index = -1;

+ 1 - 0
panda/src/dxgsg8/wdxGraphicsBuffer8.h

@@ -38,6 +38,7 @@ class EXPCL_PANDADX wdxGraphicsBuffer8 : public GraphicsBuffer {
 public:
 public:
   wdxGraphicsBuffer8(GraphicsPipe *pipe,
   wdxGraphicsBuffer8(GraphicsPipe *pipe,
                      const string &name,
                      const string &name,
+                     const FrameBufferProperties &properties,
                      int x_size, int y_size, int flags,
                      int x_size, int y_size, int flags,
                      GraphicsStateGuardian *gsg,
                      GraphicsStateGuardian *gsg,
                      GraphicsOutput *host);
                      GraphicsOutput *host);

+ 15 - 15
panda/src/dxgsg8/wdxGraphicsPipe8.cxx

@@ -87,11 +87,12 @@ pipe_constructor() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsOutput) wdxGraphicsPipe8::
 PT(GraphicsOutput) wdxGraphicsPipe8::
 make_output(const string &name,
 make_output(const string &name,
+            const FrameBufferProperties &properties,
             int x_size, int y_size, int flags,
             int x_size, int y_size, int flags,
             GraphicsStateGuardian *gsg,
             GraphicsStateGuardian *gsg,
             GraphicsOutput *host,
             GraphicsOutput *host,
             int retry,
             int retry,
-            bool precertify) {
+            bool &precertify) {
   
   
   if (!_is_valid) {
   if (!_is_valid) {
     return NULL;
     return NULL;
@@ -106,15 +107,14 @@ make_output(const string &name,
   if (retry == 0) {
   if (retry == 0) {
     if (((flags&BF_require_parasite)!=0)||
     if (((flags&BF_require_parasite)!=0)||
         ((flags&BF_refuse_window)!=0)||
         ((flags&BF_refuse_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_can_bind_color)!=0)||
         ((flags&BF_can_bind_color)!=0)||
-        ((flags&BF_can_bind_every)!=0)) {
+        ((flags&BF_can_bind_every)!=0)||
+        (properties != gsg->get_default_properties())) {
       return NULL;
       return NULL;
     }
     }
-    return new wdxGraphicsWindow8(this, name, x_size, y_size, flags, gsg, host);
+    return new wdxGraphicsWindow8(this, name, properties,
+                                  x_size, y_size, flags, gsg, host);
   }
   }
   
   
   // Second thing to try: a wdxGraphicsBuffer8
   // Second thing to try: a wdxGraphicsBuffer8
@@ -123,19 +123,19 @@ make_output(const string &name,
     if ((!support_render_texture)||
     if ((!support_render_texture)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_window)!=0)||
         ((flags&BF_require_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
-        ((flags&BF_can_bind_every)!=0)) {
+        ((flags&BF_can_bind_every)!=0)||
+        (properties != gsg->get_default_properties())) {
       return NULL;
       return NULL;
     }
     }
-    if (precertify) {
-      if (!gsg->get_supports_render_texture()) {
-        return NULL;
-      }
+    if ((gsg != 0)&&
+        (gsg->is_valid())&&
+        (!gsg->needs_reset())&&
+        (gsg->get_supports_render_texture())) {
+      precertify = true;
     }
     }
-    return new wdxGraphicsBuffer8(this, name, x_size, y_size, flags, gsg, host);
+    return new wdxGraphicsBuffer8(this, name, properties,
+                                  x_size, y_size, flags, gsg, host);
   }
   }
   
   
   // Nothing else left to try.
   // Nothing else left to try.

+ 8 - 7
panda/src/dxgsg8/wdxGraphicsPipe8.h

@@ -58,13 +58,14 @@ public:
    bool special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size,UINT y_size);
    bool special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size,UINT y_size);
 
 
 protected:
 protected:
-  virtual PT(GraphicsOutput) make_output(const string &name,
-                                         int x_size, int y_size, int flags,
-                                         GraphicsStateGuardian *gsg,
-                                         GraphicsOutput *host,
-                                         int retry,
-                                         bool precertify);
-
+   virtual PT(GraphicsOutput) make_output(const string &name,
+                                          const FrameBufferProperties &properties,
+                                          int x_size, int y_size, int flags,
+                                          GraphicsStateGuardian *gsg,
+                                          GraphicsOutput *host,
+                                          int retry,
+                                          bool &precertify);
+   
 private:
 private:
   bool init();
   bool init();
   bool find_all_card_memavails();
   bool find_all_card_memavails();

+ 13 - 13
panda/src/dxgsg8/wdxGraphicsWindow8.cxx

@@ -41,17 +41,17 @@ TypeHandle wdxGraphicsWindow8::_type_handle;
 wdxGraphicsWindow8::
 wdxGraphicsWindow8::
 wdxGraphicsWindow8(GraphicsPipe *pipe,
 wdxGraphicsWindow8(GraphicsPipe *pipe,
                    const string &name,
                    const string &name,
+                   const FrameBufferProperties &properties,
                    int x_size, int y_size, int flags,
                    int x_size, int y_size, int flags,
                    GraphicsStateGuardian *gsg,
                    GraphicsStateGuardian *gsg,
                    GraphicsOutput *host):
                    GraphicsOutput *host):
-  WinGraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host)
+  WinGraphicsWindow(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
   // dont actually create the window in the constructor.  reason:
   // dont actually create the window in the constructor.  reason:
   // multi-threading requires panda C++ window object to exist in
   // multi-threading requires panda C++ window object to exist in
   // separate thread from actual API window
   // separate thread from actual API window
 
 
   _dxgsg = DCAST(DXGraphicsStateGuardian8, gsg);
   _dxgsg = DCAST(DXGraphicsStateGuardian8, gsg);
-  _buffer_mask = 0;
   _depth_buffer_bpp = 0;
   _depth_buffer_bpp = 0;
   _awaiting_restore = false;
   _awaiting_restore = false;
   ZeroMemory(&_wcontext, sizeof(_wcontext));
   ZeroMemory(&_wcontext, sizeof(_wcontext));
@@ -148,13 +148,7 @@ make_current() {
   // reset the GSG state if this is the first time it has been used.
   // reset the GSG state if this is the first time it has been used.
   // (We can't just call reset() when we construct the GSG, because
   // (We can't just call reset() when we construct the GSG, because
   // reset() requires having a current context.)
   // reset() requires having a current context.)
-  if (dxgsg->reset_if_new()) {
-    // We should also fill in the buffer mask at this time, which adds
-    // support for depth buffer or stencil buffer if the window
-    // supports it.  This assumes that the gsg will not be shared by
-    // other windows with a different buffer mask.
-    dxgsg->_buffer_mask |= _buffer_mask;
-  }
+  dxgsg->reset_if_new();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -530,7 +524,8 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
   wdxdisplay8_cat.debug() << "Display Width " << dwRenderWidth << " and PresParam Width " << _wcontext._presentation_params.BackBufferWidth << "\n";
   wdxdisplay8_cat.debug() << "Display Width " << dwRenderWidth << " and PresParam Width " << _wcontext._presentation_params.BackBufferWidth << "\n";
 
 
   // BUGBUG: need to change panda to put frame buffer properties with GraphicsWindow, not GSG!!
   // BUGBUG: need to change panda to put frame buffer properties with GraphicsWindow, not GSG!!
-  int frame_buffer_mode = _gsg->get_properties().get_frame_buffer_mode();
+  // Update: Did I fix the bug? - Josh
+  int frame_buffer_mode = _fb_properties.get_frame_buffer_mode();
   bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0);
   bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0);
 
 
   PRINT_REFCNT(wdxdisplay8, _d3d8);
   PRINT_REFCNT(wdxdisplay8, _d3d8);
@@ -710,10 +705,15 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
   PRINT_REFCNT(wdxdisplay8, _wcontext._d3d_device);
   PRINT_REFCNT(wdxdisplay8, _wcontext._d3d_device);
 
 
   if (presentation_params->EnableAutoDepthStencil) {
   if (presentation_params->EnableAutoDepthStencil) {
-    _buffer_mask |= RenderBuffer::T_depth;
+    _fb_properties.buffer_mask_add(RenderBuffer::T_depth);
     if (IS_STENCIL_FORMAT(presentation_params->AutoDepthStencilFormat)) {
     if (IS_STENCIL_FORMAT(presentation_params->AutoDepthStencilFormat)) {
-      _buffer_mask |= RenderBuffer::T_stencil;
+      _fb_properties.buffer_mask_add(RenderBuffer::T_stencil);
+    } else {
+      _fb_properties.buffer_mask_remove(RenderBuffer::T_stencil);
     }
     }
+  } else {
+    _fb_properties.buffer_mask_remove(RenderBuffer::T_depth);
+    _fb_properties.buffer_mask_remove(RenderBuffer::T_stencil);
   }
   }
 
 
   init_resized_window();
   init_resized_window();
@@ -877,7 +877,7 @@ search_for_device(wdxGraphicsPipe8 *dxpipe, DXDeviceInfo *device_info) {
   _wcontext._is_dx8_1 = dxpipe->__is_dx8_1;
   _wcontext._is_dx8_1 = dxpipe->__is_dx8_1;
   _wcontext._card_id = device_info->cardID;  // could this change by end?
   _wcontext._card_id = device_info->cardID;  // could this change by end?
 
 
-  int frame_buffer_mode = _gsg->get_properties().get_frame_buffer_mode();
+  int frame_buffer_mode = _fb_properties.get_frame_buffer_mode();
   bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0);
   bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0);
 
 
   hr = _d3d8->GetAdapterIdentifier(device_info->cardID, D3DENUM_NO_WHQL_LEVEL,
   hr = _d3d8->GetAdapterIdentifier(device_info->cardID, D3DENUM_NO_WHQL_LEVEL,

+ 1 - 1
panda/src/dxgsg8/wdxGraphicsWindow8.h

@@ -36,6 +36,7 @@ class EXPCL_PANDADX wdxGraphicsWindow8 : public WinGraphicsWindow {
 public:
 public:
   wdxGraphicsWindow8(GraphicsPipe *pipe,
   wdxGraphicsWindow8(GraphicsPipe *pipe,
                      const string &name,
                      const string &name,
+                     const FrameBufferProperties &properties,
                      int x_size, int y_size, int flags,
                      int x_size, int y_size, int flags,
                      GraphicsStateGuardian *gsg,
                      GraphicsStateGuardian *gsg,
                      GraphicsOutput *host);
                      GraphicsOutput *host);
@@ -82,7 +83,6 @@ private:
   DXGraphicsStateGuardian8 *_dxgsg;
   DXGraphicsStateGuardian8 *_dxgsg;
   DXScreenData _wcontext;
   DXScreenData _wcontext;
 
 
-  int _buffer_mask;
   int _depth_buffer_bpp;
   int _depth_buffer_bpp;
   bool _awaiting_restore;
   bool _awaiting_restore;
 
 

+ 2 - 6
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -740,7 +740,7 @@ do_clear(const RenderBuffer &buffer) {
           if (FAILED(hr2)) {
           if (FAILED(hr2)) {
             dxgsg9_cat.error()
             dxgsg9_cat.error()
               << "Unable to clear depth buffer; removing.\n";
               << "Unable to clear depth buffer; removing.\n";
-            _buffer_mask &= ~RenderBuffer::T_depth;
+            _current_properties->buffer_mask_remove(RenderBuffer::T_depth);
           }
           }
         }
         }
         if (buffer_type & RenderBuffer::T_stencil) {
         if (buffer_type & RenderBuffer::T_stencil) {
@@ -750,7 +750,7 @@ do_clear(const RenderBuffer &buffer) {
           if (FAILED(hr2)) {
           if (FAILED(hr2)) {
             dxgsg9_cat.error()
             dxgsg9_cat.error()
               << "Unable to clear stencil buffer; removing.\n";
               << "Unable to clear stencil buffer; removing.\n";
-            _buffer_mask &= ~RenderBuffer::T_stencil;
+            _current_properties->buffer_mask_remove(RenderBuffer::T_stencil);
           }
           }
         }
         }
       }
       }
@@ -2360,10 +2360,6 @@ reset() {
 
 
   // overwrite gsg defaults with these values
   // overwrite gsg defaults with these values
 
 
-  // We always have at least a color buffer (the depth and/or stencil
-  // buffer flags will be filled in by the window).
-  _buffer_mask = RenderBuffer::T_color;
-
   HRESULT hr;
   HRESULT hr;
 
 
   // make sure gsg passes all current state down to us
   // make sure gsg passes all current state down to us

+ 3 - 2
panda/src/dxgsg9/wdxGraphicsBuffer9.cxx

@@ -40,10 +40,11 @@ TypeHandle wdxGraphicsBuffer9::_type_handle;
 wdxGraphicsBuffer9::
 wdxGraphicsBuffer9::
 wdxGraphicsBuffer9(GraphicsPipe *pipe,
 wdxGraphicsBuffer9(GraphicsPipe *pipe,
                    const string &name,
                    const string &name,
+                   const FrameBufferProperties &prop,
                    int x_size, int y_size, int flags,
                    int x_size, int y_size, int flags,
                    GraphicsStateGuardian *gsg,
                    GraphicsStateGuardian *gsg,
                    GraphicsOutput *host):
                    GraphicsOutput *host):
-  GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
+  GraphicsBuffer(pipe, name, prop, x_size, y_size, flags, gsg, host)
 {
 {
   // initialize all class members
   // initialize all class members
   _cube_map_index = -1;
   _cube_map_index = -1;
@@ -53,7 +54,7 @@ wdxGraphicsBuffer9(GraphicsPipe *pipe,
   _dx_texture_context9 = NULL;
   _dx_texture_context9 = NULL;
   _new_z_stencil_surface = NULL;
   _new_z_stencil_surface = NULL;
 
 
-// is this correct ???
+  // is this correct ???
   // Since the pbuffer never gets flipped, we get screenshots from the
   // Since the pbuffer never gets flipped, we get screenshots from the
   // same buffer we draw into.
   // same buffer we draw into.
   _screenshot_buffer_type = _draw_buffer_type;
   _screenshot_buffer_type = _draw_buffer_type;

+ 1 - 0
panda/src/dxgsg9/wdxGraphicsBuffer9.h

@@ -38,6 +38,7 @@ class EXPCL_PANDADX wdxGraphicsBuffer9 : public GraphicsBuffer {
 public:
 public:
   wdxGraphicsBuffer9(GraphicsPipe *pipe,
   wdxGraphicsBuffer9(GraphicsPipe *pipe,
                      const string &name,
                      const string &name,
+                     const FrameBufferProperties &prop,
                      int x_size, int y_size, int flags,
                      int x_size, int y_size, int flags,
                      GraphicsStateGuardian *gsg,
                      GraphicsStateGuardian *gsg,
                      GraphicsOutput *host);
                      GraphicsOutput *host);

+ 15 - 16
panda/src/dxgsg9/wdxGraphicsPipe9.cxx

@@ -87,11 +87,12 @@ pipe_constructor() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsOutput) wdxGraphicsPipe9::
 PT(GraphicsOutput) wdxGraphicsPipe9::
 make_output(const string &name,
 make_output(const string &name,
+            const FrameBufferProperties &prop,
             int x_size, int y_size, int flags,
             int x_size, int y_size, int flags,
             GraphicsStateGuardian *gsg,
             GraphicsStateGuardian *gsg,
             GraphicsOutput *host,
             GraphicsOutput *host,
             int retry,
             int retry,
-            bool precertify) {
+            bool &precertify) {
   
   
   if (!_is_valid) {
   if (!_is_valid) {
     return NULL;
     return NULL;
@@ -100,21 +101,19 @@ make_output(const string &name,
   DXGraphicsStateGuardian9 *wdxgsg;
   DXGraphicsStateGuardian9 *wdxgsg;
   DCAST_INTO_R(wdxgsg, gsg, NULL);
   DCAST_INTO_R(wdxgsg, gsg, NULL);
 
 
-  
   // First thing to try: a visible window.
   // First thing to try: a visible window.
 
 
   if (retry == 0) {
   if (retry == 0) {
     if (((flags&BF_require_parasite)!=0)||
     if (((flags&BF_require_parasite)!=0)||
         ((flags&BF_refuse_window)!=0)||
         ((flags&BF_refuse_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_can_bind_color)!=0)||
         ((flags&BF_can_bind_color)!=0)||
-        ((flags&BF_can_bind_every)!=0)) {
+        ((flags&BF_can_bind_every)!=0)||
+        (prop != gsg->get_default_properties())) {
       return NULL;
       return NULL;
     }
     }
-    return new wdxGraphicsWindow9(this, name, x_size, y_size, flags, gsg, host);
+    return new wdxGraphicsWindow9(this, name, prop,
+                                  x_size, y_size, flags, gsg, host);
   }
   }
   
   
   // Second thing to try: a wdxGraphicsBuffer9
   // Second thing to try: a wdxGraphicsBuffer9
@@ -123,19 +122,19 @@ make_output(const string &name,
     if ((!support_render_texture)||
     if ((!support_render_texture)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_window)!=0)||
         ((flags&BF_require_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
-        ((flags&BF_can_bind_every)!=0)) {
+        ((flags&BF_can_bind_every)!=0)||
+        (prop != gsg->get_default_properties())) {
       return NULL;
       return NULL;
     }
     }
-    if (precertify) {
-      if (!gsg->get_supports_render_texture()) {
-        return NULL;
-      }
+    if ((gsg != 0)&&
+        (gsg->is_valid())&&
+        (!gsg->needs_reset())&&
+        (gsg->get_supports_render_texture())) {
+      precertify = true;
     }
     }
-    return new wdxGraphicsBuffer9(this, name, x_size, y_size, flags, gsg, host);
+    return new wdxGraphicsBuffer9(this, name, prop,
+                                  x_size, y_size, flags, gsg, host);
   }
   }
   
   
   // Nothing else left to try.
   // Nothing else left to try.

+ 2 - 1
panda/src/dxgsg9/wdxGraphicsPipe9.h

@@ -59,11 +59,12 @@ public:
 
 
 protected:
 protected:
   virtual PT(GraphicsOutput) make_output(const string &name,
   virtual PT(GraphicsOutput) make_output(const string &name,
+                                         const FrameBufferProperties &prop,
                                          int x_size, int y_size, int flags,
                                          int x_size, int y_size, int flags,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsOutput *host,
                                          GraphicsOutput *host,
                                          int retry,
                                          int retry,
-                                         bool precertify);
+                                         bool &precertify);
 
 
 private:
 private:
   bool init();
   bool init();

+ 13 - 13
panda/src/dxgsg9/wdxGraphicsWindow9.cxx

@@ -41,17 +41,17 @@ TypeHandle wdxGraphicsWindow9::_type_handle;
 wdxGraphicsWindow9::
 wdxGraphicsWindow9::
 wdxGraphicsWindow9(GraphicsPipe *pipe,
 wdxGraphicsWindow9(GraphicsPipe *pipe,
                    const string &name,
                    const string &name,
+                   const FrameBufferProperties &prop,
                    int x_size, int y_size, int flags,
                    int x_size, int y_size, int flags,
                    GraphicsStateGuardian *gsg,
                    GraphicsStateGuardian *gsg,
                    GraphicsOutput *host):
                    GraphicsOutput *host):
-  WinGraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host)
+  WinGraphicsWindow(pipe, name, prop, x_size, y_size, flags, gsg, host)
 {
 {
   // dont actually create the window in the constructor.  reason:
   // dont actually create the window in the constructor.  reason:
   // multi-threading requires panda C++ window object to exist in
   // multi-threading requires panda C++ window object to exist in
   // separate thread from actual API window
   // separate thread from actual API window
 
 
   _dxgsg = DCAST(DXGraphicsStateGuardian9, gsg);
   _dxgsg = DCAST(DXGraphicsStateGuardian9, gsg);
-  _buffer_mask = 0;
   _depth_buffer_bpp = 0;
   _depth_buffer_bpp = 0;
   _awaiting_restore = false;
   _awaiting_restore = false;
   ZeroMemory(&_wcontext, sizeof(_wcontext));
   ZeroMemory(&_wcontext, sizeof(_wcontext));
@@ -83,13 +83,7 @@ make_current() {
   // reset the GSG state if this is the first time it has been used.
   // reset the GSG state if this is the first time it has been used.
   // (We can't just call reset() when we construct the GSG, because
   // (We can't just call reset() when we construct the GSG, because
   // reset() requires having a current context.)
   // reset() requires having a current context.)
-  if (dxgsg->reset_if_new()) {
-    // We should also fill in the buffer mask at this time, which adds
-    // support for depth buffer or stencil buffer if the window
-    // supports it.  This assumes that the gsg will not be shared by
-    // other windows with a different buffer mask.
-    dxgsg->_buffer_mask |= _buffer_mask;
-  }
+  dxgsg->reset_if_new();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -531,7 +525,8 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
   wdxdisplay9_cat.debug() << "Display Width " << dwRenderWidth << " and PresParam Width " << _wcontext._presentation_params.BackBufferWidth << "\n";
   wdxdisplay9_cat.debug() << "Display Width " << dwRenderWidth << " and PresParam Width " << _wcontext._presentation_params.BackBufferWidth << "\n";
 
 
   // BUGBUG: need to change panda to put frame buffer properties with GraphicsWindow, not GSG!!
   // BUGBUG: need to change panda to put frame buffer properties with GraphicsWindow, not GSG!!
-  int frame_buffer_mode = _gsg->get_properties().get_frame_buffer_mode();
+  // Update: Did I fix the bug? - Josh
+  int frame_buffer_mode = _fb_properties.get_frame_buffer_mode();
   bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0);
   bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0);
 
 
   PRINT_REFCNT(wdxdisplay9, _d3d9);
   PRINT_REFCNT(wdxdisplay9, _d3d9);
@@ -726,10 +721,15 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
   PRINT_REFCNT(wdxdisplay9, _wcontext._d3d_device);
   PRINT_REFCNT(wdxdisplay9, _wcontext._d3d_device);
 
 
   if (presentation_params->EnableAutoDepthStencil) {
   if (presentation_params->EnableAutoDepthStencil) {
-    _buffer_mask |= RenderBuffer::T_depth;
+    _fb_properties.buffer_mask_add(RenderBuffer::T_depth);
     if (IS_STENCIL_FORMAT(presentation_params->AutoDepthStencilFormat)) {
     if (IS_STENCIL_FORMAT(presentation_params->AutoDepthStencilFormat)) {
-      _buffer_mask |= RenderBuffer::T_stencil;
+      _fb_properties.buffer_mask_add(RenderBuffer::T_stencil);
+    } else {
+      _fb_properties.buffer_mask_remove(RenderBuffer::T_stencil);
     }
     }
+  } else {
+    _fb_properties.buffer_mask_remove(RenderBuffer::T_depth);
+    _fb_properties.buffer_mask_remove(RenderBuffer::T_stencil);
   }
   }
 
 
   init_resized_window();
   init_resized_window();
@@ -893,7 +893,7 @@ search_for_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info) {
   _wcontext._is_dx9_1 = dxpipe->__is_dx9_1;
   _wcontext._is_dx9_1 = dxpipe->__is_dx9_1;
   _wcontext._card_id = device_info->cardID;  // could this change by end?
   _wcontext._card_id = device_info->cardID;  // could this change by end?
 
 
-  int frame_buffer_mode = _gsg->get_properties().get_frame_buffer_mode();
+  int frame_buffer_mode = _fb_properties.get_frame_buffer_mode();
   bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0);
   bool bWantStencil = ((frame_buffer_mode & FrameBufferProperties::FM_stencil) != 0);
 
 
   hr = _d3d9->GetAdapterIdentifier(device_info->cardID, 0,
   hr = _d3d9->GetAdapterIdentifier(device_info->cardID, 0,

+ 1 - 0
panda/src/dxgsg9/wdxGraphicsWindow9.h

@@ -36,6 +36,7 @@ class EXPCL_PANDADX wdxGraphicsWindow9 : public WinGraphicsWindow {
 public:
 public:
   wdxGraphicsWindow9(GraphicsPipe *pipe,
   wdxGraphicsWindow9(GraphicsPipe *pipe,
                      const string &name,
                      const string &name,
+                     const FrameBufferProperties &prop,
                      int x_size, int y_size, int flags,
                      int x_size, int y_size, int flags,
                      GraphicsStateGuardian *gsg,
                      GraphicsStateGuardian *gsg,
                      GraphicsOutput *host);
                      GraphicsOutput *host);

+ 39 - 4
panda/src/glstuff/glGraphicsBuffer_src.cxx

@@ -26,14 +26,15 @@ TypeHandle CLP(GraphicsBuffer)::_type_handle;
 CLP(GraphicsBuffer)::
 CLP(GraphicsBuffer)::
 CLP(GraphicsBuffer)(GraphicsPipe *pipe,
 CLP(GraphicsBuffer)(GraphicsPipe *pipe,
                     const string &name,
                     const string &name,
+                    const FrameBufferProperties &properties,
                     int x_size, int y_size, int flags,
                     int x_size, int y_size, int flags,
                     GraphicsStateGuardian *gsg,
                     GraphicsStateGuardian *gsg,
                     GraphicsOutput *host) :
                     GraphicsOutput *host) :
-  GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
+  GraphicsBuffer(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
-  // Since the FBO never gets flipped, we get screenshots from the
-  // same buffer we draw into.
-  _screenshot_buffer_type = _draw_buffer_type;
+  // An FBO doesn't have a back buffer.
+  _draw_buffer_type       = RenderBuffer::T_front;
+  _screenshot_buffer_type = RenderBuffer::T_front;
 
 
   // Initialize these.
   // Initialize these.
   _fbo = 0;
   _fbo = 0;
@@ -76,6 +77,9 @@ begin_frame(FrameMode mode) {
     return false;
     return false;
   }
   }
 
 
+  CLP(GraphicsStateGuardian) *glgsg;
+  DCAST_INTO_R(glgsg, _gsg, false);
+
   if (!_host->begin_frame(FM_parasite)) {
   if (!_host->begin_frame(FM_parasite)) {
     return false;
     return false;
   }
   }
@@ -84,6 +88,32 @@ begin_frame(FrameMode mode) {
   if (mode == FM_render) {
   if (mode == FM_render) {
     rebuild_bitplanes();
     rebuild_bitplanes();
     clear_cube_map_selection();
     clear_cube_map_selection();
+
+    // Verify that the frame buffer is ready for rendering.
+    GLenum status = glgsg->_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
+    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+      GLCAT.error() << "EXT_framebuffer_object reports non-framebuffer-completeness.\n";
+      switch(status) {
+      case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+        GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n"; break;
+      case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+        GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n"; break;
+      case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
+        GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n"; break;
+      case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
+        GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n"; break;
+      case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+        GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n"; break;
+      case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+        GLCAT.error() << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n"; break;
+      case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+        GLCAT.error() << "FRAMEBUFFER_UNSUPPORTED_EXT\n"; break;
+      default:
+        GLCAT.error() << "OTHER PROBLEM\n"; break;
+      }
+      glgsg->_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+      return false;
+    }
   }
   }
   return true;
   return true;
 }
 }
@@ -177,6 +207,7 @@ rebuild_bitplanes() {
   // For all slots, update the slot.
   // For all slots, update the slot.
     
     
   for (int slot=0; slot<SLOT_COUNT; slot++) {
   for (int slot=0; slot<SLOT_COUNT; slot++) {
+    if (slot == SLOT_stencil) continue;
     Texture *tex = attach[slot];
     Texture *tex = attach[slot];
     if (tex) {
     if (tex) {
       // If the texture is already bound to the slot, and it's
       // If the texture is already bound to the slot, and it's
@@ -242,6 +273,8 @@ rebuild_bitplanes() {
   // These record the size of all nonzero renderbuffers.
   // These record the size of all nonzero renderbuffers.
   _rb_size_x = desired_x;
   _rb_size_x = desired_x;
   _rb_size_y = desired_y;
   _rb_size_y = desired_y;
+  
+  glgsg->report_my_gl_errors();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -271,6 +304,7 @@ generate_mipmaps() {
       GLP(BindTexture)(target, 0);
       GLP(BindTexture)(target, 0);
     }
     }
   }
   }
+  glgsg->report_my_gl_errors();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -307,6 +341,7 @@ end_frame(FrameMode mode) {
     }
     }
     clear_cube_map_selection();
     clear_cube_map_selection();
   }
   }
+  glgsg->report_my_gl_errors();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
panda/src/glstuff/glGraphicsBuffer_src.h

@@ -52,6 +52,7 @@ class EXPCL_GL CLP(GraphicsBuffer) : public GraphicsBuffer {
 public:
 public:
   CLP(GraphicsBuffer)(GraphicsPipe *pipe,
   CLP(GraphicsBuffer)(GraphicsPipe *pipe,
                       const string &name,
                       const string &name,
+                      const FrameBufferProperties &properties,
                       int x_size, int y_size, int flags,
                       int x_size, int y_size, int flags,
                       GraphicsStateGuardian *gsg,
                       GraphicsStateGuardian *gsg,
                       GraphicsOutput *host);
                       GraphicsOutput *host);

+ 36 - 39
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -915,19 +915,16 @@ reset() {
 
 
   _auto_rescale_normal = false;
   _auto_rescale_normal = false;
 
 
-  // All GL implementations have the following buffers.
-  _buffer_mask = (RenderBuffer::T_color |
-                  RenderBuffer::T_depth |
-                  RenderBuffer::T_stencil |
-                  RenderBuffer::T_accum);
-
   // If we don't have double-buffering, don't attempt to write to the
   // If we don't have double-buffering, don't attempt to write to the
   // back buffer.
   // back buffer.
-  GLboolean has_back;
-  GLP(GetBooleanv)(GL_DOUBLEBUFFER, &has_back);
-  if (!has_back) {
-    _buffer_mask &= ~RenderBuffer::T_back;
-  }
+  // Update: this code has been disabled.  Instead, the code that
+  // creates the window needs to make sure it created a back buffer
+  // in those cases where a back buffer was requested. - Josh
+  // GLboolean has_back;
+  // GLP(GetBooleanv)(GL_DOUBLEBUFFER, &has_back);
+  // if (!has_back) {
+  //   _buffer_mask &= ~RenderBuffer::T_back;
+  // }
 
 
   // Ensure the initial state is what we say it should be (in some
   // Ensure the initial state is what we say it should be (in some
   // cases, we don't want the GL default settings; in others, we have
   // cases, we don't want the GL default settings; in others, we have
@@ -1120,7 +1117,8 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) {
   GLsizei width = GLsizei(w);
   GLsizei width = GLsizei(w);
   GLsizei height = GLsizei(h);
   GLsizei height = GLsizei(h);
 
 
-  set_draw_buffer(get_render_buffer(_current_display_region->get_draw_buffer_type()));
+  set_draw_buffer(get_render_buffer(_current_display_region->get_draw_buffer_type(),
+                                    *_current_properties));
   enable_scissor(true);
   enable_scissor(true);
   GLP(Scissor)(x, y, width, height);
   GLP(Scissor)(x, y, width, height);
   GLP(Viewport)(x, y, width, height);
   GLP(Viewport)(x, y, width, height);
@@ -2901,8 +2899,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
 
 
   // Match framebuffer format if necessary.
   // Match framebuffer format if necessary.
   if (tex->get_match_framebuffer_format()) {
   if (tex->get_match_framebuffer_format()) {
-    const FrameBufferProperties &properties = get_properties();
-    int mode = properties.get_frame_buffer_mode();
+    int mode = _current_properties->get_frame_buffer_mode();
 
 
     switch (tex->get_format()) {
     switch (tex->get_format()) {
     case Texture::F_depth_component:
     case Texture::F_depth_component:
@@ -3014,8 +3011,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
   int xo, yo, w, h;
   int xo, yo, w, h;
   dr->get_region_pixels(xo, yo, w, h);
   dr->get_region_pixels(xo, yo, w, h);
 
 
-  const FrameBufferProperties &properties = get_properties();
-  int mode = properties.get_frame_buffer_mode();
+  int mode = _current_properties->get_frame_buffer_mode();
 
 
   Texture::Format format = tex->get_format();
   Texture::Format format = tex->get_format();
   Texture::ComponentType component_type = tex->get_component_type();
   Texture::ComponentType component_type = tex->get_component_type();
@@ -3023,7 +3019,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
 
 
   switch (format) {
   switch (format) {
   case Texture::F_depth_component:
   case Texture::F_depth_component:
-    if (properties.get_depth_bits() <= 8) {
+    if (_current_properties->get_depth_bits() <= 8) {
       component_type = Texture::T_unsigned_byte;
       component_type = Texture::T_unsigned_byte;
     } else {
     } else {
       component_type = Texture::T_unsigned_short;
       component_type = Texture::T_unsigned_short;
@@ -3031,7 +3027,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
     break;
     break;
 
 
   case Texture::F_stencil_index:
   case Texture::F_stencil_index:
-    if (properties.get_stencil_bits() <= 8) {
+    if (_current_properties->get_stencil_bits() <= 8) {
       component_type = Texture::T_unsigned_byte;
       component_type = Texture::T_unsigned_byte;
     } else {
     } else {
       component_type = Texture::T_unsigned_short;
       component_type = Texture::T_unsigned_short;
@@ -3045,7 +3041,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
     } else {
     } else {
       format = Texture::F_rgb;
       format = Texture::F_rgb;
     }
     }
-    if (properties.get_color_bits() <= 24) {
+    if (_current_properties->get_color_bits() <= 24) {
       component_type = Texture::T_unsigned_byte;
       component_type = Texture::T_unsigned_byte;
     } else {
     } else {
       component_type = Texture::T_unsigned_short;
       component_type = Texture::T_unsigned_short;
@@ -4159,39 +4155,39 @@ set_draw_buffer(const RenderBuffer &rb) {
   case RenderBuffer::T_front:
   case RenderBuffer::T_front:
     GLP(DrawBuffer)(GL_FRONT);
     GLP(DrawBuffer)(GL_FRONT);
     break;
     break;
-
+    
   case RenderBuffer::T_back:
   case RenderBuffer::T_back:
     GLP(DrawBuffer)(GL_BACK);
     GLP(DrawBuffer)(GL_BACK);
     break;
     break;
-
+    
   case RenderBuffer::T_right:
   case RenderBuffer::T_right:
     GLP(DrawBuffer)(GL_RIGHT);
     GLP(DrawBuffer)(GL_RIGHT);
     break;
     break;
-
+    
   case RenderBuffer::T_left:
   case RenderBuffer::T_left:
     GLP(DrawBuffer)(GL_LEFT);
     GLP(DrawBuffer)(GL_LEFT);
     break;
     break;
-
+    
   case RenderBuffer::T_front_right:
   case RenderBuffer::T_front_right:
-    nassertv(_is_stereo);
+    nassertv(_current_properties->is_stereo());
     GLP(DrawBuffer)(GL_FRONT_RIGHT);
     GLP(DrawBuffer)(GL_FRONT_RIGHT);
     break;
     break;
-
+    
   case RenderBuffer::T_front_left:
   case RenderBuffer::T_front_left:
-    nassertv(_is_stereo);
+    nassertv(_current_properties->is_stereo());
     GLP(DrawBuffer)(GL_FRONT_LEFT);
     GLP(DrawBuffer)(GL_FRONT_LEFT);
     break;
     break;
-
+    
   case RenderBuffer::T_back_right:
   case RenderBuffer::T_back_right:
-    nassertv(_is_stereo);
+    nassertv(_current_properties->is_stereo());
     GLP(DrawBuffer)(GL_BACK_RIGHT);
     GLP(DrawBuffer)(GL_BACK_RIGHT);
     break;
     break;
-
+    
   case RenderBuffer::T_back_left:
   case RenderBuffer::T_back_left:
-    nassertv(_is_stereo);
+    nassertv(_current_properties->is_stereo());
     GLP(DrawBuffer)(GL_BACK_LEFT);
     GLP(DrawBuffer)(GL_BACK_LEFT);
     break;
     break;
-
+    
   default:
   default:
     GLP(DrawBuffer)(GL_FRONT_AND_BACK);
     GLP(DrawBuffer)(GL_FRONT_AND_BACK);
   }
   }
@@ -4219,38 +4215,39 @@ set_read_buffer(const RenderBuffer &rb) {
   case RenderBuffer::T_front:
   case RenderBuffer::T_front:
     GLP(ReadBuffer)(GL_FRONT);
     GLP(ReadBuffer)(GL_FRONT);
     break;
     break;
-
+    
   case RenderBuffer::T_back:
   case RenderBuffer::T_back:
     GLP(ReadBuffer)(GL_BACK);
     GLP(ReadBuffer)(GL_BACK);
     break;
     break;
-
+    
   case RenderBuffer::T_right:
   case RenderBuffer::T_right:
     GLP(ReadBuffer)(GL_RIGHT);
     GLP(ReadBuffer)(GL_RIGHT);
     break;
     break;
-
+    
   case RenderBuffer::T_left:
   case RenderBuffer::T_left:
     GLP(ReadBuffer)(GL_LEFT);
     GLP(ReadBuffer)(GL_LEFT);
     break;
     break;
-
+    
   case RenderBuffer::T_front_right:
   case RenderBuffer::T_front_right:
     GLP(ReadBuffer)(GL_FRONT_RIGHT);
     GLP(ReadBuffer)(GL_FRONT_RIGHT);
     break;
     break;
-
+    
   case RenderBuffer::T_front_left:
   case RenderBuffer::T_front_left:
     GLP(ReadBuffer)(GL_FRONT_LEFT);
     GLP(ReadBuffer)(GL_FRONT_LEFT);
     break;
     break;
-
+    
   case RenderBuffer::T_back_right:
   case RenderBuffer::T_back_right:
     GLP(ReadBuffer)(GL_BACK_RIGHT);
     GLP(ReadBuffer)(GL_BACK_RIGHT);
     break;
     break;
-
+    
   case RenderBuffer::T_back_left:
   case RenderBuffer::T_back_left:
     GLP(ReadBuffer)(GL_BACK_LEFT);
     GLP(ReadBuffer)(GL_BACK_LEFT);
     break;
     break;
-
+    
   default:
   default:
     GLP(ReadBuffer)(GL_FRONT_AND_BACK);
     GLP(ReadBuffer)(GL_FRONT_AND_BACK);
   }
   }
+  
   report_my_gl_errors();
   report_my_gl_errors();
 }
 }
 
 

+ 2 - 1
panda/src/glxdisplay/glxGraphicsBuffer.cxx

@@ -39,10 +39,11 @@ TypeHandle glxGraphicsBuffer::_type_handle;
 glxGraphicsBuffer::
 glxGraphicsBuffer::
 glxGraphicsBuffer(GraphicsPipe *pipe, 
 glxGraphicsBuffer(GraphicsPipe *pipe, 
                   const string &name,
                   const string &name,
+                  const FrameBufferProperties &properties,
                   int x_size, int y_size, int flags,
                   int x_size, int y_size, int flags,
                   GraphicsStateGuardian *gsg,
                   GraphicsStateGuardian *gsg,
                   GraphicsOutput *host) :
                   GraphicsOutput *host) :
-  GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
+  GraphicsBuffer(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
   glxGraphicsPipe *glx_pipe;
   glxGraphicsPipe *glx_pipe;
   DCAST_INTO_V(glx_pipe, _pipe);
   DCAST_INTO_V(glx_pipe, _pipe);

+ 1 - 0
panda/src/glxdisplay/glxGraphicsBuffer.h

@@ -37,6 +37,7 @@ class glxGraphicsBuffer : public GraphicsBuffer {
 public:
 public:
   glxGraphicsBuffer(GraphicsPipe *pipe, 
   glxGraphicsBuffer(GraphicsPipe *pipe, 
                     const string &name,
                     const string &name,
+                    const FrameBufferProperties &properties,
                     int x_size, int y_size, int flags,
                     int x_size, int y_size, int flags,
                     GraphicsStateGuardian *gsg,
                     GraphicsStateGuardian *gsg,
                     GraphicsOutput *host);
                     GraphicsOutput *host);

+ 12 - 9
panda/src/glxdisplay/glxGraphicsPipe.cxx

@@ -275,6 +275,7 @@ make_gsg(const FrameBufferProperties &properties,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsOutput) glxGraphicsPipe::
 PT(GraphicsOutput) glxGraphicsPipe::
 make_output(const string &name,
 make_output(const string &name,
+            const FrameBufferProperties &properties,
             int x_size, int y_size, int flags,
             int x_size, int y_size, int flags,
             GraphicsStateGuardian *gsg,
             GraphicsStateGuardian *gsg,
             GraphicsOutput *host,
             GraphicsOutput *host,
@@ -285,6 +286,11 @@ make_output(const string &name,
     return NULL;
     return NULL;
   }
   }
 
 
+  // This pipe is not yet capable of creating nonhomogeneous windows.
+  if (properties != gsg->get_default_properties()) {
+    return NULL;
+  }
+
   glxGraphicsStateGuardian *glxgsg;
   glxGraphicsStateGuardian *glxgsg;
   DCAST_INTO_R(glxgsg, gsg, NULL);
   DCAST_INTO_R(glxgsg, gsg, NULL);
 
 
@@ -293,15 +299,13 @@ make_output(const string &name,
   if (retry == 0) {
   if (retry == 0) {
     if (((flags&BF_require_parasite)!=0)||
     if (((flags&BF_require_parasite)!=0)||
         ((flags&BF_refuse_window)!=0)||
         ((flags&BF_refuse_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_can_bind_color)!=0)||
         ((flags&BF_can_bind_color)!=0)||
         ((flags&BF_can_bind_every)!=0)) {
         ((flags&BF_can_bind_every)!=0)) {
       return NULL;
       return NULL;
     }
     }
-    return new glxGraphicsWindow(this, name, x_size, y_size, flags, gsg, host);
+    return new glxGraphicsWindow(this, name, properties,
+                                 x_size, y_size, flags, gsg, host);
   }
   }
   
   
   //  // Second thing to try: a glGraphicsBuffer
   //  // Second thing to try: a glGraphicsBuffer
@@ -317,7 +321,8 @@ make_output(const string &name,
   //        return NULL;
   //        return NULL;
   //      }
   //      }
   //    }
   //    }
-  //    return new glGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
+  //    return new glGraphicsBuffer(this, name, properties,
+  //                                x_size, y_size, flags, gsg, host);
   //  }
   //  }
   
   
 #ifdef HAVE_GLXFBCONFIG
 #ifdef HAVE_GLXFBCONFIG
@@ -327,14 +332,12 @@ make_output(const string &name,
     if ((!support_render_texture)||
     if ((!support_render_texture)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_window)!=0)||
         ((flags&BF_require_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_can_bind_every)!=0)) {
         ((flags&BF_can_bind_every)!=0)) {
       return NULL;
       return NULL;
     }
     }
-    return new glxGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
+    return new glxGraphicsBuffer(this, name, properties,
+                                 x_size, y_size, flags, gsg, host);
   }
   }
 #endif  // HAVE_GLXFBCONFIG
 #endif  // HAVE_GLXFBCONFIG
   
   

+ 1 - 0
panda/src/glxdisplay/glxGraphicsPipe.h

@@ -114,6 +114,7 @@ protected:
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
                                              GraphicsStateGuardian *share_with);
                                              GraphicsStateGuardian *share_with);
   virtual PT(GraphicsOutput) make_output(const string &name,
   virtual PT(GraphicsOutput) make_output(const string &name,
+                                         const FrameBufferProperties &properties,
                                          int x_size, int y_size, int flags,
                                          int x_size, int y_size, int flags,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsOutput *host,
                                          GraphicsOutput *host,

+ 1 - 0
panda/src/glxdisplay/glxGraphicsWindow.cxx

@@ -46,6 +46,7 @@ TypeHandle glxGraphicsWindow::_type_handle;
 glxGraphicsWindow::
 glxGraphicsWindow::
 glxGraphicsWindow(GraphicsPipe *pipe, 
 glxGraphicsWindow(GraphicsPipe *pipe, 
                   const string &name,
                   const string &name,
+                  const FrameBufferProperties &properties,
                   int x_size, int y_size, int flags,
                   int x_size, int y_size, int flags,
                   GraphicsStateGuardian *gsg,
                   GraphicsStateGuardian *gsg,
                   GraphicsOutput *host) :
                   GraphicsOutput *host) :

+ 1 - 0
panda/src/glxdisplay/glxGraphicsWindow.h

@@ -34,6 +34,7 @@ class glxGraphicsWindow : public GraphicsWindow {
 public:
 public:
   glxGraphicsWindow(GraphicsPipe *pipe, 
   glxGraphicsWindow(GraphicsPipe *pipe, 
                     const string &name,
                     const string &name,
+                    const FrameBufferProperties &properties,
                     int x_size, int y_size, int flags,
                     int x_size, int y_size, int flags,
                     GraphicsStateGuardian *gsg,
                     GraphicsStateGuardian *gsg,
                     GraphicsOutput *host);
                     GraphicsOutput *host);

+ 6 - 5
panda/src/mesadisplay/osMesaGraphicsBuffer.cxx

@@ -30,11 +30,12 @@ TypeHandle OsMesaGraphicsBuffer::_type_handle;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 OsMesaGraphicsBuffer::
 OsMesaGraphicsBuffer::
 OsMesaGraphicsBuffer(GraphicsPipe *pipe,
 OsMesaGraphicsBuffer(GraphicsPipe *pipe,
-                  const string &name,
-                  int x_size, int y_size, int flags,
-                  GraphicsStateGuardian *gsg,
-                  GraphicsOutput *host) :
-  GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
+                     const string &name,
+                     const FrameBufferProperties &properties,
+                     int x_size, int y_size, int flags,
+                     GraphicsStateGuardian *gsg,
+                     GraphicsOutput *host) :
+  GraphicsBuffer(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
   _type = GL_UNSIGNED_BYTE;
   _type = GL_UNSIGNED_BYTE;
 }
 }

+ 1 - 0
panda/src/mesadisplay/osMesaGraphicsBuffer.h

@@ -34,6 +34,7 @@ class EXPCL_PANDAMESA OsMesaGraphicsBuffer : public GraphicsBuffer {
 public:
 public:
   OsMesaGraphicsBuffer(GraphicsPipe *pipe, 
   OsMesaGraphicsBuffer(GraphicsPipe *pipe, 
                        const string &name,
                        const string &name,
+                       const FrameBufferProperties &properties,
                        int x_size, int y_size, int flags,
                        int x_size, int y_size, int flags,
                        GraphicsStateGuardian *gsg,
                        GraphicsStateGuardian *gsg,
                        GraphicsOutput *host);
                        GraphicsOutput *host);

+ 6 - 6
panda/src/mesadisplay/osMesaGraphicsPipe.cxx

@@ -125,11 +125,12 @@ make_gsg(const FrameBufferProperties &properties,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsOutput) OsMesaGraphicsPipe::
 PT(GraphicsOutput) OsMesaGraphicsPipe::
 make_output(const string &name,
 make_output(const string &name,
+            const FrameBufferProperties &properties,
             int x_size, int y_size, int flags,
             int x_size, int y_size, int flags,
             GraphicsStateGuardian *gsg,
             GraphicsStateGuardian *gsg,
             GraphicsOutput *host,
             GraphicsOutput *host,
             int retry,
             int retry,
-            bool precertify) {
+            bool &precertify) {
   
   
   if (!_is_valid) {
   if (!_is_valid) {
     return NULL;
     return NULL;
@@ -141,14 +142,13 @@ make_output(const string &name,
     if ((!support_render_texture)||
     if ((!support_render_texture)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_window)!=0)||
         ((flags&BF_require_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
-        ((flags&BF_can_bind_every)!=0)) {
+        ((flags&BF_can_bind_every)!=0)||
+        (properties != gsg->get_default_properties()) {
       return NULL;
       return NULL;
     }
     }
-    return new OsMesaGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
+    return new OsMesaGraphicsBuffer(this, name, properties,
+                                    x_size, y_size, flags, gsg, host);
   }
   }
   
   
   // Nothing else left to try.
   // Nothing else left to try.

+ 1 - 0
panda/src/mesadisplay/osMesaGraphicsPipe.h

@@ -49,6 +49,7 @@ protected:
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
                                              GraphicsStateGuardian *share_with);
                                              GraphicsStateGuardian *share_with);
   virtual PT(GraphicsOutput) make_output(const string &name,
   virtual PT(GraphicsOutput) make_output(const string &name,
+                                         const FrameBufferProperties &properties,
                                          int x_size, int y_size, int flags,
                                          int x_size, int y_size, int flags,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsOutput *host,
                                          GraphicsOutput *host,

+ 2 - 1
panda/src/osxdisplay/osxGraphicsBuffer.cxx

@@ -32,10 +32,11 @@ TypeHandle osxGraphicsBuffer::_type_handle;
 osxGraphicsBuffer::
 osxGraphicsBuffer::
 osxGraphicsBuffer(GraphicsPipe *pipe,
 osxGraphicsBuffer(GraphicsPipe *pipe,
                   const string &name,
                   const string &name,
+                  const FrameBufferProperties &properties,
                   int x_size, int y_size, int flags,
                   int x_size, int y_size, int flags,
                   GraphicsStateGuardian *gsg,
                   GraphicsStateGuardian *gsg,
                   GraphicsOutput *host) :
                   GraphicsOutput *host) :
-  GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
+  GraphicsBuffer(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
   osxGraphicsPipe *osx_pipe;
   osxGraphicsPipe *osx_pipe;
   DCAST_INTO_V(osx_pipe, _pipe);
   DCAST_INTO_V(osx_pipe, _pipe);

+ 1 - 0
panda/src/osxdisplay/osxGraphicsBuffer.h

@@ -36,6 +36,7 @@ class EXPCL_PANDAGL osxGraphicsBuffer : public GraphicsBuffer {
 public:
 public:
   osxGraphicsBuffer(GraphicsPipe *pipe, 
   osxGraphicsBuffer(GraphicsPipe *pipe, 
                     const string &name,
                     const string &name,
+                    const FrameBufferProperties &properties,
                     int x_size, int y_size, int flags,
                     int x_size, int y_size, int flags,
                     GraphicsStateGuardian *gsg,
                     GraphicsStateGuardian *gsg,
                     GraphicsOutput *host);
                     GraphicsOutput *host);

+ 11 - 12
panda/src/osxdisplay/osxGraphicsPipe.cxx

@@ -115,16 +115,17 @@ make_gsg(const FrameBufferProperties &properties,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsOutput) osxGraphicsPipe::
 PT(GraphicsOutput) osxGraphicsPipe::
 make_output(const string &name,
 make_output(const string &name,
+            const FrameBufferProperties &properties,
             int x_size, int y_size, int flags,
             int x_size, int y_size, int flags,
             GraphicsStateGuardian *gsg,
             GraphicsStateGuardian *gsg,
             GraphicsOutput *host,
             GraphicsOutput *host,
             int retry,
             int retry,
-            bool precertify) {
+            bool &precertify) {
   
   
   if (!_is_valid) {
   if (!_is_valid) {
     return NULL;
     return NULL;
   }
   }
-
+  
   osxGraphicsStateGuardian *osxgsg;
   osxGraphicsStateGuardian *osxgsg;
   DCAST_INTO_R(osxgsg, gsg, NULL);
   DCAST_INTO_R(osxgsg, gsg, NULL);
 
 
@@ -133,15 +134,14 @@ make_output(const string &name,
   if (retry == 0) {
   if (retry == 0) {
     if (((flags&BF_require_parasite)!=0)||
     if (((flags&BF_require_parasite)!=0)||
         ((flags&BF_refuse_window)!=0)||
         ((flags&BF_refuse_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_can_bind_color)!=0)||
         ((flags&BF_can_bind_color)!=0)||
-        ((flags&BF_can_bind_every)!=0)) {
+        ((flags&BF_can_bind_every)!=0)||
+        (properties != gsg->get_default_properties())) {
       return NULL;
       return NULL;
     }
     }
-    return new osxGraphicsWindow(this, name, x_size, y_size, flags, gsg, host);
+    return new osxGraphicsWindow(this, name, properties,
+                                 x_size, y_size, flags, gsg, host);
   }
   }
   
   
   //  // Second thing to try: a glGraphicsBuffer
   //  // Second thing to try: a glGraphicsBuffer
@@ -166,14 +166,13 @@ make_output(const string &name,
     if ((!support_render_texture)||
     if ((!support_render_texture)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_window)!=0)||
         ((flags&BF_require_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
-        ((flags&BF_can_bind_every)!=0)) {
+        ((flags&BF_can_bind_every)!=0)||
+        (properties != gsg->get_default_properties())) {
       return NULL;
       return NULL;
     }
     }
-    return new osxGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
+    return new osxGraphicsBuffer(this, name, properties,
+                                 x_size, y_size, flags, gsg, host);
   }
   }
   
   
   // Nothing else left to try.
   // Nothing else left to try.

+ 2 - 1
panda/src/osxdisplay/osxGraphicsPipe.h

@@ -39,11 +39,12 @@ protected:
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties,
                                              GraphicsStateGuardian *share_with);
                                              GraphicsStateGuardian *share_with);
   virtual PT(GraphicsOutput) make_output(const string &name,
   virtual PT(GraphicsOutput) make_output(const string &name,
+                                         const FrameBufferProperties &properties,
                                          int x_size, int y_size, int flags,
                                          int x_size, int y_size, int flags,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsOutput *host,
                                          GraphicsOutput *host,
                                          int retry,
                                          int retry,
-                                         bool precertify);
+                                         bool &precertify);
 
 
 private:
 private:
  public:
  public:

+ 2 - 1
panda/src/osxdisplay/osxGraphicsWindow.cxx

@@ -394,10 +394,11 @@ OSStatus osxGraphicsWindow::handleTextInput (EventHandlerCallRef myHandler, Even
 osxGraphicsWindow::
 osxGraphicsWindow::
 osxGraphicsWindow(GraphicsPipe *pipe, 
 osxGraphicsWindow(GraphicsPipe *pipe, 
                   const string &name,
                   const string &name,
+                  const FrameBufferProperties &properties,
                   int x_size, int y_size, int flags,
                   int x_size, int y_size, int flags,
                   GraphicsStateGuardian *gsg,
                   GraphicsStateGuardian *gsg,
                   GraphicsOutput *host) :
                   GraphicsOutput *host) :
-  GraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host),
+  GraphicsWindow(pipe, name, properties, x_size, y_size, flags, gsg, host),
   _osx_window(NULL),
   _osx_window(NULL),
   _is_fullsreen(false),
   _is_fullsreen(false),
 #ifdef HACK_SCREEN_HASH_CONTEXT  
 #ifdef HACK_SCREEN_HASH_CONTEXT  

+ 1 - 0
panda/src/osxdisplay/osxGraphicsWindow.h

@@ -41,6 +41,7 @@ class osxGraphicsWindow : public GraphicsWindow {
 public:
 public:
   osxGraphicsWindow(GraphicsPipe *pipe, 
   osxGraphicsWindow(GraphicsPipe *pipe, 
                     const string &name,
                     const string &name,
+                    const FrameBufferProperties &properties,
                     int x_size, int y_size, int flags,
                     int x_size, int y_size, int flags,
                     GraphicsStateGuardian *gsg,
                     GraphicsStateGuardian *gsg,
                     GraphicsOutput *host);
                     GraphicsOutput *host);

+ 6 - 5
panda/src/wgldisplay/wglGraphicsBuffer.cxx

@@ -35,10 +35,11 @@ TypeHandle wglGraphicsBuffer::_type_handle;
 wglGraphicsBuffer::
 wglGraphicsBuffer::
 wglGraphicsBuffer(GraphicsPipe *pipe,
 wglGraphicsBuffer(GraphicsPipe *pipe,
                   const string &name,
                   const string &name,
+                  const FrameBufferProperties &properties,
                   int x_size, int y_size, int flags,
                   int x_size, int y_size, int flags,
                   GraphicsStateGuardian *gsg,
                   GraphicsStateGuardian *gsg,
                   GraphicsOutput *host) :
                   GraphicsOutput *host) :
-  GraphicsBuffer(pipe, name, x_size, y_size, flags, gsg, host)
+  GraphicsBuffer(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
   _pbuffer = (HPBUFFERARB)0;
   _pbuffer = (HPBUFFERARB)0;
   _pbuffer_dc = (HDC)0;
   _pbuffer_dc = (HDC)0;
@@ -142,7 +143,7 @@ begin_render_texture() {
   wglGraphicsStateGuardian *wglgsg;
   wglGraphicsStateGuardian *wglgsg;
   DCAST_INTO_V(wglgsg, _gsg);
   DCAST_INTO_V(wglgsg, _gsg);
   
   
-  if (_gsg->get_properties().is_single_buffered()) {
+  if (_fb_properties.is_single_buffered()) {
     wglgsg->_wglReleaseTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
     wglgsg->_wglReleaseTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
   } else {
   } else {
     wglgsg->_wglReleaseTexImageARB(_pbuffer, WGL_BACK_LEFT_ARB);
     wglgsg->_wglReleaseTexImageARB(_pbuffer, WGL_BACK_LEFT_ARB);
@@ -189,7 +190,7 @@ end_render_texture() {
       return;
       return;
     }
     }
     GLP(BindTexture)(target, gtc->_index);
     GLP(BindTexture)(target, gtc->_index);
-    if (_gsg->get_properties().is_single_buffered()) {
+    if (_fb_properties.is_single_buffered()) {
       wglgsg->_wglBindTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
       wglgsg->_wglBindTexImageARB(_pbuffer, WGL_FRONT_LEFT_ARB);
     } else {
     } else {
       wglgsg->_wglBindTexImageARB(_pbuffer, WGL_BACK_LEFT_ARB);
       wglgsg->_wglBindTexImageARB(_pbuffer, WGL_BACK_LEFT_ARB);
@@ -413,7 +414,7 @@ make_pbuffer(HDC twindow_dc) {
   
   
   if (bindtexture != 0) {
   if (bindtexture != 0) {
 
 
-    if (_gsg->get_properties().get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) {
+    if (_fb_properties.get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) {
       iattrib_list[ni++] = WGL_TEXTURE_FORMAT_ARB;
       iattrib_list[ni++] = WGL_TEXTURE_FORMAT_ARB;
       iattrib_list[ni++] = WGL_TEXTURE_RGBA_ARB;
       iattrib_list[ni++] = WGL_TEXTURE_RGBA_ARB;
     } else {
     } else {
@@ -536,7 +537,7 @@ choose_pbuffer_format(HDC twindow_dc, bool draw_to_texture) {
 
 
   if (draw_to_texture) {
   if (draw_to_texture) {
     // If we want to be able to render-to-texture, request that.
     // If we want to be able to render-to-texture, request that.
-    if (_gsg->get_properties().get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) {
+    if (_fb_properties.get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) {
       iattrib_list[ni++] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
       iattrib_list[ni++] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
       iattrib_list[ni++] = true;
       iattrib_list[ni++] = true;
     } else {
     } else {

+ 1 - 0
panda/src/wgldisplay/wglGraphicsBuffer.h

@@ -43,6 +43,7 @@ class EXPCL_PANDAGL wglGraphicsBuffer : public GraphicsBuffer {
 public:
 public:
   wglGraphicsBuffer(GraphicsPipe *pipe, 
   wglGraphicsBuffer(GraphicsPipe *pipe, 
                     const string &name,
                     const string &name,
+                    const FrameBufferProperties &properties,
                     int x_size, int y_size, int flags,
                     int x_size, int y_size, int flags,
                     GraphicsStateGuardian *gsg,
                     GraphicsStateGuardian *gsg,
                     GraphicsOutput *host);
                     GraphicsOutput *host);

+ 27 - 22
panda/src/wgldisplay/wglGraphicsPipe.cxx

@@ -75,8 +75,7 @@ pipe_constructor() {
 //     Function: wglGraphicsPipe::make_gsg
 //     Function: wglGraphicsPipe::make_gsg
 //       Access: Private
 //       Access: Private
 //  Description: Creates a new GSG to use the pipe (but no windows
 //  Description: Creates a new GSG to use the pipe (but no windows
-//               have been created yet for the GSG).  This method will
-//               be called in the draw thread for the GSG.
+//               have been created yet for the GSG).
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsStateGuardian) wglGraphicsPipe::
 PT(GraphicsStateGuardian) wglGraphicsPipe::
 make_gsg(const FrameBufferProperties &properties, 
 make_gsg(const FrameBufferProperties &properties, 
@@ -85,6 +84,11 @@ make_gsg(const FrameBufferProperties &properties,
     return NULL;
     return NULL;
   }
   }
 
 
+  // THIS CODE IS INCORRECT.  THIS ROUTINE IS NOT CALLED IN THE
+  // DRAW THREAD.  THE FIX IS THAT PIXEL FORMAT SELECTION NEEDS TO
+  // BE DONE ON A PER-WINDOW BASIS, AND IT NEEDS TO BE DONE IN
+  // OPEN_WINDOW, NOT HERE.
+  
   wglGraphicsStateGuardian *share_gsg = NULL;
   wglGraphicsStateGuardian *share_gsg = NULL;
 
 
   if (share_with != (GraphicsStateGuardian *)NULL) {
   if (share_with != (GraphicsStateGuardian *)NULL) {
@@ -197,11 +201,12 @@ make_gsg(const FrameBufferProperties &properties,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(GraphicsOutput) wglGraphicsPipe::
 PT(GraphicsOutput) wglGraphicsPipe::
 make_output(const string &name,
 make_output(const string &name,
+            const FrameBufferProperties &properties,
             int x_size, int y_size, int flags,
             int x_size, int y_size, int flags,
             GraphicsStateGuardian *gsg,
             GraphicsStateGuardian *gsg,
             GraphicsOutput *host,
             GraphicsOutput *host,
             int retry,
             int retry,
-            bool precertify) {
+            bool &precertify) {
   
   
   if (!_is_valid) {
   if (!_is_valid) {
     return NULL;
     return NULL;
@@ -215,31 +220,32 @@ make_output(const string &name,
   if (retry == 0) {
   if (retry == 0) {
     if (((flags&BF_require_parasite)!=0)||
     if (((flags&BF_require_parasite)!=0)||
         ((flags&BF_refuse_window)!=0)||
         ((flags&BF_refuse_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_can_bind_color)!=0)||
         ((flags&BF_can_bind_color)!=0)||
         ((flags&BF_can_bind_every)!=0)) {
         ((flags&BF_can_bind_every)!=0)) {
       return NULL;
       return NULL;
     }
     }
-    return new wglGraphicsWindow(this, name, x_size, y_size, flags, gsg, host);
+    return new wglGraphicsWindow(this, name, properties,
+                                 x_size, y_size, flags, gsg, host);
   }
   }
   
   
-  //  // Second thing to try: a glGraphicsBuffer
-  //  
+  // Second thing to try: a GLGraphicsBuffer
+  
   //  if (retry == 1) {
   //  if (retry == 1) {
   //    if ((!support_render_texture)||
   //    if ((!support_render_texture)||
   //        ((flags&BF_require_parasite)!=0)||
   //        ((flags&BF_require_parasite)!=0)||
   //        ((flags&BF_require_window)!=0)) {
   //        ((flags&BF_require_window)!=0)) {
   //      return NULL;
   //      return NULL;
   //    }
   //    }
-  //    if (precertify) {
-  //      if (!wglgsg->_supports_framebuffer_object) {
-  //        return NULL;
-  //      }
+  //    if ((wglgsg != 0) &&
+  //        (wglgsg->is_valid()) &&
+  //        (!wglgsg->needs_reset()) &&
+  //        (wglgsg->_supports_framebuffer_object) &&
+  //        (wglgsg->_glDrawBuffers != 0)) {
+  //      precertify = true;
   //    }
   //    }
-  //    return new glGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
+  //    return new GLGraphicsBuffer(this, name, properties,
+  //                                x_size, y_size, flags, gsg, host);
   //  }
   //  }
   
   
   // Third thing to try: a wglGraphicsBuffer
   // Third thing to try: a wglGraphicsBuffer
@@ -248,19 +254,18 @@ make_output(const string &name,
     if ((!support_render_texture)||
     if ((!support_render_texture)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_window)!=0)||
         ((flags&BF_require_window)!=0)||
-        ((flags&BF_need_aux_rgba_MASK)!=0)||
-        ((flags&BF_need_aux_hrgba_MASK)!=0)||
-        ((flags&BF_need_aux_float_MASK)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_size_track_host)!=0)||
         ((flags&BF_can_bind_every)!=0)) {
         ((flags&BF_can_bind_every)!=0)) {
       return NULL;
       return NULL;
     }
     }
-    if (precertify) {
-      if (!wglgsg->_supports_pbuffer) {
-        return NULL;
-      }
+    if ((wglgsg != 0) &&
+        (wglgsg->is_valid()) &&
+        (!wglgsg->needs_reset()) &&
+        (wglgsg->_supports_pbuffer)) {
+      precertify = true;
     }
     }
-    return new wglGraphicsBuffer(this, name, x_size, y_size, flags, gsg, host);
+    return new wglGraphicsBuffer(this, name, properties,
+                                 x_size, y_size, flags, gsg, host);
   }
   }
   
   
   // Nothing else left to try.
   // Nothing else left to try.

+ 2 - 1
panda/src/wgldisplay/wglGraphicsPipe.h

@@ -40,11 +40,12 @@ public:
 
 
 protected:
 protected:
   virtual PT(GraphicsOutput) make_output(const string &name,
   virtual PT(GraphicsOutput) make_output(const string &name,
+                                         const FrameBufferProperties &properties,
                                          int x_size, int y_size, int flags,
                                          int x_size, int y_size, int flags,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsStateGuardian *gsg,
                                          GraphicsOutput *host,
                                          GraphicsOutput *host,
                                          int retry,
                                          int retry,
-                                         bool precertify);
+                                         bool &precertify);
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties, 
   virtual PT(GraphicsStateGuardian) make_gsg(const FrameBufferProperties &properties, 
                                              GraphicsStateGuardian *share_with);
                                              GraphicsStateGuardian *share_with);
 
 

+ 2 - 1
panda/src/wgldisplay/wglGraphicsWindow.cxx

@@ -133,10 +133,11 @@ GetAvailVidMem() {
 wglGraphicsWindow::
 wglGraphicsWindow::
 wglGraphicsWindow(GraphicsPipe *pipe, 
 wglGraphicsWindow(GraphicsPipe *pipe, 
                   const string &name,
                   const string &name,
+                  const FrameBufferProperties &properties,
                   int x_size, int y_size, int flags,
                   int x_size, int y_size, int flags,
                   GraphicsStateGuardian *gsg,
                   GraphicsStateGuardian *gsg,
                   GraphicsOutput *host) :
                   GraphicsOutput *host) :
-  WinGraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host)
+  WinGraphicsWindow(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
   _hdc = (HDC)0;
   _hdc = (HDC)0;
 }
 }

+ 1 - 0
panda/src/wgldisplay/wglGraphicsWindow.h

@@ -31,6 +31,7 @@ class EXPCL_PANDAGL wglGraphicsWindow : public WinGraphicsWindow {
 public:
 public:
   wglGraphicsWindow(GraphicsPipe *pipe, 
   wglGraphicsWindow(GraphicsPipe *pipe, 
                     const string &name,
                     const string &name,
+                    const FrameBufferProperties &properties,
                     int x_size, int y_size, int flags,
                     int x_size, int y_size, int flags,
                     GraphicsStateGuardian *gsg,
                     GraphicsStateGuardian *gsg,
                     GraphicsOutput *host);
                     GraphicsOutput *host);

+ 2 - 1
panda/src/windisplay/winGraphicsWindow.cxx

@@ -82,10 +82,11 @@ static tRegisterRawInputDevices  pRegisterRawInputDevices;
 WinGraphicsWindow::
 WinGraphicsWindow::
 WinGraphicsWindow(GraphicsPipe *pipe,
 WinGraphicsWindow(GraphicsPipe *pipe,
                   const string &name,
                   const string &name,
+                  const FrameBufferProperties &properties,
                   int x_size, int y_size, int flags,
                   int x_size, int y_size, int flags,
                   GraphicsStateGuardian *gsg,
                   GraphicsStateGuardian *gsg,
                   GraphicsOutput *host) : 
                   GraphicsOutput *host) : 
-  GraphicsWindow(pipe, name, x_size, y_size, flags, gsg, host)
+  GraphicsWindow(pipe, name, properties, x_size, y_size, flags, gsg, host)
 {
 {
   initialize_input_devices();
   initialize_input_devices();
   _hWnd = (HWND)0;
   _hWnd = (HWND)0;

+ 1 - 0
panda/src/windisplay/winGraphicsWindow.h

@@ -43,6 +43,7 @@ class EXPCL_PANDAWIN WinGraphicsWindow : public GraphicsWindow {
 public:
 public:
   WinGraphicsWindow(GraphicsPipe *pipe,
   WinGraphicsWindow(GraphicsPipe *pipe,
                     const string &name,
                     const string &name,
+                    const FrameBufferProperties &properties,
                     int x_size, int y_size, int flags,
                     int x_size, int y_size, int flags,
                     GraphicsStateGuardian *gsg,
                     GraphicsStateGuardian *gsg,
                     GraphicsOutput *host);
                     GraphicsOutput *host);