Browse Source

better antialias handling

David Rose 21 years ago
parent
commit
185fbf613e

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

@@ -834,7 +834,7 @@ issue_light(const LightAttrib *attrib) {
 void GraphicsStateGuardian::
 issue_color_write(const ColorWriteAttrib *attrib) {
   _color_write_mode = attrib->get_mode();
-  set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);
+  set_blend_mode();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -845,7 +845,7 @@ issue_color_write(const ColorWriteAttrib *attrib) {
 void GraphicsStateGuardian::
 issue_transparency(const TransparencyAttrib *attrib) {
   _transparency_mode = attrib->get_mode();
-  set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);
+  set_blend_mode();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -857,7 +857,7 @@ void GraphicsStateGuardian::
 issue_color_blend(const ColorBlendAttrib *attrib) {
   _color_blend = attrib;
   _color_blend_mode = attrib->get_mode();
-  set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);
+  set_blend_mode();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -1184,14 +1184,13 @@ end_bind_clip_planes() {
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::set_blend_mode
 //       Access: Protected, Virtual
-//  Description: Called after any of these three blending states have
-//               changed; this function is responsible for setting the
-//               appropriate color blending mode based on the given
-//               properties.
+//  Description: Called after any of the things that might change
+//               blending state have changed, this function is
+//               responsible for setting the appropriate color
+//               blending mode based on the current properties.
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
-set_blend_mode(ColorWriteAttrib::Mode, ColorBlendAttrib::Mode,
-               TransparencyAttrib::Mode) {
+set_blend_mode() {
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 3
panda/src/display/graphicsStateGuardian.h

@@ -191,9 +191,7 @@ protected:
   virtual void bind_clip_plane(PlaneNode *plane, int pane_id);
   virtual void end_bind_clip_planes();
 
-  virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
-                              ColorBlendAttrib::Mode color_blend_mode,
-                              TransparencyAttrib::Mode transparency_mode);
+  virtual void set_blend_mode();
 
   virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
                                                  CPT(DisplayRegion) dr)=0;

+ 9 - 11
panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx

@@ -4569,26 +4569,24 @@ bind_clip_plane(PlaneNode *plane, int plane_id) {
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian7::set_blend_mode
 //       Access: Protected, Virtual
-//  Description: Called after any of these three blending states have
-//               changed; this function is responsible for setting the
-//               appropriate color blending mode based on the given
-//               properties.
+//  Description: Called after any of the things that might change
+//               blending state have changed, this function is
+//               responsible for setting the appropriate color
+//               blending mode based on the current properties.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian7::
-set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
-               ColorBlendAttrib::Mode color_blend_mode,
-               TransparencyAttrib::Mode transparency_mode) {
+set_blend_mode() {
   // If color_write_mode is off, we disable writing to the color using
   // blending.  I don't know if it is possible in DX to disable color
   // outside of a blend mode.
-  if (color_write_mode == ColorWriteAttrib::M_off) {
+  if (_color_write_mode == ColorWriteAttrib::M_off) {
     enable_blend(true);
     call_dxBlendFunc(D3DBLEND_ZERO, D3DBLEND_ONE);
     return;
   }
   
   // Is there a color blend set?
-  if (color_blend_mode != ColorBlendAttrib::M_none) {
+  if (_color_blend_mode != ColorBlendAttrib::M_none) {
     enable_blend(true);
 
     // DX7 supports only ColorBlendAttrib::M_add.  Assume that's what
@@ -4601,7 +4599,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
   }
 
   // No color blend; is there a transparency set?
-  switch (transparency_mode) {
+  switch (_transparency_mode) {
   case TransparencyAttrib::M_none:
   case TransparencyAttrib::M_binary:
     break;
@@ -4616,7 +4614,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
 
   default:
     dxgsg7_cat.error()
-      << "invalid transparency mode " << (int)transparency_mode << endl;
+      << "invalid transparency mode " << (int)_transparency_mode << endl;
     break;
   }
 

+ 1 - 3
panda/src/dxgsg7/dxGraphicsStateGuardian7.h

@@ -154,9 +154,7 @@ protected:
   virtual void enable_clip_plane(int plane_id, bool enable);
   virtual void bind_clip_plane(PlaneNode *plane, int plane_id);
 
-  virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
-                              ColorBlendAttrib::Mode color_blend_mode,
-                              TransparencyAttrib::Mode transparency_mode);
+  virtual void set_blend_mode();
 
   void free_pointers();            // free local internal buffers
   void free_dxgsg_objects(void);   // free the DirectX objects we create

+ 1 - 1
panda/src/dxgsg8/dxGraphicsStateGuardian8.I

@@ -183,7 +183,7 @@ set_color_writemask(UINT color_writemask) {
     } else {
         // blending can only handle on/off
         assert((color_writemask==0x0)||(color_writemask==0xFFFFFFFF));
-        set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);        
+        set_blend_mode();
     }
   }
 }

+ 10 - 12
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -3924,17 +3924,15 @@ issue_color_write(const ColorWriteAttrib *attrib) {
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian8::set_blend_mode
 //       Access: Protected, Virtual
-//  Description: Called after any of these three blending states have
-//               changed; this function is responsible for setting the
-//               appropriate color blending mode based on the given
-//               properties.
+//  Description: Called after any of the things that might change
+//               blending state have changed, this function is
+//               responsible for setting the appropriate color
+//               blending mode based on the current properties.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
-set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
-               ColorBlendAttrib::Mode color_blend_mode,
-               TransparencyAttrib::Mode transparency_mode) {
+set_blend_mode() {
 
-  if((color_write_mode == ColorWriteAttrib::M_off) && !_pScrn->bCanDirectDisableColorWrites) {
+  if((_color_write_mode == ColorWriteAttrib::M_off) && !_pScrn->bCanDirectDisableColorWrites) {
     // need !_pScrn->bCanDirectDisableColorWrites guard because other issue_colorblend,issue_transp
     // will come this way, and they should ignore the colorwriteattrib value since it's been
     // handled separately in set_color_writemask
@@ -3944,10 +3942,10 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
   }
 
   // Is there a color blend set?
-  if (color_blend_mode != ColorBlendAttrib::M_none) {
+  if (_color_blend_mode != ColorBlendAttrib::M_none) {
     enable_blend(true);
   
-    switch (color_blend_mode) {
+    switch (_color_blend_mode) {
     case ColorBlendAttrib::M_add:
       _pD3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
       break;
@@ -3975,7 +3973,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
   }
 
   // No color blend; is there a transparency set?
-  switch (transparency_mode) {
+  switch (_transparency_mode) {
   case TransparencyAttrib::M_none:
   case TransparencyAttrib::M_binary:
     break;
@@ -3991,7 +3989,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
 
   default:
     dxgsg8_cat.error()
-      << "invalid transparency mode " << (int)transparency_mode << endl;
+      << "invalid transparency mode " << (int)_transparency_mode << endl;
     break;
   }
 

+ 1 - 3
panda/src/dxgsg8/dxGraphicsStateGuardian8.h

@@ -155,9 +155,7 @@ protected:
   virtual void enable_clip_plane(int plane_id, bool enable);
   virtual void bind_clip_plane(PlaneNode *plane, int plane_id);
 
-  virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
-                              ColorBlendAttrib::Mode color_blend_mode,
-                              TransparencyAttrib::Mode transparency_mode);
+  virtual void set_blend_mode();
 
   void free_nondx_resources();            // free local internal buffers
   void free_d3d_device(void);

+ 1 - 1
panda/src/dxgsg9/dxGraphicsStateGuardian9.I

@@ -164,7 +164,7 @@ set_color_writemask(UINT color_writemask) {
     } else {
         // blending can only handle on/off
         assert((color_writemask==0x0)||(color_writemask==0xFFFFFFFF));
-        set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);        
+        set_blend_mode();
     }
   }
 }

+ 10 - 12
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -3912,17 +3912,15 @@ issue_color_write(const ColorWriteAttrib *attrib) {
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian9::set_blend_mode
 //       Access: Protected, Virtual
-//  Description: Called after any of these three blending states have
-//               changed; this function is responsible for setting the
-//               appropriate color blending mode based on the given
-//               properties.
+//  Description: Called after any of the things that might change
+//               blending state have changed, this function is
+//               responsible for setting the appropriate color
+//               blending mode based on the current properties.
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian9::
-set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
-               ColorBlendAttrib::Mode color_blend_mode,
-               TransparencyAttrib::Mode transparency_mode) {
+set_blend_mode() {
 
-  if((color_write_mode == ColorWriteAttrib::M_off) && !_pScrn->bCanDirectDisableColorWrites) {
+  if((_color_write_mode == ColorWriteAttrib::M_off) && !_pScrn->bCanDirectDisableColorWrites) {
     // need !_pScrn->bCanDirectDisableColorWrites guard because other issue_colorblend,issue_transp
     // will come this way, and they should ignore the colorwriteattrib value since it's been
     // handled separately in set_color_writemask
@@ -3933,10 +3931,10 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
   }
 
   // Is there a color blend set?
-  if (color_blend_mode != ColorBlendAttrib::M_none) {
+  if (_color_blend_mode != ColorBlendAttrib::M_none) {
     enable_blend(true);
 
-    switch (color_blend_mode) {
+    switch (_color_blend_mode) {
     case ColorBlendAttrib::M_add:
       _pD3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
       break;
@@ -3964,7 +3962,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
   }
 
   // No color blend; is there a transparency set?
-  switch (transparency_mode) {
+  switch (_transparency_mode) {
   case TransparencyAttrib::M_none:
   case TransparencyAttrib::M_binary:
     break;
@@ -3980,7 +3978,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
 
   default:
     dxgsg9_cat.error()
-      << "invalid transparency mode " << (int)transparency_mode << endl;
+      << "invalid transparency mode " << (int)_transparency_mode << endl;
     break;
   }
 

+ 1 - 3
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -156,9 +156,7 @@ protected:
   virtual void enable_clip_plane(int plane_id, bool enable);
   virtual void bind_clip_plane(PlaneNode *plane, int plane_id);
 
-  virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
-                              ColorBlendAttrib::Mode color_blend_mode,
-                              TransparencyAttrib::Mode transparency_mode);
+  virtual void set_blend_mode();
 
   void free_nondx_resources();            // free local internal buffers
   void free_d3d_device(void);

+ 90 - 66
panda/src/glstuff/glGraphicsStateGuardian_src.I

@@ -83,20 +83,82 @@ report_my_errors(int line, const char *source_file) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: CLP(GraphicsStateGuardian)::enable_multisample
-//       Access:
-//  Description:
+//     Function: CLP(GraphicsStateGuardian)::enable_multisample_antialias
+//       Access: Protected
+//  Description: Specifies whether multisample should be enabled for
+//               antialiasing purposes.
 ////////////////////////////////////////////////////////////////////
 INLINE void CLP(GraphicsStateGuardian)::
-enable_multisample(bool val) {
-  if (_multisample_enabled != val && _supports_multisample) {
-    _multisample_enabled = val;
-    if (val) {
-      GLP(Enable)(GL_MULTISAMPLE);
-    } else {
-      if (!_multisample_alpha_one_enabled && !_multisample_alpha_mask_enabled) {
+enable_multisample_antialias(bool val) {
+  if (_supports_multisample) {
+    if ((_multisample_mode & MM_antialias) != 0 && !val) {
+      // Turn off antialias multisample.
+      _multisample_mode &= ~MM_antialias;
+      if (_multisample_mode == 0) {
+        GLP(Disable)(GL_MULTISAMPLE);
+      }
+    } else if ((_multisample_mode & MM_antialias) == 0 && val) {
+      // Turn on antialias multisample.
+      if (_multisample_mode == 0) {
+        GLP(Enable)(GL_MULTISAMPLE);
+      }
+      _multisample_mode |= MM_antialias;
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GraphicsStateGuardian)::enable_multisample_alpha_one
+//       Access: Protected
+//  Description: Specifies whether multisample should be enabled for
+//               transparency purposes, using the sample_alpha_to_one
+//               mode.
+////////////////////////////////////////////////////////////////////
+INLINE void CLP(GraphicsStateGuardian)::
+enable_multisample_alpha_one(bool val) {
+  if (_supports_multisample) {
+    if ((_multisample_mode & MM_antialias) != 0 && !val) {
+      // Turn off sample_alpha_to_one multisample.
+      _multisample_mode &= ~MM_antialias;
+      GLP(Disable)(GL_SAMPLE_ALPHA_TO_ONE);
+      if (_multisample_mode == 0) {
+        GLP(Disable)(GL_MULTISAMPLE);
+      }
+    } else if ((_multisample_mode & MM_antialias) == 0 && val) {
+      // Turn on sample_alpha_to_one multisample.
+      if (_multisample_mode == 0) {
+        GLP(Enable)(GL_MULTISAMPLE);
+      }
+      GLP(Enable)(GL_SAMPLE_ALPHA_TO_ONE);
+      _multisample_mode |= MM_antialias;
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GraphicsStateGuardian)::enable_multisample_alpha_mask
+//       Access: Protected
+//  Description: Specifies whether multisample should be enabled for
+//               transparency purposes, using the sample_alpha_to_mask
+//               mode.
+////////////////////////////////////////////////////////////////////
+INLINE void CLP(GraphicsStateGuardian)::
+enable_multisample_alpha_mask(bool val) {
+  if (_supports_multisample) {
+    if ((_multisample_mode & MM_antialias) != 0 && !val) {
+      // Turn off sample_alpha_to_mask multisample.
+      _multisample_mode &= ~MM_antialias;
+      GLP(Disable)(GL_SAMPLE_ALPHA_TO_COVERAGE);
+      if (_multisample_mode == 0) {
         GLP(Disable)(GL_MULTISAMPLE);
       }
+    } else if ((_multisample_mode & MM_antialias) == 0 && val) {
+      // Turn on sample_alpha_to_mask multisample.
+      if (_multisample_mode == 0) {
+        GLP(Enable)(GL_MULTISAMPLE);
+      }
+      GLP(Enable)(GL_SAMPLE_ALPHA_TO_COVERAGE);
+      _multisample_mode |= MM_antialias;
     }
   }
 }
@@ -157,15 +219,16 @@ enable_polygon_smooth(bool val) {
 //       Access: Protected
 //  Description: Sets the appropriate antialiasing modes to render a
 //               series of line primitives, according to
-//               _antialias_mode.
+//               _auto_antialias_mode.
 ////////////////////////////////////////////////////////////////////
 INLINE void CLP(GraphicsStateGuardian)::
 setup_antialias_line() {
-  if (_antialias_mode == (unsigned short)AntialiasAttrib::M_best) {
+  if (_auto_antialias_mode) {
     // Lines supposedly look better using line smoothing, even if we
     // have multisample available.
-    enable_multisample(false);
+    enable_multisample_antialias(false);
     enable_line_smooth(true);
+    set_blend_mode();
   }
 }
 
@@ -174,15 +237,16 @@ setup_antialias_line() {
 //       Access: Protected
 //  Description: Sets the appropriate antialiasing modes to render a
 //               series of point primitives, according to
-//               _antialias_mode.
+//               _auto_antialias_mode.
 ////////////////////////////////////////////////////////////////////
 INLINE void CLP(GraphicsStateGuardian)::
 setup_antialias_point() {
-  if (_antialias_mode == (unsigned short)AntialiasAttrib::M_best) {
+  if (_auto_antialias_mode) {
     // Points supposedly look better using point smoothing, even if we
     // have multisample available.
-    enable_multisample(false);
+    enable_multisample_antialias(false);
     enable_point_smooth(true);
+    set_blend_mode();
   }
 }
 
@@ -191,30 +255,34 @@ setup_antialias_point() {
 //       Access: Protected
 //  Description: Sets the appropriate antialiasing modes to render a
 //               series of point primitives, according to
-//               _antialias_mode.
+//               _auto_antialias_mode.
 ////////////////////////////////////////////////////////////////////
 INLINE void CLP(GraphicsStateGuardian)::
 setup_antialias_polygon() {
-  if (_antialias_mode == (unsigned short)AntialiasAttrib::M_best) {
+  if (_auto_antialias_mode) {
     switch (_render_mode) {
     case RenderModeAttrib::M_wireframe:
       // In wireframe mode, we're really drawing lines.
-      enable_multisample(false);
+      enable_multisample_antialias(false);
       enable_line_smooth(true);
       break;
 
     case RenderModeAttrib::M_point:
       // In point mode, we're drawing points.
-      enable_multisample(false);
+      enable_multisample_antialias(false);
       enable_point_smooth(true);
       break;
 
     default:
       // For polygons, multisample is best if it's available, otherwise
       // polygon smoothing will do.
-      enable_multisample(true);
-      enable_polygon_smooth(true);
+      if (_supports_multisample) {
+        enable_multisample_antialias(true);
+      } else {
+        enable_polygon_smooth(true);
+      }
     }
+    set_blend_mode();
   }
 }
 
@@ -260,50 +328,6 @@ enable_scissor(bool val)
     }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: CLP(GraphicsStateGuardian)::enable_multisample_alpha_one
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void CLP(GraphicsStateGuardian)::
-enable_multisample_alpha_one(bool val) {
-  if (_supports_multisample) {
-    if (_multisample_alpha_one_enabled != val) {
-      _multisample_alpha_one_enabled = val;
-      if (val) {
-        GLP(Enable)(GL_SAMPLE_ALPHA_TO_ONE);
-        GLP(Enable)(GL_MULTISAMPLE);
-      } else {
-        GLP(Disable)(GL_SAMPLE_ALPHA_TO_ONE);
-        if (!_multisample_enabled) {
-          GLP(Disable)(GL_MULTISAMPLE);
-        }
-      }
-    }
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: CLP(GraphicsStateGuardian)::enable_multisample_alpha_mask
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void CLP(GraphicsStateGuardian)::
-enable_multisample_alpha_mask(bool val) {
-  if (_multisample_alpha_mask_enabled != val) {
-    _multisample_alpha_mask_enabled = val;
-    if (val) {
-      GLP(Enable)(GL_SAMPLE_ALPHA_TO_COVERAGE);
-      GLP(Enable)(GL_MULTISAMPLE);
-    } else {
-      GLP(Disable)(GL_SAMPLE_ALPHA_TO_COVERAGE);
-      if (!_multisample_enabled) {
-        GLP(Disable)(GL_MULTISAMPLE);
-      }
-    }
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CLP(GraphicsStateGuardian)::enable_blend
 //       Access:

+ 77 - 25
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -450,14 +450,12 @@ reset() {
 
   // Set up all the enabled/disabled flags to GL's known initial
   // values: everything off.
-  _multisample_enabled = false;
+  _multisample_mode = 0;
   _line_smooth_enabled = false;
   _point_smooth_enabled = false;
   _polygon_smooth_enabled = false;
   _scissor_enabled = false;
   _stencil_test_enabled = false;
-  _multisample_alpha_one_enabled = false;
-  _multisample_alpha_mask_enabled = false;
   _blend_enabled = false;
   _depth_test_enabled = false;
   _fog_enabled = false;
@@ -498,7 +496,7 @@ reset() {
   _needs_tex_mat = false;
   _current_tex_gen = DCAST(TexGenAttrib, TexGenAttrib::make());
   _needs_tex_gen = false;
-  _antialias_mode = AntialiasAttrib::M_none;
+  _auto_antialias_mode = false;
   _render_mode = RenderModeAttrib::M_filled;
 
   report_my_gl_errors();
@@ -2571,21 +2569,52 @@ issue_render_mode(const RenderModeAttrib *attrib) {
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 issue_antialias(const AntialiasAttrib *attrib) {
-  _antialias_mode = attrib->get_mode();
-
-  if (_antialias_mode == AntialiasAttrib::M_best) {
+  if (attrib->get_mode_type() == AntialiasAttrib::M_auto) {
     // In this special mode, we must enable antialiasing on a
     // case-by-case basis, because we enable it differently for
     // polygons and for points and lines.
+    _auto_antialias_mode = true;
 
   } else {
     // Otherwise, explicitly enable or disable according to the bits
-    // that are set.
-    enable_line_smooth((_antialias_mode & AntialiasAttrib::M_line) != 0);
-    enable_point_smooth((_antialias_mode & AntialiasAttrib::M_point) != 0);
-    enable_polygon_smooth((_antialias_mode & AntialiasAttrib::M_polygon) != 0);
-    enable_multisample((_antialias_mode & AntialiasAttrib::M_multisample) != 0);
+    // that are set.  But if multisample is requested and supported,
+    // don't use the other bits at all (they will be ignored by GL
+    // anyway).
+    _auto_antialias_mode = false;
+    unsigned short mode = attrib->get_mode();
+
+    if (_supports_multisample &&
+        (mode & AntialiasAttrib::M_multisample) != 0) {
+      enable_multisample_antialias(true);
+
+    } else {
+      enable_multisample_antialias(false);
+      enable_line_smooth((mode & AntialiasAttrib::M_line) != 0);
+      enable_point_smooth((mode & AntialiasAttrib::M_point) != 0);
+      enable_polygon_smooth((mode & AntialiasAttrib::M_polygon) != 0);
+    }
+  }
+
+  switch (attrib->get_mode_quality()) {
+  case AntialiasAttrib::M_faster:
+    GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_FASTEST);
+    GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_FASTEST);
+    GLP(Hint)(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
+    break;
+
+  case AntialiasAttrib::M_better:
+    GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_NICEST);
+    GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_NICEST);
+    GLP(Hint)(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+    break;
+
+  default:
+    GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
+    GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
+    GLP(Hint)(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE);
+    break;
   }
+
   report_my_gl_errors();
 }
 
@@ -4404,34 +4433,32 @@ end_bind_clip_planes() {
 ////////////////////////////////////////////////////////////////////
 //     Function: CLP(GraphicsStateGuardian)::set_blend_mode
 //       Access: Protected, Virtual
-//  Description: Called after any of these three blending states have
-//               changed; this function is responsible for setting the
-//               appropriate color blending mode based on the given
-//               properties.
+//  Description: Called after any of the things that might change
+//               blending state have changed, this function is
+//               responsible for setting the appropriate color
+//               blending mode based on the current properties.
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
-set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
-               ColorBlendAttrib::Mode color_blend_mode,
-               TransparencyAttrib::Mode transparency_mode) {
+set_blend_mode() {
   // If color_write_mode is off, we disable writing to the color using
   // blending.  This case is only used if we can't use GLP(ColorMask) to
   // disable the color writing for some reason (usually a driver
   // problem).
-  if (color_write_mode == ColorWriteAttrib::M_off) {
+  if (_color_write_mode == ColorWriteAttrib::M_off) {
     enable_multisample_alpha_one(false);
     enable_multisample_alpha_mask(false);
     enable_blend(true);
     _glBlendEquation(GL_FUNC_ADD);
     GLP(BlendFunc)(GL_ZERO, GL_ONE);
-    return;
+   return;
   }
 
   // Is there a color blend set?
-  if (color_blend_mode != ColorBlendAttrib::M_none) {
+  if (_color_blend_mode != ColorBlendAttrib::M_none) {
     enable_multisample_alpha_one(false);
     enable_multisample_alpha_mask(false);
     enable_blend(true);
-    _glBlendEquation(get_blend_equation_type(color_blend_mode));
+    _glBlendEquation(get_blend_equation_type(_color_blend_mode));
     GLP(BlendFunc)(get_blend_func(_color_blend->get_operand_a()),
                    get_blend_func(_color_blend->get_operand_b()));
     Colorf c = _color_blend->get_color();
@@ -4440,7 +4467,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
   }
 
   // No color blend; is there a transparency set?
-  switch (transparency_mode) {
+  switch (_transparency_mode) {
   case TransparencyAttrib::M_none:
   case TransparencyAttrib::M_binary:
     break;
@@ -4468,10 +4495,35 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
     
   default:
     GLCAT.error()
-      << "invalid transparency mode " << (int)transparency_mode << endl;
+      << "invalid transparency mode " << (int)_transparency_mode << endl;
     break;
   }
 
+  if (_line_smooth_enabled || _point_smooth_enabled) {
+    // If we have either of these turned on, we also need to have
+    // blend mode enabled in order to see it.
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    _glBlendEquation(GL_FUNC_ADD);
+    GLP(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    return;
+  }
+
+  if (_polygon_smooth_enabled && 
+      (get_properties().get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) != 0) {
+    // For polygon smoothing, we need this special kind of blending,
+    // but this only works if we have an alpha channel in the frame
+    // buffer.  We should also sort the polygons front-to-back, but
+    // that's the application's problem.
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    _glBlendEquation(GL_FUNC_ADD);
+    GLP(BlendFunc)(GL_SRC_ALPHA_SATURATE, GL_ONE);
+    return;
+  }
+
   // Nothing's set, so disable blending.
   enable_multisample_alpha_one(false);
   enable_multisample_alpha_mask(false);

+ 12 - 10
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -178,9 +178,7 @@ protected:
   virtual void bind_clip_plane(PlaneNode *plane, int plane_id);
   virtual void end_bind_clip_planes();
 
-  virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
-                              ColorBlendAttrib::Mode color_blend_mode,
-                              TransparencyAttrib::Mode transparency_mode);
+  virtual void set_blend_mode();
 
   virtual void finish_modify_state();
 
@@ -189,7 +187,9 @@ protected:
                                                  CPT(DisplayRegion) dr);
   virtual void restore_frame_buffer(SavedFrameBuffer *frame_buffer);
 
-  INLINE void enable_multisample(bool val);
+  INLINE void enable_multisample_antialias(bool val);
+  INLINE void enable_multisample_alpha_one(bool val);
+  INLINE void enable_multisample_alpha_mask(bool val);
   INLINE void enable_line_smooth(bool val);
   INLINE void enable_point_smooth(bool val);
   INLINE void enable_polygon_smooth(bool val);
@@ -199,8 +199,6 @@ protected:
 
   INLINE void enable_scissor(bool val);
   INLINE void enable_stencil_test(bool val);
-  INLINE void enable_multisample_alpha_one(bool val);
-  INLINE void enable_multisample_alpha_mask(bool val);
   INLINE void enable_blend(bool val);
   INLINE void enable_depth_test(bool val);
   INLINE void enable_fog(bool val);
@@ -249,14 +247,18 @@ protected:
   void save_mipmap_images(Texture *tex);
 #endif
 
-  bool _multisample_enabled;
+  enum MultisampleMode {
+    MM_antialias  = 0x0001,
+    MM_alpha_one  = 0x0002,
+    MM_alpha_mask = 0x0004,
+  };
+
+  int _multisample_mode;
   bool _line_smooth_enabled;
   bool _point_smooth_enabled;
   bool _polygon_smooth_enabled;
   bool _scissor_enabled;
   bool _stencil_test_enabled;
-  bool _multisample_alpha_one_enabled;
-  bool _multisample_alpha_mask_enabled;
   bool _blend_enabled;
   bool _depth_test_enabled;
   bool _fog_enabled;
@@ -278,7 +280,7 @@ protected:
   bool _needs_tex_mat;
   CPT(TexGenAttrib) _current_tex_gen;
   bool _needs_tex_gen;
-  unsigned short _antialias_mode;
+  bool _auto_antialias_mode;
   RenderModeAttrib::Mode _render_mode;
 
   CPT(DisplayRegion) _actual_display_region;

+ 27 - 1
panda/src/pgraph/antialiasAttrib.I

@@ -32,9 +32,35 @@ AntialiasAttrib(unsigned short mode) :
 ////////////////////////////////////////////////////////////////////
 //     Function: AntialiasAttrib::get_mode
 //       Access: Published
-//  Description: Returns the render mode.
+//  Description: Returns the specified antialias mode.
 ////////////////////////////////////////////////////////////////////
 INLINE unsigned short AntialiasAttrib::
 get_mode() const {
   return _mode;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: AntialiasAttrib::get_mode_type
+//       Access: Published
+//  Description: Returns the specified antialias mode, with the
+//               quality bits masked out.  This therefore indicates
+//               only the requested type of antialiasing: M_none,
+//               M_auto, or some specific combination.
+////////////////////////////////////////////////////////////////////
+INLINE unsigned short AntialiasAttrib::
+get_mode_type() const {
+  return _mode & M_type_mask;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AntialiasAttrib::get_mode_quality
+//       Access: Published
+//  Description: Returns the specified antialias mode, with the type
+//               bits masked out.  This therefore indicates only the
+//               requested quality settings: one of M_faster,
+//               M_better, M_dont_care, or zero (unspecified).
+////////////////////////////////////////////////////////////////////
+INLINE unsigned short AntialiasAttrib::
+get_mode_quality() const {
+  return _mode & ~M_type_mask;
+}

+ 62 - 19
panda/src/pgraph/antialiasAttrib.cxx

@@ -31,20 +31,36 @@ TypeHandle AntialiasAttrib::_type_handle;
 //       Access: Published, Static
 //  Description: Constructs a new AntialiasAttrib object.
 //
-//               The mode should be either M_none, M_best, or a union
+//               The mode should be either M_none, M_auto, or a union
 //               of any or all of M_point, M_line, M_polygon, and
-//               M_multisample.
+//               M_multisample.  Also, in addition to the above
+//               choices, it may include either of M_better of
+//               M_faster to specify a performance/quality tradeoff
+//               hint.
 //
 //               If M_none is specified, no antialiasing is performed.  
 //
-//               If M_best is specified, M_multisample is selected if
+//               If M_multisample is specified, it means to use the
+//               special framebuffer multisample bits for
+//               antialiasing, if it is available.  If so, the
+//               M_point, M_line, and M_polygon modes are ignored.
+//               This advanced antialiasing mode is only available on
+//               certain graphics hardware.  If it is not available,
+//               the M_multisample bit is ignored (and the other modes
+//               may be used instead, if specified).
+//
+//               M_point, M_line, and/or M_polygon specify
+//               per-primitive smoothing.  When enabled, M_point and
+//               M_line may force transparency on.  M_polygon requires
+//               a frame buffer that includes an alpha channel, and it
+//               works best if the primitives are sorted
+//               front-to-back.
+//
+//               If M_auto is specified, M_multisample is selected if
 //               it is available, otherwise M_polygon is selected,
 //               unless drawing lines or points, in which case M_line
 //               or M_point is selected (these two generally produce
 //               better results than M_multisample)
-//
-//               In the explicit form, it enables all of the specified
-//               multisample modes.
 ////////////////////////////////////////////////////////////////////
 CPT(RenderAttrib) AntialiasAttrib::
 make(unsigned short mode) {
@@ -74,14 +90,17 @@ issue(GraphicsStateGuardianBase *gsg) const {
 void AntialiasAttrib::
 output(ostream &out) const {
   out << get_type() << ":";
-  if (_mode == M_none) {
+  
+  int type = get_mode_type();
+  char sep = ' ';
+
+  if (type == M_none) {
     out << " none";
 
-  } else if (_mode == M_best) {
-    out << " best";
+  } else if (type == M_auto) {
+    out << " auto";
 
   } else {
-    char sep = ' ';
     if ((_mode & M_point) != 0) {
       out << sep << "point";
       sep = '|';
@@ -94,11 +113,20 @@ output(ostream &out) const {
       out << sep << "polygon";
       sep = '|';
     }
-    if ((_mode & M_best) != 0) {
+    if ((_mode & M_auto) != 0) {
       out << sep << "best";
       sep = '|';
     }
   }
+
+  if ((_mode & M_faster) != 0) {
+    out << sep << "faster";
+    sep = '|';
+  }
+  if ((_mode & M_better) != 0) {
+    out << sep << "better";
+    sep = '|';
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -147,17 +175,32 @@ CPT(RenderAttrib) AntialiasAttrib::
 compose_impl(const RenderAttrib *other) const {
   const AntialiasAttrib *ta;
   DCAST_INTO_R(ta, other, 0);
-  if (ta->get_mode() == M_none || ta->get_mode() == M_best ||
-      get_mode() == M_none || get_mode() == M_best) {
-    // These two special modes don't combine: if one of these modes is
+
+  unsigned short mode_type;
+  unsigned short mode_quality;
+
+  if (ta->get_mode_type() == M_none || ta->get_mode_type() == M_auto ||
+      get_mode_type() == M_auto) {
+    // These two special types don't combine: if one of these modes is
     // involved, the lower attrib wins.
-    return ta;
+    mode_type = ta->get_mode_type();
+
+  } else {
+    // Otherwise, the both modes reflect an explicit setting.  In that
+    // case, these modes combine in the sensible way, as a union of
+    // bits.
+    mode_type = get_mode_type() | ta->get_mode_type();
+  }
+
+  if (ta->get_mode_quality() != 0) {
+    // If any quality is specified on the lower attrib, it wins.
+    mode_quality = ta->get_mode_quality();
+  } else {
+    // Otherwise, the upper quality wins.
+    mode_quality = get_mode_quality();
   }
 
-  // Otherwise, both attribs reflect an explicit setting.  In that
-  // case, these modes combine in the sensible way, as a union of
-  // bits.
-  return make(get_mode() | ta->get_mode());
+  return make(mode_type | mode_quality);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 9 - 1
panda/src/pgraph/antialiasAttrib.h

@@ -38,7 +38,13 @@ PUBLISHED:
     M_line        = 0x0002,
     M_polygon     = 0x0004,
     M_multisample = 0x0008,
-    M_best        = 0x001f,
+    M_auto        = 0x001f,
+    M_type_mask   = 0x001f,
+
+    // Extra add-on bits for performance/quality hints.
+    M_faster      = 0x0020,
+    M_better      = 0x0040,
+    M_dont_care   = 0x0060,
   };
 
 private:
@@ -48,6 +54,8 @@ PUBLISHED:
   static CPT(RenderAttrib) make(unsigned short mode);
 
   INLINE unsigned short get_mode() const;
+  INLINE unsigned short get_mode_type() const;
+  INLINE unsigned short get_mode_quality() const;
 
 public:
   virtual void issue(GraphicsStateGuardianBase *gsg) const;