From 9d77fe4e066d5beabda2af8b3e21f4df8c5447df Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 6 Apr 2006 21:54:46 +0000 Subject: [PATCH] alpha mode issues --- panda/src/egg/eggPrimitive.cxx | 13 ++++++-- panda/src/egg/eggRenderMode.h | 10 +++--- panda/src/egg/eggTexture.cxx | 47 +++++++++++++++++++++++++++++ panda/src/egg/eggTexture.h | 1 + panda/src/egg2pg/config_egg2pg.cxx | 6 +++- panda/src/egg2pg/eggRenderState.cxx | 12 ++------ 6 files changed, 72 insertions(+), 17 deletions(-) diff --git a/panda/src/egg/eggPrimitive.cxx b/panda/src/egg/eggPrimitive.cxx index 534484c6bd..d1bdc15b3e 100644 --- a/panda/src/egg/eggPrimitive.cxx +++ b/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); + } } } } diff --git a/panda/src/egg/eggRenderMode.h b/panda/src/egg/eggRenderMode.h index ecf5018702..1e6485b4b2 100644 --- a/panda/src/egg/eggRenderMode.h +++ b/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" diff --git a/panda/src/egg/eggTexture.cxx b/panda/src/egg/eggTexture.cxx index 0e5bf1ee21..d744221662 100644 --- a/panda/src/egg/eggTexture.cxx +++ b/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 diff --git a/panda/src/egg/eggTexture.h b/panda/src/egg/eggTexture.h index 49ca071e06..2111c73917 100644 --- a/panda/src/egg/eggTexture.h +++ b/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; diff --git a/panda/src/egg2pg/config_egg2pg.cxx b/panda/src/egg2pg/config_egg2pg.cxx index 393da2441e..463aa89804 100644 --- a/panda/src/egg2pg/config_egg2pg.cxx +++ b/panda/src/egg2pg/config_egg2pg.cxx @@ -129,7 +129,11 @@ ConfigVariableBool egg_suppress_hidden ConfigVariableEnum 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 that involves a non-unity alpha, " + "or because of a four-channel texture.")); ConfigureFn(config_egg2pg) { init_libegg2pg(); diff --git a/panda/src/egg2pg/eggRenderState.cxx b/panda/src/egg2pg/eggRenderState.cxx index 9e2ca3c5c5..1b9b65bf50 100644 --- a/panda/src/egg2pg/eggRenderState.cxx +++ b/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; } }