diff --git a/include/osgText/Text3D b/include/osgText/Text3D index eb5a59df3..21f10de92 100644 --- a/include/osgText/Text3D +++ b/include/osgText/Text3D @@ -23,128 +23,132 @@ namespace osgText { class OSGTEXT_EXPORT Text3D : public osgText::TextBase { -public: + public: - /** Reder mode used to render the Text. - * PER_FACE : render all front face with the default StateSet - * all wall face with the wall StateSet - * all back face with the back StateSet (back face of the character, no the OpenGL back face) - * - * PER_GLYPH : render all Charactere with the default StateSet - */ - enum RenderMode - { - PER_FACE, - PER_GLYPH - }; + /** Reder mode used to render the Text. + * PER_FACE : render all front face with the default StateSet + * all wall face with the wall StateSet + * all back face with the back StateSet (back face of the character, no the OpenGL back face) + * + * PER_GLYPH : render all Charactere with the default StateSet + */ + enum RenderMode + { + PER_FACE, + PER_GLYPH + }; - Text3D(); - Text3D(const Text3D& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + Text3D(); + Text3D(const Text3D& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); - META_Object(osgText,Text3D) + META_Object(osgText,Text3D) - /** Get the Charactere Depth of text. */ - float getCharacterDepth() const; + /** Get the Charactere Depth of text. */ + float getCharacterDepth() const; - /** Set the Charactere Depth of text. */ - void setCharacterDepth(float characterDepth); + /** Set the Charactere Depth of text. */ + void setCharacterDepth(float characterDepth); - /** Get the render mode used to render the text. */ - RenderMode getRenderMode() const { return _renderMode; } - /** Set the render mode used to render the text. */ - void setRenderMode(RenderMode renderMode) { _renderMode = renderMode; computeGlyphRepresentation(); } + /** Get the render mode used to render the text. */ + RenderMode getRenderMode() const { return _renderMode; } + /** Set the render mode used to render the text. */ + void setRenderMode(RenderMode renderMode) { _renderMode = renderMode; computeGlyphRepresentation(); } -// /** Get the wall StateSet */ -// osg::StateSet * getWallStateSet() { return _wallStateSet.get(); } -// /** Get or create the wall StateSet */ -// osg::StateSet * getOrCreateWallStateSet() -// { -// if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet; -// return _wallStateSet.get(); -// } -// /** Set the wall StateSet */ -// void setWallStateSet(osg::StateSet * wallStateSet) { _wallStateSet = wallStateSet; } -// -// /** Get the back StateSet */ -// osg::StateSet * getBackStateSet() { return _backStateSet.get(); } -// /** Get or create the back StateSet */ -// osg::StateSet * getOrCreateBackStateSet() { if (_backStateSet.valid() == false) _backStateSet = new osg::StateSet; return _backStateSet.get(); } -// /** Set the back StateSet */ -// void setBackStateSet(osg::StateSet * backStateSet) { _backStateSet = backStateSet; } -// + + /** Get the wall StateSet */ + osg::StateSet* getWallStateSet() { return _wallStateSet.get(); } + /** Get the wall StateSet */ + const osg::StateSet* getWallStateSet() const { return _wallStateSet.get(); } + /** Get or create the wall StateSet */ + osg::StateSet* getOrCreateWallStateSet() + { + if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet; + return _wallStateSet.get(); + } + /** Set the wall StateSet */ + void setWallStateSet(osg::StateSet* wallStateSet) { _wallStateSet = wallStateSet; } + + /** Get the back StateSet */ + osg::StateSet* getBackStateSet() { return _backStateSet.get(); } + /** Get the back StateSet */ + osg::StateSet* getBackStateSet() const { return _backStateSet.get(); } + /** Get or create the back StateSet */ + osg::StateSet* getOrCreateBackStateSet() { if (_backStateSet.valid() == false) _backStateSet = new osg::StateSet; return _backStateSet.get(); } + /** Set the back StateSet */ + void setBackStateSet(osg::StateSet* backStateSet) { _backStateSet = backStateSet; } - /** Draw the text.*/ - virtual void drawImplementation(osg::RenderInfo& renderInfo) const; + /** Draw the text.*/ + virtual void drawImplementation(osg::RenderInfo& renderInfo) const; - /** return false, osgText::Text does not support accept(AttributeFunctor&).*/ - virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; } + /** return false, osgText::Text does not support accept(AttributeFunctor&).*/ + virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; } - /** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/ - virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return false; } + /** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/ + virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return false; } - /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ - virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const; + /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ + virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const; - /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/ - virtual bool supports(const osg::PrimitiveFunctor&) const { return false; } + /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/ + virtual bool supports(const osg::PrimitiveFunctor&) const { return false; } - /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ - virtual void accept(osg::PrimitiveFunctor& pf) const; + /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ + virtual void accept(osg::PrimitiveFunctor& pf) const; - /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ - virtual void setThreadSafeRefUnref(bool threadSafe); + /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ + virtual void setThreadSafeRefUnref(bool threadSafe); - /** Resize any per context GLObject buffers to specified size. */ - virtual void resizeGLObjectBuffers(unsigned int maxSize); + /** Resize any per context GLObject buffers to specified size. */ + virtual void resizeGLObjectBuffers(unsigned int maxSize); - /** If State is non-zero, this function releases OpenGL objects for - * the specified graphics context. Otherwise, releases OpenGL objexts - * for all graphics contexts. */ - virtual void releaseGLObjects(osg::State* state=0) const; + /** If State is non-zero, this function releases OpenGL objects for + * the specified graphics context. Otherwise, releases OpenGL objexts + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* state=0) const; -// // make Font a friend to allow it set the _font to 0 if the font is -// // forcefully unloaded. - friend class Font; + // // make Font a friend to allow it set the _font to 0 if the font is + // // forcefully unloaded. + friend class Font; - virtual osg::BoundingBox computeBound() const; + virtual osg::BoundingBox computeBound() const; -protected: + protected: - virtual ~Text3D() {} + virtual ~Text3D() {} - void renderPerGlyph(osg::State & state) const; - void renderPerFace(osg::State & state) const; + void renderPerGlyph(osg::State & state) const; + void renderPerFace(osg::State & state) const; - String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last); + String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last); - void computeGlyphRepresentation(); - void computePositions(unsigned int contextID) const; + void computeGlyphRepresentation(); + void computePositions(unsigned int contextID) const; - // ** glyph and other information to render the glyph - struct GlyphRenderInfo - { - GlyphRenderInfo(GlyphGeometry* glyphGeometry, osg::Vec3 & pos): - _glyphGeometry(glyphGeometry), - _position(pos) {} + // ** glyph and other information to render the glyph + struct GlyphRenderInfo + { + GlyphRenderInfo(GlyphGeometry* glyphGeometry, osg::Vec3 & pos): + _glyphGeometry(glyphGeometry), + _position(pos) {} - osg::ref_ptr _glyphGeometry; - osg::Vec3 _position; - }; + osg::ref_ptr _glyphGeometry; + osg::Vec3 _position; + }; - typedef std::vector LineRenderInfo; - typedef std::vector TextRenderInfo; + typedef std::vector LineRenderInfo; + typedef std::vector TextRenderInfo; - TextRenderInfo _textRenderInfo; + TextRenderInfo _textRenderInfo; - RenderMode _renderMode; + RenderMode _renderMode; - osg::ref_ptr _wallStateSet; - osg::ref_ptr _backStateSet; + osg::ref_ptr _wallStateSet; + osg::ref_ptr _backStateSet; }; } diff --git a/src/osgText/Text3D.cpp b/src/osgText/Text3D.cpp index 3e784cc40..a4ae86666 100644 --- a/src/osgText/Text3D.cpp +++ b/src/osgText/Text3D.cpp @@ -584,6 +584,17 @@ void Text3D::renderPerGlyph(osg::State & state) const { osg::Matrix original_modelview = state.getModelViewMatrix(); + const osg::StateSet* frontStateSet = getStateSet(); + const osg::StateSet* wallStateSet = getWallStateSet(); + const osg::StateSet* backStateSet = getBackStateSet(); + bool applyMainColor = false; + + if (wallStateSet==0) wallStateSet = frontStateSet; + else if (wallStateSet->getAttribute(osg::StateAttribute::MATERIAL)!=0) applyMainColor = true; + + if (backStateSet==0) backStateSet = frontStateSet; + else if (backStateSet->getAttribute(osg::StateAttribute::MATERIAL)!=0) applyMainColor = true; + // ** for each line, do ... TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) @@ -605,6 +616,11 @@ void Text3D::renderPerGlyph(osg::State & state) const state.applyDisablingOfVertexAttributes(); + if (frontStateSet!=backStateSet) + { + state.apply(frontStateSet); + if (applyMainColor) state.Color(_color.r(),_color.g(),_color.b(),_color.a()); + } osg::Geometry::PrimitiveSetList & pslFront = it->_glyphGeometry->getFrontPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr) @@ -612,6 +628,8 @@ void Text3D::renderPerGlyph(osg::State & state) const (*itr)->draw(state, false); } + if (wallStateSet!=frontStateSet) state.apply(wallStateSet); + // ** render the wall face of the glyph osg::Geometry::PrimitiveSetList & pslWall = it->_glyphGeometry->getWallPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr) @@ -619,6 +637,12 @@ void Text3D::renderPerGlyph(osg::State & state) const (*itr)->draw(state, false); } + if (backStateSet!=wallStateSet) + { + state.apply(backStateSet); + if (applyMainColor) state.Color(_color.r(),_color.g(),_color.b(),_color.a()); + } + osg::Geometry::PrimitiveSetList & pslBack = it->_glyphGeometry->getBackPrimitiveSetList(); for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr) { @@ -636,6 +660,18 @@ void Text3D::renderPerFace(osg::State & state) const state.Normal(0.0f,0.0f,1.0f); #endif + const osg::StateSet* frontStateSet = getStateSet(); + const osg::StateSet* wallStateSet = getWallStateSet(); + const osg::StateSet* backStateSet = getBackStateSet(); + bool applyMainColor = false; + + if (wallStateSet==0) wallStateSet = frontStateSet; + else if (wallStateSet->getAttribute(osg::StateAttribute::MATERIAL)!=0) applyMainColor = true; + + if (backStateSet==0) backStateSet = frontStateSet; + else if (backStateSet->getAttribute(osg::StateAttribute::MATERIAL)!=0) applyMainColor = true; + + TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) { @@ -659,6 +695,7 @@ void Text3D::renderPerFace(osg::State & state) const } } + if (wallStateSet!=frontStateSet) state.apply(wallStateSet); // ** render all wall face of the text for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) @@ -687,6 +724,13 @@ void Text3D::renderPerFace(osg::State & state) const // ** render all back face of the text state.Normal(0.0f,0.0f,-1.0f); #endif + + if (backStateSet!=wallStateSet) + { + state.apply(backStateSet); + if (applyMainColor) state.Color(_color.r(),_color.g(),_color.b(),_color.a()); + } + for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) { // ** for each glyph in the line, do ...