Enabled the settng/getting of the Text3D's WallStateSet and BackStateSet along with use of these in the rendering implementation

to allow separate colour and other state to be assigned to the front, wall and back faces.
This commit is contained in:
Robert Osfield 2011-03-07 12:33:11 +00:00
parent afecdbb46b
commit 215fca84f7
2 changed files with 136 additions and 88 deletions

View File

@ -23,128 +23,132 @@ namespace osgText {
class OSGTEXT_EXPORT Text3D : public osgText::TextBase class OSGTEXT_EXPORT Text3D : public osgText::TextBase
{ {
public: public:
/** Reder mode used to render the Text. /** Reder mode used to render the Text.
* PER_FACE : render all front face with the default StateSet * PER_FACE : render all front face with the default StateSet
* all wall face with the wall 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) * 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 * PER_GLYPH : render all Charactere with the default StateSet
*/ */
enum RenderMode enum RenderMode
{ {
PER_FACE, PER_FACE,
PER_GLYPH PER_GLYPH
}; };
Text3D(); Text3D();
Text3D(const Text3D& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); 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. */ /** Get the Charactere Depth of text. */
float getCharacterDepth() const; float getCharacterDepth() const;
/** Set the Charactere Depth of text. */ /** Set the Charactere Depth of text. */
void setCharacterDepth(float characterDepth); void setCharacterDepth(float characterDepth);
/** Get the render mode used to render the text. */ /** Get the render mode used to render the text. */
RenderMode getRenderMode() const { return _renderMode; } RenderMode getRenderMode() const { return _renderMode; }
/** Set the render mode used to render the text. */ /** Set the render mode used to render the text. */
void setRenderMode(RenderMode renderMode) { _renderMode = renderMode; computeGlyphRepresentation(); } void setRenderMode(RenderMode renderMode) { _renderMode = renderMode; computeGlyphRepresentation(); }
// /** Get the wall StateSet */
// osg::StateSet * getWallStateSet() { return _wallStateSet.get(); } /** Get the wall StateSet */
// /** Get or create the wall StateSet */ osg::StateSet* getWallStateSet() { return _wallStateSet.get(); }
// osg::StateSet * getOrCreateWallStateSet() /** Get the wall StateSet */
// { const osg::StateSet* getWallStateSet() const { return _wallStateSet.get(); }
// if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet; /** Get or create the wall StateSet */
// return _wallStateSet.get(); osg::StateSet* getOrCreateWallStateSet()
// } {
// /** Set the wall StateSet */ if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet;
// void setWallStateSet(osg::StateSet * wallStateSet) { _wallStateSet = wallStateSet; } return _wallStateSet.get();
// }
// /** Get the back StateSet */ /** Set the wall StateSet */
// osg::StateSet * getBackStateSet() { return _backStateSet.get(); } void setWallStateSet(osg::StateSet* wallStateSet) { _wallStateSet = wallStateSet; }
// /** Get or create the back StateSet */
// osg::StateSet * getOrCreateBackStateSet() { if (_backStateSet.valid() == false) _backStateSet = new osg::StateSet; return _backStateSet.get(); } /** Get the back StateSet */
// /** Set the back StateSet */ osg::StateSet* getBackStateSet() { return _backStateSet.get(); }
// void setBackStateSet(osg::StateSet * backStateSet) { _backStateSet = backStateSet; } /** 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.*/ /** Draw the text.*/
virtual void drawImplementation(osg::RenderInfo& renderInfo) const; virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
/** return false, osgText::Text does not support accept(AttributeFunctor&).*/ /** return false, osgText::Text does not support accept(AttributeFunctor&).*/
virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; } virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; }
/** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/ /** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/
virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return false; } 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.*/ /** 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; virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const;
/** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/ /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/
virtual bool supports(const osg::PrimitiveFunctor&) const { return false; } 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.*/ /** 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; virtual void accept(osg::PrimitiveFunctor& pf) const;
/** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
virtual void setThreadSafeRefUnref(bool threadSafe); virtual void setThreadSafeRefUnref(bool threadSafe);
/** Resize any per context GLObject buffers to specified size. */ /** Resize any per context GLObject buffers to specified size. */
virtual void resizeGLObjectBuffers(unsigned int maxSize); virtual void resizeGLObjectBuffers(unsigned int maxSize);
/** If State is non-zero, this function releases OpenGL objects for /** If State is non-zero, this function releases OpenGL objects for
* the specified graphics context. Otherwise, releases OpenGL objexts * the specified graphics context. Otherwise, releases OpenGL objexts
* for all graphics contexts. */ * for all graphics contexts. */
virtual void releaseGLObjects(osg::State* state=0) const; virtual void releaseGLObjects(osg::State* state=0) const;
// // make Font a friend to allow it set the _font to 0 if the font is // // make Font a friend to allow it set the _font to 0 if the font is
// // forcefully unloaded. // // forcefully unloaded.
friend class Font; 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 renderPerGlyph(osg::State & state) const;
void renderPerFace(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 computeGlyphRepresentation();
void computePositions(unsigned int contextID) const; void computePositions(unsigned int contextID) const;
// ** glyph and other information to render the glyph // ** glyph and other information to render the glyph
struct GlyphRenderInfo struct GlyphRenderInfo
{ {
GlyphRenderInfo(GlyphGeometry* glyphGeometry, osg::Vec3 & pos): GlyphRenderInfo(GlyphGeometry* glyphGeometry, osg::Vec3 & pos):
_glyphGeometry(glyphGeometry), _glyphGeometry(glyphGeometry),
_position(pos) {} _position(pos) {}
osg::ref_ptr<GlyphGeometry> _glyphGeometry; osg::ref_ptr<GlyphGeometry> _glyphGeometry;
osg::Vec3 _position; osg::Vec3 _position;
}; };
typedef std::vector<GlyphRenderInfo> LineRenderInfo; typedef std::vector<GlyphRenderInfo> LineRenderInfo;
typedef std::vector<LineRenderInfo> TextRenderInfo; typedef std::vector<LineRenderInfo> TextRenderInfo;
TextRenderInfo _textRenderInfo; TextRenderInfo _textRenderInfo;
RenderMode _renderMode; RenderMode _renderMode;
osg::ref_ptr<osg::StateSet> _wallStateSet; osg::ref_ptr<osg::StateSet> _wallStateSet;
osg::ref_ptr<osg::StateSet> _backStateSet; osg::ref_ptr<osg::StateSet> _backStateSet;
}; };
} }

