瀏覽代碼

add ColorBlendAttrib, unify color blending

David Rose 24 年之前
父節點
當前提交
79766b015e

+ 121 - 62
panda/src/crgsg/crGraphicsStateGuardian.cxx

@@ -3205,6 +3205,11 @@ issue_texture_apply(const TextureApplyAttrib *attrib) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CRGraphicsStateGuardian::
 void CRGraphicsStateGuardian::
 issue_color_write(const ColorWriteAttrib *attrib) {
 issue_color_write(const ColorWriteAttrib *attrib) {
+  // If we did not override this function, the default implementation
+  // would achieve turning off color writes by changing the blend mode
+  // in set_blend_mode().  However, since GL does support an easy way
+  // to disable writes to the color buffer, we can take advantage of
+  // it here.
   ColorWriteAttrib::Mode mode = attrib->get_mode();
   ColorWriteAttrib::Mode mode = attrib->get_mode();
   if (mode == ColorWriteAttrib::M_off) {
   if (mode == ColorWriteAttrib::M_off) {
     chromium.ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
     chromium.ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@@ -3268,10 +3273,6 @@ issue_cull_face(const CullFaceAttrib *attrib) {
     chromium.Enable(GL_CULL_FACE);
     chromium.Enable(GL_CULL_FACE);
     chromium.CullFace(GL_FRONT);
     chromium.CullFace(GL_FRONT);
     break;
     break;
-  case CullFaceAttrib::M_cull_all:
-    chromium.Enable(GL_CULL_FACE);
-    chromium.CullFace(GL_FRONT_AND_BACK);
-    break;
   default:
   default:
     crgsg_cat.error()
     crgsg_cat.error()
       << "invalid cull face mode " << (int)mode << endl;
       << "invalid cull face mode " << (int)mode << endl;
@@ -3280,64 +3281,6 @@ issue_cull_face(const CullFaceAttrib *attrib) {
   report_errors();
   report_errors();
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: CRGraphicsStateGuardian::issue_transparency
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void CRGraphicsStateGuardian::
-issue_transparency(const TransparencyAttrib *attrib) {
-  TransparencyAttrib::Mode mode = attrib->get_mode();
-
-  switch (mode) {
-  case TransparencyAttrib::M_none:
-    enable_multisample_alpha_one(false);
-    enable_multisample_alpha_mask(false);
-    enable_blend(false);
-    enable_alpha_test(false);
-    break;
-  case TransparencyAttrib::M_alpha:
-  case TransparencyAttrib::M_alpha_sorted:
-    // Should we really have an "alpha" and an "alpha_sorted" mode,
-    // like Performer does?  (The difference is that "alpha" is with
-    // the write to the depth buffer disabled.)  Or should we just use
-    // the separate depth write transition to control this?  Doing it
-    // implicitly requires a bit more logic here and in the state
-    // management; for now we require the user to explicitly turn off
-    // the depth write.
-    enable_multisample_alpha_one(false);
-    enable_multisample_alpha_mask(false);
-    enable_blend(true);
-    enable_alpha_test(false);
-    call_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    break;
-  case TransparencyAttrib::M_multisample:
-    enable_multisample_alpha_one(true);
-    enable_multisample_alpha_mask(true);
-    enable_blend(false);
-    enable_alpha_test(false);
-    break;
-  case TransparencyAttrib::M_multisample_mask:
-    enable_multisample_alpha_one(false);
-    enable_multisample_alpha_mask(true);
-    enable_blend(false);
-    enable_alpha_test(false);
-    break;
-  case TransparencyAttrib::M_binary:
-    enable_multisample_alpha_one(false);
-    enable_multisample_alpha_mask(false);
-    enable_blend(false);
-    enable_alpha_test(true);
-    call_glAlphaFunc(GL_EQUAL, 1);
-    break;
-  default:
-    crgsg_cat.error()
-      << "invalid transparency mode " << (int)mode << endl;
-    break;
-  }
-  report_errors();
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::issue_fog
 //     Function: CRGraphicsStateGuardian::issue_fog
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -4626,6 +4569,122 @@ end_bind_lights() {
   chromium.PopMatrix();
   chromium.PopMatrix();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: CRGraphicsStateGuardian::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.
+////////////////////////////////////////////////////////////////////
+void CRGraphicsStateGuardian::
+set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
+               ColorBlendAttrib::Mode color_blend_mode,
+               TransparencyAttrib::Mode transparency_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 chromium.ColorMask to
+  // disable the color writing for some reason (usually a driver
+  // problem).
+  if (color_write_mode == ColorWriteAttrib::M_off) {
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_ZERO, GL_ONE);
+    return;
+  }
+
+  // Is there a color blend set?
+  switch (color_blend_mode) {
+  case ColorBlendAttrib::M_none:
+    break;
+
+  case ColorBlendAttrib::M_multiply:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_DST_COLOR, GL_ZERO);
+    return;
+
+  case ColorBlendAttrib::M_add:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_ONE, GL_ONE);
+    return;
+
+  case ColorBlendAttrib::M_multiply_add:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_DST_COLOR, GL_ONE);
+    return;
+
+  default:
+    crgsg_cat.error()
+      << "Unknown color blend mode " << (int)color_blend_mode << endl;
+    break;
+  }
+
+  // No color blend; is there a transparency set?
+  switch (transparency_mode) {
+  case TransparencyAttrib::M_none:
+    break;
+
+  case TransparencyAttrib::M_alpha:
+  case TransparencyAttrib::M_alpha_sorted:
+    // Should we really have an "alpha" and an "alpha_sorted" mode,
+    // like Performer does?  (The difference is that "alpha" is with
+    // the write to the depth buffer disabled.)  Or should we just use
+    // the separate depth write transition to control this?  Doing it
+    // implicitly requires a bit more logic here and in the state
+    // management; for now we require the user to explicitly turn off
+    // the depth write.
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    return;
+
+  case TransparencyAttrib::M_multisample:
+    enable_multisample_alpha_one(true);
+    enable_multisample_alpha_mask(true);
+    enable_blend(false);
+    enable_alpha_test(false);
+    return;
+
+  case TransparencyAttrib::M_multisample_mask:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(true);
+    enable_blend(false);
+    enable_alpha_test(false);
+    return;
+
+  case TransparencyAttrib::M_binary:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(false);
+    enable_alpha_test(true);
+    call_glAlphaFunc(GL_EQUAL, 1);
+    return;
+
+  default:
+    crgsg_cat.error()
+      << "invalid transparency mode " << (int)transparency_mode << endl;
+    break;
+  }
+
+  // Nothing's set, so disable blending.
+  enable_multisample_alpha_one(false);
+  enable_multisample_alpha_mask(false);
+  enable_blend(false);
+  enable_alpha_test(false);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CRGraphicsStateGuardian::free_pointers
 //     Function: CRGraphicsStateGuardian::free_pointers
 //       Access: Protected
 //       Access: Protected

+ 4 - 2
panda/src/crgsg/crGraphicsStateGuardian.h

@@ -173,10 +173,8 @@ public:
   virtual void issue_depth_test(const DepthTestAttrib *attrib);
   virtual void issue_depth_test(const DepthTestAttrib *attrib);
   virtual void issue_depth_write(const DepthWriteAttrib *attrib);
   virtual void issue_depth_write(const DepthWriteAttrib *attrib);
   virtual void issue_cull_face(const CullFaceAttrib *attrib);
   virtual void issue_cull_face(const CullFaceAttrib *attrib);
-  virtual void issue_transparency(const TransparencyAttrib *attrib);
   virtual void issue_fog(const FogAttrib *attrib);
   virtual void issue_fog(const FogAttrib *attrib);
   virtual void issue_depth_offset(const DepthOffsetAttrib *attrib);
   virtual void issue_depth_offset(const DepthOffsetAttrib *attrib);
-  //  virtual void issue_color_blend(const ColorBlendAttrib *attrib);
   //  virtual void issue_tex_gen(const TexGenAttrib *attrib);
   //  virtual void issue_tex_gen(const TexGenAttrib *attrib);
   //  virtual void issue_stencil(const StencilAttrib *attrib);
   //  virtual void issue_stencil(const StencilAttrib *attrib);
   //  virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
   //  virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
@@ -216,6 +214,10 @@ protected:
   virtual void begin_bind_lights();
   virtual void begin_bind_lights();
   virtual void end_bind_lights();
   virtual void end_bind_lights();
 
 
+  virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
+                              ColorBlendAttrib::Mode color_blend_mode,
+                              TransparencyAttrib::Mode transparency_mode);
+
   void free_pointers();
   void free_pointers();
   virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
   virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
                                                  CPT(DisplayRegion) dr);
                                                  CPT(DisplayRegion) dr);

+ 1 - 2
panda/src/crgsg/create_crgsg.py

@@ -18,7 +18,6 @@ files=(
     "%(n)sTextureContext.cxx",
     "%(n)sTextureContext.cxx",
     "%(n)sTextureContext.h",
     "%(n)sTextureContext.h",
     "%(n)sext.h",
     "%(n)sext.h",
-    "%(n)sgsg_composite.cxx",
     "%(n)sgsg_composite1.cxx",
     "%(n)sgsg_composite1.cxx",
     #"Sources.pp",
     #"Sources.pp",
 )
 )
