Added support for computing bounds of text.

This commit is contained in:
Robert Osfield 2003-03-03 09:37:02 +00:00
parent fbe674b321
commit e2b95c50a4
3 changed files with 91 additions and 52 deletions

View File

@ -200,10 +200,16 @@ protected:
// iternal map used for rendering. Set up by the computeGlyphRepresentation() method.
TextureGlyphQuadMap _textureGlyphQuadMap;
mutable osg::BoundingBox _textBB;
void computeGlyphRepresentation();
// internal caches of the positioning of the text.
osg::Matrix _matrix;
osg::Vec3 _offset;
mutable osg::BoundingBox _textBB;
void computePositions();
};
}

View File

@ -70,10 +70,10 @@ void Font::addGlyph(unsigned int charcode, Glyph* glyph)
// reserve enough space for the glyphs.
glyphTexture->setTextureSize(256,256);
//glyphTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
glyphTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR);
glyphTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
//glyphTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR);
//glyphTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST);
//glyphTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
glyphTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
glyphTexture->setMaxAnisotropy(8);
_glyphTextureList.push_back(glyphTexture);
@ -202,7 +202,7 @@ void Font::GlyphTexture::apply(osg::State& state) const
applyTexParameters(GL_TEXTURE_2D,state);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
//glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
// allocate the texture memory.
glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
@ -221,7 +221,7 @@ void Font::GlyphTexture::apply(osg::State& state) const
}
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
//glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
// now subload the glyphs that are outstanding for this graphics context.
GlyphList& glyphsWereSubloading = _glyphsToSubload[contextID];

View File

