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...."
This commit is contained in:
Robert Osfield
2009-07-24 14:59:51 +00:00
parent 773ae51a45
commit 31a947fda6
4 changed files with 116 additions and 7 deletions

View File

@@ -370,6 +370,7 @@ protected:
void computeBackdropPositions(unsigned int contextID) const;
void computeBackdropBoundingBox() const;
void computeBoundingBoxMargin() const;
void computeColorGradients() const;
void computeColorGradientsOverall() const;

View File

@@ -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;

View File

@@ -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());

View File

@@ -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;