From 31a947fda6bee2197321d3711a958cb3f0fa6831 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 24 Jul 2009 14:59:51 +0000 Subject: [PATCH] From Terry Welsh, "Okay, here are the mods I wrote for drawing a filled bounding box behind osgText::Text. I made it so the box would get drawn using whichever BackdropImplementation was selected. However, I did not implement STENCIL_BUFFER. In that case it defaults to drawing the bounding box using POLYGON_OFFSET instead. Also made it so the BOUNDINGBOX and FILLEDBOUNDINGBOX are drawn with a settable color and margin size. While I was at it I tightened up the values applied with DEPTH_RANGE and POLYGON_OFFSET, not just for drawing the bounding box but also for drawing backdrop text (these values must be coupled since the bounding box has to be drawn deeper in Z than the backdrop text). The values in use before seemed like overkill and I was seeing some z-clipping with my background scenery in the case of DEPTH_RANGE. If there was a good reason for the large values please let me know...." --- include/osgText/Text | 1 + include/osgText/TextBase | 17 ++++++-- src/osgText/Text.cpp | 91 ++++++++++++++++++++++++++++++++++++++-- src/osgText/TextBase.cpp | 14 +++++++ 4 files changed, 116 insertions(+), 7 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index dca04fb3b..420b44e75 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -370,6 +370,7 @@ protected: void computeBackdropPositions(unsigned int contextID) const; void computeBackdropBoundingBox() const; + void computeBoundingBoxMargin() const; void computeColorGradients() const; void computeColorGradientsOverall() const; diff --git a/include/osgText/TextBase b/include/osgText/TextBase index f8e25cb12..ded2b0683 100644 --- a/include/osgText/TextBase +++ b/include/osgText/TextBase @@ -194,15 +194,24 @@ public: enum DrawModeMask { - TEXT = 1, /// default - BOUNDINGBOX = 2, - ALIGNMENT = 4 + TEXT = 1, /// default + BOUNDINGBOX = 2, + FILLEDBOUNDINGBOX = 4, + ALIGNMENT = 8 }; void setDrawMode(unsigned int mode); unsigned int getDrawMode() const { return _drawMode; } + void setBoundingBoxMargin(float margin); + + float getBoundingBoxMargin() const { return _textBBMargin; } + + void setBoundingBoxColor(const osg::Vec4& color){ _textBBColor = color; } + + const osg::Vec4& getBoundingBoxColor() const { return _textBBColor; } + void setKerningType(KerningType kerningType) { _kerningType = kerningType; } @@ -255,6 +264,8 @@ protected: bool _autoRotateToScreen; Layout _layout; unsigned int _drawMode; + float _textBBMargin; + osg::Vec4 _textBBColor; KerningType _kerningType; unsigned int _lineCount; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index b9d56fcaf..d86cd4c48 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -542,6 +542,7 @@ void Text::computeGlyphRepresentation() TextBase::computePositions(); computeBackdropBoundingBox(); + computeBoundingBoxMargin(); computeColorGradients(); } @@ -1022,6 +1023,21 @@ void Text::computeBackdropBoundingBox() const } } +// This method expands the bounding box to a settable margin when a bounding box drawing mode is active. +void Text::computeBoundingBoxMargin() const +{ + if(_drawMode & (BOUNDINGBOX | FILLEDBOUNDINGBOX)){ + _textBB.set( + _textBB.xMin() - _textBBMargin, + _textBB.yMin() - _textBBMargin, + _textBB.zMin(), + _textBB.xMax() + _textBBMargin, + _textBB.yMax() + _textBBMargin, + _textBB.zMax() + ); + } +} + void Text::computeColorGradients() const { switch(_colorGradientMode) @@ -1331,6 +1347,73 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie glNormal3fv(_normal.ptr()); + if (_drawMode & FILLEDBOUNDINGBOX) + { + + if (_textBB.valid()) + { + state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF); + + const osg::Matrix& matrix = _autoTransformCache[contextID]._matrix; + + osg::Vec3 c00(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*matrix); + osg::Vec3 c10(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*matrix); + osg::Vec3 c11(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*matrix); + osg::Vec3 c01(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*matrix); + + switch(_backdropImplementation) + { + case NO_DEPTH_BUFFER: + // Do nothing. The bounding box will be rendered before the text and that's all that matters. + break; + case DEPTH_RANGE: + glPushAttrib(GL_DEPTH_BUFFER_BIT); + //unsigned int backdrop_index = 0; + //unsigned int max_backdrop_index = 8; + //const double offset = double(max_backdrop_index - backdrop_index) * 0.003; + glDepthRange(0.001, 1.001); + break; + /*case STENCIL_BUFFER: + break;*/ + default: + glPushAttrib(GL_POLYGON_OFFSET_FILL); + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0.1f * osg::PolygonOffset::getFactorMultiplier(), 10.0f * osg::PolygonOffset::getUnitsMultiplier() ); + } + + glColor4f(colorMultiplier.r()*_textBBColor.r(),colorMultiplier.g()*_textBBColor.g(),colorMultiplier.b()*_textBBColor.b(),colorMultiplier.a()*_textBBColor.a()); + glBegin(GL_QUADS); + glVertex3fv(c00.ptr()); + glVertex3fv(c10.ptr()); + glVertex3fv(c11.ptr()); + glVertex3fv(c01.ptr()); + glEnd(); + + switch(_backdropImplementation) + { + case NO_DEPTH_BUFFER: + // Do nothing. + break; + case DEPTH_RANGE: + glDepthRange(0.0, 1.0); + glPopAttrib(); + break; + /*case STENCIL_BUFFER: + break;*/ + default: + glDisable(GL_POLYGON_OFFSET_FILL); + glPopAttrib(); + } + } + } + +#if 1 + state.applyTextureMode(0,GL_TEXTURE_2D,true); +#else + state.applyTextureMode(0,GL_TEXTURE_2D,false); +#endif + state.applyTextureAttribute(0,getActiveFont()->getTexEnv()); + if (_drawMode & TEXT) { @@ -1382,7 +1465,7 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie osg::Vec3 c01(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*matrix); - glColor4fv(colorMultiplier.ptr()); + glColor4f(colorMultiplier.r()*_textBBColor.r(),colorMultiplier.g()*_textBBColor.g(),colorMultiplier.b()*_textBBColor.b(),colorMultiplier.a()*_textBBColor.a()); glBegin(GL_LINE_LOOP); glVertex3fv(c00.ptr()); glVertex3fv(c10.ptr()); @@ -1390,7 +1473,7 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie glVertex3fv(c01.ptr()); glEnd(); } - } + } if (_drawMode & ALIGNMENT) { @@ -1805,7 +1888,7 @@ void Text::renderWithPolygonOffset(osg::State& state, const osg::Vec4& colorMult { state.setVertexPointer( 3, GL_FLOAT, 0, &(transformedBackdropCoords.front())); glPolygonOffset(0.1f * osg::PolygonOffset::getFactorMultiplier(), - 2.0f * osg::PolygonOffset::getUnitsMultiplier() * (max_backdrop_index-backdrop_index) ); + osg::PolygonOffset::getUnitsMultiplier() * (max_backdrop_index-backdrop_index) ); glDrawArrays(GL_QUADS,0,transformedBackdropCoords.size()); } } @@ -1911,7 +1994,7 @@ void Text::renderWithDepthRange(osg::State& state, const osg::Vec4& colorMultipl if (!transformedBackdropCoords.empty()) { state.setVertexPointer( 3, GL_FLOAT, 0, &(transformedBackdropCoords.front())); - double offset = double(max_backdrop_index-backdrop_index)*0.003; + double offset = double(max_backdrop_index-backdrop_index)*0.0001; glDepthRange( offset, 1.0+offset); glDrawArrays(GL_QUADS,0,transformedBackdropCoords.size()); diff --git a/src/osgText/TextBase.cpp b/src/osgText/TextBase.cpp index 3237beeac..91bcc4402 100644 --- a/src/osgText/TextBase.cpp +++ b/src/osgText/TextBase.cpp @@ -44,6 +44,8 @@ TextBase::TextBase(): _autoRotateToScreen(false), _layout(LEFT_TO_RIGHT), _drawMode(TEXT), + _textBBMargin(0.0f), + _textBBColor(0.0, 0.0, 0.0, 0.5), _kerningType(KERNING_DEFAULT), _lineCount(0) { @@ -69,6 +71,8 @@ TextBase::TextBase(const TextBase& textBase,const osg::CopyOp& copyop): _autoRotateToScreen(textBase._autoRotateToScreen), _layout(textBase._layout), _drawMode(textBase._drawMode), + _textBBMargin(textBase._textBBMargin), + _textBBColor(textBase._textBBColor), _kerningType(textBase._kerningType), _lineCount(textBase._lineCount) { @@ -225,6 +229,16 @@ void TextBase::setDrawMode(unsigned int mode) } +void TextBase::setBoundingBoxMargin(float margin) +{ + if (_textBBMargin == margin) + return; + + _textBBMargin = margin; + computeGlyphRepresentation(); +} + + osg::BoundingBox TextBase::computeBound() const { osg::BoundingBox bbox;