@ -114,21 +114,25 @@ void Text::setText(const wchar_t* text)
void Text::setPosition(const osg::Vec3& pos)
{
_position = pos;
computePositions();
}
void Text::setAlignment(AlignmentType alignment)
{
_alignment = alignment;
computePositions();
}
void Text::setAxisAlignment(AxisAlignment axis)
{
_axisAlignment = axis;
computePositions();
}
void Text::setRotation(const osg::Quat& quat)
{
_rotation = quat;
computePositions();
}
void Text::setLayout(Layout layout)
@ -145,10 +149,7 @@ void Text::setColor(const osg::Vec4& color)
bool Text::computeBound() const
{
_bbox.init();
_textBB.init();
osg::Matrix matrix;
matrix.makeTranslate(_position);
for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin();
titr!=_textureGlyphQuadMap.end();
@ -160,8 +161,7 @@ bool Text::computeBound() const
citr != glyphquad._coords.end();
++citr)
{
_textBB.expandBy(osg::Vec3(citr->x(),citr->y(),0.0f));
_bbox.expandBy(osg::Vec3(citr->x(),citr->y(),0.0f)*matrix);
_bbox.expandBy(osg::Vec3(citr->x(),citr->y(),0.0f)*_matrix);
}
}
@ -276,65 +276,98 @@ void Text::computeGlyphRepresentation()
previous_charcode = charcode;
}
_textBB.init();
for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin();
titr!=_textureGlyphQuadMap.end();
++titr)
{
const GlyphQuads& glyphquad = titr->second;
for(GlyphQuads::Coords::const_iterator citr = glyphquad._coords.begin();
citr != glyphquad._coords.end();
++citr)
{
_textBB.expandBy(osg::Vec3(citr->x(),citr->y(),0.0f));
}
}
if (!_textureGlyphQuadMap.empty())
{
setStateSet(const_cast<osg::StateSet*>((*_textureGlyphQuadMap.begin()).first.get()));
}
computePositions();
}
void Text::computePositions()
{
switch(_alignment)
{
case LEFT_TOP: _offset.set(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()); break;
case LEFT_CENTER: _offset.set(_textBB.xMin(),(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin()); break;
case LEFT_BOTTOM: _offset.set(_textBB.xMin(),_textBB.yMin(),_textBB.zMin()); break;
case CENTER_TOP: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,_textBB.yMax(),_textBB.zMin()); break;
case CENTER_CENTER: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin()); break;
case CENTER_BOTTOM: _offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,_textBB.yMin(),_textBB.zMin()); break;
case RIGHT_TOP: _offset.set(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()); break;
case RIGHT_CENTER: _offset.set(_textBB.xMax(),(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin()); break;
case RIGHT_BOTTOM: _offset.set(_textBB.xMax(),_textBB.yMin(),_textBB.zMin()); break;
case BASE_LINE: _offset.set(0.0f,0.0f,0.0f); break;
}
_matrix.makeTranslate(_position-_offset);
switch(_axisAlignment)
{
case XZ_PLANE: _matrix.preMult(osg::Matrix::rotate(osg::inDegrees(90.0f),1.0f,0.0f,0.0f)); break;
case YZ_PLANE: _matrix.preMult(osg::Matrix::rotate(osg::inDegrees(90.0f),1.0f,0.0f,0.0f)*osg::Matrix::rotate(osg::inDegrees(90.0f),0.0f,0.0f,1.0f)); break;
case XY_PLANE: break; // nop - already on XY plane.
case SCREEN: break; // nop - need to account for rotation in draw as it depends on ModelView _matrix.
}
if (_axisAlignment!=SCREEN && !_rotation.zeroRotation())
{
osg::Matrix matrix;
_rotation.get(matrix);
_matrix.preMult(matrix);
}
dirtyBound();
}
void Text::drawImplementation(osg::State& state) const
{
osg::Vec3 offset;
switch(_alignment)
{
case LEFT_TOP: offset.set(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()); break;
case LEFT_CENTER: offset.set(_textBB.xMin(),(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin()); break;
case LEFT_BOTTOM: offset.set(_textBB.xMin(),_textBB.yMin(),_textBB.zMin()); break;
case CENTER_TOP: offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,_textBB.yMax(),_textBB.zMin()); break;
case CENTER_CENTER: offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin()); break;
case CENTER_BOTTOM: offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,_textBB.yMin(),_textBB.zMin()); break;
case RIGHT_TOP: offset.set(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()); break;
case RIGHT_CENTER: offset.set(_textBB.xMax(),(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin()); break;
case RIGHT_BOTTOM: offset.set(_textBB.xMax(),_textBB.yMin(),_textBB.zMin()); break;
case BASE_LINE: offset.set(0.0f,0.0f,0.0f);
}
glPushMatrix();
glTranslatef(_position.x(),_position.y(),_position.z());
glTranslatef(-offset.x(),-offset.y(),-offset.z());
switch(_axisAlignment)
// draw part.
glMultMatrixf(_matrix.ptr());
if (_axisAlignment==SCREEN)
{
case XZ_PLANE: glRotatef(90.0f,1.0f,0.0f,0.0f); break;
case YZ_PLANE: glRotatef(90.0f,0.0f,0.0f,1.0f); glRotatef(90.0f,1.0f,0.0f,0.0f); break;
case XY_PLANE: break; // nop - already on XY plane.
case SCREEN:
osg::Matrix mv = state.getModelViewMatrix();
mv.setTrans(0.0f,0.0f,0.0f);
osg::Matrix mat3x3;
mat3x3.invert(mv);
glMultMatrixf(mat3x3.ptr());
if (!_rotation.zeroRotation())
{
osg::Matrix mv = state.getModelViewMatrix();
mv.setTrans(0.0f,0.0f,0.0f);
osg::Matrix mat3x3;
mat3x3.invert(mv);
glMultMatrixf(mat3x3.ptr());
osg::Matrix matrix;
_rotation.get(matrix);
glMultMatrixf(matrix.ptr());
}
break;
}
}
if (!_rotation.zeroRotation())
{
osg::Matrix matrix;
_rotation.get(matrix);
glMultMatrixf(matrix.ptr());
}
glNormal3f(0.0f,0.0,1.0f);
glColor4fv(_color.ptr());
@ -386,7 +419,7 @@ void Text::drawImplementation(osg::State& state) const
if (_drawMode & ALIGNMENT)
{
glColor4f(1.0f,0.0f,1.0f,1.0f);
glTranslatef(offset.x(),offset.y(),offset.z());
glTranslatef(_offset.x(),_offset.y(),_offset.z());
state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);