diff --git a/panda/src/text/textNode.I b/panda/src/text/textNode.I index fe3c371fd3..7256096f06 100644 --- a/panda/src/text/textNode.I +++ b/panda/src/text/textNode.I @@ -486,6 +486,23 @@ set_card_actual(float left, float right, float bottom, float top) { invalidate_no_measure(); } +//////////////////////////////////////////////////////////////////// +// Function: TextNode::set_card_decal +// Access: Published +// Description: Sets the card_decal flag. When this is true, the +// text is decalled onto the card, which is necessary if +// the TextNode is to be rendered in the 3-d world +// without putting it in a bin. +//////////////////////////////////////////////////////////////////// +INLINE void TextNode:: +set_card_decal(bool card_decal) { + if (card_decal) { + _flags |= F_card_decal; + } else { + _flags &= ~F_card_decal; + } +} + //////////////////////////////////////////////////////////////////// // Function: TextNode::clear_card // Access: Published @@ -508,6 +525,16 @@ has_card() const { return (_flags & F_has_card) != 0; } +//////////////////////////////////////////////////////////////////// +// Function: TextNode::get_card_decal +// Access: Published +// Description: Returns the card_decal flag. See set_card_decal(). +//////////////////////////////////////////////////////////////////// +INLINE bool TextNode:: +get_card_decal() const { + return (_flags & F_card_decal) != 0; +} + //////////////////////////////////////////////////////////////////// // Function: TextNode::is_card_as_margin // Access: Published @@ -637,6 +664,33 @@ get_coordinate_system() const { return _coordinate_system; } +//////////////////////////////////////////////////////////////////// +// Function: TextNode::set_usage_hint +// Access: Published +// Description: Specifies the UsageHint that will be applied to +// generated geometry. The default is UH_static, which +// is probably the right setting, but if you know the +// TextNode's geometry will have a short lifespan, it +// may be better to set it to UH_stream. See +// geomEnums.h. +//////////////////////////////////////////////////////////////////// +INLINE void TextNode:: +set_usage_hint(qpGeom::UsageHint usage_hint) { + _assembler.set_usage_hint(usage_hint); + invalidate_no_measure(); +} + +//////////////////////////////////////////////////////////////////// +// Function: TextNode::get_usage_hint +// Access: Published +// Description: Returns the UsageHint that will be applied to +// generated geometry. See set_usage_hint(). +//////////////////////////////////////////////////////////////////// +INLINE qpGeom::UsageHint TextNode:: +get_usage_hint() const { + return _assembler.get_usage_hint(); +} + //////////////////////////////////////////////////////////////////// // Function: TextNode::set_font // Access: Published @@ -1058,33 +1112,6 @@ clear_glyph_shift() { invalidate_with_measure(); } -//////////////////////////////////////////////////////////////////// -// Function: TextNode::set_usage_hint -// Access: Published -// Description: Specifies the UsageHint that will be applied to -// generated geometry. The default is UH_static, which -// is probably the right setting, but if you know the -// TextNode's geometry will have a short lifespan, it -// may be better to set it to UH_stream. See -// geomEnums.h. -//////////////////////////////////////////////////////////////////// -INLINE void TextNode:: -set_usage_hint(qpGeom::UsageHint usage_hint) { - _assembler.set_usage_hint(usage_hint); - invalidate_no_measure(); -} - -//////////////////////////////////////////////////////////////////// -// Function: TextNode::get_usage_hint -// Access: Published -// Description: Returns the UsageHint that will be applied to -// generated geometry. See set_usage_hint(). -//////////////////////////////////////////////////////////////////// -INLINE qpGeom::UsageHint TextNode:: -get_usage_hint() const { - return _assembler.get_usage_hint(); -} - //////////////////////////////////////////////////////////////////// // Function: TextNode::set_text diff --git a/panda/src/text/textNode.cxx b/panda/src/text/textNode.cxx index 45668c9b3e..53c15b63b1 100644 --- a/panda/src/text/textNode.cxx +++ b/panda/src/text/textNode.cxx @@ -48,6 +48,7 @@ #include "accumulatedAttribs.h" #include "renderState.h" #include "renderModeAttrib.h" +#include "decalEffect.h" #include "dcast.h" #include "bamFile.h" #include "zStream.h" @@ -247,7 +248,8 @@ generate() { LMatrix4f::convert_mat(CS_zup_right, _coordinate_system) * _transform; - root->set_transform(TransformState::make_mat(mat)); + CPT(TransformState) transform = TransformState::make_mat(mat); + root->set_transform(transform); wstring wtext = get_wtext(); @@ -282,29 +284,26 @@ generate() { // Incidentally, that means we don't need to measure the text now. _flags &= ~F_needs_measure; + // Now flatten our hierarchy to get rid of the transforms we put in, + // applying them to the vertices. + + if (text_flatten) { + SceneGraphReducer gr; + gr.apply_attribs(root); + gr.flatten(root, ~SceneGraphReducer::CS_within_radius); + gr.collect_vertex_data(root); + gr.unify(root); + } // Now deal with the decorations. - if (has_frame()) { - PT(PandaNode) frame_root = make_frame(); - root->add_child(frame_root, get_draw_order() + 1); - frame_root->set_attrib(ColorAttrib::make_flat(get_frame_color())); - if (get_frame_color()[3] != 1.0f) { - frame_root->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha)); - } - - if (has_bin()) { - frame_root->set_attrib(CullBinAttrib::make(get_bin(), get_draw_order() + 1)); - } - } - if (has_card()) { PT(PandaNode) card_root; if (has_card_border()) card_root = make_card_with_border(); else card_root = make_card(); - root->add_child(card_root, get_draw_order()); + card_root->set_transform(transform); card_root->set_attrib(ColorAttrib::make_flat(get_card_color())); if (get_card_color()[3] != 1.0f) { card_root->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha)); @@ -316,17 +315,36 @@ generate() { if (has_bin()) { card_root->set_attrib(CullBinAttrib::make(get_bin(), get_draw_order())); } + + // We always apply attribs down to the card vertices. + SceneGraphReducer gr; + gr.apply_attribs(card_root); + + // In order to decal the text onto the card, the card must + // become the parent of the text. + card_root->add_child(root); + root = card_root; + + if (get_card_decal()) { + card_root->set_effect(DecalEffect::make()); + } } - // Now flatten our hierarchy to get rid of the transforms we put in, - // applying them to the vertices. + if (has_frame()) { + PT(PandaNode) frame_root = make_frame(); + frame_root->set_transform(transform); + root->add_child(frame_root, get_draw_order() + 1); + frame_root->set_attrib(ColorAttrib::make_flat(get_frame_color())); + if (get_frame_color()[3] != 1.0f) { + frame_root->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha)); + } + + if (has_bin()) { + frame_root->set_attrib(CullBinAttrib::make(get_bin(), get_draw_order() + 1)); + } - if (text_flatten) { SceneGraphReducer gr; - gr.apply_attribs(root); - gr.flatten(root, ~SceneGraphReducer::CS_within_radius); - gr.collect_vertex_data(root); - gr.unify(root); + gr.apply_attribs(frame_root); } return root; diff --git a/panda/src/text/textNode.h b/panda/src/text/textNode.h index 84b6eea741..81fd82701b 100644 --- a/panda/src/text/textNode.h +++ b/panda/src/text/textNode.h @@ -105,8 +105,10 @@ PUBLISHED: float bottom, float top); INLINE void set_card_actual(float left, float right, float bottom, float top); + INLINE void set_card_decal(bool card_decal); INLINE void clear_card(); INLINE bool has_card() const; + INLINE bool get_card_decal() const; INLINE bool is_card_as_margin() const; INLINE LVecBase4f get_card_as_set() const; INLINE LVecBase4f get_card_actual() const; @@ -118,9 +120,12 @@ PUBLISHED: INLINE void set_coordinate_system(CoordinateSystem cs); INLINE CoordinateSystem get_coordinate_system() const; + INLINE void set_usage_hint(qpGeom::UsageHint usage_hint); + INLINE qpGeom::UsageHint get_usage_hint() const; + // These methods are inherited from TextProperties, but we override // here so we can flag the TextNode as dirty when they have been - // change. + // changed. INLINE void set_font(TextFont *font); INLINE void clear_font(); @@ -170,12 +175,9 @@ PUBLISHED: INLINE void set_glyph_shift(float glyph_shift); INLINE void clear_glyph_shift(); - INLINE void set_usage_hint(qpGeom::UsageHint usage_hint); - INLINE qpGeom::UsageHint get_usage_hint() const; - // These methods are inherited from TextEncoder, but we override // here so we can flag the TextNode as dirty when they have been - // change. + // changed. INLINE void set_text(const string &text); INLINE void set_text(const string &text, Encoding encoding); INLINE void clear_text(); @@ -268,6 +270,7 @@ private: F_needs_rebuild = 0x0100, F_needs_measure = 0x0200, F_has_overflow = 0x0400, + F_card_decal = 0x0800, }; int _flags;