Browse Source

alpha mode issues

David Rose 19 years ago
parent
commit
9d77fe4e06

+ 11 - 2
panda/src/egg/eggPrimitive.cxx

@@ -47,8 +47,17 @@ determine_alpha_mode() {
   if (result == (EggRenderMode *)NULL) {
     int num_textures = get_num_textures();
     for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
-      if (get_texture(i)->get_alpha_mode() != AM_unspecified) {
-        result = get_texture(i);
+      EggTexture *egg_tex = get_texture(i);
+
+      // We only want to consider the alpha mode on those textures
+      // that can affect the transparency of the polygon.  This
+      // mostly depends on the envtype flag.
+      if (egg_tex->affects_polygon_alpha()) {
+        // This texture might affect the polygon alpha, so it gets to
+        // decide the polygon transparency mode.
+        if (egg_tex->get_alpha_mode() != AM_unspecified) {
+          result = get_texture(i);
+        }
       }
     }
   }

+ 5 - 5
panda/src/egg/eggRenderMode.h

@@ -123,12 +123,12 @@ private:
   static TypeHandle _type_handle;
 };
 
-ostream &operator << (ostream &out, EggRenderMode::AlphaMode mode);
-istream &operator >> (istream &in, EggRenderMode::AlphaMode &mode);
+EXPCL_PANDAEGG ostream &operator << (ostream &out, EggRenderMode::AlphaMode mode);
+EXPCL_PANDAEGG istream &operator >> (istream &in, EggRenderMode::AlphaMode &mode);
 
-ostream &operator << (ostream &out, EggRenderMode::DepthWriteMode mode);
-ostream &operator << (ostream &out, EggRenderMode::DepthTestMode mode);
-ostream &operator << (ostream &out, EggRenderMode::VisibilityMode mode);
+EXPCL_PANDAEGG ostream &operator << (ostream &out, EggRenderMode::DepthWriteMode mode);
+EXPCL_PANDAEGG ostream &operator << (ostream &out, EggRenderMode::DepthTestMode mode);
+EXPCL_PANDAEGG ostream &operator << (ostream &out, EggRenderMode::VisibilityMode mode);
 
 #include "eggRenderMode.I"
 

+ 47 - 0
panda/src/egg/eggTexture.cxx

@@ -543,6 +543,53 @@ has_alpha_channel(int num_components) const {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggTexture::affects_polygon_alpha
+//       Access: Published
+//  Description: Returns true if this texture's environment type or
+//               combine mode allows the texture to have an affect on
+//               the polygon's alpha values, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool EggTexture::
+affects_polygon_alpha() const {
+  switch (_env_type) {
+  case ET_modulate:
+  case ET_replace:
+    return true;
+
+  case ET_decal:
+  case ET_blend:
+  case ET_add:
+  case ET_blend_color_scale:
+    return false;
+
+  case ET_unspecified:
+    break;
+  }
+
+  switch (_combiner[CC_alpha]._mode) {
+  case CM_replace:
+  case CM_modulate:
+  case CM_add_signed:
+  case CM_subtract:
+    return true;
+
+  case CM_interpolate:
+  case CM_add:
+  case CM_dot3_rgb:
+  case CM_dot3_rgba:
+    return false;
+
+  case CM_unspecified:
+    break;
+  }
+
+  // A completely unspecified texture environment implies "modulate",
+  // which does affect alpha.
+  return true;
+}
+
+
 ////////////////////////////////////////////////////////////////////
 //     Function: EggTexture::clear_multitexture
 //       Access: Published

+ 1 - 0
panda/src/egg/eggTexture.h

@@ -192,6 +192,7 @@ PUBLISHED:
 
   INLINE void set_env_type(EnvType type);
   INLINE EnvType get_env_type() const;
+  bool affects_polygon_alpha() const;
 
   INLINE void set_combine_mode(CombineChannel channel, CombineMode cm);
   INLINE CombineMode get_combine_mode(CombineChannel channel) const;

+ 5 - 1
panda/src/egg2pg/config_egg2pg.cxx

@@ -129,7 +129,11 @@ ConfigVariableBool egg_suppress_hidden
 
 
 ConfigVariableEnum<EggRenderMode::AlphaMode> egg_alpha_mode
-("egg-alpha-mode", EggRenderMode::AM_blend);
+("egg-alpha-mode", EggRenderMode::AM_blend,
+ PRC_DESC("Specifies the alpha mode to apply when the alpha specification "
+          "\"on\" appears in the egg file (or when a primitive is implicitly "
+          "transparent, because of a <RGBA> that involves a non-unity alpha, "
+          "or because of a four-channel texture."));
 
 ConfigureFn(config_egg2pg) {
   init_libegg2pg();

+ 3 - 9
panda/src/egg2pg/eggRenderState.cxx

@@ -115,20 +115,14 @@ fill_state(EggPrimitive *egg_prim) {
       // mode, assume it should be alpha'ed if the texture has an
       // alpha channel (unless the texture environment type is one
       // that doesn't apply its alpha to the result).
-      if (am == EggRenderMode::AM_unspecified) {
+      if (egg_tex->affects_polygon_alpha() &&
+          am == EggRenderMode::AM_unspecified) {
         const TextureAttrib *tex_attrib = DCAST(TextureAttrib, def._texture);
         Texture *tex = tex_attrib->get_texture();
         nassertv(tex != (Texture *)NULL);
         int num_components = tex->get_num_components();
         if (egg_tex->has_alpha_channel(num_components)) {
-          switch (egg_tex->get_env_type()) {
-          case EggTexture::ET_decal:
-          case EggTexture::ET_add:
-            break;
-
-          default:
-            implicit_alpha = true;
-          }
+          implicit_alpha = true;
         }
       }