View File

@ -584,6 +584,17 @@ void Text3D::renderPerGlyph(osg::State & state) const
{ {
osg::Matrix original_modelview = state.getModelViewMatrix(); 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 ... // ** for each line, do ...
TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end(); TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
@ -605,6 +616,11 @@ void Text3D::renderPerGlyph(osg::State & state) const
state.applyDisablingOfVertexAttributes(); 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(); osg::Geometry::PrimitiveSetList & pslFront = it->_glyphGeometry->getFrontPrimitiveSetList();
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr) 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); (*itr)->draw(state, false);
} }
if (wallStateSet!=frontStateSet) state.apply(wallStateSet);
// ** render the wall face of the glyph // ** render the wall face of the glyph
osg::Geometry::PrimitiveSetList & pslWall = it->_glyphGeometry->getWallPrimitiveSetList(); osg::Geometry::PrimitiveSetList & pslWall = it->_glyphGeometry->getWallPrimitiveSetList();
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr) 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); (*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(); osg::Geometry::PrimitiveSetList & pslBack = it->_glyphGeometry->getBackPrimitiveSetList();
for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr) 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); state.Normal(0.0f,0.0f,1.0f);
#endif #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(); TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) 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 // ** render all wall face of the text
for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine) 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 // ** render all back face of the text
state.Normal(0.0f,0.0f,-1.0f); state.Normal(0.0f,0.0f,-1.0f);
#endif #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 (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
{ {
// ** for each glyph in the line, do ... // ** for each glyph in the line, do ...