@@ -945,4 +944,4 @@ for fn in files:
 
 
 #define make_GlGraphicsStateGuardian make_CRGraphicsStateGuardian
 #define make_GlGraphicsStateGuardian make_CRGraphicsStateGuardian
 
 
-"""
+"""

+ 50 - 0
panda/src/display/graphicsStateGuardian.cxx

@@ -152,6 +152,10 @@ reset() {
   _current_alpha_offset = 0;
   _current_alpha_offset = 0;
   _current_alpha_scale = 1;
   _current_alpha_scale = 1;
 
 
+  _color_write_mode = ColorWriteAttrib::M_on;
+  _color_blend_mode = ColorBlendAttrib::M_none;
+  _transparency_mode = TransparencyAttrib::M_none;
+
   _has_scene_graph_color = false;
   _has_scene_graph_color = false;
   _issued_color_stale = false;
   _issued_color_stale = false;
   _vertex_colors_enabled = true;
   _vertex_colors_enabled = true;
@@ -1287,6 +1291,39 @@ issue_light(const LightAttrib *attrib) {
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::issue_color_write
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+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);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::issue_transparency
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+issue_transparency(const TransparencyAttrib *attrib) {
+  _transparency_mode = attrib->get_mode();
+  set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::issue_color_blend
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+issue_color_blend(const ColorBlendAttrib *attrib) {
+  _color_blend_mode = attrib->get_mode();
+  set_blend_mode(_color_write_mode, _color_blend_mode, _transparency_mode);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::bind_light
 //     Function: GraphicsStateGuardian::bind_light
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -1409,6 +1446,19 @@ void GraphicsStateGuardian::
 end_bind_lights() {
 end_bind_lights() {
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     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.
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+set_blend_mode(ColorWriteAttrib::Mode, ColorBlendAttrib::Mode,
+               TransparencyAttrib::Mode) {
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::mark_prepared_texture
 //     Function: GraphicsStateGuardian::mark_prepared_texture
 //       Access: Protected
 //       Access: Protected

+ 14 - 0
panda/src/display/graphicsStateGuardian.h

@@ -39,6 +39,9 @@
 #include "transformState.h"
 #include "transformState.h"
 #include "renderState.h"
 #include "renderState.h"
 #include "light.h"
 #include "light.h"
+#include "colorWriteAttrib.h"
+#include "colorBlendAttrib.h"
+#include "transparencyAttrib.h"
 
 
 #include "notify.h"
 #include "notify.h"
 #include "pvector.h"
 #include "pvector.h"
@@ -188,6 +191,9 @@ public:
   virtual void issue_color_scale(const ColorScaleAttrib *attrib);
   virtual void issue_color_scale(const ColorScaleAttrib *attrib);
   virtual void issue_color(const ColorAttrib *attrib);
   virtual void issue_color(const ColorAttrib *attrib);
   virtual void issue_light(const LightAttrib *attrib);
   virtual void issue_light(const LightAttrib *attrib);
+  virtual void issue_color_write(const ColorWriteAttrib *attrib);
+  virtual void issue_transparency(const TransparencyAttrib *attrib);
+  virtual void issue_color_blend(const ColorBlendAttrib *attrib);
 
 
   virtual void bind_light(PointLight *light, int light_id);
   virtual void bind_light(PointLight *light, int light_id);
   virtual void bind_light(DirectionalLight *light, int light_id);
   virtual void bind_light(DirectionalLight *light, int light_id);
@@ -202,6 +208,10 @@ protected:
   virtual void begin_bind_lights();
   virtual void begin_bind_lights();
   virtual void end_bind_lights();
   virtual void end_bind_lights();
 
 
+  virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
+                              ColorBlendAttrib::Mode color_blend_mode,
+                              TransparencyAttrib::Mode transparency_mode);
+
   virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
   virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
                                                  CPT(DisplayRegion) dr)=0;
                                                  CPT(DisplayRegion) dr)=0;
   virtual void restore_frame_buffer(SavedFrameBuffer *frame_buffer)=0;
   virtual void restore_frame_buffer(SavedFrameBuffer *frame_buffer)=0;
@@ -292,6 +302,10 @@ protected:
   float _current_alpha_offset;
   float _current_alpha_offset;
   float _current_alpha_scale;
   float _current_alpha_scale;
 
 
+  ColorWriteAttrib::Mode _color_write_mode;
+  ColorBlendAttrib::Mode _color_blend_mode;
+  TransparencyAttrib::Mode _transparency_mode;
+
 public:
 public:
   // Statistics
   // Statistics
   static PStatCollector _total_texusage_pcollector;
   static PStatCollector _total_texusage_pcollector;

+ 121 - 62
panda/src/glgsg/glGraphicsStateGuardian.cxx

@@ -3204,6 +3204,11 @@ issue_texture_apply(const TextureApplyAttrib *attrib) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GLGraphicsStateGuardian::
 void GLGraphicsStateGuardian::
 issue_color_write(const ColorWriteAttrib *attrib) {
 issue_color_write(const ColorWriteAttrib *attrib) {
+  // If we did not override this function, the default implementation
+  // would achieve turning off color writes by changing the blend mode
+  // in set_blend_mode().  However, since GL does support an easy way
+  // to disable writes to the color buffer, we can take advantage of
+  // it here.
   ColorWriteAttrib::Mode mode = attrib->get_mode();
   ColorWriteAttrib::Mode mode = attrib->get_mode();
   if (mode == ColorWriteAttrib::M_off) {
   if (mode == ColorWriteAttrib::M_off) {
     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@@ -3267,10 +3272,6 @@ issue_cull_face(const CullFaceAttrib *attrib) {
     glEnable(GL_CULL_FACE);
     glEnable(GL_CULL_FACE);
     glCullFace(GL_FRONT);
     glCullFace(GL_FRONT);
     break;
     break;
-  case CullFaceAttrib::M_cull_all:
-    glEnable(GL_CULL_FACE);
-    glCullFace(GL_FRONT_AND_BACK);
-    break;
   default:
   default:
     glgsg_cat.error()
     glgsg_cat.error()
       << "invalid cull face mode " << (int)mode << endl;
       << "invalid cull face mode " << (int)mode << endl;
@@ -3279,64 +3280,6 @@ issue_cull_face(const CullFaceAttrib *attrib) {
   report_errors();
   report_errors();
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::issue_transparency
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GLGraphicsStateGuardian::
-issue_transparency(const TransparencyAttrib *attrib) {
-  TransparencyAttrib::Mode mode = attrib->get_mode();
-
-  switch (mode) {
-  case TransparencyAttrib::M_none:
-    enable_multisample_alpha_one(false);
-    enable_multisample_alpha_mask(false);
-    enable_blend(false);
-    enable_alpha_test(false);
-    break;
-  case TransparencyAttrib::M_alpha:
-  case TransparencyAttrib::M_alpha_sorted:
-    // Should we really have an "alpha" and an "alpha_sorted" mode,
-    // like Performer does?  (The difference is that "alpha" is with
-    // the write to the depth buffer disabled.)  Or should we just use
-    // the separate depth write transition to control this?  Doing it
-    // implicitly requires a bit more logic here and in the state
-    // management; for now we require the user to explicitly turn off
-    // the depth write.
-    enable_multisample_alpha_one(false);
-    enable_multisample_alpha_mask(false);
-    enable_blend(true);
-    enable_alpha_test(false);
-    call_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    break;
-  case TransparencyAttrib::M_multisample:
-    enable_multisample_alpha_one(true);
-    enable_multisample_alpha_mask(true);
-    enable_blend(false);
-    enable_alpha_test(false);
-    break;
-  case TransparencyAttrib::M_multisample_mask:
-    enable_multisample_alpha_one(false);
-    enable_multisample_alpha_mask(true);
-    enable_blend(false);
-    enable_alpha_test(false);
-    break;
-  case TransparencyAttrib::M_binary:
-    enable_multisample_alpha_one(false);
-    enable_multisample_alpha_mask(false);
-    enable_blend(false);
-    enable_alpha_test(true);
-    call_glAlphaFunc(GL_EQUAL, 1);
-    break;
-  default:
-    glgsg_cat.error()
-      << "invalid transparency mode " << (int)mode << endl;
-    break;
-  }
-  report_errors();
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::issue_fog
 //     Function: GLGraphicsStateGuardian::issue_fog
 //       Access: Public, Virtual
 //       Access: Public, Virtual
@@ -4625,6 +4568,122 @@ end_bind_lights() {
   glPopMatrix();
   glPopMatrix();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::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.
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
+               ColorBlendAttrib::Mode color_blend_mode,
+               TransparencyAttrib::Mode transparency_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 glColorMask to
+  // disable the color writing for some reason (usually a driver
+  // problem).
+  if (color_write_mode == ColorWriteAttrib::M_off) {
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_ZERO, GL_ONE);
+    return;
+  }
+
+  // Is there a color blend set?
+  switch (color_blend_mode) {
+  case ColorBlendAttrib::M_none:
+    break;
+
+  case ColorBlendAttrib::M_multiply:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_DST_COLOR, GL_ZERO);
+    return;
+
+  case ColorBlendAttrib::M_add:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_ONE, GL_ONE);
+    return;
+
+  case ColorBlendAttrib::M_multiply_add:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_DST_COLOR, GL_ONE);
+    return;
+
+  default:
+    glgsg_cat.error()
+      << "Unknown color blend mode " << (int)color_blend_mode << endl;
+    break;
+  }
+
+  // No color blend; is there a transparency set?
+  switch (transparency_mode) {
+  case TransparencyAttrib::M_none:
+    break;
+
+  case TransparencyAttrib::M_alpha:
+  case TransparencyAttrib::M_alpha_sorted:
+    // Should we really have an "alpha" and an "alpha_sorted" mode,
+    // like Performer does?  (The difference is that "alpha" is with
+    // the write to the depth buffer disabled.)  Or should we just use
+    // the separate depth write transition to control this?  Doing it
+    // implicitly requires a bit more logic here and in the state
+    // management; for now we require the user to explicitly turn off
+    // the depth write.
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(true);
+    enable_alpha_test(false);
+    call_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    return;
+
+  case TransparencyAttrib::M_multisample:
+    enable_multisample_alpha_one(true);
+    enable_multisample_alpha_mask(true);
+    enable_blend(false);
+    enable_alpha_test(false);
+    return;
+
+  case TransparencyAttrib::M_multisample_mask:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(true);
+    enable_blend(false);
+    enable_alpha_test(false);
+    return;
+
+  case TransparencyAttrib::M_binary:
+    enable_multisample_alpha_one(false);
+    enable_multisample_alpha_mask(false);
+    enable_blend(false);
+    enable_alpha_test(true);
+    call_glAlphaFunc(GL_EQUAL, 1);
+    return;
+
+  default:
+    glgsg_cat.error()
+      << "invalid transparency mode " << (int)transparency_mode << endl;
+    break;
+  }
+
+  // Nothing's set, so disable blending.
+  enable_multisample_alpha_one(false);
+  enable_multisample_alpha_mask(false);
+  enable_blend(false);
+  enable_alpha_test(false);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::free_pointers
 //     Function: GLGraphicsStateGuardian::free_pointers
 //       Access: Protected
 //       Access: Protected

+ 4 - 2
panda/src/glgsg/glGraphicsStateGuardian.h

@@ -162,10 +162,8 @@ public:
   virtual void issue_depth_test(const DepthTestAttrib *attrib);
   virtual void issue_depth_test(const DepthTestAttrib *attrib);
   virtual void issue_depth_write(const DepthWriteAttrib *attrib);
   virtual void issue_depth_write(const DepthWriteAttrib *attrib);
   virtual void issue_cull_face(const CullFaceAttrib *attrib);
   virtual void issue_cull_face(const CullFaceAttrib *attrib);
-  virtual void issue_transparency(const TransparencyAttrib *attrib);
   virtual void issue_fog(const FogAttrib *attrib);
   virtual void issue_fog(const FogAttrib *attrib);
   virtual void issue_depth_offset(const DepthOffsetAttrib *attrib);
   virtual void issue_depth_offset(const DepthOffsetAttrib *attrib);
-  //  virtual void issue_color_blend(const ColorBlendAttrib *attrib);
   //  virtual void issue_tex_gen(const TexGenAttrib *attrib);
   //  virtual void issue_tex_gen(const TexGenAttrib *attrib);
   //  virtual void issue_stencil(const StencilAttrib *attrib);
   //  virtual void issue_stencil(const StencilAttrib *attrib);
   //  virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
   //  virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
@@ -205,6 +203,10 @@ protected:
   virtual void begin_bind_lights();
   virtual void begin_bind_lights();
   virtual void end_bind_lights();
   virtual void end_bind_lights();
 
 
+  virtual void set_blend_mode(ColorWriteAttrib::Mode color_write_mode,
+                              ColorBlendAttrib::Mode color_blend_mode,
+                              TransparencyAttrib::Mode transparency_mode);
+
   void free_pointers();
   void free_pointers();
   virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
   virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
                                                  CPT(DisplayRegion) dr);
                                                  CPT(DisplayRegion) dr);

+ 3 - 0
panda/src/pgraph/Sources.pp

@@ -11,6 +11,7 @@
     binCullHandler.I binCullHandler.h \
     binCullHandler.I binCullHandler.h \
     qpcamera.I qpcamera.h \
     qpcamera.I qpcamera.h \
     colorAttrib.I colorAttrib.h \
     colorAttrib.I colorAttrib.h \
+    colorBlendAttrib.I colorBlendAttrib.h \
     colorScaleAttrib.I colorScaleAttrib.h \
     colorScaleAttrib.I colorScaleAttrib.h \
     colorWriteAttrib.I colorWriteAttrib.h \
     colorWriteAttrib.I colorWriteAttrib.h \
     config_pgraph.h \
     config_pgraph.h \
@@ -79,6 +80,7 @@
     binCullHandler.cxx \
     binCullHandler.cxx \
     qpcamera.cxx \
     qpcamera.cxx \
     colorAttrib.cxx \
     colorAttrib.cxx \
+    colorBlendAttrib.cxx \
     colorScaleAttrib.cxx \
     colorScaleAttrib.cxx \
     colorWriteAttrib.cxx \
     colorWriteAttrib.cxx \
     config_pgraph.cxx \
     config_pgraph.cxx \
@@ -152,6 +154,7 @@
     binCullHandler.I binCullHandler.h \
     binCullHandler.I binCullHandler.h \
     qpcamera.I qpcamera.h \
     qpcamera.I qpcamera.h \
     colorAttrib.I colorAttrib.h \
     colorAttrib.I colorAttrib.h \
+    colorBlendAttrib.I colorBlendAttrib.h \
     colorScaleAttrib.I colorScaleAttrib.h \
     colorScaleAttrib.I colorScaleAttrib.h \
     colorWriteAttrib.I colorWriteAttrib.h \
     colorWriteAttrib.I colorWriteAttrib.h \
     config_pgraph.h \
     config_pgraph.h \

+ 40 - 0
panda/src/pgraph/colorBlendAttrib.I

@@ -0,0 +1,40 @@
+// Filename: colorBlendAttrib.I
+// Created by:  drose (29Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::Constructor
+//       Access: Private
+//  Description: Use ColorBlendAttrib::make() to construct a new
+//               ColorBlendAttrib object.
+////////////////////////////////////////////////////////////////////
+INLINE ColorBlendAttrib::
+ColorBlendAttrib(ColorBlendAttrib::Mode mode) :
+  _mode(mode)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::get_mode
+//       Access: Published
+//  Description: Returns the colorBlend mode.
+////////////////////////////////////////////////////////////////////
+INLINE ColorBlendAttrib::Mode ColorBlendAttrib::
+get_mode() const {
+  return _mode;
+}

+ 179 - 0
panda/src/pgraph/colorBlendAttrib.cxx

@@ -0,0 +1,179 @@
+// Filename: colorBlendAttrib.cxx
+// Created by:  drose (29Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "colorBlendAttrib.h"
+#include "graphicsStateGuardianBase.h"
+#include "dcast.h"
+#include "bamReader.h"
+#include "bamWriter.h"
+#include "datagram.h"
+#include "datagramIterator.h"
+
+TypeHandle ColorBlendAttrib::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::make
+//       Access: Published, Static
+//  Description: Constructs a new ColorBlendAttrib object that specifies
+//               how to cull geometry.  By Panda convention, vertices
+//               are ordered counterclockwise when seen from the
+//               front, so the M_cull_clockwise will cull backfacing
+//               polygons.
+////////////////////////////////////////////////////////////////////
+CPT(RenderAttrib) ColorBlendAttrib::
+make(ColorBlendAttrib::Mode mode) {
+  ColorBlendAttrib *attrib = new ColorBlendAttrib(mode);
+  return return_new(attrib);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::issue
+//       Access: Public, Virtual
+//  Description: Calls the appropriate method on the indicated GSG
+//               to issue the graphics commands appropriate to the
+//               given attribute.  This is normally called
+//               (indirectly) only from
+//               GraphicsStateGuardian::set_state() or modify_state().
+////////////////////////////////////////////////////////////////////
+void ColorBlendAttrib::
+issue(GraphicsStateGuardianBase *gsg) const {
+  gsg->issue_color_blend(this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::output
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void ColorBlendAttrib::
+output(ostream &out) const {
+  out << get_type() << ":";
+  switch (get_mode()) {
+  case M_none:
+    out << "none";
+    break;
+
+  case M_multiply:
+    out << "multiply";
+    break;
+
+  case M_add:
+    out << "add";
+    break;
+
+  case M_multiply_add:
+    out << "multiply_add";
+    break;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::compare_to_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived ColorBlendAttrib
+//               types to return a unique number indicating whether
+//               this ColorBlendAttrib is equivalent to the other one.
+//
+//               This should return 0 if the two ColorBlendAttrib objects
+//               are equivalent, a number less than zero if this one
+//               should be sorted before the other one, and a number
+//               greater than zero otherwise.
+//
+//               This will only be called with two ColorBlendAttrib
+//               objects whose get_type() functions return the same.
+////////////////////////////////////////////////////////////////////
+int ColorBlendAttrib::
+compare_to_impl(const RenderAttrib *other) const {
+  const ColorBlendAttrib *ta;
+  DCAST_INTO_R(ta, other, 0);
+  return (int)_mode - (int)ta->_mode;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::make_default_impl
+//       Access: Protected, Virtual
+//  Description: Intended to be overridden by derived ColorBlendAttrib
+//               types to specify what the default property for a
+//               ColorBlendAttrib of this type should be.
+//
+//               This should return a newly-allocated ColorBlendAttrib of
+//               the same type that corresponds to whatever the
+//               standard default for this kind of ColorBlendAttrib is.
+////////////////////////////////////////////////////////////////////
+RenderAttrib *ColorBlendAttrib::
+make_default_impl() const {
+  return new ColorBlendAttrib;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::register_with_read_factory
+//       Access: Public, Static
+//  Description: Tells the BamReader how to create objects of type
+//               ColorBlendAttrib.
+////////////////////////////////////////////////////////////////////
+void ColorBlendAttrib::
+register_with_read_factory() {
+  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::write_datagram
+//       Access: Public, Virtual
+//  Description: Writes the contents of this object to the datagram
+//               for shipping out to a Bam file.
+////////////////////////////////////////////////////////////////////
+void ColorBlendAttrib::
+write_datagram(BamWriter *manager, Datagram &dg) {
+  RenderAttrib::write_datagram(manager, dg);
+
+  dg.add_int8(_mode);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::make_from_bam
+//       Access: Protected, Static
+//  Description: This function is called by the BamReader's factory
+//               when a new object of type ColorBlendAttrib is encountered
+//               in the Bam file.  It should create the ColorBlendAttrib
+//               and extract its information from the file.
+////////////////////////////////////////////////////////////////////
+TypedWritable *ColorBlendAttrib::
+make_from_bam(const FactoryParams &params) {
+  ColorBlendAttrib *attrib = new ColorBlendAttrib;
+  DatagramIterator scan;
+  BamReader *manager;
+
+  parse_params(params, scan, manager);
+  attrib->fillin(scan, manager);
+
+  return attrib;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ColorBlendAttrib::fillin
+//       Access: Protected
+//  Description: This internal function is called by make_from_bam to
+//               read in all of the relevant data from the BamFile for
+//               the new ColorBlendAttrib.
+////////////////////////////////////////////////////////////////////
+void ColorBlendAttrib::
+fillin(DatagramIterator &scan, BamReader *manager) {
+  RenderAttrib::fillin(scan, manager);
+
+  _mode = (Mode)scan.get_int8();
+}

+ 90 - 0
panda/src/pgraph/colorBlendAttrib.h

@@ -0,0 +1,90 @@
+// Filename: colorBlendAttrib.h
+// Created by:  drose (29Mar02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef COLORBLENDATTRIB_H
+#define COLORBLENDATTRIB_H
+
+#include "pandabase.h"
+
+#include "renderAttrib.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : ColorBlendAttrib
+// Description : This specifies how colors are blended into the frame
+//               buffer, for special effects.  This overrides
+//               transparency if transparency is also specified.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA ColorBlendAttrib : public RenderAttrib {
+PUBLISHED:
+  enum Mode {
+    M_none,             // Blending is disabled
+    M_multiply,         // color already in fbuffer * incoming color
+    M_add,              // color already in fbuffer + incoming color
+    M_multiply_add,     // color already in fbuffer * incoming color +
+                        //   color already in fbuffer
+  };
+
+private:
+  INLINE ColorBlendAttrib(Mode mode = M_none);
+
+PUBLISHED:
+  static CPT(RenderAttrib) make(Mode mode);
+
+  INLINE Mode get_mode() const;
+
+public:
+  virtual void issue(GraphicsStateGuardianBase *gsg) const;
+  virtual void output(ostream &out) const;
+
+protected:
+  virtual int compare_to_impl(const RenderAttrib *other) const;
+  virtual RenderAttrib *make_default_impl() const;
+
+private:
+  Mode _mode;
+
+public:
+  static void register_with_read_factory();
+  virtual void write_datagram(BamWriter *manager, Datagram &dg);
+
+protected:
+  static TypedWritable *make_from_bam(const FactoryParams &params);
+  void fillin(DatagramIterator &scan, BamReader *manager);
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    RenderAttrib::init_type();
+    register_type(_type_handle, "ColorBlendAttrib",
+                  RenderAttrib::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "colorBlendAttrib.I"
+
+#endif
+

+ 3 - 0
panda/src/pgraph/config_pgraph.cxx

@@ -22,6 +22,7 @@
 #include "billboardEffect.h"
 #include "billboardEffect.h"
 #include "qpcamera.h"
 #include "qpcamera.h"
 #include "colorAttrib.h"
 #include "colorAttrib.h"
+#include "colorBlendAttrib.h"
 #include "colorScaleAttrib.h"
 #include "colorScaleAttrib.h"
 #include "colorWriteAttrib.h"
 #include "colorWriteAttrib.h"
 #include "cullFaceAttrib.h"
 #include "cullFaceAttrib.h"
@@ -107,6 +108,7 @@ init_libpgraph() {
   BillboardEffect::init_type();
   BillboardEffect::init_type();
   qpCamera::init_type();
   qpCamera::init_type();
   ColorAttrib::init_type();
   ColorAttrib::init_type();
+  ColorBlendAttrib::init_type();
   ColorScaleAttrib::init_type();
   ColorScaleAttrib::init_type();
   ColorWriteAttrib::init_type();
   ColorWriteAttrib::init_type();
   CullFaceAttrib::init_type();
   CullFaceAttrib::init_type();
@@ -164,6 +166,7 @@ init_libpgraph() {
   BillboardEffect::register_with_read_factory();
   BillboardEffect::register_with_read_factory();
   qpCamera::register_with_read_factory();
   qpCamera::register_with_read_factory();
   ColorAttrib::register_with_read_factory();
   ColorAttrib::register_with_read_factory();
+  ColorBlendAttrib::register_with_read_factory();
   ColorScaleAttrib::register_with_read_factory();
   ColorScaleAttrib::register_with_read_factory();
   ColorWriteAttrib::register_with_read_factory();
   ColorWriteAttrib::register_with_read_factory();
   CullBinAttrib::register_with_read_factory();
   CullBinAttrib::register_with_read_factory();

+ 0 - 3
panda/src/pgraph/cullFaceAttrib.cxx

@@ -73,9 +73,6 @@ output(ostream &out) const {
   case M_cull_counter_clockwise:
   case M_cull_counter_clockwise:
     out << "cull_counter_clockwise";
     out << "cull_counter_clockwise";
     break;
     break;
-  case M_cull_all:
-    out << "cull_all";
-    break;
   }
   }
 }
 }
 
 

+ 0 - 1
panda/src/pgraph/cullFaceAttrib.h

@@ -34,7 +34,6 @@ PUBLISHED:
     M_cull_none,                // Cull no polygons
     M_cull_none,                // Cull no polygons
     M_cull_clockwise,           // Cull clockwise-oriented polygons
     M_cull_clockwise,           // Cull clockwise-oriented polygons
     M_cull_counter_clockwise,   // Cull counter-clockwise-oriented polygons
     M_cull_counter_clockwise,   // Cull counter-clockwise-oriented polygons
-    M_cull_all,         // Cull all polygons (other primitives are still drawn)
   };
   };
 
 
 private:
 private:

+ 1 - 0
panda/src/pgraph/pgraph_composite1.cxx

@@ -3,6 +3,7 @@
 #include "binCullHandler.cxx"
 #include "binCullHandler.cxx"
 #include "qpcamera.cxx"
 #include "qpcamera.cxx"
 #include "colorAttrib.cxx"
 #include "colorAttrib.cxx"
+#include "colorBlendAttrib.cxx"
 #include "colorScaleAttrib.cxx"
 #include "colorScaleAttrib.cxx"
 #include "colorWriteAttrib.cxx"
 #include "colorWriteAttrib.cxx"
 #include "config_pgraph.cxx"
 #include "config_pgraph.cxx"