diff --git a/panda/src/gobj/textureStage.I b/panda/src/gobj/textureStage.I index a8768f1ad2..3e924c55f8 100755 --- a/panda/src/gobj/textureStage.I +++ b/panda/src/gobj/textureStage.I @@ -627,6 +627,18 @@ get_combine_alpha_operand2() const { return _combine_alpha_operand2; } +//////////////////////////////////////////////////////////////////// +// Function: TextureStage::involves_color_scale +// Access: Published +// Description: Returns true if the TextureStage is affected by the +// setting of the current ColorScaleAttrib, false +// otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool TextureStage:: +involves_color_scale() const { + return _involves_color_scale; +} + //////////////////////////////////////////////////////////////////// // Function: TextureStage::uses_color // Access: Published @@ -640,15 +652,25 @@ uses_color() const { } //////////////////////////////////////////////////////////////////// -// Function: TextureStage::involves_color_scale +// Function: TextureStage::uses_primary_color // Access: Published -// Description: Returns true if the TextureStage is affected by the -// setting of the current ColorScaleAttrib, false -// otherwise. +// Description: Returns true if the TextureStage makes use of +// the CS_primary_color combine source. //////////////////////////////////////////////////////////////////// INLINE bool TextureStage:: -involves_color_scale() const { - return _involves_color_scale; +uses_primary_color() const { + return _uses_primary_color; +} + +//////////////////////////////////////////////////////////////////// +// Function: TextureStage::uses_last_saved_result +// Access: Published +// Description: Returns true if the TextureStage makes use of +// the CS_primary_color combine source. +//////////////////////////////////////////////////////////////////// +INLINE bool TextureStage:: +uses_last_saved_result() const { + return _uses_last_saved_result; } //////////////////////////////////////////////////////////////////// @@ -684,7 +706,8 @@ get_sort_seq() { //////////////////////////////////////////////////////////////////// // Function: TextureStage::update_color_flags // Access: Private -// Description: Updates _uses_color and _involves_color_scale +// Description: Updates _uses_color, _involves_color_scale, +// _uses_primary_color and _uses_last_saved_result // appropriately. //////////////////////////////////////////////////////////////////// INLINE void TextureStage:: @@ -709,6 +732,24 @@ update_color_flags() { _combine_alpha_source0 == CS_constant || _combine_alpha_source1 == CS_constant || _combine_alpha_source2 == CS_constant))); + + _uses_primary_color = + (_mode == M_combine && + (_combine_rgb_source0 == CS_primary_color || + _combine_rgb_source1 == CS_primary_color || + _combine_rgb_source2 == CS_primary_color || + _combine_alpha_source0 == CS_primary_color || + _combine_alpha_source1 == CS_primary_color || + _combine_alpha_source2 == CS_primary_color)); + + _uses_last_saved_result = + (_mode == M_combine && + (_combine_rgb_source0 == CS_last_saved_result || + _combine_rgb_source1 == CS_last_saved_result || + _combine_rgb_source2 == CS_last_saved_result || + _combine_alpha_source0 == CS_last_saved_result || + _combine_alpha_source1 == CS_last_saved_result || + _combine_alpha_source2 == CS_last_saved_result)); } INLINE ostream & diff --git a/panda/src/gobj/textureStage.h b/panda/src/gobj/textureStage.h index 8a1ad79b9b..0daac24745 100644 --- a/panda/src/gobj/textureStage.h +++ b/panda/src/gobj/textureStage.h @@ -168,8 +168,10 @@ PUBLISHED: INLINE CombineSource get_combine_alpha_source2() const; INLINE CombineOperand get_combine_alpha_operand2() const; - INLINE bool uses_color() const; INLINE bool involves_color_scale() const; + INLINE bool uses_color() const; + INLINE bool uses_primary_color() const; + INLINE bool uses_last_saved_result() const; void write(ostream &out) const; void output(ostream &out) const; @@ -195,8 +197,10 @@ private: int _rgb_scale; int _alpha_scale; bool _saved_result; - bool _uses_color; bool _involves_color_scale; + bool _uses_color; + bool _uses_primary_color; + bool _uses_last_saved_result; CombineMode _combine_rgb_mode; int _num_combine_rgb_operands; diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index 89da0cbb9d..dc7b8e5125 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -1127,8 +1127,21 @@ synthesize_shader(const RenderState *rs) { } } - text << "\t float4 primary_color = result;\n"; + // Loop first to see if something is using primary_color or last_saved_result. bool have_saved_result = false; + for (int i=0; i<_num_textures; i++) { + TextureStage *stage = texture->get_on_stage(i); + if (stage->get_mode() != TextureStage::M_combine) continue; + if (stage->uses_primary_color()) { + text << "\t float4 primary_color = result;\n"; + } + if (stage->uses_last_saved_result()) { + text << "\t float4 last_saved_result = result;\n"; + have_saved_result = true; + } + } + + // Now loop through the textures to compose our magic blending formulas. for (int i=0; i<_num_textures; i++) { TextureStage *stage = texture->get_on_stage(i); switch (stage->get_mode()) { @@ -1167,13 +1180,8 @@ synthesize_shader(const RenderState *rs) { default: break; } - if (stage->get_saved_result()) { - if (have_saved_result) { - text << "\t last_saved_result = result;\n"; - } else { - text << "\t float4 last_saved_result = result;\n"; - have_saved_result = true; - } + if (stage->get_saved_result() && have_saved_result) { + text << "\t last_saved_result = result;\n"; } } // Apply the color scale. @@ -1265,35 +1273,35 @@ synthesize_shader(const RenderState *rs) { // Description: This 'synthesizes' a combine mode into a string. //////////////////////////////////////////////////////////////////// const string ShaderGenerator:: -combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode, bool single_value, short texindex) { +combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode, bool alpha, short texindex) { ostringstream text; switch (c_mode) { case TextureStage::CM_modulate: - text << combine_source_as_string(stage, 0, single_value, texindex); + text << combine_source_as_string(stage, 0, alpha, alpha, texindex); text << " * "; - text << combine_source_as_string(stage, 1, single_value, texindex); + text << combine_source_as_string(stage, 1, alpha, alpha, texindex); break; case TextureStage::CM_add: - text << combine_source_as_string(stage, 0, single_value, texindex); + text << combine_source_as_string(stage, 0, alpha, alpha, texindex); text << " + "; - text << combine_source_as_string(stage, 1, single_value, texindex); + text << combine_source_as_string(stage, 1, alpha, alpha, texindex); break; case TextureStage::CM_add_signed: pgraph_cat.error() << "TextureStage::CombineMode ADD_SIGNED not yet supported in per-pixel mode.\n"; break; case TextureStage::CM_interpolate: text << "lerp("; - text << combine_source_as_string(stage, 1, single_value, texindex); + text << combine_source_as_string(stage, 1, alpha, alpha, texindex); text << ", "; - text << combine_source_as_string(stage, 0, single_value, texindex); + text << combine_source_as_string(stage, 0, alpha, alpha, texindex); text << ", "; - text << combine_source_as_string(stage, 2, true, texindex); + text << combine_source_as_string(stage, 2, alpha, true, texindex); text << ")"; break; case TextureStage::CM_subtract: - text << combine_source_as_string(stage, 0, single_value, texindex); + text << combine_source_as_string(stage, 0, alpha, alpha, texindex); text << " + "; - text << combine_source_as_string(stage, 1, single_value, texindex); + text << combine_source_as_string(stage, 1, alpha, alpha, texindex); break; case TextureStage::CM_dot3_rgb: pgraph_cat.error() << "TextureStage::CombineMode DOT3_RGB not yet supported in per-pixel mode.\n"; @@ -1303,7 +1311,7 @@ combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode break; case TextureStage::CM_replace: default: // Not sure if this is correct as default value. - text << combine_source_as_string(stage, 0, single_value, texindex); + text << combine_source_as_string(stage, 0, alpha, alpha, texindex); break; } return text.str(); @@ -1315,22 +1323,39 @@ combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode // Description: This 'synthesizes' a combine source into a string. //////////////////////////////////////////////////////////////////// const string ShaderGenerator:: -combine_source_as_string(CPT(TextureStage) stage, short num, bool single_value, short texindex) { +combine_source_as_string(CPT(TextureStage) stage, short num, bool alpha, bool single_value, short texindex) { TextureStage::CombineSource c_src = TextureStage::CS_undefined; TextureStage::CombineOperand c_op = TextureStage::CO_undefined; - switch (num) { - case 0: - c_src = stage->get_combine_rgb_source0(); - c_op = stage->get_combine_rgb_operand0(); - break; - case 1: - c_src = stage->get_combine_rgb_source1(); - c_op = stage->get_combine_rgb_operand1(); - break; - case 2: - c_src = stage->get_combine_rgb_source2(); - c_op = stage->get_combine_rgb_operand2(); - break; + if (alpha) { + switch (num) { + case 0: + c_src = stage->get_combine_alpha_source0(); + c_op = stage->get_combine_alpha_operand0(); + break; + case 1: + c_src = stage->get_combine_alpha_source1(); + c_op = stage->get_combine_alpha_operand1(); + break; + case 2: + c_src = stage->get_combine_alpha_source2(); + c_op = stage->get_combine_alpha_operand2(); + break; + } + } else { + switch (num) { + case 0: + c_src = stage->get_combine_rgb_source0(); + c_op = stage->get_combine_rgb_operand0(); + break; + case 1: + c_src = stage->get_combine_rgb_source1(); + c_op = stage->get_combine_rgb_operand1(); + break; + case 2: + c_src = stage->get_combine_rgb_source2(); + c_op = stage->get_combine_rgb_operand2(); + break; + } } ostringstream csource; if (c_op == TextureStage::CO_one_minus_src_color || @@ -1368,7 +1393,7 @@ combine_source_as_string(CPT(TextureStage) stage, short num, bool single_value, } else { csource << ".a"; if (!single_value) { - // Dunno if it's legal at all, but let's just allow it. + // Dunno if it's legal in the FPP at all, but let's just allow it. return "float3(" + csource.str() + ")"; } } diff --git a/panda/src/pgraphnodes/shaderGenerator.h b/panda/src/pgraphnodes/shaderGenerator.h index 8351f07511..8d2ca7038d 100644 --- a/panda/src/pgraphnodes/shaderGenerator.h +++ b/panda/src/pgraphnodes/shaderGenerator.h @@ -73,9 +73,9 @@ protected: CPT(RenderAttrib) create_shader_attrib(const string &txt); PT(Texture) update_shadow_buffer(NodePath light_np); static const string combine_mode_as_string(CPT(TextureStage) stage, - TextureStage::CombineMode c_mode, bool single_value, short texindex); + TextureStage::CombineMode c_mode, bool alpha, short texindex); static const string combine_source_as_string(CPT(TextureStage) stage, - short num, bool single_value, short texindex); + short num, bool alpha, bool single_value, short texindex); static const string texture_type_as_string(Texture::TextureType ttype); // Shader register allocation: