From e2b95c50a46b88d31a054ae431c09ef53d8da698 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 3 Mar 2003 09:37:02 +0000 Subject: [PATCH] Added support for computing bounds of text. --- include/osgText/Text | 8 ++- src/osgText/Font.cpp | 10 ++-- src/osgText/Text.cpp | 125 +++++++++++++++++++++++++++---------------- 3 files changed, 91 insertions(+), 52 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index 021430fae..6b462e3e9 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -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(); + }; } diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index ac32ac94a..ddec5e9fe 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -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]; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 9cda714c7..cfc544e4c 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -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((*_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);