diff --git a/examples/osgtext3D/GlyphGeometry.cpp b/examples/osgtext3D/GlyphGeometry.cpp index 516f581b9..0e3e84760 100644 --- a/examples/osgtext3D/GlyphGeometry.cpp +++ b/examples/osgtext3D/GlyphGeometry.cpp @@ -407,93 +407,6 @@ public: }; -///////////////////////////////////////////////////////////////////////////////////////// -// -// BevelProfile -// -BevelProfile::BevelProfile() -{ - flatBevel(); -} - -void BevelProfile::flatBevel(float width) -{ - _vertices.clear(); - - if (width>0.5f) width = 0.5f; - - _vertices.push_back(osg::Vec2(0.0f,0.0f)); - - _vertices.push_back(osg::Vec2(width,1.0f)); - - if (width<0.5f) _vertices.push_back(osg::Vec2(1-width,1.0f)); - - _vertices.push_back(osg::Vec2(1.0f,0.0f)); -} - -void BevelProfile::roundedBevel(float width, unsigned int numSteps) -{ - _vertices.clear(); - - if (width>0.5f) width = 0.5f; - - unsigned int i = 0; - for(; i<=numSteps; ++i) - { - float angle = float(osg::PI)*0.5f*(float(i)/float(numSteps)); - _vertices.push_back( osg::Vec2((1.0f-cosf(angle))*width, sinf(angle)) ); - } - - // start the second half one into the curve if the width is half way across - i = width<0.5f ? 0 : 1; - for(; i<=numSteps; ++i) - { - float angle = float(osg::PI)*0.5f*(float(numSteps-i)/float(numSteps)); - _vertices.push_back( osg::Vec2(1.0-(1.0f-cosf(angle))*width, sin(angle)) ); - } -} - -void BevelProfile::roundedBevel2(float width, unsigned int numSteps) -{ - _vertices.clear(); - - if (width>0.5f) width = 0.5f; - - float h = 0.1f; - float r = 1.0f-h; - - _vertices.push_back(osg::Vec2(0.0,0.0)); - - unsigned int i = 0; - for(; i<=numSteps; ++i) - { - float angle = float(osg::PI)*0.5f*(float(i)/float(numSteps)); - _vertices.push_back( osg::Vec2((1.0f-cosf(angle))*width, h + sinf(angle)*r) ); - } - - // start the second half one into the curve if the width is half way across - i = width<0.5f ? 0 : 1; - for(; i<=numSteps; ++i) - { - float angle = float(osg::PI)*0.5f*(float(numSteps-i)/float(numSteps)); - _vertices.push_back( osg::Vec2(1.0-(1.0f-cosf(angle))*width, h + sin(angle)*r) ); - } - - _vertices.push_back(osg::Vec2(1.0,0.0)); - -} - -void BevelProfile::print(std::ostream& fout) -{ - OSG_NOTICE<<"print bevel"<(glyphGeometry->getVertexArray()); if (!orig_vertices) @@ -698,7 +611,7 @@ osg::Geometry* computeTextGeometry(osg::Geometry* glyphGeometry, BevelProfile& p unsigned int no_vertices_on_boundary = bevel->size()/2; - osgText::BevelProfile::Vertices& profileVertices = profile.getVertices(); + const osgText::Bevel::Vertices& profileVertices = profile.getVertices(); unsigned int no_vertices_on_bevel = profileVertices.size(); Indices bevelIndices; @@ -781,7 +694,7 @@ osg::Geometry* computeTextGeometry(osg::Geometry* glyphGeometry, BevelProfile& p // // computeShellGeometry // -osg::Geometry* computeShellGeometry(osg::Geometry* glyphGeometry, BevelProfile& profile, float width) +osg::Geometry* computeShellGeometry(osg::Geometry* glyphGeometry, const osgText::Bevel& profile, float width) { osg::Vec3Array* orig_vertices = dynamic_cast(glyphGeometry->getVertexArray()); if (!orig_vertices) @@ -924,7 +837,7 @@ osg::Geometry* computeShellGeometry(osg::Geometry* glyphGeometry, BevelProfile& unsigned int no_vertices_on_boundary = bevel->size()/2; - osgText::BevelProfile::Vertices& profileVertices = profile.getVertices(); + const osgText::Bevel::Vertices& profileVertices = profile.getVertices(); unsigned int no_vertices_on_bevel = profileVertices.size(); Indices bevelIndices; diff --git a/examples/osgtext3D/GlyphGeometry.h b/examples/osgtext3D/GlyphGeometry.h index e45168d8e..70545d89a 100644 --- a/examples/osgtext3D/GlyphGeometry.h +++ b/examples/osgtext3D/GlyphGeometry.h @@ -15,38 +15,16 @@ #define OSGTEXT_GLYPHGEOMETRY 1 #include +#include "TextNode.h" namespace osgText { -class BevelProfile -{ - public: - - typedef std::vector Vertices; - - BevelProfile(); - - void flatBevel(float width=0.25f); - - void roundedBevel(float width=0.5f, unsigned int numSteps=10); - - void roundedBevel2(float width=0.5f, unsigned int numSteps=10); - - void print(std::ostream& fout); - - Vertices& getVertices() { return _vertices; } - - protected: - - Vertices _vertices; -}; - extern osg::Geometry* computeGlyphGeometry(osgText::Glyph3D* glyph, float bevelThickness, float shellThickness); -extern osg::Geometry* computeTextGeometry(osg::Geometry* glyphGeometry, BevelProfile& profile, float width); +extern osg::Geometry* computeTextGeometry(osg::Geometry* glyphGeometry, const Bevel& profile, float width); -extern osg::Geometry* computeShellGeometry(osg::Geometry* glyphGeometry, BevelProfile& profile, float width); +extern osg::Geometry* computeShellGeometry(osg::Geometry* glyphGeometry, const Bevel& profile, float width); } diff --git a/examples/osgtext3D/TextNode.cpp b/examples/osgtext3D/TextNode.cpp index 23ab043e3..d64744da1 100644 --- a/examples/osgtext3D/TextNode.cpp +++ b/examples/osgtext3D/TextNode.cpp @@ -28,7 +28,7 @@ using namespace osgText; // Bevel::Bevel() { - _thickness = 0.1f; + _thickness = 0.02f; flatBevel(); } @@ -191,8 +191,8 @@ void Layout::layout(TextNode& text) const osg::Vec3 size(characterSize, characterSize, 0.0); if (style) { - size.y() = characterSize * style->getWidthRatio(); - size.z() = characterSize * style->getThicknessRatio(); + size.y() = characterSize; + size.z() = characterSize; } @@ -242,8 +242,11 @@ void Layout::layout(TextNode& text) const OSG_NOTICE<<"pos = "<getVerticalHeight(); - osg::ref_ptr transform = new osg::PositionAttitudeTransform; transform->setPosition(position); transform->setAttitude(osg::Quat(osg::inDegrees(90.0),osg::Vec3d(1.0,0.0,0.0))); - transform->setScale(osg::Vec3d(scale, scale, scale)); + transform->setScale(size); osg::ref_ptr geode = new osg::Geode; - bool outline = false; - float thickness = 5; - float width = 10; - BevelProfile profile; + const Bevel* bevel = style ? style->getBevel() : 0; + bool outline = style ? style->getOutlineRatio()>0.0f : false; + float width = style->getThicknessRatio(); float creaseAngle = 30.0f; bool smooth = true; - osg::ref_ptr glyphGeometry = osgText::computeGlyphGeometry(glyph, thickness, width); - osg::ref_ptr textGeometry = osgText::computeTextGeometry(glyphGeometry.get(), profile, width); - osg::ref_ptr shellGeometry = outline ? osgText::computeShellGeometry(glyphGeometry.get(), profile, width) : 0; - if (textGeometry.valid()) geode->addDrawable(textGeometry.get()); - if (shellGeometry.valid()) geode->addDrawable(shellGeometry.get()); - - // create the normals - if (smooth && textGeometry.valid()) + if (bevel) + { + float thickness = bevel->getBevelThickness(); + + osg::ref_ptr glyphGeometry = osgText::computeGlyphGeometry(glyph, thickness, width); + osg::ref_ptr textGeometry = osgText::computeTextGeometry(glyphGeometry.get(), *bevel, width); + osg::ref_ptr shellGeometry = outline ? osgText::computeShellGeometry(glyphGeometry.get(), *bevel, width) : 0; + if (textGeometry.valid()) geode->addDrawable(textGeometry.get()); + if (shellGeometry.valid()) geode->addDrawable(shellGeometry.get()); + + // create the normals + if (smooth && textGeometry.valid()) + { + osgUtil::SmoothingVisitor::smooth(*textGeometry, osg::DegreesToRadians(creaseAngle)); + } + } + else { - osgUtil::SmoothingVisitor::smooth(*textGeometry, osg::DegreesToRadians(creaseAngle)); } transform->addChild(geode.get()); diff --git a/examples/osgtext3D/osgtext3D.cpp b/examples/osgtext3D/osgtext3D.cpp index 91dc16244..244bb6ff1 100644 --- a/examples/osgtext3D/osgtext3D.cpp +++ b/examples/osgtext3D/osgtext3D.cpp @@ -74,7 +74,7 @@ int main_experimental(osg::ArgumentParser& arguments) OSG_NOTICE<<"creaseAngle="< style = new osgText::Style; - float thickness = 0.0f; + float thickness = 0.1f; while(arguments.read("--thickness",thickness)) {} style->setThicknessRatio(thickness); + // set up any bevel if required + float r; + osg::ref_ptr bevel; + while(arguments.read("--rounded",r)) { bevel = new osgText::Bevel; bevel->roundedBevel2(r); } + while(arguments.read("--rounded")) { bevel = new osgText::Bevel; bevel->roundedBevel2(0.25); } + while(arguments.read("--flat",r)) { bevel = new osgText::Bevel; bevel->flatBevel(r); } + while(arguments.read("--flat")) { bevel = new osgText::Bevel; bevel->flatBevel(0.25); } + while(arguments.read("--bevel-thickness",r)) { if (bevel.valid()) bevel->setBevelThickness(r); } + + style->setBevel(bevel); + osgText::TextNode* text = new osgText::TextNode; text->setText(word); text->setFont(font.get()); @@ -180,6 +191,8 @@ int main(int argc, char** argv) text->setTextTechnique(new osgText::TextTechnique); text->update(); + viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); + viewer.addEventHandler(new osgViewer::StatsHandler); viewer.setSceneData(text); return viewer.run(); diff --git a/include/osgText/Text3D b/include/osgText/Text3D index 16924780e..e51943100 100644 --- a/include/osgText/Text3D +++ b/include/osgText/Text3D @@ -16,8 +16,7 @@ #include -#include - +#include namespace osgText { @@ -75,11 +74,7 @@ public: /** Set the Font to use to render the text. * setFont(0) sets the use of the default font.*/ - inline void setFont(Font3D* font=0) { setFont(osg::ref_ptr(font)); }; - - /** Set the Font to use to render the text.*/ - void setFont(osg::ref_ptr font); - + void setFont(Font* font); /** Set the font, loaded from the specified front file, to use to render the text, * setFont("") sets the use of the default font. @@ -87,7 +82,7 @@ public: void setFont(const std::string& fontfile); /** Get the font. Return 0 if default is being used.*/ - const Font3D* getFont() const { return _font.get(); } + const Font* getFont() const { return _font.get(); } @@ -156,7 +151,7 @@ protected: TextRenderInfo _textRenderInfo; - osg::ref_ptr _font; + osg::ref_ptr _font; float _characterDepth; diff --git a/src/osgPlugins/freetype/FreeTypeFont.cpp b/src/osgPlugins/freetype/FreeTypeFont.cpp index de8b17823..f75aff99f 100644 --- a/src/osgPlugins/freetype/FreeTypeFont.cpp +++ b/src/osgPlugins/freetype/FreeTypeFont.cpp @@ -35,7 +35,8 @@ struct Char3DInfo _maxY(-FLT_MAX), _maxX(-FLT_MAX), _minX(FLT_MAX), - _minY(FLT_MAX) + _minY(FLT_MAX), + _coord_scale(1.0/64.0) { } ~Char3DInfo() @@ -55,8 +56,12 @@ struct Char3DInfo return _geometry.get(); } - void addVertex(const osg::Vec3& pos) + void addVertex(osg::Vec3 pos) { + _previous = pos; + + pos *= _coord_scale; + if (!_verts->empty() && _verts->back()==pos) { // OSG_NOTICE<<"addVertex("<back(); + osg::Vec3 p0 = _previous; osg::Vec3 p1 = osg::Vec3(control.x(),control.y(),0); osg::Vec3 p2 = osg::Vec3(pos.x(),pos.y(),0); @@ -103,7 +108,7 @@ struct Char3DInfo void cubicTo(const osg::Vec2& control1, const osg::Vec2& control2, const osg::Vec2& pos) { - osg::Vec3 p0 = _verts->back(); + osg::Vec3 p0 = _previous; osg::Vec3 p1 = osg::Vec3(control1.x(),control1.y(),0); osg::Vec3 p2 = osg::Vec3(control2.x(),control2.y(),0); osg::Vec3 p3 = osg::Vec3(pos.x(),pos.y(),0); @@ -136,44 +141,45 @@ struct Char3DInfo osg::ref_ptr _verts; osg::ref_ptr _geometry; + osg::Vec3 _previous; int _idx; int _numSteps; double _maxY; double _maxX; double _minX; double _minY; + double _coord_scale; + }; -#define FT_NUM(x) (x/64.0) int moveTo( const FT_Vector* to, void* user ) { Char3DInfo* char3d = (Char3DInfo*)user; - char3d->moveTo( osg::Vec2(FT_NUM(to->x),FT_NUM(to->y)) ); + char3d->moveTo( osg::Vec2(to->x,to->y) ); return 0; } int lineTo( const FT_Vector* to, void* user ) { Char3DInfo* char3d = (Char3DInfo*)user; - char3d->lineTo( osg::Vec2(FT_NUM(to->x),FT_NUM(to->y)) ); + char3d->lineTo( osg::Vec2(to->x,to->y) ); return 0; } int conicTo( const FT_Vector* control,const FT_Vector* to, void* user ) { Char3DInfo* char3d = (Char3DInfo*)user; - char3d->conicTo( osg::Vec2(FT_NUM(control->x),FT_NUM(control->y)), osg::Vec2(FT_NUM(to->x),FT_NUM(to->y)) ); + char3d->conicTo( osg::Vec2(control->x,control->y), osg::Vec2(to->x,to->y) ); return 0; } int cubicTo( const FT_Vector* control1,const FT_Vector* control2,const FT_Vector* to, void* user ) { Char3DInfo* char3d = (Char3DInfo*)user; char3d->cubicTo( - osg::Vec2(FT_NUM(control1->x),FT_NUM(control1->y)), - osg::Vec2(FT_NUM(control2->x),FT_NUM(control2->y)), - osg::Vec2(FT_NUM(to->x),FT_NUM(to->y)) ); + osg::Vec2(control1->x,control1->y), + osg::Vec2(control2->x,control2->y), + osg::Vec2(to->x,to->y) ); return 0; } -#undef FT_NUM } @@ -183,7 +189,8 @@ FreeTypeFont::FreeTypeFont(const std::string& filename, FT_Face face, unsigned i _buffer(0), _face(face), _flags(flags), - _scale(1.0f) + _scale(1.0f), + _freetype_scale(1.0f) { init(); } @@ -194,7 +201,8 @@ FreeTypeFont::FreeTypeFont(FT_Byte* buffer, FT_Face face, unsigned int flags): _buffer(buffer), _face(face), _flags(flags), - _scale(1.0f) + _scale(1.0f), + _freetype_scale(1.0f) { init(); } @@ -279,7 +287,13 @@ void FreeTypeFont::init() // long xmax = ft_ceiling( bb.xMax ); // double width = (xmax - xmin)/64.0; - _scale = 1.0/height; +#if 1 + _freetype_scale = 1.0f/height; + _scale = 1.0f; +#else + _freetype_scale = 1.0f; + _scale = 1.0f/height; +#endif } } @@ -407,12 +421,14 @@ osgText::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, u } - FT_Glyph_Metrics* metrics = &(glyphslot->metrics); + FT_Glyph_Metrics* metrics = &(_face->glyph->metrics); - glyph->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX/64.0f,(float)(metrics->horiBearingY-metrics->height)/64.0f)); // bottom left. - glyph->setHorizontalAdvance((float)metrics->horiAdvance/64.0f); - glyph->setVerticalBearing(osg::Vec2((float)metrics->vertBearingX/64.0f,(float)(metrics->vertBearingY-metrics->height)/64.0f)); // top middle. - glyph->setVerticalAdvance((float)metrics->vertAdvance/64.0f); + float coord_scale = _freetype_scale/64.0f; + + glyph->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX * coord_scale,(float)(metrics->horiBearingY-metrics->height) * coord_scale)); // bottom left. + glyph->setHorizontalAdvance((float)metrics->horiAdvance * coord_scale); + glyph->setVerticalBearing(osg::Vec2((float)metrics->vertBearingX * coord_scale,(float)(metrics->vertBearingY-metrics->height) * coord_scale)); // top middle. + glyph->setVerticalAdvance((float)metrics->vertAdvance * coord_scale); // cout << " in getGlyph() implementation="< lock(_glyphMapMutex); FontSizeGlyphMap::iterator itr = _sizeGlyphMap.find(fontRes); @@ -364,6 +366,8 @@ Glyph* Font::getGlyph(const FontResolution& fontRes, unsigned int charcode) Glyph3D* Font::getGlyph3D(unsigned int charcode) { + OSG_NOTICE<<"Font::getGlyph3D("< lock(_glyphMapMutex); Glyph3DMap::iterator itr = _glyph3DMap.find(charcode); diff --git a/src/osgText/Text3D.cpp b/src/osgText/Text3D.cpp index 4a0143417..4eba03d73 100644 --- a/src/osgText/Text3D.cpp +++ b/src/osgText/Text3D.cpp @@ -102,7 +102,7 @@ void Text3D::accept(osg::PrimitiveFunctor& pf) const } } -void Text3D::setFont(osg::ref_ptr font) +void Text3D::setFont(Font* font) { _font = font; @@ -111,7 +111,7 @@ void Text3D::setFont(osg::ref_ptr font) void Text3D::setFont(const std::string & fontfile) { - setFont(readRefFont3DFile(fontfile)); + setFont(readRefFontFile(fontfile)); } String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last) diff --git a/src/osgWrappers/serializers/osgText/Text3D.cpp b/src/osgWrappers/serializers/osgText/Text3D.cpp index e0e21b3a6..4c122f911 100644 --- a/src/osgWrappers/serializers/osgText/Text3D.cpp +++ b/src/osgWrappers/serializers/osgText/Text3D.cpp @@ -11,7 +11,7 @@ static bool checkFont( const osgText::Text3D& text ) static bool readFont( osgDB::InputStream& is, osgText::Text3D& text ) { std::string fontName; is.readWrappedString( fontName ); - text.setFont( osgText::readFont3DFile(fontName) ); + text.setFont( osgText::readFontFile(fontName) ); return true; }